From f624c504d107a3629b9f044c954f85284098c61e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 31 Dec 2017 14:49:13 -0600 Subject: [PATCH] arch/arm/src/lpc54xx: Fixes a few more Ethernet bring up bugs. Rx seems to work; Tx does not. --- arch/arm/src/lpc54xx/chip/lpc54_ethernet.h | 40 ++++++++++----------- arch/arm/src/lpc54xx/lpc54_ethernet.c | 32 ++++++++++++----- configs/lpcxpresso-lpc54628/include/board.h | 4 +-- 3 files changed, 46 insertions(+), 30 deletions(-) diff --git a/arch/arm/src/lpc54xx/chip/lpc54_ethernet.h b/arch/arm/src/lpc54xx/chip/lpc54_ethernet.h index 46ab007853..1514d159ae 100644 --- a/arch/arm/src/lpc54xx/chip/lpc54_ethernet.h +++ b/arch/arm/src/lpc54xx/chip/lpc54_ethernet.h @@ -121,7 +121,7 @@ #define LPC54_ETH_DMA_INTR_STAT_OFFSET 0x1008 /* DMA interrupt status */ #define LPC54_ETH_DMA_DBG_STAT_OFFSET 0x100c /* DMA debug status */ -#define LPC54_ETH_DMACH_CTRLn_OFFSET(n) (0x1100 + ((n) << 7)) +#define LPC54_ETH_DMACH_OFFSET(n) (0x1100 + ((n) << 7)) #define LPC54_ETH_DMACH_CTRL_OFFSET 0x0000 /* DMA channel n control */ #define LPC54_ETH_DMACH_TX_CTRL_OFFSET 0x0004 /* DMA channel n transmit control */ @@ -216,26 +216,26 @@ #define LPC54_ETH_DMA_INTR_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_INTR_STAT_OFFSET) #define LPC54_ETH_DMA_DBG_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_DBG_STAT_OFFSET) -#define LPC54_ETH_DMACH_CTRL_BASE(n) (LPC54_ETHERNET_BASE + LPC54_ETH_DMACH_CTRLn_OFFSET(n)) +#define LPC54_ETH_DMACH_BASE(n) (LPC54_ETHERNET_BASE + LPC54_ETH_DMACH_OFFSET(n)) -#define LPC54_ETH_DMACH_CTRL(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_CTRL_OFFSET) -#define LPC54_ETH_DMACH_TX_CTRL(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_TX_CTRL_OFFSET) -#define LPC54_ETH_DMACH_RX_CTRL(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_RX_CTRL_OFFSET) -#define LPC54_ETH_DMACH_TXDESC_LIST_ADDR(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_TXDESC_LIST_ADDR_OFFSET) -#define LPC54_ETH_DMACH_RXDESC_LIST_ADDR(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_RXDESC_LIST_ADDR_OFFSET) -#define LPC54_ETH_DMACH_TXDESC_TAIL_PTR(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_TXDESC_TAIL_PTR_OFFSET) -#define LPC54_ETH_DMACH_RXDESC_TAIL_PTR(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_RXDESC_TAIL_PTR_OFFSET) -#define LPC54_ETH_DMACH_TXDESC_RING_LENGTH(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_TXDESC_RING_LENGTH_OFFSET) -#define LPC54_ETH_DMACH_RXDESC_RING_LENGTH(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_RXDESC_RING_LENGTH_OFFSET) -#define LPC54_ETH_DMACH_INT_EN(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_INT_EN_OFFSET) -#define LPC54_ETH_DMACH_RX_INT_WDTIMER(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_RX_INT_WDTIMER_OFFSET) -#define LPC54_ETH_DMACH_SLOT_FUNC_CTRL_STAT(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_SLOT_FUNC_CTRL_STAT_OFFSET) -#define LPC54_ETH_DMACH_CUR_HST_TXDESC(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_CUR_HST_TXDESC_OFFSET) -#define LPC54_ETH_DMACH_CUR_HST_RXDESC(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_CUR_HST_RXDESC_OFFSET) -#define LPC54_ETH_DMACH_CUR_HST_TXBUF(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_CUR_HST_TXBUF_OFFSET) -#define LPC54_ETH_DMACH_CUR_HST_RXBUF(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_CUR_HST_RXBUF_OFFSET) -#define LPC54_ETH_DMACH_STAT(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_STAT_OFFSET) -#define LPC54_ETH_DMACH_MISS_FRAME_CNT(n) (LPC54_ETH_DMACH_CTRL_BASE(n) + LPC54_ETH_DMACH_MISS_FRAME_CNT_OFFSET) +#define LPC54_ETH_DMACH_CTRL(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_CTRL_OFFSET) +#define LPC54_ETH_DMACH_TX_CTRL(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_TX_CTRL_OFFSET) +#define LPC54_ETH_DMACH_RX_CTRL(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_RX_CTRL_OFFSET) +#define LPC54_ETH_DMACH_TXDESC_LIST_ADDR(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_TXDESC_LIST_ADDR_OFFSET) +#define LPC54_ETH_DMACH_RXDESC_LIST_ADDR(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_RXDESC_LIST_ADDR_OFFSET) +#define LPC54_ETH_DMACH_TXDESC_TAIL_PTR(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_TXDESC_TAIL_PTR_OFFSET) +#define LPC54_ETH_DMACH_RXDESC_TAIL_PTR(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_RXDESC_TAIL_PTR_OFFSET) +#define LPC54_ETH_DMACH_TXDESC_RING_LENGTH(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_TXDESC_RING_LENGTH_OFFSET) +#define LPC54_ETH_DMACH_RXDESC_RING_LENGTH(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_RXDESC_RING_LENGTH_OFFSET) +#define LPC54_ETH_DMACH_INT_EN(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_INT_EN_OFFSET) +#define LPC54_ETH_DMACH_RX_INT_WDTIMER(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_RX_INT_WDTIMER_OFFSET) +#define LPC54_ETH_DMACH_SLOT_FUNC_CTRL_STAT(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_SLOT_FUNC_CTRL_STAT_OFFSET) +#define LPC54_ETH_DMACH_CUR_HST_TXDESC(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_CUR_HST_TXDESC_OFFSET) +#define LPC54_ETH_DMACH_CUR_HST_RXDESC(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_CUR_HST_RXDESC_OFFSET) +#define LPC54_ETH_DMACH_CUR_HST_TXBUF(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_CUR_HST_TXBUF_OFFSET) +#define LPC54_ETH_DMACH_CUR_HST_RXBUF(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_CUR_HST_RXBUF_OFFSET) +#define LPC54_ETH_DMACH_STAT(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_STAT_OFFSET) +#define LPC54_ETH_DMACH_MISS_FRAME_CNT(n) (LPC54_ETH_DMACH_BASE(n) + LPC54_ETH_DMACH_MISS_FRAME_CNT_OFFSET) /* Register bit definitions *********************************************************************************/ diff --git a/arch/arm/src/lpc54xx/lpc54_ethernet.c b/arch/arm/src/lpc54xx/lpc54_ethernet.c index 004613e8c9..09c2479ac3 100644 --- a/arch/arm/src/lpc54xx/lpc54_ethernet.c +++ b/arch/arm/src/lpc54xx/lpc54_ethernet.c @@ -596,7 +596,7 @@ static int lpc54_eth_transmit(struct lpc54_ethdriver_s *priv, DEBUGASSERT(priv->eth_dev.d_buf != 0 && priv->eth_dev.d_len > 0 && priv->eth_dev.d_len <= LPC54_BUFFER_SIZE && - txring->tr_ndesc < txring->tr_inuse); + txring->tr_inuse < txring->tr_ndesc); /* Fill the descriptor. */ @@ -604,6 +604,9 @@ static int lpc54_eth_transmit(struct lpc54_ethdriver_s *priv, buffer = priv->eth_dev.d_buf; buflen = priv->eth_dev.d_len; + priv->eth_dev.d_buf = NULL; + priv->eth_dev.d_len = 0; + if (buflen <= LPC54_BUFFER_MAX) { /* Prepare the Tx descriptor for transmission */ @@ -794,7 +797,9 @@ static int lpc54_eth_txpoll(struct net_driver_s *dev) chan = lpc54_eth_getring(priv); txring = &priv->eth_txring[chan]; - (txring->tr_buffers)[txring->tr_supply] = (uint32_t *)priv->eth_dev.d_buf; + + (txring->tr_buffers)[txring->tr_supply] = + (uint32_t *)priv->eth_dev.d_buf; lpc54_eth_transmit(priv, chan); @@ -911,7 +916,9 @@ static void lpc54_eth_rxdisptch(struct lpc54_ethdriver_s *priv) chan = lpc54_eth_getring(priv); txring = &priv->eth_txring[chan]; - (txring->tr_buffers)[txring->tr_supply] = (uint32_t *)priv->eth_dev.d_buf; + + (txring->tr_buffers)[txring->tr_supply] = + (uint32_t *)priv->eth_dev.d_buf; lpc54_eth_transmit(priv, chan); } @@ -953,7 +960,9 @@ static void lpc54_eth_rxdisptch(struct lpc54_ethdriver_s *priv) chan = lpc54_eth_getring(priv); txring = &priv->eth_txring[chan]; - (txring->tr_buffers)[txring->tr_supply] = (uint32_t *)priv->eth_dev.d_buf; + + (txring->tr_buffers)[txring->tr_supply] = + (uint32_t *)priv->eth_dev.d_buf; lpc54_eth_transmit(priv, chan); } @@ -974,7 +983,9 @@ static void lpc54_eth_rxdisptch(struct lpc54_ethdriver_s *priv) { chan = lpc54_eth_getring(priv); txring = &priv->eth_txring[chan]; - (txring->tr_buffers)[txring->tr_supply] = (uint32_t *)priv->eth_dev.d_buf; + + (txring->tr_buffers)[txring->tr_supply] = + (uint32_t *)priv->eth_dev.d_buf; lpc54_eth_transmit(priv, chan); } @@ -1801,7 +1812,10 @@ static int lpc54_eth_ifup(struct net_driver_s *dev) } /* Initialize Ethernet DMA ************************************************/ - /* Reset DMA */ + /* Reset DMA. Resets the logic and all internal registers of the OMA, MTL, + * and MAC. This bit is automatically cleared after the reset operation + * is complete in all Ethernet Block clock domains. + */ regval = lpc54_getreg(LPC54_ETH_DMA_MODE); regval |= ETH_DMA_MODE_SWR; @@ -2957,8 +2971,9 @@ int up_netinitialize(int intf) #else /* RMII interface. * - * REF_CLK may be available in some implementations - * RX_ER is optional on switches + * REF_CLK may be available in some implementations. Clocking from + * PHY appears to be necessary for DMA reset operations. + * RX_ER is optional on switches. */ lpc54_gpio_config(GPIO_ENET_RXD0); /* Ethernet receive data 0-1 */ @@ -2967,6 +2982,7 @@ int up_netinitialize(int intf) lpc54_gpio_config(GPIO_ENET_TXD1); lpc54_gpio_config(GPIO_ENET_RX_DV); /* Ethernet receive data valid */ lpc54_gpio_config(GPIO_ENET_TX_EN); /* Ethernet transmit data enable */ + lpc54_gpio_config(GPIO_ENET_REF_CLK); /* PHY reference clock */ #endif /* Enable clocking to the Ethernet peripheral */ diff --git a/configs/lpcxpresso-lpc54628/include/board.h b/configs/lpcxpresso-lpc54628/include/board.h index f0626bd12b..2ca923462a 100644 --- a/configs/lpcxpresso-lpc54628/include/board.h +++ b/configs/lpcxpresso-lpc54628/include/board.h @@ -404,7 +404,7 @@ * P4_10-ENET_CRS_DV Ethernet receive data valid * P4_13-ENET_TX_EN Ethernet transmit data enable * - * P4_14-ENET_RX_CLK REF_CLK, Reference clock (Not used) + * P4_14-ENET_RX_CLK REF_CLK, Reference clock * P2_26-ENET_PHY_RSTn nRST (Controlled by board logic) * * NOTE: You must set JP11 and JP12 to close 1-2 to enable Ethernet @@ -423,7 +423,7 @@ #define GPIO_ENET_RX_DV GPIO_ENET_RX_DV_2 /* P4.10 */ #define GPIO_ENET_TX_EN GPIO_ENET_TX_EN_2 /* P4.13 */ -#define GPIO_ENET_RX_CLK GPIO_ENET_RX_CLK_2 /* P4.14 */ +#define GPIO_ENET_REF_CLK GPIO_ENET_RX_CLK_2 /* P4.14 */ /**************************************************************************** * Public Types