diff --git a/arch/arm/src/lpc54xx/Kconfig b/arch/arm/src/lpc54xx/Kconfig index 6570d216ad..8fafeea975 100644 --- a/arch/arm/src/lpc54xx/Kconfig +++ b/arch/arm/src/lpc54xx/Kconfig @@ -401,6 +401,13 @@ config LPC54_EMC bool "External Memory Controller (EMC)" default n +config LPC54_ETHERNET + bool "Ethernet" + default n + select NETDEVICES + select ARCH_HAVE_PHY + depends on EXPERIMENTAL + config LPC54_LCD bool "LCD controller" default n diff --git a/arch/arm/src/lpc54xx/Make.defs b/arch/arm/src/lpc54xx/Make.defs index 09be41eaa2..4ba8c0d6f8 100644 --- a/arch/arm/src/lpc54xx/Make.defs +++ b/arch/arm/src/lpc54xx/Make.defs @@ -136,6 +136,9 @@ ifeq ($(CONFIG_LPC54_EMC),y) CHIP_CSRCS += lpc54_emc.c endif +ifeq ($(CONFIG_LPC54_ETHERNET),y) +CHIP_CSRCS += lpc54_ethernet.c +endif ifeq ($(CONFIG_LPC54_LCD),y) CHIP_CSRCS += lpc54_lcd.c endif diff --git a/arch/arm/src/lpc54xx/chip/lpc54_ethernet.h b/arch/arm/src/lpc54xx/chip/lpc54_ethernet.h new file mode 100644 index 0000000000..df3cdc7d91 --- /dev/null +++ b/arch/arm/src/lpc54xx/chip/lpc54_ethernet.h @@ -0,0 +1,517 @@ +/************************************************************************************************************ + * arch/arm/src/lpc54xx/lpc54_ethernet.h + * + * Copyright (C) 2017 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 __ARCH_ARM_SRC_LPC54XX_CHIP_LPC54_ETHERNET_H +#define __ARCH_ARM_SRC_LPC54XX_CHIP_LPC54_ETHERNET_H + +/************************************************************************************************************ + * Included Files + ************************************************************************************************************/ + +#include +#include "chip/lpc54_memorymap.h" + +/************************************************************************************************************ + * Pre-processor Definitions + ************************************************************************************************************/ + +/* Register offsets *****************************************************************************************/ + +#define LPC54_ETH_MAC_CONFIG_OFFSET 0x0000 /* MAC configuration */ +#define LPC54_ETH_MAC_EXT_CONFIG_OFFSET 0x0004 /* MAC extended configuration */ +#define LPC54_ETH_MAC_FRAME_FILTER_OFFSET 0x0008 /* MAC frame filter */ +#define LPC54_ETH_MAC_WD_TIMEROUT_OFFSET 0x000c /* MAC watchdog timeout */ +#define LPC54_ETH_MAC_VLAN_TAG_OFFSET 0x0050 /* VLAN tag */ +#define LPC54_ETH_MAC_TX_FLOW_CTRL_Q0_OFFSET 0x0070 /* Transmit flow control 0 */ +#define LPC54_ETH_MAC_TX_FLOW_CTRL_Q1_OFFSET 0x0074 /* Transmit flow control 1 */ +#define LPC54_ETH_MAC_RX_FLOW_CTRL_OFFSET 0x0090 /* Receive flow control */ +#define LPC54_ETH_MAC_TXQ_PRIO_MAP_OFFSET 0x0098 /* Transmit Queue priority mapping */ +#define LPC54_ETH_MAC_RXQ_CTRL0_OFFSET 0x00a0 /* Receive Queue control 0 */ +#define LPC54_ETH_MAC_RXQ_CTRL1_OFFSET 0x00a4 /* Receive Queue control 1 */ +#define LPC54_ETH_MAC_RXQ_CTRL2_OFFSET 0x00a8 /* Receive Queue control 2 */ +#define LPC54_ETH_MAC_INTR_STAT_OFFSET 0x00b0 /* Interrupt status */ +#define LPC54_ETH_MAC_INTR_EN_OFFSET 0x00b4 /* Interrupt enable */ +#define LPC54_ETH_MAC_RXTX_STAT_OFFSET 0x00b8 /* Receive transmit status */ +#define LPC54_ETH_MAC_PMT_CRTL_STAT_OFFSET 0x00c0 /* MAC PMT control and status */ +#define LPC54_ETH_MAC_RWK_PKT_FLT_OFFSET 0x00c4 /* Wake-up packet filter */ +#define LPC54_ETH_MAC_LPI_CTRL_STAT_OFFSET 0x00d0 /* LPI control and status */ +#define LPC54_ETH_MAC_LPI_TIMER_CTRL_OFFSET 0x00d4 /* LPI timers control */ +#define LPC54_ETH_MAC_LPI_ENTR_TIMR_OFFSET 0x00d8 /* LPI entry timer */ +#define LPC54_ETH_MAC_1US_TIC_COUNTR_OFFSET 0x00dc /* MAC 1 usec tick counter */ +#define LPC54_ETH_MAC_VERSION_OFFSET 0x0110 /* MAC version */ +#define LPC54_ETH_MAC_DBG_OFFSET 0x0114 /* MAC debug */ +#define LPC54_ETH_MAC_HW_FEAT0_OFFSET 0x011c /* MAC hardware feature 0 */ +#define LPC54_ETH_MAC_HW_FEAT1_OFFSET 0x0120 /* MAC hardware feature 1 */ +#define LPC54_ETH_MAC_HW_FEAT2_OFFSET 0x0124 /* MAC hardware feature 2 */ + +#define LPC54_ETH_MAC_MDIO_ADDR_OFFSET 0x0200 /* MIDO address */ +#define LPC54_ETH_MAC_MDIO_DATA_OFFSET 0x0204 /* MDIO data */ +#define LPC54_ETH_MAC_ADDR_HIGH_OFFSET 0x0300 /* MAC address0 high */ +#define LPC54_ETH_MAC_ADDR_LOW_OFFSET 0x0304 /* MAC address0 low */ + +#define LPC54_ETH_MAC_TIMESTAMP_CTRL_OFFSET 0x0b00 /* Timestamp control */ +#define LPC54_ETH_MAC_SUB_SCND_INCR_OFFSET 0x0b04 /* Sub-second increment */ +#define LPC54_ETH_MAC_SYS_TIME_SCND_OFFSET 0x0b08 /* System time seconds */ +#define LPC54_ETH_MAC_SYS_TIME_NSCND_OFFSET 0x0b0c /* System time nanoseconds */ +#define LPC54_ETH_MAC_SYS_TIME_SCND_UPD_OFFSET 0x0b10 /* System time seconds update */ +#define LPC54_ETH_MAC_SYS_TIME_NSCND_UPD_OFFSET 0x0b14 /* System time nanoseconds update */ +#define LPC54_ETH_MAC_SYS_TIMESTMP_ADDEND_OFFSET 0x0b18 /* Timestamp addend */ +#define LPC54_ETH_MAC_SYS_TIME_HWORD_SCND_OFFSET 0x0b1c /* System time-higher word seconds */ +#define LPC54_ETH_MAC_SYS_TIMESTMP_STAT_OFFSET 0x0b20 /* Timestamp status */ +#define LPC54_ETH_MAC_Tx_TIMESTAMP_STATUS_NSECS_OFFSET 0x0b30 /* Tx timestamp status nanoseconds */ +#define LPC54_ETH_MAC_Tx_TIMESTAMP_STATUS_SECS_OFFSET 0x0b34 /* Tx timestamp status seconds */ +#define LPC54_ETH_MAC_TIMESTAMP_INGRESS_CORR_NSEC_OFFSET 0x0b58 /* Timestamp ingress correction */ +#define LPC54_ETH_MAC_TIMESTAMP_EGRESS_CORR_NSEC_OFFSET 0x0b5c /* Timestamp egress correction */ + +#define LPC54_ETH_MTL_OP_MODE_OFFSET 0x0c00 /* MTL operation mode */ +#define LPC54_ETH_MTL_INTR_STAT_OFFSET 0x0c20 /* MTL interrupt status */ +#define LPC54_ETH_MTL_RXQ_DMA_MAP_OFFSET 0x0c30 /* MTL Rx Queue and DMA channel mapping */ + +#define LPC54_ETH_MTL_TXQ0_OP_MODE_OFFSET 0x0d00 /* MTL TxQ0 operation mode */ +#define LPC54_ETH_MTL_TXQ0_UNDRFLW_OFFSET 0x0d04 /* MTL TxQ0 underflow */ +#define LPC54_ETH_MTL_TXQ0_DBG_OFFSET 0x0d08 /* MTL TxQ0 debug */ +#define LPC54_ETH_MTL_TXQ0_ETS_STAT_OFFSET 0x0d14 /* MTL TxQ0 ETS status */ +#define LPC54_ETH_MTL_TXQ0_QNTM_WGHT_OFFSET 0x0d18 /* Queue 0 quantum or weights */ +#define LPC54_ETH_MTL_TXQ0_INTCTRL_STAT_OFFSET 0x0d2c /* MTL TxQ0 interrupt control status */ +#define LPC54_ETH_MTL_RXQ0_OP_MODE_OFFSET 0x0d30 /* MTL RxQ0 operation mode */ +#define LPC54_ETH_MTL_RXQ0_MISSPKT_OVRFLW_CNT_OFFSET 0x0d34 /* MTL RxQ0 missed packet overflow counter */ +#define LPC54_ETH_MTL_RXQ0_DBG_OFFSET 0x0d38 /* MTL RxQ0 debug */ +#define LPC54_ETH_MTL_RXQ0_CTRL_OFFSET 0x0d3c /* MTL RxQ0 control */ +#define LPC54_ETH_MTL_TXQ1_OP_MODE_OFFSET 0x0d40 /* MTL TxQ1 operation mode */ +#define LPC54_ETH_MTL_TXQ1_UNDRFLW_OFFSET 0x0d44 /* MTL TxQ1 underflow */ +#define LPC54_ETH_MTL_TXQ1_DBG_OFFSET 0x0d48 /* MTL TxQ1 debug */ +#define LPC54_ETH_MTL_TXQ1_ETS_CTRL_OFFSET 0x0d50 /* MTL TxQ1 ETS control */ +#define LPC54_ETH_MTL_TXQ1_ETS_STAT_OFFSET 0x0d54 /* MTL TxQ1 ETS status */ +#define LPC54_ETH_MTL_TXQ1_QNTM_WGHT_OFFSET 0x0d58 /* MTL TxQ1 quantum Weight */ +#define LPC54_ETH_MTL_TXQ1_SNDSLP_CRDT_OFFSET 0x0d5c /* MTL TxQ1 SendSlopCredit */ +#define LPC54_ETH_MTL_TXQ1_HI_CRDT_OFFSET 0x0d60 /* MTL TxQ1 hiCredit */ +#define LPC54_ETH_MTL_TXQ1_LO_CRDT_OFFSET 0x0d64 /* MTL TxQ1 loCredit */ +#define LPC54_ETH_MTL_TXQ1_INTCTRL_STAT_OFFSET 0x0d6c /* MTL TxQ1 interrupt control status */ +#define LPC54_ETH_MTL_RXQ1_OP_MODE_OFFSET 0x0d70 /* MTL RxQ1 operation mode */ +#define LPC54_ETH_MTL_RXQ1_MISSPKT_OVRFLW_CNT_OFFSET 0x0d74 /* MTL RxQ1 missed packet overflow counter */ +#define LPC54_ETH_MTL_RXQ1_DBG_OFFSET 0x0d78 /* MTL RxQ1 debug */ +#define LPC54_ETH_MTL_RXQ1_CTRL_OFFSET 0x0d7c /* MTL RxQ1 control */ + +#define LPC54_ETH_DMA_MODE_OFFSET 0x1000 /* DMA mode */ +#define LPC54_ETH_DMA_SYSBUS_MODE_OFFSET 0x1004 /* DMA system bus mode */ +#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_DMA_CH0_CTRL_OFFSET 0x1100 /* DMA channel 0 control */ +#define LPC54_ETH_CH0_TX_CTRL_OFFSET 0x1104 /* DMA channel 0 transmit control */ +#define LPC54_ETH_DMA_CH0_RX_CTRL_OFFSET 0x1108 /* DMA channel 0 receive control */ +#define LPC54_ETH_DMA_CH0_TXDESC_LIST_ADDR_OFFSET 0x1114 /* Channel 0 Tx descriptor list address */ +#define LPC54_ETH_DMA_CH0_RXDESC_LIST_ADDR_OFFSET 0x111c /* Channel 0 Rx descriptor list address */ +#define LPC54_ETH_DMA_CH0_TXDESC_TAIL_PTR_OFFSET 0x1120 /* Channel 0 Tx descriptor tail pointer */ +#define LPC54_ETH_DMA_CH0_RXDESC_TAIL_PTR_OFFSET 0x1128 /* Channel 0 Rx descriptor tail pointer */ +#define LPC54_ETH_DMA_CH0_TXDESC_RING_LENGTH_OFFSET 0x112c /* Channel 0 Tx descriptor ring length */ +#define LPC54_ETH_DMA_CH0_RXDESC_RING_LENGTH_OFFSET 0x1130 /* Channel 0 Rx descriptor ring length */ +#define LPC54_ETH_DMA_CH0_INT_EN_OFFSET 0x1134 /* Channel 0 interrupt enable */ +#define LPC54_ETH_DMA_CH0_RX_INT_WDTIMER_OFFSET 0x1138 /* Receive interrupt watchdog timer */ +#define LPC54_ETH_DMA_CH0_SLOT_FUNC_CTRL_STAT_OFFSET 0x113c /** Slot function control and status */ +#define LPC54_ETH_DMA_CH0_CUR_HST_TXDESC_OFFSET 0x1144 /* Channel 0 current host transmit descriptor */ +#define LPC54_ETH_DMA_CH0_CUR_HST_RXDESC_OFFSET 0x114c /** Channel 0 current host receive descriptor */ +#define LPC54_ETH_DMA_CH0_CUR_HST_TXBUF_OFFSET 0x1154 /* Channel 0 current host transmit buffer address */ +#define LPC54_ETH_DMA_CH0_CUR_HST_RXBUF_OFFSET 0x115c /* Channel 0 current application receive buffer address */ +#define LPC54_ETH_DMA_CH0_STAT_OFFSET 0x1160 /* Channel 0 DMA status */ +#define LPC54_ETH_DMA_CH0_MISS_FRAME_CNT_OFFSET 0x116c /** Channel 0 missed frame count */ +#define LPC54_ETH_DMA_CH1_CTRL_OFFSET 0x1180 /* DMA channel 1 control */ +#define LPC54_ETH_DMA_CH1_TX_CTRL_OFFSET 0x1184 /* DMA channel 1 transmit control */ +#define LPC54_ETH_DMA_CH1_RX_CTRL_OFFSET 0x1188 /* The DMA channel 1 receive control */ +#define LPC54_ETH_DMA_CH1_TXDESC_LIST_ADDR_OFFSET 0x1194 /* The channel 1 Tx descriptor list address */ +#define LPC54_ETH_DMA_CH1_RXDESC_LIST_ADDR_OFFSET 0x119c /* The channel 1 Rx descriptor list address */ +#define LPC54_ETH_DMA_CH1_TXDESC_TAIL_PTR_OFFSET 0x11a0 /* The channel 1 Tx descriptor tail pointer */ +#define LPC54_ETH_DMA_CH1_RXDESC_TAIL_PTR_OFFSET 0x11a8 /* The channel 1 Rx descriptor tail pointer */ +#define LPC54_ETH_DMA_CH1_TXDESC_RING_LENGTH_OFFSET 0x11ac /* Channel 1 Tx descriptor ring length */ +#define LPC54_ETH_DMA_CH1_RXDESC_RING_LENGTH_OFFSET 0x11b0 /* The channel 1 Rx descriptor ring length */ +#define LPC54_ETH_DMA_CH1_INT_EN_OFFSET 0x11b4 /* The channel 1 interrupt enable */ +#define LPC54_ETH_DMA_CH1_RX_INT_WDTIMER_OFFSET 0x11b8 /* The channel 1 receive interrupt watchdog timer */ +#define LPC54_ETH_DMA_CH1_SLOT_FUNC_CTRL_STAT_OFFSET 0x11bc /* The channel 1 slot function control and status */ +#define LPC54_ETH_DMA_CH1_CUR_HST_TXDESC_OFFSET 0x11c4 /* The channel 1 current host transmit descriptor */ +#define LPC54_ETH_DMA_CH1_CUR_HST_RXDESC_OFFSET 0x11cc /* The channel 1 current host receive descriptor */ +#define LPC54_ETH_DMA_CH1_CUR_HST_TXBUF_OFFSET 0x11d4 /* The channel 1 current host transmit buffer address */ +#define LPC54_ETH_DMA_CH1_CUR_HST_RXBUF_OFFSET 0x11dc /** The channel 1 current host receive buffer address */ +#define LPC54_ETH_DMA_CH1_STAT_OFFSET 0x11e0 /* Channel 1 DMA status */ +#define LPC54_ETH_DMA_CH1_MISS_FRAME_CNT_OFFSET 0x11ec /* Channel 1 missed frame count */ + +/* Register addresses ***************************************************************************************/ + +#define LPC54_ETH_MAC_CONFIG (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_CONFIG_OFFSET) +#define LPC54_ETH_MAC_EXT_CONFIG (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_EXT_CONFIG_OFFSET) +#define LPC54_ETH_MAC_FRAME_FILTER (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_FRAME_FILTER_OFFSET) +#define LPC54_ETH_MAC_WD_TIMEROUT (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_WD_TIMEROUT_OFFSET) +#define LPC54_ETH_MAC_VLAN_TAG (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_VLAN_TAG_OFFSET) +#define LPC54_ETH_MAC_TX_FLOW_CTRL_Q0 (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_TX_FLOW_CTRL_Q0_OFFSET) +#define LPC54_ETH_MAC_TX_FLOW_CTRL_Q1 (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_TX_FLOW_CTRL_Q1_OFFSET) +#define LPC54_ETH_MAC_RX_FLOW_CTRL (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_RX_FLOW_CTRL_OFFSET) +#define LPC54_ETH_MAC_TXQ_PRIO_MAP (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_TXQ_PRIO_MAP_OFFSET) +#define LPC54_ETH_MAC_RXQ_CTRL0 (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_RXQ_CTRL0_OFFSET) +#define LPC54_ETH_MAC_RXQ_CTRL1 (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_RXQ_CTRL1_OFFSET) +#define LPC54_ETH_MAC_RXQ_CTRL2 (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_RXQ_CTRL2_OFFSET) +#define LPC54_ETH_MAC_INTR_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_INTR_STAT_OFFSET) +#define LPC54_ETH_MAC_INTR_EN (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_INTR_EN_OFFSET) +#define LPC54_ETH_MAC_RXTX_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_RXTX_STAT_OFFSET) +#define LPC54_ETH_MAC_PMT_CRTL_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_PMT_CRTL_STAT_OFFSET) +#define LPC54_ETH_MAC_RWK_PKT_FLT (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_RWK_PKT_FLT_OFFSET) +#define LPC54_ETH_MAC_LPI_CTRL_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_LPI_CTRL_STAT_OFFSET) +#define LPC54_ETH_MAC_LPI_TIMER_CTRL (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_LPI_TIMER_CTRL_OFFSET) +#define LPC54_ETH_MAC_LPI_ENTR_TIMR (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_LPI_ENTR_TIMR_OFFSET) +#define LPC54_ETH_MAC_1US_TIC_COUNTR (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_1US_TIC_COUNTR_OFFSET) +#define LPC54_ETH_MAC_VERSION (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_VERSION_OFFSET) +#define LPC54_ETH_MAC_DBG (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_DBG_OFFSET) +#define LPC54_ETH_MAC_HW_FEAT0 (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_HW_FEAT0_OFFSET) +#define LPC54_ETH_MAC_HW_FEAT1 (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_HW_FEAT1_OFFSET) +#define LPC54_ETH_MAC_HW_FEAT2 (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_HW_FEAT2_OFFSET) + +#define LPC54_ETH_MAC_MDIO_ADDR (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_MDIO_ADDR_OFFSET) +#define LPC54_ETH_MAC_MDIO_DATA (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_MDIO_DATA_OFFSET) +#define LPC54_ETH_MAC_ADDR_HIGH (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_ADDR_HIGH_OFFSET) +#define LPC54_ETH_MAC_ADDR_LOW (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_ADDR_LOW_OFFSET) + +#define LPC54_ETH_MAC_TIMESTAMP_CTRL (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_TIMESTAMP_CTRL_OFFSET) +#define LPC54_ETH_MAC_SUB_SCND_INCR (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_SUB_SCND_INCR_OFFSET) +#define LPC54_ETH_MAC_SYS_TIME_SCND (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_SYS_TIME_SCND_OFFSET) +#define LPC54_ETH_MAC_SYS_TIME_NSCND (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_SYS_TIME_NSCND_OFFSET) +#define LPC54_ETH_MAC_SYS_TIME_SCND_UPD (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_SYS_TIME_SCND_UPD_OFFSET) +#define LPC54_ETH_MAC_SYS_TIME_NSCND_UPD (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_SYS_TIME_NSCND_UPD_OFFSET) +#define LPC54_ETH_MAC_SYS_TIMESTMP_ADDEND (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_SYS_TIMESTMP_ADDEND_OFFSET) +#define LPC54_ETH_MAC_SYS_TIME_HWORD_SCND (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_SYS_TIME_HWORD_SCND_OFFSET) +#define LPC54_ETH_MAC_SYS_TIMESTMP_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_SYS_TIMESTMP_STAT_OFFSET) +#define LPC54_ETH_MAC_Tx_TIMESTAMP_STATUS_NSECS (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_Tx_TIMESTAMP_STATUS_NSECS_OFFSET) +#define LPC54_ETH_MAC_Tx_TIMESTAMP_STATUS_SECS (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_Tx_TIMESTAMP_STATUS_SECS_OFFSET) +#define LPC54_ETH_MAC_TIMESTAMP_INGRESS_CORR_NSEC (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_TIMESTAMP_INGRESS_CORR_NSEC_OFFSET) +#define LPC54_ETH_MAC_TIMESTAMP_EGRESS_CORR_NSEC (LPC54_ETHERNET_BASE + LPC54_ETH_MAC_TIMESTAMP_EGRESS_CORR_NSEC_OFFSET) + +#define LPC54_ETH_MTL_OP_MODE (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_OP_MODE_OFFSET) +#define LPC54_ETH_MTL_INTR_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_INTR_STAT_OFFSET) +#define LPC54_ETH_MTL_RXQ_DMA_MAP (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_RXQ_DMA_MAP_OFFSET) + +#define LPC54_ETH_MTL_TXQ0_OP_MODE (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ0_OP_MODE_OFFSET) +#define LPC54_ETH_MTL_TXQ0_UNDRFLW (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ0_UNDRFLW_OFFSET) +#define LPC54_ETH_MTL_TXQ0_DBG (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ0_DBG_OFFSET) +#define LPC54_ETH_MTL_TXQ0_ETS_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ0_ETS_STAT_OFFSET) +#define LPC54_ETH_MTL_TXQ0_QNTM_WGHT (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ0_QNTM_WGHT_OFFSET) +#define LPC54_ETH_MTL_TXQ0_INTCTRL_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ0_INTCTRL_STAT_OFFSET) +#define LPC54_ETH_MTL_RXQ0_OP_MODE (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_RXQ0_OP_MODE_OFFSET) +#define LPC54_ETH_MTL_RXQ0_MISSPKT_OVRFLW_CNT (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_RXQ0_MISSPKT_OVRFLW_CNT_OFFSET) +#define LPC54_ETH_MTL_RXQ0_DBG (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_RXQ0_DBG_OFFSET) +#define LPC54_ETH_MTL_RXQ0_CTRL (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_RXQ0_CTRL_OFFSET) +#define LPC54_ETH_MTL_TXQ1_OP_MODE (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ1_OP_MODE_OFFSET) +#define LPC54_ETH_MTL_TXQ1_UNDRFLW (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ1_UNDRFLW_OFFSET) +#define LPC54_ETH_MTL_TXQ1_DBG (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ1_DBG_OFFSET) +#define LPC54_ETH_MTL_TXQ1_ETS_CTRL (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ1_ETS_CTRL_OFFSET) +#define LPC54_ETH_MTL_TXQ1_ETS_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ1_ETS_STAT_OFFSET) +#define LPC54_ETH_MTL_TXQ1_QNTM_WGHT (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ1_QNTM_WGHT_OFFSET) +#define LPC54_ETH_MTL_TXQ1_SNDSLP_CRDT (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ1_SNDSLP_CRDT_OFFSET) +#define LPC54_ETH_MTL_TXQ1_HI_CRDT (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ1_HI_CRDT_OFFSET) +#define LPC54_ETH_MTL_TXQ1_LO_CRDT (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ1_LO_CRDT_OFFSET) +#define LPC54_ETH_MTL_TXQ1_INTCTRL_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_TXQ1_INTCTRL_STAT_OFFSET) +#define LPC54_ETH_MTL_RXQ1_OP_MODE (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_RXQ1_OP_MODE_OFFSET) +#define LPC54_ETH_MTL_RXQ1_MISSPKT_OVRFLW_CNT (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_RXQ1_MISSPKT_OVRFLW_CNT_OFFSET) +#define LPC54_ETH_MTL_RXQ1_DBG (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_RXQ1_DBG_OFFSET) +#define LPC54_ETH_MTL_RXQ1_CTRL (LPC54_ETHERNET_BASE + LPC54_ETH_MTL_RXQ1_CTRL_OFFSET) + +#define LPC54_ETH_DMA_MODE (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_MODE_OFFSET) +#define LPC54_ETH_DMA_SYSBUS_MODE (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_SYSBUS_MODE_OFFSET) +#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_DMA_CH0_CTRL (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_CTRL_OFFSET) +#define LPC54_ETH_CH0_TX_CTRL (LPC54_ETHERNET_BASE + LPC54_ETH_CH0_TX_CTRL_OFFSET) +#define LPC54_ETH_DMA_CH0_RX_CTRL (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_RX_CTRL_OFFSET) +#define LPC54_ETH_DMA_CH0_TXDESC_LIST_ADDR (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_TXDESC_LIST_ADDR_OFFSET) +#define LPC54_ETH_DMA_CH0_RXDESC_LIST_ADDR (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_RXDESC_LIST_ADDR_OFFSET) +#define LPC54_ETH_DMA_CH0_TXDESC_TAIL_PTR (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_TXDESC_TAIL_PTR_OFFSET) +#define LPC54_ETH_DMA_CH0_RXDESC_TAIL_PTR (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_RXDESC_TAIL_PTR_OFFSET) +#define LPC54_ETH_DMA_CH0_TXDESC_RING_LENGTH (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_TXDESC_RING_LENGTH_OFFSET) +#define LPC54_ETH_DMA_CH0_RXDESC_RING_LENGTH (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_RXDESC_RING_LENGTH_OFFSET) +#define LPC54_ETH_DMA_CH0_INT_EN (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_INT_EN_OFFSET) +#define LPC54_ETH_DMA_CH0_RX_INT_WDTIMER (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_RX_INT_WDTIMER_OFFSET) +#define LPC54_ETH_DMA_CH0_SLOT_FUNC_CTRL_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_SLOT_FUNC_CTRL_STAT_OFFSET) +#define LPC54_ETH_DMA_CH0_CUR_HST_TXDESC (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_CUR_HST_TXDESC_OFFSET) +#define LPC54_ETH_DMA_CH0_CUR_HST_RXDESC (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_CUR_HST_RXDESC_OFFSET) +#define LPC54_ETH_DMA_CH0_CUR_HST_TXBUF (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_CUR_HST_TXBUF_OFFSET) +#define LPC54_ETH_DMA_CH0_CUR_HST_RXBUF (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_CUR_HST_RXBUF_OFFSET) +#define LPC54_ETH_DMA_CH0_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_STAT_OFFSET) +#define LPC54_ETH_DMA_CH0_MISS_FRAME_CNT (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH0_MISS_FRAME_CNT_OFFSET) +#define LPC54_ETH_DMA_CH1_CTRL (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_CTRL_OFFSET) +#define LPC54_ETH_DMA_CH1_TX_CTRL (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_TX_CTRL_OFFSET) +#define LPC54_ETH_DMA_CH1_RX_CTRL (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_RX_CTRL_OFFSET) +#define LPC54_ETH_DMA_CH1_TXDESC_LIST_ADDR (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_TXDESC_LIST_ADDR_OFFSET) +#define LPC54_ETH_DMA_CH1_RXDESC_LIST_ADDR (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_RXDESC_LIST_ADDR_OFFSET) +#define LPC54_ETH_DMA_CH1_TXDESC_TAIL_PTR (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_TXDESC_TAIL_PTR_OFFSET) +#define LPC54_ETH_DMA_CH1_RXDESC_TAIL_PTR (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_RXDESC_TAIL_PTR_OFFSET) +#define LPC54_ETH_DMA_CH1_TXDESC_RING_LENGTH (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_TXDESC_RING_LENGTH_OFFSET) +#define LPC54_ETH_DMA_CH1_RXDESC_RING_LENGTH (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_RXDESC_RING_LENGTH_OFFSET) +#define LPC54_ETH_DMA_CH1_INT_EN (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_INT_EN_OFFSET) +#define LPC54_ETH_DMA_CH1_RX_INT_WDTIMER (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_RX_INT_WDTIMER_OFFSET) +#define LPC54_ETH_DMA_CH1_SLOT_FUNC_CTRL_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_SLOT_FUNC_CTRL_STAT_OFFSET) +#define LPC54_ETH_DMA_CH1_CUR_HST_TXDESC (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_CUR_HST_TXDESC_OFFSET) +#define LPC54_ETH_DMA_CH1_CUR_HST_RXDESC (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_CUR_HST_RXDESC_OFFSET) +#define LPC54_ETH_DMA_CH1_CUR_HST_TXBUF (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_CUR_HST_TXBUF_OFFSET) +#define LPC54_ETH_DMA_CH1_CUR_HST_RXBUF (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_CUR_HST_RXBUF_OFFSET) +#define LPC54_ETH_DMA_CH1_STAT (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_STAT_OFFSET) +#define LPC54_ETH_DMA_CH1_MISS_FRAME_CNT (LPC54_ETHERNET_BASE + LPC54_ETH_DMA_CH1_MISS_FRAME_CNT_OFFSET) + +/* Register bit definitions *********************************************************************************/ + +/* MAC configuration */ +#define ETH_MAC_CONFIG_ +/* MAC extended configuration */ +#define ETH_MAC_EXT_CONFIG_ +/* MAC frame filter */ +#define ETH_MAC_FRAME_FILTER_ +/* MAC watchdog timeout */ +#define ETH_MAC_WD_TIMEROUT_ +/* VLAN tag */ +#define ETH_MAC_VLAN_TAG_ +/* Transmit flow control 0 */ +#define ETH_MAC_TX_FLOW_CTRL_Q0_ +/* Transmit flow control 1 */ +#define ETH_MAC_TX_FLOW_CTRL_Q1_ +/* Receive flow control */ +#define ETH_MAC_RX_FLOW_CTRL_ +/* Transmit Queue priority mapping */ +#define ETH_MAC_TXQ_PRIO_MAP_ +/* Receive Queue control 0 */ +#define ETH_MAC_RXQ_CTRL0_ +/* Receive Queue control 1 */ +#define ETH_MAC_RXQ_CTRL1_ +/* Receive Queue control 2 */ +#define ETH_MAC_RXQ_CTRL2_ +/* Interrupt status */ +#define ETH_MAC_INTR_STAT_ +/* Interrupt enable */ +#define ETH_MAC_INTR_EN_ +/* Receive transmit status */ +#define ETH_MAC_RXTX_STAT_ +/* MAC PMT control and status */ +#define ETH_MAC_PMT_CRTL_STAT_ +/* Wake-up packet filter */ +#define ETH_MAC_RWK_PKT_FLT_ +/* LPI control and status */ +#define ETH_MAC_LPI_CTRL_STAT_ +/* LPI timers control */ +#define ETH_MAC_LPI_TIMER_CTRL_ +/* LPI entry timer */ +#define ETH_MAC_LPI_ENTR_TIMR_ +/* MAC 1 usec tick counter */ +#define ETH_MAC_1US_TIC_COUNTR_ +/* MAC version */ +#define ETH_MAC_VERSION_ +/* MAC debug */ +#define ETH_MAC_DBG_ +/* MAC hardware feature 0 */ +#define ETH_MAC_HW_FEAT0_ +/* MAC hardware feature 1 */ +#define ETH_MAC_HW_FEAT1_ +/* MAC hardware feature 2 */ +#define ETH_MAC_HW_FEAT2_ + +/* MIDO address */ +#define ETH_MAC_MDIO_ADDR_ +/* MDIO data */ +#define ETH_MAC_MDIO_DATA_ +/* MAC address0 high */ +#define ETH_MAC_ADDR_HIGH_ +/* MAC address0 low */ +#define ETH_MAC_ADDR_LOW_ + +/* Timestamp control */ +#define ETH_MAC_TIMESTAMP_CTRL_ +/* Sub-second increment */ +#define ETH_MAC_SUB_SCND_INCR_ +/* System time seconds */ +#define ETH_MAC_SYS_TIME_SCND_ +/* System time nanoseconds */ +#define ETH_MAC_SYS_TIME_NSCND_ +/* System time seconds update */ +#define ETH_MAC_SYS_TIME_SCND_UPD_ +/* System time nanoseconds update */ +#define ETH_MAC_SYS_TIME_NSCND_UPD_ +/* Timestamp addend */ +#define ETH_MAC_SYS_TIMESTMP_ADDEND_ +/* System time-higher word seconds */ +#define ETH_MAC_SYS_TIME_HWORD_SCND_ +/* Timestamp status */ +#define ETH_MAC_SYS_TIMESTMP_STAT_ +/* Tx timestamp status nanoseconds */ +#define ETH_MAC_Tx_TIMESTAMP_STATUS_NSECS_ +/* Tx timestamp status seconds */ +#define ETH_MAC_Tx_TIMESTAMP_STATUS_SECS_ +/* Timestamp ingress correction */ +#define ETH_MAC_TIMESTAMP_INGRESS_CORR_NSEC_ +/* Timestamp egress correction */ +#define ETH_MAC_TIMESTAMP_EGRESS_CORR_NSEC_ + +/* MTL operation mode */ +#define ETH_MTL_OP_MODE_ +/* MTL interrupt status */ +#define ETH_MTL_INTR_STAT_ +/* MTL Rx Queue and DMA channel mapping */ +#define ETH_MTL_RXQ_DMA_MAP_ + +/* MTL TxQ0 operation mode */ +#define ETH_MTL_TXQ0_OP_MODE_ +/* MTL TxQ0 underflow */ +#define ETH_MTL_TXQ0_UNDRFLW_ +/* MTL TxQ0 debug */ +#define ETH_MTL_TXQ0_DBG_ +/* MTL TxQ0 ETS status */ +#define ETH_MTL_TXQ0_ETS_STAT_ +/* Queue 0 quantum or weights */ +#define ETH_MTL_TXQ0_QNTM_WGHT_ +/* MTL TxQ0 interrupt control status */ +#define ETH_MTL_TXQ0_INTCTRL_STAT_ +/* MTL RxQ0 operation mode */ +#define ETH_MTL_RXQ0_OP_MODE_ +/* MTL RxQ0 missed packet overflow counter */ +#define ETH_MTL_RXQ0_MISSPKT_OVRFLW_CNT_ +/* MTL RxQ0 debug */ +#define ETH_MTL_RXQ0_DBG_ +/* MTL RxQ0 control */ +#define ETH_MTL_RXQ0_CTRL_ +/* MTL TxQ1 operation mode */ +#define ETH_MTL_TXQ1_OP_MODE_ +/* MTL TxQ1 underflow */ +#define ETH_MTL_TXQ1_UNDRFLW_ +/* MTL TxQ1 debug */ +#define ETH_MTL_TXQ1_DBG_ +/* MTL TxQ1 ETS control */ +#define ETH_MTL_TXQ1_ETS_CTRL_ +/* MTL TxQ1 ETS status */ +#define ETH_MTL_TXQ1_ETS_STAT_ +/* MTL TxQ1 quantum Weight */ +#define ETH_MTL_TXQ1_QNTM_WGHT_ +/* MTL TxQ1 SendSlopCredit */ +#define ETH_MTL_TXQ1_SNDSLP_CRDT_ +/* MTL TxQ1 hiCredit */ +#define ETH_MTL_TXQ1_HI_CRDT_ +/* MTL TxQ1 loCredit */ +#define ETH_MTL_TXQ1_LO_CRDT_ +/* MTL TxQ1 interrupt control status */ +#define ETH_MTL_TXQ1_INTCTRL_STAT_ +/* MTL RxQ1 operation mode */ +#define ETH_MTL_RXQ1_OP_MODE_ +/* MTL RxQ1 missed packet overflow counter */ +#define ETH_MTL_RXQ1_MISSPKT_OVRFLW_CNT_ +/* MTL RxQ1 debug */ +#define ETH_MTL_RXQ1_DBG_ +/* MTL RxQ1 control */ +#define ETH_MTL_RXQ1_CTRL_ + +/* DMA mode */ +#define ETH_DMA_MODE_ +/* DMA system bus mode */ +#define ETH_DMA_SYSBUS_MODE_ +/* DMA interrupt status */ +#define ETH_DMA_INTR_STAT_ +/* DMA debug status */ +#define ETH_DMA_DBG_STAT_ + +/* DMA channel 0 control */ +#define ETH_DMA_CH0_CTRL_ +/* DMA channel 0 transmit control */ +#define ETH_CH0_TX_CTRL_ +/* DMA channel 0 receive control */ +#define ETH_DMA_CH0_RX_CTRL_ +/* Channel 0 Tx descriptor list address */ +#define ETH_DMA_CH0_TXDESC_LIST_ADDR_ +/* Channel 0 Rx descriptor list address */ +#define ETH_DMA_CH0_RXDESC_LIST_ADDR_ +/* Channel 0 Tx descriptor tail pointer */ +#define ETH_DMA_CH0_TXDESC_TAIL_PTR_ +/* Channel 0 Rx descriptor tail pointer */ +#define ETH_DMA_CH0_RXDESC_TAIL_PTR_ +/* Channel 0 Tx descriptor ring length */ +#define ETH_DMA_CH0_TXDESC_RING_LENGTH_ +/* Channel 0 Rx descriptor ring length */ +#define ETH_DMA_CH0_RXDESC_RING_LENGTH_ +/* Channel 0 interrupt enable */ +#define ETH_DMA_CH0_INT_EN_ +/* Receive interrupt watchdog timer */ +#define ETH_DMA_CH0_RX_INT_WDTIMER_ +/* Slot function control and status */ +#define ETH_DMA_CH0_SLOT_FUNC_CTRL_STAT_ +/* Channel 0 current host transmit descriptor */ +#define ETH_DMA_CH0_CUR_HST_TXDESC_ +/* Channel 0 current host receive descriptor */ +#define ETH_DMA_CH0_CUR_HST_RXDESC_ +/* Channel 0 current host transmit buffer address */ +#define ETH_DMA_CH0_CUR_HST_TXBUF_ +/* Channel 0 current application receive buffer address */ +#define ETH_DMA_CH0_CUR_HST_RXBUF_ +/* Channel 0 DMA status */ +#define ETH_DMA_CH0_STAT_ +/** Channel 0 missed frame count */ +#define ETH_DMA_CH0_MISS_FRAME_CNT_ +/* DMA channel 1 control */ +#define ETH_DMA_CH1_CTRL_ +/* DMA channel 1 transmit control */ +#define ETH_DMA_CH1_TX_CTRL_ +/* The DMA channel 1 receive control */ +#define ETH_DMA_CH1_RX_CTRL_ +/* The channel 1 Tx descriptor list address */ +#define ETH_DMA_CH1_TXDESC_LIST_ADDR_ +/* The channel 1 Rx descriptor list address */ +#define ETH_DMA_CH1_RXDESC_LIST_ADDR_ +/* The channel 1 Tx descriptor tail pointer */ +#define ETH_DMA_CH1_TXDESC_TAIL_PTR_ +/* The channel 1 Rx descriptor tail pointer */ +#define ETH_DMA_CH1_RXDESC_TAIL_PTR_ +/* Channel 1 Tx descriptor ring length */ +#define ETH_DMA_CH1_TXDESC_RING_LENGTH_ +/* The channel 1 Rx descriptor ring length */ +#define ETH_DMA_CH1_RXDESC_RING_LENGTH_ +/* The channel 1 interrupt enable */ +#define ETH_DMA_CH1_INT_EN_ +/* The channel 1 receive interrupt watchdog timer */ +#define ETH_DMA_CH1_RX_INT_WDTIMER_ +/* The channel 1 slot function control and status */ +#define ETH_DMA_CH1_SLOT_FUNC_CTRL_STAT_ +/* The channel 1 current host transmit descriptor */ +#define ETH_DMA_CH1_CUR_HST_TXDESC_ +/* The channel 1 current host receive descriptor */ +#define ETH_DMA_CH1_CUR_HST_RXDESC_ +/* The channel 1 current host transmit buffer address */ +#define ETH_DMA_CH1_CUR_HST_TXBUF_ +/** The channel 1 current host receive buffer address */ +#define ETH_DMA_CH1_CUR_HST_RXBUF_ +/* Channel 1 DMA status */ +#define ETH_DMA_CH1_STAT_ +/* Channel 1 missed frame count */ +#define ETH_DMA_CH1_MISS_FRAME_CNT_ + +#endif /* __ARCH_ARM_SRC_LPC54XX_CHIP_LPC54_ETHERNET_H */ diff --git a/arch/arm/src/lpc54xx/lpc54_ethernet.c b/arch/arm/src/lpc54xx/lpc54_ethernet.c new file mode 100644 index 0000000000..e7f1461e58 --- /dev/null +++ b/arch/arm/src/lpc54xx/lpc54_ethernet.c @@ -0,0 +1,1206 @@ +/**************************************************************************** + * arch/arm/src/lpc54xx/lpx54_ethernet.c + * + * Copyright (C) 2017 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_NET_PKT +# include +#endif + +#include "up_arch.h" +#include "chip/lpc54_ethernet.h" + +#ifdef CONFIG_LPC54_ETHERNET + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Work queue support is required. */ + +#if !defined(CONFIG_SCHED_WORKQUEUE) +# error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE) +#else + +/* The low priority work queue is preferred. If it is not enabled, LPWORK + * will be the same as HPWORK. + */ + +#define ETHWORK LPWORK + +/* TX poll delay = 1 seconds. CLK_TCK is the number of clock ticks per second */ + +#define LPC54_WDDELAY (1*CLK_TCK) + +/* TX timeout = 1 minute */ + +#define LPC54_TXTIMEOUT (60*CLK_TCK) + +/* This is a helper pointer for accessing the contents of the Ethernet header */ + +#define BUF ((struct eth_hdr_s *)priv->eth_dev.d_buf) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The lpc54_ethdriver_s encapsulates all state information for a single + * Ethernet interface + */ + +struct lpc54_ethdriver_s +{ + bool eth_bifup; /* true:ifup false:ifdown */ + WDOG_ID eth_txpoll; /* TX poll timer */ + WDOG_ID eth_txtimeout; /* TX timeout timer */ + struct work_s eth_irqwork; /* For deferring interupt work to the work queue */ + struct work_s eth_pollwork; /* For deferring poll work to the work queue */ + + /* This holds the information visible to the NuttX network */ + + struct net_driver_s eth_dev; /* Interface understood by the network */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* These statically allocated structures are possible because only a single + * instance of the Ethernet device could be supported. In order to support + * multiple devices instances, this data would have to be allocated + * dynamically. + */ + +/* A single packet buffer per device is used here. There might be multiple + * packet buffers in a more complex, pipelined design. + */ + +static uint8_t g_pktbuf[MAX_NET_DEV_MTU + CONFIG_NET_GUARDSIZE]; + +/* Driver state structure */ + +static struct lpc54_ethdriver_s g_ethdriver; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Common TX logic */ + +static int lpc54_eth_transmit(FAR struct lpc54_ethdriver_s *priv); +static int lpc54_eth_txpoll(FAR struct net_driver_s *dev); + +/* Interrupt handling */ + +static void lpc54_eth_receive(FAR struct lpc54_ethdriver_s *priv); +static void lpc54_eth_txdone(FAR struct lpc54_ethdriver_s *priv); + +static void lpc54_eth_interrupt_work(FAR void *arg); +static int lpc54_eth_interrupt(int irq, FAR void *context, FAR void *arg); + +/* Watchdog timer expirations */ + +static void lpc54_eth_txtimeout_work(FAR void *arg); +static void lpc54_eth_txtimeout_expiry(int argc, wdparm_t arg, ...); + +static void lpc54_eth_poll_work(FAR void *arg); +static void lpc54_eth_poll_expiry(int argc, wdparm_t arg, ...); + +/* NuttX callback functions */ + +static int lpc54_eth_ifup(FAR struct net_driver_s *dev); +static int lpc54_eth_ifdown(FAR struct net_driver_s *dev); + +static void lpc54_eth_txavail_work(FAR void *arg); +static int lpc54_eth_txavail(FAR struct net_driver_s *dev); + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int lpc54_eth_addmac(FAR struct net_driver_s *dev, + FAR const uint8_t *mac); +#ifdef CONFIG_NET_IGMP +static int lpc54_eth_rmmac(FAR struct net_driver_s *dev, + FAR const uint8_t *mac); +#endif +#ifdef CONFIG_NET_ICMPv6 +static void lpc54_eth_ipv6multicast(FAR struct lpc54_ethdriver_s *priv); +#endif +#endif +#ifdef CONFIG_NETDEV_IOCTL +static int lpc54_eth_ioctl(FAR struct net_driver_s *dev, int cmd, + unsigned long arg); +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc54_eth_transmit + * + * Description: + * Start hardware transmission. Called either from the txdone interrupt + * handling or from watchdog based polling. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * the network is locked. + * + ****************************************************************************/ + +static int lpc54_eth_transmit(FAR struct lpc54_ethdriver_s *priv) +{ + /* Verify that the hardware is ready to send another packet. If we get + * here, then we are committed to sending a packet; Higher level logic + * must have assured that there is no transmission in progress. + */ +#warning Missing logic + + /* Increment statistics */ + + NETDEV_TXPACKETS(priv->eth_dev); + + /* Send the packet: address=priv->eth_dev.d_buf, length=priv->eth_dev.d_len */ +#warning Missing logic + + /* Enable Tx interrupts */ +#warning Missing logic + + /* Setup the TX timeout watchdog (perhaps restarting the timer) */ + + (void)wd_start(priv->eth_txtimeout, LPC54_TXTIMEOUT, + lpc54_eth_txtimeout_expiry, 1, (wdparm_t)priv); + return OK; +} + +/**************************************************************************** + * Name: lpc54_eth_txpoll + * + * Description: + * The transmitter is available, check if the network has any outgoing + * packets ready to send. This is a callback from devif_poll(). + * devif_poll() may be called: + * + * 1. When the preceding TX packet send is complete, + * 2. When the preceding TX packet send timesout and the interface is reset + * 3. During normal TX polling + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * OK on success; a negated errno on failure + * + * Assumptions: + * May or may not be called from an interrupt handler. In either case, + * the network is locked. + * + ****************************************************************************/ + +static int lpc54_eth_txpoll(FAR struct net_driver_s *dev) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private; + + /* If the polling resulted in data that should be sent out on the network, + * the field d_len is set to a value > 0. + */ + + if (priv->eth_dev.d_len > 0) + { + /* Look up the destination MAC address and add it to the Ethernet + * header. + */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->eth_dev.d_flags)) +#endif + { + arp_out(&priv->eth_dev); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + neighbor_out(&priv->eth_dev); + } +#endif /* CONFIG_NET_IPv6 */ + + /* Send the packet */ + + lpc54_eth_transmit(priv); + + /* Check if there is room in the device to hold another packet. If not, + * return a non-zero value to terminate the poll. + */ + } + + /* If zero is returned, the polling will continue until all connections have + * been examined. + */ + + return 0; +} + +/**************************************************************************** + * Name: lpc54_eth_receive + * + * Description: + * An interrupt was received indicating the availability of a new RX packet + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * The network is locked. + * + ****************************************************************************/ + +static void lpc54_eth_receive(FAR struct lpc54_ethdriver_s *priv) +{ + do + { + /* Check for errors and update statistics */ +#warning Missing logic + + /* Check if the packet is a valid size for the network buffer + * configuration. + */ +#warning Missing logic + + /* Copy the data data from the hardware to priv->eth_dev.d_buf. Set + * amount of data in priv->eth_dev.d_len + */ +#warning Missing logic + +#ifdef CONFIG_NET_PKT + /* When packet sockets are enabled, feed the frame into the packet tap */ + + pkt_input(&priv->eth_dev); +#endif + + /* We only accept IP packets of the configured type and ARP packets */ + +#ifdef CONFIG_NET_IPv4 + if (BUF->type == HTONS(ETHTYPE_IP)) + { + ninfo("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->eth_dev); + + /* Handle ARP on input then give the IPv4 packet to the network + * layer + */ + + arp_ipin(&priv->eth_dev); + ipv4_input(&priv->eth_dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->eth_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv6 + if (IFF_IS_IPv4(priv->eth_dev.d_flags)) +#endif + { + arp_out(&priv->eth_dev); + } +#ifdef CONFIG_NET_IPv6 + else + { + neighbor_out(&kel->eth_dev); + } +#endif + + /* And send the packet */ + + lpc54_eth_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_IPv6 + if (BUF->type == HTONS(ETHTYPE_IP6)) + { + ninfo("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->eth_dev); + + /* Give the IPv6 packet to the network layer */ + + ipv6_input(&priv->eth_dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->eth_dev.d_len > 0) + { + /* Update the Ethernet header with the correct MAC address */ + +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv4(priv->eth_dev.d_flags)) + { + arp_out(&priv->eth_dev); + } + else +#endif +#ifdef CONFIG_NET_IPv6 + { + neighbor_out(&priv->eth_dev); + } +#endif + + /* And send the packet */ + + lpc54_eth_transmit(priv); + } + } + else +#endif +#ifdef CONFIG_NET_ARP + if (BUF->type == htons(ETHTYPE_ARP)) + { + arp_arpin(&priv->eth_dev); + NETDEV_RXARP(&priv->eth_dev); + + /* If the above function invocation resulted in data that should be + * sent out on the network, the field d_len will set to a value > 0. + */ + + if (priv->eth_dev.d_len > 0) + { + lpc54_eth_transmit(priv); + } + } + else +#endif + { + NETDEV_RXDROPPED(&priv->eth_dev); + } + } + while (); /* While there are more packets to be processed */ +} + +/**************************************************************************** + * Name: lpc54_eth_txdone + * + * Description: + * An interrupt was received indicating that the last TX packet(s) is done + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * The network is locked. + * + ****************************************************************************/ + +static void lpc54_eth_txdone(FAR struct lpc54_ethdriver_s *priv) +{ + int delay; + + /* Check for errors and update statistics */ +#warning Missing logic + + NETDEV_TXDONE(priv->eth_dev); + + /* Check if there are pending transmissions */ +#warning Missing logic + + /* If no further transmissions are pending, then cancel the TX timeout and + * disable further Tx interrupts. + */ + + wd_cancel(priv->eth_txtimeout); + + /* And disable further TX interrupts. */ +#warning Missing logic + + /* In any event, poll the network for new TX data */ + + (void)devif_poll(&priv->eth_dev, lpc54_eth_txpoll); +} + +/**************************************************************************** + * Name: lpc54_eth_interrupt_work + * + * Description: + * Perform interrupt related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() was called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * The network is locked. + * + ****************************************************************************/ + +static void lpc54_eth_interrupt_work(FAR void *arg) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg; + + /* Lock the network and serialize driver operations if necessary. + * NOTE: Serialization is only required in the case where the driver work + * is performed on an LP worker thread and where more than one LP worker + * thread has been configured. + */ + + net_lock(); + + /* Process pending Ethernet interrupts */ +#warning Missing logic + + /* Get and clear interrupt status bits */ +#warning Missing logic + + /* Handle interrupts according to status bit settings */ +#warning Missing logic + + /* Check if we received an incoming packet, if so, call lpc54_eth_receive() */ +#warning Missing logic + + lpc54_eth_receive(priv); + + /* Check if a packet transmission just completed. If so, call lpc54_eth_txdone. + * This may disable further Tx interrupts if there are no pending + * transmissions. + */ +#warning Missing logic + + lpc54_eth_txdone(priv); + net_unlock(); + + /* Re-enable Ethernet interrupts */ + + up_enable_irq(LPC54_IRQ_ETHERNET); +} + +/**************************************************************************** + * Name: lpc54_eth_interrupt + * + * Description: + * Hardware interrupt handler + * + * Parameters: + * irq - Number of the IRQ that generated the interrupt + * context - Interrupt register state save info (architecture-specific) + * + * Returned Value: + * OK on success + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc54_eth_interrupt(int irq, FAR void *context, FAR void *arg) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg; + + DEBUGASSERT(priv != NULL); + + /* Disable further Ethernet interrupts. Because Ethernet interrupts are + * also disabled if the TX timeout event occurs, there can be no race + * condition here. + */ + + up_disable_irq(LPC54_IRQ_ETHERNET); + + /* TODO: Determine if a TX transfer just completed */ +#warning Missing logic + + { + /* If a TX transfer just completed, then cancel the TX timeout so + * there will be no race condition between any subsequent timeout + * expiration and the deferred interrupt processing. + */ + + wd_cancel(priv->eth_txtimeout); + } + + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(ETHWORK, &priv->eth_irqwork, lpc54_eth_interrupt_work, priv, 0); + return OK; +} + +/**************************************************************************** + * Name: lpc54_eth_txtimeout_work + * + * Description: + * Perform TX timeout related work from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * The network is locked. + * + ****************************************************************************/ + +static void lpc54_eth_txtimeout_work(FAR void *arg) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg; + + /* Lock the network and serialize driver operations if necessary. + * NOTE: Serialization is only required in the case where the driver work + * is performed on an LP worker thread and where more than one LP worker + * thread has been configured. + */ + + net_lock(); + + /* Increment statistics and dump debug info */ + + NETDEV_TXTIMEOUTS(priv->eth_dev); + + /* Then reset the hardware */ +#warning Missing logic + + /* Then poll the network for new XMIT data */ + + (void)devif_poll(&priv->eth_dev, lpc54_eth_txpoll); + net_unlock(); +} + +/**************************************************************************** + * Name: lpc54_eth_txtimeout_expiry + * + * Description: + * Our TX watchdog timed out. Called from the timer interrupt handler. + * The last TX never completed. Reset the hardware and start again. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void lpc54_eth_txtimeout_expiry(int argc, wdparm_t arg, ...) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg; + + /* Disable further Ethernet interrupts. This will prevent some race + * conditions with interrupt work. There is still a potential race + * condition with interrupt work that is already queued and in progress. + */ + + up_disable_irq(LPC54_IRQ_ETHERNET); + + /* Schedule to perform the TX timeout processing on the worker thread. */ + + work_queue(ETHWORK, &priv->eth_irqwork, lpc54_eth_txtimeout_work, priv, 0); +} + +/**************************************************************************** + * Name: lpc54_eth_poll_process + * + * Description: + * Perform the periodic poll. This may be called either from watchdog + * timer logic or from the worker thread, depending upon the configuration. + * + * Parameters: + * priv - Reference to the driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static inline void lpc54_eth_poll_process(FAR struct lpc54_ethdriver_s *priv) +{ +#warning Missing logic +} + +/**************************************************************************** + * Name: lpc54_eth_poll_work + * + * Description: + * Perform periodic polling from the worker thread + * + * Parameters: + * arg - The argument passed when work_queue() as called. + * + * Returned Value: + * OK on success + * + * Assumptions: + * The network is locked. + * + ****************************************************************************/ + +static void lpc54_eth_poll_work(FAR void *arg) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg; + + /* Lock the network and serialize driver operations if necessary. + * NOTE: Serialization is only required in the case where the driver work + * is performed on an LP worker thread and where more than one LP worker + * thread has been configured. + */ + + net_lock(); + + /* Perform the poll */ + + /* Check if there is room in the send another TX packet. We cannot perform + * the TX poll if he are unable to accept another packet for transmission. + */ +#warning Missing logic + + /* If so, update TCP timing states and poll the network for new XMIT data. + * Hmmm.. might be bug here. Does this mean if there is a transmit in + * progress, we will missing TCP time state updates? + */ + + (void)devif_timer(&priv->eth_dev, lpc54_eth_txpoll); + + /* Setup the watchdog poll timer again */ + + (void)wd_start(priv->eth_txpoll, LPC54_WDDELAY, lpc54_eth_poll_expiry, 1, + (wdparm_t)priv); + net_unlock(); +} + +/**************************************************************************** + * Name: lpc54_eth_poll_expiry + * + * Description: + * Periodic timer handler. Called from the timer interrupt handler. + * + * Parameters: + * argc - The number of available arguments + * arg - The first argument + * + * Returned Value: + * None + * + * Assumptions: + * Global interrupts are disabled by the watchdog logic. + * + ****************************************************************************/ + +static void lpc54_eth_poll_expiry(int argc, wdparm_t arg, ...) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg; + + /* Schedule to perform the interrupt processing on the worker thread. */ + + work_queue(ETHWORK, &priv->eth_pollwork, lpc54_eth_poll_work, priv, 0); +} + +/**************************************************************************** + * Name: lpc54_eth_ifup + * + * Description: + * NuttX Callback: Bring up the Ethernet interface when an IP address is + * provided + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc54_eth_ifup(FAR struct net_driver_s *dev) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private; + +#ifdef CONFIG_NET_IPv4 + ninfo("Bringing up: %d.%d.%d.%d\n", + dev->d_ipaddr & 0xff, (dev->d_ipaddr >> 8) & 0xff, + (dev->d_ipaddr >> 16) & 0xff, dev->d_ipaddr >> 24); +#endif +#ifdef CONFIG_NET_IPv6 + ninfo("Bringing up: %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", + dev->d_ipv6addr[0], dev->d_ipv6addr[1], dev->d_ipv6addr[2], + dev->d_ipv6addr[3], dev->d_ipv6addr[4], dev->d_ipv6addr[5], + dev->d_ipv6addr[6], dev->d_ipv6addr[7]); +#endif + + /* Initialize PHYs, the Ethernet interface, and setup up Ethernet interrupts */ +#warning Missing logic + + /* Instantiate the MAC address from priv->eth_dev.d_mac.ether.ether_addr_octet */ +#warning Missing logic + +#ifdef CONFIG_NET_ICMPv6 + /* Set up IPv6 multicast address filtering */ + + lpc54_eth_ipv6multicast(priv); +#endif + + /* Set and activate a timer process */ + + (void)wd_start(priv->eth_txpoll, LPC54_WDDELAY, lpc54_eth_poll_expiry, 1, + (wdparm_t)priv); + + /* Enable the Ethernet interrupt */ + + priv->eth_bifup = true; + up_enable_irq(LPC54_IRQ_ETHERNET); + return OK; +} + +/**************************************************************************** + * Name: lpc54_eth_ifdown + * + * Description: + * NuttX Callback: Stop the interface. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * + ****************************************************************************/ + +static int lpc54_eth_ifdown(FAR struct net_driver_s *dev) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private; + irqstate_t flags; + + /* Disable the Ethernet interrupt */ + + flags = enter_critical_section(); + up_disable_irq(LPC54_IRQ_ETHERNET); + + /* Cancel the TX poll timer and TX timeout timers */ + + wd_cancel(priv->eth_txpoll); + wd_cancel(priv->eth_txtimeout); + + /* Put the EMAC in its reset, non-operational state. This should be + * a known configuration that will guarantee the lpc54_eth_ifup() always + * successfully brings the interface back up. + */ +#warning Missing logic + + /* Mark the device "down" */ + + priv->eth_bifup = false; + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: lpc54_eth_txavail_work + * + * Description: + * Perform an out-of-cycle poll on the worker thread. + * + * Parameters: + * arg - Reference to the NuttX driver state structure (cast to void*) + * + * Returned Value: + * None + * + * Assumptions: + * Called on the higher priority worker thread. + * + ****************************************************************************/ + +static void lpc54_eth_txavail_work(FAR void *arg) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)arg; + + /* Lock the network and serialize driver operations if necessary. + * NOTE: Serialization is only required in the case where the driver work + * is performed on an LP worker thread and where more than one LP worker + * thread has been configured. + */ + + net_lock(); + + /* Ignore the notification if the interface is not yet up */ + + if (priv->eth_bifup) + { + /* Check if there is room in the hardware to hold another outgoing packet. */ +#warning Missing logic + + /* If so, then poll the network for new XMIT data */ + + (void)devif_poll(&priv->eth_dev, lpc54_eth_txpoll); + } + + net_unlock(); +} + +/**************************************************************************** + * Name: lpc54_eth_txavail + * + * Description: + * Driver callback invoked when new TX data is available. This is a + * stimulus perform an out-of-cycle poll and, thereby, reduce the TX + * latency. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * + * Returned Value: + * None + * + * Assumptions: + * Called in normal user mode + * + ****************************************************************************/ + +static int lpc54_eth_txavail(FAR struct net_driver_s *dev) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private; + + /* Is our single work structure available? It may not be if there are + * pending interrupt actions and we will have to ignore the Tx + * availability action. + */ + + if (work_available(&priv->eth_pollwork)) + { + /* Schedule to serialize the poll on the worker thread. */ + + work_queue(ETHWORK, &priv->eth_pollwork, lpc54_eth_txavail_work, priv, 0); + } + + return OK; +} + +/**************************************************************************** + * Name: lpc54_eth_addmac + * + * Description: + * NuttX Callback: Add the specified MAC address to the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be added + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6) +static int lpc54_eth_addmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ +#warning Missing logic + + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc54_eth_rmmac + * + * Description: + * NuttX Callback: Remove the specified MAC address from the hardware multicast + * address filtering + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * mac - The MAC address to be removed + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IGMP +static int lpc54_eth_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private; + + /* Add the MAC address to the hardware multicast routing table */ +#warning Missing logic + + return OK; +} +#endif + +/**************************************************************************** + * Name: lpc54_eth_ipv6multicast + * + * Description: + * Configure the IPv6 multicast MAC address. + * + * Parameters: + * priv - A reference to the private driver state structure + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_ICMPv6 +static void lpc54_eth_ipv6multicast(FAR struct lpc54_ethdriver_s *priv) +{ + FAR struct net_driver_s *dev; + uint16_t tmp16; + uint8_t mac[6]; + + /* For ICMPv6, we need to add the IPv6 multicast address + * + * For IPv6 multicast addresses, the Ethernet MAC is derived by + * the four low-order octets OR'ed with the MAC 33:33:00:00:00:00, + * so for example the IPv6 address FF02:DEAD:BEEF::1:3 would map + * to the Ethernet MAC address 33:33:00:01:00:03. + * + * NOTES: This appears correct for the ICMPv6 Router Solicitation + * Message, but the ICMPv6 Neighbor Solicitation message seems to + * use 33:33:ff:01:00:03. + */ + + mac[0] = 0x33; + mac[1] = 0x33; + + dev = &priv->dev; + tmp16 = dev->d_ipv6addr[6]; + mac[2] = 0xff; + mac[3] = tmp16 >> 8; + + tmp16 = dev->d_ipv6addr[7]; + mac[4] = tmp16 & 0xff; + mac[5] = tmp16 >> 8; + + ninfo("IPv6 Multicast: %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + (void)lpc54_eth_addmac(dev, mac); + +#ifdef CONFIG_NET_ICMPv6_AUTOCONF + /* Add the IPv6 all link-local nodes Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Advertisement + * packets. + */ + + (void)lpc54_eth_addmac(dev, g_ipv6_ethallnodes.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_AUTOCONF */ + +#ifdef CONFIG_NET_ICMPv6_ROUTER + /* Add the IPv6 all link-local routers Ethernet address. This is the + * address that we expect to receive ICMPv6 Router Solicitation + * packets. + */ + + (void)lpc54_eth_addmac(dev, g_ipv6_ethallrouters.ether_addr_octet); + +#endif /* CONFIG_NET_ICMPv6_ROUTER */ +} +#endif /* CONFIG_NET_ICMPv6 */ + +/**************************************************************************** + * Name: lpc54_eth_ioctl + * + * Description: + * Handle network IOCTL commands directed to this device. + * + * Parameters: + * dev - Reference to the NuttX driver state structure + * cmd - The IOCTL command + * arg - The argument for the IOCTL command + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_IOCTL +static int lpc54_eth_ioctl(FAR struct net_driver_s *dev, int cmd, + unsigned long arg) +{ + FAR struct lpc54_ethdriver_s *priv = (FAR struct lpc54_ethdriver_s *)dev->d_private; + int ret; + + /* Decode and dispatch the driver-specific IOCTL command */ + + switch (cmd) + { + /* Add cases here to support the IOCTL commands */ +#warning Missing logic + + default: + nerr("ERROR: Unrecognized IOCTL command: %d\n", command); + return -ENOTTY; /* Special return value for this case */ + } + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc54_eth_initialize + * + * Description: + * Initialize the Ethernet controller and driver + * + * Parameters: + * intf - In the case where there are multiple EMACs, this value + * identifies which EMAC is to be initialized. + * + * Returned Value: + * OK on success; Negated errno on failure. + * + * Assumptions: + * + ****************************************************************************/ + +int lpc54_eth_initialize(int intf) +{ + FAR struct lpc54_ethdriver_s *priv; + + /* Get the interface structure associated with this interface number. */ + + DEBUGASSERT(intf == 0); + priv = &g_ethdriver; + + /* Check if a Ethernet chip is recognized at its I/O base */ +#warning Missing logic + + /* Attach the IRQ to the driver */ + + if (irq_attach(LPC54_IRQ_ETHERNET, lpc54_eth_interrupt, priv)) + { + /* We could not attach the ISR to the interrupt */ + + return -EAGAIN; + } + + /* Initialize the driver structure */ + + memset(priv, 0, sizeof(struct lpc54_ethdriver_s)); + priv->eth_dev.d_buf = g_pktbuf; /* Single packet buffer */ + priv->eth_dev.d_ifup = lpc54_eth_ifup; /* I/F up (new IP address) callback */ + priv->eth_dev.d_ifdown = lpc54_eth_ifdown; /* I/F down callback */ + priv->eth_dev.d_txavail = lpc54_eth_txavail; /* New TX data callback */ +#ifdef CONFIG_NET_IGMP + priv->eth_dev.d_addmac = lpc54_eth_addmac; /* Add multicast MAC address */ + priv->eth_dev.d_rmmac = lpc54_eth_rmmac; /* Remove multicast MAC address */ +#endif +#ifdef CONFIG_NETDEV_IOCTL + priv->eth_dev.d_ioctl = lpc54_eth_ioctl; /* Handle network IOCTL commands */ +#endif + priv->eth_dev.d_private = (FAR void *)g_ethdriver; /* Used to recover private state from dev */ + + /* Create a watchdog for timing polling for and timing of transmisstions */ + + priv->eth_txpoll = wd_create(); /* Create periodic poll timer */ + priv->eth_txtimeout = wd_create(); /* Create TX timeout timer */ + + DEBUGASSERT(priv->eth_txpoll != NULL && priv->eth_txtimeout != NULL); + + /* Put the interface in the down state. This usually amounts to resetting + * the device and/or calling lpc54_eth_ifdown(). + */ +#warning Missing logic + + /* Read the MAC address from the hardware into priv->eth_dev.d_mac.ether.ether_addr_octet */ +#warning Missing logic + + /* Register the device with the OS so that socket IOCTLs can be performed */ + + (void)netdev_register(&priv->eth_dev, NET_LL_ETHERNET); + return OK; +} + +#endif /* CONFIG_LPC54_ETHERNET */ diff --git a/arch/arm/src/lpc54xx/lpc54_tickless.c b/arch/arm/src/lpc54xx/lpc54_tickless.c index 4d5cee3965..57dd593cf8 100644 --- a/arch/arm/src/lpc54xx/lpc54_tickless.c +++ b/arch/arm/src/lpc54xx/lpc54_tickless.c @@ -4,7 +4,7 @@ * Copyright (C) 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * - * Derives from the LPC43xx tickless most logic + * Derives from the LPC43xx tickless mode logic * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/configs/lpcxpresso-lpc54628/README.txt b/configs/lpcxpresso-lpc54628/README.txt index 140f577de3..1a2bbca375 100644 --- a/configs/lpcxpresso-lpc54628/README.txt +++ b/configs/lpcxpresso-lpc54628/README.txt @@ -77,9 +77,11 @@ STATUS been well tested. 2017-12-26: Added an RNG driver. The RNG is actually controlled by a ROM function. This driver seems to work fine when single stepping. However, - if I collect samples indefinitely, I do a reserved interrupt. I suspect - that to use the ROM at high frequencies it may be necessary to modify the - ROM access timing in some way. + if I collect samples indefinitely, I get a reserved interrupt. The symptom + before the crash is that local variables are getting corrupted after the + call into ROM. Increasing the stack size does not seem to help. Perhaps + to use the ROM at high frequencies it may be necessary to modify the ROM + access timing in some way??? There is still no support for the Accelerometer, SPIFI, Ethernet, or USB. There is a complete, but not-yet-functional SD card drirver. There is a diff --git a/configs/lpcxpresso-lpc54628/fb/defconfig b/configs/lpcxpresso-lpc54628/fb/defconfig index a219f546c5..292f8af403 100644 --- a/configs/lpcxpresso-lpc54628/fb/defconfig +++ b/configs/lpcxpresso-lpc54628/fb/defconfig @@ -3,6 +3,7 @@ CONFIG_ARCH_BOARD_LPCXPRESSO_LPC54628=y CONFIG_ARCH_BOARD="lpcxpresso-lpc54628" CONFIG_ARCH_CHIP_LPC54628=y CONFIG_ARCH_CHIP_LPC54XX=y +CONFIG_ARCH_INTERRUPTSTACK=2048 CONFIG_ARCH_STACKDUMP=y CONFIG_ARCH_STDARG_H=y CONFIG_ARCH="arm" diff --git a/configs/lpcxpresso-lpc54628/nsh/defconfig b/configs/lpcxpresso-lpc54628/nsh/defconfig index 2695a86915..70d2e78068 100644 --- a/configs/lpcxpresso-lpc54628/nsh/defconfig +++ b/configs/lpcxpresso-lpc54628/nsh/defconfig @@ -4,6 +4,7 @@ CONFIG_ARCH_BOARD="lpcxpresso-lpc54628" CONFIG_ARCH_BUTTONS=y CONFIG_ARCH_CHIP_LPC54628=y CONFIG_ARCH_CHIP_LPC54XX=y +CONFIG_ARCH_INTERRUPTSTACK=2048 CONFIG_ARCH_IRQBUTTONS=y CONFIG_ARCH_STACKDUMP=y CONFIG_ARCH_STDARG_H=y diff --git a/configs/lpcxpresso-lpc54628/nxwm/defconfig b/configs/lpcxpresso-lpc54628/nxwm/defconfig index cb4dba4bda..4c2f839ee1 100644 --- a/configs/lpcxpresso-lpc54628/nxwm/defconfig +++ b/configs/lpcxpresso-lpc54628/nxwm/defconfig @@ -7,6 +7,7 @@ CONFIG_ARCH_BOARD_LPCXPRESSO_LPC54628=y CONFIG_ARCH_BOARD="lpcxpresso-lpc54628" CONFIG_ARCH_CHIP_LPC54628=y CONFIG_ARCH_CHIP_LPC54XX=y +CONFIG_ARCH_INTERRUPTSTACK=2048 CONFIG_ARCH_STACKDUMP=y CONFIG_ARCH_STDARG_H=y CONFIG_ARCH="arm" diff --git a/drivers/net/skeleton.c b/drivers/net/skeleton.c index 9a8c8a0a8f..4f2f9afc4c 100644 --- a/drivers/net/skeleton.c +++ b/drivers/net/skeleton.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/net/skeleton.c * - * Copyright (C) 2017 Gregory Nutt. All rights reserved. + * Copyright (C) 2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -71,16 +71,11 @@ # error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE) #else - /* Use the selected work queue */ +/* The low priority work queue is preferred. If it is not enabled, LPWORK + * will be the same as HPWORK. + */ -# if defined(CONFIG_skeleton_HPWORK) -# define ETHWORK HPWORK -# elif defined(CONFIG_skeleton_LPWORK) -# define ETHWORK LPWORK -# else -# error Neither CONFIG_skeleton_HPWORK nor CONFIG_skeleton_LPWORK defined -# endif -#endif +#define ETHWORK LPWORK /* CONFIG_skeleton_NINTERFACES determines the number of physical interfaces * that will be supported. @@ -127,7 +122,7 @@ struct skel_driver_s * Private Data ****************************************************************************/ -/* These statically allocated structur would mean that only a single +/* These statically allocated structur eswould mean that only a single * instance of the device could be supported. In order to support multiple * devices instances, this data would have to be allocated dynamically. */ @@ -192,7 +187,7 @@ static void skel_ipv6multicast(FAR struct skel_driver_s *priv); #endif #ifdef CONFIG_NETDEV_IOCTL static int skel_ioctl(FAR struct net_driver_s *dev, int cmd, - unsigned long arg); + unsigned long arg); #endif /****************************************************************************