airoha: backport minor fixup for Ethernet driver on Offload Scenario

Backport minor fixup merged upstream for Ethernet driver on Offload
Scenario. This is to continue the effort of keeping the Airoha Ethernet
driver synced with the upstream version.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
This commit is contained in:
Christian Marangi 2026-04-01 09:07:38 +02:00
parent cd0f6ddf13
commit 2f52b8f724
No known key found for this signature in database
GPG Key ID: AC001D09ADBFEAD7
7 changed files with 143 additions and 23 deletions

View File

@ -0,0 +1,63 @@
From cedc1bf327de62ec30af9743bd1f601c2de30553 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Sun, 29 Mar 2026 12:32:27 +0200
Subject: [PATCH] net: airoha: Delay offloading until all net_devices are fully
registered
Netfilter flowtable can theoretically try to offload flower rules as soon
as a net_device is registered while all the other ones are not
registered or initialized, triggering a possible NULL pointer dereferencing
of qdma pointer in airoha_ppe_set_cpu_port routine. Moreover, if
register_netdev() fails for a particular net_device, there is a small
race if Netfilter tries to offload flowtable rules before all the
net_devices are properly unregistered in airoha_probe() error patch,
triggering a NULL pointer dereferencing in airoha_ppe_set_cpu_port
routine. In order to avoid any possible race, delay offloading until
all net_devices are registered in the networking subsystem.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260329-airoha-regiser-race-fix-v2-1-f4ebb139277b@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 2 ++
drivers/net/ethernet/airoha/airoha_eth.h | 1 +
drivers/net/ethernet/airoha/airoha_ppe.c | 7 +++++++
3 files changed, 10 insertions(+)
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2957,6 +2957,8 @@ static int airoha_register_gdm_devices(s
return err;
}
+ set_bit(DEV_STATE_REGISTERED, &eth->state);
+
return 0;
}
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -88,6 +88,7 @@ enum {
enum {
DEV_STATE_INITIALIZED,
+ DEV_STATE_REGISTERED,
};
enum {
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -1387,6 +1387,13 @@ int airoha_ppe_setup_tc_block_cb(struct
struct airoha_eth *eth = ppe->eth;
int err = 0;
+ /* Netfilter flowtable can try to offload flower rules while not all
+ * the net_devices are registered or initialized. Delay offloading
+ * until all net_devices are registered in the system.
+ */
+ if (!test_bit(DEV_STATE_REGISTERED, &eth->state))
+ return -EBUSY;
+
mutex_lock(&flow_offload_mutex);
if (!eth->npu)

View File

@ -0,0 +1,57 @@
From 514aac3599879a7ed48b7dc19e31145beb6958ac Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Fri, 27 Mar 2026 10:48:21 +0100
Subject: [PATCH] net: airoha: Add missing cleanup bits in
airoha_qdma_cleanup_rx_queue()
In order to properly cleanup hw rx QDMA queues and bring the device to
the initial state, reset rx DMA queue head/tail index. Moreover, reset
queued DMA descriptor fields.
Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
Tested-by: Madhur Agrawal <Madhur.Agrawal@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260327-airoha_qdma_cleanup_rx_queue-fix-v1-1-369d6ab1511a@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -794,18 +794,34 @@ static int airoha_qdma_init_rx_queue(str
static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q)
{
- struct airoha_eth *eth = q->qdma->eth;
+ struct airoha_qdma *qdma = q->qdma;
+ struct airoha_eth *eth = qdma->eth;
+ int qid = q - &qdma->q_rx[0];
while (q->queued) {
struct airoha_queue_entry *e = &q->entry[q->tail];
+ struct airoha_qdma_desc *desc = &q->desc[q->tail];
struct page *page = virt_to_head_page(e->buf);
dma_sync_single_for_cpu(eth->dev, e->dma_addr, e->dma_len,
page_pool_get_dma_dir(q->page_pool));
page_pool_put_full_page(q->page_pool, page, false);
+ /* Reset DMA descriptor */
+ WRITE_ONCE(desc->ctrl, 0);
+ WRITE_ONCE(desc->addr, 0);
+ WRITE_ONCE(desc->data, 0);
+ WRITE_ONCE(desc->msg0, 0);
+ WRITE_ONCE(desc->msg1, 0);
+ WRITE_ONCE(desc->msg2, 0);
+ WRITE_ONCE(desc->msg3, 0);
+
q->tail = (q->tail + 1) % q->ndesc;
q->queued--;
}
+
+ q->head = q->tail;
+ airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
+ FIELD_PREP(RX_RING_DMA_IDX_MASK, q->tail));
}
static int airoha_qdma_init_rx(struct airoha_qdma *qdma)

View File

@ -13,7 +13,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1409,6 +1409,10 @@ static int airoha_hw_init(struct platfor
@@ -1425,6 +1425,10 @@ static int airoha_hw_init(struct platfor
if (err)
return err;

View File

@ -28,7 +28,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
airoha_fe_crsn_qsel_init(eth);
@@ -1641,7 +1643,8 @@ static int airoha_dev_open(struct net_de
@@ -1657,7 +1659,8 @@ static int airoha_dev_open(struct net_de
if (err)
return err;

View File

@ -15,7 +15,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -3109,7 +3109,6 @@ static void airoha_remove(struct platfor
@@ -3127,7 +3127,6 @@ static void airoha_remove(struct platfor
}
static const char * const en7581_xsi_rsts_names[] = {
@ -23,7 +23,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
"hsi0-mac",
"hsi1-mac",
"hsi-mac",
@@ -3141,7 +3140,6 @@ static int airoha_en7581_get_src_port_id
@@ -3159,7 +3158,6 @@ static int airoha_en7581_get_src_port_id
}
static const char * const an7583_xsi_rsts_names[] = {

View File

@ -35,7 +35,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
{
struct airoha_eth *eth = port->qdma->eth;
@@ -1638,6 +1644,17 @@ static int airoha_dev_open(struct net_de
@@ -1654,6 +1660,17 @@ static int airoha_dev_open(struct net_de
struct airoha_qdma *qdma = port->qdma;
u32 pse_port = FE_PSE_PORT_PPE1;
@ -53,7 +53,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
netif_tx_start_all_queues(dev);
err = airoha_set_vip_for_gdm_port(port, true);
if (err)
@@ -1702,6 +1719,11 @@ static int airoha_dev_stop(struct net_de
@@ -1718,6 +1735,11 @@ static int airoha_dev_stop(struct net_de
}
}
@ -65,7 +65,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
return 0;
}
@@ -2833,6 +2855,20 @@ static const struct ethtool_ops airoha_e
@@ -2849,6 +2871,20 @@ static const struct ethtool_ops airoha_e
.get_link = ethtool_op_get_link,
};
@ -86,7 +86,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
{
int i;
@@ -2877,6 +2913,99 @@ bool airoha_is_valid_gdm_port(struct air
@@ -2893,6 +2929,99 @@ bool airoha_is_valid_gdm_port(struct air
return false;
}
@ -186,7 +186,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
struct device_node *np)
{
@@ -2948,6 +3077,12 @@ static int airoha_alloc_gdm_port(struct
@@ -2964,6 +3093,12 @@ static int airoha_alloc_gdm_port(struct
port->id = id;
eth->ports[p] = port;
@ -199,7 +199,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
return airoha_metadata_dst_alloc(port);
}
@@ -3075,6 +3210,10 @@ error_napi_stop:
@@ -3093,6 +3228,10 @@ error_napi_stop:
if (port->dev->reg_state == NETREG_REGISTERED)
unregister_netdev(port->dev);
@ -210,7 +210,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
airoha_metadata_dst_free(port);
}
airoha_hw_cleanup(eth);
@@ -3101,6 +3240,10 @@ static void airoha_remove(struct platfor
@@ -3119,6 +3258,10 @@ static void airoha_remove(struct platfor
unregister_netdev(port->dev);
airoha_metadata_dst_free(port);
@ -223,7 +223,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -537,6 +537,10 @@ struct airoha_gdm_port {
@@ -538,6 +538,10 @@ struct airoha_gdm_port {
struct net_device *dev;
int id;

View File

@ -28,7 +28,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
{
@@ -1647,6 +1649,7 @@ static int airoha_dev_open(struct net_de
@@ -1663,6 +1665,7 @@ static int airoha_dev_open(struct net_de
struct airoha_qdma *qdma = port->qdma;
u32 pse_port = FE_PSE_PORT_PPE1;
@ -36,7 +36,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
if (airhoa_is_phy_external(port)) {
err = phylink_of_phy_connect(port->phylink, dev->dev.of_node, 0);
if (err) {
@@ -1657,6 +1660,7 @@ static int airoha_dev_open(struct net_de
@@ -1673,6 +1676,7 @@ static int airoha_dev_open(struct net_de
phylink_start(port->phylink);
}
@ -44,7 +44,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
netif_tx_start_all_queues(dev);
err = airoha_set_vip_for_gdm_port(port, true);
@@ -1722,10 +1726,12 @@ static int airoha_dev_stop(struct net_de
@@ -1738,10 +1742,12 @@ static int airoha_dev_stop(struct net_de
}
}
@ -57,7 +57,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
return 0;
}
@@ -2858,6 +2864,7 @@ static const struct ethtool_ops airoha_e
@@ -2874,6 +2880,7 @@ static const struct ethtool_ops airoha_e
.get_link = ethtool_op_get_link,
};
@ -65,7 +65,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static struct phylink_pcs *airoha_phylink_mac_select_pcs(struct phylink_config *config,
phy_interface_t interface)
{
@@ -2871,6 +2878,7 @@ static void airoha_mac_config(struct phy
@@ -2887,6 +2894,7 @@ static void airoha_mac_config(struct phy
const struct phylink_link_state *state)
{
}
@ -73,7 +73,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static int airoha_metadata_dst_alloc(struct airoha_gdm_port *port)
{
@@ -2916,6 +2924,7 @@ bool airoha_is_valid_gdm_port(struct air
@@ -2932,6 +2940,7 @@ bool airoha_is_valid_gdm_port(struct air
return false;
}
@ -81,7 +81,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy,
unsigned int mode, phy_interface_t interface,
int speed, int duplex, bool tx_pause, bool rx_pause)
@@ -3008,6 +3017,7 @@ static int airoha_setup_phylink(struct n
@@ -3024,6 +3033,7 @@ static int airoha_setup_phylink(struct n
return 0;
}
@ -89,7 +89,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
struct device_node *np)
@@ -3080,11 +3090,13 @@ static int airoha_alloc_gdm_port(struct
@@ -3096,11 +3106,13 @@ static int airoha_alloc_gdm_port(struct
port->id = id;
eth->ports[p] = port;
@ -103,7 +103,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
return airoha_metadata_dst_alloc(port);
}
@@ -3213,10 +3225,12 @@ error_napi_stop:
@@ -3231,10 +3243,12 @@ error_napi_stop:
if (port->dev->reg_state == NETREG_REGISTERED)
unregister_netdev(port->dev);
@ -116,7 +116,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
airoha_metadata_dst_free(port);
}
airoha_hw_cleanup(eth);
@@ -3243,10 +3257,12 @@ static void airoha_remove(struct platfor
@@ -3261,10 +3275,12 @@ static void airoha_remove(struct platfor
unregister_netdev(port->dev);
airoha_metadata_dst_free(port);
@ -131,7 +131,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -537,9 +537,11 @@ struct airoha_gdm_port {
@@ -538,9 +538,11 @@ struct airoha_gdm_port {
struct net_device *dev;
int id;