From 72b818a1979f3b216ce39b019f56c1b1ecd5c3cf Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Wed, 4 Dec 2024 18:52:20 +0700 Subject: [PATCH 1/6] manifest: Update hal_renesas commit ID to support Ethernet Update hal_renesas new commit ID, in this version there are support for Ethernet and Ethernet phy in hal layer Signed-off-by: Duy Nguyen --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index deecf69acfe98..39bb8e84afeb5 100644 --- a/west.yml +++ b/west.yml @@ -215,7 +215,7 @@ manifest: - hal - name: hal_renesas path: modules/hal/renesas - revision: 10326518701e25bf336a2eaeb8b5820110e4e6a3 + revision: f77a8501c2adeec8eb98f51ee5c5c5aa095575a1 groups: - hal - name: hal_rpi_pico From b50b8f0a4857c86d1847376ce09b1a96a19e900c Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Fri, 25 Oct 2024 11:47:59 +0700 Subject: [PATCH 2/6] drivers: mdio: Initial support for renesas RA mdio driver Add support for mdio driver for Renesas RA MCU series This support utilize the r_ether_phy driver in hal renesas to support mdio write and read function Signed-off-by: Duy Nguyen --- drivers/mdio/CMakeLists.txt | 1 + drivers/mdio/Kconfig | 1 + drivers/mdio/Kconfig.renesas_ra | 11 +++ drivers/mdio/mdio_renesas_ra.c | 123 +++++++++++++++++++++++++ dts/bindings/mdio/renesas,ra-mdio.yaml | 15 +++ modules/Kconfig.renesas_fsp | 5 + 6 files changed, 156 insertions(+) create mode 100644 drivers/mdio/Kconfig.renesas_ra create mode 100644 drivers/mdio/mdio_renesas_ra.c create mode 100644 dts/bindings/mdio/renesas,ra-mdio.yaml diff --git a/drivers/mdio/CMakeLists.txt b/drivers/mdio/CMakeLists.txt index 640919c1037b1..779ba7ed5ef30 100644 --- a/drivers/mdio/CMakeLists.txt +++ b/drivers/mdio/CMakeLists.txt @@ -16,3 +16,4 @@ zephyr_library_sources_ifdef(CONFIG_MDIO_ST_STM32_HAL mdio_stm32_hal.c) zephyr_library_sources_ifdef(CONFIG_MDIO_INFINEON_XMC4XXX mdio_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_MDIO_NXP_ENET_QOS mdio_nxp_enet_qos.c) zephyr_library_sources_ifdef(CONFIG_MDIO_DWCXGMAC mdio_dwcxgmac.c) +zephyr_library_sources_ifdef(CONFIG_MDIO_RENESAS_RA mdio_renesas_ra.c) diff --git a/drivers/mdio/Kconfig b/drivers/mdio/Kconfig index 3c001237a8f59..77dc4d3411171 100644 --- a/drivers/mdio/Kconfig +++ b/drivers/mdio/Kconfig @@ -37,6 +37,7 @@ source "drivers/mdio/Kconfig.stm32_hal" source "drivers/mdio/Kconfig.xmc4xxx" source "drivers/mdio/Kconfig.nxp_enet_qos" source "drivers/mdio/Kconfig.dwcxgmac" +source "drivers/mdio/Kconfig.renesas_ra" config MDIO_INIT_PRIORITY int "Init priority" diff --git a/drivers/mdio/Kconfig.renesas_ra b/drivers/mdio/Kconfig.renesas_ra new file mode 100644 index 0000000000000..9702bf9b2b465 --- /dev/null +++ b/drivers/mdio/Kconfig.renesas_ra @@ -0,0 +1,11 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config MDIO_RENESAS_RA + bool "RENESAS MDIO controller driver" + default y + depends on DT_HAS_RENESAS_RA_MDIO_ENABLED + select PINCTRL + select USE_RA_FSP_ETHER_PHY + help + Enable RENESAS MDIO support. diff --git a/drivers/mdio/mdio_renesas_ra.c b/drivers/mdio/mdio_renesas_ra.c new file mode 100644 index 0000000000000..e32443a29ea88 --- /dev/null +++ b/drivers/mdio/mdio_renesas_ra.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "r_ether_phy.h" + +#include + +LOG_MODULE_REGISTER(renesas_ra_mdio, CONFIG_MDIO_LOG_LEVEL); + +#define DT_DRV_COMPAT renesas_ra_mdio + +struct renesas_ra_mdio_config { + const struct pinctrl_dev_config *pincfg; + uint8_t instance; +}; + +struct renesas_ra_mdio_data { + struct k_mutex rw_mutex; + struct st_ether_phy_cfg ether_phy_cfg; + struct st_ether_phy_instance_ctrl ether_phy_ctrl; +}; + +static int renesas_ra_mdio_read(const struct device *dev, uint8_t prtad, uint8_t regad, + uint16_t *data) +{ + struct renesas_ra_mdio_data *dev_data = dev->data; + uint32_t read; + fsp_err_t err; + + dev_data->ether_phy_ctrl.phy_lsi_address = prtad; + + k_mutex_lock(&dev_data->rw_mutex, K_FOREVER); + + err = R_ETHER_PHY_Read(&dev_data->ether_phy_ctrl, regad, &read); + + k_mutex_unlock(&dev_data->rw_mutex); + + if (err != FSP_SUCCESS) { + return -EIO; + } + + *data = read & UINT16_MAX; + + return 0; +} + +static int renesas_ra_mdio_write(const struct device *dev, uint8_t prtad, uint8_t regad, + uint16_t data) +{ + struct renesas_ra_mdio_data *dev_data = dev->data; + fsp_err_t err; + + dev_data->ether_phy_ctrl.phy_lsi_address = prtad; + + k_mutex_lock(&dev_data->rw_mutex, K_FOREVER); + + err = R_ETHER_PHY_Write(&dev_data->ether_phy_ctrl, regad, data); + + k_mutex_unlock(&dev_data->rw_mutex); + + if (err != FSP_SUCCESS) { + return -EIO; + } + + return 0; +} + +static int renesas_ra_mdio_initialize(const struct device *dev) +{ + struct renesas_ra_mdio_data *data = dev->data; + const struct renesas_ra_mdio_config *cfg = dev->config; + int err; + fsp_err_t fsp_err; + + err = pinctrl_apply_state(cfg->pincfg, PINCTRL_STATE_DEFAULT); + if (err != 0) { + return err; + } + + fsp_err = R_ETHER_PHY_Open(&data->ether_phy_ctrl, &data->ether_phy_cfg); + + if (fsp_err != FSP_SUCCESS) { + LOG_ERR("Failed to init mdio driver - R_ETHER_PHY_Open fail"); + } + + k_mutex_init(&data->rw_mutex); + + return 0; +} + +static DEVICE_API(mdio, renesas_ra_mdio_api) = { + .read = renesas_ra_mdio_read, + .write = renesas_ra_mdio_write, +}; + +#define RENSAS_RA_MDIO_INSTANCE_DEFINE(node) \ + PINCTRL_DT_INST_DEFINE(node); \ + static struct renesas_ra_mdio_data renesas_ra_mdio##node##_data = { \ + .ether_phy_cfg = { \ + .channel = 0, \ + .phy_reset_wait_time = 0x00020000, \ + .mii_bit_access_wait_time = 8, \ + .phy_lsi_type = ETHER_PHY_LSI_TYPE_CUSTOM, \ + .flow_control = ETHER_PHY_FLOW_CONTROL_DISABLE, \ + }}; \ + static const struct renesas_ra_mdio_config renesas_ra_mdio##node##_cfg = { \ + .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(node)}; \ + DEVICE_DT_INST_DEFINE(node, &renesas_ra_mdio_initialize, NULL, \ + &renesas_ra_mdio##node##_data, &renesas_ra_mdio##node##_cfg, \ + POST_KERNEL, CONFIG_MDIO_INIT_PRIORITY, &renesas_ra_mdio_api); + +DT_INST_FOREACH_STATUS_OKAY(RENSAS_RA_MDIO_INSTANCE_DEFINE) diff --git a/dts/bindings/mdio/renesas,ra-mdio.yaml b/dts/bindings/mdio/renesas,ra-mdio.yaml new file mode 100644 index 0000000000000..51971c9e8a977 --- /dev/null +++ b/dts/bindings/mdio/renesas,ra-mdio.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA External MDIO controller + +compatible: "renesas,ra-mdio" + +include: [mdio-controller.yaml, pinctrl-device.yaml] + +properties: + pinctrl-0: + required: true + + pinctrl-names: + required: true diff --git a/modules/Kconfig.renesas_fsp b/modules/Kconfig.renesas_fsp index 9a1f796938551..1800ee52d522f 100644 --- a/modules/Kconfig.renesas_fsp +++ b/modules/Kconfig.renesas_fsp @@ -81,4 +81,9 @@ config USE_RA_FSP_CANFD help Enable RA FSP CANFD driver +config USE_RA_FSP_ETHER_PHY + bool + help + Enable RA FSP Ethernet phy driver + endif # HAS_RENESAS_RA_FSP From 9038ccbd5922b591feea4578bfb7b42c417b0b9b Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Fri, 25 Oct 2024 11:50:44 +0700 Subject: [PATCH 3/6] drivers: eth: phy_mii: Add BMSR second read in update_link state The ICS1894 phy AN_COMPLETE bit is latched high, this make the BMSR first read return incorrect status of the AN state, update one more BMSR read to ensure all latched bit is clear and BMSR return actual status of the phy chip Signed-off-by: Duy Nguyen --- drivers/ethernet/phy/phy_mii.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/ethernet/phy/phy_mii.c b/drivers/ethernet/phy/phy_mii.c index 8aa5b17d51cf0..a19eb252bb117 100644 --- a/drivers/ethernet/phy/phy_mii.c +++ b/drivers/ethernet/phy/phy_mii.c @@ -205,6 +205,14 @@ static int update_link_state(const struct device *dev) k_sleep(K_MSEC(100)); + /* On some PHY chips, the BMSR bits are latched, so the first read may + * show incorrect status. A second read ensures correct values. + */ + if (phy_mii_reg_read(dev, MII_BMSR, &bmsr_reg) < 0) { + return -EIO; + } + + /* Second read, clears the latched bits and gives the correct status */ if (phy_mii_reg_read(dev, MII_BMSR, &bmsr_reg) < 0) { return -EIO; } From fd5b83151220e6edd4209cf2d0fc830c56dc8c40 Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Tue, 29 Oct 2024 10:35:01 +0700 Subject: [PATCH 4/6] drivers: eth: Initial support for Renesas RA Ethernet driver This commit is to enable Ethernet drivers support on Renesas RA MCU, first target support is the Renesas RA8 series Signed-off-by: Duy Nguyen --- drivers/ethernet/CMakeLists.txt | 1 + drivers/ethernet/Kconfig | 1 + drivers/ethernet/Kconfig.renesas_ra | 36 ++ drivers/ethernet/eth_renesas_ra.c | 413 ++++++++++++++++++ dts/arm/renesas/ra/ra8/ra8x1.dtsi | 16 + .../ethernet/renesas,ra-ethernet.yaml | 18 + modules/Kconfig.renesas_fsp | 5 + 7 files changed, 490 insertions(+) create mode 100644 drivers/ethernet/Kconfig.renesas_ra create mode 100644 drivers/ethernet/eth_renesas_ra.c create mode 100644 dts/bindings/ethernet/renesas,ra-ethernet.yaml diff --git a/drivers/ethernet/CMakeLists.txt b/drivers/ethernet/CMakeLists.txt index 545187a6b2cf1..abab18562e15c 100644 --- a/drivers/ethernet/CMakeLists.txt +++ b/drivers/ethernet/CMakeLists.txt @@ -41,6 +41,7 @@ zephyr_library_sources_ifdef(CONFIG_ETH_ADIN2111 eth_adin2111.c) zephyr_library_sources_ifdef(CONFIG_ETH_LAN865X eth_lan865x.c oa_tc6.c) zephyr_library_sources_ifdef(CONFIG_ETH_XMC4XXX eth_xmc4xxx.c) zephyr_library_sources_ifdef(CONFIG_ETH_TEST eth_test.c) +zephyr_library_sources_ifdef(CONFIG_ETH_RENESAS_RA eth_renesas_ra.c) if(CONFIG_ETH_NXP_S32_NETC) zephyr_library_sources(eth_nxp_s32_netc.c) diff --git a/drivers/ethernet/Kconfig b/drivers/ethernet/Kconfig index 178733bd24792..7164189b1aac7 100644 --- a/drivers/ethernet/Kconfig +++ b/drivers/ethernet/Kconfig @@ -82,6 +82,7 @@ source "drivers/ethernet/dwc_xgmac/Kconfig" source "drivers/ethernet/phy/Kconfig" source "drivers/ethernet/nxp_enet/Kconfig" +source "drivers/ethernet/Kconfig.renesas_ra" endif # "Ethernet Drivers" diff --git a/drivers/ethernet/Kconfig.renesas_ra b/drivers/ethernet/Kconfig.renesas_ra new file mode 100644 index 0000000000000..a6c04e9392b17 --- /dev/null +++ b/drivers/ethernet/Kconfig.renesas_ra @@ -0,0 +1,36 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config ETH_RENESAS_RA + bool "Renesas RA Ethernet" + default y + depends on DT_HAS_RENESAS_RA_ETHERNET_ENABLED + select USE_RA_FSP_ETHER + select MDIO + help + Enable Renesas RA Ethernet Driver. + +if ETH_RENESAS_RA + +config ETH_RA_RX_THREAD_STACK_SIZE + int "Stack size for internal incoming packet handler" + default 1500 + help + Size of the stack used for internal thread which is ran for + incoming packet processing. + +config ETH_RA_RX_THREAD_PRIORITY + int "Renesas RA Ethernet receive thread priority" + default 2 + +config ETH_RENESAS_TX_BUF_NUM + int "Number of Transmit buffer" + default 4 + range 1 8 + +config ETH_RENESAS_RX_BUF_NUM + int "Number of Receive buffer" + default 4 + range 1 8 + +endif diff --git a/drivers/ethernet/eth_renesas_ra.c b/drivers/ethernet/eth_renesas_ra.c new file mode 100644 index 0000000000000..9ce7d41a7ab6f --- /dev/null +++ b/drivers/ethernet/eth_renesas_ra.c @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_ethernet + +/* Renesas RA ethernet driver */ + +#define LOG_MODULE_NAME eth_ra_ethernet +#define LOG_LEVEL CONFIG_ETHERNET_LOG_LEVEL + +#include +LOG_MODULE_REGISTER(LOG_MODULE_NAME); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "r_ether.h" +#include "r_ether_phy.h" + +/* Additional configurations to use with hal_renesas */ +#define ETHER_DEFAULT NULL +#define ETHER_CHANNEL0 0 +#define ETHER_BUF_SIZE 1536 +#define ETHER_PADDING_OFFSET 1 +#define ETHER_BROADCAST_FILTER 0 +#define ETHER_TOTAL_BUF_NUM (CONFIG_ETH_RENESAS_TX_BUF_NUM + CONFIG_ETH_RENESAS_RX_BUF_NUM) +#define ETHER_EE_RECEIVE_EVENT_MASK (0x01070000) + +void ether_eint_isr(void); +void renesas_ra_eth_callback(ether_callback_args_t *p_args); +static void renesas_ra_eth_buffer_init(const struct device *dev); + +extern void ether_init_buffers(ether_instance_ctrl_t *const p_instance_ctrl); +extern void ether_configure_mac(ether_instance_ctrl_t *const p_instance_ctrl, + const uint8_t mac_addr[], const uint8_t mode); +extern void ether_do_link(ether_instance_ctrl_t *const p_instance_ctrl, const uint8_t mode); + +uint8_t g_ether0_mac_address[6] = DT_INST_PROP(0, local_mac_address); +struct renesas_ra_eth_context { + struct net_if *iface; + uint8_t mac[6]; + + K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_ETH_RA_RX_THREAD_STACK_SIZE); + struct k_thread thread; + struct k_sem rx_sem; + ether_instance_ctrl_t ctrl; + /** pinctrl configs */ + const struct pinctrl_dev_config *pcfg; +}; + +struct renesas_ra_eth_config { + const ether_cfg_t *p_cfg; + const struct device *phy_dev; +}; + +#define DECLARE_ETHER_RX_BUFFER(idx, _) \ + static __aligned(32) uint8_t g_ether0_ether_rx_buffer##idx[ETHER_BUF_SIZE]; + +#define DECLARE_ETHER_TX_BUFFER(idx, _) \ + static __aligned(32) uint8_t g_ether0_ether_tx_buffer##idx[ETHER_BUF_SIZE]; + +#define DECLARE_ETHER_RX_BUFFER_PTR(idx, _) (uint8_t *)&g_ether0_ether_rx_buffer##idx[0] + +#define DECLARE_ETHER_TX_BUFFER_PTR(idx, _) (uint8_t *)&g_ether0_ether_tx_buffer##idx[0] + +LISTIFY(CONFIG_ETH_RENESAS_RX_BUF_NUM, DECLARE_ETHER_RX_BUFFER, (;)); +LISTIFY(CONFIG_ETH_RENESAS_TX_BUF_NUM, DECLARE_ETHER_TX_BUFFER, (;)); + +uint8_t *pp_g_ether0_ether_buffers[ETHER_TOTAL_BUF_NUM] = { + LISTIFY(CONFIG_ETH_RENESAS_RX_BUF_NUM, DECLARE_ETHER_RX_BUFFER_PTR, (,)), + LISTIFY(CONFIG_ETH_RENESAS_TX_BUF_NUM, DECLARE_ETHER_TX_BUFFER_PTR, (,)) +}; + +static __aligned(16) ether_instance_descriptor_t + g_ether0_tx_descriptors[CONFIG_ETH_RENESAS_TX_BUF_NUM]; +static __aligned(16) ether_instance_descriptor_t + g_ether0_rx_descriptors[CONFIG_ETH_RENESAS_RX_BUF_NUM]; + +const ether_extended_cfg_t g_ether0_extended_cfg_t = { + .p_rx_descriptors = g_ether0_rx_descriptors, + .p_tx_descriptors = g_ether0_tx_descriptors, +}; + +/* Dummy configuration for ether phy as hal layer require */ +const ether_phy_extended_cfg_t g_ether_phy0_extended_cfg = { + .p_target_init = ETHER_DEFAULT, .p_target_link_partner_ability_get = ETHER_DEFAULT}; + +const ether_phy_cfg_t g_ether_phy0_cfg; + +ether_phy_instance_ctrl_t g_ether_phy0_ctrl; + +const ether_phy_instance_t g_ether_phy0 = {.p_ctrl = &g_ether_phy0_ctrl, + .p_cfg = &g_ether_phy0_cfg, + .p_api = &g_ether_phy_on_ether_phy}; + +const ether_cfg_t g_ether0_cfg = { + .channel = ETHER_CHANNEL0, + .zerocopy = ETHER_ZEROCOPY_DISABLE, + .multicast = ETHER_MULTICAST_ENABLE, + .promiscuous = ETHER_PROMISCUOUS_DISABLE, + .flow_control = ETHER_FLOW_CONTROL_DISABLE, + .padding = ETHER_PADDING_DISABLE, + .padding_offset = ETHER_PADDING_OFFSET, + .broadcast_filter = ETHER_BROADCAST_FILTER, + .p_mac_address = g_ether0_mac_address, + .num_tx_descriptors = CONFIG_ETH_RENESAS_TX_BUF_NUM, + .num_rx_descriptors = CONFIG_ETH_RENESAS_RX_BUF_NUM, + .pp_ether_buffers = pp_g_ether0_ether_buffers, + .ether_buffer_size = ETHER_BUF_SIZE, + .irq = DT_INST_IRQN(0), + .interrupt_priority = DT_INST_IRQ(0, priority), + .p_callback = ETHER_DEFAULT, + .p_ether_phy_instance = &g_ether_phy0, + .p_context = ETHER_DEFAULT, + .p_extend = &g_ether0_extended_cfg_t, +}; + +static struct renesas_ra_eth_config eth_0_config = { + .p_cfg = &g_ether0_cfg, .phy_dev = DEVICE_DT_GET(DT_INST_PHANDLE(0, phy_handle))}; + +/* Driver functions */ +static enum ethernet_hw_caps renesas_ra_eth_get_capabilities(const struct device *dev) +{ + ARG_UNUSED(dev); + + return ETHERNET_LINK_10BASE_T | ETHERNET_LINK_100BASE_T; +} + +void renesas_ra_eth_callback(ether_callback_args_t *p_args) +{ + struct device *dev = (struct device *)p_args->p_context; + struct renesas_ra_eth_context *ctx = dev->data; + + if (p_args->status_eesr & ETHER_EE_RECEIVE_EVENT_MASK) { + k_sem_give(&ctx->rx_sem); + } +} + +static void renesas_ra_eth_buffer_init(const struct device *dev) +{ + struct renesas_ra_eth_context *ctx = dev->data; + ether_extended_cfg_t *p_ether_extended_cfg = + (ether_extended_cfg_t *)ctx->ctrl.p_ether_cfg->p_extend; + /* Initialize the transmit and receive descriptor */ + memset(p_ether_extended_cfg->p_rx_descriptors, 0x00, + sizeof(ether_instance_descriptor_t) * ctx->ctrl.p_ether_cfg->num_rx_descriptors); + memset(p_ether_extended_cfg->p_tx_descriptors, 0x00, + sizeof(ether_instance_descriptor_t) * ctx->ctrl.p_ether_cfg->num_tx_descriptors); + + ether_init_buffers(&ctx->ctrl); +} + +static void phy_link_state_changed(const struct device *pdev, struct phy_link_state *state, + void *user_data) +{ + const struct device *dev = (struct device *)user_data; + struct renesas_ra_eth_context *ctx = dev->data; + R_ETHERC0_Type *p_reg_etherc; + + p_reg_etherc = (R_ETHERC0_Type *)ctx->ctrl.p_reg_etherc; + + ARG_UNUSED(pdev); + + if (state->is_up) { + + ctx->ctrl.link_change = ETHER_LINK_CHANGE_LINK_UP; + ctx->ctrl.previous_link_status = ETHER_PREVIOUS_LINK_STATUS_UP; + + renesas_ra_eth_buffer_init(dev); + + /* + * ETHERC and EDMAC are set after ETHERC and EDMAC are reset in software + * and sending and receiving is permitted. + */ + ether_configure_mac(&ctx->ctrl, ctx->ctrl.p_ether_cfg->p_mac_address, 0); + + switch (state->speed) { + /* Half duplex link */ + case LINK_HALF_100BASE_T: { + ctx->ctrl.link_speed_duplex = ETHER_PHY_LINK_SPEED_100H; + break; + } + + case LINK_HALF_10BASE_T: { + ctx->ctrl.link_speed_duplex = ETHER_PHY_LINK_SPEED_10H; + break; + } + + /* Full duplex link */ + case LINK_FULL_100BASE_T: { + ctx->ctrl.link_speed_duplex = ETHER_PHY_LINK_SPEED_100F; + break; + } + + case LINK_FULL_10BASE_T: { + ctx->ctrl.link_speed_duplex = ETHER_PHY_LINK_SPEED_10F; + break; + } + + default: { + ctx->ctrl.link_speed_duplex = ETHER_PHY_LINK_SPEED_100F; + break; + } + } + + ether_do_link(&ctx->ctrl, 0); + ctx->ctrl.link_change = ETHER_LINK_CHANGE_LINK_UP; + ctx->ctrl.previous_link_status = ETHER_PREVIOUS_LINK_STATUS_UP; + ctx->ctrl.link_establish_status = ETHER_LINK_ESTABLISH_STATUS_UP; + LOG_DBG("Link up"); + net_eth_carrier_on(ctx->iface); + } else { + ctx->ctrl.link_change = ETHER_LINK_CHANGE_LINK_DOWN; + ctx->ctrl.previous_link_status = ETHER_PREVIOUS_LINK_STATUS_DOWN; + ctx->ctrl.link_establish_status = ETHER_LINK_ESTABLISH_STATUS_DOWN; + net_eth_carrier_off(ctx->iface); + } +} + +static void renesas_ra_eth_initialize(struct net_if *iface) +{ + fsp_err_t err; + const struct device *dev = net_if_get_device(iface); + struct renesas_ra_eth_context *ctx = dev->data; + const struct renesas_ra_eth_config *cfg = dev->config; + const char *phy_connection_type = DT_INST_PROP_OR(0, phy_connection_type, "rmii"); + + LOG_DBG("eth_initialize"); + + net_if_set_link_addr(iface, ctx->mac, sizeof(ctx->mac), NET_LINK_ETHERNET); + + if (ctx->iface == NULL) { + ctx->iface = iface; + } + + ethernet_init(iface); + + R_PMISC->PFENET = (uint8_t)(0x0 << R_PMISC_PFENET_PHYMODE0_Pos); + + if (strstr(phy_connection_type, "mii") != NULL) { + /* Configure pins for MII or RMII. Set PHYMODE0 if MII is selected. */ + R_PMISC->PFENET = (uint8_t)(0x1 << R_PMISC_PFENET_PHYMODE0_Pos); + } else { + LOG_ERR("Failed to init ether - phy-connection-type not support"); + } + + err = R_ETHER_Open(&ctx->ctrl, cfg->p_cfg); + + if (err != FSP_SUCCESS) { + LOG_ERR("Failed to init ether - R_ETHER_Open fail"); + } + + err = R_ETHER_CallbackSet(&ctx->ctrl, renesas_ra_eth_callback, dev, NULL); + + if (err != FSP_SUCCESS) { + LOG_ERR("Failed to init ether - R_ETHER_CallbackSet fail"); + } + + phy_link_callback_set(cfg->phy_dev, &phy_link_state_changed, (void *)dev); + /* Do not start the interface until PHY link is up */ + net_if_carrier_off(ctx->iface); +} + +static int renesas_ra_eth_tx(const struct device *dev, struct net_pkt *pkt) +{ + fsp_err_t err = FSP_SUCCESS; + struct renesas_ra_eth_context *ctx = dev->data; + uint16_t len = net_pkt_get_len(pkt); + static uint8_t tx_buf[NET_ETH_MAX_FRAME_SIZE]; + + if (net_pkt_read(pkt, tx_buf, len)) { + goto error; + } + + /* Check if packet length is less than minimum Ethernet frame size */ + if (len < NET_ETH_MINIMAL_FRAME_SIZE) { + /* Add padding to meet the minimum frame size */ + memset(tx_buf + len, 0, NET_ETH_MINIMAL_FRAME_SIZE - len); + len = NET_ETH_MINIMAL_FRAME_SIZE; + } + + err = R_ETHER_Write(&ctx->ctrl, tx_buf, len); + if (err != FSP_SUCCESS) { + goto error; + } + + return 0; + +error: + LOG_ERR("Writing to FIFO failed"); + return -1; +} + +static const struct ethernet_api api_funcs = { + .iface_api.init = renesas_ra_eth_initialize, + .get_capabilities = renesas_ra_eth_get_capabilities, + .send = renesas_ra_eth_tx, +}; + +static void renesas_ra_eth_isr(const struct device *dev) +{ + ARG_UNUSED(dev); + ether_eint_isr(); +} + +static struct net_pkt *renesas_ra_eth_rx(const struct device *dev) +{ + fsp_err_t err = FSP_SUCCESS; + struct renesas_ra_eth_context *ctx; + struct net_pkt *pkt = NULL; + uint32_t len = 0; + static uint8_t rx_buf[NET_ETH_MAX_FRAME_SIZE]; + + __ASSERT_NO_MSG(dev != NULL); + ctx = dev->data; + __ASSERT_NO_MSG(ctx != NULL); + + err = R_ETHER_Read(&ctx->ctrl, rx_buf, &len); + if ((err != FSP_SUCCESS) && (err != FSP_ERR_ETHER_ERROR_NO_DATA)) { + LOG_ERR("Failed to read packets"); + goto out; + } + + pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, len, AF_UNSPEC, 0, K_MSEC(100)); + if (!pkt) { + LOG_ERR("Failed to obtain RX buffer"); + goto out; + } + + if (net_pkt_write(pkt, rx_buf, len)) { + LOG_ERR("Failed to append RX buffer to context buffer"); + net_pkt_unref(pkt); + pkt = NULL; + goto out; + } + +out: + if (pkt == NULL) { + eth_stats_update_errors_rx(ctx->iface); + } + + return pkt; +} + +static void renesas_ra_eth_thread(void *p1, void *p2, void *p3) +{ + ARG_UNUSED(p2); + ARG_UNUSED(p3); + + const struct device *dev = p1; + struct net_if *iface; + int res; + struct net_pkt *pkt = NULL; + struct renesas_ra_eth_context *ctx = dev->data; + + while (true) { + res = k_sem_take(&ctx->rx_sem, K_MSEC(CONFIG_PHY_MONITOR_PERIOD)); + if (res == 0) { + pkt = renesas_ra_eth_rx(dev); + + if (pkt != NULL) { + iface = net_pkt_iface(pkt); + res = net_recv_data(iface, pkt); + if (res < 0) { + net_pkt_unref(pkt); + } + } + } + } +} + +#define ELC_EVENT_EDMAC_EINT(channel) ELC_EVENT_EDMAC##channel##_EINT + +/* Bindings to the platform */ +int renesas_ra_eth_init(const struct device *dev) +{ + struct renesas_ra_eth_context *ctx = dev->data; + + R_ICU->IELSR[DT_INST_IRQN(0)] = ELC_EVENT_EDMAC_EINT(0); + + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), renesas_ra_eth_isr, + DEVICE_DT_INST_GET(0), 0); + + k_thread_create(&ctx->thread, ctx->thread_stack, CONFIG_ETH_RA_RX_THREAD_STACK_SIZE, + renesas_ra_eth_thread, (void *)dev, NULL, NULL, + K_PRIO_COOP(CONFIG_ETH_RA_RX_THREAD_PRIORITY), 0, K_NO_WAIT); + + irq_enable(DT_INST_IRQN(0)); + + return 0; +} + +#define ETHER_RA_INIT(idx) \ + PINCTRL_DT_INST_DEFINE(0); \ + static struct renesas_ra_eth_context eth_0_context = { \ + .mac = DT_INST_PROP(0, local_mac_address), \ + .rx_sem = Z_SEM_INITIALIZER(eth_0_context.rx_sem, 0, UINT_MAX), \ + .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0), \ + }; \ + \ + ETH_NET_DEVICE_DT_INST_DEFINE(0, renesas_ra_eth_init, NULL, ð_0_context, ð_0_config, \ + CONFIG_ETH_INIT_PRIORITY, &api_funcs, NET_ETH_MTU /*MTU*/); + +DT_INST_FOREACH_STATUS_OKAY(ETHER_RA_INIT); diff --git a/dts/arm/renesas/ra/ra8/ra8x1.dtsi b/dts/arm/renesas/ra/ra8/ra8x1.dtsi index 96d493e25e4d6..3d9ad95ec08aa 100644 --- a/dts/arm/renesas/ra/ra8/ra8x1.dtsi +++ b/dts/arm/renesas/ra/ra8/ra8x1.dtsi @@ -557,6 +557,22 @@ status = "disabled"; }; }; + + eth: ethernet@40354100 { + compatible = "renesas,ra-ethernet"; + reg = <0x40354100 0xfc>; + interrupts = <42 0>; + local-mac-address = [00 11 22 33 44 55]; + phy-connection-type = "rmii"; + status = "disabled"; + }; + + mdio: mdio { + compatible = "renesas,ra-mdio"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; }; diff --git a/dts/bindings/ethernet/renesas,ra-ethernet.yaml b/dts/bindings/ethernet/renesas,ra-ethernet.yaml new file mode 100644 index 0000000000000..002510e9c6698 --- /dev/null +++ b/dts/bindings/ethernet/renesas,ra-ethernet.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA Ethernet + +compatible: "renesas,ra-ethernet" + +include: [ethernet-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + phy-handle: + required: true diff --git a/modules/Kconfig.renesas_fsp b/modules/Kconfig.renesas_fsp index 1800ee52d522f..4b9eb15ddd4e9 100644 --- a/modules/Kconfig.renesas_fsp +++ b/modules/Kconfig.renesas_fsp @@ -86,4 +86,9 @@ config USE_RA_FSP_ETHER_PHY help Enable RA FSP Ethernet phy driver +config USE_RA_FSP_ETHER + bool + help + Enable RA FSP Ethernet driver + endif # HAS_RENESAS_RA_FSP From dae9479af32adc1ab4f380814b6fed0067badedc Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Tue, 29 Oct 2024 10:35:44 +0700 Subject: [PATCH 5/6] boards: renesas: ra: Add Ethernet support for RA8 boards Enable Ethernet controller node and mdio node for RA boards. Add pinctl for mdio and Ethernet usage Signed-off-by: Duy Nguyen --- boards/renesas/ek_ra8d1/Kconfig.defconfig | 13 ++++++++++ boards/renesas/ek_ra8d1/doc/index.rst | 12 +++++++++ boards/renesas/ek_ra8d1/ek_ra8d1-pinctrl.dtsi | 25 ++++++++++++++++--- boards/renesas/ek_ra8d1/ek_ra8d1.dts | 18 +++++++++++++ boards/renesas/ek_ra8m1/Kconfig.defconfig | 13 ++++++++++ boards/renesas/ek_ra8m1/doc/index.rst | 4 +++ boards/renesas/ek_ra8m1/ek_ra8m1-pinctrl.dtsi | 17 +++++++++++++ boards/renesas/ek_ra8m1/ek_ra8m1.dts | 18 +++++++++++++ boards/renesas/mck_ra8t1/Kconfig.defconfig | 13 ++++++++++ boards/renesas/mck_ra8t1/doc/index.rst | 2 ++ .../renesas/mck_ra8t1/mck_ra8t1-pinctrl.dtsi | 17 +++++++++++++ boards/renesas/mck_ra8t1/mck_ra8t1.dts | 18 +++++++++++++ 12 files changed, 166 insertions(+), 4 deletions(-) create mode 100644 boards/renesas/ek_ra8d1/Kconfig.defconfig create mode 100644 boards/renesas/ek_ra8m1/Kconfig.defconfig create mode 100644 boards/renesas/mck_ra8t1/Kconfig.defconfig diff --git a/boards/renesas/ek_ra8d1/Kconfig.defconfig b/boards/renesas/ek_ra8d1/Kconfig.defconfig new file mode 100644 index 0000000000000..d99c0d945ba15 --- /dev/null +++ b/boards/renesas/ek_ra8d1/Kconfig.defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_EK_RA8D1 + +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING + +endif # BOARD_EK_RA8D1 diff --git a/boards/renesas/ek_ra8d1/doc/index.rst b/boards/renesas/ek_ra8d1/doc/index.rst index 20c887373c8ee..bed54638bd279 100644 --- a/boards/renesas/ek_ra8d1/doc/index.rst +++ b/boards/renesas/ek_ra8d1/doc/index.rst @@ -112,6 +112,18 @@ The below features are currently supported on Zephyr OS for EK-RA8D1 board: +--------------+------------+------------------+ | I2C | on-chip | i2c | +--------------+------------+------------------+ +| ETHERNET | on-chip | ethernet | ++--------------+------------+------------------+ + +**Note:** for using Ethernet on RA8D1 board please set switch SW1 as following configuration: + ++-------------+-------------+--------------+------------+------------+------------+-------------+-----------+ +| SW1-1 PMOD1 | SW1-2 TRACE | SW1-3 CAMERA | SW1-4 ETHA | SW1-5 ETHB | SW1-6 GLCD | SW1-7 SDRAM | SW1-8 I3C | ++-------------+-------------+--------------+------------+------------+------------+-------------+-----------+ +| OFF | OFF | OFF | OFF | ON | OFF | OFF | OFF | ++-------------+-------------+--------------+------------+------------+------------+-------------+-----------+ + +**CAUTION:** Do not enable SW1-4 and SW1-5 together Other hardware features are currently not supported by the port. diff --git a/boards/renesas/ek_ra8d1/ek_ra8d1-pinctrl.dtsi b/boards/renesas/ek_ra8d1/ek_ra8d1-pinctrl.dtsi index b450f9c339319..a96d4d225f211 100644 --- a/boards/renesas/ek_ra8d1/ek_ra8d1-pinctrl.dtsi +++ b/boards/renesas/ek_ra8d1/ek_ra8d1-pinctrl.dtsi @@ -19,10 +19,10 @@ spi0_default: spi0_default { group1 { /* MISO MOSI RSPCK SSL */ - psels = , - , - , - ; + psels = , + , + , + ; }; }; @@ -53,4 +53,21 @@ drive-strength = "medium"; }; }; + + ether_default: ether_default { + group1 { + psels = , /* ET0_MDC */ + , /* ET0_MDIO */ + , /* ET0_LINKSTA */ + , /* RMII0_TXD_EN_B */ + , /* RMII0_TXD1_BR */ + , /* RMII0_TXD0_B */ + , /* REF50CK0_B */ + , /* RMII0_RXD0_B */ + , /* RMII0_RXD1_B */ + , /* RMII0_RX_ER_B */ + ; /* RMII0_CRS_DV_B */ + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra8d1/ek_ra8d1.dts b/boards/renesas/ek_ra8d1/ek_ra8d1.dts index 82eb5f3b43e5b..6ef2af8b46bd4 100644 --- a/boards/renesas/ek_ra8d1/ek_ra8d1.dts +++ b/boards/renesas/ek_ra8d1/ek_ra8d1.dts @@ -160,3 +160,21 @@ pinctrl-0 = <&iic1_default>; pinctrl-names = "default"; }; + +ð { + local-mac-address = [74 90 50 B0 5D E9]; + status = "okay"; + phy-handle = <&phy>; +}; + +&mdio { + pinctrl-0 = <ðer_default>; + pinctrl-names = "default"; + status = "okay"; + + phy: ethernet-phy@5 { + compatible = "ethernet-phy"; + reg = <5>; + status = "okay"; + }; +}; diff --git a/boards/renesas/ek_ra8m1/Kconfig.defconfig b/boards/renesas/ek_ra8m1/Kconfig.defconfig new file mode 100644 index 0000000000000..7f10ef8232f43 --- /dev/null +++ b/boards/renesas/ek_ra8m1/Kconfig.defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_EK_RA8M1 + +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING + +endif # BOARD_EK_RA8M1 diff --git a/boards/renesas/ek_ra8m1/doc/index.rst b/boards/renesas/ek_ra8m1/doc/index.rst index 09d36befe02dc..d62ed9c3937ed 100644 --- a/boards/renesas/ek_ra8m1/doc/index.rst +++ b/boards/renesas/ek_ra8m1/doc/index.rst @@ -112,6 +112,10 @@ The below features are currently supported on Zephyr OS for EK-RA8M1 board: +-----------+------------+----------------------+ | CAN | on-chip | canfd | +-----------+------------+----------------------+ +| ETHERNET | on-chip | ethernet | ++-----------+------------+----------------------+ + +**Note:** For using Ethernet module on EK-RA8M1, remove jumper J61 to enable Ethernet B Other hardware features are currently not supported by the port. diff --git a/boards/renesas/ek_ra8m1/ek_ra8m1-pinctrl.dtsi b/boards/renesas/ek_ra8m1/ek_ra8m1-pinctrl.dtsi index e1cf5623feccf..cac279265a133 100644 --- a/boards/renesas/ek_ra8m1/ek_ra8m1-pinctrl.dtsi +++ b/boards/renesas/ek_ra8m1/ek_ra8m1-pinctrl.dtsi @@ -97,4 +97,21 @@ drive-strength = "high"; }; }; + + ether_default: ether_default { + group1 { + psels = , /* ET0_MDC */ + , /* ET0_MDIO */ + , /* ET0_LINKSTA */ + , /* RMII0_TXD_EN_B */ + , /* RMII0_TXD1_BR */ + , /* RMII0_TXD0_B */ + , /* REF50CK0_B */ + , /* RMII0_RXD0_B */ + , /* RMII0_RXD1_B */ + , /* RMII0_RX_ER_B */ + ; /* RMII0_CRS_DV_B */ + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/ek_ra8m1/ek_ra8m1.dts b/boards/renesas/ek_ra8m1/ek_ra8m1.dts index 3d587fb0e1777..daeeaff22778d 100644 --- a/boards/renesas/ek_ra8m1/ek_ra8m1.dts +++ b/boards/renesas/ek_ra8m1/ek_ra8m1.dts @@ -287,3 +287,21 @@ pmod2_serial: &uart2 {}; pmod_serial: &pmod1_serial {}; pmod_header: &pmod1_header {}; + +ð { + local-mac-address = [74 90 50 B0 6D 5A]; + status = "okay"; + phy-handle = <&phy>; +}; + +&mdio { + pinctrl-0 = <ðer_default>; + pinctrl-names = "default"; + status = "okay"; + + phy: ethernet-phy@5 { + compatible = "ethernet-phy"; + reg = <5>; + status = "okay"; + }; +}; diff --git a/boards/renesas/mck_ra8t1/Kconfig.defconfig b/boards/renesas/mck_ra8t1/Kconfig.defconfig new file mode 100644 index 0000000000000..37c1586dbb1cc --- /dev/null +++ b/boards/renesas/mck_ra8t1/Kconfig.defconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if BOARD_MCK_RA8T1 + +if NETWORKING + +config NET_L2_ETHERNET + default y + +endif # NETWORKING + +endif # BOARD_MCK_RA8T1 diff --git a/boards/renesas/mck_ra8t1/doc/index.rst b/boards/renesas/mck_ra8t1/doc/index.rst index eeda35fceaf01..999767e0bc2b8 100644 --- a/boards/renesas/mck_ra8t1/doc/index.rst +++ b/boards/renesas/mck_ra8t1/doc/index.rst @@ -110,6 +110,8 @@ The below features are currently supported on Zephyr OS for MCB-RA8T1 board: +--------------+------------+----------------------+ | I2C | on-chip | i2c | +--------------+------------+----------------------+ +| ETHERNET | on-chip | ethernet | ++--------------+------------+----------------------+ Other hardware features are currently not supported by the port. diff --git a/boards/renesas/mck_ra8t1/mck_ra8t1-pinctrl.dtsi b/boards/renesas/mck_ra8t1/mck_ra8t1-pinctrl.dtsi index 63903204f4481..2f13bbbf4c242 100644 --- a/boards/renesas/mck_ra8t1/mck_ra8t1-pinctrl.dtsi +++ b/boards/renesas/mck_ra8t1/mck_ra8t1-pinctrl.dtsi @@ -53,4 +53,21 @@ drive-strength = "medium"; }; }; + + ether_default: ether_default { + group1 { + psels = , /* ET0_MDC */ + , /* ET0_MDIO */ + , /* ET0_LINKSTA */ + , /* RMII0_TXD_EN_B */ + , /* RMII0_TXD1_BR */ + , /* RMII0_TXD0_B */ + , /* REF50CK0_B */ + , /* RMII0_RXD0_B */ + , /* RMII0_RXD1_B */ + , /* RMII0_RX_ER_B */ + ; /* RMII0_CRS_DV_B */ + drive-strength = "high"; + }; + }; }; diff --git a/boards/renesas/mck_ra8t1/mck_ra8t1.dts b/boards/renesas/mck_ra8t1/mck_ra8t1.dts index 19f46abcddce4..a0e4387e60c17 100644 --- a/boards/renesas/mck_ra8t1/mck_ra8t1.dts +++ b/boards/renesas/mck_ra8t1/mck_ra8t1.dts @@ -153,3 +153,21 @@ pinctrl-0 = <&iic1_default>; pinctrl-names = "default"; }; + +ð { + local-mac-address = [74 90 50 6D 81 75]; + status = "okay"; + phy-handle = <&phy>; +}; + +&mdio { + pinctrl-0 = <ðer_default>; + pinctrl-names = "default"; + status = "okay"; + + phy: ethernet-phy@5 { + compatible = "ethernet-phy"; + reg = <5>; + status = "okay"; + }; +}; From d9239c6ae469f06f551f3ba623fbe08945d4a12e Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Thu, 21 Nov 2024 14:35:47 +0700 Subject: [PATCH 6/6] sample: net: Add initialize for dup_flag when publish When publish message, the dup_flag is not intialize causing it to have random value and making the AWS MQTT broker to reject the message Add initialize dup_flag as 0 Signed-off-by: Duy Nguyen --- samples/net/cloud/aws_iot_mqtt/src/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/net/cloud/aws_iot_mqtt/src/main.c b/samples/net/cloud/aws_iot_mqtt/src/main.c index 5e52d70187f30..c03f250bcaa21 100644 --- a/samples/net/cloud/aws_iot_mqtt/src/main.c +++ b/samples/net/cloud/aws_iot_mqtt/src/main.c @@ -126,6 +126,7 @@ static int publish_message(const char *topic, size_t topic_len, uint8_t *payload struct mqtt_publish_param msg; msg.retain_flag = 0u; + msg.dup_flag = 0u; msg.message.topic.topic.utf8 = topic; msg.message.topic.topic.size = topic_len; msg.message.topic.qos = CONFIG_AWS_QOS;