Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
@@ -467,6 +467,8 @@ function device_capabilities(config) {
|
||||
|
||||
phy_capabilities.ht_capa = band.ht_capa ?? 0;
|
||||
phy_capabilities.vht_capa = band.vht_capa ?? 0;
|
||||
phy_capabilities.he_mac_cap = [];
|
||||
phy_capabilities.he_phy_cap = [];
|
||||
for (let iftype in band.iftype_data) {
|
||||
if (!iftype.iftypes.ap)
|
||||
continue;
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
From f329924bb49458c65297f1361f545816a5b90998 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 17 Apr 2026 08:36:31 +0200
|
||||
Subject: [PATCH 1/2] net: airoha: Move ndesc initialization at end of
|
||||
airoha_qdma_init_tx()
|
||||
|
||||
If queue entry list allocation fails in airoha_qdma_init_tx_queue routine,
|
||||
airoha_qdma_cleanup_tx_queue() will trigger a NULL pointer dereference
|
||||
accessing the queue entry array. The issue is due to the early ndesc
|
||||
initialization in airoha_qdma_init_tx_queue(). Fix the issue moving ndesc
|
||||
initialization at end of airoha_qdma_init_tx routine.
|
||||
|
||||
Fixes: 3f47e67dff1f7 ("net: airoha: Add the capability to consume out-of-order DMA tx descriptors")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260417-airoha_qdma_cleanup_tx_queue-fix-net-v4-1-e04bcc2c9642@kernel.org
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -954,27 +954,27 @@ static int airoha_qdma_init_tx_queue(str
|
||||
dma_addr_t dma_addr;
|
||||
|
||||
spin_lock_init(&q->lock);
|
||||
- q->ndesc = size;
|
||||
q->qdma = qdma;
|
||||
q->free_thr = 1 + MAX_SKB_FRAGS;
|
||||
INIT_LIST_HEAD(&q->tx_list);
|
||||
|
||||
- q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
|
||||
+ q->entry = devm_kzalloc(eth->dev, size * sizeof(*q->entry),
|
||||
GFP_KERNEL);
|
||||
if (!q->entry)
|
||||
return -ENOMEM;
|
||||
|
||||
- q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc),
|
||||
+ q->desc = dmam_alloc_coherent(eth->dev, size * sizeof(*q->desc),
|
||||
&dma_addr, GFP_KERNEL);
|
||||
if (!q->desc)
|
||||
return -ENOMEM;
|
||||
|
||||
- for (i = 0; i < q->ndesc; i++) {
|
||||
+ for (i = 0; i < size; i++) {
|
||||
u32 val = FIELD_PREP(QDMA_DESC_DONE_MASK, 1);
|
||||
|
||||
list_add_tail(&q->entry[i].list, &q->tx_list);
|
||||
WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val));
|
||||
}
|
||||
+ q->ndesc = size;
|
||||
|
||||
/* xmit ring drop default setting */
|
||||
airoha_qdma_set(qdma, REG_TX_RING_BLOCKING(qid),
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
From 3309965fe44c00fd65af7cef5016e9e782c021a7 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 17 Apr 2026 08:36:32 +0200
|
||||
Subject: [PATCH 2/2] net: airoha: Add missing bits in
|
||||
airoha_qdma_cleanup_tx_queue()
|
||||
|
||||
Similar to airoha_qdma_cleanup_rx_queue(), reset DMA TX descriptors in
|
||||
airoha_qdma_cleanup_tx_queue routine. Moreover, reset TX_DMA_IDX to
|
||||
TX_CPU_IDX to notify the NIC the QDMA TX ring is empty.
|
||||
|
||||
Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260417-airoha_qdma_cleanup_tx_queue-fix-net-v4-2-e04bcc2c9642@kernel.org
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 32 ++++++++++++++++++++++--
|
||||
1 file changed, 30 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1039,12 +1039,15 @@ static int airoha_qdma_init_tx(struct ai
|
||||
|
||||
static void airoha_qdma_cleanup_tx_queue(struct airoha_queue *q)
|
||||
{
|
||||
- struct airoha_eth *eth = q->qdma->eth;
|
||||
- int i;
|
||||
+ struct airoha_qdma *qdma = q->qdma;
|
||||
+ struct airoha_eth *eth = qdma->eth;
|
||||
+ int i, qid = q - &qdma->q_tx[0];
|
||||
+ u16 index = 0;
|
||||
|
||||
spin_lock_bh(&q->lock);
|
||||
for (i = 0; i < q->ndesc; i++) {
|
||||
struct airoha_queue_entry *e = &q->entry[i];
|
||||
+ struct airoha_qdma_desc *desc = &q->desc[i];
|
||||
|
||||
if (!e->dma_addr)
|
||||
continue;
|
||||
@@ -1055,8 +1058,33 @@ static void airoha_qdma_cleanup_tx_queue
|
||||
e->dma_addr = 0;
|
||||
e->skb = NULL;
|
||||
list_add_tail(&e->list, &q->tx_list);
|
||||
+
|
||||
+ /* 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);
|
||||
+
|
||||
q->queued--;
|
||||
}
|
||||
+
|
||||
+ if (!list_empty(&q->tx_list)) {
|
||||
+ struct airoha_queue_entry *e;
|
||||
+
|
||||
+ e = list_first_entry(&q->tx_list, struct airoha_queue_entry,
|
||||
+ list);
|
||||
+ index = e - q->entry;
|
||||
+ }
|
||||
+ /* Set TX_DMA_IDX to TX_CPU_IDX to notify the hw the QDMA TX ring is
|
||||
+ * empty.
|
||||
+ */
|
||||
+ airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
|
||||
+ FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
|
||||
+ airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK,
|
||||
+ FIELD_PREP(TX_RING_DMA_IDX_MASK, index));
|
||||
+
|
||||
spin_unlock_bh(&q->lock);
|
||||
}
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
From f3206328bb52c2787197d80d7cbd687946047d5f Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 14 Apr 2026 16:08:52 +0200
|
||||
Subject: [PATCH] net: airoha: Wait for NPU PPE configuration to complete in
|
||||
airoha_ppe_offload_setup()
|
||||
|
||||
In order to properly enable flowtable hw offloading, poll
|
||||
REG_PPE_FLOW_CFG register in airoha_ppe_offload_setup routine and
|
||||
wait for NPU PPE configuration triggered by ppe_init callback to complete
|
||||
before running airoha_ppe_hw_init().
|
||||
|
||||
Fixes: 00a7678310fe3 ("net: airoha: Introduce flowtable offload support")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260414-airoha-wait-for-npu-config-offload-setup-v2-1-5a9bf6d43aee@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_ppe.c | 28 ++++++++++++++++++++++++
|
||||
1 file changed, 28 insertions(+)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -1354,6 +1354,29 @@ static struct airoha_npu *airoha_ppe_npu
|
||||
return npu;
|
||||
}
|
||||
|
||||
+static int airoha_ppe_wait_for_npu_init(struct airoha_eth *eth)
|
||||
+{
|
||||
+ int err;
|
||||
+ u32 val;
|
||||
+
|
||||
+ /* PPE_FLOW_CFG default register value is 0. Since we reset FE
|
||||
+ * during the device probe we can just check the configured value
|
||||
+ * is not 0 here.
|
||||
+ */
|
||||
+ err = read_poll_timeout(airoha_fe_rr, val, val, USEC_PER_MSEC,
|
||||
+ 100 * USEC_PER_MSEC, false, eth,
|
||||
+ REG_PPE_PPE_FLOW_CFG(0));
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
+ if (airoha_ppe_is_enabled(eth, 1))
|
||||
+ err = read_poll_timeout(airoha_fe_rr, val, val, USEC_PER_MSEC,
|
||||
+ 100 * USEC_PER_MSEC, false, eth,
|
||||
+ REG_PPE_PPE_FLOW_CFG(1));
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static int airoha_ppe_offload_setup(struct airoha_eth *eth)
|
||||
{
|
||||
struct airoha_npu *npu = airoha_ppe_npu_get(eth);
|
||||
@@ -1367,6 +1390,11 @@ static int airoha_ppe_offload_setup(stru
|
||||
if (err)
|
||||
goto error_npu_put;
|
||||
|
||||
+ /* Wait for NPU PPE configuration to complete */
|
||||
+ err = airoha_ppe_wait_for_npu_init(eth);
|
||||
+ if (err)
|
||||
+ goto error_npu_put;
|
||||
+
|
||||
ppe_num_stats_entries = airoha_ppe_get_total_num_stats_entries(ppe);
|
||||
if (ppe_num_stats_entries > 0) {
|
||||
err = npu->ops.ppe_init_stats(npu, ppe->foe_stats_dma,
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
From d647f2545219754603b2064de948425cdfd93fba Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 17 Apr 2026 17:24:41 +0200
|
||||
Subject: [PATCH] net: airoha: Fix PPE cpu port configuration for GDM2 loopback
|
||||
path
|
||||
|
||||
When QoS loopback is enabled for GDM3 or GDM4, incoming packets are
|
||||
forwarded to GDM2. However, the PPE cpu port for GDM2 is not configured
|
||||
in this path, causing traffic originating from GDM3/GDM4, which may
|
||||
be set up as WAN ports backed by QDMA1, to be incorrectly directed
|
||||
to QDMA0 instead.
|
||||
Configure the PPE cpu port for GDM2 when QoS loopback is active on
|
||||
GDM3 or GDM4 to ensure traffic is routed to the correct QDMA instance.
|
||||
|
||||
Fixes: 9cd451d414f6 ("net: airoha: Add loopback support for GDM2")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260417-airoha-ppe-cpu-port-for-gdm2-loopback-v1-1-c7a9de0f6f57@kernel.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 8 ++++++--
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 3 ++-
|
||||
drivers/net/ethernet/airoha/airoha_ppe.c | 6 +++---
|
||||
3 files changed, 11 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1755,7 +1755,7 @@ static int airoha_set_gdm2_loopback(stru
|
||||
{
|
||||
struct airoha_eth *eth = port->qdma->eth;
|
||||
u32 val, pse_port, chan;
|
||||
- int src_port;
|
||||
+ int i, src_port;
|
||||
|
||||
/* Forward the traffic to the proper GDM port */
|
||||
pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3
|
||||
@@ -1797,6 +1797,9 @@ static int airoha_set_gdm2_loopback(stru
|
||||
SP_CPORT_MASK(val),
|
||||
__field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
|
||||
|
||||
+ for (i = 0; i < eth->soc->num_ppe; i++)
|
||||
+ airoha_ppe_set_cpu_port(port, i, AIROHA_GDM2_IDX);
|
||||
+
|
||||
if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
|
||||
u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq);
|
||||
|
||||
@@ -1835,7 +1838,8 @@ static int airoha_dev_init(struct net_de
|
||||
}
|
||||
|
||||
for (i = 0; i < eth->soc->num_ppe; i++)
|
||||
- airoha_ppe_set_cpu_port(port, i);
|
||||
+ airoha_ppe_set_cpu_port(port, i,
|
||||
+ airoha_get_fe_port(port));
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -653,7 +653,8 @@ int airoha_get_fe_port(struct airoha_gdm
|
||||
bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
|
||||
struct airoha_gdm_port *port);
|
||||
|
||||
-void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id);
|
||||
+void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id,
|
||||
+ u8 fport);
|
||||
bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);
|
||||
void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
|
||||
u16 hash, bool rx_wlan);
|
||||
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
|
||||
@@ -85,10 +85,9 @@ static u32 airoha_ppe_get_timestamp(stru
|
||||
return FIELD_GET(AIROHA_FOE_IB1_BIND_TIMESTAMP, timestamp);
|
||||
}
|
||||
|
||||
-void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id)
|
||||
+void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id, u8 fport)
|
||||
{
|
||||
struct airoha_qdma *qdma = port->qdma;
|
||||
- u8 fport = airoha_get_fe_port(port);
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
u8 qdma_id = qdma - ð->qdma[0];
|
||||
u32 fe_cpu_port;
|
||||
@@ -182,7 +181,8 @@ static void airoha_ppe_hw_init(struct ai
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
- airoha_ppe_set_cpu_port(port, i);
|
||||
+ airoha_ppe_set_cpu_port(port, i,
|
||||
+ airoha_get_fe_port(port));
|
||||
}
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
From b94769eb2f30e61e86cd8551c084c34134290d89 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Thu, 16 Apr 2026 12:30:12 +0200
|
||||
Subject: [PATCH] net: airoha: Fix possible TX queue stall in
|
||||
airoha_qdma_tx_napi_poll()
|
||||
|
||||
Since multiple net_device TX queues can share the same hw QDMA TX queue,
|
||||
there is no guarantee we have inflight packets queued in hw belonging to a
|
||||
net_device TX queue stopped in the xmit path because hw QDMA TX queue
|
||||
can be full. In this corner case the net_device TX queue will never be
|
||||
re-activated. In order to avoid any potential net_device TX queue stall,
|
||||
we need to wake all the net_device TX queues feeding the same hw QDMA TX
|
||||
queue in airoha_qdma_tx_napi_poll routine.
|
||||
|
||||
Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Link: https://patch.msgid.link/20260416-airoha-txq-potential-stall-v2-1-42c732074540@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 37 ++++++++++++++++++++----
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 1 +
|
||||
2 files changed, 33 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -843,6 +843,21 @@ static int airoha_qdma_init_rx(struct ai
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)
|
||||
+{
|
||||
+ struct airoha_qdma *qdma = q->qdma;
|
||||
+ struct airoha_eth *eth = qdma->eth;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
+ struct airoha_gdm_port *port = eth->ports[i];
|
||||
+
|
||||
+ if (port && port->qdma == qdma)
|
||||
+ netif_tx_wake_all_queues(port->dev);
|
||||
+ }
|
||||
+ q->txq_stopped = false;
|
||||
+}
|
||||
+
|
||||
static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct airoha_tx_irq_queue *irq_q;
|
||||
@@ -919,12 +934,21 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||
|
||||
txq = netdev_get_tx_queue(skb->dev, queue);
|
||||
netdev_tx_completed_queue(txq, 1, skb->len);
|
||||
- if (netif_tx_queue_stopped(txq) &&
|
||||
- q->ndesc - q->queued >= q->free_thr)
|
||||
- netif_tx_wake_queue(txq);
|
||||
-
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
+
|
||||
+ if (q->txq_stopped && q->ndesc - q->queued >= q->free_thr) {
|
||||
+ /* Since multiple net_device TX queues can share the
|
||||
+ * same hw QDMA TX queue, there is no guarantee we have
|
||||
+ * inflight packets queued in hw belonging to a
|
||||
+ * net_device TX queue stopped in the xmit path.
|
||||
+ * In order to avoid any potential net_device TX queue
|
||||
+ * stall, we need to wake all the net_device TX queues
|
||||
+ * feeding the same hw QDMA TX queue.
|
||||
+ */
|
||||
+ airoha_qdma_wake_netdev_txqs(q);
|
||||
+ }
|
||||
+
|
||||
unlock:
|
||||
spin_unlock_bh(&q->lock);
|
||||
}
|
||||
@@ -2016,6 +2040,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
if (q->queued + nr_frags >= q->ndesc) {
|
||||
/* not enough space in the queue */
|
||||
netif_tx_stop_queue(txq);
|
||||
+ q->txq_stopped = true;
|
||||
spin_unlock_bh(&q->lock);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
@@ -2071,8 +2096,10 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
TX_RING_CPU_IDX_MASK,
|
||||
FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
|
||||
|
||||
- if (q->ndesc - q->queued < q->free_thr)
|
||||
+ if (q->ndesc - q->queued < q->free_thr) {
|
||||
netif_tx_stop_queue(txq);
|
||||
+ q->txq_stopped = true;
|
||||
+ }
|
||||
|
||||
spin_unlock_bh(&q->lock);
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -193,6 +193,7 @@ struct airoha_queue {
|
||||
int ndesc;
|
||||
int free_thr;
|
||||
int buf_size;
|
||||
+ bool txq_stopped;
|
||||
|
||||
struct napi_struct napi;
|
||||
struct page_pool *page_pool;
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
From 379050947a1828826ad7ea50c95245a56929b35a Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Mon, 20 Apr 2026 10:07:47 +0200
|
||||
Subject: [PATCH] net: airoha: Move ndesc initialization at end of
|
||||
airoha_qdma_init_rx_queue()
|
||||
|
||||
If queue entry or DMA descriptor list allocation fails in
|
||||
airoha_qdma_init_rx_queue routine, airoha_qdma_cleanup() will trigger a
|
||||
NULL pointer dereference running netif_napi_del() for RX queue NAPIs
|
||||
since netif_napi_add() has never been executed to this particular RX NAPI.
|
||||
The issue is due to the early ndesc initialization in
|
||||
airoha_qdma_init_rx_queue() since airoha_qdma_cleanup() relies on ndesc
|
||||
value to check if the queue is properly initialized. Fix the issue moving
|
||||
ndesc initialization at end of airoha_qdma_init_tx routine.
|
||||
Move page_pool allocation after descriptor list allocation in order to
|
||||
avoid memory leaks if desc allocation fails.
|
||||
|
||||
Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260420-airoha_qdma_init_rx_queue-fix-v2-1-d99347e5c18d@kernel.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 14 +++++++-------
|
||||
1 file changed, 7 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -745,14 +745,18 @@ static int airoha_qdma_init_rx_queue(str
|
||||
dma_addr_t dma_addr;
|
||||
|
||||
q->buf_size = PAGE_SIZE / 2;
|
||||
- q->ndesc = ndesc;
|
||||
q->qdma = qdma;
|
||||
|
||||
- q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
|
||||
+ q->entry = devm_kzalloc(eth->dev, ndesc * sizeof(*q->entry),
|
||||
GFP_KERNEL);
|
||||
if (!q->entry)
|
||||
return -ENOMEM;
|
||||
|
||||
+ q->desc = dmam_alloc_coherent(eth->dev, ndesc * sizeof(*q->desc),
|
||||
+ &dma_addr, GFP_KERNEL);
|
||||
+ if (!q->desc)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
q->page_pool = page_pool_create(&pp_params);
|
||||
if (IS_ERR(q->page_pool)) {
|
||||
int err = PTR_ERR(q->page_pool);
|
||||
@@ -761,11 +765,7 @@ static int airoha_qdma_init_rx_queue(str
|
||||
return err;
|
||||
}
|
||||
|
||||
- q->desc = dmam_alloc_coherent(eth->dev, q->ndesc * sizeof(*q->desc),
|
||||
- &dma_addr, GFP_KERNEL);
|
||||
- if (!q->desc)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
+ q->ndesc = ndesc;
|
||||
netif_napi_add(eth->napi_dev, &q->napi, airoha_qdma_rx_napi_poll);
|
||||
|
||||
airoha_qdma_wr(qdma, REG_RX_RING_BASE(qid), dma_addr);
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
From 4b91cb65789b794bfc8d50554b8994f8e0f16309 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Mon, 20 Apr 2026 10:07:48 +0200
|
||||
Subject: [PATCH] net: airoha: Add size check for TX NAPIs in
|
||||
airoha_qdma_cleanup()
|
||||
|
||||
If airoha_qdma_init routine fails before airoha_qdma_tx_irq_init() runs
|
||||
successfully for all TX NAPIs, airoha_qdma_cleanup() will
|
||||
unconditionally runs netif_napi_del() on TX NAPIs, triggering a NULL
|
||||
pointer dereference. Fix the issue relying on q_tx_irq size value to
|
||||
check if the TX NAPIs is properly initialized in airoha_qdma_cleanup().
|
||||
Moreover, run netif_napi_add_tx() just if irq_q queue is properly
|
||||
allocated.
|
||||
|
||||
Fixes: 23020f049327 ("net: airoha: Introduce ethernet support for EN7581 SoC")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260420-airoha_qdma_init_rx_queue-fix-v2-2-d99347e5c18d@kernel.org
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 11 ++++++++---
|
||||
1 file changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -1020,8 +1020,6 @@ static int airoha_qdma_tx_irq_init(struc
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
dma_addr_t dma_addr;
|
||||
|
||||
- netif_napi_add_tx(eth->napi_dev, &irq_q->napi,
|
||||
- airoha_qdma_tx_napi_poll);
|
||||
irq_q->q = dmam_alloc_coherent(eth->dev, size * sizeof(u32),
|
||||
&dma_addr, GFP_KERNEL);
|
||||
if (!irq_q->q)
|
||||
@@ -1031,6 +1029,9 @@ static int airoha_qdma_tx_irq_init(struc
|
||||
irq_q->size = size;
|
||||
irq_q->qdma = qdma;
|
||||
|
||||
+ netif_napi_add_tx(eth->napi_dev, &irq_q->napi,
|
||||
+ airoha_qdma_tx_napi_poll);
|
||||
+
|
||||
airoha_qdma_wr(qdma, REG_TX_IRQ_BASE(id), dma_addr);
|
||||
airoha_qdma_rmw(qdma, REG_TX_IRQ_CFG(id), TX_IRQ_DEPTH_MASK,
|
||||
FIELD_PREP(TX_IRQ_DEPTH_MASK, size));
|
||||
@@ -1450,8 +1451,12 @@ static void airoha_qdma_cleanup(struct a
|
||||
}
|
||||
}
|
||||
|
||||
- for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++)
|
||||
+ for (i = 0; i < ARRAY_SIZE(qdma->q_tx_irq); i++) {
|
||||
+ if (!qdma->q_tx_irq[i].size)
|
||||
+ continue;
|
||||
+
|
||||
netif_napi_del(&qdma->q_tx_irq[i].napi);
|
||||
+ }
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
|
||||
if (!qdma->q_tx[i].ndesc)
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
From 2d9f5a118205da2683ffcec78b9347f1f01a820e Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 21 Apr 2026 08:35:11 +0200
|
||||
Subject: [PATCH] net: airoha: fix BQL imbalance in TX path
|
||||
|
||||
Fix a possible BQL imbalance in airoha_dev_xmit(), where inflight
|
||||
packets are accounted only for the AIROHA_NUM_TX_RING netdev TX
|
||||
queues. The queue index is computed as:
|
||||
|
||||
qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx)
|
||||
txq = netdev_get_tx_queue(dev, qid);
|
||||
|
||||
However, airoha_qdma_tx_napi_poll() accounts completions across all
|
||||
netdev TX queues (num_tx_queues), leading to inconsistent BQL
|
||||
accounting.
|
||||
|
||||
Also reset all netdev TX queues in the ndo_stop callback.
|
||||
|
||||
Fixes: 1d304174106c ("net: airoha: Implement BQL support")
|
||||
Fixes: c9f947769b77 ("net: airoha: Reset BQL stopping the netdevice")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260421-airoha-fix-bql-v1-1-f135afe4275b@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 7 +++----
|
||||
1 file changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -929,10 +929,9 @@ static int airoha_qdma_tx_napi_poll(stru
|
||||
q->queued--;
|
||||
|
||||
if (skb) {
|
||||
- u16 queue = skb_get_queue_mapping(skb);
|
||||
struct netdev_queue *txq;
|
||||
|
||||
- txq = netdev_get_tx_queue(skb->dev, queue);
|
||||
+ txq = skb_get_tx_queue(skb->dev, skb);
|
||||
netdev_tx_completed_queue(txq, 1, skb->len);
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
@@ -1744,7 +1743,7 @@ static int airoha_dev_stop(struct net_de
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++)
|
||||
+ for (i = 0; i < dev->num_tx_queues; i++)
|
||||
netdev_tx_reset_subqueue(dev, i);
|
||||
|
||||
airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
|
||||
@@ -2039,7 +2038,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
|
||||
spin_lock_bh(&q->lock);
|
||||
|
||||
- txq = netdev_get_tx_queue(dev, qid);
|
||||
+ txq = skb_get_tx_queue(dev, skb);
|
||||
nr_frags = 1 + skb_shinfo(skb)->nr_frags;
|
||||
|
||||
if (q->queued + nr_frags >= q->ndesc) {
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
From 3854de7b38be742cf7558476956d12414cb274f2 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 21 Apr 2026 08:43:07 +0200
|
||||
Subject: [PATCH] net: airoha: stop net_device TX queue before updating CPU
|
||||
index
|
||||
|
||||
Currently, airoha_eth driver updates the CPU index register prior of
|
||||
verifying whether the number of free descriptors has fallen below the
|
||||
threshold.
|
||||
Move net_device TX queue length check before updating the TX CPU index
|
||||
in order to update TX CPU index even if there are more packets to be
|
||||
transmitted but the net_device TX queue is going to be stopped
|
||||
accounting the inflight packets.
|
||||
|
||||
Fixes: 1d304174106c ("net: airoha: Implement BQL support")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260421-airoha-xmit-stop-condition-v1-1-e670d6a48467@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 9 ++++-----
|
||||
1 file changed, 4 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2094,17 +2094,16 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
|
||||
skb_tx_timestamp(skb);
|
||||
netdev_tx_sent_queue(txq, skb->len);
|
||||
+ if (q->ndesc - q->queued < q->free_thr) {
|
||||
+ netif_tx_stop_queue(txq);
|
||||
+ q->txq_stopped = true;
|
||||
+ }
|
||||
|
||||
if (netif_xmit_stopped(txq) || !netdev_xmit_more())
|
||||
airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid),
|
||||
TX_RING_CPU_IDX_MASK,
|
||||
FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
|
||||
|
||||
- if (q->ndesc - q->queued < q->free_thr) {
|
||||
- netif_tx_stop_queue(txq);
|
||||
- q->txq_stopped = true;
|
||||
- }
|
||||
-
|
||||
spin_unlock_bh(&q->lock);
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
From e070aac63b42bf81f4dc565f9f841ff47e6c992f Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 21 Apr 2026 10:53:33 +0200
|
||||
Subject: [PATCH] net: airoha: Do not wake all netdev TX queues in
|
||||
airoha_qdma_wake_netdev_txqs()
|
||||
|
||||
Do not wake every netdev TX queue across all ports sharing the QDMA
|
||||
running netif_tx_wake_all_queues routine in airoha_qdma_wake_netdev_txqs()
|
||||
but only the ones that are mapped the specific QDMA stopped hw TX queue.
|
||||
This patch can potentially avoid waking already stopped netdev TX queues
|
||||
that are mapped to a different QDMA hw TX queue.
|
||||
Introduce airoha_qdma_get_txq utility routine.
|
||||
|
||||
Fixes: b94769eb2f30 ("net: airoha: Fix possible TX queue stall in airoha_qdma_tx_napi_poll()")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260421-airoha-wake_netdev_txqs-optmization-v1-1-e0be95115d53@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 19 +++++++++++++++----
|
||||
drivers/net/ethernet/airoha/airoha_eth.h | 5 +++++
|
||||
2 files changed, 20 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -847,13 +847,24 @@ static void airoha_qdma_wake_netdev_txqs
|
||||
{
|
||||
struct airoha_qdma *qdma = q->qdma;
|
||||
struct airoha_eth *eth = qdma->eth;
|
||||
- int i;
|
||||
+ int i, qid = q - &qdma->q_tx[0];
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
|
||||
struct airoha_gdm_port *port = eth->ports[i];
|
||||
+ int j;
|
||||
|
||||
- if (port && port->qdma == qdma)
|
||||
- netif_tx_wake_all_queues(port->dev);
|
||||
+ if (!port)
|
||||
+ continue;
|
||||
+
|
||||
+ if (port->qdma != qdma)
|
||||
+ continue;
|
||||
+
|
||||
+ for (j = 0; j < port->dev->num_tx_queues; j++) {
|
||||
+ if (airoha_qdma_get_txq(qdma, j) != qid)
|
||||
+ continue;
|
||||
+
|
||||
+ netif_wake_subqueue(port->dev, j);
|
||||
+ }
|
||||
}
|
||||
q->txq_stopped = false;
|
||||
}
|
||||
@@ -2001,7 +2012,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
u16 index;
|
||||
u8 fport;
|
||||
|
||||
- qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx);
|
||||
+ qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb));
|
||||
tag = airoha_get_dsa_tag(skb, dev);
|
||||
|
||||
msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK,
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
|
||||
@@ -631,6 +631,11 @@ u32 airoha_rmw(void __iomem *base, u32 o
|
||||
#define airoha_qdma_clear(qdma, offset, val) \
|
||||
airoha_rmw((qdma)->regs, (offset), (val), 0)
|
||||
|
||||
+static inline u16 airoha_qdma_get_txq(struct airoha_qdma *qdma, u16 qid)
|
||||
+{
|
||||
+ return qid % ARRAY_SIZE(qdma->q_tx);
|
||||
+}
|
||||
+
|
||||
static inline bool airoha_is_lan_gdm_port(struct airoha_gdm_port *port)
|
||||
{
|
||||
/* GDM1 port on EN7581 SoC is connected to the lan dsa switch.
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
From bde34e84edc8b5571fbde7e941e175a4293ee1eb Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Fri, 24 Apr 2026 11:00:28 +0200
|
||||
Subject: [PATCH] net: airoha: Do not read uninitialized fragment address in
|
||||
airoha_dev_xmit()
|
||||
|
||||
The transmit loop in airoha_dev_xmit() reads fragment address and length
|
||||
during its final iteration, when the loop index equals
|
||||
skb_shinfo(skb)->nr_frags, at which point the fragment data is
|
||||
uninitialized. While these values are never consumed, the read itself is
|
||||
unsafe and may trigger a page fault. Fix this by avoiding the fragment
|
||||
read on the last iteration.
|
||||
Additionally, move the skb pointer from the first to the last used packet
|
||||
descriptor, so that airoha_qdma_tx_napi_poll() defers freeing the skb
|
||||
until the final descriptor is processed.
|
||||
|
||||
Fixes: 23020f0493270 ("net: airoha: Introduce ethernet support for EN7581 SoC")
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Link: https://patch.msgid.link/20260424-airoha-xmit-fix-read-frag-v1-1-fdc0a83c79e8@kernel.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/ethernet/airoha/airoha_eth.c | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
|
||||
@@ -2007,8 +2007,8 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
struct netdev_queue *txq;
|
||||
struct airoha_queue *q;
|
||||
LIST_HEAD(tx_list);
|
||||
+ int i = 0, qid;
|
||||
void *data;
|
||||
- int i, qid;
|
||||
u16 index;
|
||||
u8 fport;
|
||||
|
||||
@@ -2067,7 +2067,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
list);
|
||||
index = e - q->entry;
|
||||
|
||||
- for (i = 0; i < nr_frags; i++) {
|
||||
+ while (true) {
|
||||
struct airoha_qdma_desc *desc = &q->desc[index];
|
||||
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
|
||||
dma_addr_t addr;
|
||||
@@ -2079,7 +2079,7 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
goto error_unmap;
|
||||
|
||||
list_move_tail(&e->list, &tx_list);
|
||||
- e->skb = i ? NULL : skb;
|
||||
+ e->skb = i == nr_frags - 1 ? skb : NULL;
|
||||
e->dma_addr = addr;
|
||||
e->dma_len = len;
|
||||
|
||||
@@ -2098,6 +2098,9 @@ static netdev_tx_t airoha_dev_xmit(struc
|
||||
WRITE_ONCE(desc->msg1, cpu_to_le32(msg1));
|
||||
WRITE_ONCE(desc->msg2, cpu_to_le32(0xffff));
|
||||
|
||||
+ if (++i == nr_frags)
|
||||
+ break;
|
||||
+
|
||||
data = skb_frag_address(frag);
|
||||
len = skb_frag_size(frag);
|
||||
}
|
||||
+1
-1
@@ -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
|
||||
@@ -1423,6 +1423,10 @@ static int airoha_hw_init(struct platfor
|
||||
@@ -1490,6 +1490,10 @@ static int airoha_hw_init(struct platfor
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
|
||||
airoha_fe_crsn_qsel_init(eth);
|
||||
|
||||
@@ -1655,7 +1657,8 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1722,7 +1724,8 @@ static int airoha_dev_open(struct net_de
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -3126,7 +3126,6 @@ static void airoha_remove(struct platfor
|
||||
@@ -3202,7 +3202,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",
|
||||
@@ -3180,7 +3179,6 @@ static u32 airoha_en7581_get_vip_port(st
|
||||
@@ -3256,7 +3255,6 @@ static u32 airoha_en7581_get_vip_port(st
|
||||
}
|
||||
|
||||
static const char * const an7583_xsi_rsts_names[] = {
|
||||
|
||||
+8
-8
@@ -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;
|
||||
@@ -1652,6 +1658,17 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1719,6 +1725,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)
|
||||
@@ -1716,6 +1733,11 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -1783,6 +1800,11 @@ static int airoha_dev_stop(struct net_de
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2846,6 +2868,20 @@ static const struct ethtool_ops airoha_e
|
||||
@@ -2922,6 +2944,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;
|
||||
@@ -2890,6 +2926,99 @@ bool airoha_is_valid_gdm_port(struct air
|
||||
@@ -2966,6 +3002,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)
|
||||
{
|
||||
@@ -2963,6 +3092,12 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -3039,6 +3168,12 @@ static int airoha_alloc_gdm_port(struct
|
||||
port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
|
||||
eth->ports[p] = port;
|
||||
|
||||
@@ -199,7 +199,7 @@ Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
||||
return airoha_metadata_dst_alloc(port);
|
||||
}
|
||||
|
||||
@@ -3092,6 +3227,10 @@ error_napi_stop:
|
||||
@@ -3168,6 +3303,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);
|
||||
@@ -3118,6 +3257,10 @@ static void airoha_remove(struct platfor
|
||||
@@ -3194,6 +3333,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
|
||||
@@ -539,6 +539,10 @@ struct airoha_gdm_port {
|
||||
@@ -540,6 +540,10 @@ struct airoha_gdm_port {
|
||||
int id;
|
||||
int nbq;
|
||||
|
||||
|
||||
+11
-11
@@ -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)
|
||||
{
|
||||
@@ -1661,6 +1663,7 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1728,6 +1730,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) {
|
||||
@@ -1671,6 +1674,7 @@ static int airoha_dev_open(struct net_de
|
||||
@@ -1738,6 +1741,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);
|
||||
@@ -1736,10 +1740,12 @@ static int airoha_dev_stop(struct net_de
|
||||
@@ -1803,10 +1807,12 @@ static int airoha_dev_stop(struct net_de
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2871,6 +2877,7 @@ static const struct ethtool_ops airoha_e
|
||||
@@ -2947,6 +2953,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)
|
||||
{
|
||||
@@ -2884,6 +2891,7 @@ static void airoha_mac_config(struct phy
|
||||
@@ -2960,6 +2967,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)
|
||||
{
|
||||
@@ -2929,6 +2937,7 @@ bool airoha_is_valid_gdm_port(struct air
|
||||
@@ -3005,6 +3013,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)
|
||||
@@ -3021,6 +3030,7 @@ static int airoha_setup_phylink(struct n
|
||||
@@ -3097,6 +3106,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)
|
||||
@@ -3095,11 +3105,13 @@ static int airoha_alloc_gdm_port(struct
|
||||
@@ -3171,11 +3181,13 @@ static int airoha_alloc_gdm_port(struct
|
||||
port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
|
||||
eth->ports[p] = port;
|
||||
|
||||
@@ -103,7 +103,7 @@ Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu>
|
||||
|
||||
return airoha_metadata_dst_alloc(port);
|
||||
}
|
||||
@@ -3230,10 +3242,12 @@ error_napi_stop:
|
||||
@@ -3306,10 +3318,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);
|
||||
@@ -3260,10 +3274,12 @@ static void airoha_remove(struct platfor
|
||||
@@ -3336,10 +3350,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
|
||||
@@ -539,9 +539,11 @@ struct airoha_gdm_port {
|
||||
@@ -540,9 +540,11 @@ struct airoha_gdm_port {
|
||||
int id;
|
||||
int nbq;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user