diff --git a/drivers/ethernet/nxp_imx_netc/Kconfig b/drivers/ethernet/nxp_imx_netc/Kconfig index 5c6af4f5c0c..21636cb438a 100644 --- a/drivers/ethernet/nxp_imx_netc/Kconfig +++ b/drivers/ethernet/nxp_imx_netc/Kconfig @@ -12,11 +12,25 @@ menuconfig ETH_NXP_IMX_NETC if ETH_NXP_IMX_NETC +DT_GIC_ITS_COMPAT := arm,gic-v3-its +DT_NETC_PATH := $(dt_nodelabel_path,netc) +DT_NETC_INT_PARENT_PATH := $(dt_node_ph_prop_path,$(DT_NETC_PATH),msi-parent) +DT_NETC_INT_IS_GIC := $(dt_node_has_compat,$(DT_NETC_INT_PARENT_PATH),$(DT_GIC_ITS_COMPAT)) + +config ETH_NXP_IMX_NETC_MSI_GIC + bool + default y if ($(DT_NETC_INT_IS_GIC) && DT_HAS_ARM_GIC_V3_ITS_ENABLED) + depends on GIC_V3_ITS + help + Use GIC ITS controller as MSI module for NXP NETC + +if !ETH_NXP_IMX_NETC_MSI_GIC config ETH_NXP_IMX_MSGINTR int "Message Interrupt module select" default 1 help Message Interrupt module select. +endif config ETH_NXP_IMX_RX_THREAD_PRIO int "RX thread priority" diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c index 32762582dce..ec82fafb653 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c @@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(nxp_imx_eth); #include #include #include +#ifdef CONFIG_GIC_V3_ITS +#include +#endif #include "../eth.h" #include "eth_nxp_imx_netc_priv.h" @@ -173,6 +176,28 @@ static void netc_eth_rx_thread(void *arg1, void *unused1, void *unused2) } } +#ifdef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC + +static void netc_tx_isr_handler(const void *arg) +{ + const struct device *dev = (const struct device *)arg; + struct netc_eth_data *data = dev->data; + + EP_CleanTxIntrFlags(&data->handle, 1, 0); + data->tx_done = true; +} + +static void netc_rx_isr_handler(const void *arg) +{ + const struct device *dev = (const struct device *)arg; + struct netc_eth_data *data = dev->data; + + EP_CleanRxIntrFlags(&data->handle, 1); + k_sem_give(&data->rx_sem); +} + +#else /* CONFIG_ETH_NXP_IMX_NETC_MSI_GIC */ + static void msgintr_isr(void) { uint32_t irqs = NETC_MSGINTR->MSI[NETC_MSGINTR_CHANNEL].MSIR; @@ -203,6 +228,8 @@ static void msgintr_isr(void) SDK_ISR_EXIT_BARRIER; } +#endif + int netc_eth_init_common(const struct device *dev) { const struct netc_eth_config *config = dev->config; @@ -222,6 +249,51 @@ int netc_eth_init_common(const struct device *dev) #endif /* MSIX entry configuration */ +#ifdef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC + int ret; + + if (config->msi_dev == NULL) { + LOG_ERR("MSI device is not configured"); + return -ENODEV; + } + ret = its_setup_deviceid(config->msi_dev, config->msi_device_id, NETC_MSIX_ENTRY_NUM); + if (ret != 0) { + LOG_ERR("Failed to setup device ID for MSI: %d", ret); + return ret; + } + data->tx_intid = its_alloc_intid(config->msi_dev); + data->rx_intid = its_alloc_intid(config->msi_dev); + + msg_addr = its_get_msi_addr(config->msi_dev); + msix_entry[NETC_TX_MSIX_ENTRY_IDX].control = kNETC_MsixIntrMaskBit; + msix_entry[NETC_TX_MSIX_ENTRY_IDX].msgAddr = msg_addr; + msix_entry[NETC_TX_MSIX_ENTRY_IDX].msgData = NETC_TX_MSIX_ENTRY_IDX; + ret = its_map_intid(config->msi_dev, config->msi_device_id, NETC_TX_MSIX_ENTRY_IDX, + data->tx_intid); + if (ret != 0) { + LOG_ERR("Failed to map TX MSI interrupt: %d", ret); + return ret; + } + + msix_entry[NETC_RX_MSIX_ENTRY_IDX].control = kNETC_MsixIntrMaskBit; + msix_entry[NETC_RX_MSIX_ENTRY_IDX].msgAddr = msg_addr; + msix_entry[NETC_RX_MSIX_ENTRY_IDX].msgData = NETC_RX_MSIX_ENTRY_IDX; + ret = its_map_intid(config->msi_dev, config->msi_device_id, NETC_RX_MSIX_ENTRY_IDX, + data->rx_intid); + if (ret != 0) { + LOG_ERR("Failed to map RX MSI interrupt: %d", ret); + return ret; + } + + if (!irq_is_enabled(data->tx_intid)) { + irq_connect_dynamic(data->tx_intid, 0, netc_tx_isr_handler, dev, 0); + irq_enable(data->tx_intid); + } + if (!irq_is_enabled(data->rx_intid)) { + irq_connect_dynamic(data->rx_intid, 0, netc_rx_isr_handler, dev, 0); + irq_enable(data->rx_intid); + } +#else msg_addr = MSGINTR_GetIntrSelectAddr(NETC_MSGINTR, NETC_MSGINTR_CHANNEL); msix_entry[NETC_TX_MSIX_ENTRY_IDX].control = kNETC_MsixIntrMaskBit; msix_entry[NETC_TX_MSIX_ENTRY_IDX].msgAddr = msg_addr; @@ -235,6 +307,7 @@ int netc_eth_init_common(const struct device *dev) IRQ_CONNECT(NETC_MSGINTR_IRQ, 0, msgintr_isr, 0, 0); irq_enable(NETC_MSGINTR_IRQ); } +#endif /* Endpoint configuration. */ EP_GetDefaultConfig(&ep_config); diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h index 157f7e61bae..1aba309246f 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h @@ -9,7 +9,9 @@ #include "nxp_imx_netc.h" #include "fsl_netc_endpoint.h" +#ifndef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC #include "fsl_msgintr.h" +#endif /* Buffer and descriptor alignment */ #define NETC_BUFF_ALIGN 64 @@ -33,6 +35,7 @@ #define NETC_MSGINTR_IRQ DT_IRQN_BY_IDX(DT_NODELABEL(netc), 0) #endif +#ifndef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC #if (CONFIG_ETH_NXP_IMX_MSGINTR == 1) #define NETC_MSGINTR MSGINTR1 #ifndef NETC_MSGINTR_IRQ @@ -46,6 +49,7 @@ #else #error "Current CONFIG_ETH_NXP_IMX_MSGINTR not support" #endif +#endif /* CONFIG_ETH_NXP_IMX_NETC_MSI_GIC */ /* Timeout for various operations */ #define NETC_TIMEOUT K_MSEC(20) @@ -90,8 +94,13 @@ struct netc_eth_config { void (*bdr_init)(netc_bdr_config_t *bdr_config, netc_rx_bdr_config_t *rx_bdr_config, netc_tx_bdr_config_t *tx_bdr_config); const struct pinctrl_dev_config *pincfg; +#ifdef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC + const struct device *msi_dev; + uint8_t msi_device_id; /* MSI device ID */ +#else uint8_t tx_intr_msg_data; uint8_t rx_intr_msg_data; +#endif #ifdef CONFIG_PTP_CLOCK_NXP_NETC const struct device *ptp_clock; #endif @@ -113,6 +122,10 @@ struct netc_eth_data { K_KERNEL_STACK_MEMBER(rx_thread_stack, CONFIG_ETH_NXP_IMX_RX_THREAD_STACK_SIZE); uint8_t *rx_frame; +#ifdef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC + unsigned int tx_intid; + unsigned int rx_intid; +#endif }; int netc_eth_init_common(const struct device *dev); diff --git a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_psi.c b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_psi.c index 3dc10ae8724..10f0def52e8 100644 --- a/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_psi.c +++ b/drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_psi.c @@ -200,8 +200,14 @@ static const struct ethernet_api netc_eth_api = {.iface_api.init = netc_eth_ifac .pseudo_mac = DT_ENUM_HAS_VALUE(DT_DRV_INST(n), phy_connection_type, internal), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ .si_idx = (DT_INST_PROP(n, mac_index) << 8) | DT_INST_PROP(n, si_index), \ - .tx_intr_msg_data = NETC_TX_INTR_MSG_DATA_START + n, \ - .rx_intr_msg_data = NETC_RX_INTR_MSG_DATA_START + n, \ + IF_ENABLED(CONFIG_ETH_NXP_IMX_NETC_MSI_GIC, \ + (.msi_device_id = DT_INST_PROP_OR(n, msi_device_id, 0), \ + .msi_dev = (COND_CODE_1(DT_NODE_HAS_PROP(DT_INST_PARENT(n), msi_parent), \ + (DEVICE_DT_GET(DT_PHANDLE(DT_INST_PARENT(n), msi_parent))), NULL)), \ + )) \ + IF_DISABLED(CONFIG_ETH_NXP_IMX_NETC_MSI_GIC, \ + (.tx_intr_msg_data = NETC_TX_INTR_MSG_DATA_START + n, \ + .rx_intr_msg_data = NETC_RX_INTR_MSG_DATA_START + n,)) \ IF_ENABLED(CONFIG_PTP_CLOCK_NXP_NETC, \ (.ptp_clock = DEVICE_DT_GET(DT_INST_PHANDLE(n, ptp_clock)),)) \ }; \ diff --git a/dts/bindings/ethernet/nxp,imx-netc-psi.yaml b/dts/bindings/ethernet/nxp,imx-netc-psi.yaml index 7aba10df1e3..128a385af07 100644 --- a/dts/bindings/ethernet/nxp,imx-netc-psi.yaml +++ b/dts/bindings/ethernet/nxp,imx-netc-psi.yaml @@ -20,3 +20,7 @@ properties: required: true type: int description: The SI index of this PSI. + + msi-device-id: + type: int + description: The device ID passed to MSI controller. diff --git a/dts/bindings/ethernet/nxp,imx-netc.yaml b/dts/bindings/ethernet/nxp,imx-netc.yaml new file mode 100644 index 00000000000..bf1d53254a2 --- /dev/null +++ b/dts/bindings/ethernet/nxp,imx-netc.yaml @@ -0,0 +1,16 @@ +# Copyright 2025 NXP +# SPDX-License-Identifier: Apache-2.0 + +description: NXP i.MX NETC Controller + +compatible: "nxp,imx-netc" + +include: [base.yaml] + +properties: + reg: + required: true + + msi-parent: + type: phandle + description: MSI controller