drivers: ethernet: support for numaker m55m1x series

Add support for Nuvoton numaker m55m1x series EMAC controller.
Also include NOCACHE_MEMORY allocation.
Support to generate random mac address and remove emac data flash.

Signed-off-by: cyliang tw <cyliang@nuvoton.com>
This commit is contained in:
cyliang tw 2025-04-07 15:15:00 +08:00 committed by Benjamin Cabé
commit ea1129ee1a
9 changed files with 90 additions and 23 deletions

View file

@ -0,0 +1,16 @@
# SPDX-License-Identifier: Apache-2.0
#
# Nuvoton NuMaker M55M1 board configuration
#
# Copyright (c) 2025 Nuvoton Technology Corporation.
if BOARD_NUMAKER_M55M1
if NETWORKING
config NET_L2_ETHERNET
default y if !MODEM
endif # NETWORKING
endif # BOARD_NUMAKER_M55M1

View file

@ -24,4 +24,23 @@
<PC9MFP_GPIO>;
};
};
/* EMAC multi-function pins for MDIO, TX, REFCLK, RX pins */
emac_default: emac_default {
group0 {
pinmux = <PE8MFP_EMAC0_RMII_MDC>,
<PE9MFP_EMAC0_RMII_MDIO>,
<PC8MFP_EMAC0_RMII_REFCLK>,
<PC7MFP_EMAC0_RMII_RXD0>,
<PC6MFP_EMAC0_RMII_RXD1>,
<PA7MFP_EMAC0_RMII_CRSDV>,
<PA6MFP_EMAC0_RMII_RXERR>;
};
group1 {
pinmux = <PE10MFP_EMAC0_RMII_TXD0>,
<PE11MFP_EMAC0_RMII_TXD1>,
<PE12MFP_EMAC0_RMII_TXEN>;
slew-rate = "fast";
};
};
};

View file

@ -86,3 +86,9 @@
pinctrl-names = "default";
status = "okay";
};
&emac {
pinctrl-0 = <&emac_default>;
pinctrl-names = "default";
status = "okay";
};

View file

@ -133,6 +133,9 @@ Ethernet
kconfig options: :kconfig:option:`CONFIG_ETH_NATIVE_POSIX` and its related options have been
deprecated in favor of :kconfig:option:`CONFIG_ETH_NATIVE_TAP` (:github:`86578`).
* NuMaker Ethernet driver ``eth_numaker.c`` now supports ``gen_random_mac``,
and the EMAC data flash feature has been removed (:github:`87953`).
Enhanced Serial Peripheral Interface (eSPI)
===========================================

View file

@ -9,6 +9,7 @@ config ETH_NUMAKER
select HAS_NUMAKER_ETH
select PINCTRL
depends on DT_HAS_NUVOTON_NUMAKER_ETHERNET_ENABLED
select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT
help
This option enables the Ethernet driver for Nuvoton NuMaker family of
processors.

View file

@ -21,22 +21,31 @@
#ifdef CONFIG_SOC_M467
#include <m460_eth.h>
#else
#include <numaker_eth.h>
#endif
LOG_MODULE_REGISTER(eth_numaker, CONFIG_ETHERNET_LOG_LEVEL);
/* Device EMAC Interface port */
#define NUMAKER_GMAC_INTF 0
/* 2KB Data Flash at 0xFF800 */
#define NUMAKER_DATA_FLASH (0xFF800U)
#define NUMAKER_MASK_32 (0xFFFFFFFFU)
#define NUMAKER_MII_CONFIG (ADVERTISE_CSMA | ADVERTISE_10HALF | ADVERTISE_10FULL | \
ADVERTISE_100HALF | ADVERTISE_100FULL)
#define NUMAKER_MII_LINKED (BMSR_ANEGCOMPLETE | BMSR_LSTATUS)
extern synopGMACdevice GMACdev[GMAC_CNT];
#ifdef CONFIG_NOCACHE_MEMORY
DmaDesc tx_desc[GMAC_CNT][TRANSMIT_DESC_SIZE] __nocache __aligned(64);
DmaDesc rx_desc[GMAC_CNT][RECEIVE_DESC_SIZE] __nocache __aligned(64);
struct sk_buff tx_buf[GMAC_CNT][TRANSMIT_DESC_SIZE] __nocache __aligned(64);
struct sk_buff rx_buf[GMAC_CNT][RECEIVE_DESC_SIZE] __nocache __aligned(64);
#else
extern struct sk_buff tx_buf[GMAC_CNT][TRANSMIT_DESC_SIZE];
extern struct sk_buff rx_buf[GMAC_CNT][RECEIVE_DESC_SIZE];
#endif
static uint32_t eth_phy_addr;
@ -167,33 +176,31 @@ static int reset_phy(synopGMACdevice *gmacdev)
static void m_numaker_read_mac_addr(char *mac)
{
#if DT_INST_PROP(0, zephyr_random_mac_address)
gen_random_mac(mac, NUMAKER_OUI_B0, NUMAKER_OUI_B1, NUMAKER_OUI_B2);
#else
uint32_t uid1;
/* Fetch word 0 of data flash */
uint32_t word0 = *(uint32_t *)(NUMAKER_DATA_FLASH + 0x04U);
uint32_t word0;
/*
* Fetch word 1 of data flash
* we only want bottom 16 bits of word1 (MAC bits 32-47)
* and bit 9 forced to 1, bit 8 forced to 0
* Locally administered MAC, reduced conflicts
* http://en.wikipedia.org/wiki/MAC_address
*/
uint32_t word1 = *(uint32_t *)NUMAKER_DATA_FLASH;
uint32_t word1;
/* Not burn any mac address at the beginning of data flash */
if (word0 == NUMAKER_MASK_32) {
/* Generate a semi-unique MAC address from the UUID */
SYS_UnlockReg();
/* Enable FMC ISP function */
FMC_Open();
uid1 = FMC_ReadUID(1);
word1 = (uid1 & 0x003FFFFF) | ((uid1 & 0x030000) << 6) >> 8;
word0 = ((FMC_ReadUID(0) >> 4) << 20) | ((uid1 & 0xFF) << 12) |
(FMC_ReadUID(2) & 0xFFF);
/* Disable FMC ISP function */
FMC_Close();
/* Lock protected registers */
SYS_LockReg();
}
/* Generate a semi-unique MAC address from the UUID */
SYS_UnlockReg();
/* Enable FMC ISP function */
FMC_Open();
uid1 = FMC_ReadUID(1);
word1 = (uid1 & 0x003FFFFF) | ((uid1 & 0x030000) << 6) >> 8;
word0 = ((FMC_ReadUID(0) >> 4) << 20) | ((uid1 & 0xFF) << 12) |
(FMC_ReadUID(2) & 0xFFF);
/* Disable FMC ISP function */
FMC_Close();
/* Lock protected registers */
SYS_LockReg();
word1 |= 0x00000200;
word1 &= 0x0000FEFF;
@ -204,7 +211,7 @@ static void m_numaker_read_mac_addr(char *mac)
mac[3] = (word0 & 0x00ff0000) >> 16;
mac[4] = (word0 & 0x0000ff00) >> 8;
mac[5] = (word0 & 0x000000ff);
#endif
LOG_INF("mac address %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3],
mac[4], mac[5]);
}

View file

@ -15,4 +15,9 @@
#define NU_ETH_MTU_SIZE 1500
/* NuMaker chip's OUI*/
#define NUMAKER_OUI_B0 0xDA
#define NUMAKER_OUI_B1 0x00
#define NUMAKER_OUI_B2 0x53
#endif /* ZEPHYR_DRIVERS_ETHERNET_ETH_NUMAKER_PRIV_H_ */

View file

@ -335,6 +335,16 @@
#size-cells = <0>;
status = "disabled";
};
emac: ethernet@40208000 {
compatible = "nuvoton,numaker-ethernet";
reg = <0x40208000 0x2000>;
interrupts = <63 0>;
resets = <&rst NUMAKER_SYS_EMAC0RST>;
phy-addr = <0>;
clocks = <&pcc NUMAKER_EMAC0_MODULE 0 0>;
status = "disabled";
};
};
};

View file

@ -198,7 +198,7 @@ manifest:
groups:
- hal
- name: hal_nuvoton
revision: 8eec051270fe45c3f9a1a12de60220e1ab26b579
revision: be1042dc8a96ebe9ea4c5d714f07c617539106d6
path: modules/hal/nuvoton
groups:
- hal