mirror of
https://github.com/openwrt/openwrt.git
synced 2026-06-17 12:40:16 +04:00
627cd79e1c
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>
169 lines
5.6 KiB
Diff
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 */
|