Skip to content

Commit 3308b74

Browse files
committed
drivers: ethernet: imx_netc: add GIC MSI support
It could use GIC ITS as MSI controller on Cortex-A Core, so added GIC ITS MSI support for NETC drivers. Signed-off-by: Jiafei Pan <Jiafei.Pan@nxp.com>
1 parent 1d98712 commit 3308b74

File tree

6 files changed

+128
-2
lines changed

6 files changed

+128
-2
lines changed

drivers/ethernet/nxp_imx_netc/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,25 @@ menuconfig ETH_NXP_IMX_NETC
1212

1313
if ETH_NXP_IMX_NETC
1414

15+
DT_GIC_ITS_COMPAT := arm,gic-v3-its
16+
DT_NETC_PATH := $(dt_nodelabel_path,netc)
17+
DT_NETC_INT_PARENT_PATH := $(dt_node_ph_prop_path,$(DT_NETC_PATH),msi-parent)
18+
DT_NETC_INT_IS_GIC := $(dt_node_has_compat,$(DT_NETC_INT_PARENT_PATH),$(DT_GIC_ITS_COMPAT))
19+
20+
config ETH_NXP_IMX_NETC_MSI_GIC
21+
bool
22+
default y if ($(DT_NETC_INT_IS_GIC) && DT_HAS_ARM_GIC_V3_ITS_ENABLED)
23+
depends on GIC_V3_ITS
24+
help
25+
Use GIC ITS controller as MSI module for NXP NETC
26+
27+
if !ETH_NXP_IMX_NETC_MSI_GIC
1528
config ETH_NXP_IMX_MSGINTR
1629
int "Message Interrupt module select"
1730
default 1
1831
help
1932
Message Interrupt module select.
33+
endif
2034

2135
config ETH_NXP_IMX_RX_THREAD_PRIO
2236
int "RX thread priority"

drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ LOG_MODULE_REGISTER(nxp_imx_eth);
2121
#include <zephyr/net/phy.h>
2222
#include <ethernet/eth_stats.h>
2323
#include <zephyr/net/dsa_core.h>
24+
#ifdef CONFIG_GIC_V3_ITS
25+
#include <zephyr/drivers/interrupt_controller/gicv3_its.h>
26+
#endif
2427
#include "../eth.h"
2528
#include "eth_nxp_imx_netc_priv.h"
2629

@@ -173,6 +176,28 @@ static void netc_eth_rx_thread(void *arg1, void *unused1, void *unused2)
173176
}
174177
}
175178

179+
#ifdef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC
180+
181+
static void netc_tx_isr_handler(const void *arg)
182+
{
183+
const struct device *dev = (const struct device *)arg;
184+
struct netc_eth_data *data = dev->data;
185+
186+
EP_CleanTxIntrFlags(&data->handle, 1, 0);
187+
data->tx_done = true;
188+
}
189+
190+
static void netc_rx_isr_handler(const void *arg)
191+
{
192+
const struct device *dev = (const struct device *)arg;
193+
struct netc_eth_data *data = dev->data;
194+
195+
EP_CleanRxIntrFlags(&data->handle, 1);
196+
k_sem_give(&data->rx_sem);
197+
}
198+
199+
#else /* CONFIG_ETH_NXP_IMX_NETC_MSI_GIC */
200+
176201
static void msgintr_isr(void)
177202
{
178203
uint32_t irqs = NETC_MSGINTR->MSI[NETC_MSGINTR_CHANNEL].MSIR;
@@ -203,6 +228,8 @@ static void msgintr_isr(void)
203228
SDK_ISR_EXIT_BARRIER;
204229
}
205230

231+
#endif
232+
206233
int netc_eth_init_common(const struct device *dev)
207234
{
208235
const struct netc_eth_config *config = dev->config;
@@ -222,6 +249,51 @@ int netc_eth_init_common(const struct device *dev)
222249
#endif
223250

224251
/* MSIX entry configuration */
252+
#ifdef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC
253+
int ret;
254+
255+
if (config->msi_dev == NULL) {
256+
LOG_ERR("MSI device is not configured");
257+
return -ENODEV;
258+
}
259+
ret = its_setup_deviceid(config->msi_dev, config->msi_device_id, NETC_MSIX_ENTRY_NUM);
260+
if (ret != 0) {
261+
LOG_ERR("Failed to setup device ID for MSI: %d", ret);
262+
return ret;
263+
}
264+
data->tx_intid = its_alloc_intid(config->msi_dev);
265+
data->rx_intid = its_alloc_intid(config->msi_dev);
266+
267+
msg_addr = its_get_msi_addr(config->msi_dev);
268+
msix_entry[NETC_TX_MSIX_ENTRY_IDX].control = kNETC_MsixIntrMaskBit;
269+
msix_entry[NETC_TX_MSIX_ENTRY_IDX].msgAddr = msg_addr;
270+
msix_entry[NETC_TX_MSIX_ENTRY_IDX].msgData = NETC_TX_MSIX_ENTRY_IDX;
271+
ret = its_map_intid(config->msi_dev, config->msi_device_id, NETC_TX_MSIX_ENTRY_IDX,
272+
data->tx_intid);
273+
if (ret != 0) {
274+
LOG_ERR("Failed to map TX MSI interrupt: %d", ret);
275+
return ret;
276+
}
277+
278+
msix_entry[NETC_RX_MSIX_ENTRY_IDX].control = kNETC_MsixIntrMaskBit;
279+
msix_entry[NETC_RX_MSIX_ENTRY_IDX].msgAddr = msg_addr;
280+
msix_entry[NETC_RX_MSIX_ENTRY_IDX].msgData = NETC_RX_MSIX_ENTRY_IDX;
281+
ret = its_map_intid(config->msi_dev, config->msi_device_id, NETC_RX_MSIX_ENTRY_IDX,
282+
data->rx_intid);
283+
if (ret != 0) {
284+
LOG_ERR("Failed to map RX MSI interrupt: %d", ret);
285+
return ret;
286+
}
287+
288+
if (!irq_is_enabled(data->tx_intid)) {
289+
irq_connect_dynamic(data->tx_intid, 0, netc_tx_isr_handler, dev, 0);
290+
irq_enable(data->tx_intid);
291+
}
292+
if (!irq_is_enabled(data->rx_intid)) {
293+
irq_connect_dynamic(data->rx_intid, 0, netc_rx_isr_handler, dev, 0);
294+
irq_enable(data->rx_intid);
295+
}
296+
#else
225297
msg_addr = MSGINTR_GetIntrSelectAddr(NETC_MSGINTR, NETC_MSGINTR_CHANNEL);
226298
msix_entry[NETC_TX_MSIX_ENTRY_IDX].control = kNETC_MsixIntrMaskBit;
227299
msix_entry[NETC_TX_MSIX_ENTRY_IDX].msgAddr = msg_addr;
@@ -235,6 +307,7 @@ int netc_eth_init_common(const struct device *dev)
235307
IRQ_CONNECT(NETC_MSGINTR_IRQ, 0, msgintr_isr, 0, 0);
236308
irq_enable(NETC_MSGINTR_IRQ);
237309
}
310+
#endif
238311

239312
/* Endpoint configuration. */
240313
EP_GetDefaultConfig(&ep_config);

drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_priv.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99

1010
#include "nxp_imx_netc.h"
1111
#include "fsl_netc_endpoint.h"
12+
#ifndef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC
1213
#include "fsl_msgintr.h"
14+
#endif
1315

1416
/* Buffer and descriptor alignment */
1517
#define NETC_BUFF_ALIGN 64
@@ -33,6 +35,7 @@
3335
#define NETC_MSGINTR_IRQ DT_IRQN_BY_IDX(DT_NODELABEL(netc), 0)
3436
#endif
3537

38+
#ifndef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC
3639
#if (CONFIG_ETH_NXP_IMX_MSGINTR == 1)
3740
#define NETC_MSGINTR MSGINTR1
3841
#ifndef NETC_MSGINTR_IRQ
@@ -46,6 +49,7 @@
4649
#else
4750
#error "Current CONFIG_ETH_NXP_IMX_MSGINTR not support"
4851
#endif
52+
#endif /* CONFIG_ETH_NXP_IMX_NETC_MSI_GIC */
4953

5054
/* Timeout for various operations */
5155
#define NETC_TIMEOUT K_MSEC(20)
@@ -90,8 +94,13 @@ struct netc_eth_config {
9094
void (*bdr_init)(netc_bdr_config_t *bdr_config, netc_rx_bdr_config_t *rx_bdr_config,
9195
netc_tx_bdr_config_t *tx_bdr_config);
9296
const struct pinctrl_dev_config *pincfg;
97+
#ifdef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC
98+
const struct device *msi_dev;
99+
uint8_t msi_device_id; /* MSI device ID */
100+
#else
93101
uint8_t tx_intr_msg_data;
94102
uint8_t rx_intr_msg_data;
103+
#endif
95104
#ifdef CONFIG_PTP_CLOCK_NXP_NETC
96105
const struct device *ptp_clock;
97106
#endif
@@ -113,6 +122,10 @@ struct netc_eth_data {
113122

114123
K_KERNEL_STACK_MEMBER(rx_thread_stack, CONFIG_ETH_NXP_IMX_RX_THREAD_STACK_SIZE);
115124
uint8_t *rx_frame;
125+
#ifdef CONFIG_ETH_NXP_IMX_NETC_MSI_GIC
126+
unsigned int tx_intid;
127+
unsigned int rx_intid;
128+
#endif
116129
};
117130

118131
int netc_eth_init_common(const struct device *dev);

drivers/ethernet/nxp_imx_netc/eth_nxp_imx_netc_psi.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,14 @@ static const struct ethernet_api netc_eth_api = {.iface_api.init = netc_eth_ifac
200200
.pseudo_mac = DT_ENUM_HAS_VALUE(DT_DRV_INST(n), phy_connection_type, internal), \
201201
.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
202202
.si_idx = (DT_INST_PROP(n, mac_index) << 8) | DT_INST_PROP(n, si_index), \
203-
.tx_intr_msg_data = NETC_TX_INTR_MSG_DATA_START + n, \
204-
.rx_intr_msg_data = NETC_RX_INTR_MSG_DATA_START + n, \
203+
IF_ENABLED(CONFIG_ETH_NXP_IMX_NETC_MSI_GIC, \
204+
(.msi_device_id = DT_INST_PROP_OR(n, msi_device_id, 0), \
205+
.msi_dev = (COND_CODE_1(DT_NODE_HAS_PROP(DT_INST_PARENT(n), msi_parent), \
206+
(DEVICE_DT_GET(DT_PHANDLE(DT_INST_PARENT(n), msi_parent))), NULL)), \
207+
)) \
208+
IF_DISABLED(CONFIG_ETH_NXP_IMX_NETC_MSI_GIC, \
209+
(.tx_intr_msg_data = NETC_TX_INTR_MSG_DATA_START + n, \
210+
.rx_intr_msg_data = NETC_RX_INTR_MSG_DATA_START + n,)) \
205211
IF_ENABLED(CONFIG_PTP_CLOCK_NXP_NETC, \
206212
(.ptp_clock = DEVICE_DT_GET(DT_INST_PHANDLE(n, ptp_clock)),)) \
207213
}; \

dts/bindings/ethernet/nxp,imx-netc-psi.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,7 @@ properties:
2020
required: true
2121
type: int
2222
description: The SI index of this PSI.
23+
24+
msi-device-id:
25+
type: int
26+
description: The device ID passed to MSI controller.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright 2025 NXP
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: NXP i.MX NETC Controller
5+
6+
compatible: "nxp,imx-netc"
7+
8+
include: [base.yaml]
9+
10+
properties:
11+
reg:
12+
required: true
13+
14+
msi-parent:
15+
type: phandle
16+
description: MSI controller

0 commit comments

Comments
 (0)