Merge Official Source

Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
Tianling Shen
2026-05-02 15:35:52 +08:00
269 changed files with 1786 additions and 14801 deletions
-1
View File
@@ -53,7 +53,6 @@ define Package/base-files/conffiles
/etc/config/
/etc/config/network
/etc/config/system
/etc/dropbear/
/etc/ethers
/etc/group
/etc/hosts
+2 -2
View File
@@ -1,14 +1,14 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=wireless-regdb
PKG_VERSION:=2026.02.04
PKG_VERSION:=2026.03.18
PKG_RELEASE:=1
PKG_LICENSE:=ISC
PKG_LICENSE_FILES:=LICENSE
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@KERNEL/software/network/wireless-regdb/
PKG_HASH:=0ff48a5cd9e9cfe8e815a24e023734919e9a3b7ad2f039243ad121cf5aabf6c6
PKG_HASH:=5fc0000475d8c5368ccc5222827c16aef98b1eb6a69c9b5a3e7b7e98528945ac
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
@@ -1,6 +1,6 @@
--- a/db.txt
+++ b/db.txt
@@ -446,9 +446,8 @@ country CL: DFS-JP
@@ -460,9 +460,8 @@ country CL: DFS-JP
# https://www.miit.gov.cn/cms_files/filemanager/1226211233/attach/20236/d1dc19424d5a4cfe90d631adeee8dd58.pdf
# Note: The transmit power for 5250-5350MHz bands can be raised by 3dBm when TPC is implemented
country CN: DFS-FCC
@@ -12,7 +12,7 @@
(5725 - 5850 @ 80), (33)
# 60 GHz band channels 1,4: 28dBm, channels 2,3: 44dBm
# ref: http://www.miit.gov.cn/n11293472/n11505629/n11506593/n11960250/n11960606/n11960700/n12330791.files/n12330790.pdf
@@ -2007,14 +2006,12 @@ country US: DFS-FCC
@@ -2040,14 +2039,12 @@ country US: DFS-FCC
(920 - 928 @ 8), (30)
(2400 - 2472 @ 40), (30)
# 5.15 ~ 5.25 GHz: 30 dBm for master mode, 23 dBm for clients
+1 -9
View File
@@ -532,13 +532,9 @@ define KernelPackage/crypto-hw-eip93
KCONFIG:= \
CONFIG_CRYPTO_HW=y \
CONFIG_CRYPTO_DEV_EIP93 \
CONFIG_CRYPTO_DEV_EIP93_AES=y@lt6.18 \
CONFIG_CRYPTO_DEV_EIP93_DES=y@lt6.18 \
CONFIG_CRYPTO_DEV_EIP93_AEAD=y@lt6.18 \
CONFIG_CRYPTO_DEV_EIP93_GENERIC_SW_MAX_LEN=256 \
CONFIG_CRYPTO_DEV_EIP93_AES_128_SW_MAX_LEN=512
FILES:=$(LINUX_DIR)/drivers/crypto/mtk-eip93/crypto-hw-eip93.ko@lt6.18 \
$(LINUX_DIR)/drivers/crypto/inside-secure/eip93/crypto-hw-eip93.ko@ge6.18
FILES:=$(LINUX_DIR)/drivers/crypto/inside-secure/eip93/crypto-hw-eip93.ko
AUTOLOAD:=$(call AutoLoad,09,crypto-hw-eip93)
$(call AddDepends/crypto)
endef
@@ -550,10 +546,6 @@ It enables DES/3DES/AES ECB/CBC/CTR and
IPSEC offload with authenc(hmac(sha1/sha256), aes/cbc/rfc3686)
endef
define KernelPackage/crypto-hw-eip93/airoha
FILES:=$(LINUX_DIR)/drivers/crypto/inside-secure/eip93/crypto-hw-eip93.ko
endef
$(eval $(call KernelPackage,crypto-hw-eip93))
define KernelPackage/crypto-kpp
+1 -1
View File
@@ -44,7 +44,7 @@ define Package/dnsmasq/Default
CATEGORY:=Base system
TITLE:=DNS and DHCP server
URL:=http://www.thekelleys.org.uk/dnsmasq/
DEPENDS:=+libubus
DEPENDS:=+libubus +@BUSYBOX_CONFIG_PIDOF
USERID:=dnsmasq=453:dnsmasq=453
endef
+1 -1
View File
@@ -62,7 +62,7 @@ define Package/dropbear
CATEGORY:=Base system
TITLE:=Small SSH2 client/server
MENU:=1
DEPENDS:= +USE_GLIBC:libcrypt-compat +DROPBEAR_ZLIB:zlib
DEPENDS:= +USE_GLIBC:libcrypt-compat +DROPBEAR_ZLIB:zlib +@BUSYBOX_CONFIG_PIDOF
ALTERNATIVES:=100:/usr/bin/ssh-keygen:/usr/sbin/dropbear
$(if $(CONFIG_DROPBEAR_SCP),ALTERNATIVES+= \
100:/usr/bin/scp:/usr/sbin/dropbear,)
+3 -3
View File
@@ -7,8 +7,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=ca-certificates
PKG_VERSION:=20250419
PKG_RELEASE:=2
PKG_VERSION:=20260223
PKG_RELEASE:=1
PKG_MAINTAINER:=
PKG_LICENSE:=GPL-2.0-or-later MPL-2.0
@@ -16,7 +16,7 @@ PKG_LICENSE_FILES:=debian/copyright
PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).tar.xz
PKG_SOURCE_URL:=@DEBIAN/pool/main/c/ca-certificates
PKG_HASH:=33b44ef78653ecd3f0f2f13e5bba6be466be2e7da72182f737912b81798ba5d2
PKG_HASH:=2fa2b00d4360f0d14ec51640ae8aea9e563956b95ea786e3c3c01c4eead42b56
PKG_INSTALL:=1
include $(INCLUDE_DIR)/package.mk
@@ -16,7 +16,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -1713,9 +1713,11 @@ static int airoha_qdma_tx_napi_poll(stru
@@ -1729,9 +1729,11 @@ static int airoha_qdma_tx_napi_poll(stru
WRITE_ONCE(desc->msg1, 0);
if (skb) {
@@ -29,7 +29,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (netif_tx_queue_stopped(txq) &&
q->ndesc - q->queued >= q->free_thr)
netif_tx_wake_queue(txq);
@@ -2494,7 +2496,9 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -2510,7 +2512,9 @@ static netdev_tx_t airoha_dev_xmit(struc
q->queued += i;
skb_tx_timestamp(skb);
@@ -17,7 +17,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -1669,8 +1669,12 @@ static int airoha_qdma_tx_napi_poll(stru
@@ -1685,8 +1685,12 @@ static int airoha_qdma_tx_napi_poll(stru
irq_queued = FIELD_GET(IRQ_ENTRY_LEN_MASK, status);
while (irq_queued > 0 && done < budget) {
@@ -31,7 +31,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (val == 0xff)
break;
@@ -1680,9 +1684,7 @@ static int airoha_qdma_tx_napi_poll(stru
@@ -1696,9 +1700,7 @@ static int airoha_qdma_tx_napi_poll(stru
irq_queued--;
done++;
@@ -41,7 +41,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (qid >= ARRAY_SIZE(qdma->q_tx))
continue;
@@ -1690,46 +1692,53 @@ static int airoha_qdma_tx_napi_poll(stru
@@ -1706,46 +1708,53 @@ static int airoha_qdma_tx_napi_poll(stru
if (!q->ndesc)
continue;
@@ -14,7 +14,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -1789,6 +1789,10 @@ static int airoha_qdma_init_tx_queue(str
@@ -1805,6 +1805,10 @@ static int airoha_qdma_init_tx_queue(str
WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val));
}
@@ -29,7 +29,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
#define AIROHA_NUM_TX_RING 32
#define AIROHA_NUM_RX_RING 32
#define AIROHA_FE_MC_MAX_VLAN_TABLE 64
@@ -2421,21 +2423,44 @@ static void airoha_dev_get_stats64(struc
@@ -2437,21 +2439,44 @@ static void airoha_dev_get_stats64(struc
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
@@ -76,7 +76,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
if (skb->ip_summed == CHECKSUM_PARTIAL)
msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) |
FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) |
@@ -2609,6 +2634,7 @@ static const struct net_device_ops airoh
@@ -2625,6 +2650,7 @@ static const struct net_device_ops airoh
.ndo_init = airoha_dev_init,
.ndo_open = airoha_dev_open,
.ndo_stop = airoha_dev_stop,
@@ -100,7 +100,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
};
struct airoha_eth {
@@ -1961,6 +2002,27 @@ static void airoha_qdma_init_qos(struct
@@ -1977,6 +2018,27 @@ static void airoha_qdma_init_qos(struct
FIELD_PREP(SLA_SLOW_TICK_RATIO_MASK, 40));
}
@@ -128,7 +128,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
static int airoha_qdma_hw_init(struct airoha_qdma *qdma)
{
int i;
@@ -2011,6 +2073,7 @@ static int airoha_qdma_hw_init(struct ai
@@ -2027,6 +2089,7 @@ static int airoha_qdma_hw_init(struct ai
airoha_qdma_set(qdma, REG_TXQ_CNGST_CFG,
TXQ_CNGST_DROP_EN | TXQ_CNGST_DEI_DROP_EN);
@@ -136,7 +136,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
return 0;
}
@@ -2630,6 +2693,135 @@ airoha_ethtool_get_rmon_stats(struct net
@@ -2646,6 +2709,135 @@ airoha_ethtool_get_rmon_stats(struct net
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
@@ -272,7 +272,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
static const struct net_device_ops airoha_netdev_ops = {
.ndo_init = airoha_dev_init,
.ndo_open = airoha_dev_open,
@@ -2638,6 +2830,7 @@ static const struct net_device_ops airoh
@@ -2654,6 +2846,7 @@ static const struct net_device_ops airoh
.ndo_start_xmit = airoha_dev_xmit,
.ndo_get_stats64 = airoha_dev_get_stats64,
.ndo_set_mac_address = airoha_dev_set_macaddr,
@@ -280,7 +280,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
};
static const struct ethtool_ops airoha_ethtool_ops = {
@@ -2687,7 +2880,8 @@ static int airoha_alloc_gdm_port(struct
@@ -2703,7 +2896,8 @@ static int airoha_alloc_gdm_port(struct
dev->watchdog_timeo = 5 * HZ;
dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
NETIF_F_TSO6 | NETIF_F_IPV6_CSUM |
@@ -94,7 +94,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
/* qos stats counters */
u64 cpu_tx_packets;
u64 fwd_tx_packets;
@@ -2809,6 +2850,243 @@ static int airoha_tc_setup_qdisc_ets(str
@@ -2825,6 +2866,243 @@ static int airoha_tc_setup_qdisc_ets(str
}
}
@@ -338,7 +338,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
void *type_data)
{
@@ -2817,6 +3095,8 @@ static int airoha_dev_tc_setup(struct ne
@@ -2833,6 +3111,8 @@ static int airoha_dev_tc_setup(struct ne
switch (type) {
case TC_SETUP_QDISC_ETS:
return airoha_tc_setup_qdisc_ets(port, type_data);
@@ -347,7 +347,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
default:
return -EOPNOTSUPP;
}
@@ -2867,7 +3147,8 @@ static int airoha_alloc_gdm_port(struct
@@ -2883,7 +3163,8 @@ static int airoha_alloc_gdm_port(struct
}
dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port),
@@ -357,7 +357,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
if (!dev) {
dev_err(eth->dev, "alloc_etherdev failed\n");
return -ENOMEM;
@@ -2887,6 +3168,11 @@ static int airoha_alloc_gdm_port(struct
@@ -2903,6 +3184,11 @@ static int airoha_alloc_gdm_port(struct
dev->irq = qdma->irq;
SET_NETDEV_DEV(dev, eth->dev);
@@ -20,7 +20,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -2785,7 +2785,7 @@ static int airoha_qdma_set_tx_ets_sched(
@@ -2801,7 +2801,7 @@ static int airoha_qdma_set_tx_ets_sched(
struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params;
enum tx_sched_mode mode = TC_SCH_SP;
u16 w[AIROHA_NUM_QOS_QUEUES] = {};
@@ -29,7 +29,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (p->bands > AIROHA_NUM_QOS_QUEUES)
return -EINVAL;
@@ -2799,7 +2799,20 @@ static int airoha_qdma_set_tx_ets_sched(
@@ -2815,7 +2815,20 @@ static int airoha_qdma_set_tx_ets_sched(
if (nstrict == AIROHA_NUM_QOS_QUEUES - 1)
return -EINVAL;
@@ -24,7 +24,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -2548,11 +2548,10 @@ static u16 airoha_dev_select_queue(struc
@@ -2564,11 +2564,10 @@ static u16 airoha_dev_select_queue(struc
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
struct net_device *dev)
{
@@ -37,7 +37,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
struct netdev_queue *txq;
struct airoha_queue *q;
void *data = skb->data;
@@ -2575,8 +2574,9 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -2591,8 +2590,9 @@ static netdev_tx_t airoha_dev_xmit(struc
if (skb_cow_head(skb, 0))
goto error;
@@ -49,7 +49,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
tcp_hdr(skb)->check = (__force __sum16)csum;
msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TSO_MASK, 1);
@@ -2605,7 +2605,7 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -2621,7 +2621,7 @@ static netdev_tx_t airoha_dev_xmit(struc
for (i = 0; i < nr_frags; i++) {
struct airoha_qdma_desc *desc = &q->desc[index];
struct airoha_queue_entry *e = &q->entry[index];
@@ -16,7 +16,7 @@ Signed-off-by: Andrew Lunn <andrew@lunn.ch>
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ b/drivers/net/ethernet/mediatek/airoha_eth.c
@@ -2468,7 +2468,7 @@ static int airoha_dev_stop(struct net_de
@@ -2484,7 +2484,7 @@ static int airoha_dev_stop(struct net_de
{
struct airoha_gdm_port *port = netdev_priv(dev);
struct airoha_qdma *qdma = port->qdma;
@@ -25,7 +25,7 @@ Signed-off-by: Andrew Lunn <andrew@lunn.ch>
netif_tx_disable(dev);
err = airoha_set_gdm_ports(qdma->eth, false);
@@ -2479,6 +2479,14 @@ static int airoha_dev_stop(struct net_de
@@ -2495,6 +2495,14 @@ static int airoha_dev_stop(struct net_de
GLOBAL_CFG_TX_DMA_EN_MASK |
GLOBAL_CFG_RX_DMA_EN_MASK);
@@ -101,7 +101,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-obj-$(CONFIG_NET_AIROHA) += airoha_eth.o
--- /dev/null
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -0,0 +1,3357 @@
@@ -0,0 +1,3373 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2024 AIROHA Inc
@@ -1804,18 +1804,34 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+
+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)
@@ -3461,7 +3477,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+MODULE_DESCRIPTION("Ethernet driver for Airoha SoC");
--- a/drivers/net/ethernet/mediatek/airoha_eth.c
+++ /dev/null
@@ -1,3357 +0,0 @@
@@ -1,3373 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2024 AIROHA Inc
@@ -5164,18 +5180,34 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-
-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)
@@ -74,7 +74,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
napi_gro_receive(&q->napi, skb);
done++;
@@ -1636,25 +1655,76 @@ static u16 airoha_dev_select_queue(struc
@@ -1652,25 +1671,76 @@ static u16 airoha_dev_select_queue(struc
return queue < dev->num_tx_queues ? queue : 0;
}
@@ -155,7 +155,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
if (skb->ip_summed == CHECKSUM_PARTIAL)
msg0 |= FIELD_PREP(QDMA_ETH_TXMSG_TCO_MASK, 1) |
FIELD_PREP(QDMA_ETH_TXMSG_UCO_MASK, 1) |
@@ -1685,6 +1755,8 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -1701,6 +1771,8 @@ static netdev_tx_t airoha_dev_xmit(struc
spin_lock_bh(&q->lock);
txq = netdev_get_tx_queue(dev, qid);
@@ -164,7 +164,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
if (q->queued + nr_frags > q->ndesc) {
/* not enough space in the queue */
netif_tx_stop_queue(txq);
@@ -1692,7 +1764,10 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -1708,7 +1780,10 @@ static netdev_tx_t airoha_dev_xmit(struc
return NETDEV_TX_BUSY;
}
@@ -175,7 +175,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
for (i = 0; i < nr_frags; i++) {
struct airoha_qdma_desc *desc = &q->desc[index];
struct airoha_queue_entry *e = &q->entry[index];
@@ -2223,6 +2298,37 @@ static const struct ethtool_ops airoha_e
@@ -2239,6 +2314,37 @@ static const struct ethtool_ops airoha_e
.get_rmon_stats = airoha_ethtool_get_rmon_stats,
};
@@ -213,7 +213,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
static int airoha_alloc_gdm_port(struct airoha_eth *eth, struct device_node *np)
{
const __be32 *id_ptr = of_get_property(np, "reg", NULL);
@@ -2295,6 +2401,10 @@ static int airoha_alloc_gdm_port(struct
@@ -2311,6 +2417,10 @@ static int airoha_alloc_gdm_port(struct
port->id = id;
eth->ports[index] = port;
@@ -224,7 +224,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
return register_netdev(dev);
}
@@ -2387,8 +2497,10 @@ error_hw_cleanup:
@@ -2403,8 +2513,10 @@ error_hw_cleanup:
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
@@ -236,7 +236,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
}
free_netdev(eth->napi_dev);
platform_set_drvdata(pdev, NULL);
@@ -2413,6 +2525,7 @@ static void airoha_remove(struct platfor
@@ -2429,6 +2541,7 @@ static void airoha_remove(struct platfor
continue;
unregister_netdev(port->dev);
@@ -25,7 +25,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1562,6 +1562,7 @@ static int airoha_dev_open(struct net_de
@@ -1578,6 +1578,7 @@ static int airoha_dev_open(struct net_de
airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
GLOBAL_CFG_TX_DMA_EN_MASK |
GLOBAL_CFG_RX_DMA_EN_MASK);
@@ -33,7 +33,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
return 0;
}
@@ -1577,16 +1578,20 @@ static int airoha_dev_stop(struct net_de
@@ -1593,16 +1594,20 @@ static int airoha_dev_stop(struct net_de
if (err)
return err;
@@ -62,7 +62,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
}
return 0;
@@ -2329,13 +2334,14 @@ static void airoha_metadata_dst_free(str
@@ -2345,13 +2350,14 @@ static void airoha_metadata_dst_free(str
}
}
@@ -79,7 +79,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
u32 id;
if (!id_ptr) {
@@ -2344,14 +2350,14 @@ static int airoha_alloc_gdm_port(struct
@@ -2360,14 +2366,14 @@ static int airoha_alloc_gdm_port(struct
}
id = be32_to_cpup(id_ptr);
@@ -96,7 +96,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
dev_err(eth->dev, "duplicate gdm port id: %d\n", id);
return -EINVAL;
}
@@ -2399,7 +2405,7 @@ static int airoha_alloc_gdm_port(struct
@@ -2415,7 +2421,7 @@ static int airoha_alloc_gdm_port(struct
port->qdma = qdma;
port->dev = dev;
port->id = id;
@@ -105,7 +105,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
err = airoha_metadata_dst_alloc(port);
if (err)
@@ -2471,6 +2477,7 @@ static int airoha_probe(struct platform_
@@ -2487,6 +2493,7 @@ static int airoha_probe(struct platform_
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
airoha_qdma_start_napi(&eth->qdma[i]);
@@ -113,7 +113,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
for_each_child_of_node(pdev->dev.of_node, np) {
if (!of_device_is_compatible(np, "airoha,eth-mac"))
continue;
@@ -2478,7 +2485,7 @@ static int airoha_probe(struct platform_
@@ -2494,7 +2501,7 @@ static int airoha_probe(struct platform_
if (!of_device_is_available(np))
continue;
@@ -63,7 +63,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
airoha_fe_rmw(eth, REG_GDM_LEN_CFG(p),
GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
@@ -1614,8 +1605,11 @@ static int airoha_dev_set_macaddr(struct
@@ -1630,8 +1621,11 @@ static int airoha_dev_set_macaddr(struct
static int airoha_dev_init(struct net_device *dev)
{
struct airoha_gdm_port *port = netdev_priv(dev);
@@ -83,7 +83,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
static void airoha_fe_maccr_init(struct airoha_eth *eth)
{
int p;
@@ -1539,7 +1512,7 @@ static int airoha_dev_open(struct net_de
@@ -1555,7 +1528,7 @@ static int airoha_dev_open(struct net_de
int err;
netif_tx_start_all_queues(dev);
@@ -92,7 +92,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
if (err)
return err;
@@ -1565,7 +1538,7 @@ static int airoha_dev_stop(struct net_de
@@ -1581,7 +1554,7 @@ static int airoha_dev_stop(struct net_de
int i, err;
netif_tx_disable(dev);
@@ -76,7 +76,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
napi_gro_receive(&q->napi, skb);
done++;
@@ -1301,6 +1310,10 @@ static int airoha_hw_init(struct platfor
@@ -1317,6 +1326,10 @@ static int airoha_hw_init(struct platfor
return err;
}
@@ -87,7 +87,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
set_bit(DEV_STATE_INITIALIZED, &eth->state);
return 0;
@@ -2165,6 +2178,47 @@ static int airoha_tc_htb_alloc_leaf_queu
@@ -2181,6 +2194,47 @@ static int airoha_tc_htb_alloc_leaf_queu
return 0;
}
@@ -135,7 +135,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
static void airoha_tc_remove_htb_queue(struct airoha_gdm_port *port, int queue)
{
struct net_device *dev = port->dev;
@@ -2248,6 +2302,9 @@ static int airoha_dev_tc_setup(struct ne
@@ -2264,6 +2318,9 @@ static int airoha_dev_tc_setup(struct ne
return airoha_tc_setup_qdisc_ets(port, type_data);
case TC_SETUP_QDISC_HTB:
return airoha_tc_setup_qdisc_htb(port, type_data);
@@ -145,7 +145,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
default:
return -EOPNOTSUPP;
}
@@ -2503,6 +2560,7 @@ static void airoha_remove(struct platfor
@@ -2519,6 +2576,7 @@ static void airoha_remove(struct platfor
}
free_netdev(eth->napi_dev);
@@ -18,7 +18,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1588,14 +1588,81 @@ static int airoha_dev_set_macaddr(struct
@@ -1604,14 +1604,81 @@ static int airoha_dev_set_macaddr(struct
return 0;
}
@@ -34,7 +34,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
airoha_fe_rmw(eth, REG_CDM1_VLAN_CTRL, CDM1_VLAN_MASK,
FIELD_PREP(CDM1_VLAN_MASK, 0x8100));
@@ -1520,9 +1515,9 @@ static void airoha_update_hw_stats(struc
@@ -1536,9 +1531,9 @@ static void airoha_update_hw_stats(struc
static int airoha_dev_open(struct net_device *dev)
{
@@ -45,7 +45,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
netif_tx_start_all_queues(dev);
err = airoha_set_vip_for_gdm_port(port, true);
@@ -1536,6 +1531,11 @@ static int airoha_dev_open(struct net_de
@@ -1552,6 +1547,11 @@ static int airoha_dev_open(struct net_de
airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
GDM_STAG_EN_MASK);
@@ -132,7 +132,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
airoha_qdma_fill_rx_queue(q);
@@ -1161,7 +1178,6 @@ static int airoha_qdma_hw_init(struct ai
@@ -1177,7 +1194,6 @@ static int airoha_qdma_hw_init(struct ai
}
airoha_qdma_wr(qdma, REG_QDMA_GLOBAL_CFG,
@@ -16,7 +16,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1705,6 +1705,20 @@ static void airoha_dev_get_stats64(struc
@@ -1721,6 +1721,20 @@ static void airoha_dev_get_stats64(struc
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
@@ -37,7 +37,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev)
{
@@ -2397,6 +2411,7 @@ static const struct net_device_ops airoh
@@ -2413,6 +2427,7 @@ static const struct net_device_ops airoh
.ndo_init = airoha_dev_init,
.ndo_open = airoha_dev_open,
.ndo_stop = airoha_dev_stop,
@@ -17,7 +17,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2502,6 +2502,7 @@ static int airoha_alloc_gdm_port(struct
@@ -2518,6 +2518,7 @@ static int airoha_alloc_gdm_port(struct
NETIF_F_SG | NETIF_F_TSO |
NETIF_F_HW_TC;
dev->features |= dev->hw_features;
@@ -25,7 +25,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1741,18 +1741,13 @@ static u32 airoha_get_dsa_tag(struct sk_
@@ -1757,18 +1757,13 @@ static u32 airoha_get_dsa_tag(struct sk_
{
#if IS_ENABLED(CONFIG_NET_DSA)
struct ethhdr *ehdr;
@@ -66,7 +66,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2355,7 +2355,7 @@ static int airoha_tc_get_htb_get_leaf_qu
@@ -2371,7 +2371,7 @@ static int airoha_tc_get_htb_get_leaf_qu
return -EINVAL;
}
@@ -22,7 +22,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2028,7 +2028,7 @@ static int airoha_qdma_set_tx_ets_sched(
@@ -2044,7 +2044,7 @@ static int airoha_qdma_set_tx_ets_sched(
struct tc_ets_qopt_offload_replace_params *p = &opt->replace_params;
enum tx_sched_mode mode = TC_SCH_SP;
u16 w[AIROHA_NUM_QOS_QUEUES] = {};
@@ -31,7 +31,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (p->bands > AIROHA_NUM_QOS_QUEUES)
return -EINVAL;
@@ -2046,17 +2046,17 @@ static int airoha_qdma_set_tx_ets_sched(
@@ -2062,17 +2062,17 @@ static int airoha_qdma_set_tx_ets_sched(
* lowest priorities with respect to SP ones.
* e.g: WRR0, WRR1, .., WRRm, SP0, SP1, .., SPn
*/
@@ -35,7 +35,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2451,6 +2451,19 @@ static void airoha_metadata_dst_free(str
@@ -2467,6 +2467,19 @@ static void airoha_metadata_dst_free(str
}
}
@@ -55,7 +55,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
/* enable 1:N vlan action, init vlan table */
airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK);
@@ -1631,7 +1650,6 @@ static void airhoha_set_gdm2_loopback(st
@@ -1647,7 +1666,6 @@ static void airhoha_set_gdm2_loopback(st
if (port->id == 3) {
/* FIXME: handle XSI_PCE1_PORT */
@@ -63,7 +63,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
airoha_fe_rmw(eth, REG_FE_WAN_PORT,
WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT));
@@ -2106,6 +2124,125 @@ static int airoha_tc_setup_qdisc_ets(str
@@ -2122,6 +2140,125 @@ static int airoha_tc_setup_qdisc_ets(str
}
}
@@ -189,7 +189,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
static int airoha_qdma_get_trtcm_param(struct airoha_qdma *qdma, int channel,
u32 addr, enum trtcm_param_type param,
enum trtcm_mode_type mode,
@@ -2270,10 +2407,142 @@ static int airoha_tc_htb_alloc_leaf_queu
@@ -2286,10 +2423,142 @@ static int airoha_tc_htb_alloc_leaf_queu
return 0;
}
@@ -93,7 +93,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
RX_DONE_INT_MASK);
return done;
@@ -944,7 +948,7 @@ unlock:
@@ -960,7 +964,7 @@ unlock:
}
if (done < budget && napi_complete(napi))
@@ -102,7 +102,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
TX_DONE_INT_MASK(id));
return done;
@@ -1175,13 +1179,16 @@ static int airoha_qdma_hw_init(struct ai
@@ -1191,13 +1195,16 @@ static int airoha_qdma_hw_init(struct ai
int i;
/* clear pending irqs */
@@ -123,7 +123,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
/* setup irq binding */
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
@@ -1226,13 +1233,14 @@ static int airoha_qdma_hw_init(struct ai
@@ -1242,13 +1249,14 @@ static int airoha_qdma_hw_init(struct ai
static irqreturn_t airoha_irq_handler(int irq, void *dev_instance)
{
@@ -142,7 +142,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
airoha_qdma_wr(qdma, REG_INT_STATUS(i), intr[i]);
}
@@ -1240,7 +1248,7 @@ static irqreturn_t airoha_irq_handler(in
@@ -1256,7 +1264,7 @@ static irqreturn_t airoha_irq_handler(in
return IRQ_NONE;
if (intr[1] & RX_DONE_INT_MASK) {
@@ -151,7 +151,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
RX_DONE_INT_MASK);
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
@@ -1257,7 +1265,7 @@ static irqreturn_t airoha_irq_handler(in
@@ -1273,7 +1281,7 @@ static irqreturn_t airoha_irq_handler(in
if (!(intr[0] & TX_DONE_INT_MASK(i)))
continue;
@@ -160,7 +160,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
TX_DONE_INT_MASK(i));
napi_schedule(&qdma->q_tx_irq[i].napi);
}
@@ -1266,6 +1274,39 @@ static irqreturn_t airoha_irq_handler(in
@@ -1282,6 +1290,39 @@ static irqreturn_t airoha_irq_handler(in
return IRQ_HANDLED;
}
@@ -200,7 +200,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
static int airoha_qdma_init(struct platform_device *pdev,
struct airoha_eth *eth,
struct airoha_qdma *qdma)
@@ -1273,9 +1314,7 @@ static int airoha_qdma_init(struct platf
@@ -1289,9 +1330,7 @@ static int airoha_qdma_init(struct platf
int err, id = qdma - &eth->qdma[0];
const char *res;
@@ -210,7 +210,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
res = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d", id);
if (!res)
return -ENOMEM;
@@ -1285,12 +1324,7 @@ static int airoha_qdma_init(struct platf
@@ -1301,12 +1340,7 @@ static int airoha_qdma_init(struct platf
return dev_err_probe(eth->dev, PTR_ERR(qdma->regs),
"failed to iomap qdma%d regs\n", id);
@@ -224,7 +224,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (err)
return err;
@@ -2781,7 +2815,7 @@ static int airoha_alloc_gdm_port(struct
@@ -2797,7 +2831,7 @@ static int airoha_alloc_gdm_port(struct
dev->features |= dev->hw_features;
dev->vlan_features = dev->hw_features;
dev->dev.of_node = np;
@@ -58,7 +58,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
return done;
}
@@ -1178,17 +1188,24 @@ static int airoha_qdma_hw_init(struct ai
@@ -1194,17 +1204,24 @@ static int airoha_qdma_hw_init(struct ai
{
int i;
@@ -91,7 +91,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
/* setup irq binding */
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++) {
@@ -1235,6 +1252,7 @@ static irqreturn_t airoha_irq_handler(in
@@ -1251,6 +1268,7 @@ static irqreturn_t airoha_irq_handler(in
{
struct airoha_irq_bank *irq_bank = dev_instance;
struct airoha_qdma *qdma = irq_bank->qdma;
@@ -99,7 +99,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
u32 intr[ARRAY_SIZE(irq_bank->irqmask)];
int i;
@@ -1247,17 +1265,24 @@ static irqreturn_t airoha_irq_handler(in
@@ -1263,17 +1281,24 @@ static irqreturn_t airoha_irq_handler(in
if (!test_bit(DEV_STATE_INITIALIZED, &qdma->eth->state))
return IRQ_NONE;
@@ -20,7 +20,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1077,17 +1077,13 @@ static int airoha_qdma_init_hfwd_queues(
@@ -1093,17 +1093,13 @@ static int airoha_qdma_init_hfwd_queues(
int size;
size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc);
@@ -27,7 +27,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
#include <linux/platform_device.h>
#include <linux/tcp.h>
#include <linux/u64_stats_sync.h>
@@ -1072,9 +1073,11 @@ static void airoha_qdma_cleanup_tx_queue
@@ -1088,9 +1089,11 @@ static void airoha_qdma_cleanup_tx_queue
static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma)
{
struct airoha_eth *eth = qdma->eth;
@@ -40,7 +40,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
size = HW_DSCP_NUM * sizeof(struct airoha_qdma_fwd_desc);
if (!dmam_alloc_coherent(eth->dev, size, &dma_addr, GFP_KERNEL))
@@ -1082,10 +1085,34 @@ static int airoha_qdma_init_hfwd_queues(
@@ -1098,10 +1101,34 @@ static int airoha_qdma_init_hfwd_queues(
airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr);
@@ -38,7 +38,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
{
struct airoha_eth *eth = port->qdma->eth;
@@ -1124,7 +1115,7 @@ static int airoha_qdma_init_hfwd_queues(
@@ -1140,7 +1131,7 @@ static int airoha_qdma_init_hfwd_queues(
LMGR_INIT_START | LMGR_SRAM_MODE_MASK |
HW_FWD_DESC_NUM_MASK,
FIELD_PREP(HW_FWD_DESC_NUM_MASK, HW_DSCP_NUM) |
@@ -23,7 +23,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2880,7 +2880,15 @@ static int airoha_alloc_gdm_port(struct
@@ -2896,7 +2896,15 @@ static int airoha_alloc_gdm_port(struct
if (err)
return err;
@@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1065,19 +1065,13 @@ static void airoha_qdma_cleanup_tx_queue
@@ -1081,19 +1081,13 @@ static void airoha_qdma_cleanup_tx_queue
static int airoha_qdma_init_hfwd_queues(struct airoha_qdma *qdma)
{
@@ -40,7 +40,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
name = devm_kasprintf(eth->dev, GFP_KERNEL, "qdma%d-buf", id);
if (!name)
return -ENOMEM;
@@ -1099,8 +1093,12 @@ static int airoha_qdma_init_hfwd_queues(
@@ -1115,8 +1109,12 @@ static int airoha_qdma_init_hfwd_queues(
rmem = of_reserved_mem_lookup(np);
of_node_put(np);
dma_addr = rmem->base;
@@ -54,7 +54,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (!dmam_alloc_coherent(eth->dev, size, &dma_addr,
GFP_KERNEL))
return -ENOMEM;
@@ -1108,6 +1106,11 @@ static int airoha_qdma_init_hfwd_queues(
@@ -1124,6 +1122,11 @@ static int airoha_qdma_init_hfwd_queues(
airoha_qdma_wr(qdma, REG_FWD_BUF_BASE, dma_addr);
@@ -66,7 +66,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
airoha_qdma_rmw(qdma, REG_HW_FWD_DSCP_CFG,
HW_FWD_DSCP_PAYLOAD_SIZE_MASK,
FIELD_PREP(HW_FWD_DSCP_PAYLOAD_SIZE_MASK, 0));
@@ -1116,7 +1119,7 @@ static int airoha_qdma_init_hfwd_queues(
@@ -1132,7 +1135,7 @@ static int airoha_qdma_init_hfwd_queues(
airoha_qdma_rmw(qdma, REG_LMGR_INIT_CFG,
LMGR_INIT_START | LMGR_SRAM_MODE_MASK |
HW_FWD_DESC_NUM_MASK,
@@ -21,7 +21,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1068,14 +1068,15 @@ static int airoha_qdma_init_hfwd_queues(
@@ -1084,14 +1084,15 @@ static int airoha_qdma_init_hfwd_queues(
int size, index, num_desc = HW_DSCP_NUM;
struct airoha_eth *eth = qdma->eth;
int id = qdma - &eth->qdma[0];
@@ -38,7 +38,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
index = of_property_match_string(eth->dev->of_node,
"memory-region-names", name);
if (index >= 0) {
@@ -1096,9 +1097,9 @@ static int airoha_qdma_init_hfwd_queues(
@@ -1112,9 +1113,9 @@ static int airoha_qdma_init_hfwd_queues(
/* Compute the number of hw descriptors according to the
* reserved memory size and the payload buffer size
*/
@@ -50,7 +50,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (!dmam_alloc_coherent(eth->dev, size, &dma_addr,
GFP_KERNEL))
return -ENOMEM;
@@ -1111,9 +1112,10 @@ static int airoha_qdma_init_hfwd_queues(
@@ -1127,9 +1128,10 @@ static int airoha_qdma_init_hfwd_queues(
return -ENOMEM;
airoha_qdma_wr(qdma, REG_FWD_DSCP_BASE, dma_addr);
@@ -24,7 +24,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2601,13 +2601,15 @@ static int airoha_dev_setup_tc_block_cb(
@@ -2617,13 +2617,15 @@ static int airoha_dev_setup_tc_block_cb(
void *type_data, void *cb_priv)
{
struct net_device *dev = cb_priv;
@@ -18,7 +18,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2183,11 +2183,14 @@ static int airoha_qdma_get_tx_ets_stats(
@@ -2199,11 +2199,14 @@ static int airoha_qdma_get_tx_ets_stats(
static int airoha_tc_setup_qdisc_ets(struct airoha_gdm_port *port,
struct tc_ets_qopt_offload *opt)
{
@@ -18,7 +18,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1715,7 +1715,9 @@ static void airhoha_set_gdm2_loopback(st
@@ -1731,7 +1731,9 @@ static void airhoha_set_gdm2_loopback(st
airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff);
airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2),
LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK,
@@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2027,8 +2027,12 @@ static void airoha_ethtool_get_mac_stats
@@ -2043,8 +2043,12 @@ static void airoha_ethtool_get_mac_stats
airoha_update_hw_stats(port);
do {
start = u64_stats_fetch_begin(&port->stats.syncp);
@@ -15,7 +15,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2775,6 +2775,7 @@ static const struct ethtool_ops airoha_e
@@ -2791,6 +2791,7 @@ static const struct ethtool_ops airoha_e
.get_drvinfo = airoha_ethtool_get_drvinfo,
.get_eth_mac_stats = airoha_ethtool_get_mac_stats,
.get_rmon_stats = airoha_ethtool_get_rmon_stats,
@@ -22,7 +22,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1878,6 +1878,20 @@ static u32 airoha_get_dsa_tag(struct sk_
@@ -1894,6 +1894,20 @@ static u32 airoha_get_dsa_tag(struct sk_
#endif
}
@@ -43,7 +43,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
struct net_device *dev)
{
@@ -1931,7 +1945,7 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -1947,7 +1961,7 @@ static netdev_tx_t airoha_dev_xmit(struc
txq = netdev_get_tx_queue(dev, qid);
nr_frags = 1 + skb_shinfo(skb)->nr_frags;
@@ -21,7 +21,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1392,8 +1392,7 @@ static int airoha_hw_init(struct platfor
@@ -1408,8 +1408,7 @@ static int airoha_hw_init(struct platfor
int err, i;
/* disable xsi */
@@ -31,7 +31,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
if (err)
return err;
@@ -2927,6 +2926,7 @@ free_metadata_dst:
@@ -2943,6 +2942,7 @@ free_metadata_dst:
static int airoha_probe(struct platform_device *pdev)
{
@@ -39,7 +39,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
struct device_node *np;
struct airoha_eth *eth;
int i, err;
@@ -2935,6 +2935,10 @@ static int airoha_probe(struct platform_
@@ -2951,6 +2951,10 @@ static int airoha_probe(struct platform_
if (!eth)
return -ENOMEM;
@@ -50,7 +50,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
eth->dev = &pdev->dev;
err = dma_set_mask_and_coherent(eth->dev, DMA_BIT_MASK(32));
@@ -2959,13 +2963,18 @@ static int airoha_probe(struct platform_
@@ -2975,13 +2979,18 @@ static int airoha_probe(struct platform_
return err;
}
@@ -75,7 +75,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
eth->xsi_rsts);
if (err) {
dev_err(eth->dev, "failed to get bulk xsi reset lines\n");
@@ -3051,8 +3060,23 @@ static void airoha_remove(struct platfor
@@ -3067,8 +3076,23 @@ static void airoha_remove(struct platfor
platform_set_drvdata(pdev, NULL);
}
@@ -59,7 +59,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
}
/* GMD4 */
for (q = 0; q < pse_port_num_queues[FE_PSE_PORT_GDM4]; q++)
@@ -1767,8 +1774,11 @@ static int airoha_dev_init(struct net_de
@@ -1783,8 +1790,11 @@ static int airoha_dev_init(struct net_de
airhoha_set_gdm2_loopback(port);
fallthrough;
case 2:
@@ -47,7 +47,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
/* enable 1:N vlan action, init vlan table */
airoha_fe_set(eth, REG_MC_VLAN_EN, MC_VLAN_EN_MASK);
@@ -1761,8 +1742,10 @@ static void airhoha_set_gdm2_loopback(st
@@ -1777,8 +1758,10 @@ static void airhoha_set_gdm2_loopback(st
static int airoha_dev_init(struct net_device *dev)
{
struct airoha_gdm_port *port = netdev_priv(dev);
@@ -60,7 +60,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
airoha_set_macaddr(port, dev->dev_addr);
@@ -1775,16 +1758,27 @@ static int airoha_dev_init(struct net_de
@@ -1791,16 +1774,27 @@ static int airoha_dev_init(struct net_de
fallthrough;
case 2:
if (airoha_ppe_is_enabled(eth, 1)) {
@@ -22,7 +22,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1687,13 +1687,17 @@ static int airoha_dev_set_macaddr(struct
@@ -1703,13 +1703,17 @@ static int airoha_dev_set_macaddr(struct
return 0;
}
@@ -43,7 +43,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port);
airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC);
@@ -1714,29 +1718,25 @@ static void airhoha_set_gdm2_loopback(st
@@ -1730,29 +1734,25 @@ static void airhoha_set_gdm2_loopback(st
airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2));
airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2));
@@ -89,7 +89,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
}
static int airoha_dev_init(struct net_device *dev)
@@ -1753,8 +1753,13 @@ static int airoha_dev_init(struct net_de
@@ -1769,8 +1769,13 @@ static int airoha_dev_init(struct net_de
case 3:
case 4:
/* If GDM2 is active we can't enable loopback */
@@ -105,7 +105,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
fallthrough;
case 2:
if (airoha_ppe_is_enabled(eth, 1)) {
@@ -3072,11 +3077,38 @@ static const char * const en7581_xsi_rst
@@ -3088,11 +3093,38 @@ static const char * const en7581_xsi_rst
"xfp-mac",
};
@@ -17,7 +17,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1689,10 +1689,8 @@ static int airoha_dev_set_macaddr(struct
@@ -1705,10 +1705,8 @@ static int airoha_dev_set_macaddr(struct
static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
{
@@ -29,7 +29,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
int src_port;
/* Forward the traffic to the proper GDM port */
@@ -1704,6 +1702,8 @@ static int airhoha_set_gdm2_loopback(str
@@ -1720,6 +1718,8 @@ static int airhoha_set_gdm2_loopback(str
/* Enable GDM2 loopback */
airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff);
airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff);
@@ -38,7 +38,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2),
LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK,
FIELD_PREP(LPBK_CHAN_MASK, chan) |
@@ -1718,6 +1718,8 @@ static int airhoha_set_gdm2_loopback(str
@@ -1734,6 +1734,8 @@ static int airhoha_set_gdm2_loopback(str
airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2));
airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2));
@@ -47,7 +47,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
src_port = eth->soc->ops.get_src_port_id(port, nbq);
if (src_port < 0)
return src_port;
@@ -1731,7 +1733,7 @@ static int airhoha_set_gdm2_loopback(str
@@ -1747,7 +1749,7 @@ static int airhoha_set_gdm2_loopback(str
SP_CPORT_MASK(val),
FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val)));
@@ -56,7 +56,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
FC_ID_OF_SRC_PORT24_MASK,
FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2));
@@ -1900,6 +1902,22 @@ static bool airoha_dev_tx_queue_busy(str
@@ -1916,6 +1918,22 @@ static bool airoha_dev_tx_queue_busy(str
return index >= tail;
}
@@ -79,7 +79,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
struct net_device *dev)
{
@@ -1940,7 +1958,7 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -1956,7 +1974,7 @@ static netdev_tx_t airoha_dev_xmit(struc
}
}
@@ -88,7 +88,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
@@ -3101,6 +3119,35 @@ static int airoha_en7581_get_src_port_id
@@ -3117,6 +3135,35 @@ static int airoha_en7581_get_src_port_id
return -EINVAL;
}
@@ -124,7 +124,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
static const struct airoha_eth_soc_data en7581_soc_data = {
.version = 0x7581,
.xsi_rsts_names = en7581_xsi_rsts_names,
@@ -3111,8 +3158,19 @@ static const struct airoha_eth_soc_data
@@ -3127,8 +3174,19 @@ static const struct airoha_eth_soc_data
},
};
@@ -172,7 +172,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
MBI_RX_AGE_SEL_MASK | MBI_TX_AGE_SEL_MASK,
FIELD_PREP(MBI_RX_AGE_SEL_MASK, 3) |
FIELD_PREP(MBI_TX_AGE_SEL_MASK, 3));
@@ -1697,7 +1697,7 @@ static int airhoha_set_gdm2_loopback(str
@@ -1713,7 +1713,7 @@ static int airhoha_set_gdm2_loopback(str
pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3
: FE_PSE_PORT_GDM4;
airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port);
@@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -3044,6 +3044,7 @@ static int airoha_probe(struct platform_
@@ -3060,6 +3060,7 @@ static int airoha_probe(struct platform_
error_napi_stop:
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
airoha_qdma_stop_napi(&eth->qdma[i]);
@@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2990,11 +2990,11 @@ static int airoha_probe(struct platform_
@@ -3006,11 +3006,11 @@ static int airoha_probe(struct platform_
return err;
}
@@ -23,7 +23,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -892,19 +892,13 @@ static int airoha_qdma_tx_napi_poll(stru
@@ -908,19 +908,13 @@ static int airoha_qdma_tx_napi_poll(stru
dma_unmap_single(eth->dev, e->dma_addr, e->dma_len,
DMA_TO_DEVICE);
@@ -46,7 +46,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (skb) {
u16 queue = skb_get_queue_mapping(skb);
struct netdev_queue *txq;
@@ -949,6 +943,7 @@ static int airoha_qdma_init_tx_queue(str
@@ -965,6 +959,7 @@ static int airoha_qdma_init_tx_queue(str
q->ndesc = size;
q->qdma = qdma;
q->free_thr = 1 + MAX_SKB_FRAGS;
@@ -54,7 +54,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
q->entry = devm_kzalloc(eth->dev, q->ndesc * sizeof(*q->entry),
GFP_KERNEL);
@@ -961,9 +956,9 @@ static int airoha_qdma_init_tx_queue(str
@@ -977,9 +972,9 @@ static int airoha_qdma_init_tx_queue(str
return -ENOMEM;
for (i = 0; i < q->ndesc; i++) {
@@ -66,7 +66,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
WRITE_ONCE(q->desc[i].ctrl, cpu_to_le32(val));
}
@@ -973,9 +968,9 @@ static int airoha_qdma_init_tx_queue(str
@@ -989,9 +984,9 @@ static int airoha_qdma_init_tx_queue(str
airoha_qdma_wr(qdma, REG_TX_RING_BASE(qid), dma_addr);
airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
@@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
return 0;
}
@@ -1031,17 +1026,21 @@ static int airoha_qdma_init_tx(struct ai
@@ -1047,17 +1042,21 @@ 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;
@@ -104,7 +104,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
q->queued--;
}
spin_unlock_bh(&q->lock);
@@ -1883,20 +1882,6 @@ static u32 airoha_get_dsa_tag(struct sk_
@@ -1899,20 +1898,6 @@ static u32 airoha_get_dsa_tag(struct sk_
#endif
}
@@ -125,7 +125,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
static int airoha_get_fe_port(struct airoha_gdm_port *port)
{
struct airoha_qdma *qdma = port->qdma;
@@ -1919,8 +1904,10 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -1935,8 +1920,10 @@ static netdev_tx_t airoha_dev_xmit(struc
struct airoha_gdm_port *port = netdev_priv(dev);
struct airoha_qdma *qdma = port->qdma;
u32 nr_frags, tag, msg0, msg1, len;
@@ -136,7 +136,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
void *data;
int i, qid;
u16 index;
@@ -1966,7 +1953,7 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -1982,7 +1969,7 @@ static netdev_tx_t airoha_dev_xmit(struc
txq = netdev_get_tx_queue(dev, qid);
nr_frags = 1 + skb_shinfo(skb)->nr_frags;
@@ -145,7 +145,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
/* not enough space in the queue */
netif_tx_stop_queue(txq);
spin_unlock_bh(&q->lock);
@@ -1975,11 +1962,13 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -1991,11 +1978,13 @@ static netdev_tx_t airoha_dev_xmit(struc
len = skb_headlen(skb);
data = skb->data;
@@ -161,7 +161,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
dma_addr_t addr;
u32 val;
@@ -1989,7 +1978,14 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -2005,7 +1994,14 @@ static netdev_tx_t airoha_dev_xmit(struc
if (unlikely(dma_mapping_error(dev->dev.parent, addr)))
goto error_unmap;
@@ -177,7 +177,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
val = FIELD_PREP(QDMA_DESC_LEN_MASK, len);
if (i < nr_frags - 1)
@@ -2002,15 +1998,9 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -2018,15 +2014,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));
@@ -193,7 +193,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
q->queued += i;
skb_tx_timestamp(skb);
@@ -2019,7 +2009,7 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -2035,7 +2025,7 @@ static netdev_tx_t airoha_dev_xmit(struc
if (netif_xmit_stopped(txq) || !netdev_xmit_more())
airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid),
TX_RING_CPU_IDX_MASK,
@@ -202,7 +202,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (q->ndesc - q->queued < q->free_thr)
netif_tx_stop_queue(txq);
@@ -2029,10 +2019,13 @@ static netdev_tx_t airoha_dev_xmit(struc
@@ -2045,10 +2035,13 @@ static netdev_tx_t airoha_dev_xmit(struc
return NETDEV_TX_OK;
error_unmap:
@@ -23,7 +23,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2924,19 +2924,26 @@ static int airoha_alloc_gdm_port(struct
@@ -2940,19 +2940,26 @@ static int airoha_alloc_gdm_port(struct
port->id = id;
eth->ports[p] = port;
@@ -60,7 +60,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
}
static int airoha_probe(struct platform_device *pdev)
@@ -3027,6 +3034,10 @@ static int airoha_probe(struct platform_
@@ -3043,6 +3050,10 @@ static int airoha_probe(struct platform_
}
}
@@ -71,7 +71,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
return 0;
error_napi_stop:
@@ -3040,10 +3051,12 @@ error_hw_cleanup:
@@ -3056,10 +3067,12 @@ error_hw_cleanup:
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
@@ -40,7 +40,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
airoha_fe_crsn_qsel_init(eth);
@@ -1690,27 +1690,29 @@ static int airhoha_set_gdm2_loopback(str
@@ -1706,27 +1706,29 @@ static int airhoha_set_gdm2_loopback(str
/* Forward the traffic to the proper GDM port */
pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3
: FE_PSE_PORT_GDM4;
@@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
/* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */
nbq = port->id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
@@ -1746,8 +1748,8 @@ static int airoha_dev_init(struct net_de
@@ -1762,8 +1764,8 @@ static int airoha_dev_init(struct net_de
airoha_set_macaddr(port, dev->dev_addr);
switch (port->id) {
@@ -89,7 +89,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
/* If GDM2 is active we can't enable loopback */
if (!eth->ports[1]) {
int err;
@@ -1757,7 +1759,7 @@ static int airoha_dev_init(struct net_de
@@ -1773,7 +1775,7 @@ static int airoha_dev_init(struct net_de
return err;
}
fallthrough;
@@ -98,7 +98,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (airoha_ppe_is_enabled(eth, 1)) {
/* For PPE2 always use secondary cpu port. */
fe_cpu_port = FE_PSE_PORT_CDM2;
@@ -3100,14 +3102,14 @@ static const char * const en7581_xsi_rst
@@ -3116,14 +3118,14 @@ static const char * const en7581_xsi_rst
static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq)
{
switch (port->id) {
@@ -115,7 +115,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
/* 7581 SoC supports eth and usb serdes on GDM4 port */
if (!nbq)
return HSGMII_LAN_7581_ETH_SRCPORT;
@@ -3131,12 +3133,12 @@ static const char * const an7583_xsi_rst
@@ -3147,12 +3149,12 @@ static const char * const an7583_xsi_rst
static int airoha_an7583_get_src_port_id(struct airoha_gdm_port *port, int nbq)
{
switch (port->id) {
@@ -16,7 +16,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2805,6 +2805,7 @@ static const struct ethtool_ops airoha_e
@@ -2821,6 +2821,7 @@ static const struct ethtool_ops airoha_e
.get_drvinfo = airoha_ethtool_get_drvinfo,
.get_eth_mac_stats = airoha_ethtool_get_mac_stats,
.get_rmon_stats = airoha_ethtool_get_rmon_stats,
@@ -15,7 +15,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1727,7 +1727,7 @@ static int airhoha_set_gdm2_loopback(str
@@ -1743,7 +1743,7 @@ static int airhoha_set_gdm2_loopback(str
airoha_fe_rmw(eth,
REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)),
SP_CPORT_MASK(val),
@@ -24,7 +24,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
if (port->id != AIROHA_GDM3_IDX && airoha_is_7581(eth))
airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
@@ -1781,7 +1781,7 @@ static int airoha_dev_init(struct net_de
@@ -1797,7 +1797,7 @@ static int airoha_dev_init(struct net_de
ppe_id = pse_port == FE_PSE_PORT_PPE2 ? 1 : 0;
airoha_fe_rmw(eth, REG_PPE_DFT_CPORT0(ppe_id),
DFT_CPORT_MASK(port->id),
@@ -33,7 +33,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
return 0;
}
@@ -2138,7 +2138,7 @@ static int airoha_qdma_set_chan_tx_sched
@@ -2154,7 +2154,7 @@ static int airoha_qdma_set_chan_tx_sched
airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3),
CHAN_QOS_MODE_MASK(channel),
@@ -19,7 +19,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1729,10 +1729,12 @@ static int airhoha_set_gdm2_loopback(str
@@ -1745,10 +1745,12 @@ static int airhoha_set_gdm2_loopback(str
SP_CPORT_MASK(val),
__field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
@@ -18,7 +18,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1611,6 +1611,7 @@ static int airoha_dev_open(struct net_de
@@ -1627,6 +1627,7 @@ static int airoha_dev_open(struct net_de
int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN;
struct airoha_gdm_port *port = netdev_priv(dev);
struct airoha_qdma *qdma = port->qdma;
@@ -26,7 +26,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
netif_tx_start_all_queues(dev);
err = airoha_set_vip_for_gdm_port(port, true);
@@ -1634,6 +1635,14 @@ static int airoha_dev_open(struct net_de
@@ -1650,6 +1651,14 @@ static int airoha_dev_open(struct net_de
GLOBAL_CFG_RX_DMA_EN_MASK);
atomic_inc(&qdma->users);
@@ -41,7 +41,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
return 0;
}
@@ -1651,6 +1660,9 @@ static int airoha_dev_stop(struct net_de
@@ -1667,6 +1676,9 @@ static int airoha_dev_stop(struct net_de
for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++)
netdev_tx_reset_subqueue(dev, i);
@@ -51,7 +51,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
if (atomic_dec_and_test(&qdma->users)) {
airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
GLOBAL_CFG_TX_DMA_EN_MASK |
@@ -1744,7 +1756,7 @@ static int airoha_dev_init(struct net_de
@@ -1760,7 +1772,7 @@ static int airoha_dev_init(struct net_de
struct airoha_gdm_port *port = netdev_priv(dev);
struct airoha_qdma *qdma = port->qdma;
struct airoha_eth *eth = qdma->eth;
@@ -60,7 +60,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
u8 ppe_id;
airoha_set_macaddr(port, dev->dev_addr);
@@ -1765,7 +1777,7 @@ static int airoha_dev_init(struct net_de
@@ -1781,7 +1793,7 @@ static int airoha_dev_init(struct net_de
if (airoha_ppe_is_enabled(eth, 1)) {
/* For PPE2 always use secondary cpu port. */
fe_cpu_port = FE_PSE_PORT_CDM2;
@@ -69,7 +69,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
break;
}
fallthrough;
@@ -1774,13 +1786,11 @@ static int airoha_dev_init(struct net_de
@@ -1790,13 +1802,11 @@ static int airoha_dev_init(struct net_de
/* For PPE1 select cpu port according to the running QDMA. */
fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1;
@@ -39,7 +39,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1754,11 +1754,13 @@ static int airhoha_set_gdm2_loopback(str
@@ -1770,11 +1770,13 @@ static int airhoha_set_gdm2_loopback(str
static int airoha_dev_init(struct net_device *dev)
{
struct airoha_gdm_port *port = netdev_priv(dev);
@@ -55,7 +55,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
airoha_set_macaddr(port, dev->dev_addr);
switch (port->id) {
@@ -1782,7 +1784,7 @@ static int airoha_dev_init(struct net_de
@@ -1798,7 +1800,7 @@ static int airoha_dev_init(struct net_de
}
fallthrough;
default: {
@@ -64,7 +64,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
/* For PPE1 select cpu port according to the running QDMA. */
fe_cpu_port = qdma_id ? FE_PSE_PORT_CDM2 : FE_PSE_PORT_CDM1;
@@ -2866,11 +2868,10 @@ bool airoha_is_valid_gdm_port(struct air
@@ -2882,11 +2884,10 @@ bool airoha_is_valid_gdm_port(struct air
}
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
@@ -77,7 +77,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
struct net_device *dev;
int err, p;
u32 id;
@@ -2901,7 +2902,6 @@ static int airoha_alloc_gdm_port(struct
@@ -2917,7 +2918,6 @@ static int airoha_alloc_gdm_port(struct
return -ENOMEM;
}
@@ -85,7 +85,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
dev->netdev_ops = &airoha_netdev_ops;
dev->ethtool_ops = &airoha_ethtool_ops;
dev->max_mtu = AIROHA_MAX_MTU;
@@ -2913,7 +2913,6 @@ static int airoha_alloc_gdm_port(struct
@@ -2929,7 +2929,6 @@ static int airoha_alloc_gdm_port(struct
dev->features |= dev->hw_features;
dev->vlan_features = dev->hw_features;
dev->dev.of_node = np;
@@ -93,7 +93,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
SET_NETDEV_DEV(dev, eth->dev);
/* reserve hw queues for HTB offloading */
@@ -2934,7 +2933,7 @@ static int airoha_alloc_gdm_port(struct
@@ -2950,7 +2949,7 @@ static int airoha_alloc_gdm_port(struct
port = netdev_priv(dev);
u64_stats_init(&port->stats.syncp);
spin_lock_init(&port->stats.lock);
@@ -102,7 +102,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
port->dev = dev;
port->id = id;
eth->ports[p] = port;
@@ -3034,7 +3033,6 @@ static int airoha_probe(struct platform_
@@ -3050,7 +3049,6 @@ static int airoha_probe(struct platform_
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
airoha_qdma_start_napi(&eth->qdma[i]);
@@ -110,7 +110,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
for_each_child_of_node(pdev->dev.of_node, np) {
if (!of_device_is_compatible(np, "airoha,eth-mac"))
continue;
@@ -3042,7 +3040,7 @@ static int airoha_probe(struct platform_
@@ -3058,7 +3056,7 @@ static int airoha_probe(struct platform_
if (!of_device_is_available(np))
continue;
@@ -32,7 +32,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1755,8 +1755,7 @@ static int airoha_dev_init(struct net_de
@@ -1771,8 +1771,7 @@ static int airoha_dev_init(struct net_de
{
struct airoha_gdm_port *port = netdev_priv(dev);
struct airoha_eth *eth = port->eth;
@@ -42,7 +42,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
port->qdma = &eth->qdma[!airoha_is_lan_gdm_port(port)];
@@ -1774,28 +1773,13 @@ static int airoha_dev_init(struct net_de
@@ -1790,28 +1789,13 @@ static int airoha_dev_init(struct net_de
if (err)
return err;
}
@@ -75,7 +75,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
return 0;
}
@@ -1898,7 +1882,7 @@ static u32 airoha_get_dsa_tag(struct sk_
@@ -1914,7 +1898,7 @@ static u32 airoha_get_dsa_tag(struct sk_
#endif
}
@@ -23,7 +23,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1368,6 +1368,33 @@ static int airoha_qdma_init(struct platf
@@ -1384,6 +1384,33 @@ static int airoha_qdma_init(struct platf
return airoha_qdma_hw_init(qdma);
}
@@ -57,7 +57,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
static int airoha_hw_init(struct platform_device *pdev,
struct airoha_eth *eth)
{
@@ -1395,41 +1422,30 @@ static int airoha_hw_init(struct platfor
@@ -1411,41 +1438,30 @@ static int airoha_hw_init(struct platfor
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++) {
err = airoha_qdma_init(pdev, eth, &eth->qdma[i]);
if (err)
@@ -110,7 +110,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
}
static void airoha_qdma_start_napi(struct airoha_qdma *qdma)
@@ -3012,7 +3028,7 @@ static int airoha_probe(struct platform_
@@ -3028,7 +3044,7 @@ static int airoha_probe(struct platform_
err = airoha_hw_init(pdev, eth);
if (err)
@@ -119,7 +119,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
airoha_qdma_start_napi(&eth->qdma[i]);
@@ -3040,10 +3056,6 @@ static int airoha_probe(struct platform_
@@ -3056,10 +3072,6 @@ static int airoha_probe(struct platform_
error_napi_stop:
for (i = 0; i < ARRAY_SIZE(eth->qdma); i++)
airoha_qdma_stop_napi(&eth->qdma[i]);
@@ -130,7 +130,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
@@ -3055,6 +3067,8 @@ error_hw_cleanup:
@@ -3071,6 +3083,8 @@ error_hw_cleanup:
unregister_netdev(port->dev);
airoha_metadata_dst_free(port);
}
@@ -139,7 +139,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
free_netdev(eth->napi_dev);
platform_set_drvdata(pdev, NULL);
@@ -3066,10 +3080,8 @@ static void airoha_remove(struct platfor
@@ -3082,10 +3096,8 @@ static void airoha_remove(struct platfor
struct airoha_eth *eth = platform_get_drvdata(pdev);
int i;
@@ -151,7 +151,7 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
@@ -3080,9 +3092,9 @@ static void airoha_remove(struct platfor
@@ -3096,9 +3108,9 @@ static void airoha_remove(struct platfor
unregister_netdev(port->dev);
airoha_metadata_dst_free(port);
}
@@ -26,7 +26,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- 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
@@ -2973,6 +2973,8 @@ static int airoha_register_gdm_devices(s
return err;
}
@@ -1,57 +0,0 @@
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)
@@ -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),
@@ -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);
}
@@ -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,
@@ -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 - &eth->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));
}
}
}
@@ -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;
@@ -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);
@@ -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)
@@ -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) {
@@ -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;
@@ -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.
@@ -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);
}
@@ -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;
@@ -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[] = {
@@ -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;
@@ -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;
@@ -295,7 +295,7 @@ SVN-Revision: 35130
&sin->sin6_addr);
sin->sin6_scope_id = 0;
}
@@ -852,12 +852,12 @@ int ip6_datagram_send_ctl(struct net *ne
@@ -853,12 +853,12 @@ int ip6_datagram_send_ctl(struct net *ne
}
if (fl6->flowlabel&IPV6_FLOWINFO_MASK) {
@@ -312,7 +312,7 @@ SVN-Revision: 35130
case IPV6_2292HOPOPTS:
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -986,7 +986,7 @@ static bool ipv6_hop_jumbo(struct sk_buf
@@ -990,7 +990,7 @@ static bool ipv6_hop_jumbo(struct sk_buf
goto drop;
}
@@ -295,7 +295,7 @@ SVN-Revision: 35130
&sin->sin6_addr);
sin->sin6_scope_id = 0;
}
@@ -852,12 +852,12 @@ int ip6_datagram_send_ctl(struct net *ne
@@ -853,12 +853,12 @@ int ip6_datagram_send_ctl(struct net *ne
}
if (fl6->flowlabel&IPV6_FLOWINFO_MASK) {
@@ -312,7 +312,7 @@ SVN-Revision: 35130
case IPV6_2292HOPOPTS:
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -984,7 +984,7 @@ static bool ipv6_hop_jumbo(struct sk_buf
@@ -988,7 +988,7 @@ static bool ipv6_hop_jumbo(struct sk_buf
goto drop;
}
@@ -18626,7 +18626,7 @@ Signed-off-by: j-schambacher <joerg@hifiberry.com>
* For devices with more than one control interface, we assume the
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -2397,6 +2397,8 @@ static const struct usb_audio_quirk_flag
@@ -2399,6 +2399,8 @@ static const struct usb_audio_quirk_flag
QUIRK_FLAG_ALIGN_TRANSFER),
DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */
QUIRK_FLAG_ALIGN_TRANSFER),
@@ -22,7 +22,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -255,6 +255,9 @@
@@ -258,6 +258,9 @@
#define USB_VENDOR_ID_BAANTO 0x2453
#define USB_DEVICE_ID_BAANTO_MT_190W2 0x0100
@@ -32,7 +32,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
#define USB_VENDOR_ID_BELKIN 0x050d
#define USB_DEVICE_ID_FLIP_KVM 0x3201
@@ -1481,6 +1484,9 @@
@@ -1484,6 +1487,9 @@
#define USB_VENDOR_ID_XIAOMI 0x2717
#define USB_DEVICE_ID_MI_SILENT_MOUSE 0x5014
@@ -44,7 +44,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
#define USB_DEVICE_ID_THT_2P_ARCADE 0x75e1
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -44,6 +44,7 @@ static const struct hid_device_id hid_qu
@@ -45,6 +45,7 @@ static const struct hid_device_id hid_qu
{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682), HID_QUIRK_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692), HID_QUIRK_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM), HID_QUIRK_NOGET },
@@ -52,7 +52,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.org>
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2), HID_QUIRK_ALWAYS_POLL },
@@ -216,6 +217,7 @@ static const struct hid_device_id hid_qu
@@ -217,6 +218,7 @@ static const struct hid_device_id hid_qu
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_GROUP_AUDIO), HID_QUIRK_NOGET },
@@ -26,7 +26,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
/* Device and char device-related information */
static DEFINE_IDA(gpio_ida);
static dev_t gpio_devt;
@@ -2814,8 +2816,8 @@ int gpiod_direction_output(struct gpio_d
@@ -2813,8 +2815,8 @@ int gpiod_direction_output(struct gpio_d
value = !!value;
/* GPIOs used for enabled IRQs shall not be set as output */
@@ -37,7 +37,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
gpiod_err(desc,
"%s: tried to set a GPIO tied to an IRQ as output\n",
__func__);
@@ -3766,8 +3768,8 @@ int gpiochip_lock_as_irq(struct gpio_chi
@@ -3765,8 +3767,8 @@ int gpiochip_lock_as_irq(struct gpio_chi
}
/* To be valid for IRQ the line needs to be input or open drain */
@@ -20,7 +20,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -4935,6 +4935,7 @@ static const struct {
@@ -4942,6 +4942,7 @@ static const struct {
*/
static int hci_dev_setup_sync(struct hci_dev *hdev)
{
@@ -28,7 +28,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
int ret = 0;
bool invalid_bdaddr;
size_t i;
@@ -4963,7 +4964,8 @@ static int hci_dev_setup_sync(struct hci
@@ -4970,7 +4971,8 @@ static int hci_dev_setup_sync(struct hci
test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks);
if (!ret) {
if (test_bit(HCI_QUIRK_USE_BDADDR_PROPERTY, &hdev->quirks) &&
@@ -15,7 +15,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -4935,7 +4935,8 @@ static const struct {
@@ -4942,7 +4942,8 @@ static const struct {
*/
static int hci_dev_setup_sync(struct hci_dev *hdev)
{
@@ -43,7 +43,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
retry_disable:
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -646,7 +646,7 @@ void drm_mode_config_validate(struct drm
@@ -643,7 +643,7 @@ void drm_mode_config_validate(struct drm
struct drm_encoder *encoder;
struct drm_crtc *crtc;
struct drm_plane *plane;
@@ -90,7 +90,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return;
/* Fast path: if the BO is still retained by someone, no need to test
@@ -783,7 +783,7 @@ int vc4_create_bo_ioctl(struct drm_devic
@@ -786,7 +786,7 @@ int vc4_create_bo_ioctl(struct drm_devic
struct vc4_bo *bo = NULL;
int ret;
@@ -99,7 +99,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
ret = vc4_grab_bin_bo(vc4, vc4file);
@@ -813,7 +813,7 @@ int vc4_mmap_bo_ioctl(struct drm_device
@@ -816,7 +816,7 @@ int vc4_mmap_bo_ioctl(struct drm_device
struct drm_vc4_mmap_bo *args = data;
struct drm_gem_object *gem_obj;
@@ -108,7 +108,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
@@ -839,7 +839,7 @@ vc4_create_shader_bo_ioctl(struct drm_de
@@ -842,7 +842,7 @@ vc4_create_shader_bo_ioctl(struct drm_de
struct vc4_bo *bo = NULL;
int ret;
@@ -117,7 +117,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
if (args->size == 0)
@@ -918,7 +918,7 @@ int vc4_set_tiling_ioctl(struct drm_devi
@@ -921,7 +921,7 @@ int vc4_set_tiling_ioctl(struct drm_devi
struct vc4_bo *bo;
bool t_format;
@@ -126,7 +126,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
if (args->flags != 0)
@@ -964,7 +964,7 @@ int vc4_get_tiling_ioctl(struct drm_devi
@@ -967,7 +967,7 @@ int vc4_get_tiling_ioctl(struct drm_devi
struct drm_gem_object *gem_obj;
struct vc4_bo *bo;
@@ -135,7 +135,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
if (args->flags != 0 || args->modifier != 0)
@@ -1007,7 +1007,7 @@ int vc4_bo_cache_init(struct drm_device
@@ -1010,7 +1010,7 @@ int vc4_bo_cache_init(struct drm_device
int ret;
int i;
@@ -144,7 +144,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
/* Create the initial set of BO labels that the kernel will
@@ -1071,7 +1071,7 @@ int vc4_label_bo_ioctl(struct drm_device
@@ -1074,7 +1074,7 @@ int vc4_label_bo_ioctl(struct drm_device
struct drm_gem_object *gem_obj;
int ret = 0, label;
@@ -213,7 +213,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
driver = &vc4_drm_driver;
--- a/drivers/gpu/drm/vc4/vc4_gem.c
+++ b/drivers/gpu/drm/vc4/vc4_gem.c
@@ -76,7 +76,7 @@ vc4_get_hang_state_ioctl(struct drm_devi
@@ -77,7 +77,7 @@ vc4_get_hang_state_ioctl(struct drm_devi
u32 i;
int ret = 0;
@@ -222,7 +222,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
if (!vc4->v3d) {
@@ -389,7 +389,7 @@ vc4_wait_for_seqno(struct drm_device *de
@@ -392,7 +392,7 @@ vc4_wait_for_seqno(struct drm_device *de
unsigned long timeout_expire;
DEFINE_WAIT(wait);
@@ -231,7 +231,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
if (vc4->finished_seqno >= seqno)
@@ -474,7 +474,7 @@ vc4_submit_next_bin_job(struct drm_devic
@@ -477,7 +477,7 @@ vc4_submit_next_bin_job(struct drm_devic
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct vc4_exec_info *exec;
@@ -240,7 +240,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return;
again:
@@ -522,7 +522,7 @@ vc4_submit_next_render_job(struct drm_de
@@ -525,7 +525,7 @@ vc4_submit_next_render_job(struct drm_de
if (!exec)
return;
@@ -249,7 +249,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return;
/* A previous RCL may have written to one of our textures, and
@@ -543,7 +543,7 @@ vc4_move_job_to_render(struct drm_device
@@ -546,7 +546,7 @@ vc4_move_job_to_render(struct drm_device
struct vc4_dev *vc4 = to_vc4_dev(dev);
bool was_empty = list_empty(&vc4->render_job_list);
@@ -258,7 +258,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return;
list_move_tail(&exec->head, &vc4->render_job_list);
@@ -970,7 +970,7 @@ vc4_job_handle_completed(struct vc4_dev
@@ -973,7 +973,7 @@ vc4_job_handle_completed(struct vc4_dev
unsigned long irqflags;
struct vc4_seqno_cb *cb, *cb_temp;
@@ -267,7 +267,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return;
spin_lock_irqsave(&vc4->job_lock, irqflags);
@@ -1009,7 +1009,7 @@ int vc4_queue_seqno_cb(struct drm_device
@@ -1012,7 +1012,7 @@ int vc4_queue_seqno_cb(struct drm_device
struct vc4_dev *vc4 = to_vc4_dev(dev);
unsigned long irqflags;
@@ -276,7 +276,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
cb->func = func;
@@ -1065,7 +1065,7 @@ vc4_wait_seqno_ioctl(struct drm_device *
@@ -1068,7 +1068,7 @@ vc4_wait_seqno_ioctl(struct drm_device *
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct drm_vc4_wait_seqno *args = data;
@@ -285,7 +285,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
return vc4_wait_for_seqno_ioctl_helper(dev, args->seqno,
@@ -1082,7 +1082,7 @@ vc4_wait_bo_ioctl(struct drm_device *dev
@@ -1085,7 +1085,7 @@ vc4_wait_bo_ioctl(struct drm_device *dev
struct drm_gem_object *gem_obj;
struct vc4_bo *bo;
@@ -294,7 +294,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
if (args->pad != 0)
@@ -1131,7 +1131,7 @@ vc4_submit_cl_ioctl(struct drm_device *d
@@ -1134,7 +1134,7 @@ vc4_submit_cl_ioctl(struct drm_device *d
args->shader_rec_size,
args->bo_handle_count);
@@ -303,7 +303,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
if (!vc4->v3d) {
@@ -1267,7 +1267,7 @@ int vc4_gem_init(struct drm_device *dev)
@@ -1270,7 +1270,7 @@ int vc4_gem_init(struct drm_device *dev)
struct vc4_dev *vc4 = to_vc4_dev(dev);
int ret;
@@ -312,7 +312,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
return -ENODEV;
vc4->dma_fence_context = dma_fence_context_alloc(1);
@@ -1326,7 +1326,7 @@ int vc4_gem_madvise_ioctl(struct drm_dev
@@ -1329,7 +1329,7 @@ int vc4_gem_madvise_ioctl(struct drm_dev
struct vc4_bo *bo;
int ret;
@@ -76,7 +76,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
VC4_HD_VID_CTL_ENABLE |
VC4_HD_VID_CTL_CLRRGB |
VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
@@ -3121,6 +3134,7 @@ static int vc4_hdmi_runtime_suspend(stru
@@ -3127,6 +3140,7 @@ static int vc4_hdmi_runtime_suspend(stru
{
struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
@@ -84,7 +84,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
clk_disable_unprepare(vc4_hdmi->hsm_clock);
return 0;
@@ -3153,6 +3167,10 @@ static int vc4_hdmi_runtime_resume(struc
@@ -3159,6 +3173,10 @@ static int vc4_hdmi_runtime_resume(struc
goto err_disable_clk;
}
@@ -95,7 +95,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
if (vc4_hdmi->variant->reset)
vc4_hdmi->variant->reset(vc4_hdmi);
@@ -3273,7 +3291,9 @@ static int vc4_hdmi_bind(struct device *
@@ -3279,7 +3297,9 @@ static int vc4_hdmi_bind(struct device *
return ret;
if ((of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi0") ||
@@ -106,7 +106,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
HDMI_READ(HDMI_VID_CTL) & VC4_HD_VID_CTL_ENABLE) {
clk_prepare_enable(vc4_hdmi->pixel_clock);
clk_prepare_enable(vc4_hdmi->hsm_clock);
@@ -3407,10 +3427,66 @@ static const struct vc4_hdmi_variant bcm
@@ -3413,10 +3433,66 @@ static const struct vc4_hdmi_variant bcm
.hp_detect = vc5_hdmi_hp_detect,
};
@@ -115,7 +115,7 @@ Signed-off-by: David Turner <david.turner@raspberrypi.com>
card->dai_link = dai_link;
card->num_links = 1;
card->name = vc4_hdmi->variant->card_name;
@@ -3234,6 +3280,8 @@ static int vc4_hdmi_bind(struct device *
@@ -3240,6 +3286,8 @@ static int vc4_hdmi_bind(struct device *
if (ret)
return ret;
@@ -124,7 +124,7 @@ Signed-off-by: David Turner <david.turner@raspberrypi.com>
spin_lock_init(&vc4_hdmi->hw_lock);
INIT_DELAYED_WORK(&vc4_hdmi->scrambling_work, vc4_hdmi_scrambling_wq);
@@ -3346,8 +3394,16 @@ err_put_runtime_pm:
@@ -3352,8 +3400,16 @@ err_put_runtime_pm:
return ret;
}
@@ -39,7 +39,7 @@ Signed-off-by: Dom Cobley <popcornmix@gmail.com>
clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock);
clk_disable_unprepare(vc4_hdmi->pixel_clock);
@@ -3219,6 +3221,8 @@ static int vc4_hdmi_runtime_suspend(stru
@@ -3225,6 +3227,8 @@ static int vc4_hdmi_runtime_suspend(stru
struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
clk_disable_unprepare(vc4_hdmi->audio_clock);
@@ -157,7 +157,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
/* Only try to fixup DBLCLK modes to get 480i and 576i
* working.
@@ -3481,6 +3483,7 @@ static const struct vc4_hdmi_variant bcm
@@ -3487,6 +3489,7 @@ static const struct vc4_hdmi_variant bcm
PHY_LANE_CK,
},
.unsupported_odd_h_timings = true,
@@ -165,7 +165,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
.external_irq_controller = true,
.init_resources = vc5_hdmi_init_resources,
@@ -3510,6 +3513,7 @@ static const struct vc4_hdmi_variant bcm
@@ -3516,6 +3519,7 @@ static const struct vc4_hdmi_variant bcm
PHY_LANE_2,
},
.unsupported_odd_h_timings = true,
@@ -173,7 +173,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
.external_irq_controller = true,
.init_resources = vc5_hdmi_init_resources,
@@ -3539,6 +3543,7 @@ static const struct vc4_hdmi_variant bcm
@@ -3545,6 +3549,7 @@ static const struct vc4_hdmi_variant bcm
PHY_LANE_CK,
},
.unsupported_odd_h_timings = false,
@@ -181,7 +181,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
.external_irq_controller = true,
.init_resources = vc5_hdmi_init_resources,
@@ -3566,6 +3571,7 @@ static const struct vc4_hdmi_variant bcm
@@ -3572,6 +3577,7 @@ static const struct vc4_hdmi_variant bcm
PHY_LANE_CK,
},
.unsupported_odd_h_timings = false,
@@ -18,7 +18,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -3351,7 +3351,7 @@ static int vc4_hdmi_bind(struct device *
@@ -3357,7 +3357,7 @@ static int vc4_hdmi_bind(struct device *
vc4_hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node);
of_node_put(ddc_node);
if (!vc4_hdmi->ddc) {
+1 -1
View File
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
ARCH:=arm
BOARD:=bcm53xx
BOARDNAME:=Broadcom BCM47xx/53xx (ARM)
FEATURES:=squashfs nand usb pci pcie gpio pwm
FEATURES:=squashfs nand usb pci pcie gpio pwm ramdisk
CPU_TYPE:=cortex-a9
SUBTARGETS:=generic
@@ -39,7 +39,7 @@ Signed-off-by: Qingfang Deng <dqfext@gmail.com>
mcr |= MAC_MCR_TX_EN | MAC_MCR_RX_EN | MAC_MCR_FORCE_LINK;
mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
}
@@ -4523,6 +4533,61 @@ static int mtk_set_pauseparam(struct net
@@ -4543,6 +4553,61 @@ static int mtk_set_pauseparam(struct net
return phylink_ethtool_set_pauseparam(mac->phylink, pause);
}
@@ -101,7 +101,7 @@ Signed-off-by: Qingfang Deng <dqfext@gmail.com>
static u16 mtk_select_queue(struct net_device *dev, struct sk_buff *skb,
struct net_device *sb_dev)
{
@@ -4555,6 +4620,8 @@ static const struct ethtool_ops mtk_etht
@@ -4575,6 +4640,8 @@ static const struct ethtool_ops mtk_etht
.set_pauseparam = mtk_set_pauseparam,
.get_rxnfc = mtk_get_rxnfc,
.set_rxnfc = mtk_set_rxnfc,
@@ -110,7 +110,7 @@ Signed-off-by: Qingfang Deng <dqfext@gmail.com>
};
static const struct net_device_ops mtk_netdev_ops = {
@@ -4615,6 +4682,8 @@ static int mtk_add_mac(struct mtk_eth *e
@@ -4635,6 +4702,8 @@ static int mtk_add_mac(struct mtk_eth *e
}
mac = netdev_priv(eth->netdev[id]);
eth->mac[id] = mac;
@@ -36,7 +36,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -567,6 +567,8 @@ static const struct sfp_quirk sfp_quirks
@@ -588,6 +588,8 @@ static const struct sfp_quirk sfp_quirks
SFP_QUIRK_F("Turris", "RTSFP-2.5G", sfp_fixup_rollball),
SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),
SFP_QUIRK_F("Turris", "RTSFP-10G", sfp_fixup_rollball),
@@ -1,56 +0,0 @@
From 95aca8602ef70ffd3d971675751c81826e124f90 Mon Sep 17 00:00:00 2001
From: John Pavlick <jspavlick@posteo.net>
Date: Mon, 6 Apr 2026 13:23:33 +0000
Subject: [PATCH] net: sfp: add quirks for Hisense and HSGQ GPON ONT SFP
modules
Several GPON ONT SFP sticks based on Realtek RTL960x report
1000BASE-LX at 1300MBd in their EEPROM but can operate at 2500base-X.
On hosts capable of 2500base-X (e.g. Banana Pi R3 / MT7986), the
kernel negotiates only 1G because it trusts the incorrect EEPROM data.
Add quirks for:
- Hisense-Leox LXT-010S-H
- Hisense ZNID-GPON-2311NA
- HSGQ HSGQ-XPON-Stick
Each quirk advertises 2500base-X and ignores TX_FAULT during the
module's ~40s Linux boot time.
Tested on Banana Pi R3 (MT7986) with OpenWrt 25.12.1, confirmed
2.5Gbps link and full throughput with flow offloading.
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Suggested-by: Marcin Nita <marcin.nita@leolabs.pl>
Signed-off-by: John Pavlick <jspavlick@posteo.net>
Link: https://patch.msgid.link/20260406132321.72563-1-jspavlick@posteo.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
drivers/net/phy/sfp.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -538,6 +538,22 @@ static const struct sfp_quirk sfp_quirks
SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
sfp_fixup_ignore_tx_fault_and_los),
+ // Hisense LXT-010S-H is a GPON ONT SFP (sold as LEOX LXT-010S-H) that
+ // can operate at 2500base-X, but reports 1000BASE-LX / 1300MBd in its
+ // EEPROM
+ SFP_QUIRK("Hisense-Leox", "LXT-010S-H", sfp_quirk_2500basex,
+ sfp_fixup_ignore_tx_fault),
+
+ // Hisense ZNID-GPON-2311NA can operate at 2500base-X, but reports
+ // 1000BASE-LX / 1300MBd in its EEPROM
+ SFP_QUIRK("Hisense", "ZNID-GPON-2311NA", sfp_quirk_2500basex,
+ sfp_fixup_ignore_tx_fault),
+
+ // HSGQ HSGQ-XPON-Stick can operate at 2500base-X, but reports
+ // 1000BASE-LX / 1300MBd in its EEPROM
+ SFP_QUIRK("HSGQ", "HSGQ-XPON-Stick", sfp_quirk_2500basex,
+ sfp_fixup_ignore_tx_fault),
+
// Lantech 8330-262D-E and 8330-265D can operate at 2500base-X, but
// incorrectly report 2500MBd NRZ in their EEPROM.
// Some 8330-265D modules have inverted LOS, while all of them report

Some files were not shown because too many files have changed in this diff Show More