summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-09-26 15:55:21 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-09-26 15:55:21 -0600
commitcda383a549d16f8b441a423578d69a9dfdf1e579 (patch)
treec7a24a48c5452278c76907c329047344adfefdfd
parent5a50891de49e3ff53a607c481e0a05a19029d8f0 (diff)
downloadnuttx-cda383a549d16f8b441a423578d69a9dfdf1e579.tar.gz
nuttx-cda383a549d16f8b441a423578d69a9dfdf1e579.tar.bz2
nuttx-cda383a549d16f8b441a423578d69a9dfdf1e579.zip
Beginng of support for GMII/RGMII PHYs
-rw-r--r--nuttx/ChangeLog2
-rw-r--r--nuttx/arch/arm/src/sama5/Kconfig4
-rw-r--r--nuttx/arch/arm/src/sama5/chip/sam_gmac.h2
-rw-r--r--nuttx/arch/arm/src/sama5/sam_emac.c8
-rw-r--r--nuttx/arch/arm/src/sama5/sam_ethernet.h8
-rw-r--r--nuttx/arch/arm/src/sama5/sam_gmac.c348
-rw-r--r--nuttx/drivers/net/Kconfig6
-rw-r--r--nuttx/include/nuttx/net/gmii.h261
-rw-r--r--nuttx/include/nuttx/net/mii.h45
9 files changed, 522 insertions, 162 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index d8e643fc9..6f39e782e 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -5640,4 +5640,6 @@
* arch/arm/src/sama5/sam_gmac.c: Initial GMAC driver is really
just the EMAC driver forced to compile with the GMAC register
definitions (2013-9-26).
+ * arch/arm/src/sama5/sam_gmac.c and include/nuttx/net/gmii.h:
+ Beginning of support for GMII/RGMII PHY support (2013-9-26)
diff --git a/nuttx/arch/arm/src/sama5/Kconfig b/nuttx/arch/arm/src/sama5/Kconfig
index 3474c2e16..21638744f 100644
--- a/nuttx/arch/arm/src/sama5/Kconfig
+++ b/nuttx/arch/arm/src/sama5/Kconfig
@@ -277,7 +277,7 @@ config SAMA5_GMAC_NRXBUFFERS
config SAMA5_GMAC_NTXBUFFERS
int "Number of TX buffers"
- default 1
+ default 8
---help---
GMAC buffer memory is segmented into full Ethernet packets (size
NET_BUFSIZE bytes). This setting provides the number of such packets
@@ -471,7 +471,7 @@ config SAMA5_EMAC_NRXBUFFERS
config SAMA5_EMAC_NTXBUFFERS
int "Number of TX buffers"
- default 1
+ default 8
---help---
EMAC buffer memory is segmented into full Ethernet packets (size
NET_BUFSIZE bytes). This setting provides the number of such packets
diff --git a/nuttx/arch/arm/src/sama5/chip/sam_gmac.h b/nuttx/arch/arm/src/sama5/chip/sam_gmac.h
index 6ed56589b..ffb42aa66 100644
--- a/nuttx/arch/arm/src/sama5/chip/sam_gmac.h
+++ b/nuttx/arch/arm/src/sama5/chip/sam_gmac.h
@@ -483,7 +483,7 @@
# define GMAC_NCFGR_CLK_DIV32 (2 << GMAC_NCFGR_CLK_SHIFT) /* MCK divided by 32 (MCK up to 80 MHz) */
# define GMAC_NCFGR_CLK_DIV48 (3 << GMAC_NCFGR_CLK_SHIFT) /* MCK divided by 48 (MCK up to 120 MHz) */
# define GMAC_NCFGR_CLK_DIV64 (4 << GMAC_NCFGR_CLK_SHIFT) /* MCK divided by 64 (MCK up to 160 MHz) */
-# define GMAC_NCFGR_CLK_DIV96 (5 << GMAC_NCFGR_CLK_SHIFT) /* MCK divided by 64 (MCK up to 240 MHz) */
+# define GMAC_NCFGR_CLK_DIV96 (5 << GMAC_NCFGR_CLK_SHIFT) /* MCK divided by 96 (MCK up to 240 MHz) */
#define GMAC_NCFGR_DBW_SHIFT (21) /* Bits 21-22: Data Bus Width */
#define GMAC_NCFGR_DBW_MASK (3 << GMAC_NCFGR_DBW_SHIFT)
# define GMAC_NCFGR_DBW_32 (0 << GMAC_NCFGR_DBW_SHIFT) /* 32-bit data bus width */
diff --git a/nuttx/arch/arm/src/sama5/sam_emac.c b/nuttx/arch/arm/src/sama5/sam_emac.c
index be0df5d2e..1c5198020 100644
--- a/nuttx/arch/arm/src/sama5/sam_emac.c
+++ b/nuttx/arch/arm/src/sama5/sam_emac.c
@@ -94,7 +94,7 @@
/* Number of buffer for TX */
#ifndef CONFIG_SAMA5_EMAC_NTXBUFFERS
-# define CONFIG_SAMA5_EMAC_NTXBUFFERS 32
+# define CONFIG_SAMA5_EMAC_NTXBUFFERS 8
#endif
#undef CONFIG_SAMA5_EMAC_NBC
@@ -294,11 +294,13 @@ static struct sam_emac_s g_emac;
/* Preallocated data */
/* TX descriptors list */
-static struct emac_txdesc_s g_txdesc[TX_BUFFERS] __attribute__((aligned(8)));
+static struct emac_txdesc_s g_txdesc[CONFIG_SAMA5_EMAC_NTXBUFFERS]
+ __attribute__((aligned(8)));
/* RX descriptors list */
-static struct emac_rxdesc_s g_rxdesc[RX_BUFFERS]__attribute__((aligned(8)));
+static struct emac_rxdesc_s g_rxdesc[CONFIG_SAMA5_EMAC_NRXBUFFERS]
+ __attribute__((aligned(8)));
/* Transmit Buffers
*
diff --git a/nuttx/arch/arm/src/sama5/sam_ethernet.h b/nuttx/arch/arm/src/sama5/sam_ethernet.h
index f48b5da6c..605840bc9 100644
--- a/nuttx/arch/arm/src/sama5/sam_ethernet.h
+++ b/nuttx/arch/arm/src/sama5/sam_ethernet.h
@@ -75,6 +75,8 @@
# define SAMA5_GMAC_PHY_LAN8700 1
# elif defined(CONFIG_ETH0_PHY_KSZ8051)
# define SAMA5_GMAC_PHY_KSZ8051 1
+# elif defined(CONFIG_ETH0_PHY_KSZ90x1)
+# define SAMA5_GMAC_PHY_KSZ90x1 1
# else
# error ETH0 PHY unrecognized
# endif
@@ -85,6 +87,8 @@
# define SAMA5_GMAC_PHY_LAN8700 1
# elif defined(CONFIG_ETH1_PHY_KSZ8051)
# define SAMA5_GMAC_PHY_KSZ8051 1
+# elif defined(CONFIG_ETH1_PHY_KSZ90x1)
+# define SAMA5_GMAC_PHY_KSZ90x1 1
# else
# error ETH1 PHY unrecognized
# endif
@@ -97,6 +101,8 @@
# define SAMA5_EMAC_PHY_LAN8700 1
# elif defined(CONFIG_ETH0_PHY_KSZ8051)
# define SAMA5_EMAC_PHY_KSZ8051 1
+# elif defined(CONFIG_ETH0_PHY_KSZ90x1)
+# define SAMA5_EMAC_PHY_KSZ90x1 1
# else
# error ETH0 PHY unrecognized
# endif
@@ -107,6 +113,8 @@
# define SAMA5_EMAC_PHY_LAN8700 1
# elif defined(CONFIG_ETH1_PHY_KSZ8051)
# define SAMA5_EMAC_PHY_KSZ8051 1
+# elif defined(CONFIG_ETH1_PHY_KSZ90x1)
+# define SAMA5_EMAC_PHY_KSZ90x1 1
# else
# error ETH1 PHY unrecognized
# endif
diff --git a/nuttx/arch/arm/src/sama5/sam_gmac.c b/nuttx/arch/arm/src/sama5/sam_gmac.c
index db3c8ef07..b25d74b57 100644
--- a/nuttx/arch/arm/src/sama5/sam_gmac.c
+++ b/nuttx/arch/arm/src/sama5/sam_gmac.c
@@ -60,7 +60,7 @@
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/kmalloc.h>
-#include <nuttx/net/mii.h>
+#include <nuttx/net/gmii.h>
#include <nuttx/net/uip/uip.h>
#include <nuttx/net/uip/uip-arp.h>
#include <nuttx/net/uip/uip-arch.h>
@@ -94,7 +94,7 @@
/* Number of buffer for TX */
#ifndef CONFIG_SAMA5_GMAC_NTXBUFFERS
-# define CONFIG_SAMA5_GMAC_NTXBUFFERS 32
+# define CONFIG_SAMA5_GMAC_NTXBUFFERS 8
#endif
#undef CONFIG_SAMA5_GMAC_NBC
@@ -149,17 +149,11 @@
/* PHY definitions */
-#if defined(SAMA5_GMAC_PHY_DM9161)
-# define MII_OUI_MSB 0x0181
-# define MII_OUI_LSB 0x2e
-#elif defined(SAMA5_GMAC_PHY_LAN8700)
-# define MII_OUI_MSB 0x0007
-# define MII_OUI_LSB 0x30
-#elif defined(SAMA5_GMAC_PHY_KSZ8051)
-# define MII_OUI_MSB 0x0022
-# define MII_OUI_LSB 0x05
+#ifdef SAMA5_GMAC_PHY_KSZ90x1
+# define GMII_OUI_MSB 0x0022
+# define GMII_OUI_LSB 0x05
#else
-# error GMAC PHY unrecognized
+# error Unknown PHY
#endif
#ifdef CONFIG_SAMA5_GMAC_PHYSR_ALTCONFIG
@@ -203,6 +197,13 @@
#define GMAC_RX_UNITSIZE 128 /* Fixed size for RX buffer */
#define GMAC_TX_UNITSIZE CONFIG_NET_BUFSIZE /* MAX size for Ethernet packet */
+/* The MAC can support frame lengths up to 1536 bytes */
+
+#define GMAC_MAX_FRAMELEN 1536
+#if CONFIG_NET_BUFSIZE >GMAC_MAX_FRAMELEN
+# error CONFIG_NET_BUFSIZE is too large
+#endif
+
/* We need at least one more free buffer than transmit buffers */
#define SAM_GMAC_NFREEBUFFERS (CONFIG_SAMA5_GMAC_NTXBUFFERS+1)
@@ -235,7 +236,7 @@
/* PHY read/write delays in loop counts */
-#define PHY_RETRY_MAX 1000000
+#define PHY_RETRY_MAX 300000
/* Helpers ******************************************************************/
/* This is a helper pointer for accessing the contents of the GMAC
@@ -294,11 +295,13 @@ static struct sam_gmac_s g_gmac;
/* Preallocated data */
/* TX descriptors list */
-static struct gmac_txdesc_s g_txdesc[TX_BUFFERS] __attribute__((aligned(8)));
+static struct gmac_txdesc_s g_txdesc[CONFIG_SAMA5_GMAC_NTXBUFFERS]
+ __attribute__((aligned(8)));
/* RX descriptors list */
-static struct gmac_rxdesc_s g_rxdesc[RX_BUFFERS]__attribute__((aligned(8)));
+static struct gmac_rxdesc_s g_rxdesc[CONFIG_SAMA5_GMAC_NRXBUFFERS]
+ __attribute__((aligned(8)));
/* Transmit Buffers
*
@@ -307,14 +310,13 @@ static struct gmac_rxdesc_s g_rxdesc[RX_BUFFERS]__attribute__((aligned(8)));
* shall be set to 0
*/
-static uint8_t g_txbuffer[CONFIG_SAMA5_GMAC_NTXBUFFERS * GMAC_TX_UNITSIZE];
- __attribute__((aligned(8)))
+static uint8_t g_txbuffer[CONFIG_SAMA5_GMAC_NTXBUFFERS * GMAC_TX_UNITSIZE]
+ __attribute__((aligned(8)));
/* Receive Buffers */
static uint8_t g_rxbuffer[CONFIG_SAMA5_GMAC_NRXBUFFERS * GMAC_RX_UNITSIZE]
__attribute__((aligned(8)));
-
#endif
/****************************************************************************
@@ -384,6 +386,7 @@ static int sam_phywrite(struct sam_gmac_s *priv, uint8_t phyaddr,
uint8_t regaddr, uint16_t phyval);
static int sam_autonegotiate(struct sam_gmac_s *priv);
static bool sam_linkup(struct sam_gmac_s *priv);
+static void sam_mdcclock(struct sam_gmac_s *priv);
static int sam_phyinit(struct sam_gmac_s *priv);
/* GMAC Initialization */
@@ -1786,9 +1789,7 @@ static void sam_phydump(struct sam_gmac_s *priv)
/* Enable management port */
- regval = sam_getreg(priv, SAM_GMAC_NCR);
- regval |= GMAC_NCR_MPE;
- sam_putreg(priv, SAM_GMAC_NCR, regval);
+ sam_enablemdio(priv);
#ifdef CONFIG_SAMA5_GMAC_RGMII
nllvdbg("RMII Registers (Address %02x)\n", priv->phyaddr);
@@ -1796,24 +1797,88 @@ static void sam_phydump(struct sam_gmac_s *priv)
nllvdbg("MII Registers (Address %02x)\n", priv->phyaddr);
#endif
- sam_phyread(priv, priv->phyaddr, MII_MCR, &phyval);
+ sam_phyread(priv, priv->phyaddr, GMII_MCR, &phyval);
nllvdbg(" MCR: %04x\n", phyval);
- sam_phyread(priv, priv->phyaddr, MII_MSR, &phyval);
+ sam_phyread(priv, priv->phyaddr, GMII_MSR, &phyval);
nllvdbg(" MSR: %04x\n", phyval);
- sam_phyread(priv, priv->phyaddr, MII_ADVERTISE, &phyval);
+ sam_phyread(priv, priv->phyaddr, GMII_ADVERTISE, &phyval);
nllvdbg(" ADVERTISE: %04x\n", phyval);
- sam_phyread(priv, priv->phyaddr, MII_LPA, &phyval);
+ sam_phyread(priv, priv->phyaddr, GMII_LPA, &phyval);
nllvdbg(" LPR: %04x\n", phyval);
sam_phyread(priv, priv->phyaddr, CONFIG_SAMA5_GMAC_PHYSR, &phyval);
nllvdbg(" PHYSR: %04x\n", phyval);
/* Disable management port */
+ sam_disablemdio(priv);
+}
+#endif
+
+/****************************************************************************
+ * Function: sam_enablemdio
+ *
+ * Description:
+ * Enable the management port
+ *
+ * Parameters:
+ * priv - A reference to the private driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void sam_enablemdio(struct sam_gmac_s *priv)
+{
+ uint32_t regval;
+ uint32_t enables;
+
+ /* Enable management port */
+
regval = sam_getreg(priv, SAM_GMAC_NCR);
+ enables = regval & (GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+
+ regval &= ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+ regval |= GMAC_NCR_MPE;
+ sam_putreg(priv, SAM_GMAC_NCR, regval);
+
+ regval |= enables;
+ sam_putreg(priv, SAM_GMAC_NCR, regval);
+}
+
+/****************************************************************************
+ * Function: sam_disablemdio
+ *
+ * Description:
+ * Disable the management port
+ *
+ * Parameters:
+ * priv - A reference to the private driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void sam_disablemdio(struct sam_gmac_s *priv)
+{
+ uint32_t regval;
+ uint32_t enables;
+
+ /* Disable management port */
+
+ regval = sam_getreg(priv, SAM_GMAC_NCR);
+ enables = regval & (GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+
+ regval &= ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+ sam_putreg(priv, SAM_GMAC_NCR, regval);
+
regval &= ~GMAC_NCR_MPE;
sam_putreg(priv, SAM_GMAC_NCR, regval);
+
+ regval |= enables;
+ sam_putreg(priv, SAM_GMAC_NCR, regval);
}
-#endif
/****************************************************************************
* Function: sam_phywait
@@ -1866,7 +1931,6 @@ static int sam_phywait(struct sam_gmac_s *priv)
static int sam_phyreset(struct sam_gmac_s *priv)
{
- uint32_t regval;
uint16_t mcr;
int timeout;
int ret;
@@ -1875,13 +1939,11 @@ static int sam_phyreset(struct sam_gmac_s *priv)
/* Enable management port */
- regval = sam_getreg(priv, SAM_GMAC_NCR);
- regval |= GMAC_NCR_MPE;
- sam_putreg(priv, SAM_GMAC_NCR, regval);
+ sam_enablemdio(priv);
/* Reset the PHY */
- ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, MII_MCR_RESET);
+ ret = sam_phywrite(priv, priv->phyaddr, GMII_MCR, GMII_MCR_RESET);
if (ret < 0)
{
nlldbg("ERROR: sam_phywrite failed: %d\n", ret);
@@ -1892,14 +1954,14 @@ static int sam_phyreset(struct sam_gmac_s *priv)
ret = -ETIMEDOUT;
for (timeout = 0; timeout < 10; timeout++)
{
- mcr = MII_MCR_RESET;
- int result = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr);
+ mcr = GMII_MCR_RESET;
+ int result = sam_phyread(priv, priv->phyaddr, GMII_MCR, &mcr);
if (result < 0)
{
nlldbg("ERROR: Failed to read the MCR register: %d\n", ret);
ret = result;
}
- else if ((mcr & MII_MCR_RESET) == 0)
+ else if ((mcr & GMII_MCR_RESET) == 0)
{
ret = OK;
break;
@@ -1908,9 +1970,7 @@ static int sam_phyreset(struct sam_gmac_s *priv)
/* Disable management port */
- regval = sam_getreg(priv, SAM_GMAC_NCR);
- regval &= ~GMAC_NCR_MPE;
- sam_putreg(priv, SAM_GMAC_NCR, regval);
+ sam_disablemdio(priv);
return ret;
}
@@ -1932,7 +1992,6 @@ static int sam_phyreset(struct sam_gmac_s *priv)
static int sam_phyfind(struct sam_gmac_s *priv, uint8_t *phyaddr)
{
- uint32_t regval;
uint16_t phyval;
uint8_t candidate;
unsigned int offset;
@@ -1942,16 +2001,14 @@ static int sam_phyfind(struct sam_gmac_s *priv, uint8_t *phyaddr)
/* Enable management port */
- regval = sam_getreg(priv, SAM_GMAC_NCR);
- regval |= GMAC_NCR_MPE;
- sam_putreg(priv, SAM_GMAC_NCR, regval);
+ sam_enablemdio(priv);
- candidate = *phyaddr;
+ /* Check initial candidate address */
- /* Check current candidate address */
+ candidate = *phyaddr;
- ret = sam_phyread(priv, candidate, MII_PHYID1, &phyval);
- if (ret == OK && phyval == MII_OUI_MSB)
+ ret = sam_phyread(priv, candidate, GMII_PHYID1, &phyval);
+ if (ret == OK && phyval == GMII_OUI_MSB)
{
*phyaddr = candidate;
ret = OK;
@@ -1972,8 +2029,8 @@ static int sam_phyfind(struct sam_gmac_s *priv, uint8_t *phyaddr)
/* Try reading the PHY ID from the candidate PHY address */
- ret = sam_phyread(priv, candidate, MII_PHYID1, &phyval);
- if (ret == OK && phyval == MII_OUI_MSB)
+ ret = sam_phyread(priv, candidate, GMII_PHYID1, &phyval);
+ if (ret == OK && phyval == GMII_OUI_MSB)
{
ret = OK;
break;
@@ -1991,9 +2048,7 @@ static int sam_phyfind(struct sam_gmac_s *priv, uint8_t *phyaddr)
/* Disable management port */
- regval = sam_getreg(priv, SAM_GMAC_NCR);
- regval &= ~GMAC_NCR_MPE;
- sam_putreg(priv, SAM_GMAC_NCR, regval);
+ sam_disablemdio(priv);
return ret;
}
@@ -2034,7 +2089,7 @@ static int sam_phyread(struct sam_gmac_s *priv, uint8_t phyaddr,
/* Write the PHY Maintenance register */
regval = GMAC_MAN_DATA(0) | GMAC_MAN_WTN | GMAC_MAN_REGA(regaddr) |
- GMAC_MAN_PHYA(priv->phyaddr) | GMAC_MAN_READ;
+ GMAC_MAN_PHYA(priv->phyaddr) | GMAC_MAN_READ | GMAC_MAN_CLTTO;
sam_putreg(priv, SAM_GMAC_MAN, regval);
/* Wait until the PHY is again idle */
@@ -2046,7 +2101,7 @@ static int sam_phyread(struct sam_gmac_s *priv, uint8_t phyaddr,
return ret;
}
- /* Return data */
+ /* Return the PHY data */
*phyval = (uint16_t)(sam_getreg(priv, SAM_GMAC_MAN) & GMAC_MAN_DATA_MASK);
return OK;
@@ -2089,7 +2144,7 @@ static int sam_phywrite(struct sam_gmac_s *priv, uint8_t phyaddr,
/* Write the PHY Maintenance register */
regval = GMAC_MAN_DATA(phyval) | GMAC_MAN_WTN | GMAC_MAN_REGA(regaddr) |
- GMAC_MAN_PHYA(priv->phyaddr) | GMAC_MAN_WRITE;
+ GMAC_MAN_PHYA(priv->phyaddr) | GMAC_MAN_WRITE | GMAC_MAN_CLTTO;
sam_putreg(priv, SAM_GMAC_MAN, regval);
/* Wait until the PHY is again IDLE */
@@ -2132,13 +2187,11 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
/* Enable management port */
- regval = sam_getreg(priv, SAM_GMAC_NCR);
- regval |= GMAC_NCR_MPE;
- sam_putreg(priv, SAM_GMAC_NCR, regval);
+ sam_enablemdio(priv);
/* Verify tht we can read the PHYID register */
- ret = sam_phyread(priv, priv->phyaddr, MII_PHYID1, &phyid1);
+ ret = sam_phyread(priv, priv->phyaddr, GMII_PHYID1, &phyid1);
if (ret < 0)
{
nlldbg("ERROR: Failed to read PHYID1\n");
@@ -2147,7 +2200,7 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
nllvdbg("PHYID1: %04x PHY address: %02x\n", phyid1, priv->phyaddr);
- ret = sam_phyread(priv, priv->phyaddr, MII_PHYID2, &phyid2);
+ ret = sam_phyread(priv, priv->phyaddr, GMII_PHYID2, &phyid2);
if (ret < 0)
{
nlldbg("ERROR: Failed to read PHYID2\n");
@@ -2156,8 +2209,8 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
nllvdbg("PHYID2: %04x PHY address: %02x\n", phyid2, priv->phyaddr);
- if (phyid1 == MII_OUI_MSB &&
- ((phyid2 & MII_PHYID2_OUI) >> 10) == MII_OUI_LSB)
+ if (phyid1 == GMII_OUI_MSB &&
+ ((phyid2 & GMII_PHYID2_OUI) >> 10) == GMII_OUI_LSB)
{
nllvdbg(" Vendor Model Number: %04x\n", ((phyid2 >> 4) & 0x3f));
nllvdbg(" Model Revision Number: %04x\n", (phyid2 & 7));
@@ -2169,18 +2222,18 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
/* Setup control register */
- ret = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr);
+ ret = sam_phyread(priv, priv->phyaddr, GMII_MCR, &mcr);
if (ret < 0)
{
nlldbg("ERROR: Failed to read MCR\n");
goto errout;
}
- mcr &= ~MII_MCR_ANENABLE; /* Remove autonegotiation enable */
- mcr &= ~(MII_MCR_LOOPBACK | MII_MCR_PDOWN);
- mcr |= MII_MCR_ISOLATE; /* Electrically isolate PHY */
+ mcr &= ~GMII_MCR_ANENABLE; /* Remove autonegotiation enable */
+ mcr &= ~(GMII_MCR_LOOPBACK | GMII_MCR_PDOWN);
+ mcr |= GMII_MCR_ISOLATE; /* Electrically isolate PHY */
- ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr);
+ ret = sam_phywrite(priv, priv->phyaddr, GMII_MCR, mcr);
if (ret < 0)
{
nlldbg("ERROR: Failed to write MCR\n");
@@ -2191,11 +2244,11 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
* Next page 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3
*/
- advertise = MII_ADVERTISE_100BASETXFULL | MII_ADVERTISE_100BASETXHALF |
- MII_ADVERTISE_10BASETXFULL | MII_ADVERTISE_10BASETXHALF |
- MII_ADVERTISE_8023;
+ advertise = GMII_ADVERTISE_100BASETXFULL | GMII_ADVERTISE_100BASETXHALF |
+ GMII_ADVERTISE_10BASETXFULL | GMII_ADVERTISE_10BASETXHALF |
+ GMII_ADVERTISE_8023;
- ret = sam_phywrite(priv, priv->phyaddr, MII_ADVERTISE, advertise);
+ ret = sam_phywrite(priv, priv->phyaddr, GMII_ADVERTISE, advertise);
if (ret < 0)
{
nlldbg("ERROR: Failed to write ANAR\n");
@@ -2204,15 +2257,15 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
/* Read and modify control register */
- ret = sam_phyread(priv, priv->phyaddr, MII_MCR, &mcr);
+ ret = sam_phyread(priv, priv->phyaddr, GMII_MCR, &mcr);
if (ret < 0)
{
nlldbg("ERROR: Failed to read MCR\n");
goto errout;
}
- mcr |= (MII_MCR_SPEED100 | MII_MCR_ANENABLE | MII_MCR_FULLDPLX);
- ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr);
+ mcr |= (GMII_MCR_SPEED100 | GMII_MCR_ANENABLE | GMII_MCR_FULLDPLX);
+ ret = sam_phywrite(priv, priv->phyaddr, GMII_MCR, mcr);
if (ret < 0)
{
nlldbg("ERROR: Failed to write MCR\n");
@@ -2221,10 +2274,10 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
/* Restart Auto_negotiation */
- mcr |= MII_MCR_ANRESTART;
- mcr &= ~MII_MCR_ISOLATE;
+ mcr |= GMII_MCR_ANRESTART;
+ mcr &= ~GMII_MCR_ISOLATE;
- ret = sam_phywrite(priv, priv->phyaddr, MII_MCR, mcr);
+ ret = sam_phywrite(priv, priv->phyaddr, GMII_MCR, mcr);
if (ret < 0)
{
nlldbg("ERROR: Failed to write MCR\n");
@@ -2238,7 +2291,7 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
timeout = 0;
for (;;)
{
- ret = sam_phyread(priv, priv->phyaddr, MII_MSR, &msr);
+ ret = sam_phyread(priv, priv->phyaddr, GMII_MSR, &msr);
if (ret < 0)
{
nlldbg("ERROR: Failed to read MSR\n");
@@ -2247,7 +2300,7 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
/* Completed successfully? */
- if ((msr & MII_MSR_ANEGCOMPLETE) != 0)
+ if ((msr & GMII_MSR_ANEGCOMPLETE) != 0)
{
/* Yes.. break out of the loop */
@@ -2268,7 +2321,7 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
/* Get the AutoNeg Link partner base page */
- ret = sam_phyread(priv, priv->phyaddr, MII_LPA, &lpa);
+ ret = sam_phyread(priv, priv->phyaddr, GMII_LPA, &lpa);
if (ret < 0)
{
nlldbg("ERROR: Failed to read ANLPAR\n");
@@ -2280,26 +2333,26 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
regval = sam_getreg(priv, SAM_GMAC_NCFGR);
regval &= (GMAC_NCFGR_SPD | GMAC_NCFGR_FD);
- if (((advertise & lpa) & MII_ADVERTISE_100BASETXFULL) != 0)
+ if (((advertise & lpa) & GMII_ADVERTISE_100BASETXFULL) != 0)
{
/* Set MII for 100BaseTX and Full Duplex */
regval |= (GMAC_NCFGR_SPD | GMAC_NCFGR_FD);
}
- else if (((advertise & lpa) & MII_ADVERTISE_10BASETXFULL) != 0)
+ else if (((advertise & lpa) & GMII_ADVERTISE_10BASETXFULL) != 0)
{
/* Set MII for 10BaseT and Full Duplex */
regval |= GMAC_NCFGR_FD;
}
- else if (((advertise & lpa) & MII_ADVERTISE_100BASETXHALF) != 0)
+ else if (((advertise & lpa) & GMII_ADVERTISE_100BASETXHALF) != 0)
{
/* Set MII for 100BaseTX and half Duplex */
regval |= GMAC_NCFGR_SPD;
}
#if 0
- else if (((advertise & lpa) & MII_ADVERTISE_10BASETXHALF) != 0)
+ else if (((advertise & lpa) & GMII_ADVERTISE_10BASETXHALF) != 0)
{
/* set MII for 10BaseT and half Duplex */
}
@@ -2318,11 +2371,9 @@ static int sam_autonegotiate(struct sam_gmac_s *priv)
sam_putreg(priv, SAM_GMAC_UR, regval);
errout:
- /* Disable management port */
+ /* Disable the management port */
- regval = sam_getreg(priv, SAM_GMAC_NCR);
- regval &= ~GMAC_NCR_MPE;
- sam_putreg(priv, SAM_GMAC_NCR, regval);
+ sam_disablemdio(priv);
return ret;
}
@@ -2350,18 +2401,18 @@ static bool sam_linkup(struct sam_gmac_s *priv)
/* Enable management port */
- regval = sam_getreg(priv, SAM_GMAC_NCR);
- regval |= GMAC_NCR_MPE;
- sam_putreg(priv, SAM_GMAC_NCR, regval);
+ sam_enablemdio(priv);
- ret = sam_phyread(priv, priv->phyaddr, MII_MSR, &msr);
+ /* Read the PHY MSR register */
+
+ ret = sam_phyread(priv, priv->phyaddr, GMII_MSR, &msr);
if (ret < 0)
{
nlldbg("ERROR: Failed to read MSR: %d\n", ret);
goto errout;
}
- if ((msr & MII_MSR_LINKSTATUS) == 0)
+ if ((msr & GMII_MSR_LINKSTATUS) == 0)
{
nlldbg("ERROR: MSR LinkStatus: %04x\n", msr);
goto errout;
@@ -2379,20 +2430,20 @@ static bool sam_linkup(struct sam_gmac_s *priv)
regval = sam_getreg(priv, SAM_GMAC_NCFGR);
regval &= ~(GMAC_NCFGR_SPD | GMAC_NCFGR_FD);
- if ((msr & MII_MSR_100BASETXFULL) != 0 && PHYSR_IS100FDX(physr))
+ if ((msr & GMII_MSR_100BASETXFULL) != 0 && PHYSR_IS100FDX(physr))
{
/* Set GMAC for 100BaseTX and Full Duplex */
regval |= (GMAC_NCFGR_SPD | GMAC_NCFGR_FD);
}
- else if ((msr & MII_MSR_10BASETXFULL) != 0 && PHYSR_IS10FDX(physr))
+ else if ((msr & GMII_MSR_10BASETXFULL) != 0 && PHYSR_IS10FDX(physr))
{
/* Set MII for 10BaseT and Full Duplex */
regval |= GMAC_NCFGR_FD;
}
- else if ((msr & MII_MSR_100BASETXHALF) != 0 && PHYSR_IS100HDX(physr))
+ else if ((msr & GMII_MSR_100BASETXHALF) != 0 && PHYSR_IS100HDX(physr))
{
/* Set MII for 100BaseTX and Half Duplex */
@@ -2400,7 +2451,7 @@ static bool sam_linkup(struct sam_gmac_s *priv)
}
#if 0
- else if ((msr & MII_MSR_10BASETXHALF) != 0 && PHYSR_IS10HDX(physr))
+ else if ((msr & GMII_MSR_10BASETXHALF) != 0 && PHYSR_IS10HDX(physr))
{
/* Set MII for 10BaseT and Half Duplex */
}
@@ -2416,14 +2467,67 @@ static bool sam_linkup(struct sam_gmac_s *priv)
errout:
/* Disable management port */
- regval = sam_getreg(priv, SAM_GMAC_NCR);
- regval &= ~GMAC_NCR_MPE;
- sam_putreg(priv, SAM_GMAC_NCR, regval);
-
+ sam_disablemdio(priv);
return linkup;
}
/****************************************************************************
+ * Function: sam_mdcclock
+ *
+ * Description:
+ * Configure the MDC clocking
+ *
+ * Parameters:
+ * priv - A reference to the private driver state structure
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void sam_mdcclock(struct sam_gmac_s *priv)
+{
+ uint32_t ncfgr;
+ uint32_t ncr;
+ uint32_t enables;
+
+ /* Disable RX and TX momentarily */
+
+ ncr = sam_getreg(priv, SAM_GMAC_NCR);
+ enables = ncr & (GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+ ncr &= ~(GMAC_NCR_RXEN | GMAC_NCR_TXEN);
+ sam_putreg(priv, SAM_GMAC_NCR, ncr);
+
+ /* Modify the NCFGR register based on the configured board MCK frequency */
+
+ ncfgr = sam_getreg(priv, SAM_GMAC_NCFGR);
+ ncfgr &= ~GMAC_NCFGR_CLK_MASK;
+
+#if BOARD_MCK_FREQUENCY <= 20000000
+ ncfgr = GMAC_NCFGR_CLK_DIV8; /* MCK divided by 8 (MCK up to 20 MHz) */
+#elif BOARD_MCK_FREQUENCY <= 40000000
+ ncfgr = GMAC_NCFGR_CLK_DIV16; /* MCK divided by 16 (MCK up to 40 MHz) */
+#elif BOARD_MCK_FREQUENCY <= 80000000
+ ncfgr = GMAC_NCFGR_CLK_DIV32; /* MCK divided by 32 (MCK up to 80 MHz) */
+#elif BOARD_MCK_FREQUENCY <= 120000000
+ ncfgr = GMAC_NCFGR_CLK_DIV48; /* MCK divided by 48 (MCK up to 120 MHz) */
+#elif BOARD_MCK_FREQUENCY <= 160000000
+ ncfgr = GMAC_NCFGR_CLK_DIV64; /* MCK divided by 64 (MCK up to 160 MHz) */
+#elif BOARD_MCK_FREQUENCY <= 240000000
+ ncfgr = GMAC_NCFGR_CLK_DIV96; /* MCK divided by 64 (MCK up to 240 MHz) */
+#else
+# error Invalid BOARD_MCK_FREQUENCY
+#endif
+
+ sam_putreg(priv, SAM_GMAC_NCFGR, ncfgr);
+
+ /* Restore RX and TX enable settings */
+
+ ncr |= enables;
+ sam_putreg(priv, SAM_GMAC_NCR, ncr);
+}
+
+/****************************************************************************
* Function: sam_phyinit
*
* Description:
@@ -2439,27 +2543,11 @@ errout:
static int sam_phyinit(struct sam_gmac_s *priv)
{
- uint32_t regval;
int ret;
/* Configure PHY clocking */
- regval = sam_getreg(priv, SAM_GMAC_NCFGR);
- regval &= ~GMAC_NCFGR_CLK_MASK;
-
-#if BOARD_MCK_FREQUENCY > (160*1000*1000)
-# error Supported MCK frequency
-#elif BOARD_MCK_FREQUENCY > (80*1000*1000)
- regval |= GMAC_NCFGR_CLK_DIV64; /* MCK divided by 64 (MCK up to 160 MHz) */
-#elif BOARD_MCK_FREQUENCY > (40*1000*1000)
- regval |= GMAC_NCFGR_CLK_DIV32; /* MCK divided by 32 (MCK up to 80 MHz) */
-#elif BOARD_MCK_FREQUENCY > (20*1000*1000)
- regval |= GMAC_NCFGR_CLK_DIV16; /* MCK divided by 16 (MCK up to 40 MHz) */
-#else
- regval |= GMAC_NCFGR_CLK_DIV8; /* MCK divided by 8 (MCK up to 20 MHz) */
-#endif
-
- sam_putreg(priv, SAM_GMAC_NCFGR, regval);
+ sam_mdcclock(priv);
/* Check the PHY Address */
@@ -2497,41 +2585,27 @@ static int sam_phyinit(struct sam_gmac_s *priv)
static inline void sam_ethgpioconfig(struct sam_gmac_s *priv)
{
- /* Configure PIO pins to support GMAC */
- /* Configure GMAC PIO pins common to both MII and RMII */
-#warning REVISIT: Do we need all of these?
+ /* Configure PIO pins to support GMAC in RGMII mode */
+
sam_configpio(PIO_GMAC_TX0);
sam_configpio(PIO_GMAC_TX1);
-#if 0
sam_configpio(PIO_GMAC_TX2);
sam_configpio(PIO_GMAC_TX3);
- sam_configpio(PIO_GMAC_TX4);
- sam_configpio(PIO_GMAC_TX5);
- sam_configpio(PIO_GMAC_TX6);
- sam_configpio(PIO_GMAC_TX7);
-#endif
+
sam_configpio(PIO_GMAC_RX0);
sam_configpio(PIO_GMAC_RX1);
-#if 0
sam_configpio(PIO_GMAC_RX2);
sam_configpio(PIO_GMAC_RX3);
- sam_configpio(PIO_GMAC_RX4);
- sam_configpio(PIO_GMAC_RX5);
- sam_configpio(PIO_GMAC_RX6);
- sam_configpio(PIO_GMAC_RX7);
-#endif
- sam_configpio(PIO_GMAC_TXEN);
- sam_configpio(PIO_GMAC_TXER);
+
sam_configpio(PIO_GMAC_TXCK);
+ sam_configpio(PIO_GMAC_TXEN);
sam_configpio(PIO_GMAC_RXCK);
sam_configpio(PIO_GMAC_RXDV);
sam_configpio(PIO_GMAC_RXER);
- sam_configpio(PIO_GMAC_125CK);
- sam_configpio(PIO_GMAC_125CKO);
- sam_configpio(PIO_GMAC_COL);
- sam_configpio(PIO_GMAC_CRS);
+
sam_configpio(PIO_GMAC_MDC);
sam_configpio(PIO_GMAC_MDIO);
+ sam_configpio(PIO_GMAC_125CK);
}
/****************************************************************************
diff --git a/nuttx/drivers/net/Kconfig b/nuttx/drivers/net/Kconfig
index c13848021..923cb4eec 100644
--- a/nuttx/drivers/net/Kconfig
+++ b/nuttx/drivers/net/Kconfig
@@ -200,6 +200,9 @@ config ETH0_PHY_KS8721
config ETH0_PHY_KSZ8051
bool "Micrel KSZ8051 PHY"
+config ETH0_PHY_KSZ90x1
+ bool "Micrel KSZ9021/31 PHY"
+
config ETH0_PHY_DP83848C
bool "National Semiconduction DP83848C PHY"
@@ -228,6 +231,9 @@ config ETH1_PHY_KS8721
config ETH1_PHY_KSZ8051
bool "Micrel KSZ8051 PHY"
+config ETH1_PHY_KSZ90x1
+ bool "Micrel KSZ9021/31 PHY"
+
config ETH1_PHY_DP83848C
bool "National Semiconduction DP83848C PHY"
diff --git a/nuttx/include/nuttx/net/gmii.h b/nuttx/include/nuttx/net/gmii.h
new file mode 100644
index 000000000..1b7f3b2bf
--- /dev/null
+++ b/nuttx/include/nuttx/net/gmii.h
@@ -0,0 +1,261 @@
+/*********************************************************************************************
+ * include/nuttx/net/gmii.h
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ *********************************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_NET_GMII_H
+#define __INCLUDE_NUTTX_NET_GMII_H
+
+/*********************************************************************************************
+ * Included Files
+ *********************************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/net/mii.h>
+
+/*********************************************************************************************
+ * Pre-Processor Definitions
+ *********************************************************************************************/
+
+/* MII register offsets **********************************************************************/
+
+/* Common MII management registers. The IEEE 802.3 standard specifies a
+ * register set for controlling and gathering status from the PHY layer. The
+ * registers are collectively known as the MII Management registers and are
+ * detailed in Section 22.2.4 of the IEEE 802.3 specification.
+ */
+
+#define GMII_MCR MII_MCR /* GMII management control */
+#define GMII_MSR MII_MSR /* GMII management status */
+#define GMII_PHYID1 MII_PHYID1 /* PHY ID 1 */
+#define GMII_PHYID2 MII_PHYID2 /* PHY ID 2 */
+#define GMII_ADVERTISE MII_ADVERTISE /* Auto-negotiation advertisement */
+#define GMII_LPA MII_LPA /* Auto-negotiation link partner base page ability */
+#define GMII_EXPANSION MII_EXPANSION /* Auto-negotiation expansion */
+#define GMII_NEXTPAGE MII_NEXTPAGE /* Auto-negotiation next page */
+#define GMII_LPANEXTPAGE MII_LPANEXTPAGE /* Auto-negotiation link partner received next page */
+#define GMII_CTRL1000 9 /* 1000BASE-T control */
+#define GMII_STAT1000 10 /* 1000BASE-T status */
+#define GMII_PSECR 11 /* PSE Control register */
+#define GMII_ERDWR 12 /* Extend Register - Data Write Register */
+#define GMII_ERDRR 13 /* Extend Register - Data Read Register */
+#define GMII_ESTATUS MII_ESTATUS /* Extended MII status register */
+
+/* Extended Registers: Registers 16-31 may be used for vendor specific abilities */
+
+/* Micrel KSZ9021/31 Vendor Specific Registers */
+
+#define GMII_KSZ90x1_RLPBK 17 /* Remote loopback, LED mode */
+#define GMII_KSZ90x1_LINKMD 18 /* LinkMD(c) cable diagnostic */
+#define GMII_KSZ90x1_PMAPCS 19 /* Digital PMA/PCS status */
+#define GMII_KSZ90x1_RXERR 21 /* RXER counter */
+#define GMII_KSZ90x1_ICS 27 /* Interrupt control/status */
+#define GMII_KSZ90x1_DBGCTRL1 28 /* Digital debug control 1 */
+#define GMII_KSZ90x1_PHYCTRL 31 /* PHY control */
+
+/* Micrel KSZ9021/31 Extended registers */
+
+#define GMII_KSZ90x1_CCR 256 /* Common control */
+#define GMII_KSZ90x1_SSR 257 /* Strap status */
+#define GMII_KSZ90x1_OMSOR 258 /* Operation mode strap override */
+#define GMII_KSZ90x1_OMSSR 259 /* Operation mode strap status */
+#define GMII_KSZ90x1_RCCPSR 260 /* RGMII clock and control pad skew */
+#define GMII_KSZ90x1_RRDPSR 261 /* RGMII RX data pad skew */
+#define GMII_KSZ90x1_ATR 263 /* Analog test register */
+
+/* MII register bit settings *****************************************************************/
+
+/* MII Control register bit definitions */
+
+#define GMII_MCR_UNIDIR MII_MCR_UNIDIR
+#define GMII_MCR_SPEED1000 MII_MCR_SPEED1000
+#define GMII_MCR_CTST MII_MCR_CTST
+#define GMII_MCR_FULLDPLX MII_MCR_FULLDPLX
+#define GMII_MCR_ANRESTART MII_MCR_ANRESTART
+#define GMII_MCR_ISOLATE MII_MCR_ISOLATE
+#define GMII_MCR_PDOWN MII_MCR_PDOWN
+#define GMII_MCR_ANENABLE MII_MCR_ANENABLE
+#define GMII_MCR_SPEED100 MII_MCR_SPEED100
+#define GMII_MCR_LOOPBACK MII_MCR_LOOPBACK
+#define GMII_MCR_RESET MII_MCR_RESET
+
+/* MII Status register bit definitions */
+
+#define GMII_MSR_EXTCAP MII_MSR_EXTCAP
+#define GMII_MSR_JABBERDETECT MII_MSR_JABBERDETECT
+#define GMII_MSR_LINKSTATUS MII_MSR_LINKSTATUS
+#define GMII_MSR_ANEGABLE MII_MSR_ANEGABLE
+#define GMII_MSR_RFAULT MII_MSR_RFAULT
+#define GMII_MSR_ANEGCOMPLETE MII_MSR_ANEGCOMPLETE
+#define GMII_MSR_UNIDIR MII_MSR_UNIDIR
+#define GMII_MSR_MFRAMESUPPRESS MII_MSR_MFRAMESUPPRESS
+#define GMII_MSR_ESTATEN MII_MSR_ESTATEN
+#define GMII_MSR_100BASET2FULL MII_MSR_100BASET2FULL
+#define GMII_MSR_100BASET2HALF MII_MSR_100BASET2HALF
+#define GMII_MSR_10BASETXHALF MII_MSR_10BASETXHALF
+#define GMII_MSR_10BASETXFULL MII_MSR_10BASETXFULL
+#define GMII_MSR_100BASETXHALF MII_MSR_100BASETXHALF
+#define GMII_MSR_100BASETXFULL MII_MSR_100BASETXFULL
+#define GMII_MSR_100BASET4 MII_MSR_100BASET4
+
+/* MII ID2 register bits */
+
+#define GMII_PHYID2_OUI MII_PHYID2_OUI
+#define GMII_PHYID2_MODEL MII_PHYID2_MODEL
+#define GMII_PHYID2_REV MII_PHYID2_REV
+
+/* Advertisement control register bit definitions */
+
+#define GMII_ADVERTISE_SELECT MII_ADVERTISE_SELECT
+#define GMII_ADVERTISE_CSMA MII_ADVERTISE_CSMA
+#define GMII_ADVERTISE_8023 MII_ADVERTISE_8023
+#define GMII_ADVERTISE_8029 MII_ADVERTISE_8029
+#define GMII_ADVERTISE_8025 MII_ADVERTISE_8025
+#define GMII_ADVERTISE_1394 MII_ADVERTISE_1394
+#define GMII_ADVERTISE_10BASETXHALF MII_ADVERTISE_10BASETXHALF
+#define GMII_ADVERTISE_1000XFULL MII_ADVERTISE_1000XFULL
+#define GMII_ADVERTISE_10BASETXFULL MII_ADVERTISE_10BASETXFULL
+#define GMII_ADVERTISE_1000XHALF MII_ADVERTISE_1000XHALF
+#define GMII_ADVERTISE_100BASETXHALF MII_ADVERTISE_100BASETXHALF
+#define GMII_ADVERTISE_1000XPAUSE MII_ADVERTISE_1000XPAUSE
+#define GMII_ADVERTISE_100BASETXFULL MII_ADVERTISE_100BASETXFULL
+#define GMII_ADVERTISE_1000XASYMPAU MII_ADVERTISE_1000XASYMPAU
+#define GMII_ADVERTISE_100BASET4 MII_ADVERTISE_100BASET4
+#define GMII_ADVERTISE_FDXPAUSE MII_ADVERTISE_FDXPAUSE
+#define GMII_ADVERTISE_ASYMPAUSE MII_ADVERTISE_ASYMPAUSE
+#define GMII_ADVERTISE_RFAULT MII_ADVERTISE_RFAULT
+#define GMII_ADVERTISE_LPACK MII_ADVERTISE_LPACK
+#define GMII_ADVERTISE_NXTPAGE MII_ADVERTISE_NXTPAGE
+
+/* Link partner ability register bit definitions */
+
+#define GMII_LPA_SELECT MII_LPA_SELECT
+#define GMII_LPA_CSMA MII_LPA_CSMA
+#define GMII_LPA_8023 MII_LPA_8023
+#define GMII_LPA_8029 MII_LPA_8029
+#define GMII_LPA_8025 MII_LPA_8025
+#define GMII_LPA_8025 MII_LPA_1394
+#define GMII_LPA_1394 MII_LPA_1394
+#define GMII_LPA_10BASETXHALF MII_LPA_10BASETXHALF
+#define GMII_LPA_1000XFULL MII_LPA_1000XFULL
+#define GMII_LPA_1000XFULL MII_LPA_10BASETXFULL
+#define GMII_LPA_10BASETXFULL MII_LPA_10BASETXFULL
+#define GMII_LPA_1000XHALF MII_LPA_1000XHALF
+#define GMII_LPA_100BASETXHALF MII_LPA_100BASETXHALF
+#define GMII_LPA_1000XPAUSE MII_LPA_1000XPAUSE
+#define GMII_LPA_100BASETXFULL MII_LPA_100BASETXFULL
+#define GMII_LPA_1000XASYMPAU MII_LPA_1000XASYMPAU
+#define GMII_LPA_100BASET4 MII_LPA_100BASET4
+#define GMII_LPA_FDXPAUSE MII_LPA_FDXPAUSE
+#define GMII_LPA_ASYMPAUSE MII_LPA_ASYMPAUSE
+#define GMII_LPA_RFAULT MII_LPA_RFAULT
+#define GMII_LPA_LPACK MII_LPA_LPACK
+#define GMII_LPA_NXTPAGE MII_LPA_NXTPAGE
+
+/* Link partner ability in next page format */
+
+#define GMII_LPANP_MESSAGE MII_LPANP_MESSAGE
+#define GMII_LPANP_TOGGLE MII_LPANP_TOGGLE
+#define GMII_LPANP_LACK2 MII_LPANP_LACK2
+#define GMII_LPANP_MSGPAGE MII_LPANP_MSGPAGE
+#define GMII_LPANP_LPACK MII_LPANP_LPACK
+#define GMII_LPANP_NXTPAGE MII_LPANP_NXTPAGE
+
+/* MII Auto-negotiation expansion register bit definitions */
+
+#define GMII_EXPANSION_ANEGABLE MII_EXPANSION_ANEGABLE
+#define GMII_EXPANSION_PAGERECVD MII_EXPANSION_PAGERECVD
+#define GMII_EXPANSION_ENABLENPAGE MII_EXPANSION_ENABLENPAGE
+#define GMII_EXPANSION_NXTPAGEABLE MII_EXPANSION_NXTPAGEABLE
+#define GMII_EXPANSION_PARFAULTS MII_EXPANSION_PARFAULTS
+
+/* Auto-negotiation next page advertisement */
+
+#define GMII_NPADVERTISE_CODE MII_NPADVERTISE_CODE
+#define GMII_NPADVERTISE_TOGGLE MII_NPADVERTISE_TOGGLE
+#define GMII_NPADVERTISE_ACK2 MII_NPADVERTISE_ACK2
+#define GMII_NPADVERTISE_MSGPAGE MII_NPADVERTISE_MSGPAGE
+#define GMII_NPADVERTISE_NXTPAGE MII_NPADVERTISE_NXTPAGE
+
+/* MMD access control register */
+
+#define GMII_MMDCONTROL_DEVAD_SHIFT MII_MMDCONTROL_DEVAD_SHIFT
+#define GMII_MMDCONTROL_DEVAD_MASK MII_MMDCONTROL_DEVAD_MASK
+# define GMII_MMDCONTROL_DEVAD(n) MII_MMDCONTROL_DEVAD(n)
+#define GMII_MMDCONTROL_FUNC_SHIFT MII_MMDCONTROL_FUNC_SHIFT
+#define GMII_MMDCONTROL_FUNC_MASK MII_MMDCONTROL_FUNC_MASK
+# define GMII_MMDCONTROL_FUNC_ADDR MII_MMDCONTROL_FUNC_ADDR
+# define GMII_MMDCONTROL_FUNC_NOINCR MII_MMDCONTROL_FUNC_NOINCR
+# define GMII_MMDCONTROL_FUNC_RWINCR MII_MMDCONTROL_FUNC_RWINCR
+# define GMII_MMDCONTROL_FUNC_WINCR MII_MMDCONTROL_FUNC_WINCR
+
+/* Extended status register */
+
+#define GMII_ESTATUS_1000BASETHALF MII_ESTATUS_1000BASETHALF
+#define GMII_ESTATUS_1000BASETFULL MII_ESTATUS_1000BASETFULL
+#define GMII_ESTATUS_1000BASEXHALF MII_ESTATUS_1000BASEXHALF
+#define GMII_ESTATUS_1000BASEXFULL MII_ESTATUS_1000BASEXFULL
+
+/* Extend Register - Data Write Register */
+
+#define GMII_ERDWR_ADDR_SHIFT (0) /* Bits 0-7: Select extended register address */
+#define GMII_ERDWR_ADDR_MASK (0xff << GMII_ERDWR_ADDR_SHIFT)
+# define GMII_ERDWR_ADDR(n) ((n) << GMII_ERDWR_ADDR_SHIFT)
+#define GMII_ERDWR_PAGE (1 << 8) /* Bit 8: Select page for extended register */
+ /* Bits 9-14: Reserved */
+#define GMII_ERDWR_READ (0) /* Bit 15: 0=Read extended register */
+#define GMII_ERDWR_WRITE (1 << 15) /* Bit 15: 1=Write extended register */
+
+/* Extend Register - Data Read Register (16-bit data value) */
+
+/*********************************************************************************************
+ * Type Definitions
+ *********************************************************************************************/
+
+/*********************************************************************************************
+ * Public Function Prototypes
+ *********************************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_NUTTX_NET_GMII_H */
diff --git a/nuttx/include/nuttx/net/mii.h b/nuttx/include/nuttx/net/mii.h
index 5ad39aa77..411d51384 100644
--- a/nuttx/include/nuttx/net/mii.h
+++ b/nuttx/include/nuttx/net/mii.h
@@ -1,7 +1,7 @@
/****************************************************************************
* include/nuttx/net/mii.h
*
- * Copyright (C) 2008-2010, 2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2008-2010, 2012-2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -164,21 +164,6 @@
#define MII_LAN8720_IMR 0x1e /* Interrupt Mask Register */
#define MII_LAN8720_SCSR 0x1f /* PHY Special Control/Status Register */
-/* GMII */
-
-#define GMII_MCR MII_MCR /* GMII management control */
-#define GMII_MSR MII_MSR /* GMII management status */
-#define GMII_PHYID1 MII_PHYID1 /* PHY ID 1 */
-#define GMII_PHYID2 MII_PHYID2 /* PHY ID 2 */
-#define GMII_ADVERTISE MII_ADVERTISE /* Auto-negotiation advertisement */
-#define GMII_LPA MII_LPA /* Auto-negotiation link partner base page ability */
-#define GMII_EXPANSION MII_EXPANSION /* Auto-negotiation expansion */
-#define GMII_NEXTPAGE MII_NEXTPAGE /* Auto-negotiation next page */
-#define GMII_LPANEXTPAGE MII_LPANEXTPAGE /* Auto-negotiation link partner received next page */
-#define GMII_CTRL1000 0x09 /* 1000BASE-T control */
-#define GMII_STAT1000 0x0a /* 1000BASE-T status */
-#define GMII_ESTATUS MII_ESTATUS /* Extended status register */
-
/* MII register bit settings ************************************************/
/* MII Control register bit definitions */
@@ -204,6 +189,7 @@
#define MII_MSR_RFAULT (1 << 4) /* Bit 4: Remote fault */
#define MII_MSR_ANEGCOMPLETE (1 << 5) /* Bit 5: Auto-negotiation complete */
#define MII_MSR_MFRAMESUPPRESS (1 << 6) /* Bit 6: Management frame suppression */
+#define MII_MSR_UNIDIR (1 << 7) /* Bit 7: Unidirectional ability */
#define MII_MSR_ESTATEN (1 << 8) /* Bit 8: Extended Status in R15 */
#define MII_MSR_100BASET2FULL (1 << 9) /* Bit 9: 100BASE-T2 half duplex able */
#define MII_MSR_100BASET2HALF (1 << 10) /* Bit 10: 100BASE-T2 full duplex able */
@@ -213,11 +199,12 @@
#define MII_MSR_100BASETXFULL (1 << 14) /* Bit 14: 100BASE-TX full duplex able */
#define MII_MSR_100BASET4 (1 << 15) /* Bit 15: 100BASE-T4 able */
+/* MII ID1 register bits: Bits 3-18 of the Organizationally Unique identifier (OUI) */
/* MII ID2 register bits */
-#define MII_PHYID2_OUI 0xfc00 /* Bits 19-24 of OUI mask */
-#define MII_PHYID2_MODEL 0x03f0 /* Model number mask */
-#define MII_PHYID2_REV 0x000f /* Revision number mask */
+#define MII_PHYID2_OUI 0xfc00 /* Bits 10-15: OUI mask [24:19] */
+#define MII_PHYID2_MODEL 0x03f0 /* Bits 4-9: Model number mask */
+#define MII_PHYID2_REV 0x000f /* Bits 0-3: Revision number mask */
/* Advertisement control register bit definitions */
@@ -290,6 +277,26 @@
#define MII_NPADVERTISE_MSGPAGE (1 << 13) /* Bit 13: Message page */
#define MII_NPADVERTISE_NXTPAGE (1 << 15) /* Bit 15: Next page indication */
+/* MMD access control register */
+
+#define MII_MMDCONTROL_DEVAD_SHIFT (0) /* Bits 0-4: Device address */
+#define MII_MMDCONTROL_DEVAD_MASK (31 << MII_MMDCONTROL_DEVAD_SHIFT)
+# define MII_MMDCONTROL_DEVAD(n) ((n) << MII_MMDCONTROL_DEVAD_SHIFT)
+ /* Bits 5-13: Reserved */
+#define MII_MMDCONTROL_FUNC_SHIFT (14) /* Bits 14-15: Function */
+#define MII_MMDCONTROL_FUNC_MASK (3 << MII_MMDCONTROL_FUNC_SHIFT)
+# define MII_MMDCONTROL_FUNC_ADDR (0 << MII_MMDCONTROL_FUNC_SHIFT) /* Address */
+# define MII_MMDCONTROL_FUNC_NOINCR (1 << MII_MMDCONTROL_FUNC_SHIFT) /* Data, no post increment */
+# define MII_MMDCONTROL_FUNC_RWINCR (2 << MII_MMDCONTROL_FUNC_SHIFT) /* Data, post incr on reads & writes */
+# define MII_MMDCONTROL_FUNC_WINCR (3 << MII_MMDCONTROL_FUNC_SHIFT) /* Data, post incr on writes */
+
+/* Extended status register */
+ /* Bits 0-11: Reserved */
+#define MII_ESTATUS_1000BASETHALF (1 << 12) /* Bit 12: 1000BASE-T Half Duplex able */
+#define MII_ESTATUS_1000BASETFULL (1 << 13) /* Bit 13: 1000BASE-T Full Duplex able */
+#define MII_ESTATUS_1000BASEXHALF (1 << 14) /* Bit 14: 1000BASE-X Half Duplex able */
+#define MII_ESTATUS_1000BASEXFULL (1 << 15) /* Bit 15: 1000BASE-X Full Duplex able */
+
/* MII PHYADDR register bit definitions */
#define DP83840_PHYADDR_DUPLEX (1 << 7)