Files
openwrt/target/linux/generic/pending-6.18/795-05-net-ethernet-mtk_eth_soc-add-per-conduit-DSA-user-po.patch
T
Christian Marangi 627cd79e1c generic: update pending PCS patch with .fill_available_pcs OP
While implementing standalone PCS support for DSA, it was found that making
the MAC driver passing the available_pcs array is limiting and problematic
for memory handling and allocation. To better handle this, change the logic
and make phylink allocate the struct and make the MAC driver implement a
function in phylink_config .fill_available_pcs to fill the PCS array.

Update the Airoha and Mediatek driver to reflect this new implementation.

Link: https://github.com/openwrt/openwrt/pull/23413
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
2026-05-18 23:32:34 +02:00

169 lines
5.6 KiB
Diff

From e404de9968c4010b1f5fea4fba78ddbb220ba97a Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Thu, 23 Apr 2026 15:19:04 +0100
Subject: [PATCH 5/9] net: ethernet: mtk_eth_soc: add per-conduit DSA user-port
queue map
Today the driver maps every DSA user port to QDMA TX queue
dp->index + 3 at three call sites (link-speed notifier, SW TX
select_queue, and PPE flow offload). The mapping is correct for a
single DSA switch per conduit with contiguous port indices, which
covers every current MediaTek SoC paired with MT7530/MT7531/built-in
switch.
It falls apart in two scenarios that start to matter:
1) Multiple DSA switches on one MT7988 (built-in MT7530 on GMAC2
plus an external switch on a SerDes GMAC). Each switch has its
own dp->index space starting at 0, so port 0 of switch A and
port 0 of switch B both map to QDMA queue 3 and stomp each
other's shaping and offload state.
2) Switches with non-contiguous user-port indices (CPU port in the
middle of the range, some indices reserved), where "queue =
dp->index + 3" leaves gaps or overshoots num_tx_queues.
Introduce a per-conduit queue map so those three call sites can
convert dp->index to a collision-free queue ID:
- mac->dsa_queue_base: queue index where this conduit's DSA user
ports start. Zeroth conduit uses MTK_MAX_DEVS (skipping the
queues reserved for non-DSA egress), later conduits start after
the previous conduit's user-port range.
- mac->dsa_port_rank[dp->index]: rank (0..N-1) of dp within its
switch's user-port sequence, so sparse dp->index layouts become
dense queue assignments.
mtk_update_dsa_queue_map() walks every conduit and rebuilds both.
It is called from the existing DSA user-port NETDEV_CHANGE notifier
so link-up of any DSA user port triggers a recompute. Initial
values at mac creation reproduce the old "queue = dp->index + 3"
layout, so behavior does not change until the next patches switch
call sites over.
MTK_DSA_USER_PORT_MAX is 32, comfortably covering the 16-port
MxL862xx; bump it if a larger switch needs per-port queuing.
This patch only adds infrastructure; no call sites are converted
yet so there is no functional change.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 56 ++++++++++++++++++++-
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 ++++
2 files changed, 65 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -3751,6 +3751,48 @@ static bool mtk_uses_dsa(struct net_devi
#endif
}
+/*
+ * Recompute the per-conduit DSA user-port queue map. Each conduit's mac
+ * gets a queue base (queues 0..MTK_MAX_DEVS-1 are reserved for non-DSA
+ * egress via GDM{1,2,3}), followed by a contiguous rank for every user
+ * port of the DSA switch attached to that conduit. dsa_port_rank[]
+ * translates dp->index (which may be non-contiguous and may collide
+ * across switches) into that rank.
+ *
+ * Call this on DSA topology changes. Idempotent.
+ */
+static void mtk_update_dsa_queue_map(struct mtk_eth *eth)
+{
+ struct net_device *conduit;
+ struct dsa_switch *ds;
+ struct mtk_mac *mac;
+ struct dsa_port *dp;
+ u8 base = MTK_MAX_DEVS;
+ u8 rank;
+ int i;
+
+ for (i = 0; i < MTK_MAX_DEVS; i++) {
+ conduit = eth->netdev[i];
+ if (!conduit)
+ continue;
+
+ mac = netdev_priv(conduit);
+ mac->dsa_queue_base = base;
+
+ if (!netdev_uses_dsa(conduit))
+ continue;
+
+ ds = conduit->dsa_ptr->ds;
+ rank = 0;
+ dsa_switch_for_each_user_port(dp, ds) {
+ if (dp->index < MTK_DSA_USER_PORT_MAX)
+ mac->dsa_port_rank[dp->index] = rank;
+ rank++;
+ }
+ base += rank;
+ }
+}
+
static int mtk_device_event(struct notifier_block *n, unsigned long event, void *ptr)
{
struct mtk_mac *mac = container_of(n, struct mtk_mac, device_notifier);
@@ -3775,6 +3817,8 @@ found:
if (!dsa_user_dev_check(dev))
return NOTIFY_DONE;
+ mtk_update_dsa_queue_map(eth);
+
if (__ethtool_get_link_ksettings(dev, &s))
return NOTIFY_DONE;
@@ -5055,7 +5099,7 @@ static int mtk_add_mac(struct mtk_eth *e
phy_interface_t phy_mode;
struct phylink *phylink;
struct mtk_mac *mac;
- int id, err, count;
+ int id, err, count, i;
int txqs = 1;
u32 val;
@@ -5089,6 +5133,16 @@ static int mtk_add_mac(struct mtk_eth *e
mac->hw = eth;
mac->of_node = np;
+ /*
+ * Initialize the DSA user-port queue map to an identity mapping
+ * starting at MTK_MAX_DEVS, so that a mac without any DSA switch
+ * attached keeps the historic "queue = dp->index + 3" layout.
+ * mtk_update_dsa_queue_map() rewrites this once DSA state is up.
+ */
+ mac->dsa_queue_base = MTK_MAX_DEVS;
+ for (i = 0; i < MTK_DSA_USER_PORT_MAX; i++)
+ mac->dsa_port_rank[i] = i;
+
memset(mac->hwlro_ip, 0, sizeof(mac->hwlro_ip));
mac->hwlro_ip_cnt = 0;
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -25,6 +25,14 @@
#define MTK_MAX_DSA_PORTS 7
#define MTK_DSA_PORT_MASK GENMASK(2, 0)
+/*
+ * Upper bound on dp->index across all DSA switches we support attaching
+ * to an MT7988 / MT7986 / MT7622 / MT7621 conduit. Sized to cover the
+ * 16-port MaxLinear MxL862xx with room to spare; increase when a larger
+ * switch needs per-port queue mapping.
+ */
+#define MTK_DSA_USER_PORT_MAX 32
+
#define MTK_QTX_PER_PAGE 16
#define MTK_QDMA_PAGE_SIZE 2048
#define MTK_MAX_RX_LENGTH 1536
@@ -1414,6 +1422,8 @@ struct mtk_mac {
int hwlro_ip_cnt;
unsigned int syscfg0;
struct notifier_block device_notifier;
+ u8 dsa_queue_base;
+ u8 dsa_port_rank[MTK_DSA_USER_PORT_MAX];
};
/* the struct describing the SoC. these are declared in the soc_xyz.c files */