From e4af9572d0d1d4d8b1f66ea1e00e1625d64b66f5 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 26 Sep 2013 15:55:21 -0600 Subject: [PATCH] Beginng of support for GMII/RGMII PHYs --- ChangeLog | 2 + arch/arm/src/sama5/Kconfig | 4 +- arch/arm/src/sama5/chip/sam_gmac.h | 2 +- arch/arm/src/sama5/sam_emac.c | 8 +- arch/arm/src/sama5/sam_ethernet.h | 8 + arch/arm/src/sama5/sam_gmac.c | 352 +++++++++++++++++------------ drivers/net/Kconfig | 6 + include/nuttx/net/gmii.h | 261 +++++++++++++++++++++ include/nuttx/net/mii.h | 45 ++-- 9 files changed, 524 insertions(+), 164 deletions(-) create mode 100644 include/nuttx/net/gmii.h diff --git a/ChangeLog b/ChangeLog index d8e643fc9a..6f39e782eb 100644 --- a/ChangeLog +++ b/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/arch/arm/src/sama5/Kconfig b/arch/arm/src/sama5/Kconfig index 3474c2e165..21638744f4 100644 --- a/arch/arm/src/sama5/Kconfig +++ b/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/arch/arm/src/sama5/chip/sam_gmac.h b/arch/arm/src/sama5/chip/sam_gmac.h index 6ed56589b9..ffb42aa664 100644 --- a/arch/arm/src/sama5/chip/sam_gmac.h +++ b/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/arch/arm/src/sama5/sam_emac.c b/arch/arm/src/sama5/sam_emac.c index be0df5d2ea..1c51980203 100644 --- a/arch/arm/src/sama5/sam_emac.c +++ b/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/arch/arm/src/sama5/sam_ethernet.h b/arch/arm/src/sama5/sam_ethernet.h index f48b5da6c9..605840bc9f 100644 --- a/arch/arm/src/sama5/sam_ethernet.h +++ b/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/arch/arm/src/sama5/sam_gmac.c b/arch/arm/src/sama5/sam_gmac.c index db3c8ef071..b25d74b578 100644 --- a/arch/arm/src/sama5/sam_gmac.c +++ b/arch/arm/src/sama5/sam_gmac.c @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include #include #include @@ -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,25 +1797,89 @@ 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 */ - regval = sam_getreg(priv, SAM_GMAC_NCR); - regval &= ~GMAC_NCR_MPE; - sam_putreg(priv, SAM_GMAC_NCR, regval); + 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); +} + /**************************************************************************** * 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); + + /* Check initial candidate address */ candidate = *phyaddr; - /* Check current candidate 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) { *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,13 +2467,66 @@ 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 * @@ -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/drivers/net/Kconfig b/drivers/net/Kconfig index c138480216..923cb4eec8 100644 --- a/drivers/net/Kconfig +++ b/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/include/nuttx/net/gmii.h b/include/nuttx/net/gmii.h new file mode 100644 index 0000000000..1b7f3b2bf2 --- /dev/null +++ b/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 + * + * 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 +#include + +/********************************************************************************************* + * 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/include/nuttx/net/mii.h b/include/nuttx/net/mii.h index 5ad39aa77b..411d51384d 100644 --- a/include/nuttx/net/mii.h +++ b/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 * * 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)