Skip to content

Commit 4be0439

Browse files
decsnyaescolar
authored andcommitted
drivers: nxp_enet: Convert RX to workqueue
Convert from multiple threads for each instance to use one workqueue for all instances. The benefit is to save memory and use a kernel function that already exists for a use case like this. Also introduce the ETH_NXP_ENET_RX_THREAD_PRIORITY kconfig, which makes the thread priority of the workqueue configurable. Finally, remove the code enabling the RxBufferInterrupt, since the meaning of it isn't used currently in this driver. Signed-off-by: Declan Snyder <[email protected]>
1 parent bc785e0 commit 4be0439

File tree

2 files changed

+47
-28
lines changed

2 files changed

+47
-28
lines changed

drivers/ethernet/Kconfig.nxp_enet

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ config ETH_NXP_ENET_RX_THREAD_STACK_SIZE
3838
help
3939
ENET RX thread stack size in bytes.
4040

41+
config ETH_NXP_ENET_RX_THREAD_PRIORITY
42+
int "NXP ENET driver RX cooperative thread priority"
43+
default 2
44+
help
45+
ENET MAC Driver handles RX in cooperative workqueue thread.
46+
This options sets the priority of that thread.
47+
4148
config ETH_NXP_ENET_RX_BUFFERS
4249
int "Number of RX buffers for ethernet driver"
4350
default 6

drivers/ethernet/eth_nxp_enet.c

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* NXP ENET MAC Driver
22
*
3-
* Copyright 2023 NXP
3+
* Copyright 2023-2024 NXP
44
*
55
* Inspiration from eth_mcux.c, which was:
66
* Copyright (c) 2016-2017 ARM Ltd
@@ -23,6 +23,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
2323
#include <zephyr/sys/util.h>
2424
#include <zephyr/kernel.h>
2525
#include <zephyr/sys/__assert.h>
26+
#include <zephyr/kernel/thread_stack.h>
2627

2728
#include <zephyr/net/net_pkt.h>
2829
#include <zephyr/net/net_if.h>
@@ -73,10 +74,8 @@ struct nxp_enet_mac_data {
7374
uint8_t mac_addr[6];
7475
enet_handle_t enet_handle;
7576
struct k_sem tx_buf_sem;
76-
77-
K_KERNEL_STACK_MEMBER(rx_thread_stack, CONFIG_ETH_NXP_ENET_RX_THREAD_STACK_SIZE);
78-
79-
struct k_thread rx_thread;
77+
struct k_work rx_work;
78+
const struct device *dev;
8079
struct k_sem rx_thread_sem;
8180
struct k_mutex tx_frame_buf_mutex;
8281
struct k_mutex rx_frame_buf_mutex;
@@ -88,6 +87,24 @@ struct nxp_enet_mac_data {
8887
uint8_t *rx_frame_buf;
8988
};
9089

90+
static K_THREAD_STACK_DEFINE(enet_rx_stack, CONFIG_ETH_NXP_ENET_RX_THREAD_STACK_SIZE);
91+
static struct k_work_q rx_work_queue;
92+
93+
static int rx_queue_init(void)
94+
{
95+
struct k_work_queue_config cfg = {.name = "ENET_RX"};
96+
97+
k_work_queue_init(&rx_work_queue);
98+
k_work_queue_start(&rx_work_queue, enet_rx_stack,
99+
K_THREAD_STACK_SIZEOF(enet_rx_stack),
100+
K_PRIO_COOP(CONFIG_ETH_NXP_ENET_RX_THREAD_PRIORITY),
101+
&cfg);
102+
103+
return 0;
104+
}
105+
106+
SYS_INIT(rx_queue_init, POST_KERNEL, 0);
107+
91108
static inline struct net_if *get_iface(struct nxp_enet_mac_data *data)
92109
{
93110
return data->iface;
@@ -387,22 +404,23 @@ static int eth_nxp_enet_rx(const struct device *dev)
387404
return -EIO;
388405
}
389406

390-
static void eth_nxp_enet_rx_thread(void *arg1, void *unused1, void *unused2)
407+
static void eth_nxp_enet_rx_thread(struct k_work *work)
391408
{
392-
const struct device *dev = arg1;
409+
struct nxp_enet_mac_data *data =
410+
CONTAINER_OF(work, struct nxp_enet_mac_data, rx_work);
411+
const struct device *dev = data->dev;
393412
const struct nxp_enet_mac_config *config = dev->config;
394-
struct nxp_enet_mac_data *data = dev->data;
413+
int ret;
395414

396-
while (1) {
397-
if (k_sem_take(&data->rx_thread_sem, K_FOREVER) == 0) {
398-
while (eth_nxp_enet_rx(dev) == 1) {
399-
;
400-
}
401-
/* enable the IRQ for RX */
402-
ENET_EnableInterrupts(config->base,
403-
kENET_RxFrameInterrupt | kENET_RxBufferInterrupt);
404-
}
415+
if (k_sem_take(&data->rx_thread_sem, K_FOREVER)) {
416+
return;
405417
}
418+
419+
do {
420+
ret = eth_nxp_enet_rx(dev);
421+
} while (ret == 1);
422+
423+
ENET_EnableInterrupts(config->base, kENET_RxFrameInterrupt);
406424
}
407425

408426
static int nxp_enet_phy_reset_and_configure(const struct device *phy)
@@ -514,10 +532,10 @@ static void eth_nxp_enet_isr(const struct device *dev)
514532

515533
uint32_t eir = ENET_GetInterruptStatus(config->base);
516534

517-
if (eir & (kENET_RxBufferInterrupt | kENET_RxFrameInterrupt)) {
535+
if (eir & (kENET_RxFrameInterrupt)) {
518536
ENET_ReceiveIRQHandler(ENET_IRQ_HANDLER_ARGS(config->base, &data->enet_handle));
519-
ENET_DisableInterrupts(config->base,
520-
kENET_RxFrameInterrupt | kENET_RxBufferInterrupt);
537+
ENET_DisableInterrupts(config->base, kENET_RxFrameInterrupt);
538+
k_work_submit_to_queue(&rx_work_queue, &data->rx_work);
521539
}
522540

523541
if (eir & kENET_TxFrameInterrupt) {
@@ -552,19 +570,12 @@ static int eth_nxp_enet_init(const struct device *dev)
552570
#if defined(CONFIG_PTP_CLOCK_NXP_ENET)
553571
k_sem_init(&data->ptp_ts_sem, 0, 1);
554572
#endif
573+
k_work_init(&data->rx_work, eth_nxp_enet_rx_thread);
555574

556575
if (config->generate_mac) {
557576
config->generate_mac(data->mac_addr);
558577
}
559578

560-
/* Start interruption-poll thread */
561-
k_thread_create(&data->rx_thread, data->rx_thread_stack,
562-
K_KERNEL_STACK_SIZEOF(data->rx_thread_stack),
563-
eth_nxp_enet_rx_thread, (void *) dev, NULL, NULL,
564-
K_PRIO_COOP(2),
565-
0, K_NO_WAIT);
566-
k_thread_name_set(&data->rx_thread, "eth_nxp_enet_rx");
567-
568579
err = clock_control_get_rate(config->clock_dev, config->clock_subsys,
569580
&enet_module_clock_rate);
570581
if (err) {
@@ -888,6 +899,7 @@ static const struct ethernet_api api_funcs = {
888899
NXP_ENET_DECIDE_MAC_ADDR(n) \
889900
.tx_frame_buf = nxp_enet_##n##_tx_frame_buf, \
890901
.rx_frame_buf = nxp_enet_##n##_rx_frame_buf, \
902+
.dev = DEVICE_DT_INST_GET(n), \
891903
}; \
892904
\
893905
ETH_NXP_ENET_PM_DEVICE_INIT(n) \

0 commit comments

Comments
 (0)