diff --git a/boards/arm/npcm400f_evb/fun_def_list.h b/boards/arm/npcm400f_evb/fun_def_list.h index 5377a145fac5a9..91e86afbaf08f1 100644 --- a/boards/arm/npcm400f_evb/fun_def_list.h +++ b/boards/arm/npcm400f_evb/fun_def_list.h @@ -128,3 +128,7 @@ FUN_DEFINE(DT_NODELABEL(pinctrl_sgpio0_default), IOX1_LDSH, IOX1_DOUT, IOX1_DIN, #if DT_NODE_HAS_STATUS(DT_NODELABEL(sgpio1), okay) && CONFIG_SGPIO_NPCM4XX FUN_DEFINE(DT_NODELABEL(pinctrl_sgpio1_default), IOX2_LDSH, IOX2_DOUT, IOX2_DIN, IOX2_SCLK) #endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(emac), okay) && CONFIG_ETH_NPCM4XX +FUN_DEFINE(DT_NODELABEL(pinctrl_emac_default), EMAC) +#endif diff --git a/boards/arm/npcm400f_evb/npcm400f_evb.dts b/boards/arm/npcm400f_evb/npcm400f_evb.dts index 6bdc24b8b40099..46f218a27bb69c 100644 --- a/boards/arm/npcm400f_evb/npcm400f_evb.dts +++ b/boards/arm/npcm400f_evb/npcm400f_evb.dts @@ -233,7 +233,7 @@ tdi-gpios = <&gpio0 1 (GPIO_PUSH_PULL | GPIO_ACTIVE_HIGH)>; tdo-gpios = <&gpio0 2 (GPIO_ACTIVE_HIGH)>; tms-gpios = <&gpio0 3 (GPIO_PUSH_PULL | GPIO_ACTIVE_HIGH)>; - status = "okay"; + status = "disabled"; }; &i3c4 { @@ -608,3 +608,7 @@ pin-offset = <120>; }; }; + +&emac { + status = "okay"; +}; diff --git a/boards/arm/npcm400f_evb/npcm400f_evb_defconfig b/boards/arm/npcm400f_evb/npcm400f_evb_defconfig index f20c49568920ec..8f768af3b191a3 100644 --- a/boards/arm/npcm400f_evb/npcm400f_evb_defconfig +++ b/boards/arm/npcm400f_evb/npcm400f_evb_defconfig @@ -99,9 +99,31 @@ CONFIG_USB=y CONFIG_USB_DC_NPCM4XX=y # JTAG Driver -CONFIG_JTAG=y -CONFIG_JTAG_SHELL=y -CONFIG_JTAG_NPCM4XX=y +CONFIG_JTAG=n +CONFIG_JTAG_SHELL=n +CONFIG_JTAG_NPCM4XX=n # SGPIO Driver CONFIG_SGPIO_NPCM4XX=n + +# EMAC Driver +CONFIG_ETH_NPCM4XX=y + +# Networking config +CONFIG_NETWORKING=y +CONFIG_NET_L2_ETHERNET=y +CONFIG_NET_IPV4=y +CONFIG_NET_IPV6=n +CONFIG_NET_TCP=y +CONFIG_NET_SOCKETS=y +CONFIG_NET_SHELL=y +CONFIG_NET_TCP_ISN_RFC6528=n +CONFIG_NET_CONFIG_SETTINGS=y +CONFIG_NET_CONFIG_AUTO_INIT=y +CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" +CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" +CONFIG_NET_CONFIG_INIT_TIMEOUT=3 + +# Network driver config +CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/drivers/ethernet/CMakeLists.txt b/drivers/ethernet/CMakeLists.txt index dd5200cb52c74c..2dfc2bc6dd7c26 100644 --- a/drivers/ethernet/CMakeLists.txt +++ b/drivers/ethernet/CMakeLists.txt @@ -22,6 +22,7 @@ zephyr_sources_ifdef(CONFIG_ETH_STM32_HAL eth_stm32_hal.c) zephyr_sources_ifdef(CONFIG_ETH_LITEETH eth_liteeth.c) zephyr_sources_ifdef(CONFIG_ETH_W5500 eth_w5500.c) zephyr_sources_ifdef(CONFIG_DSA_KSZ8794 dsa_ksz8794.c) +zephyr_sources_ifdef(CONFIG_ETH_NPCM4XX eth_npcm4xx.c) if(CONFIG_ETH_NATIVE_POSIX) zephyr_library() diff --git a/drivers/ethernet/Kconfig b/drivers/ethernet/Kconfig index 94c41c943283a1..029a141514862d 100644 --- a/drivers/ethernet/Kconfig +++ b/drivers/ethernet/Kconfig @@ -57,5 +57,6 @@ source "drivers/ethernet/Kconfig.liteeth" source "drivers/ethernet/Kconfig.gecko" source "drivers/ethernet/Kconfig.w5500" source "drivers/ethernet/Kconfig.dsa" +source "drivers/ethernet/Kconfig.npcm4xx" endmenu # "Ethernet Drivers" diff --git a/drivers/ethernet/Kconfig.npcm4xx b/drivers/ethernet/Kconfig.npcm4xx new file mode 100644 index 00000000000000..293d6b485b29cf --- /dev/null +++ b/drivers/ethernet/Kconfig.npcm4xx @@ -0,0 +1,71 @@ +# Nuvoton Ethernet driver configuration options + +# SPDX-License-Identifier: Apache-2.0 + +DT_COMPAT_NUVOTON_NPCM4XX_ETHERNET := nuvoton,npcm4xx-ethernet + +config ETH_NPCM4XX + bool "Nuvoton NPCM4XX Ethernet driver" + depends on SOC_FAMILY_NPCM4XX + help + This option enables the ethernet driver for NPCM4XX family of + processors. + Say y if you wish to use ethernet on NPCM4XX MCU. + +config ETH_NPCM4XX_RX_THREAD_STACK_SIZE + int "RX thread stack size" + default 4096 + help + RX thread stack size + +config ETH_NPCM4XX_RX_THREAD_PRIO + int "RX thread priority" + default 3 + help + RX thread priority + +config ETH_NPCM4XX_PHY_ADDRESS + int "Phy address" + default 1 + help + The phy address to use. + +config ETH_NPCM4XX_RANDOM_MAC + bool "Random MAC address" + depends on ENTROPY_GENERATOR + default y + help + Generate a random MAC address dynamically. + +if !ETH_NPCM4XX_RANDOM_MAC + +config ETH_NPCM4XX_MAC3 + hex "MAC Address Byte 3" + default 0 + range 0 0xff + help + This is the byte 3 of the MAC address. + +config ETH_NPCM4XX_MAC4 + hex "MAC Address Byte 4" + default 0 + range 0 0xff + help + This is the byte 4 of the MAC address. + +config ETH_NPCM4XX_MAC5 + hex "MAC Address Byte 5" + default 0 + range 0 0xff + help + This is the byte 5 of the MAC address. + +endif # !ETH_NPCM4XX_RANDOM_MAC + +config ETH_NPCM4XX_CARRIER_CHECK_RX_IDLE_TIMEOUT_MS + int "Carrier check timeout period (ms)" + default 500 + range 100 30000 + help + Set the RX idle timeout period in milliseconds after which the + PHY's carrier status is re-evaluated. diff --git a/drivers/ethernet/eth_npcm4xx.c b/drivers/ethernet/eth_npcm4xx.c new file mode 100644 index 00000000000000..deac776c20a09c --- /dev/null +++ b/drivers/ethernet/eth_npcm4xx.c @@ -0,0 +1,1240 @@ +/* + * Copyright (c) 2024 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nuvoton_npcm4xx_ethernet + +#define LOG_MODULE_NAME eth_npcm4xx +#define LOG_LEVEL LOG_LEVEL_WRN + +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eth_npcm4xx.h" +#include "eth.h" + +#define ETH_NPCM4XX_MTU 1500 +#define PHY_ADDR PHY_ADDRESS + +#define NUVOTON_OUI_B0 0x08 +#define NUVOTON_OUI_B1 0x00 +#define NUVOTON_OUI_B2 0x27 + +#define ETH_NPCM4XX_REG_BASE ((struct emac_reg *)(DT_INST_REG_ADDR(0))) + +#define GET_FIRST_DMA_TX_DESC(heth) (heth->TxDesc) +#define IS_ETH_DMATXDESC_OWN(dma_tx_desc) (dma_tx_desc->Status & \ + ETH_DMATXDESC_OWN) + +/* Device constant configuration parameters */ +struct eth_npcm4xx_dev_cfg { + void (*config_func)(void); +}; + +/* Device run time data */ +struct eth_npcm4xx_dev_data { + struct net_if *iface; + uint8_t mac_addr[6]; + struct ETH_HANDLE_TYPE heth; + struct k_mutex tx_mutex; + struct k_sem rx_int_sem; + + K_KERNEL_STACK_MEMBER(rx_thread_stack, + CONFIG_ETH_NPCM4XX_RX_THREAD_STACK_SIZE); + struct k_thread rx_thread; + bool link_up; +}; + +#define __eth_npcm4xx_desc __aligned(4) +#define __eth_npcm4xx_buf __aligned(4) +/* Ethernet Rx DMA Descriptors */ +static struct ETH_DMA_DESCRIPTOR DMARxDscrTab[ETH_RXBUFNB] __eth_npcm4xx_desc; +/* Ethernet Tx DMA Descriptors */ +static struct ETH_DMA_DESCRIPTOR DMATxDscrTab[ETH_TXBUFNB] __eth_npcm4xx_desc; +/* Ethernet Receive Buffers */ +static uint8_t Rx_Buff[ETH_RXBUFNB][ETH_RX_BUF_SIZE] __eth_npcm4xx_buf; +/* Ethernet Transmit Buffers */ +static uint8_t Tx_Buff[ETH_TXBUFNB][ETH_TX_BUF_SIZE] __eth_npcm4xx_buf; + +inline int __ETH_LOCK(struct ETH_HANDLE_TYPE *__HANDLE__) +{ + if ((__HANDLE__)->Lock == ETH_LOCK_LOCKED) { + return ETH_RET_BUSY; + } else { + return 0; + } +} + +inline void __ETH_UNLOCK(struct ETH_HANDLE_TYPE *__HANDLE__) +{ + (__HANDLE__)->Lock = ETH_LOCK_UNLOCKED; +} + +enum ETH_RET_STATUS ETH_WritePHYRegister(struct ETH_HANDLE_TYPE *heth, + uint16_t PHYReg, uint32_t RegValue) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + uint32_t tmpreg = 0; + uint32_t timeout = 0xFFFF; + + /* Check the ETH peripheral state */ + if (heth->State == ETH_STATE_BUSY_WR) { + return ETH_RET_BUSY; + } + + heth->State = ETH_STATE_BUSY_WR; + + /* Keep only the CSR Clock Range CR[2:0] bits value */ + tmpreg = (emac_regs->MACMIIAR & (0x0F << NPCM4XX_MACMIIAR_CR)); + /* Prepare the MII register address value */ + /* Set the PHY device address */ + tmpreg |= (((uint32_t)heth->InitParm.PhyAddress << 11) & (0x1F << NPCM4XX_MACMIIAR_PA)); + /* Set the PHY register address */ + tmpreg |= (((uint32_t)PHYReg << 6) & (0x1F << NPCM4XX_MACMIIAR_MR)); + /* Set the write mode */ + tmpreg |= BIT(NPCM4XX_MACMIIAR_MW); + /* Set the MII Busy bit */ + tmpreg |= BIT(NPCM4XX_MACMIIAR_MB); + + /* Give the value to the MII data register */ + emac_regs->MACMIIDR = (uint16_t)RegValue; + /* Write the result value into the MII Address register */ + emac_regs->MACMIIAR = tmpreg; + + /* Check for the Busy flag */ + while ((tmpreg & BIT(NPCM4XX_MACMIIAR_MB)) == BIT(NPCM4XX_MACMIIAR_MB)) { + /* Check for the Timeout */ + if ((timeout--) == 0) { + heth->State = ETH_STATE_READY; + __ETH_UNLOCK(heth); /* Process Unlocked */ + + return ETH_RET_TIMEOUT; + } + tmpreg = emac_regs->MACMIIAR; + } + + heth->State = ETH_STATE_READY; + + return ETH_RET_OK; +} + +enum ETH_RET_STATUS ETH_ReadPHYRegister(struct ETH_HANDLE_TYPE *heth, + uint16_t PHYReg, uint32_t *RegValue) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + uint32_t tmpreg = 0; + uint32_t timeout = 0xFFFF; + + /* Check the ETH peripheral state */ + if (heth->State == ETH_STATE_BUSY_RD) { + return ETH_RET_BUSY; + } + + heth->State = ETH_STATE_BUSY_RD; + + /* Keep only the CSR Clock Range CR[2:0] bits value */ + tmpreg = emac_regs->MACMIIAR & (0x0F << NPCM4XX_MACMIIAR_CR); + /* Prepare the MII address register value */ + /* Set the PHY device address */ + tmpreg |= (((uint32_t)heth->InitParm.PhyAddress << 11) & (0x1F << NPCM4XX_MACMIIAR_PA)); + /* Set the PHY register address */ + tmpreg |= (((uint32_t)PHYReg << 6) & (0x1F << NPCM4XX_MACMIIAR_MR)); + /* Set the read mode */ + tmpreg &= ~BIT(NPCM4XX_MACMIIAR_MW); + /* Set the MII Busy bit */ + tmpreg |= BIT(NPCM4XX_MACMIIAR_MB); + /* Write the result value into the MII Address register */ + emac_regs->MACMIIAR = tmpreg; + + /* Check for the Busy flag */ + while ((tmpreg & BIT(NPCM4XX_MACMIIAR_MB)) == BIT(NPCM4XX_MACMIIAR_MB)) { + /* Check for the Timeout */ + if ((timeout--) == 0) { + heth->State = ETH_STATE_READY; + __ETH_UNLOCK(heth); /* Process Unlocked */ + + return ETH_RET_TIMEOUT; + } + tmpreg = emac_regs->MACMIIAR; + } + + /* Get MACMIIDR value */ + *RegValue = (uint16_t)(emac_regs->MACMIIDR); + + heth->State = ETH_STATE_READY; + + return ETH_RET_OK; +} + +enum ETH_RET_STATUS ETH_TransmitFrame(struct ETH_HANDLE_TYPE *heth, uint32_t FrameLength) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + uint32_t bufcount = 0, size = 0, i = 0; + + if (__ETH_LOCK(heth)) { + return ETH_RET_BUSY; + } + + heth->State = ETH_STATE_BUSY; + + if (FrameLength == 0) { + heth->State = ETH_STATE_READY; + __ETH_UNLOCK(heth); + + LOG_ERR("FrameLength error!\r\n"); + return ETH_RET_ERROR; + } + + /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */ + if (((heth->TxDesc)->Status & ETH_DMATXDESC_OWN) != 0) { + /* OWN bit set */ + heth->State = ETH_STATE_BUSY_TX; + __ETH_UNLOCK(heth); + + LOG_DBG("OWN bit set!\r\n"); + return ETH_RET_ERROR; + } + + /* Get the number of needed Tx buffers for the current frame */ + if (FrameLength > ETH_TX_BUF_SIZE) { + bufcount = FrameLength / ETH_TX_BUF_SIZE; + if (FrameLength % ETH_TX_BUF_SIZE) { + bufcount++; + } + } else { + bufcount = 1; + } + + if (bufcount == 1) { + /* Set LAST and FIRST segment */ + heth->TxDesc->Status |= ETH_DMATXDESC_FS|ETH_DMATXDESC_LS; + /* Set frame size */ + heth->TxDesc->ControlBufferSize = (FrameLength & ETH_DMATXDESC_TBS1); + /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */ + heth->TxDesc->Status |= ETH_DMATXDESC_OWN; + /* Point to next descriptor */ + heth->TxDesc = (struct ETH_DMA_DESCRIPTOR *)(heth->TxDesc->Buffer2NextDescAddr); + } else { + for (i = 0; i < bufcount; i++) { + /* Clear FIRST and LAST segment bits */ + heth->TxDesc->Status &= ~(ETH_DMATXDESC_FS | ETH_DMATXDESC_LS); + if (i == 0) { + /* Setting the first segment bit */ + heth->TxDesc->Status |= ETH_DMATXDESC_FS; + } + /* Program size */ + heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1); + if (i == (bufcount-1)) { + /* Setting the last segment bit */ + heth->TxDesc->Status |= ETH_DMATXDESC_LS; + size = FrameLength - (bufcount-1)*ETH_TX_BUF_SIZE; + heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1); + } + /* Set Own bit of the Tx descriptor Status: gives the buffer + * back to ETHERNET DMA + */ + heth->TxDesc->Status |= ETH_DMATXDESC_OWN; + /* point to next descriptor */ + heth->TxDesc = (struct ETH_DMA_DESCRIPTOR *) + (heth->TxDesc->Buffer2NextDescAddr); + } + } + + /* When Tx Buffer unavailable flag is set: clear it and resume transmission */ + if ((emac_regs->DMASR & BIT(NPCM4XX_DMASR_TBUS)) != 0) { + /* Clear TBUS ETHERNET DMA flag */ + emac_regs->DMASR = BIT(NPCM4XX_DMASR_TBUS); + /* Resume DMA transmission*/ + emac_regs->DMATPDR = 0; + } + + heth->State = ETH_STATE_READY; + + __ETH_UNLOCK(heth); + + return ETH_RET_OK; +} + +enum ETH_RET_STATUS ETH_GetReceivedFrame(struct ETH_HANDLE_TYPE *heth) +{ + uint32_t descriptorscancounter = 0U; + + /* Process Locked */ + if (__ETH_LOCK(heth)) { + return ETH_RET_BUSY; + } + + /* Set ETH HAL State to BUSY */ + heth->State = ETH_STATE_BUSY; + + /* Scan descriptors owned by CPU */ + while (((heth->RxDesc->Status & ETH_DMARXDESC_OWN) == 0) && + (descriptorscancounter < ETH_RXBUFNB)) { + /* Just for security */ + descriptorscancounter++; + + /* Check if first segment in frame */ + if ((heth->RxDesc->Status & (ETH_DMARXDESC_FS | ETH_DMARXDESC_LS)) == + (uint32_t)ETH_DMARXDESC_FS) { + heth->RxFrameInfos.FSRxDesc = heth->RxDesc; + heth->RxFrameInfos.SegCount = 1U; + /* Point to next descriptor */ + heth->RxDesc = (struct ETH_DMA_DESCRIPTOR *) + (heth->RxDesc->Buffer2NextDescAddr); + } + /* Check if intermediate segment */ + else if ((heth->RxDesc->Status & (ETH_DMARXDESC_LS | ETH_DMARXDESC_FS)) == 0) { + /* Increment segment count */ + (heth->RxFrameInfos.SegCount)++; + /* Point to next descriptor */ + heth->RxDesc = (struct ETH_DMA_DESCRIPTOR *) + (heth->RxDesc->Buffer2NextDescAddr); + } else { + /* Should be last segment */ + + /* Last segment */ + heth->RxFrameInfos.LSRxDesc = heth->RxDesc; + + /* Increment segment count */ + (heth->RxFrameInfos.SegCount)++; + + /* Check if last segment is first segment: one segment contains the frame */ + if ((heth->RxFrameInfos.SegCount) == 1U) { + heth->RxFrameInfos.FSRxDesc = heth->RxDesc; + } + + /* Get the Frame Length of the received packet: + * substruct 4 bytes of the CRC + */ + heth->RxFrameInfos.length = (((heth->RxDesc)->Status & + ETH_DMARXDESC_FL) >> 16) - 4U; + + /* Get the address of the buffer start address */ + heth->RxFrameInfos.buffer = ((heth->RxFrameInfos).FSRxDesc)->Buffer1Addr; + + /* Point to next descriptor */ + heth->RxDesc = (struct ETH_DMA_DESCRIPTOR *) + (heth->RxDesc->Buffer2NextDescAddr); + + /* Set HAL State to Ready */ + heth->State = ETH_STATE_READY; + + /* Process Unlocked */ + __ETH_UNLOCK(heth); + + /* Return function status */ + return ETH_RET_OK; + } + } + /* Set HAL State to Ready */ + heth->State = ETH_STATE_READY; + /* Process Unlocked */ + __ETH_UNLOCK(heth); + /* Return function status */ + return ETH_RET_ERROR; +} + +static int eth_tx(const struct device *dev, struct net_pkt *pkt) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + struct eth_npcm4xx_dev_data *dev_data = dev->data; + struct ETH_HANDLE_TYPE *heth; + uint8_t *dma_buffer; + int res; + size_t total_len; + struct ETH_DMA_DESCRIPTOR *dma_tx_desc; + enum ETH_RET_STATUS hal_ret = ETH_RET_OK; + + __ASSERT_NO_MSG(pkt != NULL); + __ASSERT_NO_MSG(pkt->frags != NULL); + __ASSERT_NO_MSG(dev != NULL); + __ASSERT_NO_MSG(dev_data != NULL); + + heth = &dev_data->heth; + + k_mutex_lock(&dev_data->tx_mutex, K_FOREVER); + + total_len = net_pkt_get_len(pkt); + if (total_len > ETH_TX_BUF_SIZE) { + LOG_ERR("PKT too big"); + res = -EIO; + goto error; + } + + dma_tx_desc = GET_FIRST_DMA_TX_DESC(heth); + while (IS_ETH_DMATXDESC_OWN(dma_tx_desc) != 0) { + k_yield(); + } + + dma_buffer = (uint8_t *)(dma_tx_desc->Buffer1Addr); + + if (net_pkt_read(pkt, dma_buffer, total_len)) { + res = -ENOBUFS; + goto error; + } + + + hal_ret = ETH_TransmitFrame(heth, total_len); + + if (hal_ret != ETH_RET_OK) { + LOG_ERR("HAL_ETH_Transmit: failed!"); + res = -EIO; + goto error; + } + + if ((emac_regs->DMASR & BIT(NPCM4XX_DMASR_TUS)) != 0) { + /* Clear TUS ETHERNET DMA flag */ + emac_regs->DMASR = BIT(NPCM4XX_DMASR_TUS); + /* Resume DMA transmission*/ + emac_regs->DMATPDR = 0; + res = -EIO; + goto error; + } + + res = 0; +error: + k_mutex_unlock(&dev_data->tx_mutex); + + return res; +} + +static struct net_if *get_iface(struct eth_npcm4xx_dev_data *ctx, + uint16_t vlan_tag) +{ + ARG_UNUSED(vlan_tag); + + return ctx->iface; +} + +static struct net_pkt *eth_rx(const struct device *dev, uint16_t *vlan_tag) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + struct eth_npcm4xx_dev_data *dev_data; + struct ETH_HANDLE_TYPE *heth; + struct ETH_DMA_DESCRIPTOR *dma_rx_desc; + + struct net_pkt *pkt; + size_t total_len; + uint8_t *dma_buffer; + enum ETH_RET_STATUS hal_ret = ETH_RET_OK; + + __ASSERT_NO_MSG(dev != NULL); + + dev_data = dev->data; + + __ASSERT_NO_MSG(dev_data != NULL); + + heth = &dev_data->heth; + + + hal_ret = ETH_GetReceivedFrame(heth); + if (hal_ret != ETH_RET_OK) { + /* no frame available */ + return NULL; + } + + total_len = heth->RxFrameInfos.length; + dma_buffer = (uint8_t *)heth->RxFrameInfos.buffer; + + pkt = net_pkt_rx_alloc_with_buffer(get_iface(dev_data, *vlan_tag), + total_len, AF_UNSPEC, 0, K_NO_WAIT); + if (!pkt) { + LOG_ERR("Failed to obtain RX buffer"); + goto release_desc; + } + + if (net_pkt_write(pkt, dma_buffer, total_len)) { + LOG_ERR("Failed to append RX buffer to context buffer"); + net_pkt_unref(pkt); + pkt = NULL; + goto release_desc; + } + +release_desc: + + /* Release descriptors to DMA */ + /* Point to first descriptor */ + dma_rx_desc = heth->RxFrameInfos.FSRxDesc; + /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ + for (int i = 0; i < heth->RxFrameInfos.SegCount; i++) { + dma_rx_desc->Status |= ETH_DMARXDESC_OWN; + dma_rx_desc = (struct ETH_DMA_DESCRIPTOR *) + (dma_rx_desc->Buffer2NextDescAddr); + } + + /* Clear Segment_Count */ + heth->RxFrameInfos.SegCount = 0; + + /* When Rx Buffer unavailable flag is set: clear it + * and resume reception. + */ + if ((emac_regs->DMASR & BIT(NPCM4XX_DMASR_RBUS)) != 0) { + /* Clear RBUS ETHERNET DMA flag */ + emac_regs->DMASR = BIT(NPCM4XX_DMASR_RBUS); + /* Resume DMA reception */ + emac_regs->DMARPDR = 0; + } + + if (!pkt) { + eth_stats_update_errors_rx(get_iface(dev_data, *vlan_tag)); + } + + return pkt; +} + +static void rx_thread(void *arg1, void *unused1, void *unused2) +{ + uint16_t vlan_tag = NET_VLAN_TAG_UNSPEC; + const struct device *dev; + struct eth_npcm4xx_dev_data *dev_data; + struct net_pkt *pkt; + int res; + uint32_t status; + enum ETH_RET_STATUS hal_ret = ETH_RET_OK; + + __ASSERT_NO_MSG(arg1 != NULL); + ARG_UNUSED(unused1); + ARG_UNUSED(unused2); + + dev = (const struct device *)arg1; + dev_data = dev->data; + + __ASSERT_NO_MSG(dev_data != NULL); + + while (1) { + res = k_sem_take(&dev_data->rx_int_sem, + K_MSEC(CONFIG_ETH_NPCM4XX_CARRIER_CHECK_RX_IDLE_TIMEOUT_MS)); + if (res == 0) { + /* semaphore taken, update link status and receive packets */ + if (dev_data->link_up != true) { + dev_data->link_up = true; + net_eth_carrier_on(get_iface(dev_data, + vlan_tag)); + } + while ((pkt = eth_rx(dev, &vlan_tag)) != NULL) { + res = net_recv_data(net_pkt_iface(pkt), pkt); + if (res < 0) { + eth_stats_update_errors_rx( + net_pkt_iface(pkt)); + LOG_ERR("Failed to enqueue frame " + "into RX queue: %d", res); + net_pkt_unref(pkt); + } + } + } else if (res == -EAGAIN) { + /* semaphore timeout period expired, check link status */ + hal_ret = ETH_ReadPHYRegister(&dev_data->heth, + PHY_BSR, (uint32_t *) &status); + if (hal_ret == ETH_RET_OK) { + if ((status & PHY_LINKED_STATUS) == PHY_LINKED_STATUS) { + if (dev_data->link_up != true) { + dev_data->link_up = true; + net_eth_carrier_on( + get_iface(dev_data, + vlan_tag)); + } + } else { + if (dev_data->link_up != false) { + dev_data->link_up = false; + net_eth_carrier_off( + get_iface(dev_data, + vlan_tag)); + } + } + } + } + } +} + +static void eth_isr(const struct device *dev) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + struct eth_npcm4xx_dev_data *dev_data; + uint32_t sts = emac_regs->DMASR; + + dev_data = dev->data; + + /* Frame received */ + if (sts & BIT(NPCM4XX_DMASR_RS)) { + /* Clear the Eth DMA Rx IT pending bits */ + emac_regs->DMASR = BIT(NPCM4XX_DMASR_RS); + dev_data->heth.State = ETH_STATE_READY; + /* TODO: Need to check */ + k_sem_give(&dev_data->rx_int_sem); + __ETH_UNLOCK(&dev_data->heth); + } + /* Frame transmitted */ + if (sts & BIT(NPCM4XX_DMASR_TS)) { + /* Clear the Eth DMA Rx IT pending bits */ + emac_regs->DMASR = BIT(NPCM4XX_DMASR_TS); + + } + /* Normal Interrupt Summary */ + if (sts & BIT(NPCM4XX_DMASR_NIS)) { + emac_regs->DMASR = BIT(NPCM4XX_DMASR_NIS); + } + + /* Abnormal Interrupt Summary */ + if (sts & BIT(NPCM4XX_DMASR_AIS)) { + /* Clear the ETH DMA Error flags */ + emac_regs->DMASR = BIT(NPCM4XX_DMASR_AIS); + } +} + +#if defined(CONFIG_ETH_NPCM4XX_RANDOM_MAC) +static void generate_mac(uint8_t *mac_addr) +{ + gen_random_mac(mac_addr, NUVOTON_OUI_B0, NUVOTON_OUI_B1, NUVOTON_OUI_B2); +} +#endif + +void __SetSMIClock(void) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + const struct device *const clk_dev = device_get_binding(NPCM4XX_CLK_CTRL_NAME); + struct npcm4xx_clk_cfg clk_cfg; + uint32_t core_clk; + int ret; + uint32_t value = 0; + + clk_cfg.bus = NPCM4XX_CLOCK_BUS_CORE; + + /* Clock Range (1 MHz ~ 2.5 MHz) */ + value = (emac_regs->MACMIIAR & (0x0F << NPCM4XX_MACMIIAR_CR)); + + ret = clock_control_get_rate(clk_dev, (clock_control_subsys_t *) + &clk_cfg, &core_clk); + + if (ret < 0) { + LOG_ERR("Get ITIM clock rate error %d", ret); + } + + if (core_clk < 10000000) { + value |= (0x08 << NPCM4XX_MACMIIAR_CR); /* DIV 4 */ + } else if ((core_clk >= 10000000) && (core_clk < 20000000)) { + value |= (0x0A << NPCM4XX_MACMIIAR_CR); /* DIV 8 */ + } else if ((core_clk >= 20000000) && (core_clk <= 35000000)) { + value |= (0x02 << NPCM4XX_MACMIIAR_CR); /* DIV 16 */ + } else if ((core_clk >= 35000000) && (core_clk < 60000000)) { + value |= (0x03 << NPCM4XX_MACMIIAR_CR); /* DIV 26 */ + } else if ((core_clk >= 60000000) && (core_clk < 100000000)) { + value |= (0x00 << NPCM4XX_MACMIIAR_CR); /* DIV 42 */ + } + + emac_regs->MACMIIAR = value; +} + + + +void ETH_MACAddressConfig(uint32_t MacAddr, uint8_t *Addr, uint8_t IsSrcAddr, uint8_t MacAddrMsk) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + uint32_t addr_L = 0; + uint32_t addr_H = 0; + + if (MacAddr > 31) { + return; + } + + addr_H = ((uint32_t)Addr[5] << 8) | (uint32_t)Addr[4]; + addr_L = ((uint32_t)Addr[3] << 24) | ((uint32_t)Addr[2] << 16) | + ((uint32_t)Addr[1] << 8) | Addr[0]; + + if (MacAddr >= 1) { + addr_H |= BIT(NPCM4XX_MACA1HR_AE); + if (IsSrcAddr) { + addr_H |= BIT(NPCM4XX_MACA1HR_SA); + } + if (MacAddrMsk) { + addr_H |= ((MacAddrMsk & 0x3F) << NPCM4XX_MACA1HR_MBC); + } + } + + if (MacAddr <= 15) { + *((uint32_t *)((uint32_t)(&(emac_regs->MACA0HR)) + (MacAddr*8))) = addr_H; + *((uint32_t *)((uint32_t)(&(emac_regs->MACA0LR)) + (MacAddr*8))) = addr_L; + } else { + *((uint32_t *)((uint32_t)(&(emac_regs->MACA16HR)) + ((MacAddr-16)*8))) = addr_H; + *((uint32_t *)((uint32_t)(&(emac_regs->MACA16LR)) + ((MacAddr-16)*8))) = addr_L; + } +} + +void ETH_MACDMAConfig(struct ETH_HANDLE_TYPE *heth, uint32_t err) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + uint32_t reg = 0; + + /* Auto-negotiation failed */ + if (err == 1) { + /* Set Ethernet duplex mode to Full-duplex, and speed to 100Mbps*/ + (heth->InitParm).DuplexMode = ETH_MODE_FULLDUPLEX; + (heth->InitParm).Speed = ETH_SPEED_100M; + } + + /*------------------------ ETHERNET MACCR Configuration ---------------------------*/ + /* Speed */ + if (heth->InitParm.Speed == ETH_SPEED_100M) { + reg |= BIT(NPCM4XX_MACCR_FES); + } else { + reg &= ~BIT(NPCM4XX_MACCR_FES); + } + + /* Duplex mode */ + if (heth->InitParm.DuplexMode == ETH_MODE_FULLDUPLEX) { + reg |= BIT(NPCM4XX_MACCR_DM); + } else { + reg &= ~BIT(NPCM4XX_MACCR_DM); + } + + /* Ipv4 checksum */ + if (heth->InitParm.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE) { + reg |= BIT(NPCM4XX_MACCR_IPCO); + } else { + reg &= ~BIT(NPCM4XX_MACCR_IPCO); + } + + /* Retry disable */ + reg |= BIT(NPCM4XX_MACCR_RD); + emac_regs->MACCR = reg; + + /*----------------------- ETHERNET MACFFR Configuration ---------------------------*/ + /* forwards all control frames to application except Pause frame. */ + emac_regs->MACFFR = BIT(NPCM4XX_MACFFR_PCF_ForwardExcptPause); + + /*----------------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/ + emac_regs->MACHTHR = 0; + emac_regs->MACHTLR = 0; + + /*----------------------- ETHERNET MACFCR Configuration ---------------------------*/ + /* Zero-quanta pause disable */ + emac_regs->MACFCR |= BIT(NPCM4XX_MACFCR_ZQPD); + + /*----------------------- ETHERNET MACVLANTR Configuration ------------------------*/ + emac_regs->MACVLANTR = 0; + + /* Ethernet DMA default initialization ************************************/ + /*----------------------- ETHERNET DMAOMR Configuration ---------------------------*/ + emac_regs->DMAOMR = (BIT(NPCM4XX_DMAOMR_RSF) | BIT(NPCM4XX_DMAOMR_TSF)); + /*----------------------- ETHERNET DMABMR Configuration ------------------*/ + emac_regs->DMABMR = (0x80000 | 0x400 | BIT(NPCM4XX_DMABMR_EDE)); + + if ((heth->InitParm).RxMode == ETH_RXINTERRUPT_MODE) { + /* Enable the Ethernet Rx Interrupt */ + emac_regs->DMAIER |= (BIT(NPCM4XX_DMAIER_NISE) | BIT(NPCM4XX_DMAIER_RIE)); + } + + /* Initialize MAC address in ethernet MAC */ + ETH_MACAddressConfig(0, heth->InitParm.MACAddr, 0, 0); +} + +void ETH_Set_Negotiation(struct ETH_HANDLE_TYPE *heth) +{ + uint32_t value = 0; + /* Read the result */ +#if (EMAC_PHY == IP101A) + ETH_ReadPHYRegister(heth, PHY_SMR, &value); + if (value & PHY_SMR_DUPLEX) { + (heth->InitParm).DuplexMode = ETH_MODE_FULLDUPLEX; + LOG_DBG("full-"); + } else { + (heth->InitParm).DuplexMode = ETH_MODE_HALFDUPLEX; + LOG_DBG("half-"); + } + if (value & PHY_SMR_SPEED) { + (heth->InitParm).Speed = ETH_SPEED_100M; + LOG_DBG("100 \r\n"); + } else { + (heth->InitParm).Speed = ETH_SPEED_10M; + LOG_DBG("10 \r\n"); + } + +#elif (EMAC_PHY == DP83848) + ETH_ReadPHYRegister(heth, PHY_STS, &value); + if (value & PHY_STS_DUPLEX) { + (heth->InitParm).DuplexMode = ETH_MODE_FULLDUPLEX; + LOG_DBG("full-"); + } else { + (heth->InitParm).DuplexMode = ETH_MODE_HALFDUPLEX; + LOG_DBG("half-"); + } + if (value & PHY_STS_SPEED) { + (heth->InitParm).Speed = ETH_SPEED_10M; + LOG_DBG("10 \r\n"); + } else { + (heth->InitParm).Speed = ETH_SPEED_100M; + LOG_DBG("100 \r\n"); + } +#endif + /*-------------------- MAC DMA initialization and configuration ----------------*/ + /* Configure MAC and DMA */ + ETH_MACDMAConfig(heth, 0); +} + +enum ETH_RET_STATUS ETH_DMATxDescListInit(struct ETH_HANDLE_TYPE *heth, + struct ETH_DMA_DESCRIPTOR *DMATxDescTab, uint8_t *TxBuff, uint32_t TxBuffCount) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + uint32_t i = 0; + struct ETH_DMA_DESCRIPTOR *dmatxdesc; + + if (__ETH_LOCK(heth)) { + return ETH_RET_BUSY; + } + + heth->State = ETH_STATE_BUSY; + + /* Set the DMATxDescToSet pointer with the first one of the DMATxDescTab list */ + heth->TxDesc = DMATxDescTab; + + /* Fill each DMATxDesc descriptor with the right values */ + for (i = 0; i < TxBuffCount; i++) { + /* Get the pointer on the member (i) of the Tx Desc list */ + dmatxdesc = DMATxDescTab + i; + /* Set Second Address Chained bit */ + dmatxdesc->Status = ETH_DMATXDESC_TCH; + /* Set Buffer1 address pointer */ + dmatxdesc->Buffer1Addr = (uint32_t)(&TxBuff[i*ETH_TX_BUF_SIZE]); + if ((heth->InitParm).ChecksumMode == ETH_CHECKSUM_BY_HARDWARE) { + /* Set the DMA Tx descriptors checksum insertion */ + dmatxdesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL; + } + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + if (i < (TxBuffCount-1)) { + /* Set next descriptor address register with next descriptor base address */ + dmatxdesc->Buffer2NextDescAddr = (uint32_t)(DMATxDescTab+i+1); + } else { + /* For last descriptor, set next descriptor address register equal to the + * first descriptor base address + */ + dmatxdesc->Buffer2NextDescAddr = (uint32_t) DMATxDescTab; + } + } + /* Set Transmit Descriptor List Address Register */ + emac_regs->DMATDLAR = (uint32_t) DMATxDescTab; + + heth->State = ETH_STATE_READY; + + __ETH_UNLOCK(heth); + + return ETH_RET_OK; +} + +/*------------------------------------------------------------------------------------------------*/ +/** + * @brief Initializes the DMA Rx descriptors in chain mode. + * @param [in] heth The Ethernet handler + * @param [in] DMARxDescTab Pointer to the first Rx desc list + * @param [in] RxBuff Pointer to the first RxBuffer list + * @param [in] RxBuffCount Number of the used Rx desc in the list + * @return The return status + */ +/*------------------------------------------------------------------------------------------------*/ +enum ETH_RET_STATUS ETH_DMARxDescListInit(struct ETH_HANDLE_TYPE *heth, + struct ETH_DMA_DESCRIPTOR *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + uint32_t i = 0; + struct ETH_DMA_DESCRIPTOR *DMARxDesc; + + if (__ETH_LOCK(heth)) { + return ETH_RET_BUSY; + } + + heth->State = ETH_STATE_BUSY; + + /* Set the Ethernet RxDesc pointer with the first one of the DMARxDescTab list */ + heth->RxDesc = DMARxDescTab; + + /* Fill each DMARxDesc descriptor with the right values */ + for (i = 0; i < RxBuffCount; i++) { + /* Get the pointer on the member (i) of the Rx Desc list */ + DMARxDesc = DMARxDescTab+i; + /* Set Own bit of the Rx descriptor Status */ + DMARxDesc->Status = ETH_DMARXDESC_OWN; + /* Set Buffer1 size and Second Address Chained bit */ + DMARxDesc->ControlBufferSize = (ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE); + /* Set Buffer1 address pointer */ + DMARxDesc->Buffer1Addr = (uint32_t)(&RxBuff[i*ETH_RX_BUF_SIZE]); + if ((heth->InitParm).RxMode == ETH_RXINTERRUPT_MODE) { + /* Enable Ethernet DMA Rx Descriptor interrupt */ + DMARxDesc->ControlBufferSize &= ~ETH_DMARXDESC_DIC; + } + + /* Initialize the next descriptor with the Next Descriptor Polling Enable */ + if (i < (RxBuffCount-1)) { + /* Set next descriptor address register with next descriptor base address */ + DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab+i+1); + } else { + /* For last descriptor, set next descriptor address register equal to the + * first descriptor base address + */ + DMARxDesc->Buffer2NextDescAddr = (uint32_t)(DMARxDescTab); + } + } + + /* Set Receive Descriptor List Address Register */ + emac_regs->DMARDLAR = (uint32_t) DMARxDescTab; + + heth->State = ETH_STATE_READY; + + __ETH_UNLOCK(heth); + + return ETH_RET_OK; +} + +enum ETH_RET_STATUS ETH_Start(struct ETH_HANDLE_TYPE *heth) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + + if (__ETH_LOCK(heth)) { + return ETH_RET_BUSY; + } + + heth->State = ETH_STATE_BUSY; + + /* Enable the MAC transmission */ + emac_regs->MACCR |= BIT(NPCM4XX_MACCR_TE); + /* Enable the MAC reception */ + emac_regs->MACCR |= BIT(NPCM4XX_MACCR_RE); + /* Set the Flush Transmit FIFO bit */ + emac_regs->DMAOMR |= BIT(NPCM4XX_DMAOMR_FTF); + /* Enable the DMA transmission */ + emac_regs->DMAOMR |= BIT(NPCM4XX_DMAOMR_ST); + /* Enable the DMA reception */ + emac_regs->DMAOMR |= BIT(NPCM4XX_DMAOMR_SR); + + LOG_DBG("emac registers :\r\n"); + LOG_DBG("MACCR = %08x\r\n", emac_regs->MACCR); + LOG_DBG("MACFFR = %08x\r\n", emac_regs->MACFFR); + LOG_DBG("MACFCR = %08x\r\n", emac_regs->MACFCR); + + LOG_DBG("DMABMR = %08x\r\n", emac_regs->DMABMR); + LOG_DBG("DMAOMR = %08x\r\n", emac_regs->DMAOMR); + + heth->State = ETH_STATE_READY; + + __ETH_UNLOCK(heth); + + return ETH_RET_OK; +} + +static int eth_initialize(const struct device *dev) +{ + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + struct eth_npcm4xx_dev_data *dev_data; + struct ETH_HANDLE_TYPE *heth; + uint32_t value = 0; + uint32_t timeout = 0; + + dev_data = dev->data; + heth = &dev_data->heth; + + heth->InitParm.MACAddr = dev_data->mac_addr; + + if (heth->State == ETH_STATE_RESET) { + __ETH_UNLOCK(heth); + } + + /* EMAC Software reset */ + RegSetBit(emac_regs->DMABMR, BIT(NPCM4XX_DMABMR_SR)); + timeout = 0; + while ((emac_regs->DMABMR & BIT(NPCM4XX_DMABMR_SR)) != 0) { + timeout++; + if (timeout > 0xFFFFFF) { + return -ENOTSUP; + } + } + +#if defined(CONFIG_ETH_NPCM4XX_RANDOM_MAC) + generate_mac(dev_data->mac_addr); + heth->InitParm.MACAddr = dev_data->mac_addr; +#endif + + /*-------------------------------- MAC Initialization ----------------------*/ + /* Clock Range (1 MHz ~ 2.5 MHz) */ + __SetSMIClock(); + + /*-------------------- PHY initialization and configuration ----------------*/ + /* Reset PHY */ + if (ETH_WritePHYRegister(heth, PHY_BCR, PHY_BCR_RESET) != ETH_RET_OK) { + ETH_MACDMAConfig(heth, 1); + heth->State = ETH_STATE_READY; + + LOG_DBG("Reset PHY error.\r\n"); + return ETH_RET_ERROR; + } + /* Delay to assure PHY reset */ + timeout = 0xFFF; + while (timeout--) + ; + + /* PHY loopback mode */ + if ((heth->InitParm).PhyLoopback == 1) { + ETH_ReadPHYRegister(heth, PHY_BCR, &value); + value |= PHY_BCR_LOOPBACK; + ETH_WritePHYRegister(heth, PHY_BCR, value); + } + + /* Negotiation */ + if ((heth->InitParm).AutoNegotiation == 1) { + timeout = 0xFFFF; + /* We wait for linked status and auto-negotiation completed status */ + while (timeout-- > 0) { + ETH_ReadPHYRegister(heth, PHY_BSR, &value); + if ((value & (PHY_BSR_LINKED_STATUS | PHY_BSR_AUTONEGO_COMPLETE)) == + (PHY_BSR_LINKED_STATUS | PHY_BSR_AUTONEGO_COMPLETE)) { + LOG_DBG("PHY_BSR : %4xX\r\n", value); + break; + } + + if (timeout == 0) { + ETH_MACDMAConfig(heth, 1); + heth->State = ETH_STATE_READY; + __ETH_UNLOCK(heth); + LOG_ERR("Wait error.\r\n"); + + return -ENOTSUP; + } + } + + LOG_DBG("auto-nego. : "); + } else { + /* Manual negotiation */ + if (((heth->InitParm).DuplexMode == ETH_MODE_FULLDUPLEX) && + ((heth->InitParm).Speed == ETH_SPEED_100M)) { + value = PHY_BCR_FULLDUPLEX_100M; + } else if (((heth->InitParm).DuplexMode == ETH_MODE_FULLDUPLEX) && + ((heth->InitParm).Speed == ETH_SPEED_10M)) { + value = PHY_BCR_FULLDUPLEX_10M; + } else if (((heth->InitParm).DuplexMode == ETH_MODE_HALFDUPLEX) && + ((heth->InitParm).Speed == ETH_SPEED_100M)) { + value = PHY_BCR_HALFDUPLEX_100M; + } else if (((heth->InitParm).DuplexMode == ETH_MODE_HALFDUPLEX) && + ((heth->InitParm).Speed == ETH_SPEED_10M)) { + value = PHY_BCR_HALFDUPLEX_10M; + } + + /* PHY loopback mode */ + if ((heth->InitParm).PhyLoopback == 1) { + value |= PHY_BCR_LOOPBACK; + } + + if (ETH_WritePHYRegister(heth, PHY_BCR, value) != ETH_RET_OK) { + ETH_MACDMAConfig(heth, 1); + heth->State = ETH_STATE_READY; + + return ETH_RET_ERROR; + } + timeout = 0x7FFF; + /* We wait for linked status */ + while (timeout-- > 0) { + ETH_ReadPHYRegister(heth, PHY_BSR, &value); + if (value & PHY_BSR_LINKED_STATUS) { + LOG_DBG("PHY_BSR : %4x\r\n", value); + break; + } + + if (timeout == 0) { + ETH_MACDMAConfig(heth, 1); + heth->State = ETH_STATE_READY; + __ETH_UNLOCK(heth); + LOG_ERR("Wait error.\r\n"); + + return ETH_RET_TIMEOUT; + } + } + + LOG_DBG("manual-nego.: "); + } + ETH_Set_Negotiation(heth); + + heth->State = ETH_STATE_READY; + + dev_data->link_up = false; + + /* Initialize semaphores */ + k_mutex_init(&dev_data->tx_mutex); + k_sem_init(&dev_data->rx_int_sem, 0, K_SEM_MAX_LIMIT); + + /* Start interruption-poll thread */ + k_thread_create(&dev_data->rx_thread, dev_data->rx_thread_stack, + K_KERNEL_STACK_SIZEOF(dev_data->rx_thread_stack), + rx_thread, (void *) dev, NULL, NULL, + K_PRIO_COOP(CONFIG_ETH_NPCM4XX_RX_THREAD_PRIO), + 0, K_NO_WAIT); + + k_thread_name_set(&dev_data->rx_thread, "stm_eth"); + + /* Initialize Tx Descriptors list: Chain Mode */ + ETH_DMATxDescListInit(heth, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); + + /* Initialize Rx Descriptors list: Chain Mode */ + ETH_DMARxDescListInit(heth, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); + + if (ETH_Start(heth) != ETH_RET_OK) { + LOG_ERR("ETH_Start{_IT} failed"); + } + + /* Mask all Rx interrupt */ + emac_regs->MMCRIMR = 0xFFFFFFFF; + /* Mask all Tx interrupt */ + emac_regs->MMCTIMR = 0xFFFFFFFF; + emac_regs->mmc_ipc_intr_mask_rx = 0xFFFFFFFF; + + LOG_DBG("MAC %02x:%02x:%02x:%02x:%02x:%02x", + dev_data->mac_addr[0], dev_data->mac_addr[1], + dev_data->mac_addr[2], dev_data->mac_addr[3], + dev_data->mac_addr[4], dev_data->mac_addr[5]); + + return 0; +} + +static void eth_iface_init(struct net_if *iface) +{ + const struct device *dev; + struct eth_npcm4xx_dev_data *dev_data; + const struct eth_npcm4xx_dev_cfg *dev_cfg; + bool is_first_init = false; + + __ASSERT_NO_MSG(iface != NULL); + + dev = net_if_get_device(iface); + __ASSERT_NO_MSG(dev != NULL); + + dev_data = dev->data; + __ASSERT_NO_MSG(dev_data != NULL); + dev_cfg = dev->config; + + /* For VLAN, this value is only used to get the correct L2 driver. + * The iface pointer in context should contain the main interface + * if the VLANs are enabled. + */ + if (dev_data->iface == NULL) { + dev_data->iface = iface; + is_first_init = true; + } + + /* Register Ethernet MAC Address with the upper layer */ + net_if_set_link_addr(iface, dev_data->mac_addr, + sizeof(dev_data->mac_addr), + NET_LINK_ETHERNET); + + ethernet_init(iface); + + net_if_flag_set(iface, NET_IF_NO_AUTO_START); + net_if_flag_set(iface, NET_IF_PROMISC); + + if (is_first_init) { + /* Now that the iface is setup, we are safe to enable IRQs. */ + __ASSERT_NO_MSG(DEV_CFG(dev)->config_func != NULL); + dev_cfg->config_func(); + } +} + +static enum ethernet_hw_caps eth_npcm4xx_get_capabilities(const struct device *dev) +{ + ARG_UNUSED(dev); + + return ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T | ETHERNET_PROMISC_MODE; +} + +static int eth_npcm4xx_set_config(const struct device *dev, + enum ethernet_config_type type, + const struct ethernet_config *config) +{ + + struct emac_reg *const emac_regs = ETH_NPCM4XX_REG_BASE; + struct eth_npcm4xx_dev_data *dev_data; + struct ETH_HANDLE_TYPE *heth; + + switch (type) { + case ETHERNET_CONFIG_TYPE_MAC_ADDRESS: + dev_data = dev->data; + heth = &dev_data->heth; + + memcpy(dev_data->mac_addr, config->mac_address.addr, 6); + heth->InitParm.MACAddr = dev_data->mac_addr; + + net_if_set_link_addr(dev_data->iface, dev_data->mac_addr, + sizeof(dev_data->mac_addr), + NET_LINK_ETHERNET); + return 0; + case ETHERNET_CONFIG_TYPE_PROMISC_MODE: + emac_regs->MACFFR |= BIT(NPCM4XX_MACFFR_PM); + return 0; + default: + break; + } + + return -ENOTSUP; +} + +static const struct ethernet_api eth_api = { + .iface_api.init = eth_iface_init, + + .get_capabilities = eth_npcm4xx_get_capabilities, + .set_config = eth_npcm4xx_set_config, + .send = eth_tx, +}; + +static void eth0_irq_config(void) +{ + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), eth_isr, + DEVICE_DT_INST_GET(0), 0); + irq_enable(DT_INST_IRQN(0)); +} + + +static const struct eth_npcm4xx_dev_cfg eth0_config = { + .config_func = eth0_irq_config, +}; + +static struct eth_npcm4xx_dev_data eth0_data = { + .mac_addr = { + NUVOTON_OUI_B0, + NUVOTON_OUI_B1, + NUVOTON_OUI_B2, +#if !defined(CONFIG_ETH_NPCM4XX_RANDOM_MAC) + CONFIG_ETH_NPCM4XX_MAC3, + CONFIG_ETH_NPCM4XX_MAC4, + CONFIG_ETH_NPCM4XX_MAC5 + #endif + }, + .heth = { + .InitParm = { + .AutoNegotiation = 1, + .Speed = ETH_SPEED_100M, + .DuplexMode = ETH_MODE_FULLDUPLEX, + .RxMode = ETH_RXINTERRUPT_MODE, + .ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE, /* ETH_CHECKSUM_BY_HARDWARE */ + .PhyAddress = PHY_ADDRESS, + .PhyLoopback = 0, + }, + .State = ETH_STATE_RESET, + }, + + +}; + +ETH_NET_DEVICE_DT_INST_DEFINE(0, eth_initialize, + NULL, ð0_data, ð0_config, + CONFIG_ETH_INIT_PRIORITY, ð_api, ETH_NPCM4XX_MTU); diff --git a/drivers/ethernet/eth_npcm4xx.h b/drivers/ethernet/eth_npcm4xx.h new file mode 100644 index 00000000000000..a93f86c8bc9046 --- /dev/null +++ b/drivers/ethernet/eth_npcm4xx.h @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2024 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#define IP101A '1' +#define DP83848 '2' +/* DP83848 and IP101A phys are supported. */ +#define EMAC_PHY DP83848 + +/*!< ETH_HEADER + ETH_EXTRA + ETH_VLAN_TAG + ETH_MAX_ETH_PAYLOAD + ETH_CRC */ +#define ETH_MAX_PACKET_SIZE ((uint32_t)1524U) + +/* DP83848: 0x01, IP101A: 0x01 */ +#define PHY_ADDRESS (0x01) +#define PHY_BCR (0x0000) +#define PHY_BSR (0x0001) +#define PHY_ID1 (0x0002) +#define PHY_ID2 (0x0003) +#define PHY_ADV (0x0004) +#define PHY_LPA (0x0005) +/* PHY: DP83848 */ +#define PHY_STS (0x0010) +/* PHY: IP101A */ +#define PHY_SMR (0x0012) +/* PHY: IP101A */ +#define PHY_PAD (0x001A) +/* PHY: DP83848 */ +#define PHY_EDCR (0x001D) + +/*!< PHY Reset */ +#define PHY_RESET ((uint16_t)0x8000) +/*!< Select loop-back mode */ +#define PHY_LOOPBACK ((uint16_t)0x4000) +/*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) +/*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) +/*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) +/*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) +/*!< Enable auto-negotiation function */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) +/*!< Restart auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) +/*!< Select the power down mode */ +#define PHY_POWERDOWN ((uint16_t)0x0800) +/*!< Isolate PHY from MII */ +#define PHY_ISOLATE ((uint16_t)0x0400) + +/*!< Auto-Negotiation process completed */ +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) +/*!< Valid link established */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004) +/*!< Jabber condition detected*/ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002) + +/* BCR (Register 0) */ +/*!< PHY Reset */ +#define PHY_BCR_RESET ((uint16_t)0x8000) +/*!< Select loop-back mode */ +#define PHY_BCR_LOOPBACK ((uint16_t)0x4000) +/*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_BCR_FULLDUPLEX_100M ((uint16_t)0x2100) +/*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_BCR_HALFDUPLEX_100M ((uint16_t)0x2000) +/*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_BCR_FULLDUPLEX_10M ((uint16_t)0x0100) +/*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_BCR_HALFDUPLEX_10M ((uint16_t)0x0000) +/*!< Enable auto-negotiation function */ +#define PHY_BCR_AUTONEGOTIATION ((uint16_t)0x1000) +/*!< Select the power down mode */ +#define PHY_BCR_POWERDOWN ((uint16_t)0x0800) +/*!< Isolate PHY from MII */ +#define PHY_BCR_ISOLATE ((uint16_t)0x0400) +/*!< Restart auto-negotiation function */ +#define PHY_BCR_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) + +/* BSR (Register 1) */ +/*!< Auto-Negotiation process completed */ +#define PHY_BSR_AUTONEGO_COMPLETE ((uint16_t)0x0020) +/*!< Valid link established */ +#define PHY_BSR_LINKED_STATUS ((uint16_t)0x0004) +/*!< Jabber condition detected */ +#define PHY_BSR_JABBER_DETECTION ((uint16_t)0x0002) + +/* SMR (Register 18, PHY: IP101A) */ +/*!< The speed selection after auto-negotiation */ +#define PHY_SMR_SPEED ((uint16_t)0x4000) +/*!< The duplex selection after auto-negotiation */ +#define PHY_SMR_DUPLEX ((uint16_t)0x2000) + +/* PHYSTS (Register 16, PHY: DP83848) */ +/*!< The duplex selection after auto-negotiation */ +#define PHY_STS_DUPLEX ((uint16_t)0x0004) +/*!< The speed selection after auto-negotiation */ +#define PHY_STS_SPEED ((uint16_t)0x0002) + +/* buffer size for receive */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE +/* buffer size for transmit */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE +/* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_RXBUFNB ((uint32_t)2) +/* 4 Tx buffers of size ETH_TX_BUF_SIZE */ +#define ETH_TXBUFNB ((uint32_t)2) + + +/* + * @brief Bit definition of TDES0 register: DMA Tx descriptor status register + */ +/*!< OWN bit: descriptor is owned by DMA engine */ +#define ETH_DMATXDESC_OWN ((uint32_t)0x80000000U) +/*!< Interrupt on Completion */ +#define ETH_DMATXDESC_IC ((uint32_t)0x40000000U) +/*!< Last Segment */ +#define ETH_DMATXDESC_LS ((uint32_t)0x20000000U) +/*!< First Segment */ +#define ETH_DMATXDESC_FS ((uint32_t)0x10000000U) +/*!< Disable CRC */ +#define ETH_DMATXDESC_DC ((uint32_t)0x08000000U) +/*!< Disable Padding */ +#define ETH_DMATXDESC_DP ((uint32_t)0x04000000U) +/*!< Transmit Time Stamp Enable */ +#define ETH_DMATXDESC_TTSE ((uint32_t)0x02000000U) +/*!< Checksum Insertion Control: 4 cases */ +#define ETH_DMATXDESC_CIC ((uint32_t)0x00C00000U) +/*!< Do Nothing: Checksum Engine is bypassed */ +#define ETH_DMATXDESC_CIC_BYPASS ((uint32_t)0x00000000U) +/*!< IPV4 header Checksum Insertion */ +#define ETH_DMATXDESC_CIC_IPV4HEADER ((uint32_t)0x00400000U) +/*!< TCP/UDP/ICMP Checksum Insertion calculated over segment only */ +#define ETH_DMATXDESC_CIC_TCPUDPICMP_SEGMENT ((uint32_t)0x00800000U) +/*!< TCP/UDP/ICMP Checksum Insertion fully calculated */ +#define ETH_DMATXDESC_CIC_TCPUDPICMP_FULL ((uint32_t)0x00C00000U) +/*!< Transmit End of Ring */ +#define ETH_DMATXDESC_TER ((uint32_t)0x00200000U) +/*!< Second Address Chained */ +#define ETH_DMATXDESC_TCH ((uint32_t)0x00100000U) +/*!< Tx Time Stamp Status */ +#define ETH_DMATXDESC_TTSS ((uint32_t)0x00020000U) +/*!< IP Header Error */ +#define ETH_DMATXDESC_IHE ((uint32_t)0x00010000U) +/*!< Error summary: OR of the following bits: UE || ED || EC || LCO || NC || LCA || FF || JT */ +#define ETH_DMATXDESC_ES ((uint32_t)0x00008000U) +/*!< Jabber Timeout */ +#define ETH_DMATXDESC_JT ((uint32_t)0x00004000U) +/*!< Frame Flushed: DMA/MTL flushed the frame due to SW flush */ +#define ETH_DMATXDESC_FF ((uint32_t)0x00002000U) +/*!< Payload Checksum Error */ +#define ETH_DMATXDESC_PCE ((uint32_t)0x00001000U) +/*!< Loss of Carrier: carrier lost during transmission */ +#define ETH_DMATXDESC_LCA ((uint32_t)0x00000800U) +/*!< No Carrier: no carrier signal from the transceiver */ +#define ETH_DMATXDESC_NC ((uint32_t)0x00000400U) +/*!< Late Collision: transmission aborted due to collision */ +#define ETH_DMATXDESC_LCO ((uint32_t)0x00000200U) +/*!< Excessive Collision: transmission aborted after 16 collisions */ +#define ETH_DMATXDESC_EC ((uint32_t)0x00000100U) +/*!< VLAN Frame */ +#define ETH_DMATXDESC_VF ((uint32_t)0x00000080U) +/*!< Collision Count */ +#define ETH_DMATXDESC_CC ((uint32_t)0x00000078U) +/*!< Excessive Deferral */ +#define ETH_DMATXDESC_ED ((uint32_t)0x00000004U) +/*!< Underflow Error: late data arrival from the memory */ +#define ETH_DMATXDESC_UF ((uint32_t)0x00000002U) +/*!< Deferred Bit */ +#define ETH_DMATXDESC_DB ((uint32_t)0x00000001U) + +/*!< Transmit Buffer2 Size */ +#define ETH_DMATXDESC_TBS2 ((uint32_t)0x1FFF0000U) +/*!< Transmit Buffer1 Size */ +#define ETH_DMATXDESC_TBS1 ((uint32_t)0x00001FFFU) + +/* + * @brief Bit definition of RDES0 register: DMA Rx descriptor status register + */ +/*!< OWN bit: descriptor is owned by DMA engine */ +#define ETH_DMARXDESC_OWN ((uint32_t)0x80000000U) +/*!< DA Filter Fail for the rx frame */ +#define ETH_DMARXDESC_AFM ((uint32_t)0x40000000U) +/*!< Receive descriptor frame length */ +#define ETH_DMARXDESC_FL ((uint32_t)0x3FFF0000U) +/*!< Error summary: OR of the following bits: DE || OE || IPC || LC || RWT || RE || CE */ +#define ETH_DMARXDESC_ES ((uint32_t)0x00008000U) +/*!< Descriptor error: no more descriptors for receive frame */ +#define ETH_DMARXDESC_DE ((uint32_t)0x00004000U) +/*!< SA Filter Fail for the received frame */ +#define ETH_DMARXDESC_SAF ((uint32_t)0x00002000U) +/*!< Frame size not matching with length field */ +#define ETH_DMARXDESC_LE ((uint32_t)0x00001000U) +/*!< Overflow Error: Frame was damaged due to buffer overflow */ +#define ETH_DMARXDESC_OE ((uint32_t)0x00000800U) +/*!< VLAN Tag: received frame is a VLAN frame */ +#define ETH_DMARXDESC_VLAN ((uint32_t)0x00000400U) +/*!< First descriptor of the frame */ +#define ETH_DMARXDESC_FS ((uint32_t)0x00000200U) +/*!< Last descriptor of the frame */ +#define ETH_DMARXDESC_LS ((uint32_t)0x00000100U) +/*!< IPC Checksum Error: Rx Ipv4 header checksum error */ +#define ETH_DMARXDESC_IPV4HCE ((uint32_t)0x00000080U) +/*!< Late collision occurred during reception */ +#define ETH_DMARXDESC_LC ((uint32_t)0x00000040U) +/*!< Frame type - Ethernet, otherwise 802.3 */ +#define ETH_DMARXDESC_FT ((uint32_t)0x00000020U) +/*!< Receive Watchdog Timeout: watchdog timer expired during reception */ +#define ETH_DMARXDESC_RWT ((uint32_t)0x00000010U) +/*!< Receive error: error reported by MII interface */ +#define ETH_DMARXDESC_RE ((uint32_t)0x00000008U) +/*!< Dribble bit error: frame contains non int multiple of 8 bits */ +#define ETH_DMARXDESC_DBE ((uint32_t)0x00000004U) +/*!< CRC error */ +#define ETH_DMARXDESC_CE ((uint32_t)0x00000002U) +/*!< Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error */ +#define ETH_DMARXDESC_MAMPCE ((uint32_t)0x00000001U) + +/* + * @brief Bit definition of RDES1 register + */ +/*!< Disable Interrupt on Completion */ +#define ETH_DMARXDESC_DIC ((uint32_t)0x80000000U) +/*!< Receive Buffer2 Size */ +#define ETH_DMARXDESC_RBS2 ((uint32_t)0x1FFF0000U) +/*!< Receive End of Ring */ +#define ETH_DMARXDESC_RER ((uint32_t)0x00008000U) +/*!< Second Address Chained */ +#define ETH_DMARXDESC_RCH ((uint32_t)0x00004000U) +/*!< Receive Buffer1 Size */ +#define ETH_DMARXDESC_RBS1 ((uint32_t)0x00001FFFU) + +enum ETH_RET_STATUS { + ETH_RET_OK = 0x00, + ETH_RET_ERROR = 0x01, + ETH_RET_BUSY = 0x02, + ETH_RET_TIMEOUT = 0x03 +}; + +enum ETH_LOCK { + ETH_LOCK_UNLOCKED = 0x00, + ETH_LOCK_LOCKED = 0x01 +}; + +enum ETH_STATE { + /*!< Peripheral not yet Initialized or disabled */ + ETH_STATE_RESET = 0x00, + /*!< Peripheral Initialized and ready for use */ + ETH_STATE_READY = 0x01, + /*!< an internal process is ongoing */ + ETH_STATE_BUSY = 0x02, + /*!< Data Transmission process is ongoing */ + ETH_STATE_BUSY_TX = 0x12, + /*!< Data Reception process is ongoing */ + ETH_STATE_BUSY_RX = 0x22, + /*!< Data Transmission and Reception process is ongoing */ + ETH_STATE_BUSY_TX_RX = 0x32, + /*!< Write process is ongoing */ + ETH_STATE_BUSY_WR = 0x42, + /*!< Read process is ongoing */ + ETH_STATE_BUSY_RD = 0x82, + /*!< Timeout state */ + ETH_STATE_TIMEOUT = 0x03, + /*!< Reception process is ongoing */ + ETH_STATE_ERROR = 0x04 +}; + +enum ETH_SPEED { + ETH_SPEED_10M = 0x00, + ETH_SPEED_100M = 0x01, +}; + +enum ETH_DUPLEX { + ETH_MODE_HALFDUPLEX = 0x00, + ETH_MODE_FULLDUPLEX = 0x01, +}; + +enum ETH_RX_MODE { + ETH_RXPOLLING_MODE = 0x00, + ETH_RXINTERRUPT_MODE = 0x01, +}; + +enum ETH_CHKSUM_MODE { + ETH_CHECKSUM_BY_HARDWARE = 0x00, + ETH_CHECKSUM_BY_SOFTWARE = 0x01, +}; + +struct ETH_INIT_PARM { + /*!< Selects or not the AutoNegotiation mode for the external PHY. */ + uint32_t AutoNegotiation; + /*!< Sets the Ethernet speed: 10/100 Mbps. */ + enum ETH_SPEED Speed; + /*!< Selects the MAC duplex mode: Half-Duplex or Full-Duplex mode. */ + enum ETH_DUPLEX DuplexMode; + /*!< Ethernet PHY address. (This parameter must be a number between Min_Data = 0 and + * Max_Data = 32.) + */ + uint16_t PhyAddress; + /*!< MAC Address of used Hardware: must be pointer on an array of 6 bytes. */ + uint8_t *MACAddr; + /*!< Selects the Ethernet Rx mode: Polling mode, Interrupt mode. */ + enum ETH_RX_MODE RxMode; + /*!< Selects if the checksum is check by hardware or by software. */ + enum ETH_CHKSUM_MODE ChecksumMode; + /*!< Selects or not the Loopback mode for the external PHY. */ + uint32_t PhyLoopback; +}; + +struct ETH_DMA_DESCRIPTOR { + /*!< Status */ + uint32_t Status; + /*!< Control and Buffer1, Buffer2 lengths */ + uint32_t ControlBufferSize; + /*!< Buffer1 address pointer */ + uint32_t Buffer1Addr; + /*!< Buffer2 or next descriptor address pointer */ + uint32_t Buffer2NextDescAddr; + + /*!< Enhanced Ethernet DMA PTP Descriptors */ + /*!< Extended status for PTP receive descriptor */ + uint32_t ExtendedStatus; + /*!< Reserved */ + uint32_t Reserved1; + /*!< Time Stamp Low value for transmit and receive */ + uint32_t TimeStampLow; + /*!< Time Stamp High value for transmit and receive */ + uint32_t TimeStampHigh; +}; + +struct ETH_DMA_RX_INFO { + /*!< First Segment Rx Desc */ + struct ETH_DMA_DESCRIPTOR *FSRxDesc; + /*!< Last Segment Rx Desc */ + struct ETH_DMA_DESCRIPTOR *LSRxDesc; + /*!< Segment count */ + uint32_t SegCount; + /*!< Frame length */ + uint32_t length; + /*!< Frame buffer */ + uint32_t buffer; +}; + +struct ETH_HANDLE_TYPE { + /*!< Ethernet init parm configuration */ + struct ETH_INIT_PARM InitParm; + /*!< Ethernet link status */ + uint32_t LinkStatus; + /*!< Rx descriptor to Get */ + struct ETH_DMA_DESCRIPTOR *RxDesc; + /*!< Tx descriptor to Set */ + struct ETH_DMA_DESCRIPTOR *TxDesc; + /*!< last Rx frame infos */ + struct ETH_DMA_RX_INFO RxFrameInfos; + /*!< ETH communication state */ + enum ETH_STATE State; + /*!< ETH Lock */ + uint32_t Lock; +}; diff --git a/dts/arm/nuvoton/npcm4xx.dtsi b/dts/arm/nuvoton/npcm4xx.dtsi index 735253852b6b12..538cd02258bb0f 100644 --- a/dts/arm/nuvoton/npcm4xx.dtsi +++ b/dts/arm/nuvoton/npcm4xx.dtsi @@ -625,6 +625,15 @@ status = "disabled"; }; + emac: ethernet@40018000 { + compatible = "nuvoton,npcm4xx-ethernet"; + reg = <0x40018000 0x2000>; + label = "ETH"; + pinctrl-0 = <&pinctrl_emac_default>; + interrupts = <36 3>; + status = "disabled"; + }; + }; soc-if { diff --git a/dts/arm/nuvoton/npcm4xx/npcm4xx-miwus-int-map.dtsi b/dts/arm/nuvoton/npcm4xx/npcm4xx-miwus-int-map.dtsi index a83079b28123b3..cea116be7cdfcc 100644 --- a/dts/arm/nuvoton/npcm4xx/npcm4xx-miwus-int-map.dtsi +++ b/dts/arm/nuvoton/npcm4xx/npcm4xx-miwus-int-map.dtsi @@ -77,11 +77,13 @@ irq-prio = <2>; group-mask = <0x08>; }; + /* group_e1a: group-e1a-map { irq = <36>; irq-prio = <2>; group-mask = <0x10>; }; + */ /* group_e1b: group-e1b-map { */ /* irq = <12>; */ /* irq-prio = <2>; */ diff --git a/dts/arm/nuvoton/npcm4xx/npcm4xx-pinctrl.dtsi b/dts/arm/nuvoton/npcm4xx/npcm4xx-pinctrl.dtsi index 0b27d00544edc7..c7b52b24a02263 100644 --- a/dts/arm/nuvoton/npcm4xx/npcm4xx-pinctrl.dtsi +++ b/dts/arm/nuvoton/npcm4xx/npcm4xx-pinctrl.dtsi @@ -50,4 +50,5 @@ pinctrl_usbd_phy_xclk: usbd_phy_xclk {}; pinctrl_sgpio0_default: sgpio0_default {}; pinctrl_sgpio1_default: sgpio1_default {}; + pinctrl_emac_default: emac_default{}; }; diff --git a/dts/bindings/ethernet/nuvoton,npcm4xx-ethernet.yaml b/dts/bindings/ethernet/nuvoton,npcm4xx-ethernet.yaml new file mode 100644 index 00000000000000..d66e19173a8c71 --- /dev/null +++ b/dts/bindings/ethernet/nuvoton,npcm4xx-ethernet.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Nuvoton Technology Corporation. +# SPDX-License-Identifier: Apache-2.0 + +description: NUVOTON NPCM4XX Ethernet + +compatible: "nuvoton,npcm4xx-ethernet" + +include: ["ethernet.yaml", "nuvoton-pinctrl.yaml"] + +properties: + reg: + required: true + interrupts: + required: true + pinctrl-0: + type: phandles + required: true + description: configurations of pinmux controllers diff --git a/soc/arm/npcm4xx/common/reg/reg_def.h b/soc/arm/npcm4xx/common/reg/reg_def.h index f33e280a048ed0..d1aca1954170d2 100644 --- a/soc/arm/npcm4xx/common/reg/reg_def.h +++ b/soc/arm/npcm4xx/common/reg/reg_def.h @@ -2665,4 +2665,940 @@ struct sgpio_reg { NPCM4XX_XEVCFG_OFFSET(n))) #define NPCM4XX_XEVSTS(base, n) (*(volatile uint8_t*)(base + \ NPCM4XX_XEVSTS_OFFSET(n))) + +/* Ethernet (ETH) registers */ +struct emac_reg { + /* 0x00: MAC Configuration Register */ + volatile uint32_t MACCR; + /* 0x04: MAC Frame Filter Register */ + volatile uint32_t MACFFR; + /* 0x08: MAC Hash Table High Register */ + volatile uint32_t MACHTHR; + /* 0x0C: MAC Hash Table Low Register */ + volatile uint32_t MACHTLR; + /* 0x10: MAC MII Address Register */ + volatile uint32_t MACMIIAR; + /* 0x14: MAC MII Data Register */ + volatile uint32_t MACMIIDR; + /* 0x18: MAC Flow Control Register */ + volatile uint32_t MACFCR; + /* 0x1C: MAC VLAN Tag Register */ + volatile uint32_t MACVLANTR; + /* 0x20: MAC Version Register */ + volatile uint32_t MACVER; + /* 0x24: MAC Debug Register */ + volatile uint32_t MACDBGR; + /* 0x28: MAC Remote Wake-Up Frame Filter Register */ + volatile uint32_t MACRWUFFR; + /* 0x2C: MAC PMT Control and Status Register */ + volatile uint32_t MACPMTCSR; + /* 0x30: MAC LPI Control and Status Register */ + volatile uint32_t MACLPICSR; + /* 0x34: MAC LPI Timers Control Register */ + volatile uint32_t MACLPITCR; + /* 0x38: MAC Interrupt Status Register */ + volatile uint32_t MACISR; + /* 0x3C: MAC Interrupt Mask Register */ + volatile uint32_t MACIMR; + /* 0x40: MAC Address 0 High Register */ + volatile uint32_t MACA0HR; + /* 0x44: MAC Address 0 Low Register */ + volatile uint32_t MACA0LR; + /* 0x48: MAC Address 1 High Register */ + volatile uint32_t MACA1HR; + /* 0x4C: MAC Address 1 Low Register */ + volatile uint32_t MACA1LR; + /* 0x50: MAC Address 2 High Register */ + volatile uint32_t MACA2HR; + /* 0x54: MAC Address 2 Low Register */ + volatile uint32_t MACA2LR; + /* 0x58: MAC Address 3 High Register */ + volatile uint32_t MACA3HR; + /* 0x5C: MAC Address 3 Low Register */ + volatile uint32_t MACA3LR; + /* 0x60: MAC Address 4 High Register */ + volatile uint32_t MACA4HR; + /* 0x64: MAC Address 4 Low Register */ + volatile uint32_t MACA4LR; + /* 0x68: MAC Address 5 High Register */ + volatile uint32_t MACA5HR; + /* 0x6C: MAC Address 5 Low Register */ + volatile uint32_t MACA5LR; + /* 0x70: MAC Address 6 High Register */ + volatile uint32_t MACA6HR; + /* 0x74: MAC Address 6 Low Register */ + volatile uint32_t MACA6LR; + /* 0x78: MAC Address 7 High Register */ + volatile uint32_t MACA7HR; + /* 0x7C: MAC Address 7 Low Register */ + volatile uint32_t MACA7LR; + /* 0x80: MAC Address 8 High Register */ + volatile uint32_t MACA8HR; + /* 0x84: MAC Address 8 Low Register */ + volatile uint32_t MACA8LR; + /* 0x88: MAC Address 9 High Register */ + volatile uint32_t MACA9HR; + /* 0x8C: MAC Address 9 Low Register */ + volatile uint32_t MACA9LR; + /* 0x90: MAC Address 10 High Register */ + volatile uint32_t MACA10HR; + /* 0x94: MAC Address 10 Low Register */ + volatile uint32_t MACA10LR; + /* 0x98: MAC Address 11 High Register */ + volatile uint32_t MACA11HR; + /* 0x9C: MAC Address 11 Low Register */ + volatile uint32_t MACA11LR; + /* 0xA0: MAC Address 12 High Register */ + volatile uint32_t MACA12HR; + /* 0xA4: MAC Address 12 Low Register */ + volatile uint32_t MACA12LR; + /* 0xA8: MAC Address 13 High Register */ + volatile uint32_t MACA13HR; + /* 0xAC: MAC Address 13 Low Register */ + volatile uint32_t MACA13LR; + /* 0xB0: MAC Address 14 High Register */ + volatile uint32_t MACA14HR; + /* 0xB4: MAC Address 14 Low Register */ + volatile uint32_t MACA14LR; + /* 0xB8: MAC Address 15 High Register */ + volatile uint32_t MACA15HR; + /* 0xBC: MAC Address 15 Low Register */ + volatile uint32_t MACA15LR; + volatile uint8_t RESERVED1[28]; + /* 0xDC: MAC Watchdog Timeout Register */ + volatile uint32_t MACWTR; + /* 0xE0: MAC General Purpose IO Register */ + volatile uint32_t MACGPIOR; + volatile uint8_t RESERVED2[28]; + + /* 0x100: MMC Control Register */ + volatile uint32_t MMCCR; + /* 0x104: MMC Receive Interrupt Register */ + volatile uint32_t MMCRIR; + /* 0x108: MMC Transmit Interrupt Register */ + volatile uint32_t MMCTIR; + /* 0x10C: MMC Receive Interrupt Mask Register */ + volatile uint32_t MMCRIMR; + /* 0x110: MMC Transmit Interrupt Mask Register */ + volatile uint32_t MMCTIMR; + /* 0x114: Number of bytes transmitted, + * exclusive of preamble and retried bytes, in good and bad frames. + */ + volatile uint32_t txoctetcount_gb; + /* 0x118: Number of good and bad frames transmitted, exclusive of retried frames. */ + volatile uint32_t txframecount_gb; + /* 0x11C: Number of good broadcast frames transmitted. */ + volatile uint32_t txbroadcastframes_g; + /* 0x120: Number of good multicast frames transmitted. */ + volatile uint32_t txmulticastframes_g; + /* 0x124: Number of good and bad frames transmitted with length 64 bytes, + * exclusive of preamble and retried frames. + */ + volatile uint32_t tx64octets_gb; + /* 0x128: Number of good and bad frames transmitted with length between + * 65 and 127 (inclusive) bytes, exclusive of preamble and retried frames. + */ + volatile uint32_t tx65to127octets_gb; + /* 0x12C: Number of good and bad frames transmitted with length between + * 128 and 255 (inclusive) bytes, exclusive of preamble and retried frames. + */ + volatile uint32_t tx128to255octets_gb; + /* 0x130: Number of good and bad frames transmitted with length between + * 256 and 511 (inclusive) bytes, exclusive of preamble and retried frames. + */ + volatile uint32_t tx256to511octets_gb; + /* 0x134: Number of good and bad frames transmitted with length between + * 512 and 1,023 (inclusive) bytes, exclusive of preamble and retried frames. + */ + volatile uint32_t tx512to1023octets_gb; + /* 0x138: Number of good and bad frames transmitted with length between + * 1,024 and maxsize (inclusive) bytes, exclusive of preamble and retried frames. + */ + volatile uint32_t tx1024tomaxoctets_gb; + /* 0x13C: Number of good and bad unicast frames ransmitted. */ + volatile uint32_t txunicastframes_gb; + /* 0x140: Number of good and bad multicast frames transmitted. */ + volatile uint32_t txmulticastframes_gb; + /* 0x144: Number of good and bad broadcast frames transmitted. */ + volatile uint32_t txbroadcastframes_gb; + /* 0x148: Number of frames aborted because of frame underflow error. */ + volatile uint32_t txunderflowerror; + /* 0x14C: Number of successfully transmitted frames after a + * single collision in the half-duplex mode. + */ + volatile uint32_t MMCTGFSCCR; + /* 0x150: Number of successfully transmitted frames after + * multiple collisions in the half-duplex mode. + */ + volatile uint32_t MMCTGFMSCCR; + /* 0x154: Number of successfully transmitted frames after + * a deferral in the half-duplex mode. + */ + volatile uint32_t txdeferred; + /* 0x158: Number of frames aborted because of late collision error. */ + volatile uint32_t txlatecol; + /* 0x15C: Number of frames aborted because of excessive (16) collision errors. */ + volatile uint32_t txexesscol; + /* 0x160: Number of frames aborted because of carrier sense error + * (no carrier or loss of carrier). + */ + volatile uint32_t txcarriererror; + /* 0x164: Number of bytes transmitted, exclusive of preamble, only in good frames. */ + volatile uint32_t txoctetcount_g; + /* 0x168: Number of good frames transmitted. */ + volatile uint32_t MMCTGFCR; + /* 0x16C: Number of frames aborted because of excessive deferral error + * (deferred for more than two max-sized frame times). + */ + volatile uint32_t txexcessdef; + /* 0x170: Number of good Pause frames transmitted. */ + volatile uint32_t txpauseframes; + /* 0x174: Number of good VLAN frames transmitted, exclusive of retried frames. */ + volatile uint32_t txvlanframes_g; + /* 0x178: Number of frames transmitted without errors and with + * length greater than the maxsize (1,518 or 1,522 bytes for VLAN + * tagged frames; 2000 bytes if enabled in Bit 27 of Register 0 + * (MAC Configuration Register)). + */ + volatile uint32_t txoversize_g; + volatile uint8_t RESERVED3[4]; + /* 0x180: Number of good and bad frames received. */ + volatile uint32_t rxframecount_gb; + /* 0x184: Number of bytes received, exclusive of preamble, in good and bad frames. */ + volatile uint32_t rxoctetcount_gb; + /* 0x188: Number of bytes received, exclusive of preamble, only in good frames. */ + volatile uint32_t rxoctetcount_g; + /* 0x18C: Number of good broadcast frames received. */ + volatile uint32_t rxbroadcastframes_g; + /* 0x190: Number of good multicast frames received. */ + volatile uint32_t rxmulticastframes_g; + /* 0x194: Number of frames received with CRC error. */ + volatile uint32_t MMCRFCECR; + /* 0x198: Number of frames received with alignment (dribble) error. + * Valid only in 10/100 mode. + */ + volatile uint32_t MMCRFAECR; + /* 0x19C: Number of frames received with runt (<64 bytes and CRC error) error. */ + volatile uint32_t rxrunterror; + /* 0x1A0: Number of giant frames received with length (including CRC) + * greater than 1,518 bytes (1,522 bytes for VLAN tagged) and with CRC error. + * If Jumbo Frame mode is enabled, then frames of length greater than 9,018 bytes + * (9,022 for VLAN tagged) are considered as giant frames. + */ + volatile uint32_t rxjabbererror; + /* 0x1A4: Number of frames received with length less than 64 bytes, without any errors. */ + volatile uint32_t rxundersize_g; + /* 0x1A8: Number of frames received without errors, with length greater than the maxsize + * (1,518 or 1,522 for VLAN tagged frames; 2,000 bytes if enabled in Bit 27 of Register 0 + * (MAC Configuration Register)). + */ + volatile uint32_t rxoversize_g; + /* 0x1AC: Number of good and bad frames received with length 64 bytes, + * exclusive of preamble. + */ + volatile uint32_t rx64octets_gb; + /* 0x1B0: Number of good and bad frames received with length between + * 65 and 127 (inclusive) bytes, exclusive of preamble. + */ + volatile uint32_t rx65to127octets_gb; + /* 0x1B4: Number of good and bad frames received with length between + * 128 and 255 (inclusive) bytes, exclusive of preamble. + */ + volatile uint32_t rx128to255octets_gb; + /* 0x1B8: Number of good and bad frames received with length between + * 256 and 511 (inclusive) bytes, exclusive of preamble. + */ + volatile uint32_t rx256to511octets_gb; + /* 0x1BC: Number of good and bad frames received with length between + * 512 and 1,023 (inclusive) bytes, exclusive of preamble. + */ + volatile uint32_t rx512to1023octets_gb; + /* 0x1C0: Number of good and bad frames received with length between + * 1,024 and maxsize (inclusive) bytes, exclusive of preamble and retried frames. + */ + volatile uint32_t rx1024tomaxoctets_gb; + /* 0x1C4: Number of received good unicast frames. */ + volatile uint32_t MMCRGUFCR; + /* 0x1C8: Number of frames received with length error + * (Length type field !=frame size), for all frames with valid length field. + */ + volatile uint32_t rxlengtherror; + /* 0x1CC: Number of frames received with length field not equal to the valid + * frame size (greater than 1,500 but less than 1,536). + */ + volatile uint32_t rxoutofrangetype; + /* 0x1D0: Number of good and valid Pause frames received. */ + volatile uint32_t rxpauseframes; + /* 0x1D4: Number of missed received frames because of FIFO overflow. + * This counter is not present in the GMAC-CORE configuration. + */ + volatile uint32_t rxfifooverflow; + /* 0x1D8: Number of good and bad VLAN frames received. */ + volatile uint32_t rxvlanframes_gb; + /* 0x1DC: Number of frames received with error because + * of watchdog timeout error (frames with a data load larger than + * 2,048 bytes or the value programmed in Register + * 55 (Watchdog Timeout Register)). + */ + volatile uint32_t rxwatchdogerror; + /* 0x1E0: Number of frames received with Receive error or Frame Extension error + * on the GMII or MII interface. + */ + volatile uint32_t rxrcverror; + /* 0x1E4: Number of received good control frames. */ + volatile uint32_t rxctrlframes_g; + volatile uint8_t RESERVED4[24]; + /* 0x200: MMC IPC Receive Checksum Offload Interrupt Mask maintains + * the mask for the interrupt generated from the receive IPC statistic counters. + * See Table 4-24 for further detail. + */ + volatile uint32_t mmc_ipc_intr_mask_rx; + volatile uint8_t RESERVED5[4]; + /* 0x208: MMC Receive Checksum Offload Interrupt maintains the interrupt + * that the receive IPC statistic counters generate. + * See Table 4-25 for further detail. + */ + volatile uint32_t mmc_ipc_intr_rx; + volatile uint8_t RESERVED6[4]; + /* 0x210: Number of good IPv4 datagrams received with the TCP, UDP, or ICMP payload. */ + volatile uint32_t rxipv4_gd_frms; + /* 0x214: Number of IPv4 datagrams received with header + * (checksum, length, or version mismatch) errors. + */ + volatile uint32_t rxipv4_hdrerr_frms; + /* 0x218: Number of IPv4 datagram frames received that did not have a + * TCP, UDP, or ICMP payload processed by the Checksum engine. + */ + volatile uint32_t rxipv4_nopay_frms; + /* 0x21C: Number of good IPv4 datagrams with fragmentation. */ + volatile uint32_t rxipv4_frag_frms; + /* 0x220: Number of good IPv4 datagrams received that had a + * UDP payload with checksum disabled. + */ + volatile uint32_t rxipv4_udsbl_frms; + /* 0x224: Number of good IPv6 datagrams received with TCP, UDP, or ICMP payloads. */ + volatile uint32_t rxipv6_gd_frms; + /* 0x228: Number of IPv6 datagrams received with header errors + * (length or version mismatch). + */ + volatile uint32_t rxipv6_hdrerr_frms; + /* 0x22C: Number of IPv6 datagram frames received that did not have + * a TCP, UDP, or ICMP payload. This includes all IPv6 datagrams + * with fragmentation or security extension headers. + */ + volatile uint32_t rxipv6_nopay_frms; + /* 0x230: Number of good IP datagrams with a good UDP payload. + * This counter is not updated when the rxipv4_udsbl_frms counter is incremented. + */ + volatile uint32_t rxudp_gd_frms; + /* 0x234: Number of good IP datagrams whose UDP payload has a checksum error. */ + volatile uint32_t rxudp_err_frms; + /* 0x238: Number of good IP datagrams with a good TCP payload. */ + volatile uint32_t rxtcp_gd_frms; + /* 0x23C: Number of good IP datagrams whose TCP payload has a checksum error. */ + volatile uint32_t rxtcp_err_frms; + /* 0x240: Number of good IP datagrams with a good ICMP payload. */ + volatile uint32_t rxicmp_gd_frms; + /* 0x244: Number of good IP datagrams whose ICMP payload has a checksum error. */ + volatile uint32_t rxicmp_err_frms; + volatile uint8_t RESERVED7[8]; + /* 0x250: Number of bytes received in good IPv4 datagrams encapsulating + * TCP, UDP, or ICMP data. (Ethernet header, FCS, pad, or IP pad bytes + * are not included in this counter or in the octet counters listed below). + */ + volatile uint32_t rxipv4_gd_octets; + /* 0x254: Number of bytes received in IPv4 datagrams with header errors + * (checksum, length, version mismatch). The value in the Length field + * of IPv4 header is used to update this counter. + */ + volatile uint32_t rxipv4_hdrerr_octets; + /* 0x258: Number of bytes received in IPv4 datagrams that did not have + * a TCP, UDP, or ICMP payload. The value in the IPv4 header's Length + * field is used to update this counter. + */ + volatile uint32_t rxipv4_nopay_octets; + /* 0x25C: Number of bytes received in fragmented IPv4 datagrams. + * The value in the IPv4 header's Length field is used to update this counter. + */ + volatile uint32_t rxipv4_frag_octets; + /* 0x260: Number of bytes received in a UDP segment that had the UDP checksum + * disabled. This counter does not count IP Header bytes. + */ + volatile uint32_t rxipv4_udsbl_octets; + /* 0x264: Number of bytes received in good IPv6 datagrams encapsulating + * TCP, UDP or ICMPv6 data. + */ + volatile uint32_t rxipv6_gd_octets; + /* 0x268: Number of bytes received in IPv6 datagrams with header errors + * (length, version mismatch). The value in the IPv6 header's Length + * field is used to update this counter. + */ + volatile uint32_t rxipv6_hdrerr_octets; + /* 0x26C: Number of bytes received in IPv6 datagrams that did not have + * a TCP, UDP, or ICMP payload. The value in the IPv6 header's Length + * field is used to update this counter. + */ + volatile uint32_t rxipv6_nopay_octets; + /* 0x270: Number of bytes received in a good UDP segment. + * This counter (and the counters below) does not count IP header bytes. + */ + volatile uint32_t rxudp_gd_octets; + /* 0x274: Number of bytes received in a UDP segment that had checksum errors. */ + volatile uint32_t rxudp_err_octets; + /* 0x278: Number of bytes received in a good TCP segment. */ + volatile uint32_t rxtcp_gd_octets; + /* 0x27C: Number of bytes received in a TCP segment with checksum errors. */ + volatile uint32_t rxtcp_err_octets; + /* 0x280: Number of bytes received in a good ICMP segment. */ + volatile uint32_t rxicmp_gd_octets; + /* 0x284: Number of bytes received in an ICMP segment with checksum errors. */ + volatile uint32_t rxicmp_err_octets; + volatile uint8_t RESERVED8[376]; + + /* 0x400: Layer 3 and Layer 4 Control Register 0 */ + volatile uint32_t L3L4CR_0; + /* 0x404: Layer 4 Address Register 0 */ + volatile uint32_t L4ADDR_0; + volatile uint8_t RESERVED9[8]; + /* 0x410: Layer 3 Address 0 Register 0 */ + volatile uint32_t L3ADDR0_0; + /* 0x414: Layer 3 Address 1 Register 0 */ + volatile uint32_t L3ADDR1_0; + /* 0x418: Layer 3 Address 2 Register 0 */ + volatile uint32_t L3ADDR2_0; + /* 0x41C: Layer 3 Address 3 Register 0 */ + volatile uint32_t L3ADDR3_0; + volatile uint8_t RESERVED10[16]; + /* 0x430: Layer 3 and Layer 4 Control Register 1 */ + volatile uint32_t L3L4CR_1; + /* 0x434: Layer 4 Address Register 1 */ + volatile uint32_t L4ADDR_1; + volatile uint8_t RESERVED11[8]; + /* 0x440: Layer 3 Address 0 Register 1 */ + volatile uint32_t L3ADDR0_1; + /* 0x444: Layer 3 Address 1 Register 1 */ + volatile uint32_t L3ADDR1_1; + /* 0x448: Layer 3 Address 2 Register 1 */ + volatile uint32_t L3ADDR2_1; + /* 0x44C: Layer 3 Address 3 Register 1 */ + volatile uint32_t L3ADDR3_1; + volatile uint8_t RESERVED12[16]; + /* 0x460: Layer 3 and Layer 4 Control Register 2 */ + volatile uint32_t L3L4CR_2; + /* 0x464: Layer 4 Address Register 2 */ + volatile uint32_t L4ADDR_2; + volatile uint8_t RESERVED13[8]; + /* 0x470: Layer 3 Address 0 Register 2 */ + volatile uint32_t L3ADDR0_2; + /* 0x474: Layer 3 Address 1 Register 2 */ + volatile uint32_t L3ADDR1_2; + /* 0x478: Layer 3 Address 2 Register 2 */ + volatile uint32_t L3ADDR2_2; + /* 0x47C: Layer 3 Address 3 Register 2 */ + volatile uint32_t L3ADDR3_2; + volatile uint8_t RESERVED14[16]; + /* 0x490: Layer 3 and Layer 4 Control Register 3 */ + volatile uint32_t L3L4CR_3; + /* 0x494: Layer 4 Address Register 3 */ + volatile uint32_t L4ADDR_3; + volatile uint8_t RESERVED15[8]; + /* 0x4A0: Layer 3 Address 0 Register 3 */ + volatile uint32_t L3ADDR0_3; + /* 0x4A4: Layer 3 Address 1 Register 3 */ + volatile uint32_t L3ADDR1_3; + /* 0x4A8: Layer 3 Address 2 Register 3 */ + volatile uint32_t L3ADDR2_3; + /* 0x4AC: Layer 3 Address 3 Register 3 */ + volatile uint32_t L3ADDR3_3; + volatile uint8_t RESERVED16[80]; + /* 0x500: Hash Table Register 0 */ + volatile uint32_t HASHTAB0; + /* 0x504: Hash Table Register 1 */ + volatile uint32_t HASHTAB1; + /* 0x508: Hash Table Register 2 */ + volatile uint32_t HASHTAB2; + /* 0x50C: Hash Table Register 3 */ + volatile uint32_t HASHTAB3; + /* 0x510: Hash Table Register 4 */ + volatile uint32_t HASHTAB4; + /* 0x514: Hash Table Register 5 */ + volatile uint32_t HASHTAB5; + /* 0x518: Hash Table Register 6 */ + volatile uint32_t HASHTAB6; + /* 0x51C: Hash Table Register 7 */ + volatile uint32_t HASHTAB7; + volatile uint8_t RESERVED17[100]; + /* 0x584: MAC Config Register */ + volatile uint32_t VLAN_TAG; + /* 0x588: MAC Config Register */ + volatile uint32_t VLAN_HASHTAB; + volatile uint8_t RESERVED18[628]; + /* 0x800: MAC Address 16 High Register */ + volatile uint32_t MACA16HR; + /* 0x804: MAC Address 16 Low Register */ + volatile uint32_t MACA16LR; + /* 0x808: MAC Address 17 High Register */ + volatile uint32_t MACA17HR; + /* 0x80C: MAC Address 17 Low Register */ + volatile uint32_t MACA17LR; + /* 0x810: MAC Address 18 High Register */ + volatile uint32_t MACA18HR; + /* 0x814: MAC Address 18 Low Register */ + volatile uint32_t MACA18LR; + /* 0x818: MAC Address 19 High Register */ + volatile uint32_t MACA19HR; + /* 0x81C: MAC Address 19 Low Register */ + volatile uint32_t MACA19LR; + /* 0x820: MAC Address 20 High Register */ + volatile uint32_t MACA20HR; + /* 0x824: MAC Address 20 Low Register */ + volatile uint32_t MACA20LR; + /* 0x828: MAC Address 21 High Register */ + volatile uint32_t MACA21HR; + /* 0x82C: MAC Address 21 Low Register */ + volatile uint32_t MACA21LR; + /* 0x830: MAC Address 22 High Register */ + volatile uint32_t MACA22HR; + /* 0x834: MAC Address 22 Low Register */ + volatile uint32_t MACA22LR; + /* 0x838: MAC Address 23 High Register */ + volatile uint32_t MACA23HR; + /* 0x83C: MAC Address 23 Low Register */ + volatile uint32_t MACA23LR; + /* 0x840: MAC Address 24 High Register */ + volatile uint32_t MACA24HR; + /* 0x844: MAC Address 24 Low Register */ + volatile uint32_t MACA24LR; + /* 0x848: MAC Address 25 High Register */ + volatile uint32_t MACA25HR; + /* 0x84C: MAC Address 25 Low Register */ + volatile uint32_t MACA25LR; + /* 0x850: MAC Address 26 High Register */ + volatile uint32_t MACA26HR; + /* 0x854: MAC Address 26 Low Register */ + volatile uint32_t MACA26LR; + /* 0x858: MAC Address 27 High Register */ + volatile uint32_t MACA27HR; + /* 0x85C: MAC Address 27 Low Register */ + volatile uint32_t MACA27LR; + /* 0x860: MAC Address 28 High Register */ + volatile uint32_t MACA28HR; + /* 0x864: MAC Address 28 Low Register */ + volatile uint32_t MACA28LR; + /* 0x868: MAC Address 29 High Register */ + volatile uint32_t MACA29HR; + /* 0x86C: MAC Address 29 Low Register */ + volatile uint32_t MACA29LR; + /* 0x870: MAC Address 30 High Register */ + volatile uint32_t MACA30HR; + /* 0x874: MAC Address 30 Low Register */ + volatile uint32_t MACA30LR; + /* 0x878: MAC Address 31 High Register */ + volatile uint32_t MACA31HR; + /* 0x87C: MAC Address 31 Low Register */ + volatile uint32_t MACA31LR; + volatile uint8_t RESERVED19[1920]; + + /* 0x1000: DMA Bus Mode Register */ + volatile uint32_t DMABMR; + /* 0x1004: DMA Transmit Poll Demand Register */ + volatile uint32_t DMATPDR; + /* 0x1008: DMA Receive Poll Demand Register */ + volatile uint32_t DMARPDR; + /* 0x100C: DMA Receive Descriptor List Address Register */ + volatile uint32_t DMARDLAR; + /* 0x1010: DMA Transmit Descriptor List Address Register */ + volatile uint32_t DMATDLAR; + /* 0x1014: DMA Status Register */ + volatile uint32_t DMASR; + /* 0x1018: DMA Operation Mode Register */ + volatile uint32_t DMAOMR; + /* 0x101C: DMA Interrupt Enable Register */ + volatile uint32_t DMAIER; + /* 0x1020: DMA Missed Frame and Buffer Overflow Counter Register */ + volatile uint32_t DMAMFBOCR; + /* 0x1024: DMA Receive Interrupt Watchdog Timer Register */ + volatile uint32_t DMARSWTR; + volatile uint8_t RESERVED20[4]; + /* 0x102C: DMA AHB or AXI Status Register */ + volatile uint32_t DMAASR; + volatile uint8_t RESERVED21[24]; + /* 0x1048: DMA Current Host Transmit Descriptor Register */ + volatile uint32_t DMACHTDR; + /* 0x104C: DMA Current Host Receive Descriptor Register */ + volatile uint32_t DMACHRDR; + /* 0x1050: DMA Current Host Transmit Buffer Address Register */ + volatile uint32_t DMACHTBAR; + /* 0x1054: DMA Current Host Receive Buffer Address Register */ + volatile uint32_t DMACHRBAR; + /* 0x1058: DMA HW Feature Register */ + volatile uint32_t DMAHWFR; +}; + +/* MACCR fields */ +#define NPCM4XX_MACCR_SARC (28U) +#define NPCM4XX_MACCR_TWOKPE (27U) +#define NPCM4XX_MACCR_CST (25U) +#define NPCM4XX_MACCR_WD (23U) +#define NPCM4XX_MACCR_JD (22U) +#define NPCM4XX_MACCR_IFG (17U) +#define NPCM4XX_MACCR_CSD (16U) +#define NPCM4XX_MACCR_FES (14U) +#define NPCM4XX_MACCR_ROD (13U) +#define NPCM4XX_MACCR_LM (12U) +#define NPCM4XX_MACCR_DM (11U) +#define NPCM4XX_MACCR_IPCO (10U) +#define NPCM4XX_MACCR_RD (9U) +#define NPCM4XX_MACCR_APCS (7U) +#define NPCM4XX_MACCR_BL (5U) +#define NPCM4XX_MACCR_DC (4U) +#define NPCM4XX_MACCR_TE (3U) +#define NPCM4XX_MACCR_RE (2U) +#define NPCM4XX_MACCR_PRELEN (0U) + +/* MACFFR fields */ +#define NPCM4XX_MACFFR_RA (31U) +#define NPCM4XX_MACFFR_DNTU (21U) +#define NPCM4XX_MACFFR_IPFE (20U) +#define NPCM4XX_MACFFR_VTFE (16U) +#define NPCM4XX_MACFFR_HPF (10U) +#define NPCM4XX_MACFFR_SAF (9U) +#define NPCM4XX_MACFFR_SAIF (8U) +#define NPCM4XX_MACFFR_PCF (6U) +#define NPCM4XX_MACFFR_PCF_ForwardExcptPause (6U) +#define NPCM4XX_MACFFR_PCF_ForwardAll (7U) +#define NPCM4XX_MACFFR_PCF_ForwardPassedAddrFilter (6U) +#define NPCM4XX_MACFFR_BFD (5U) +#define NPCM4XX_MACFFR_PAM (4U) +#define NPCM4XX_MACFFR_DAIF (3U) +#define NPCM4XX_MACFFR_HM (2U) +#define NPCM4XX_MACFFR_HU (1U) +#define NPCM4XX_MACFFR_PM (0U) + +/* MACHTHR fields */ +#define NPCM4XX_MACHTHR_HTH (0U) + +/* MACHTLR fields */ +#define NPCM4XX_MACHTLR_HTL (0U) + +/* MACMIIAR fields */ +#define NPCM4XX_MACMIIAR_PA (11U) +#define NPCM4XX_MACMIIAR_MR (6U) +#define NPCM4XX_MACMIIAR_CR (2U) +#define NPCM4XX_MACMIIAR_MW (1U) +#define NPCM4XX_MACMIIAR_MB (0U) + +/* MACMIIDR fields */ +#define NPCM4XX_MACMIIDR_MD (0U) + +/* MACFCR fields */ +#define NPCM4XX_MACFCR_PT (16U) +#define NPCM4XX_MACFCR_ZQPD (7U) +#define NPCM4XX_MACFCR_PLT (4U) +#define NPCM4XX_MACFCR_PLT_Minus4 (4U) +#define NPCM4XX_MACFCR_PLT_Minus28 (4U) +#define NPCM4XX_MACFCR_PLT_Minus144 (5U) +#define NPCM4XX_MACFCR_PLT_Minus256 (4U) +#define NPCM4XX_MACFCR_UPFD (3U) +#define NPCM4XX_MACFCR_RFCE (2U) +#define NPCM4XX_MACFCR_TFCE (1U) +#define NPCM4XX_MACFCR_FCBBPA (0U) + +/* MACVLANTR fields */ +#define NPCM4XX_MACVLANTR_VLANTC (16U) +#define NPCM4XX_MACVLANTR_VLANTI (0U) + +/* MACRWUFFR fields */ +#define NPCM4XX_MACRWUFFR_D (0U) + +/* MACPMTCSR fields */ +#define NPCM4XX_MACPMTCSR_WFFRPR (31U) +#define NPCM4XX_MACPMTCSR_RWKPTR (24U) +#define NPCM4XX_MACPMTCSR_GU (9U) +#define NPCM4XX_MACPMTCSR_WFR (6U) +#define NPCM4XX_MACPMTCSR_MPR (5U) +#define NPCM4XX_MACPMTCSR_WFE (2U) +#define NPCM4XX_MACPMTCSR_MPE (1U) +#define NPCM4XX_MACPMTCSR_PD (0U) + +/* MACDBGR fields */ +#define NPCM4XX_MACDBGR_TFF (25U) +#define NPCM4XX_MACDBGR_TFNE (24U) +#define NPCM4XX_MACDBGR_TPWA (22U) +#define NPCM4XX_MACDBGR_TFRS (20U) +#define NPCM4XX_MACDBGR_TFRS_WRITING (20U) +#define NPCM4XX_MACDBGR_TFRS_WAITING (21U) +#define NPCM4XX_MACDBGR_TFRS_READ (20U) +#define NPCM4XX_MACDBGR_TFRS_IDLE (20U) +#define NPCM4XX_MACDBGR_MTP (19U) +#define NPCM4XX_MACDBGR_MTFCS (17U) +#define NPCM4XX_MACDBGR_MTFCS_TRANSFERRING (17U) +#define NPCM4XX_MACDBGR_MTFCS_GENERATINGPCF (18U) +#define NPCM4XX_MACDBGR_MTFCS_WAITING (17U) +#define NPCM4XX_MACDBGR_MTFCS_IDLE (17U) +#define NPCM4XX_MACDBGR_MMTEA (16U) +#define NPCM4XX_MACDBGR_RFFL (8U) +#define NPCM4XX_MACDBGR_RFFL_FULL (8U) +#define NPCM4XX_MACDBGR_RFFL_ABOVEFCT (9U) +#define NPCM4XX_MACDBGR_RFFL_BELOWFCT (8U) +#define NPCM4XX_MACDBGR_RFFL_EMPTY (8U) +#define NPCM4XX_MACDBGR_RFRCS (5U) +#define NPCM4XX_MACDBGR_RFRCS_FLUSHING (5U) +#define NPCM4XX_MACDBGR_RFRCS_STATUSREADING (6U) +#define NPCM4XX_MACDBGR_RFRCS_DATAREADING (5U) +#define NPCM4XX_MACDBGR_RFRCS_IDLE (5U) +#define NPCM4XX_MACDBGR_RFWRA (4U) +#define NPCM4XX_MACDBGR_MSFRWCS (1U) +#define NPCM4XX_MACDBGR_MMRPEA (0U) + +/* MACSR fields */ +#define NPCM4XX_MACSR_TSTS (9U) +#define NPCM4XX_MACSR_MMCTS (6U) +#define NPCM4XX_MACSR_MMMCRS (5U) +#define NPCM4XX_MACSR_MMCS (4U) +#define NPCM4XX_MACSR_PMTS (3U) + +/* MACIMR fields */ +#define NPCM4XX_MACIMR_TSTIM (9U) +#define NPCM4XX_MACIMR_PMTIM (3U) + +/* MACA0HR fields */ +#define NPCM4XX_MACA0HR_MACA0H (0U) + +/* MACA0LR fields */ +#define NPCM4XX_MACA0LR_MACA0L (0U) + +/* MACA1HR fields */ +#define NPCM4XX_MACA1HR_AE (31U) +#define NPCM4XX_MACA1HR_SA (30U) +#define NPCM4XX_MACA1HR_MBC (24U) +#define NPCM4XX_MACA1HR_MACA1H (0U) + +/* MACA1LR fields */ +#define NPCM4XX_MACA1LR_MACA1L (0U) + +/* MACA2HR fields */ +#define NPCM4XX_MACA2HR_AE (31U) +#define NPCM4XX_MACA2HR_SA (30U) +#define NPCM4XX_MACA2HR_MBC (24U) +#define NPCM4XX_MACA2HR_MACA2H (0U) + +/* MACA2LR fields */ +#define NPCM4XX_MACA2LR_MACA2L (0U) + +/* MACA3HR fields */ +#define NPCM4XX_MACA3HR_AE (31U) +#define NPCM4XX_MACA3HR_SA (30U) +#define NPCM4XX_MACA3HR_MBC (24U) +#define NPCM4XX_MACA3HR_MACA3H (0U) + +/* MACWTR fields */ +#define NPCM4XX_MACWTR_PWE (16U) + +/* MMCCR fields */ +#define NPCM4XX_MMCCR_MCFHP (5U) +#define NPCM4XX_MMCCR_MCP (4U) +#define NPCM4XX_MMCCR_MCF (3U) +#define NPCM4XX_MMCCR_ROR (2U) +#define NPCM4XX_MMCCR_CSR (1U) +#define NPCM4XX_MMCCR_CR (0U) + +/* MMCRIR fields */ +#define NPCM4XX_MMCRIR_RGUFS (17U) +#define NPCM4XX_MMCRIR_RFAES (6U) +#define NPCM4XX_MMCRIR_RFCES (5U) + +/* MMCTIR fields */ +#define NPCM4XX_MMCTIR_TGFS (21U) +#define NPCM4XX_MMCTIR_TGFMSCS (15U) +#define NPCM4XX_MMCTIR_TGFSCS (14U) + +/* MMCRIMR fields */ +#define NPCM4XX_MMCRIMR_RGUFM (17U) +#define NPCM4XX_MMCRIMR_RFAEM (6U) +#define NPCM4XX_MMCRIMR_RFCEM (5U) + +/* MMCTIMR fields */ +#define NPCM4XX_MMCTIMR_TGFM (21U) +#define NPCM4XX_MMCTIMR_TGFMSCM (15U) +#define NPCM4XX_MMCTIMR_TGFSCM (14U) + +/* MMCTGFSCCR fields */ +#define NPCM4XX_MMCTGFSCCR_TGFSCC (0U) + +/* MMCTGFMSCCR fields */ +#define NPCM4XX_MMCTGFMSCCR_TGFMSCC (0U) + +/* MMCTGFCR fields */ +#define NPCM4XX_MMCTGFCR_TGFC (0U) + +/* MMCRFCECR fields */ +#define NPCM4XX_MMCRFCECR_RFCEC (0U) + +/* MMCRFAECR fields */ +#define NPCM4XX_MMCRFAECR_RFAEC (0U) + +/* MMCRGUFCR fields */ +#define NPCM4XX_MMCRGUFCR_RGUFC (0U) + +/* PTPTSCR fields */ +#define NPCM4XX_PTPTSCR_TSCNT (16U) +#define NPCM4XX_PTPTSCR_TSSMRME (15U) +#define NPCM4XX_PTPTSCR_TSSEME (14U) +#define NPCM4XX_PTPTSCR_TSSIPV4FE (13U) +#define NPCM4XX_PTPTSCR_TSSIPV6FE (12U) +#define NPCM4XX_PTPTSCR_TSSPTPOEFE (11U) +#define NPCM4XX_PTPTSCR_TSPTPPSV2E (10U) +#define NPCM4XX_PTPTSCR_TSSSR (9U) +#define NPCM4XX_PTPTSCR_TSSARFE (8U) +#define NPCM4XX_PTPTSCR_TSARU (5U) +#define NPCM4XX_PTPTSCR_TSITE (4U) +#define NPCM4XX_PTPTSCR_TSSTU (3U) +#define NPCM4XX_PTPTSCR_TSSTI (2U) +#define NPCM4XX_PTPTSCR_TSFCU (1U) +#define NPCM4XX_PTPTSCR_TSE (0U) + +/* PTPSSIR fields */ +#define NPCM4XX_PTPSSIR_STSSI (0U) + +/* PTPTSHR fields */ +#define NPCM4XX_PTPTSHR_STS (0U) + +/* PTPTSLR fields */ +#define NPCM4XX_PTPTSLR_STPNS (31U) +#define NPCM4XX_PTPTSLR_STSS (0U) + +/* PTPTSHUR fields */ +#define NPCM4XX_PTPTSHUR_TSUS (0U) + +/* PTPTSLUR fields */ +#define NPCM4XX_PTPTSLUR_TSUPNS (31U) +#define NPCM4XX_PTPTSLUR_TSUSS (0U) + +/* PTPTSAR fields */ +#define NPCM4XX_PTPTSAR_TSA (0U) + +/* PTPTTHR fields */ +#define NPCM4XX_PTPTTHR_TTSH (0U) + +/* PTPTTLR fields */ +#define NPCM4XX_PTPTTLR_TTSL (0U) + +/* PTPTSSR fields */ +#define NPCM4XX_PTPTSSR_TSTTR (2U) +#define NPCM4XX_PTPTSSR_TSSO (1U) + +/* DMABMR fields */ +#define NPCM4XX_DMABMR_AAB (25U) +#define NPCM4XX_DMABMR_FPM (24U) +#define NPCM4XX_DMABMR_USP (23U) +#define NPCM4XX_DMABMR_RDP (17U) +#define NPCM4XX_DMABMR_FB (16U) +#define NPCM4XX_DMABMR_RTPR (14U) +#define NPCM4XX_DMABMR_PBL (8U) +#define NPCM4XX_DMABMR_EDE (7U) +#define NPCM4XX_DMABMR_DSL (2U) +#define NPCM4XX_DMABMR_DA (1U) +#define NPCM4XX_DMABMR_SR (0U) + +/* DMATPDR fields */ +#define NPCM4XX_DMATPDR_TPD (0U) + +/* DMARPDR fields */ +#define NPCM4XX_DMARPDR_RPD (0U) + +/* DMARDLAR fields */ +#define NPCM4XX_DMARDLAR_SRL (0U) + +/* DMATDLAR fields */ +#define NPCM4XX_DMATDLAR_STL (0U) + +/* DMASR fields */ +#define NPCM4XX_DMASR_TSTS (29U) +#define NPCM4XX_DMASR_PMTS (28U) +#define NPCM4XX_DMASR_MMCS (27U) +#define NPCM4XX_DMASR_EBS (23U) +#define NPCM4XX_DMASR_EBS_DescAccess (25U) +#define NPCM4XX_DMASR_EBS_ReadTransf (24U) +#define NPCM4XX_DMASR_EBS_DataTransfTx (23U) +#define NPCM4XX_DMASR_TPS (20U) +#define NPCM4XX_DMASR_TPS_Stopped (20U) +#define NPCM4XX_DMASR_TPS_Fetching (20U) +#define NPCM4XX_DMASR_TPS_Waiting (21U) +#define NPCM4XX_DMASR_TPS_Reading (20U) +#define NPCM4XX_DMASR_TPS_Suspended (21U) +#define NPCM4XX_DMASR_TPS_Closing (20U) +#define NPCM4XX_DMASR_RPS (17U) +#define NPCM4XX_DMASR_RPS_Stopped (17U) +#define NPCM4XX_DMASR_RPS_Fetching (17U) +#define NPCM4XX_DMASR_RPS_Waiting (17U) +#define NPCM4XX_DMASR_RPS_Suspended (19U) +#define NPCM4XX_DMASR_RPS_Closing (17U) +#define NPCM4XX_DMASR_RPS_Queuing (17U) +#define NPCM4XX_DMASR_NIS (16U) +#define NPCM4XX_DMASR_AIS (15U) +#define NPCM4XX_DMASR_ERS (14U) +#define NPCM4XX_DMASR_FBES (13U) +#define NPCM4XX_DMASR_ETS (10U) +#define NPCM4XX_DMASR_RWTS (9U) +#define NPCM4XX_DMASR_RPSS (8U) +#define NPCM4XX_DMASR_RBUS (7U) +#define NPCM4XX_DMASR_RS (6U) +#define NPCM4XX_DMASR_TUS (5U) +#define NPCM4XX_DMASR_ROS (4U) +#define NPCM4XX_DMASR_TJTS (3U) +#define NPCM4XX_DMASR_TBUS (2U) +#define NPCM4XX_DMASR_TPSS (1U) +#define NPCM4XX_DMASR_TS (0U) + +/* DMAOMR fields */ +#define NPCM4XX_DMAOMR_DTCEFD (26U) +#define NPCM4XX_DMAOMR_RSF (25U) +#define NPCM4XX_DMAOMR_DFRF (24U) +#define NPCM4XX_DMAOMR_TSF (21U) +#define NPCM4XX_DMAOMR_FTF (20U) +#define NPCM4XX_DMAOMR_TTC (14U) +#define NPCM4XX_DMAOMR_ST (13U) +#define NPCM4XX_DMAOMR_FEF (7U) +#define NPCM4XX_DMAOMR_FUGF (6U) +#define NPCM4XX_DMAOMR_DGF (5U) +#define NPCM4XX_DMAOMR_RTC (3U) +#define NPCM4XX_DMAOMR_OSF (2U) +#define NPCM4XX_DMAOMR_SR (1U) + +/* DMAIER fields */ +#define NPCM4XX_DMAIER_NISE (16U) +#define NPCM4XX_DMAIER_AISE (15U) +#define NPCM4XX_DMAIER_ERIE (14U) +#define NPCM4XX_DMAIER_FBEIE (13U) +#define NPCM4XX_DMAIER_ETIE (10U) +#define NPCM4XX_DMAIER_RWTIE (9U) +#define NPCM4XX_DMAIER_RPSIE (8U) +#define NPCM4XX_DMAIER_RBUIE (7U) +#define NPCM4XX_DMAIER_RIE (6U) +#define NPCM4XX_DMAIER_TUIE (5U) +#define NPCM4XX_DMAIER_ROIE (4U) +#define NPCM4XX_DMAIER_TJTIE (3U) +#define NPCM4XX_DMAIER_TBUIE (2U) +#define NPCM4XX_DMAIER_TPSIE (1U) +#define NPCM4XX_DMAIER_TIE (0U) + +/* DMAMFBOCR fields */ +#define NPCM4XX_DMAMFBOCR_OFOC (28U) +#define NPCM4XX_DMAMFBOCR_MFA (17U) +#define NPCM4XX_DMAMFBOCR_OMFC (16U) +#define NPCM4XX_DMAMFBOCR_MFC (0U) + +/* DMACHTDR fields */ +#define NPCM4XX_DMACHTDR_HTDAP (0U) + +/* DMACHRDR fields */ +#define NPCM4XX_DMACHRDR_HRDAP (0U) + +/* DMACHTBAR fields */ +#define NPCM4XX_DMACHTBAR_HTBAP (0U) + +/* DMACHRBAR fields */ +#define NPCM4XX_DMACHRBAR_HRBAP (0U) + #endif /* _NUVOTON_NPCM4XX_REG_DEF_H */ diff --git a/soc/arm/npcm4xx/npcm400f/sig_def_list.h b/soc/arm/npcm4xx/npcm400f/sig_def_list.h index a07b86f7c0c332..644c60e3caba78 100644 --- a/soc/arm/npcm4xx/npcm400f/sig_def_list.h +++ b/soc/arm/npcm4xx/npcm400f/sig_def_list.h @@ -365,3 +365,7 @@ SIG_DEFINE(IOX2_DIN, D4, SIG_DESC_CLEAR(0x14, 7), SIG_DESC_SET(0x6A, 1)) /* DEVALT3.5=0, DEVALT6A.1=1 */ SIG_DEFINE(IOX2_SCLK, C4, SIG_DESC_CLEAR(0x13, 5), SIG_DESC_SET(0x6A, 1)) #endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(emac), okay) && CONFIG_ETH_NPCM4XX +SIG_DEFINE(EMAC, D3, SIG_DESC_SET(0x4D, 0), SIG_DESC_SET(0x4D, 1), SIG_DESC_SET(0x4C, 3)) +#endif