generic: sync MediaTek Ethernet driver with upstream
authorDaniel Golle <daniel@makrotopia.org>
Sat, 26 Aug 2023 01:19:18 +0000 (02:19 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Mon, 28 Aug 2023 15:35:22 +0000 (16:35 +0100)
Import commits from upstream Linux replacing some downstream patches.
Move accepted patches from pending-{5.15,6.1} to backport-{5.15,6.1}.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
127 files changed:
target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/729-20-v6.3-net-ethernet-mtk_eth_soc-align-reset-procedure-to-ve.patch
target/linux/generic/backport-5.15/730-03-v6.3-net-ethernet-mtk_eth_soc-avoid-port_mg-assignment-on.patch
target/linux/generic/backport-5.15/730-06-v6.3-net-ethernet-mediatek-ppe-assign-per-port-queues-for.patch
target/linux/generic/backport-5.15/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch [deleted file]
target/linux/generic/backport-5.15/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch
target/linux/generic/backport-5.15/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch
target/linux/generic/backport-5.15/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch
target/linux/generic/backport-5.15/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch
target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch [deleted file]
target/linux/generic/backport-5.15/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch [deleted file]
target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch [deleted file]
target/linux/generic/backport-6.1/730-09-v6.3-net-ethernet-mtk_eth_soc-fix-VLAN-rx-hardware-accele.patch
target/linux/generic/backport-6.1/733-v6.2-12-net-mediatek-sgmii-ensure-the-SGMII-PHY-is-powered-d.patch
target/linux/generic/backport-6.1/733-v6.3-18-net-ethernet-mtk_eth_soc-add-support-for-MT7981.patch
target/linux/generic/backport-6.1/733-v6.3-20-net-ethernet-mtk_eth_soc-switch-to-external-PCS-driv.patch
target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/790-v6.4-0012-net-dsa-mt7530-introduce-driver-for-MT7988-built-in-.patch
target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch [new file with mode: 0644]
target/linux/generic/hack-5.15/795-backport-phylink_pcs-helpers.patch
target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch
target/linux/generic/pending-5.15/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch [deleted file]
target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch [new file with mode: 0644]
target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch [deleted file]
target/linux/generic/pending-5.15/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch
target/linux/generic/pending-5.15/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch
target/linux/generic/pending-5.15/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch
target/linux/generic/pending-5.15/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch
target/linux/generic/pending-5.15/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch
target/linux/generic/pending-5.15/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch
target/linux/generic/pending-5.15/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch
target/linux/generic/pending-5.15/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch
target/linux/generic/pending-5.15/736-05-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch [deleted file]
target/linux/generic/pending-5.15/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch [deleted file]
target/linux/generic/pending-5.15/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch [deleted file]
target/linux/generic/pending-5.15/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch [deleted file]
target/linux/generic/pending-5.15/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch [deleted file]
target/linux/generic/pending-5.15/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch [deleted file]
target/linux/generic/pending-5.15/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch [deleted file]
target/linux/generic/pending-5.15/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch [deleted file]
target/linux/generic/pending-5.15/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch [deleted file]
target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch [new file with mode: 0644]
target/linux/generic/pending-6.1/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch
target/linux/generic/pending-6.1/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch [deleted file]
target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch [new file with mode: 0644]
target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch [deleted file]
target/linux/generic/pending-6.1/732-01-net-ethernet-mtk_eth_soc-work-around-issue-with-send.patch
target/linux/generic/pending-6.1/732-02-net-ethernet-mtk_eth_soc-set-NETIF_F_ALL_TSO.patch
target/linux/generic/pending-6.1/732-03-net-ethernet-mtk_eth_soc-fix-remaining-throughput-re.patch
target/linux/generic/pending-6.1/734-net-ethernet-mtk_eth_soc-ppe-fix-L2-offloading-with-.patch
target/linux/generic/pending-6.1/736-01-net-ethernet-mtk_eth_soc-add-code-for-offloading-flo.patch
target/linux/generic/pending-6.1/736-02-net-ethernet-mediatek-mtk_ppe-prefer-newly-added-l2-.patch
target/linux/generic/pending-6.1/736-03-net-ethernet-mtk_eth_soc-improve-keeping-track-of-of.patch
target/linux/generic/pending-6.1/736-04-net-ethernet-mediatek-fix-ppe-flow-accounting-for-L2.patch
target/linux/generic/pending-6.1/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch [deleted file]
target/linux/generic/pending-6.1/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch [deleted file]
target/linux/generic/pending-6.1/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch [deleted file]
target/linux/generic/pending-6.1/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch [deleted file]
target/linux/generic/pending-6.1/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch [deleted file]
target/linux/generic/pending-6.1/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch [deleted file]
target/linux/generic/pending-6.1/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch [deleted file]
target/linux/generic/pending-6.1/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch [deleted file]
target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch [new file with mode: 0644]
target/linux/ipq40xx/patches-5.15/704-net-phy-define-PSGMII-PHY-interface-mode.patch
target/linux/layerscape/patches-5.15/702-phy-Add-2.5G-SGMII-interface-mode.patch
target/linux/mediatek/filogic/config-6.1
target/linux/mediatek/patches-5.15/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch
target/linux/mediatek/patches-5.15/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch
target/linux/mediatek/patches-6.1/731-net-phy-mediatek-ge-soc-initialize-MT7988-PHY-LEDs-d.patch [deleted file]
target/linux/mediatek/patches-6.1/731-v6.5-net-phy-mediatek-ge-soc-support-PHY-LEDs.patch [new file with mode: 0644]
target/linux/mediatek/patches-6.1/944-net-ethernet-mtk_wed-move-dlm-a-dedicated-dts-node.patch
target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch
target/linux/ramips/patches-5.15/720-Revert-net-phy-simplify-phy_link_change-arguments.patch
target/linux/realtek/patches-5.15/704-drivers-net-phy-eee-support-for-rtl838x.patch
target/linux/realtek/patches-5.15/704-include-linux-add-phy-hsgmii-mode.patch

diff --git a/target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch b/target/linux/generic/backport-5.15/728-v6.1-04-net-ethernet-mtk_eth_soc-fix-resource-leak-in-error-.patch
new file mode 100644 (file)
index 0000000..ae3acfe
--- /dev/null
@@ -0,0 +1,35 @@
+From 8110437e59616293228cd781c486d8495a61e36a Mon Sep 17 00:00:00 2001
+From: Yan Cangang <nalanzeyu@gmail.com>
+Date: Sun, 20 Nov 2022 13:52:58 +0800
+Subject: [PATCH] net: ethernet: mtk_eth_soc: fix resource leak in error path
+
+In mtk_probe(), when mtk_ppe_init() or mtk_eth_offload_init() failed,
+mtk_mdio_cleanup() isn't called. Fix it.
+
+Fixes: ba37b7caf1ed ("net: ethernet: mtk_eth_soc: add support for initializing the PPE")
+Fixes: 502e84e2382d ("net: ethernet: mtk_eth_soc: add flow offloading support")
+Signed-off-by: Yan Cangang <nalanzeyu@gmail.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4087,13 +4087,13 @@ static int mtk_probe(struct platform_dev
+                                                  eth->soc->offload_version, i);
+                       if (!eth->ppe[i]) {
+                               err = -ENOMEM;
+-                              goto err_free_dev;
++                              goto err_deinit_mdio;
+                       }
+               }
+               err = mtk_eth_offload_init(eth);
+               if (err)
+-                      goto err_free_dev;
++                      goto err_deinit_mdio;
+       }
+       for (i = 0; i < MTK_MAX_DEVS; i++) {
diff --git a/target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch b/target/linux/generic/backport-5.15/728-v6.1-05-net-ethernet-mtk_eth_soc-fix-memory-leak-in-error-pa.patch
new file mode 100644 (file)
index 0000000..b0f5723
--- /dev/null
@@ -0,0 +1,107 @@
+From 603ea5e7ffa73c7fac07d8713d97285990695213 Mon Sep 17 00:00:00 2001
+From: Yan Cangang <nalanzeyu@gmail.com>
+Date: Sun, 20 Nov 2022 13:52:59 +0800
+Subject: [PATCH] net: ethernet: mtk_eth_soc: fix memory leak in error path
+
+In mtk_ppe_init(), when dmam_alloc_coherent() or devm_kzalloc() failed,
+the rhashtable ppe->l2_flows isn't destroyed. Fix it.
+
+In mtk_probe(), when mtk_ppe_init() or mtk_eth_offload_init() or
+register_netdev() failed, have the same problem. Fix it.
+
+Fixes: 33fc42de3327 ("net: ethernet: mtk_eth_soc: support creating mac address based offload entries")
+Signed-off-by: Yan Cangang <nalanzeyu@gmail.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c |  9 +++++----
+ drivers/net/ethernet/mediatek/mtk_ppe.c     | 19 +++++++++++++++++--
+ drivers/net/ethernet/mediatek/mtk_ppe.h     |  1 +
+ 3 files changed, 23 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4087,13 +4087,13 @@ static int mtk_probe(struct platform_dev
+                                                  eth->soc->offload_version, i);
+                       if (!eth->ppe[i]) {
+                               err = -ENOMEM;
+-                              goto err_deinit_mdio;
++                              goto err_deinit_ppe;
+                       }
+               }
+               err = mtk_eth_offload_init(eth);
+               if (err)
+-                      goto err_deinit_mdio;
++                      goto err_deinit_ppe;
+       }
+       for (i = 0; i < MTK_MAX_DEVS; i++) {
+@@ -4103,7 +4103,7 @@ static int mtk_probe(struct platform_dev
+               err = register_netdev(eth->netdev[i]);
+               if (err) {
+                       dev_err(eth->dev, "error bringing up device\n");
+-                      goto err_deinit_mdio;
++                      goto err_deinit_ppe;
+               } else
+                       netif_info(eth, probe, eth->netdev[i],
+                                  "mediatek frame engine at 0x%08lx, irq %d\n",
+@@ -4123,7 +4123,8 @@ static int mtk_probe(struct platform_dev
+       return 0;
+-err_deinit_mdio:
++err_deinit_ppe:
++      mtk_ppe_deinit(eth);
+       mtk_mdio_cleanup(eth);
+ err_free_dev:
+       mtk_free_dev(eth);
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -743,7 +743,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
+                                 MTK_PPE_ENTRIES * soc->foe_entry_size,
+                                 &ppe->foe_phys, GFP_KERNEL);
+       if (!foe)
+-              return NULL;
++              goto err_free_l2_flows;
+       ppe->foe_table = foe;
+@@ -751,11 +751,26 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
+                       sizeof(*ppe->foe_flow);
+       ppe->foe_flow = devm_kzalloc(dev, foe_flow_size, GFP_KERNEL);
+       if (!ppe->foe_flow)
+-              return NULL;
++              goto err_free_l2_flows;
+       mtk_ppe_debugfs_init(ppe, index);
+       return ppe;
++
++err_free_l2_flows:
++      rhashtable_destroy(&ppe->l2_flows);
++      return NULL;
++}
++
++void mtk_ppe_deinit(struct mtk_eth *eth)
++{
++      int i;
++
++      for (i = 0; i < ARRAY_SIZE(eth->ppe); i++) {
++              if (!eth->ppe[i])
++                      return;
++              rhashtable_destroy(&eth->ppe[i]->l2_flows);
++      }
+ }
+ static void mtk_ppe_init_foe_table(struct mtk_ppe *ppe)
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -304,6 +304,7 @@ struct mtk_ppe {
+ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
+                            int version, int index);
++void mtk_ppe_deinit(struct mtk_eth *eth);
+ void mtk_ppe_start(struct mtk_ppe *ppe);
+ int mtk_ppe_stop(struct mtk_ppe *ppe);
index f87b4c9e5b1fb1fdc57430bb284f46824dccfb97..7dde9a54824d2c6cb50383e02a660fd6b6cb219a 100644 (file)
@@ -237,8 +237,8 @@ Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  {
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -306,6 +306,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
                           int version, int index);
+@@ -307,6 +307,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
void mtk_ppe_deinit(struct mtk_eth *eth);
  void mtk_ppe_start(struct mtk_ppe *ppe);
  int mtk_ppe_stop(struct mtk_ppe *ppe);
 +int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
index 1e1ac560db76910645bffd9fa00171652eab8cdf..af987c42e25a9565bc37eda385e68ee31e4f91cb 100644 (file)
@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4421,7 +4421,7 @@ static const struct mtk_soc_data mt7621_
+@@ -4422,7 +4422,7 @@ static const struct mtk_soc_data mt7621_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7621_CLKS_BITMAP,
        .required_pctl = false,
@@ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        .hash_offset = 2,
        .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
        .txrx = {
-@@ -4460,7 +4460,7 @@ static const struct mtk_soc_data mt7623_
+@@ -4461,7 +4461,7 @@ static const struct mtk_soc_data mt7623_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7623_CLKS_BITMAP,
        .required_pctl = true,
index 8935eb673ae56c071dc168ca87aa3391399f12f5..e05042c2047d0d917b2990942f3d183c5ac7c1d2 100644 (file)
@@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  #define MTK_FOE_IB2_DEST_PORT_V2      GENMASK(12, 9)
  #define MTK_FOE_IB2_MULTICAST_V2      BIT(13)
  #define MTK_FOE_IB2_WDMA_WINFO_V2     BIT(19)
-@@ -351,6 +353,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e
+@@ -352,6 +354,8 @@ int mtk_foe_entry_set_pppoe(struct mtk_e
                            int sid);
  int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
                           int wdma_idx, int txq, int bss, int wcid);
diff --git a/target/linux/generic/backport-5.15/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/backport-5.15/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch
deleted file mode 100644 (file)
index 44af912..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 27 Oct 2022 23:39:52 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code
- on mt7621
-
-Avoid some branches in the hot path on low-end devices with limited CPU power,
-and reduce code size
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -917,7 +917,13 @@ enum mkt_eth_capabilities {
- #define MTK_MUX_GMAC12_TO_GEPHY_SGMII   \
-       (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
--#define MTK_HAS_CAPS(caps, _x)                (((caps) & (_x)) == (_x))
-+#ifdef CONFIG_SOC_MT7621
-+#define MTK_CAP_MASK MTK_NETSYS_V2
-+#else
-+#define MTK_CAP_MASK 0
-+#endif
-+
-+#define MTK_HAS_CAPS(caps, _x)                (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x))
- #define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
-                     MTK_GMAC2_RGMII | MTK_SHARED_INT | \
index 6ebd1abcd0f20ba6125d9270fb516cee4f327727..f9d822ad447bb67a2316288492acb460213bc60d 100644 (file)
@@ -181,7 +181,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  /* CDMP Ingress Control Register */
  #define MTK_CDMP_IG_CTRL      0x400
  #define MTK_CDMP_STAG_EN      BIT(0)
-@@ -1166,6 +1172,8 @@ struct mtk_eth {
+@@ -1160,6 +1166,8 @@ struct mtk_eth {
  
        int                             ip_align;
  
index 8d2991f450013b7fe7af03af1c0d66186db61408..598788d99846bf6ecb86dcfa34f61e709e790962 100644 (file)
@@ -34,7 +34,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1070,11 +1070,13 @@ struct mtk_soc_data {
+@@ -1064,11 +1064,13 @@ struct mtk_soc_data {
   * @regmap:            The register map pointing at the range used to setup
   *                     SGMII modes
   * @ana_rgc3:          The offset refers to register ANA_RGC3 related to regmap
index 36fa94a790533e027ff1b999b075ad8f4fff94a8..1ae4e83363232ef7227c944cc80f5cb3fe147734 100644 (file)
@@ -51,7 +51,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
                mtk_eth_path_name(path), __func__, updated);
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4748,6 +4748,26 @@ static const struct mtk_soc_data mt7629_
+@@ -4749,6 +4749,26 @@ static const struct mtk_soc_data mt7629_
        },
  };
  
@@ -78,7 +78,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  static const struct mtk_soc_data mt7986_data = {
        .reg_map = &mt7986_reg_map,
        .ana_rgc3 = 0x128,
-@@ -4790,6 +4810,7 @@ const struct of_device_id of_mtk_match[]
+@@ -4791,6 +4811,7 @@ const struct of_device_id of_mtk_match[]
        { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
        { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
        { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
@@ -145,7 +145,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  
  #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
        BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-@@ -963,6 +987,11 @@ enum mkt_eth_capabilities {
+@@ -957,6 +981,11 @@ enum mkt_eth_capabilities {
                      MTK_MUX_U3_GMAC2_TO_QPHY | \
                      MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
  
@@ -157,7 +157,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  #define MT7986_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
                      MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
                      MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-@@ -1076,12 +1105,14 @@ struct mtk_soc_data {
+@@ -1070,12 +1099,14 @@ struct mtk_soc_data {
   * @ana_rgc3:          The offset refers to register ANA_RGC3 related to regmap
   * @interface:         Currently configured interface mode
   * @pcs:               Phylink PCS structure
index 2e6a70d7255e164a7a1c47f1939e8ce9d2d4e5d8..42a700d543921906498d792a373638ac681fff49 100644 (file)
@@ -151,7 +151,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        }
  
        if (eth->soc->offload_version) {
-@@ -4648,6 +4685,8 @@ err_deinit_hw:
+@@ -4649,6 +4686,8 @@ err_deinit_hw:
        mtk_hw_deinit(eth);
  err_wed_exit:
        mtk_wed_exit();
@@ -228,7 +228,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  /* Infrasys subsystem config registers */
  #define INFRA_MISC2            0x70c
  #define CO_QPHY_SEL            BIT(0)
-@@ -1105,31 +1046,6 @@ struct mtk_soc_data {
+@@ -1099,31 +1040,6 @@ struct mtk_soc_data {
  /* currently no SoC has more than 2 macs */
  #define MTK_MAX_DEVS                  2
  
@@ -260,7 +260,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  /* struct mtk_eth -   This is the main datasructure for holding the state
   *                    of the driver
   * @dev:              The device pointer
-@@ -1149,6 +1065,7 @@ struct mtk_sgmii {
+@@ -1143,6 +1059,7 @@ struct mtk_sgmii {
   *                    MII modes
   * @infra:              The register map pointing at the range used to setup
   *                      SGMII and GePHY path
@@ -268,7 +268,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
   * @pctl:             The register map pointing at the range used to setup
   *                    GMAC port drive/slew values
   * @dma_refcnt:               track how many netdevs are using the DMA engine
-@@ -1189,8 +1106,8 @@ struct mtk_eth {
+@@ -1183,8 +1100,8 @@ struct mtk_eth {
        u32                             msg_enable;
        unsigned long                   sysclk;
        struct regmap                   *ethsys;
@@ -279,7 +279,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        struct regmap                   *pctl;
        bool                            hwlro;
        refcount_t                      dma_refcnt;
-@@ -1352,10 +1269,6 @@ void mtk_stats_update_mac(struct mtk_mac
+@@ -1346,10 +1263,6 @@ void mtk_stats_update_mac(struct mtk_mac
  void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
  u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
  
diff --git a/target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch b/target/linux/generic/backport-5.15/733-v6.3-21-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch
new file mode 100644 (file)
index 0000000..7742b09
--- /dev/null
@@ -0,0 +1,21 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 23 Mar 2023 11:19:14 +0100
+Subject: [PATCH] net: ethernet: mtk_eth_soc: add missing ppe cache flush when
+ deleting a flow
+
+The cache needs to be flushed to ensure that the hardware stops offloading
+the flow immediately.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -464,6 +464,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
+               hwe->ib1 &= ~MTK_FOE_IB1_STATE;
+               hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
+               dma_wmb();
++              mtk_ppe_cache_clear(ppe);
+       }
+       entry->hash = 0xffff;
diff --git a/target/linux/generic/backport-5.15/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch b/target/linux/generic/backport-5.15/733-v6.4-21-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch
deleted file mode 100644 (file)
index 9ce2735..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-From f5af7931d2a2cae66d0f9dad4ba517b1b00620b3 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 19 Apr 2023 19:07:23 +0100
-Subject: [PATCH] net: mtk_eth_soc: use WO firmware for MT7981
-
-In order to support wireless offloading on MT7981 we need to load the
-appropriate firmware. Recognize MT7981 and load mt7981_wo.bin.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 7 ++++++-
- drivers/net/ethernet/mediatek/mtk_wed_wo.h  | 1 +
- 2 files changed, 7 insertions(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
-@@ -326,7 +326,11 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
-               wo->hw->index + 1);
-       /* load firmware */
--      fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
-+      if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed"))
-+              fw_name = MT7981_FIRMWARE_WO;
-+      else
-+              fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
-+
-       ret = request_firmware(&fw, fw_name, wo->hw->dev);
-       if (ret)
-               return ret;
-@@ -386,5 +390,6 @@ int mtk_wed_mcu_init(struct mtk_wed_wo *
-                                 100, MTK_FW_DL_TIMEOUT);
- }
-+MODULE_FIRMWARE(MT7981_FIRMWARE_WO);
- MODULE_FIRMWARE(MT7986_FIRMWARE_WO0);
- MODULE_FIRMWARE(MT7986_FIRMWARE_WO1);
---- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-+++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
-@@ -88,6 +88,7 @@ enum mtk_wed_dummy_cr_idx {
-       MTK_WED_DUMMY_CR_WO_STATUS,
- };
-+#define MT7981_FIRMWARE_WO    "mediatek/mt7981_wo.bin"
- #define MT7986_FIRMWARE_WO0   "mediatek/mt7986_wo_0.bin"
- #define MT7986_FIRMWARE_WO1   "mediatek/mt7986_wo_1.bin"
diff --git a/target/linux/generic/backport-5.15/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch b/target/linux/generic/backport-5.15/733-v6.4-22-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch
deleted file mode 100644 (file)
index d715c4a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From 7c83e28f10830aa5105c25eaabe890e3adac36aa Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 9 May 2023 03:20:06 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: fix NULL pointer dereference
-
-Check for NULL pointer to avoid kernel crashing in case of missing WO
-firmware in case only a single WEDv2 device has been initialized, e.g. on
-MT7981 which can connect just one wireless frontend.
-
-Fixes: 86ce0d09e424 ("net: ethernet: mtk_eth_soc: use WO firmware for MT7981")
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
-Reviewed-by: Simon Horman <simon.horman@corigine.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/mediatek/mtk_wed.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_wed.c
-+++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -647,7 +647,7 @@ __mtk_wed_detach(struct mtk_wed_device *
-                                          BIT(hw->index), BIT(hw->index));
-       }
--      if (!hw_list[!hw->index]->wed_dev &&
-+      if ((!hw_list[!hw->index] || !hw_list[!hw->index]->wed_dev) &&
-           hw->eth->dma_dev != hw->eth->dev)
-               mtk_eth_set_dma_device(hw->eth, hw->eth->dev);
diff --git a/target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch b/target/linux/generic/backport-5.15/733-v6.4-22-net-mtk_eth_soc-use-WO-firmware-for-MT7981.patch
new file mode 100644 (file)
index 0000000..9ce2735
--- /dev/null
@@ -0,0 +1,46 @@
+From f5af7931d2a2cae66d0f9dad4ba517b1b00620b3 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 19 Apr 2023 19:07:23 +0100
+Subject: [PATCH] net: mtk_eth_soc: use WO firmware for MT7981
+
+In order to support wireless offloading on MT7981 we need to load the
+appropriate firmware. Recognize MT7981 and load mt7981_wo.bin.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/ethernet/mediatek/mtk_wed_mcu.c | 7 ++++++-
+ drivers/net/ethernet/mediatek/mtk_wed_wo.h  | 1 +
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed_mcu.c
+@@ -326,7 +326,11 @@ mtk_wed_mcu_load_firmware(struct mtk_wed
+               wo->hw->index + 1);
+       /* load firmware */
+-      fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
++      if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed"))
++              fw_name = MT7981_FIRMWARE_WO;
++      else
++              fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
++
+       ret = request_firmware(&fw, fw_name, wo->hw->dev);
+       if (ret)
+               return ret;
+@@ -386,5 +390,6 @@ int mtk_wed_mcu_init(struct mtk_wed_wo *
+                                 100, MTK_FW_DL_TIMEOUT);
+ }
++MODULE_FIRMWARE(MT7981_FIRMWARE_WO);
+ MODULE_FIRMWARE(MT7986_FIRMWARE_WO0);
+ MODULE_FIRMWARE(MT7986_FIRMWARE_WO1);
+--- a/drivers/net/ethernet/mediatek/mtk_wed_wo.h
++++ b/drivers/net/ethernet/mediatek/mtk_wed_wo.h
+@@ -88,6 +88,7 @@ enum mtk_wed_dummy_cr_idx {
+       MTK_WED_DUMMY_CR_WO_STATUS,
+ };
++#define MT7981_FIRMWARE_WO    "mediatek/mt7981_wo.bin"
+ #define MT7986_FIRMWARE_WO0   "mediatek/mt7986_wo_0.bin"
+ #define MT7986_FIRMWARE_WO1   "mediatek/mt7986_wo_1.bin"
diff --git a/target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch b/target/linux/generic/backport-5.15/733-v6.4-23-net-ethernet-mtk_eth_soc-fix-NULL-pointer-dereferenc.patch
new file mode 100644 (file)
index 0000000..d715c4a
--- /dev/null
@@ -0,0 +1,28 @@
+From 7c83e28f10830aa5105c25eaabe890e3adac36aa Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 9 May 2023 03:20:06 +0200
+Subject: [PATCH] net: ethernet: mtk_eth_soc: fix NULL pointer dereference
+
+Check for NULL pointer to avoid kernel crashing in case of missing WO
+firmware in case only a single WEDv2 device has been initialized, e.g. on
+MT7981 which can connect just one wireless frontend.
+
+Fixes: 86ce0d09e424 ("net: ethernet: mtk_eth_soc: use WO firmware for MT7981")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_wed.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -647,7 +647,7 @@ __mtk_wed_detach(struct mtk_wed_device *
+                                          BIT(hw->index), BIT(hw->index));
+       }
+-      if (!hw_list[!hw->index]->wed_dev &&
++      if ((!hw_list[!hw->index] || !hw_list[!hw->index]->wed_dev) &&
+           hw->eth->dma_dev != hw->eth->dev)
+               mtk_eth_set_dma_device(hw->eth, hw->eth->dev);
diff --git a/target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch b/target/linux/generic/backport-5.15/733-v6.4-24-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch
new file mode 100644 (file)
index 0000000..51ebcfe
--- /dev/null
@@ -0,0 +1,428 @@
+From patchwork Wed Nov  2 00:58:01 2022
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
+X-Patchwork-Id: 13027653
+X-Patchwork-Delegate: kuba@kernel.org
+Return-Path: <netdev-owner@kernel.org>
+Date: Wed, 2 Nov 2022 00:58:01 +0000
+From: Daniel Golle <daniel@makrotopia.org>
+To: Felix Fietkau <nbd@nbd.name>, John Crispin <john@phrozen.org>,
+        Sean Wang <sean.wang@mediatek.com>,
+        Mark Lee <Mark-MC.Lee@mediatek.com>,
+        "David S. Miller" <davem@davemloft.net>,
+        Eric Dumazet <edumazet@google.com>,
+        Jakub Kicinski <kuba@kernel.org>,
+        Paolo Abeni <pabeni@redhat.com>,
+        Matthias Brugger <matthias.bgg@gmail.com>,
+        netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
+        linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org
+Subject: [PATCH v4] net: ethernet: mediatek: ppe: add support for flow
+ accounting
+Message-ID: <Y2HAmYYPd77dz+K5@makrotopia.org>
+MIME-Version: 1.0
+Content-Disposition: inline
+Precedence: bulk
+List-ID: <netdev.vger.kernel.org>
+X-Mailing-List: netdev@vger.kernel.org
+X-Patchwork-Delegate: kuba@kernel.org
+
+The PPE units found in MT7622 and newer support packet and byte
+accounting of hw-offloaded flows. Add support for reading those
+counters as found in MediaTek's SDK[1].
+
+[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/bc6a6a375c800dc2b80e1a325a2c732d1737df92
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+v4: declare function mtk_mib_entry_read as static
+v3: don't bother to set 'false' values in any zero-initialized struct
+    use mtk_foe_entry_ib2
+    both changes were requested by Felix Fietkau
+
+v2: fix wrong variable name in return value check spotted by Denis Kirjanov
+
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c   |   7 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h   |   1 +
+ drivers/net/ethernet/mediatek/mtk_ppe.c       | 110 +++++++++++++++++-
+ drivers/net/ethernet/mediatek/mtk_ppe.h       |  23 +++-
+ .../net/ethernet/mediatek/mtk_ppe_debugfs.c   |   9 +-
+ .../net/ethernet/mediatek/mtk_ppe_offload.c   |   7 ++
+ drivers/net/ethernet/mediatek/mtk_ppe_regs.h  |  14 +++
+ 7 files changed, 166 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4635,8 +4635,8 @@ static int mtk_probe(struct platform_dev
+               for (i = 0; i < num_ppe; i++) {
+                       u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
+-                      eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr,
+-                                                 eth->soc->offload_version, i);
++                      eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
++
+                       if (!eth->ppe[i]) {
+                               err = -ENOMEM;
+                               goto err_deinit_ppe;
+@@ -4762,6 +4762,7 @@ static const struct mtk_soc_data mt7622_
+       .required_pctl = false,
+       .offload_version = 2,
+       .hash_offset = 2,
++      .has_accounting = true,
+       .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+@@ -4799,6 +4800,7 @@ static const struct mtk_soc_data mt7629_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7629_CLKS_BITMAP,
+       .required_pctl = false,
++      .has_accounting = true,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+@@ -4819,6 +4821,7 @@ static const struct mtk_soc_data mt7981_
+       .offload_version = 2,
+       .hash_offset = 4,
+       .foe_entry_size = sizeof(struct mtk_foe_entry),
++      .has_accounting = true,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma_v2),
+               .rxd_size = sizeof(struct mtk_rx_dma_v2),
+@@ -4839,6 +4842,7 @@ static const struct mtk_soc_data mt7986_
+       .offload_version = 2,
+       .hash_offset = 4,
+       .foe_entry_size = sizeof(struct mtk_foe_entry),
++      .has_accounting = true,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma_v2),
+               .rxd_size = sizeof(struct mtk_rx_dma_v2),
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1008,6 +1008,8 @@ struct mtk_reg_map {
+  *                            the extra setup for those pins used by GMAC.
+  * @hash_offset                       Flow table hash offset.
+  * @foe_entry_size            Foe table entry size.
++ * @has_accounting            Bool indicating support for accounting of
++ *                            offloaded flows.
+  * @txd_size                  Tx DMA descriptor size.
+  * @rxd_size                  Rx DMA descriptor size.
+  * @rx_irq_done_mask          Rx irq done register mask.
+@@ -1025,6 +1027,7 @@ struct mtk_soc_data {
+       u8              hash_offset;
+       u16             foe_entry_size;
+       netdev_features_t hw_features;
++      bool            has_accounting;
+       struct {
+               u32     txd_size;
+               u32     rxd_size;
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -74,6 +74,48 @@ static int mtk_ppe_wait_busy(struct mtk_
+       return ret;
+ }
++static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe)
++{
++      int ret;
++      u32 val;
++
++      ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val,
++                               !(val & MTK_PPE_MIB_SER_CR_ST),
++                               20, MTK_PPE_WAIT_TIMEOUT_US);
++
++      if (ret)
++              dev_err(ppe->dev, "MIB table busy");
++
++      return ret;
++}
++
++static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
++{
++      u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
++      u32 val, cnt_r0, cnt_r1, cnt_r2;
++      int ret;
++
++      val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST;
++      ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val);
++
++      ret = mtk_ppe_mib_wait_busy(ppe);
++      if (ret)
++              return ret;
++
++      cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0);
++      cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
++      cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
++
++      byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
++      byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
++      pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
++      pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
++      *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
++      *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
++
++      return 0;
++}
++
+ static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
+ {
+       ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR);
+@@ -465,6 +507,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
+               hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
+               dma_wmb();
+               mtk_ppe_cache_clear(ppe);
++              if (ppe->accounting) {
++                      struct mtk_foe_accounting *acct;
++
++                      acct = ppe->acct_table + entry->hash * sizeof(*acct);
++                      acct->packets = 0;
++                      acct->bytes = 0;
++              }
+       }
+       entry->hash = 0xffff;
+@@ -572,6 +621,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+       wmb();
+       hwe->ib1 = entry->ib1;
++      if (ppe->accounting)
++              *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
++
+       dma_wmb();
+       mtk_ppe_cache_clear(ppe);
+@@ -763,11 +815,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
+       return mtk_ppe_wait_busy(ppe);
+ }
+-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
+-                           int version, int index)
++struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
++                                               struct mtk_foe_accounting *diff)
++{
++      struct mtk_foe_accounting *acct;
++      int size = sizeof(struct mtk_foe_accounting);
++      u64 bytes, packets;
++
++      if (!ppe->accounting)
++              return NULL;
++
++      if (mtk_mib_entry_read(ppe, index, &bytes, &packets))
++              return NULL;
++
++      acct = ppe->acct_table + index * size;
++
++      acct->bytes += bytes;
++      acct->packets += packets;
++
++      if (diff) {
++              diff->bytes = bytes;
++              diff->packets = packets;
++      }
++
++      return acct;
++}
++
++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
+ {
++      bool accounting = eth->soc->has_accounting;
+       const struct mtk_soc_data *soc = eth->soc;
++      struct mtk_foe_accounting *acct;
+       struct device *dev = eth->dev;
++      struct mtk_mib_entry *mib;
+       struct mtk_ppe *ppe;
+       u32 foe_flow_size;
+       void *foe;
+@@ -784,7 +864,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
+       ppe->base = base;
+       ppe->eth = eth;
+       ppe->dev = dev;
+-      ppe->version = version;
++      ppe->version = eth->soc->offload_version;
++      ppe->accounting = accounting;
+       foe = dmam_alloc_coherent(ppe->dev,
+                                 MTK_PPE_ENTRIES * soc->foe_entry_size,
+@@ -800,6 +881,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
+       if (!ppe->foe_flow)
+               goto err_free_l2_flows;
++      if (accounting) {
++              mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib),
++                                        &ppe->mib_phys, GFP_KERNEL);
++              if (!mib)
++                      return NULL;
++
++              ppe->mib_table = mib;
++
++              acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct),
++                                  GFP_KERNEL);
++
++              if (!acct)
++                      return NULL;
++
++              ppe->acct_table = acct;
++      }
++
+       mtk_ppe_debugfs_init(ppe, index);
+       return ppe;
+@@ -929,6 +1027,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
+               ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
+               ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
+       }
++
++      if (ppe->accounting && ppe->mib_phys) {
++              ppe_w32(ppe, MTK_PPE_MIB_TB_BASE, ppe->mib_phys);
++              ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_EN,
++                      MTK_PPE_MIB_CFG_EN);
++              ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_RD_CLR,
++                      MTK_PPE_MIB_CFG_RD_CLR);
++              ppe_m32(ppe, MTK_PPE_MIB_CACHE_CTL, MTK_PPE_MIB_CACHE_CTL_EN,
++                      MTK_PPE_MIB_CFG_RD_CLR);
++      }
+ }
+ int mtk_ppe_stop(struct mtk_ppe *ppe)
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -57,6 +57,7 @@ enum {
+ #define MTK_FOE_IB2_MULTICAST         BIT(8)
+ #define MTK_FOE_IB2_WDMA_QID2         GENMASK(13, 12)
++#define MTK_FOE_IB2_MIB_CNT           BIT(15)
+ #define MTK_FOE_IB2_WDMA_DEVIDX               BIT(16)
+ #define MTK_FOE_IB2_WDMA_WINFO                BIT(17)
+@@ -285,16 +286,34 @@ struct mtk_flow_entry {
+       unsigned long cookie;
+ };
++struct mtk_mib_entry {
++      u32     byt_cnt_l;
++      u16     byt_cnt_h;
++      u32     pkt_cnt_l;
++      u8      pkt_cnt_h;
++      u8      _rsv0;
++      u32     _rsv1;
++} __packed;
++
++struct mtk_foe_accounting {
++      u64     bytes;
++      u64     packets;
++};
++
+ struct mtk_ppe {
+       struct mtk_eth *eth;
+       struct device *dev;
+       void __iomem *base;
+       int version;
+       char dirname[5];
++      bool accounting;
+       void *foe_table;
+       dma_addr_t foe_phys;
++      struct mtk_mib_entry *mib_table;
++      dma_addr_t mib_phys;
++
+       u16 foe_check_time[MTK_PPE_ENTRIES];
+       struct hlist_head *foe_flow;
+@@ -303,8 +322,7 @@ struct mtk_ppe {
+       void *acct_table;
+ };
+-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
+-                           int version, int index);
++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
+ void mtk_ppe_deinit(struct mtk_eth *eth);
+ void mtk_ppe_start(struct mtk_ppe *ppe);
+ int mtk_ppe_stop(struct mtk_ppe *ppe);
+@@ -359,5 +377,7 @@ int mtk_foe_entry_commit(struct mtk_ppe
+ void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
+ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
+ int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
++struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
++                                               struct mtk_foe_accounting *diff);
+ #endif
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
+@@ -82,6 +82,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
+               struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
+               struct mtk_foe_mac_info *l2;
+               struct mtk_flow_addr_info ai = {};
++              struct mtk_foe_accounting *acct;
+               unsigned char h_source[ETH_ALEN];
+               unsigned char h_dest[ETH_ALEN];
+               int type, state;
+@@ -95,6 +96,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file
+               if (bind && state != MTK_FOE_STATE_BIND)
+                       continue;
++              acct = mtk_foe_entry_get_mib(ppe, i, NULL);
++
+               type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
+               seq_printf(m, "%05x %s %7s", i,
+                          mtk_foe_entry_state_str(state),
+@@ -153,9 +156,11 @@ mtk_ppe_debugfs_foe_show(struct seq_file
+               *((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo);
+               seq_printf(m, " eth=%pM->%pM etype=%04x"
+-                            " vlan=%d,%d ib1=%08x ib2=%08x\n",
++                            " vlan=%d,%d ib1=%08x ib2=%08x"
++                            " packets=%llu bytes=%llu\n",
+                          h_source, h_dest, ntohs(l2->etype),
+-                         l2->vlan1, l2->vlan2, entry->ib1, ib2);
++                         l2->vlan1, l2->vlan2, entry->ib1, ib2,
++                         acct ? acct->packets : 0, acct ? acct->bytes : 0);
+       }
+       return 0;
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+@@ -497,6 +497,7 @@ static int
+ mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
+ {
+       struct mtk_flow_entry *entry;
++      struct mtk_foe_accounting diff;
+       u32 idle;
+       entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
+@@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *e
+       idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
+       f->stats.lastused = jiffies - idle * HZ;
++      if (entry->hash != 0xFFFF &&
++          mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash,
++                                &diff)) {
++              f->stats.pkts += diff.packets;
++              f->stats.bytes += diff.bytes;
++      }
++
+       return 0;
+ }
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
+@@ -149,6 +149,20 @@ enum {
+ #define MTK_PPE_MIB_TB_BASE                   0x338
++#define MTK_PPE_MIB_SER_CR                    0x33C
++#define MTK_PPE_MIB_SER_CR_ST                 BIT(16)
++#define MTK_PPE_MIB_SER_CR_ADDR                       GENMASK(13, 0)
++
++#define MTK_PPE_MIB_SER_R0                    0x340
++#define MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW               GENMASK(31, 0)
++
++#define MTK_PPE_MIB_SER_R1                    0x344
++#define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW                GENMASK(31, 16)
++#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH      GENMASK(15, 0)
++
++#define MTK_PPE_MIB_SER_R2                    0x348
++#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH               GENMASK(23, 0)
++
+ #define MTK_PPE_MIB_CACHE_CTL                 0x350
+ #define MTK_PPE_MIB_CACHE_CTL_EN              BIT(0)
+ #define MTK_PPE_MIB_CACHE_CTL_FLUSH           BIT(2)
diff --git a/target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch b/target/linux/generic/backport-5.15/733-v6.4-25-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch
new file mode 100644 (file)
index 0000000..3a02c3a
--- /dev/null
@@ -0,0 +1,51 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 23 Mar 2023 21:45:43 +0100
+Subject: [PATCH] net: ethernet: mediatek: fix ppe flow accounting for v1
+ hardware
+
+Older chips (like MT7622) use a different bit in ib2 to enable hardware
+counter support.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -605,6 +605,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+       struct mtk_eth *eth = ppe->eth;
+       u16 timestamp = mtk_eth_timestamp(eth);
+       struct mtk_foe_entry *hwe;
++      u32 val;
+       if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+               entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
+@@ -621,8 +622,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+       wmb();
+       hwe->ib1 = entry->ib1;
+-      if (ppe->accounting)
+-              *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
++      if (ppe->accounting) {
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++                      val = MTK_FOE_IB2_MIB_CNT_V2;
++              else
++                      val = MTK_FOE_IB2_MIB_CNT;
++              *mtk_foe_entry_ib2(eth, hwe) |= val;
++      }
+       dma_wmb();
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -55,9 +55,10 @@ enum {
+ #define MTK_FOE_IB2_PSE_QOS           BIT(4)
+ #define MTK_FOE_IB2_DEST_PORT         GENMASK(7, 5)
+ #define MTK_FOE_IB2_MULTICAST         BIT(8)
++#define MTK_FOE_IB2_MIB_CNT           BIT(10)
+ #define MTK_FOE_IB2_WDMA_QID2         GENMASK(13, 12)
+-#define MTK_FOE_IB2_MIB_CNT           BIT(15)
++#define MTK_FOE_IB2_MIB_CNT_V2                BIT(15)
+ #define MTK_FOE_IB2_WDMA_DEVIDX               BIT(16)
+ #define MTK_FOE_IB2_WDMA_WINFO                BIT(17)
diff --git a/target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/backport-5.15/733-v6.4-26-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch
new file mode 100644 (file)
index 0000000..f6c70e7
--- /dev/null
@@ -0,0 +1,201 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sun, 20 Nov 2022 23:01:00 +0100
+Subject: [PATCH] net: ethernet: mtk_eth_soc: drop generic vlan rx offload,
+ only use DSA untagging
+
+Through testing I found out that hardware vlan rx offload support seems to
+have some hardware issues. At least when using multiple MACs and when receiving
+tagged packets on the secondary MAC, the hardware can sometimes start to emit
+wrong tags on the first MAC as well.
+
+In order to avoid such issues, drop the feature configuration and use the
+offload feature only for DSA hardware untagging on MT7621/MT7622 devices which
+only use one MAC.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1850,9 +1850,7 @@ static int mtk_poll_rx(struct napi_struc
+       while (done < budget) {
+               unsigned int pktlen, *rxdcsum;
+-              bool has_hwaccel_tag = false;
+               struct net_device *netdev;
+-              u16 vlan_proto, vlan_tci;
+               dma_addr_t dma_addr;
+               u32 hash, reason;
+               int mac = 0;
+@@ -1987,36 +1985,21 @@ static int mtk_poll_rx(struct napi_struc
+                       skb_checksum_none_assert(skb);
+               skb->protocol = eth_type_trans(skb, netdev);
+-              if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
+-                      mtk_ppe_check_skb(eth->ppe[0], skb, hash);
+-
+-              if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
+-                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+-                              if (trxd.rxd3 & RX_DMA_VTAG_V2) {
+-                                      vlan_proto = RX_DMA_VPID(trxd.rxd4);
+-                                      vlan_tci = RX_DMA_VID(trxd.rxd4);
+-                                      has_hwaccel_tag = true;
+-                              }
+-                      } else if (trxd.rxd2 & RX_DMA_VTAG) {
+-                              vlan_proto = RX_DMA_VPID(trxd.rxd3);
+-                              vlan_tci = RX_DMA_VID(trxd.rxd3);
+-                              has_hwaccel_tag = true;
+-                      }
+-              }
+-
+               /* When using VLAN untagging in combination with DSA, the
+                * hardware treats the MTK special tag as a VLAN and untags it.
+                */
+-              if (has_hwaccel_tag && netdev_uses_dsa(netdev)) {
+-                      unsigned int port = vlan_proto & GENMASK(2, 0);
++              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
++                  (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
++                      unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
+                       if (port < ARRAY_SIZE(eth->dsa_meta) &&
+                           eth->dsa_meta[port])
+                               skb_dst_set_noref(skb, &eth->dsa_meta[port]->dst);
+-              } else if (has_hwaccel_tag) {
+-                      __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci);
+               }
++              if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
++                      mtk_ppe_check_skb(eth->ppe[0], skb, hash);
++
+               skb_record_rx_queue(skb, 0);
+               napi_gro_receive(napi, skb);
+@@ -2831,29 +2814,11 @@ static netdev_features_t mtk_fix_feature
+ static int mtk_set_features(struct net_device *dev, netdev_features_t features)
+ {
+-      struct mtk_mac *mac = netdev_priv(dev);
+-      struct mtk_eth *eth = mac->hw;
+       netdev_features_t diff = dev->features ^ features;
+-      int i;
+       if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO))
+               mtk_hwlro_netdev_disable(dev);
+-      /* Set RX VLAN offloading */
+-      if (!(diff & NETIF_F_HW_VLAN_CTAG_RX))
+-              return 0;
+-
+-      mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX),
+-              MTK_CDMP_EG_CTRL);
+-
+-      /* sync features with other MAC */
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
+-              if (!eth->netdev[i] || eth->netdev[i] == dev)
+-                      continue;
+-              eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
+-              eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX;
+-      }
+-
+       return 0;
+ }
+@@ -3167,30 +3132,6 @@ static int mtk_open(struct net_device *d
+       struct mtk_eth *eth = mac->hw;
+       int i, err;
+-      if (mtk_uses_dsa(dev) && !eth->prog) {
+-              for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
+-                      struct metadata_dst *md_dst = eth->dsa_meta[i];
+-
+-                      if (md_dst)
+-                              continue;
+-
+-                      md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
+-                                                  GFP_KERNEL);
+-                      if (!md_dst)
+-                              return -ENOMEM;
+-
+-                      md_dst->u.port_info.port_id = i;
+-                      eth->dsa_meta[i] = md_dst;
+-              }
+-      } else {
+-              /* Hardware special tag parsing needs to be disabled if at least
+-               * one MAC does not use DSA.
+-               */
+-              u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
+-              val &= ~MTK_CDMP_STAG_EN;
+-              mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
+-      }
+-
+       err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
+       if (err) {
+               netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
+@@ -3231,6 +3172,35 @@ static int mtk_open(struct net_device *d
+       phylink_start(mac->phylink);
+       netif_tx_start_all_queues(dev);
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++              return 0;
++
++      if (mtk_uses_dsa(dev) && !eth->prog) {
++              for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
++                      struct metadata_dst *md_dst = eth->dsa_meta[i];
++
++                      if (md_dst)
++                              continue;
++
++                      md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
++                                                  GFP_KERNEL);
++                      if (!md_dst)
++                              return -ENOMEM;
++
++                      md_dst->u.port_info.port_id = i;
++                      eth->dsa_meta[i] = md_dst;
++              }
++      } else {
++              /* Hardware special tag parsing needs to be disabled if at least
++               * one MAC does not use DSA.
++               */
++              u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
++              val &= ~MTK_CDMP_STAG_EN;
++              mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
++
++              mtk_w32(eth, 0, MTK_CDMP_EG_CTRL);
++      }
++
+       return 0;
+ }
+@@ -3715,10 +3685,9 @@ static int mtk_hw_init(struct mtk_eth *e
+       if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+               val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
+               mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
+-      }
+-      /* Enable RX VLan Offloading */
+-      mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
++              mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
++      }
+       /* set interrupt delays based on current Net DIM sample */
+       mtk_dim_rx(&eth->rx_dim.work);
+@@ -4358,7 +4327,7 @@ static int mtk_add_mac(struct mtk_eth *e
+               eth->netdev[id]->hw_features |= NETIF_F_LRO;
+       eth->netdev[id]->vlan_features = eth->soc->hw_features &
+-              ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
++              ~NETIF_F_HW_VLAN_CTAG_TX;
+       eth->netdev[id]->features |= eth->soc->hw_features;
+       eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -48,7 +48,6 @@
+ #define MTK_HW_FEATURES               (NETIF_F_IP_CSUM | \
+                                NETIF_F_RXCSUM | \
+                                NETIF_F_HW_VLAN_CTAG_TX | \
+-                               NETIF_F_HW_VLAN_CTAG_RX | \
+                                NETIF_F_SG | NETIF_F_TSO | \
+                                NETIF_F_TSO6 | \
+                                NETIF_F_IPV6_CSUM |\
diff --git a/target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch b/target/linux/generic/backport-5.15/733-v6.5-27-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch
new file mode 100644 (file)
index 0000000..2704fae
--- /dev/null
@@ -0,0 +1,31 @@
+From b804f765485109f9644cc05d1e8fc79ca6c6e4aa Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 19 Jul 2023 01:39:36 +0100
+Subject: [PATCH 094/250] net: ethernet: mtk_eth_soc: always
+ mtk_get_ib1_pkt_type
+
+entries and bind debugfs files would display wrong data on NETSYS_V2 and
+later because instead of using mtk_get_ib1_pkt_type the driver would use
+MTK_FOE_IB1_PACKET_TYPE which corresponds to NETSYS_V1(.x) SoCs.
+Use mtk_get_ib1_pkt_type so entries and bind records display correctly.
+
+Fixes: 03a3180e5c09e ("net: ethernet: mtk_eth_soc: introduce flow offloading support for mt7986")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/r/c0ae03d0182f4d27b874cbdf0059bc972c317f3c.1689727134.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
+@@ -98,7 +98,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
+               acct = mtk_foe_entry_get_mib(ppe, i, NULL);
+-              type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
++              type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1);
+               seq_printf(m, "%05x %s %7s", i,
+                          mtk_foe_entry_state_str(state),
+                          mtk_foe_pkt_type_str(type));
diff --git a/target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch b/target/linux/generic/backport-5.15/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch
new file mode 100644 (file)
index 0000000..0ba8bb8
--- /dev/null
@@ -0,0 +1,78 @@
+From 5ea0e1312bcfebc06b5f91d1bb82b823d6395125 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Wed, 19 Jul 2023 12:29:49 +0200
+Subject: [PATCH 095/250] net: ethernet: mtk_ppe: add MTK_FOE_ENTRY_V{1,2}_SIZE
+ macros
+
+Introduce MTK_FOE_ENTRY_V{1,2}_SIZE macros in order to make more
+explicit foe_entry size for different chipset revisions.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 +++++-----
+ drivers/net/ethernet/mediatek/mtk_ppe.h     |  3 +++
+ 2 files changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4711,7 +4711,7 @@ static const struct mtk_soc_data mt7621_
+       .required_pctl = false,
+       .offload_version = 1,
+       .hash_offset = 2,
+-      .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
++      .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+@@ -4732,7 +4732,7 @@ static const struct mtk_soc_data mt7622_
+       .offload_version = 2,
+       .hash_offset = 2,
+       .has_accounting = true,
+-      .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
++      .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+@@ -4751,7 +4751,7 @@ static const struct mtk_soc_data mt7623_
+       .required_pctl = true,
+       .offload_version = 1,
+       .hash_offset = 2,
+-      .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
++      .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+@@ -4789,8 +4789,8 @@ static const struct mtk_soc_data mt7981_
+       .required_pctl = false,
+       .offload_version = 2,
+       .hash_offset = 4,
+-      .foe_entry_size = sizeof(struct mtk_foe_entry),
+       .has_accounting = true,
++      .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma_v2),
+               .rxd_size = sizeof(struct mtk_rx_dma_v2),
+@@ -4810,8 +4810,8 @@ static const struct mtk_soc_data mt7986_
+       .required_pctl = false,
+       .offload_version = 2,
+       .hash_offset = 4,
+-      .foe_entry_size = sizeof(struct mtk_foe_entry),
+       .has_accounting = true,
++      .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma_v2),
+               .rxd_size = sizeof(struct mtk_rx_dma_v2),
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -216,6 +216,9 @@ struct mtk_foe_ipv6_6rd {
+       struct mtk_foe_mac_info l2;
+ };
++#define MTK_FOE_ENTRY_V1_SIZE 80
++#define MTK_FOE_ENTRY_V2_SIZE 96
++
+ struct mtk_foe_entry {
+       u32 ib1;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch b/target/linux/generic/backport-5.15/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch
new file mode 100644 (file)
index 0000000..6810220
--- /dev/null
@@ -0,0 +1,141 @@
+From 8cfa2576d79f9379d167a8994f0fca935c07a8bc Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Sat, 22 Jul 2023 21:32:49 +0100
+Subject: [PATCH 096/250] net: ethernet: mtk_eth_soc: remove incorrect PLL
+ configuration
+
+MT7623 GMAC0 attempts to configure the system clocking according to the
+required speed in the .mac_config callback for non-SGMII, non-baseX and
+non-TRGMII modes.
+
+state->speed setting has never been reliable in the .mac_config
+callback - there are cases where this is not the link speed,
+particularly via ethtool paths, so this has always been unreliable (as
+detailed in phylink's documentation.)
+
+There is the additional issue that mtk_gmac0_rgmii_adjust() will only
+be called if state->interface changes, which means it only configures
+the system clocking on the very first .mac_config call, which will be
+made when the network device is first brought up before any link is
+established.
+
+Essentially, this code is incredibly buggy, and probably never worked.
+
+Moreover, checking the in-kernel DT files, it seems no platform makes
+use of this code path.
+
+Therefore, let's remove it, and disable interface modes for port 0 that
+are not SGMII, 1000base-X, 2500base-X or TRGMII on the MT7623.
+
+Reviewed-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Frank Wunderlich <frank-w@public-files.de>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 54 ++++++---------------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  1 +
+ 2 files changed, 17 insertions(+), 38 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -309,7 +309,7 @@ static int mt7621_gmac0_rgmii_adjust(str
+ }
+ static void mtk_gmac0_rgmii_adjust(struct mtk_eth *eth,
+-                                 phy_interface_t interface, int speed)
++                                 phy_interface_t interface)
+ {
+       u32 val;
+       int ret;
+@@ -323,26 +323,7 @@ static void mtk_gmac0_rgmii_adjust(struc
+               return;
+       }
+-      val = (speed == SPEED_1000) ?
+-              INTF_MODE_RGMII_1000 : INTF_MODE_RGMII_10_100;
+-      mtk_w32(eth, val, INTF_MODE);
+-
+-      regmap_update_bits(eth->ethsys, ETHSYS_CLKCFG0,
+-                         ETHSYS_TRGMII_CLK_SEL362_5,
+-                         ETHSYS_TRGMII_CLK_SEL362_5);
+-
+-      val = (speed == SPEED_1000) ? 250000000 : 500000000;
+-      ret = clk_set_rate(eth->clks[MTK_CLK_TRGPLL], val);
+-      if (ret)
+-              dev_err(eth->dev, "Failed to set trgmii pll: %d\n", ret);
+-
+-      val = (speed == SPEED_1000) ?
+-              RCK_CTRL_RGMII_1000 : RCK_CTRL_RGMII_10_100;
+-      mtk_w32(eth, val, TRGMII_RCK_CTRL);
+-
+-      val = (speed == SPEED_1000) ?
+-              TCK_CTRL_RGMII_1000 : TCK_CTRL_RGMII_10_100;
+-      mtk_w32(eth, val, TRGMII_TCK_CTRL);
++      dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n");
+ }
+ static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
+@@ -428,17 +409,8 @@ static void mtk_mac_config(struct phylin
+                                                             state->interface))
+                                       goto err_phy;
+                       } else {
+-                              /* FIXME: this is incorrect. Not only does it
+-                               * use state->speed (which is not guaranteed
+-                               * to be correct) but it also makes use of it
+-                               * in a code path that will only be reachable
+-                               * when the PHY interface mode changes, not
+-                               * when the speed changes. Consequently, RGMII
+-                               * is probably broken.
+-                               */
+                               mtk_gmac0_rgmii_adjust(mac->hw,
+-                                                     state->interface,
+-                                                     state->speed);
++                                                     state->interface);
+                               /* mt7623_pad_clk_setup */
+                               for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
+@@ -4286,13 +4258,19 @@ static int mtk_add_mac(struct mtk_eth *e
+       mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+               MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
+-      __set_bit(PHY_INTERFACE_MODE_MII,
+-                mac->phylink_config.supported_interfaces);
+-      __set_bit(PHY_INTERFACE_MODE_GMII,
+-                mac->phylink_config.supported_interfaces);
++      /* MT7623 gmac0 is now missing its speed-specific PLL configuration
++       * in its .mac_config method (since state->speed is not valid there.
++       * Disable support for MII, GMII and RGMII.
++       */
++      if (!mac->hw->soc->disable_pll_modes || mac->id != 0) {
++              __set_bit(PHY_INTERFACE_MODE_MII,
++                        mac->phylink_config.supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_GMII,
++                        mac->phylink_config.supported_interfaces);
+-      if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
+-              phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
++              if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
++                      phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
++      }
+       if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id)
+               __set_bit(PHY_INTERFACE_MODE_TRGMII,
+@@ -4752,6 +4730,7 @@ static const struct mtk_soc_data mt7623_
+       .offload_version = 1,
+       .hash_offset = 2,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
++      .disable_pll_modes = true,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1027,6 +1027,7 @@ struct mtk_soc_data {
+       u16             foe_entry_size;
+       netdev_features_t hw_features;
+       bool            has_accounting;
++      bool            disable_pll_modes;
+       struct {
+               u32     txd_size;
+               u32     rxd_size;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch b/target/linux/generic/backport-5.15/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch
new file mode 100644 (file)
index 0000000..816f98e
--- /dev/null
@@ -0,0 +1,81 @@
+From a4c2233b1e4359b6c64b6f9ba98c8718a11fffee Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Sat, 22 Jul 2023 21:32:54 +0100
+Subject: [PATCH 097/250] net: ethernet: mtk_eth_soc: remove mac_pcs_get_state
+ and modernise
+
+Remove the .mac_pcs_get_state function, since as far as I can tell is
+never called - no DT appears to specify an in-band-status management
+nor SFP support for this driver.
+
+Removal of this, along with the previous patch to remove the incorrect
+clocking configuration, means that the driver becomes non-legacy, so
+we can remove the "legacy_pre_march2020" status from this driver.
+
+Reviewed-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Frank Wunderlich <frank-w@public-files.de>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 ---------------------
+ 1 file changed, 35 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -512,38 +512,6 @@ static int mtk_mac_finish(struct phylink
+       return 0;
+ }
+-static void mtk_mac_pcs_get_state(struct phylink_config *config,
+-                                struct phylink_link_state *state)
+-{
+-      struct mtk_mac *mac = container_of(config, struct mtk_mac,
+-                                         phylink_config);
+-      u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id));
+-
+-      state->link = (pmsr & MAC_MSR_LINK);
+-      state->duplex = (pmsr & MAC_MSR_DPX) >> 1;
+-
+-      switch (pmsr & (MAC_MSR_SPEED_1000 | MAC_MSR_SPEED_100)) {
+-      case 0:
+-              state->speed = SPEED_10;
+-              break;
+-      case MAC_MSR_SPEED_100:
+-              state->speed = SPEED_100;
+-              break;
+-      case MAC_MSR_SPEED_1000:
+-              state->speed = SPEED_1000;
+-              break;
+-      default:
+-              state->speed = SPEED_UNKNOWN;
+-              break;
+-      }
+-
+-      state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
+-      if (pmsr & MAC_MSR_RX_FC)
+-              state->pause |= MLO_PAUSE_RX;
+-      if (pmsr & MAC_MSR_TX_FC)
+-              state->pause |= MLO_PAUSE_TX;
+-}
+-
+ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
+                             phy_interface_t interface)
+ {
+@@ -666,7 +634,6 @@ static void mtk_mac_link_up(struct phyli
+ static const struct phylink_mac_ops mtk_phylink_ops = {
+       .validate = phylink_generic_validate,
+       .mac_select_pcs = mtk_mac_select_pcs,
+-      .mac_pcs_get_state = mtk_mac_pcs_get_state,
+       .mac_config = mtk_mac_config,
+       .mac_finish = mtk_mac_finish,
+       .mac_link_down = mtk_mac_link_down,
+@@ -4253,8 +4220,6 @@ static int mtk_add_mac(struct mtk_eth *e
+       mac->phylink_config.dev = &eth->netdev[id]->dev;
+       mac->phylink_config.type = PHYLINK_NETDEV;
+-      /* This driver makes use of state->speed in mac_config */
+-      mac->phylink_config.legacy_pre_march2020 = true;
+       mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+               MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch b/target/linux/generic/backport-5.15/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch
new file mode 100644 (file)
index 0000000..d836acc
--- /dev/null
@@ -0,0 +1,550 @@
+From 5d8d05fbf804b4485646d39551ac27452e45afd3 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 25 Jul 2023 01:52:02 +0100
+Subject: [PATCH 099/250] net: ethernet: mtk_eth_soc: add version in
+ mtk_soc_data
+
+Introduce version field in mtk_soc_data data structure in order to
+make mtk_eth driver easier to maintain for chipset configuration
+codebase. Get rid of MTK_NETSYS_V2 bit in chip capabilities.
+This is a preliminary patch to introduce support for MT7988 SoC.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/e52fae302ca135436e5cdd26d38d87be2da63055.1690246066.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 55 +++++++++++--------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h   | 36 +++++++-----
+ drivers/net/ethernet/mediatek/mtk_ppe.c       | 18 +++---
+ .../net/ethernet/mediatek/mtk_ppe_offload.c   |  2 +-
+ drivers/net/ethernet/mediatek/mtk_wed.c       |  4 +-
+ 5 files changed, 66 insertions(+), 49 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -537,7 +537,7 @@ static void mtk_set_queue_speed(struct m
+             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
+             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
+             MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
+-      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v1(eth))
+               val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
+       if (IS_ENABLED(CONFIG_SOC_MT7621)) {
+@@ -912,7 +912,7 @@ static bool mtk_rx_get_desc(struct mtk_e
+       rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
+       rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
+       rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
+               rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
+       }
+@@ -970,7 +970,7 @@ static int mtk_init_fq_dma(struct mtk_et
+               txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
+               txd->txd4 = 0;
+-              if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
++              if (mtk_is_netsys_v2_or_greater(eth)) {
+                       txd->txd5 = 0;
+                       txd->txd6 = 0;
+                       txd->txd7 = 0;
+@@ -1159,7 +1159,7 @@ static void mtk_tx_set_dma_desc(struct n
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               mtk_tx_set_dma_desc_v2(dev, txd, info);
+       else
+               mtk_tx_set_dma_desc_v1(dev, txd, info);
+@@ -1466,7 +1466,7 @@ static void mtk_update_rx_cpu_idx(struct
+ static bool mtk_page_pool_enabled(struct mtk_eth *eth)
+ {
+-      return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2);
++      return eth->soc->version == 2;
+ }
+ static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
+@@ -1806,7 +1806,7 @@ static int mtk_poll_rx(struct napi_struc
+                       break;
+               /* find out which mac the packet come from. values start at 1 */
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++              if (mtk_is_netsys_v2_or_greater(eth))
+                       mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
+               else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
+                        !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
+@@ -1902,7 +1902,7 @@ static int mtk_poll_rx(struct napi_struc
+               skb->dev = netdev;
+               bytes += skb->len;
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++              if (mtk_is_netsys_v2_or_greater(eth)) {
+                       reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
+                       hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
+                       if (hash != MTK_RXD5_FOE_ENTRY)
+@@ -1927,8 +1927,8 @@ static int mtk_poll_rx(struct napi_struc
+               /* When using VLAN untagging in combination with DSA, the
+                * hardware treats the MTK special tag as a VLAN and untags it.
+                */
+-              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
+-                  (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
++              if (mtk_is_netsys_v1(eth) && (trxd.rxd2 & RX_DMA_VTAG) &&
++                  netdev_uses_dsa(netdev)) {
+                       unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
+                       if (port < ARRAY_SIZE(eth->dsa_meta) &&
+@@ -2232,7 +2232,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+               txd->txd2 = next_ptr;
+               txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
+               txd->txd4 = 0;
+-              if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
++              if (mtk_is_netsys_v2_or_greater(eth)) {
+                       txd->txd5 = 0;
+                       txd->txd6 = 0;
+                       txd->txd7 = 0;
+@@ -2285,14 +2285,14 @@ static int mtk_tx_alloc(struct mtk_eth *
+                             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
+                             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
+                             MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
+-                      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++                      if (mtk_is_netsys_v1(eth))
+                               val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
+                       mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
+                       ofs += MTK_QTX_OFFSET;
+               }
+               val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16);
+               mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate);
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++              if (mtk_is_netsys_v2_or_greater(eth))
+                       mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4);
+       } else {
+               mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0);
+@@ -2419,7 +2419,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+               rxd->rxd3 = 0;
+               rxd->rxd4 = 0;
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++              if (mtk_is_netsys_v2_or_greater(eth)) {
+                       rxd->rxd5 = 0;
+                       rxd->rxd6 = 0;
+                       rxd->rxd7 = 0;
+@@ -2967,7 +2967,7 @@ static int mtk_start_dma(struct mtk_eth
+                      MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
+                      MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++              if (mtk_is_netsys_v2_or_greater(eth))
+                       val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
+                              MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
+                              MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
+@@ -3111,7 +3111,7 @@ static int mtk_open(struct net_device *d
+       phylink_start(mac->phylink);
+       netif_tx_start_all_queues(dev);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return 0;
+       if (mtk_uses_dsa(dev) && !eth->prog) {
+@@ -3376,7 +3376,7 @@ static void mtk_hw_reset(struct mtk_eth
+ {
+       u32 val;
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
+               val = RSTCTRL_PPE0_V2;
+       } else {
+@@ -3388,7 +3388,7 @@ static void mtk_hw_reset(struct mtk_eth
+       ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
+                            0x3ffffff);
+ }
+@@ -3414,7 +3414,7 @@ static void mtk_hw_warm_reset(struct mtk
+               return;
+       }
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
+       else
+               rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
+@@ -3584,7 +3584,7 @@ static int mtk_hw_init(struct mtk_eth *e
+       else
+               mtk_hw_reset(eth);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               /* Set FE to PDMAv2 if necessary */
+               val = mtk_r32(eth, MTK_FE_GLO_MISC);
+               mtk_w32(eth,  val | BIT(4), MTK_FE_GLO_MISC);
+@@ -3621,7 +3621,7 @@ static int mtk_hw_init(struct mtk_eth *e
+        */
+       val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
+       mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
+-      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v1(eth)) {
+               val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
+               mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
+@@ -3643,7 +3643,7 @@ static int mtk_hw_init(struct mtk_eth *e
+       mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
+       mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               /* PSE should not drop port8 and port9 packets from WDMA Tx */
+               mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
+@@ -4432,7 +4432,7 @@ static int mtk_probe(struct platform_dev
+               }
+       }
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               if (!res) {
+                       err = -EINVAL;
+@@ -4540,9 +4540,8 @@ static int mtk_probe(struct platform_dev
+       }
+       if (eth->soc->offload_version) {
+-              u32 num_ppe;
++              u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1;
+-              num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
+               num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
+               for (i = 0; i < num_ppe; i++) {
+                       u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
+@@ -4636,6 +4635,7 @@ static const struct mtk_soc_data mt2701_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7623_CLKS_BITMAP,
+       .required_pctl = true,
++      .version = 1,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+@@ -4652,6 +4652,7 @@ static const struct mtk_soc_data mt7621_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7621_CLKS_BITMAP,
+       .required_pctl = false,
++      .version = 1,
+       .offload_version = 1,
+       .hash_offset = 2,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+@@ -4672,6 +4673,7 @@ static const struct mtk_soc_data mt7622_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7622_CLKS_BITMAP,
+       .required_pctl = false,
++      .version = 1,
+       .offload_version = 2,
+       .hash_offset = 2,
+       .has_accounting = true,
+@@ -4692,6 +4694,7 @@ static const struct mtk_soc_data mt7623_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7623_CLKS_BITMAP,
+       .required_pctl = true,
++      .version = 1,
+       .offload_version = 1,
+       .hash_offset = 2,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+@@ -4714,6 +4717,7 @@ static const struct mtk_soc_data mt7629_
+       .required_clks = MT7629_CLKS_BITMAP,
+       .required_pctl = false,
+       .has_accounting = true,
++      .version = 1,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+@@ -4731,6 +4735,7 @@ static const struct mtk_soc_data mt7981_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7981_CLKS_BITMAP,
+       .required_pctl = false,
++      .version = 2,
+       .offload_version = 2,
+       .hash_offset = 4,
+       .has_accounting = true,
+@@ -4752,6 +4757,7 @@ static const struct mtk_soc_data mt7986_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7986_CLKS_BITMAP,
+       .required_pctl = false,
++      .version = 2,
+       .offload_version = 2,
+       .hash_offset = 4,
+       .has_accounting = true,
+@@ -4772,6 +4778,7 @@ static const struct mtk_soc_data rt5350_
+       .hw_features = MTK_HW_FEATURES_MT7628,
+       .required_clks = MT7628_CLKS_BITMAP,
+       .required_pctl = false,
++      .version = 1,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -817,7 +817,6 @@ enum mkt_eth_capabilities {
+       MTK_SHARED_INT_BIT,
+       MTK_TRGMII_MT7621_CLK_BIT,
+       MTK_QDMA_BIT,
+-      MTK_NETSYS_V2_BIT,
+       MTK_SOC_MT7628_BIT,
+       MTK_RSTCTRL_PPE1_BIT,
+       MTK_U3_COPHY_V2_BIT,
+@@ -852,7 +851,6 @@ enum mkt_eth_capabilities {
+ #define MTK_SHARED_INT                BIT(MTK_SHARED_INT_BIT)
+ #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
+ #define MTK_QDMA              BIT(MTK_QDMA_BIT)
+-#define MTK_NETSYS_V2         BIT(MTK_NETSYS_V2_BIT)
+ #define MTK_SOC_MT7628                BIT(MTK_SOC_MT7628_BIT)
+ #define MTK_RSTCTRL_PPE1      BIT(MTK_RSTCTRL_PPE1_BIT)
+ #define MTK_U3_COPHY_V2               BIT(MTK_U3_COPHY_V2_BIT)
+@@ -931,11 +929,11 @@ enum mkt_eth_capabilities {
+ #define MT7981_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
+-                    MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
++                    MTK_RSTCTRL_PPE1)
+ #define MT7986_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+-                    MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
++                    MTK_RSTCTRL_PPE1)
+ struct mtk_tx_dma_desc_info {
+       dma_addr_t      addr;
+@@ -1006,6 +1004,7 @@ struct mtk_reg_map {
+  * @required_pctl             A bool value to show whether the SoC requires
+  *                            the extra setup for those pins used by GMAC.
+  * @hash_offset                       Flow table hash offset.
++ * @version                   SoC version.
+  * @foe_entry_size            Foe table entry size.
+  * @has_accounting            Bool indicating support for accounting of
+  *                            offloaded flows.
+@@ -1024,6 +1023,7 @@ struct mtk_soc_data {
+       bool            required_pctl;
+       u8              offload_version;
+       u8              hash_offset;
++      u8              version;
+       u16             foe_entry_size;
+       netdev_features_t hw_features;
+       bool            has_accounting;
+@@ -1180,6 +1180,16 @@ struct mtk_mac {
+ /* the struct describing the SoC. these are declared in the soc_xyz.c files */
+ extern const struct of_device_id of_mtk_match[];
++static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
++{
++      return eth->soc->version == 1;
++}
++
++static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth)
++{
++      return eth->soc->version > 1;
++}
++
+ static inline struct mtk_foe_entry *
+ mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
+ {
+@@ -1190,7 +1200,7 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u
+ static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return MTK_FOE_IB1_BIND_TIMESTAMP_V2;
+       return MTK_FOE_IB1_BIND_TIMESTAMP;
+@@ -1198,7 +1208,7 @@ static inline u32 mtk_get_ib1_ts_mask(st
+ static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return MTK_FOE_IB1_BIND_PPPOE_V2;
+       return MTK_FOE_IB1_BIND_PPPOE;
+@@ -1206,7 +1216,7 @@ static inline u32 mtk_get_ib1_ppoe_mask(
+ static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return MTK_FOE_IB1_BIND_VLAN_TAG_V2;
+       return MTK_FOE_IB1_BIND_VLAN_TAG;
+@@ -1214,7 +1224,7 @@ static inline u32 mtk_get_ib1_vlan_tag_m
+ static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return MTK_FOE_IB1_BIND_VLAN_LAYER_V2;
+       return MTK_FOE_IB1_BIND_VLAN_LAYER;
+@@ -1222,7 +1232,7 @@ static inline u32 mtk_get_ib1_vlan_layer
+ static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val);
+       return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val);
+@@ -1230,7 +1240,7 @@ static inline u32 mtk_prep_ib1_vlan_laye
+ static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val);
+       return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val);
+@@ -1238,7 +1248,7 @@ static inline u32 mtk_get_ib1_vlan_layer
+ static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return MTK_FOE_IB1_PACKET_TYPE_V2;
+       return MTK_FOE_IB1_PACKET_TYPE;
+@@ -1246,7 +1256,7 @@ static inline u32 mtk_get_ib1_pkt_type_m
+ static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val);
+       return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val);
+@@ -1254,7 +1264,7 @@ static inline u32 mtk_get_ib1_pkt_type(s
+ static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return MTK_FOE_IB2_MULTICAST_V2;
+       return MTK_FOE_IB2_MULTICAST;
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -207,7 +207,7 @@ int mtk_foe_entry_prepare(struct mtk_eth
+       memset(entry, 0, sizeof(*entry));
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) |
+                     FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) |
+                     FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) |
+@@ -271,7 +271,7 @@ int mtk_foe_entry_set_pse_port(struct mt
+       u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
+       u32 val = *ib2;
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               val &= ~MTK_FOE_IB2_DEST_PORT_V2;
+               val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port);
+       } else {
+@@ -422,7 +422,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
+       struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
+       u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
+               *ib2 |=  FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
+                        MTK_FOE_IB2_WDMA_WINFO_V2;
+@@ -452,7 +452,7 @@ int mtk_foe_entry_set_queue(struct mtk_e
+ {
+       u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               *ib2 &= ~MTK_FOE_IB2_QID_V2;
+               *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue);
+               *ib2 |= MTK_FOE_IB2_PSE_QOS_V2;
+@@ -607,7 +607,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+       struct mtk_foe_entry *hwe;
+       u32 val;
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
+               entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2,
+                                        timestamp);
+@@ -623,7 +623,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+       hwe->ib1 = entry->ib1;
+       if (ppe->accounting) {
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++              if (mtk_is_netsys_v2_or_greater(eth))
+                       val = MTK_FOE_IB2_MIB_CNT_V2;
+               else
+                       val = MTK_FOE_IB2_MIB_CNT;
+@@ -971,7 +971,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
+                        MTK_PPE_SCAN_MODE_KEEPALIVE_AGE) |
+             FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM,
+                        MTK_PPE_ENTRIES_SHIFT);
+-      if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(ppe->eth))
+               val |= MTK_PPE_TB_CFG_INFO_SEL;
+       ppe_w32(ppe, MTK_PPE_TB_CFG, val);
+@@ -987,7 +987,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
+             MTK_PPE_FLOW_CFG_IP4_NAPT |
+             MTK_PPE_FLOW_CFG_IP4_DSLITE |
+             MTK_PPE_FLOW_CFG_IP4_NAT_FRAG;
+-      if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(ppe->eth))
+               val |= MTK_PPE_MD_TOAP_BYP_CRSN0 |
+                      MTK_PPE_MD_TOAP_BYP_CRSN1 |
+                      MTK_PPE_MD_TOAP_BYP_CRSN2 |
+@@ -1029,7 +1029,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
+       ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
+-      if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(ppe->eth)) {
+               ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
+               ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
+       }
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+@@ -193,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et
+       if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
+               mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
+                                      info.bss, info.wcid);
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++              if (mtk_is_netsys_v2_or_greater(eth)) {
+                       switch (info.wdma_idx) {
+                       case 0:
+                               pse_port = 8;
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -1091,7 +1091,7 @@ mtk_wed_rx_reset(struct mtk_wed_device *
+       } else {
+               struct mtk_eth *eth = dev->hw->eth;
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++              if (mtk_is_netsys_v2_or_greater(eth))
+                       wed_set(dev, MTK_WED_RESET_IDX,
+                               MTK_WED_RESET_IDX_RX_V2);
+               else
+@@ -1813,7 +1813,7 @@ void mtk_wed_add_hw(struct device_node *
+       hw->wdma = wdma;
+       hw->index = index;
+       hw->irq = irq;
+-      hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
++      hw->version = mtk_is_netsys_v1(eth) ? 1 : 2;
+       if (hw->version == 1) {
+               hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
diff --git a/target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch b/target/linux/generic/backport-5.15/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch
new file mode 100644 (file)
index 0000000..5a08b9d
--- /dev/null
@@ -0,0 +1,29 @@
+From f8fb8dbd158c585be7574faf92db7d614b6722ff Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 25 Jul 2023 01:52:27 +0100
+Subject: [PATCH 100/250] net: ethernet: mtk_eth_soc: increase MAX_DEVS to 3
+
+This is a preliminary patch to add MT7988 SoC support since it runs 3
+macs instead of 2.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/3563e5fab367e7d79a7f1296fabaa5c20f202d7a.1690246066.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1040,8 +1040,8 @@ struct mtk_soc_data {
+ #define MTK_DMA_MONITOR_TIMEOUT               msecs_to_jiffies(1000)
+-/* currently no SoC has more than 2 macs */
+-#define MTK_MAX_DEVS                  2
++/* currently no SoC has more than 3 macs */
++#define MTK_MAX_DEVS  3
+ /* struct mtk_eth -   This is the main datasructure for holding the state
+  *                    of the driver
diff --git a/target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch b/target/linux/generic/backport-5.15/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch
new file mode 100644 (file)
index 0000000..58729ce
--- /dev/null
@@ -0,0 +1,186 @@
+From 856be974290f28d7943be2ac5a382c4139486196 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 25 Jul 2023 01:52:44 +0100
+Subject: [PATCH 101/250] net: ethernet: mtk_eth_soc: rely on MTK_MAX_DEVS and
+ remove MTK_MAC_COUNT
+
+Get rid of MTK_MAC_COUNT since it is a duplicated of MTK_MAX_DEVS.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/1856f4266f2fc80677807b1bad867659e7b00c65.1690246066.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++++++---------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  1 -
+ 2 files changed, 27 insertions(+), 23 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -838,7 +838,7 @@ static void mtk_stats_update(struct mtk_
+ {
+       int i;
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               if (!eth->mac[i] || !eth->mac[i]->hw_stats)
+                       continue;
+               if (spin_trylock(&eth->mac[i]->hw_stats->stats_lock)) {
+@@ -1341,7 +1341,7 @@ static int mtk_queue_stopped(struct mtk_
+ {
+       int i;
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               if (!eth->netdev[i])
+                       continue;
+               if (netif_queue_stopped(eth->netdev[i]))
+@@ -1355,7 +1355,7 @@ static void mtk_wake_queue(struct mtk_et
+ {
+       int i;
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               if (!eth->netdev[i])
+                       continue;
+               netif_tx_wake_all_queues(eth->netdev[i]);
+@@ -1812,7 +1812,7 @@ static int mtk_poll_rx(struct napi_struc
+                        !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
+                       mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
+-              if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
++              if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS ||
+                            !eth->netdev[mac]))
+                       goto release_desc;
+@@ -2841,7 +2841,7 @@ static void mtk_dma_free(struct mtk_eth
+       const struct mtk_soc_data *soc = eth->soc;
+       int i;
+-      for (i = 0; i < MTK_MAC_COUNT; i++)
++      for (i = 0; i < MTK_MAX_DEVS; i++)
+               if (eth->netdev[i])
+                       netdev_reset_queue(eth->netdev[i]);
+       if (eth->scratch_ring) {
+@@ -2995,8 +2995,13 @@ static void mtk_gdm_config(struct mtk_et
+       if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
+               return;
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
+-              u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
++              u32 val;
++
++              if (!eth->netdev[i])
++                      continue;
++
++              val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
+               /* default setup the forward port to send frame to PDMA */
+               val &= ~0xffff;
+@@ -3006,7 +3011,7 @@ static void mtk_gdm_config(struct mtk_et
+               val |= config;
+-              if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i]))
++              if (netdev_uses_dsa(eth->netdev[i]))
+                       val |= MTK_GDMA_SPECIAL_TAG;
+               mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
+@@ -3605,15 +3610,15 @@ static int mtk_hw_init(struct mtk_eth *e
+        * up with the more appropriate value when mtk_mac_config call is being
+        * invoked.
+        */
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               struct net_device *dev = eth->netdev[i];
+-              mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
+-              if (dev) {
+-                      struct mtk_mac *mac = netdev_priv(dev);
++              if (!dev)
++                      continue;
+-                      mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN);
+-              }
++              mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
++              mtk_set_mcr_max_rx(netdev_priv(dev),
++                                 dev->mtu + MTK_RX_ETH_HLEN);
+       }
+       /* Indicates CDM to parse the MTK special tag from CPU
+@@ -3793,7 +3798,7 @@ static void mtk_pending_work(struct work
+       mtk_prepare_for_reset(eth);
+       /* stop all devices to make sure that dma is properly shut down */
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
+                       continue;
+@@ -3809,8 +3814,8 @@ static void mtk_pending_work(struct work
+       mtk_hw_init(eth, true);
+       /* restart DMA and enable IRQs */
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
+-              if (!test_bit(i, &restart))
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
++              if (!eth->netdev[i] || !test_bit(i, &restart))
+                       continue;
+               if (mtk_open(eth->netdev[i])) {
+@@ -3837,7 +3842,7 @@ static int mtk_free_dev(struct mtk_eth *
+ {
+       int i;
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               if (!eth->netdev[i])
+                       continue;
+               free_netdev(eth->netdev[i]);
+@@ -3856,7 +3861,7 @@ static int mtk_unreg_dev(struct mtk_eth
+ {
+       int i;
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               struct mtk_mac *mac;
+               if (!eth->netdev[i])
+                       continue;
+@@ -4157,7 +4162,7 @@ static int mtk_add_mac(struct mtk_eth *e
+       }
+       id = be32_to_cpup(_id);
+-      if (id >= MTK_MAC_COUNT) {
++      if (id >= MTK_MAX_DEVS) {
+               dev_err(eth->dev, "%d is not a valid mac id\n", id);
+               return -EINVAL;
+       }
+@@ -4302,7 +4307,7 @@ void mtk_eth_set_dma_device(struct mtk_e
+       rtnl_lock();
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               dev = eth->netdev[i];
+               if (!dev || !(dev->flags & IFF_UP))
+@@ -4610,7 +4615,7 @@ static int mtk_remove(struct platform_de
+       int i;
+       /* stop all devices to make sure that dma is properly shut down */
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               if (!eth->netdev[i])
+                       continue;
+               mtk_stop(eth->netdev[i]);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -33,7 +33,6 @@
+ #define MTK_TX_DMA_BUF_LEN_V2 0xffff
+ #define MTK_QDMA_RING_SIZE    2048
+ #define MTK_DMA_SIZE          512
+-#define MTK_MAC_COUNT         2
+ #define MTK_RX_ETH_HLEN               (VLAN_ETH_HLEN + ETH_FCS_LEN)
+ #define MTK_RX_HLEN           (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
+ #define MTK_DMA_DUMMY_DESC    0xffffffff
diff --git a/target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch b/target/linux/generic/backport-5.15/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch
new file mode 100644 (file)
index 0000000..09f59c2
--- /dev/null
@@ -0,0 +1,307 @@
+From a41d535855976838d246c079143c948dcf0f7931 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 25 Jul 2023 01:52:59 +0100
+Subject: [PATCH 102/250] net: ethernet: mtk_eth_soc: add NETSYS_V3 version
+ support
+
+Introduce NETSYS_V3 chipset version support.
+This is a preliminary patch to introduce support for MT7988 SoC.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/0db2260910755d76fa48e303b9f9bdf4e5a82340.1690246066.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 105 ++++++++++++++------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  48 +++++++--
+ 2 files changed, 116 insertions(+), 37 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -818,17 +818,32 @@ void mtk_stats_update_mac(struct mtk_mac
+                       mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
+               hw_stats->rx_flow_control_packets +=
+                       mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
+-              hw_stats->tx_skip +=
+-                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
+-              hw_stats->tx_collisions +=
+-                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
+-              hw_stats->tx_bytes +=
+-                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
+-              stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
+-              if (stats)
+-                      hw_stats->tx_bytes += (stats << 32);
+-              hw_stats->tx_packets +=
+-                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
++
++              if (mtk_is_netsys_v3_or_greater(eth)) {
++                      hw_stats->tx_skip +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs);
++                      hw_stats->tx_collisions +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs);
++                      hw_stats->tx_bytes +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs);
++                      stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs);
++                      if (stats)
++                              hw_stats->tx_bytes += (stats << 32);
++                      hw_stats->tx_packets +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs);
++              } else {
++                      hw_stats->tx_skip +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
++                      hw_stats->tx_collisions +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
++                      hw_stats->tx_bytes +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
++                      stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
++                      if (stats)
++                              hw_stats->tx_bytes += (stats << 32);
++                      hw_stats->tx_packets +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
++              }
+       }
+       u64_stats_update_end(&hw_stats->syncp);
+@@ -1130,7 +1145,10 @@ static void mtk_tx_set_dma_desc_v2(struc
+               data |= TX_DMA_LS0;
+       WRITE_ONCE(desc->txd3, data);
+-      data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
++      if (mac->id == MTK_GMAC3_ID)
++              data = PSE_GDM3_PORT;
++      else
++              data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
+       data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
+       WRITE_ONCE(desc->txd4, data);
+@@ -1141,6 +1159,8 @@ static void mtk_tx_set_dma_desc_v2(struc
+               /* tx checksum offload */
+               if (info->csum)
+                       data |= TX_DMA_CHKSUM_V2;
++              if (mtk_is_netsys_v3_or_greater(eth) && netdev_uses_dsa(dev))
++                      data |= TX_DMA_SPTAG_V3;
+       }
+       WRITE_ONCE(desc->txd5, data);
+@@ -1206,8 +1226,7 @@ static int mtk_tx_map(struct sk_buff *sk
+       mtk_tx_set_dma_desc(dev, itxd, &txd_info);
+       itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
+-      itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
+-                        MTK_TX_FLAGS_FPORT1;
++      itx_buf->mac_id = mac->id;
+       setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
+                    k++);
+@@ -1255,8 +1274,7 @@ static int mtk_tx_map(struct sk_buff *sk
+                               memset(tx_buf, 0, sizeof(*tx_buf));
+                       tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
+                       tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
+-                      tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
+-                                       MTK_TX_FLAGS_FPORT1;
++                      tx_buf->mac_id = mac->id;
+                       setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
+                                    txd_info.size, k++);
+@@ -1558,7 +1576,7 @@ static int mtk_xdp_frame_map(struct mtk_
+       }
+       mtk_tx_set_dma_desc(dev, txd, txd_info);
+-      tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1;
++      tx_buf->mac_id = mac->id;
+       tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX;
+       tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
+@@ -1806,11 +1824,24 @@ static int mtk_poll_rx(struct napi_struc
+                       break;
+               /* find out which mac the packet come from. values start at 1 */
+-              if (mtk_is_netsys_v2_or_greater(eth))
+-                      mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
+-              else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
+-                       !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
++              if (mtk_is_netsys_v2_or_greater(eth)) {
++                      u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
++
++                      switch (val) {
++                      case PSE_GDM1_PORT:
++                      case PSE_GDM2_PORT:
++                              mac = val - 1;
++                              break;
++                      case PSE_GDM3_PORT:
++                              mac = MTK_GMAC3_ID;
++                              break;
++                      default:
++                              break;
++                      }
++              } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
++                         !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
+                       mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
++              }
+               if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS ||
+                            !eth->netdev[mac]))
+@@ -2030,7 +2061,6 @@ static int mtk_poll_tx_qdma(struct mtk_e
+       while ((cpu != dma) && budget) {
+               u32 next_cpu = desc->txd2;
+-              int mac = 0;
+               desc = mtk_qdma_phys_to_virt(ring, desc->txd2);
+               if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0)
+@@ -2038,15 +2068,13 @@ static int mtk_poll_tx_qdma(struct mtk_e
+               tx_buf = mtk_desc_to_tx_buf(ring, desc,
+                                           eth->soc->txrx.txd_size);
+-              if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
+-                      mac = 1;
+-
+               if (!tx_buf->data)
+                       break;
+               if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
+                       if (tx_buf->type == MTK_TYPE_SKB)
+-                              mtk_poll_tx_done(eth, state, mac, tx_buf->data);
++                              mtk_poll_tx_done(eth, state, tx_buf->mac_id,
++                                               tx_buf->data);
+                       budget--;
+               }
+@@ -3648,7 +3676,24 @@ static int mtk_hw_init(struct mtk_eth *e
+       mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
+       mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
+-      if (mtk_is_netsys_v2_or_greater(eth)) {
++      if (mtk_is_netsys_v3_or_greater(eth)) {
++              /* PSE should not drop port1, port8 and port9 packets */
++              mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
++
++              /* GDM and CDM Threshold */
++              mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
++              mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
++
++              /* Disable GDM1 RX CRC stripping */
++              mtk_m32(eth, MTK_GDMA_STRP_CRC, 0, MTK_GDMA_FWD_CFG(0));
++
++              /* PSE GDM3 MIB counter has incorrect hw default values,
++               * so the driver ought to read clear the values beforehand
++               * in case ethtool retrieve wrong mib values.
++               */
++              for (i = 0; i < 0x80; i += 0x4)
++                      mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i);
++      } else if (!mtk_is_netsys_v1(eth)) {
+               /* PSE should not drop port8 and port9 packets from WDMA Tx */
+               mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
+@@ -4210,7 +4255,11 @@ static int mtk_add_mac(struct mtk_eth *e
+       }
+       spin_lock_init(&mac->hw_stats->stats_lock);
+       u64_stats_init(&mac->hw_stats->syncp);
+-      mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
++
++      if (mtk_is_netsys_v3_or_greater(eth))
++              mac->hw_stats->reg_offset = id * 0x80;
++      else
++              mac->hw_stats->reg_offset = id * 0x40;
+       /* phylink create */
+       err = of_get_phy_mode(np, &phy_mode);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -122,6 +122,7 @@
+ #define MTK_GDMA_ICS_EN               BIT(22)
+ #define MTK_GDMA_TCS_EN               BIT(21)
+ #define MTK_GDMA_UCS_EN               BIT(20)
++#define MTK_GDMA_STRP_CRC     BIT(16)
+ #define MTK_GDMA_TO_PDMA      0x0
+ #define MTK_GDMA_DROP_ALL       0x7777
+@@ -287,8 +288,6 @@
+ /* QDMA Interrupt grouping registers */
+ #define MTK_RLS_DONE_INT      BIT(0)
+-#define MTK_STAT_OFFSET               0x40
+-
+ /* QDMA TX NUM */
+ #define QID_BITS_V2(x)                (((x) & 0x3f) << 16)
+ #define MTK_QDMA_GMAC2_QID    8
+@@ -301,6 +300,8 @@
+ #define TX_DMA_CHKSUM_V2      (0x7 << 28)
+ #define TX_DMA_TSO_V2         BIT(31)
++#define TX_DMA_SPTAG_V3         BIT(27)
++
+ /* QDMA V2 descriptor txd4 */
+ #define TX_DMA_FPORT_SHIFT_V2 8
+ #define TX_DMA_FPORT_MASK_V2  0xf
+@@ -631,12 +632,6 @@ enum mtk_tx_flags {
+        */
+       MTK_TX_FLAGS_SINGLE0    = 0x01,
+       MTK_TX_FLAGS_PAGE0      = 0x02,
+-
+-      /* MTK_TX_FLAGS_FPORTx allows tracking which port the transmitted
+-       * SKB out instead of looking up through hardware TX descriptor.
+-       */
+-      MTK_TX_FLAGS_FPORT0     = 0x04,
+-      MTK_TX_FLAGS_FPORT1     = 0x08,
+ };
+ /* This enum allows us to identify how the clock is defined on the array of the
+@@ -722,6 +717,35 @@ enum mtk_dev_state {
+       MTK_RESETTING
+ };
++/* PSE Port Definition */
++enum mtk_pse_port {
++      PSE_ADMA_PORT = 0,
++      PSE_GDM1_PORT,
++      PSE_GDM2_PORT,
++      PSE_PPE0_PORT,
++      PSE_PPE1_PORT,
++      PSE_QDMA_TX_PORT,
++      PSE_QDMA_RX_PORT,
++      PSE_DROP_PORT,
++      PSE_WDMA0_PORT,
++      PSE_WDMA1_PORT,
++      PSE_TDMA_PORT,
++      PSE_NONE_PORT,
++      PSE_PPE2_PORT,
++      PSE_WDMA2_PORT,
++      PSE_EIP197_PORT,
++      PSE_GDM3_PORT,
++      PSE_PORT_MAX
++};
++
++/* GMAC Identifier */
++enum mtk_gmac_id {
++      MTK_GMAC1_ID = 0,
++      MTK_GMAC2_ID,
++      MTK_GMAC3_ID,
++      MTK_GMAC_ID_MAX
++};
++
+ enum mtk_tx_buf_type {
+       MTK_TYPE_SKB,
+       MTK_TYPE_XDP_TX,
+@@ -740,7 +764,8 @@ struct mtk_tx_buf {
+       enum mtk_tx_buf_type type;
+       void *data;
+-      u32 flags;
++      u16 mac_id;
++      u16 flags;
+       DEFINE_DMA_UNMAP_ADDR(dma_addr0);
+       DEFINE_DMA_UNMAP_LEN(dma_len0);
+       DEFINE_DMA_UNMAP_ADDR(dma_addr1);
+@@ -1189,6 +1214,11 @@ static inline bool mtk_is_netsys_v2_or_g
+       return eth->soc->version > 1;
+ }
++static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth)
++{
++      return eth->soc->version > 2;
++}
++
+ static inline struct mtk_foe_entry *
+ mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
+ {
diff --git a/target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch b/target/linux/generic/backport-5.15/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch
new file mode 100644 (file)
index 0000000..0a72eec
--- /dev/null
@@ -0,0 +1,193 @@
+From db797ae0542220a98658229397da464c383c991c Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 25 Jul 2023 01:53:13 +0100
+Subject: [PATCH 103/250] net: ethernet: mtk_eth_soc: convert caps in
+ mtk_soc_data struct to u64
+
+This is a preliminary patch to introduce support for MT7988 SoC.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/9499ac3670b2fc5b444404b84e8a4a169beabbf2.1690246066.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 ++++----
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 56 ++++++++++----------
+ 2 files changed, 39 insertions(+), 39 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
+@@ -15,10 +15,10 @@
+ struct mtk_eth_muxc {
+       const char      *name;
+       int             cap_bit;
+-      int             (*set_path)(struct mtk_eth *eth, int path);
++      int             (*set_path)(struct mtk_eth *eth, u64 path);
+ };
+-static const char *mtk_eth_path_name(int path)
++static const char *mtk_eth_path_name(u64 path)
+ {
+       switch (path) {
+       case MTK_ETH_PATH_GMAC1_RGMII:
+@@ -40,7 +40,7 @@ static const char *mtk_eth_path_name(int
+       }
+ }
+-static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
++static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
+ {
+       bool updated = true;
+       u32 val, mask, set;
+@@ -71,7 +71,7 @@ static int set_mux_gdm1_to_gmac1_esw(str
+       return 0;
+ }
+-static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
++static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0;
+       bool updated = true;
+@@ -94,7 +94,7 @@ static int set_mux_gmac2_gmac0_to_gephy(
+       return 0;
+ }
+-static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
++static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0, mask = 0, reg = 0;
+       bool updated = true;
+@@ -125,7 +125,7 @@ static int set_mux_u3_gmac2_to_qphy(stru
+       return 0;
+ }
+-static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
++static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0;
+       bool updated = true;
+@@ -163,7 +163,7 @@ static int set_mux_gmac1_gmac2_to_sgmii_
+       return 0;
+ }
+-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
++static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0;
+       bool updated = true;
+@@ -218,7 +218,7 @@ static const struct mtk_eth_muxc mtk_eth
+       },
+ };
+-static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
++static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
+ {
+       int i, err = 0;
+@@ -249,7 +249,7 @@ out:
+ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
+ {
+-      int path;
++      u64 path;
+       path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
+                               MTK_ETH_PATH_GMAC2_SGMII;
+@@ -260,7 +260,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk
+ int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
+ {
+-      int path = 0;
++      u64 path = 0;
+       if (mac_id == 1)
+               path = MTK_ETH_PATH_GMAC2_GEPHY;
+@@ -274,7 +274,7 @@ int mtk_gmac_gephy_path_setup(struct mtk
+ int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
+ {
+-      int path;
++      u64 path;
+       path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_RGMII :
+                               MTK_ETH_PATH_GMAC2_RGMII;
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -863,41 +863,41 @@ enum mkt_eth_capabilities {
+ };
+ /* Supported hardware group on SoCs */
+-#define MTK_RGMII             BIT(MTK_RGMII_BIT)
+-#define MTK_TRGMII            BIT(MTK_TRGMII_BIT)
+-#define MTK_SGMII             BIT(MTK_SGMII_BIT)
+-#define MTK_ESW                       BIT(MTK_ESW_BIT)
+-#define MTK_GEPHY             BIT(MTK_GEPHY_BIT)
+-#define MTK_MUX                       BIT(MTK_MUX_BIT)
+-#define MTK_INFRA             BIT(MTK_INFRA_BIT)
+-#define MTK_SHARED_SGMII      BIT(MTK_SHARED_SGMII_BIT)
+-#define MTK_HWLRO             BIT(MTK_HWLRO_BIT)
+-#define MTK_SHARED_INT                BIT(MTK_SHARED_INT_BIT)
+-#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
+-#define MTK_QDMA              BIT(MTK_QDMA_BIT)
+-#define MTK_SOC_MT7628                BIT(MTK_SOC_MT7628_BIT)
+-#define MTK_RSTCTRL_PPE1      BIT(MTK_RSTCTRL_PPE1_BIT)
+-#define MTK_U3_COPHY_V2               BIT(MTK_U3_COPHY_V2_BIT)
++#define MTK_RGMII             BIT_ULL(MTK_RGMII_BIT)
++#define MTK_TRGMII            BIT_ULL(MTK_TRGMII_BIT)
++#define MTK_SGMII             BIT_ULL(MTK_SGMII_BIT)
++#define MTK_ESW                       BIT_ULL(MTK_ESW_BIT)
++#define MTK_GEPHY             BIT_ULL(MTK_GEPHY_BIT)
++#define MTK_MUX                       BIT_ULL(MTK_MUX_BIT)
++#define MTK_INFRA             BIT_ULL(MTK_INFRA_BIT)
++#define MTK_SHARED_SGMII      BIT_ULL(MTK_SHARED_SGMII_BIT)
++#define MTK_HWLRO             BIT_ULL(MTK_HWLRO_BIT)
++#define MTK_SHARED_INT                BIT_ULL(MTK_SHARED_INT_BIT)
++#define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT)
++#define MTK_QDMA              BIT_ULL(MTK_QDMA_BIT)
++#define MTK_SOC_MT7628                BIT_ULL(MTK_SOC_MT7628_BIT)
++#define MTK_RSTCTRL_PPE1      BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
++#define MTK_U3_COPHY_V2               BIT_ULL(MTK_U3_COPHY_V2_BIT)
+ #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
+-      BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
++      BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
+ #define MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY      \
+-      BIT(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
++      BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
+ #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY          \
+-      BIT(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
++      BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
+ #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII        \
+-      BIT(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
++      BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
+ #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII     \
+-      BIT(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
++      BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
+ /* Supported path present on SoCs */
+-#define MTK_ETH_PATH_GMAC1_RGMII      BIT(MTK_ETH_PATH_GMAC1_RGMII_BIT)
+-#define MTK_ETH_PATH_GMAC1_TRGMII     BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
+-#define MTK_ETH_PATH_GMAC1_SGMII      BIT(MTK_ETH_PATH_GMAC1_SGMII_BIT)
+-#define MTK_ETH_PATH_GMAC2_RGMII      BIT(MTK_ETH_PATH_GMAC2_RGMII_BIT)
+-#define MTK_ETH_PATH_GMAC2_SGMII      BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT)
+-#define MTK_ETH_PATH_GMAC2_GEPHY      BIT(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
+-#define MTK_ETH_PATH_GDM1_ESW         BIT(MTK_ETH_PATH_GDM1_ESW_BIT)
++#define MTK_ETH_PATH_GMAC1_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
++#define MTK_ETH_PATH_GMAC1_TRGMII     BIT_ULL(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
++#define MTK_ETH_PATH_GMAC1_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
++#define MTK_ETH_PATH_GMAC2_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
++#define MTK_ETH_PATH_GMAC2_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
++#define MTK_ETH_PATH_GMAC2_GEPHY      BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
++#define MTK_ETH_PATH_GDM1_ESW         BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
+ #define MTK_GMAC1_RGMII               (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
+ #define MTK_GMAC1_TRGMII      (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
+@@ -1042,7 +1042,7 @@ struct mtk_reg_map {
+ struct mtk_soc_data {
+       const struct mtk_reg_map *reg_map;
+       u32             ana_rgc3;
+-      u32             caps;
++      u64             caps;
+       u32             required_clks;
+       bool            required_pctl;
+       u8              offload_version;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch b/target/linux/generic/backport-5.15/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch
new file mode 100644 (file)
index 0000000..4e5b857
--- /dev/null
@@ -0,0 +1,132 @@
+From a1c9f7d1d24e90294f6a6755b137fcf306851e93 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 25 Jul 2023 01:53:28 +0100
+Subject: [PATCH 104/250] net: ethernet: mtk_eth_soc: convert clock bitmap to
+ u64
+
+The to-be-added MT7988 SoC adds many new clocks which need to be
+controlled by the Ethernet driver, which will result in their total
+number exceeding 32.
+Prepare by converting clock bitmaps into 64-bit types.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/6960a39bb0078cf84d7642a9558e6a91c6cc9df3.1690246066.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 96 +++++++++++----------
+ 1 file changed, 49 insertions(+), 47 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -663,54 +663,56 @@ enum mtk_clks_map {
+       MTK_CLK_MAX
+ };
+-#define MT7623_CLKS_BITMAP    (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) |  \
+-                               BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \
+-                               BIT(MTK_CLK_TRGPLL))
+-#define MT7622_CLKS_BITMAP    (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) |  \
+-                               BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
+-                               BIT(MTK_CLK_GP2) | \
+-                               BIT(MTK_CLK_SGMII_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII_CDR_FB) | \
+-                               BIT(MTK_CLK_SGMII_CK) | \
+-                               BIT(MTK_CLK_ETH2PLL))
++#define MT7623_CLKS_BITMAP    (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) |  \
++                               BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
++                               BIT_ULL(MTK_CLK_TRGPLL))
++#define MT7622_CLKS_BITMAP    (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) |  \
++                               BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
++                               BIT_ULL(MTK_CLK_GP2) | \
++                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
++                               BIT_ULL(MTK_CLK_SGMII_CK) | \
++                               BIT_ULL(MTK_CLK_ETH2PLL))
+ #define MT7621_CLKS_BITMAP    (0)
+ #define MT7628_CLKS_BITMAP    (0)
+-#define MT7629_CLKS_BITMAP    (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) |  \
+-                               BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
+-                               BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \
+-                               BIT(MTK_CLK_SGMII_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII_CDR_FB) | \
+-                               BIT(MTK_CLK_SGMII2_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII2_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII2_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII2_CDR_FB) | \
+-                               BIT(MTK_CLK_SGMII_CK) | \
+-                               BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
+-#define MT7981_CLKS_BITMAP    (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
+-                               BIT(MTK_CLK_WOCPU0) | \
+-                               BIT(MTK_CLK_SGMII_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII_CDR_FB) | \
+-                               BIT(MTK_CLK_SGMII2_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII2_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII2_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII2_CDR_FB) | \
+-                               BIT(MTK_CLK_SGMII_CK))
+-#define MT7986_CLKS_BITMAP    (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
+-                               BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
+-                               BIT(MTK_CLK_SGMII_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII_CDR_FB) | \
+-                               BIT(MTK_CLK_SGMII2_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII2_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII2_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII2_CDR_FB))
++#define MT7629_CLKS_BITMAP    (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) |  \
++                               BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
++                               BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \
++                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
++                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
++                               BIT_ULL(MTK_CLK_SGMII_CK) | \
++                               BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP))
++#define MT7981_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \
++                               BIT_ULL(MTK_CLK_GP1) | \
++                               BIT_ULL(MTK_CLK_WOCPU0) | \
++                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
++                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
++                               BIT_ULL(MTK_CLK_SGMII_CK))
++#define MT7986_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \
++                               BIT_ULL(MTK_CLK_GP1) | \
++                               BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \
++                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
++                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
+ enum mtk_dev_state {
+       MTK_HW_INIT,
+@@ -1043,7 +1045,7 @@ struct mtk_soc_data {
+       const struct mtk_reg_map *reg_map;
+       u32             ana_rgc3;
+       u64             caps;
+-      u32             required_clks;
++      u64             required_clks;
+       bool            required_pctl;
+       u8              offload_version;
+       u8              hash_offset;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch b/target/linux/generic/backport-5.15/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch
new file mode 100644 (file)
index 0000000..028c28b
--- /dev/null
@@ -0,0 +1,477 @@
+From 94f825a7eadfc8b4c8828efdb7705d9703f9c73e Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 25 Jul 2023 01:57:42 +0100
+Subject: [PATCH 105/250] net: ethernet: mtk_eth_soc: add basic support for
+ MT7988 SoC
+
+Introduce support for ethernet chip available in MT7988 SoC to
+mtk_eth_soc driver. As a first step support only the first GMAC which
+is hard-wired to the internal DSA switch having 4 built-in gigabit
+Ethernet PHYs.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/25c8377095b95d186872eeda7aa055da83e8f0ca.1690246605.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_path.c |  14 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c  | 201 +++++++++++++++++--
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h  |  86 +++++++-
+ 3 files changed, 273 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
+@@ -43,7 +43,7 @@ static const char *mtk_eth_path_name(u64
+ static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
+ {
+       bool updated = true;
+-      u32 val, mask, set;
++      u32 mask, set, reg;
+       switch (path) {
+       case MTK_ETH_PATH_GMAC1_SGMII:
+@@ -59,11 +59,13 @@ static int set_mux_gdm1_to_gmac1_esw(str
+               break;
+       }
+-      if (updated) {
+-              val = mtk_r32(eth, MTK_MAC_MISC);
+-              val = (val & mask) | set;
+-              mtk_w32(eth, val, MTK_MAC_MISC);
+-      }
++      if (mtk_is_netsys_v3_or_greater(eth))
++              reg = MTK_MAC_MISC_V3;
++      else
++              reg = MTK_MAC_MISC;
++
++      if (updated)
++              mtk_m32(eth, mask, set, reg);
+       dev_dbg(eth->dev, "path %s in %s updated = %d\n",
+               mtk_eth_path_name(path), __func__, updated);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r
+       .pse_oq_sta             = 0x01a0,
+ };
++static const struct mtk_reg_map mt7988_reg_map = {
++      .tx_irq_mask            = 0x461c,
++      .tx_irq_status          = 0x4618,
++      .pdma = {
++              .rx_ptr         = 0x6900,
++              .rx_cnt_cfg     = 0x6904,
++              .pcrx_ptr       = 0x6908,
++              .glo_cfg        = 0x6a04,
++              .rst_idx        = 0x6a08,
++              .delay_irq      = 0x6a0c,
++              .irq_status     = 0x6a20,
++              .irq_mask       = 0x6a28,
++              .adma_rx_dbg0   = 0x6a38,
++              .int_grp        = 0x6a50,
++      },
++      .qdma = {
++              .qtx_cfg        = 0x4400,
++              .qtx_sch        = 0x4404,
++              .rx_ptr         = 0x4500,
++              .rx_cnt_cfg     = 0x4504,
++              .qcrx_ptr       = 0x4508,
++              .glo_cfg        = 0x4604,
++              .rst_idx        = 0x4608,
++              .delay_irq      = 0x460c,
++              .fc_th          = 0x4610,
++              .int_grp        = 0x4620,
++              .hred           = 0x4644,
++              .ctx_ptr        = 0x4700,
++              .dtx_ptr        = 0x4704,
++              .crx_ptr        = 0x4710,
++              .drx_ptr        = 0x4714,
++              .fq_head        = 0x4720,
++              .fq_tail        = 0x4724,
++              .fq_count       = 0x4728,
++              .fq_blen        = 0x472c,
++              .tx_sch_rate    = 0x4798,
++      },
++      .gdm1_cnt               = 0x1c00,
++      .gdma_to_ppe0           = 0x3333,
++      .ppe_base               = 0x2000,
++      .wdma_base = {
++              [0]             = 0x4800,
++              [1]             = 0x4c00,
++      },
++      .pse_iq_sta             = 0x0180,
++      .pse_oq_sta             = 0x01a0,
++};
++
+ /* strings used by ethtool */
+ static const struct mtk_ethtool_stats {
+       char str[ETH_GSTRING_LEN];
+@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats {
+ };
+ static const char * const mtk_clks_source_name[] = {
+-      "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll",
+-      "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb",
+-      "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb",
+-      "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1"
++      "ethif",
++      "sgmiitop",
++      "esw",
++      "gp0",
++      "gp1",
++      "gp2",
++      "gp3",
++      "xgp1",
++      "xgp2",
++      "xgp3",
++      "crypto",
++      "fe",
++      "trgpll",
++      "sgmii_tx250m",
++      "sgmii_rx250m",
++      "sgmii_cdr_ref",
++      "sgmii_cdr_fb",
++      "sgmii2_tx250m",
++      "sgmii2_rx250m",
++      "sgmii2_cdr_ref",
++      "sgmii2_cdr_fb",
++      "sgmii_ck",
++      "eth2pll",
++      "wocpu0",
++      "wocpu1",
++      "netsys0",
++      "netsys1",
++      "ethwarp_wocpu2",
++      "ethwarp_wocpu1",
++      "ethwarp_wocpu0",
++      "top_usxgmii0_sel",
++      "top_usxgmii1_sel",
++      "top_sgm0_sel",
++      "top_sgm1_sel",
++      "top_xfi_phy0_xtal_sel",
++      "top_xfi_phy1_xtal_sel",
++      "top_eth_gmii_sel",
++      "top_eth_refck_50m_sel",
++      "top_eth_sys_200m_sel",
++      "top_eth_sys_sel",
++      "top_eth_xgmii_sel",
++      "top_eth_mii_sel",
++      "top_netsys_sel",
++      "top_netsys_500m_sel",
++      "top_netsys_pao_2x_sel",
++      "top_netsys_sync_250m_sel",
++      "top_netsys_ppefb_250m_sel",
++      "top_netsys_warp_sel",
+ };
+ void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
+@@ -195,7 +287,7 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
+       return __raw_readl(eth->base + reg);
+ }
+-static u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned reg)
++u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg)
+ {
+       u32 val;
+@@ -326,6 +418,19 @@ static void mtk_gmac0_rgmii_adjust(struc
+       dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n");
+ }
++static void mtk_setup_bridge_switch(struct mtk_eth *eth)
++{
++      /* Force Port1 XGMAC Link Up */
++      mtk_m32(eth, 0, MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID),
++              MTK_XGMAC_STS(MTK_GMAC1_ID));
++
++      /* Adjust GSW bridge IPG to 11 */
++      mtk_m32(eth, GSWTX_IPG_MASK | GSWRX_IPG_MASK,
++              (GSW_IPG_11 << GSWTX_IPG_SHIFT) |
++              (GSW_IPG_11 << GSWRX_IPG_SHIFT),
++              MTK_GSW_CFG);
++}
++
+ static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
+                                             phy_interface_t interface)
+ {
+@@ -395,6 +500,8 @@ static void mtk_mac_config(struct phylin
+                                       goto init_err;
+                       }
+                       break;
++              case PHY_INTERFACE_MODE_INTERNAL:
++                      break;
+               default:
+                       goto err_phy;
+               }
+@@ -472,6 +579,15 @@ static void mtk_mac_config(struct phylin
+               return;
+       }
++      /* Setup gmac */
++      if (mtk_is_netsys_v3_or_greater(eth) &&
++          mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
++              mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
++              mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
++
++              mtk_setup_bridge_switch(eth);
++      }
++
+       return;
+ err_phy:
+@@ -682,11 +798,15 @@ static int mtk_mdio_init(struct mtk_eth
+       }
+       divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
++      /* Configure MDC Turbo Mode */
++      if (mtk_is_netsys_v3_or_greater(eth))
++              mtk_m32(eth, 0, MISC_MDC_TURBO, MTK_MAC_MISC_V3);
++
+       /* Configure MDC Divider */
+-      val = mtk_r32(eth, MTK_PPSC);
+-      val &= ~PPSC_MDC_CFG;
+-      val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO;
+-      mtk_w32(eth, val, MTK_PPSC);
++      val = FIELD_PREP(PPSC_MDC_CFG, divider);
++      if (!mtk_is_netsys_v3_or_greater(eth))
++              val |= PPSC_MDC_TURBO;
++      mtk_m32(eth, PPSC_MDC_CFG, val, MTK_PPSC);
+       dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
+@@ -1145,10 +1265,19 @@ static void mtk_tx_set_dma_desc_v2(struc
+               data |= TX_DMA_LS0;
+       WRITE_ONCE(desc->txd3, data);
+-      if (mac->id == MTK_GMAC3_ID)
+-              data = PSE_GDM3_PORT;
+-      else
+-              data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
++       /* set forward port */
++      switch (mac->id) {
++      case MTK_GMAC1_ID:
++              data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2;
++              break;
++      case MTK_GMAC2_ID:
++              data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2;
++              break;
++      case MTK_GMAC3_ID:
++              data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2;
++              break;
++      }
++
+       data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
+       WRITE_ONCE(desc->txd4, data);
+@@ -4304,6 +4433,17 @@ static int mtk_add_mac(struct mtk_eth *e
+                         mac->phylink_config.supported_interfaces);
+       }
++      if (mtk_is_netsys_v3_or_greater(mac->hw) &&
++          MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW_BIT) &&
++          id == MTK_GMAC1_ID) {
++              mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE |
++                                                     MAC_SYM_PAUSE |
++                                                     MAC_10000FD;
++              phy_interface_zero(mac->phylink_config.supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_INTERNAL,
++                        mac->phylink_config.supported_interfaces);
++      }
++
+       phylink = phylink_create(&mac->phylink_config,
+                                of_fwnode_handle(mac->of_node),
+                                phy_mode, &mtk_phylink_ops);
+@@ -4826,6 +4966,24 @@ static const struct mtk_soc_data mt7986_
+       },
+ };
++static const struct mtk_soc_data mt7988_data = {
++      .reg_map = &mt7988_reg_map,
++      .ana_rgc3 = 0x128,
++      .caps = MT7988_CAPS,
++      .hw_features = MTK_HW_FEATURES,
++      .required_clks = MT7988_CLKS_BITMAP,
++      .required_pctl = false,
++      .version = 3,
++      .txrx = {
++              .txd_size = sizeof(struct mtk_tx_dma_v2),
++              .rxd_size = sizeof(struct mtk_rx_dma_v2),
++              .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
++              .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
++              .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
++              .dma_len_offset = 8,
++      },
++};
++
+ static const struct mtk_soc_data rt5350_data = {
+       .reg_map = &mt7628_reg_map,
+       .caps = MT7628_CAPS,
+@@ -4844,14 +5002,15 @@ static const struct mtk_soc_data rt5350_
+ };
+ const struct of_device_id of_mtk_match[] = {
+-      { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
+-      { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
+-      { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
+-      { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
+-      { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
+-      { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
+-      { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
+-      { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
++      { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data },
++      { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data },
++      { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data },
++      { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data },
++      { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data },
++      { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data },
++      { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data },
++      { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data },
++      { .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, of_mtk_match);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -117,7 +117,8 @@
+ #define MTK_CDMP_EG_CTRL      0x404
+ /* GDM Exgress Control Register */
+-#define MTK_GDMA_FWD_CFG(x)   (0x500 + (x * 0x1000))
++#define MTK_GDMA_FWD_CFG(x)   ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ?   \
++                                 0x540 : 0x500 + (_x * 0x1000); })
+ #define MTK_GDMA_SPECIAL_TAG  BIT(24)
+ #define MTK_GDMA_ICS_EN               BIT(22)
+ #define MTK_GDMA_TCS_EN               BIT(21)
+@@ -126,6 +127,11 @@
+ #define MTK_GDMA_TO_PDMA      0x0
+ #define MTK_GDMA_DROP_ALL       0x7777
++/* GDM Egress Control Register */
++#define MTK_GDMA_EG_CTRL(x)   ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ?   \
++                                 0x544 : 0x504 + (_x * 0x1000); })
++#define MTK_GDMA_XGDM_SEL     BIT(31)
++
+ /* Unicast Filter MAC Address Register - Low */
+ #define MTK_GDMA_MAC_ADRL(x)  (0x508 + (x * 0x1000))
+@@ -386,7 +392,26 @@
+ #define PHY_IAC_TIMEOUT               HZ
+ #define MTK_MAC_MISC          0x1000c
++#define MTK_MAC_MISC_V3               0x10010
+ #define MTK_MUX_TO_ESW                BIT(0)
++#define MISC_MDC_TURBO                BIT(4)
++
++/* XMAC status registers */
++#define MTK_XGMAC_STS(x)      (((x) == MTK_GMAC3_ID) ? 0x1001C : 0x1000C)
++#define MTK_XGMAC_FORCE_LINK(x)       (((x) == MTK_GMAC2_ID) ? BIT(31) : BIT(15))
++#define MTK_USXGMII_PCS_LINK  BIT(8)
++#define MTK_XGMAC_RX_FC               BIT(5)
++#define MTK_XGMAC_TX_FC               BIT(4)
++#define MTK_USXGMII_PCS_MODE  GENMASK(3, 1)
++#define MTK_XGMAC_LINK_STS    BIT(0)
++
++/* GSW bridge registers */
++#define MTK_GSW_CFG           (0x10080)
++#define GSWTX_IPG_MASK                GENMASK(19, 16)
++#define GSWTX_IPG_SHIFT               16
++#define GSWRX_IPG_MASK                GENMASK(3, 0)
++#define GSWRX_IPG_SHIFT               0
++#define GSW_IPG_11            11
+ /* Mac control registers */
+ #define MTK_MAC_MCR(x)                (0x10100 + (x * 0x100))
+@@ -644,6 +669,11 @@ enum mtk_clks_map {
+       MTK_CLK_GP0,
+       MTK_CLK_GP1,
+       MTK_CLK_GP2,
++      MTK_CLK_GP3,
++      MTK_CLK_XGP1,
++      MTK_CLK_XGP2,
++      MTK_CLK_XGP3,
++      MTK_CLK_CRYPTO,
+       MTK_CLK_FE,
+       MTK_CLK_TRGPLL,
+       MTK_CLK_SGMII_TX_250M,
+@@ -660,6 +690,27 @@ enum mtk_clks_map {
+       MTK_CLK_WOCPU1,
+       MTK_CLK_NETSYS0,
+       MTK_CLK_NETSYS1,
++      MTK_CLK_ETHWARP_WOCPU2,
++      MTK_CLK_ETHWARP_WOCPU1,
++      MTK_CLK_ETHWARP_WOCPU0,
++      MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
++      MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
++      MTK_CLK_TOP_SGM_0_SEL,
++      MTK_CLK_TOP_SGM_1_SEL,
++      MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
++      MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
++      MTK_CLK_TOP_ETH_GMII_SEL,
++      MTK_CLK_TOP_ETH_REFCK_50M_SEL,
++      MTK_CLK_TOP_ETH_SYS_200M_SEL,
++      MTK_CLK_TOP_ETH_SYS_SEL,
++      MTK_CLK_TOP_ETH_XGMII_SEL,
++      MTK_CLK_TOP_ETH_MII_SEL,
++      MTK_CLK_TOP_NETSYS_SEL,
++      MTK_CLK_TOP_NETSYS_500M_SEL,
++      MTK_CLK_TOP_NETSYS_PAO_2X_SEL,
++      MTK_CLK_TOP_NETSYS_SYNC_250M_SEL,
++      MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL,
++      MTK_CLK_TOP_NETSYS_WARP_SEL,
+       MTK_CLK_MAX
+ };
+@@ -713,6 +764,36 @@ enum mtk_clks_map {
+                                BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
+                                BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
+                                BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
++#define MT7988_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \
++                               BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
++                               BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
++                               BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
++                               BIT_ULL(MTK_CLK_CRYPTO) | \
++                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
++                               BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
++                               BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
++                               BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
++                               BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL))
+ enum mtk_dev_state {
+       MTK_HW_INIT,
+@@ -961,6 +1042,8 @@ enum mkt_eth_capabilities {
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_RSTCTRL_PPE1)
++#define MT7988_CAPS  (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1)
++
+ struct mtk_tx_dma_desc_info {
+       dma_addr_t      addr;
+       u32             size;
+@@ -1306,6 +1389,7 @@ void mtk_stats_update_mac(struct mtk_mac
+ void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
+ u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
++u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
+ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
+ int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
diff --git a/target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch b/target/linux/generic/backport-5.15/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch
new file mode 100644 (file)
index 0000000..0a2bc6a
--- /dev/null
@@ -0,0 +1,27 @@
+From 38a7eb76220731eff40602cf433f24880be0a6c2 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Thu, 27 Jul 2023 09:02:26 +0200
+Subject: [PATCH 106/250] net: ethernet: mtk_eth_soc: enable page_pool support
+ for MT7988 SoC
+
+In order to recycle pages, enable page_pool allocator for MT7988 SoC.
+
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/r/fd4e8693980e47385a543e7b002eec0b88bd09df.1690440675.git.lorenzo@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1613,7 +1613,7 @@ static void mtk_update_rx_cpu_idx(struct
+ static bool mtk_page_pool_enabled(struct mtk_eth *eth)
+ {
+-      return eth->soc->version == 2;
++      return mtk_is_netsys_v2_or_greater(eth);
+ }
+ static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
diff --git a/target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch b/target/linux/generic/backport-5.15/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch
new file mode 100644 (file)
index 0000000..b32670d
--- /dev/null
@@ -0,0 +1,135 @@
+From 199e7d5a7f03dd377f3a7a458360dbedd71d50ba Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Thu, 27 Jul 2023 09:07:28 +0200
+Subject: [PATCH 107/250] net: ethernet: mtk_eth_soc: enable nft hw
+ flowtable_offload for MT7988 SoC
+
+Enable hw Packet Process Engine (PPE) for MT7988 SoC.
+
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/r/5e86341b0220a49620dadc02d77970de5ded9efc.1690441576.git.lorenzo@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c |  3 +++
+ drivers/net/ethernet/mediatek/mtk_ppe.c     | 19 +++++++++++++++----
+ drivers/net/ethernet/mediatek/mtk_ppe.h     | 19 ++++++++++++++++++-
+ 3 files changed, 36 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4974,6 +4974,9 @@ static const struct mtk_soc_data mt7988_
+       .required_clks = MT7988_CLKS_BITMAP,
+       .required_pctl = false,
+       .version = 3,
++      .offload_version = 2,
++      .hash_offset = 4,
++      .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma_v2),
+               .rxd_size = sizeof(struct mtk_rx_dma_v2),
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -422,13 +422,22 @@ int mtk_foe_entry_set_wdma(struct mtk_et
+       struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
+       u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
+-      if (mtk_is_netsys_v2_or_greater(eth)) {
++      switch (eth->soc->version) {
++      case 3:
++              *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
++              *ib2 |=  FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
++                       MTK_FOE_IB2_WDMA_WINFO_V2;
++              l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) |
++                           FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss);
++              break;
++      case 2:
+               *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
+               *ib2 |=  FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
+                        MTK_FOE_IB2_WDMA_WINFO_V2;
+               l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) |
+                           FIELD_PREP(MTK_FOE_WINFO_BSS, bss);
+-      } else {
++              break;
++      default:
+               *ib2 &= ~MTK_FOE_IB2_PORT_MG;
+               *ib2 |= MTK_FOE_IB2_WDMA_WINFO;
+               if (wdma_idx)
+@@ -436,6 +445,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
+               l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) |
+                           FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) |
+                           FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq);
++              break;
+       }
+       return 0;
+@@ -956,8 +966,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
+       mtk_ppe_init_foe_table(ppe);
+       ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys);
+-      val = MTK_PPE_TB_CFG_ENTRY_80B |
+-            MTK_PPE_TB_CFG_AGE_NON_L4 |
++      val = MTK_PPE_TB_CFG_AGE_NON_L4 |
+             MTK_PPE_TB_CFG_AGE_UNBIND |
+             MTK_PPE_TB_CFG_AGE_TCP |
+             MTK_PPE_TB_CFG_AGE_UDP |
+@@ -973,6 +982,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
+                        MTK_PPE_ENTRIES_SHIFT);
+       if (mtk_is_netsys_v2_or_greater(ppe->eth))
+               val |= MTK_PPE_TB_CFG_INFO_SEL;
++      if (!mtk_is_netsys_v3_or_greater(ppe->eth))
++              val |= MTK_PPE_TB_CFG_ENTRY_80B;
+       ppe_w32(ppe, MTK_PPE_TB_CFG, val);
+       ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK,
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -85,6 +85,17 @@ enum {
+ #define MTK_FOE_WINFO_BSS             GENMASK(5, 0)
+ #define MTK_FOE_WINFO_WCID            GENMASK(15, 6)
++#define MTK_FOE_WINFO_BSS_V3          GENMASK(23, 16)
++#define MTK_FOE_WINFO_WCID_V3         GENMASK(15, 0)
++
++#define MTK_FOE_WINFO_PAO_USR_INFO    GENMASK(15, 0)
++#define MTK_FOE_WINFO_PAO_TID         GENMASK(19, 16)
++#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE        BIT(20)
++#define MTK_FOE_WINFO_PAO_IS_PRIOR    BIT(21)
++#define MTK_FOE_WINFO_PAO_IS_SP               BIT(22)
++#define MTK_FOE_WINFO_PAO_HF          BIT(23)
++#define MTK_FOE_WINFO_PAO_AMSDU_EN    BIT(24)
++
+ enum {
+       MTK_FOE_STATE_INVALID,
+       MTK_FOE_STATE_UNBIND,
+@@ -106,8 +117,13 @@ struct mtk_foe_mac_info {
+       u16 pppoe_id;
+       u16 src_mac_lo;
++      /* netsys_v2 */
+       u16 minfo;
+       u16 winfo;
++
++      /* netsys_v3 */
++      u32 w3info;
++      u32 wpao;
+ };
+ /* software-only entry type */
+@@ -218,6 +234,7 @@ struct mtk_foe_ipv6_6rd {
+ #define MTK_FOE_ENTRY_V1_SIZE 80
+ #define MTK_FOE_ENTRY_V2_SIZE 96
++#define MTK_FOE_ENTRY_V3_SIZE 128
+ struct mtk_foe_entry {
+       u32 ib1;
+@@ -228,7 +245,7 @@ struct mtk_foe_entry {
+               struct mtk_foe_ipv4_dslite dslite;
+               struct mtk_foe_ipv6 ipv6;
+               struct mtk_foe_ipv6_6rd ipv6_6rd;
+-              u32 data[23];
++              u32 data[31];
+       };
+ };
diff --git a/target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch b/target/linux/generic/backport-5.15/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch
new file mode 100644 (file)
index 0000000..f314550
--- /dev/null
@@ -0,0 +1,78 @@
+From 0c024632c1e7ff69914329bfd87bec749b9c0aed Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 2 Aug 2023 04:31:09 +0100
+Subject: [PATCH 108/250] net: ethernet: mtk_eth_soc: support per-flow
+ accounting on MT7988
+
+NETSYS_V3 uses 64 bits for each counters while older SoCs are using
+48/40 bits for each counter.
+Support reading per-flow byte and package counters on NETSYS_V3.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/37a0928fa8c1253b197884c68ce1f54239421ac5.1690946442.git.daniel@makrotopia.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c  |  1 +
+ drivers/net/ethernet/mediatek/mtk_ppe.c      | 21 +++++++++++++-------
+ drivers/net/ethernet/mediatek/mtk_ppe_regs.h |  2 ++
+ 3 files changed, 17 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4976,6 +4976,7 @@ static const struct mtk_soc_data mt7988_
+       .version = 3,
+       .offload_version = 2,
+       .hash_offset = 4,
++      .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma_v2),
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -91,7 +91,6 @@ static int mtk_ppe_mib_wait_busy(struct
+ static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
+ {
+-      u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
+       u32 val, cnt_r0, cnt_r1, cnt_r2;
+       int ret;
+@@ -106,12 +105,20 @@ static int mtk_mib_entry_read(struct mtk
+       cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
+       cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
+-      byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
+-      byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
+-      pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
+-      pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
+-      *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
+-      *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
++      if (mtk_is_netsys_v3_or_greater(ppe->eth)) {
++              /* 64 bit for each counter */
++              u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3);
++              *bytes = ((u64)cnt_r1 << 32) | cnt_r0;
++              *packets = ((u64)cnt_r3 << 32) | cnt_r2;
++      } else {
++              /* 48 bit byte counter, 40 bit packet counter */
++              u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
++              u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
++              u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
++              u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
++              *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
++              *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
++      }
+       return 0;
+ }
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
+@@ -163,6 +163,8 @@ enum {
+ #define MTK_PPE_MIB_SER_R2                    0x348
+ #define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH               GENMASK(23, 0)
++#define MTK_PPE_MIB_SER_R3                    0x34c
++
+ #define MTK_PPE_MIB_CACHE_CTL                 0x350
+ #define MTK_PPE_MIB_CACHE_CTL_EN              BIT(0)
+ #define MTK_PPE_MIB_CACHE_CTL_FLUSH           BIT(2)
diff --git a/target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch b/target/linux/generic/backport-5.15/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch
new file mode 100644 (file)
index 0000000..6f1639a
--- /dev/null
@@ -0,0 +1,52 @@
+From 3b12f42772c26869d60398c1710aa27b27cd945c Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 21 Aug 2023 17:12:44 +0100
+Subject: [PATCH 109/250] net: ethernet: mtk_eth_soc: fix NULL pointer on hw
+ reset
+
+When a hardware reset is triggered on devices not initializing WED the
+calls to mtk_wed_fe_reset and mtk_wed_fe_reset_complete dereference a
+pointer on uninitialized stack memory.
+Break out of both functions in case a hw_list entry is 0.
+
+Fixes: 08a764a7c51b ("net: ethernet: mtk_wed: add reset/reset_complete callbacks")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/r/5465c1609b464cc7407ae1530c40821dcdf9d3e6.1692634266.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_wed.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -214,9 +214,13 @@ void mtk_wed_fe_reset(void)
+       for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
+               struct mtk_wed_hw *hw = hw_list[i];
+-              struct mtk_wed_device *dev = hw->wed_dev;
++              struct mtk_wed_device *dev;
+               int err;
++              if (!hw)
++                      break;
++
++              dev = hw->wed_dev;
+               if (!dev || !dev->wlan.reset)
+                       continue;
+@@ -237,8 +241,12 @@ void mtk_wed_fe_reset_complete(void)
+       for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
+               struct mtk_wed_hw *hw = hw_list[i];
+-              struct mtk_wed_device *dev = hw->wed_dev;
++              struct mtk_wed_device *dev;
++
++              if (!hw)
++                      break;
++              dev = hw->wed_dev;
+               if (!dev || !dev->wlan.reset_complete)
+                       continue;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch b/target/linux/generic/backport-5.15/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch
new file mode 100644 (file)
index 0000000..3597794
--- /dev/null
@@ -0,0 +1,44 @@
+From 489aea123d74a846ce746bfdb3efe1e7ad512e0d Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 22 Aug 2023 17:31:24 +0100
+Subject: [PATCH 110/250] net: ethernet: mtk_eth_soc: fix register definitions
+ for MT7988
+
+More register macros need to be adjusted for the 3rd GMAC on MT7988.
+Account for added bit in SYSCFG0_SGMII_MASK.
+
+Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/1c8da012e2ca80939906d85f314138c552139f0f.1692721443.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -133,10 +133,12 @@
+ #define MTK_GDMA_XGDM_SEL     BIT(31)
+ /* Unicast Filter MAC Address Register - Low */
+-#define MTK_GDMA_MAC_ADRL(x)  (0x508 + (x * 0x1000))
++#define MTK_GDMA_MAC_ADRL(x)  ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ?   \
++                                 0x548 : 0x508 + (_x * 0x1000); })
+ /* Unicast Filter MAC Address Register - High */
+-#define MTK_GDMA_MAC_ADRH(x)  (0x50C + (x * 0x1000))
++#define MTK_GDMA_MAC_ADRH(x)  ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ?   \
++                                 0x54C : 0x50C + (_x * 0x1000); })
+ /* FE global misc reg*/
+ #define MTK_FE_GLO_MISC         0x124
+@@ -500,7 +502,7 @@
+ #define ETHSYS_SYSCFG0                0x14
+ #define SYSCFG0_GE_MASK               0x3
+ #define SYSCFG0_GE_MODE(x, y) (x << (12 + (y * 2)))
+-#define SYSCFG0_SGMII_MASK     GENMASK(9, 8)
++#define SYSCFG0_SGMII_MASK     GENMASK(9, 7)
+ #define SYSCFG0_SGMII_GMAC1    ((2 << 8) & SYSCFG0_SGMII_MASK)
+ #define SYSCFG0_SGMII_GMAC2    ((3 << 8) & SYSCFG0_SGMII_MASK)
+ #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
diff --git a/target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch b/target/linux/generic/backport-5.15/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch
new file mode 100644 (file)
index 0000000..5f6651b
--- /dev/null
@@ -0,0 +1,188 @@
+From 15a84d1c44ae8c1451c265ee60500588a24e8cd6 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 22 Aug 2023 17:32:03 +0100
+Subject: [PATCH 111/250] net: ethernet: mtk_eth_soc: add reset bits for MT7988
+
+Add bits needed to reset the frame engine on MT7988.
+
+Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/89b6c38380e7a3800c1362aa7575600717bc7543.1692721443.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 76 +++++++++++++++------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++--
+ 2 files changed, 68 insertions(+), 24 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3538,19 +3538,34 @@ static void mtk_hw_reset(struct mtk_eth
+ {
+       u32 val;
+-      if (mtk_is_netsys_v2_or_greater(eth)) {
++      if (mtk_is_netsys_v2_or_greater(eth))
+               regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
++
++      if (mtk_is_netsys_v3_or_greater(eth)) {
++              val = RSTCTRL_PPE0_V3;
++
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++                      val |= RSTCTRL_PPE1_V3;
++
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
++                      val |= RSTCTRL_PPE2;
++
++              val |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2;
++      } else if (mtk_is_netsys_v2_or_greater(eth)) {
+               val = RSTCTRL_PPE0_V2;
++
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++                      val |= RSTCTRL_PPE1;
+       } else {
+               val = RSTCTRL_PPE0;
+       }
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+-              val |= RSTCTRL_PPE1;
+-
+       ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
+-      if (mtk_is_netsys_v2_or_greater(eth))
++      if (mtk_is_netsys_v3_or_greater(eth))
++              regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
++                           0x6f8ff);
++      else if (mtk_is_netsys_v2_or_greater(eth))
+               regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
+                            0x3ffffff);
+ }
+@@ -3576,13 +3591,21 @@ static void mtk_hw_warm_reset(struct mtk
+               return;
+       }
+-      if (mtk_is_netsys_v2_or_greater(eth))
++      if (mtk_is_netsys_v3_or_greater(eth)) {
++              rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V3;
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++                      rst_mask |= RSTCTRL_PPE1_V3;
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
++                      rst_mask |= RSTCTRL_PPE2;
++
++              rst_mask |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2;
++      } else if (mtk_is_netsys_v2_or_greater(eth)) {
+               rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
+-      else
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++                      rst_mask |= RSTCTRL_PPE1;
++      } else {
+               rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
+-
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+-              rst_mask |= RSTCTRL_PPE1;
++      }
+       regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask);
+@@ -3934,11 +3957,17 @@ static void mtk_prepare_for_reset(struct
+       u32 val;
+       int i;
+-      /* disabe FE P3 and P4 */
+-      val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3;
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+-              val |= MTK_FE_LINK_DOWN_P4;
+-      mtk_w32(eth, val, MTK_FE_GLO_CFG);
++      /* set FE PPE ports link down */
++      for (i = MTK_GMAC1_ID;
++           i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID);
++           i += 2) {
++              val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) | MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++                      val |= MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
++                      val |= MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT);
++              mtk_w32(eth, val, MTK_FE_GLO_CFG(i));
++      }
+       /* adjust PPE configurations to prepare for reset */
+       for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
+@@ -3999,11 +4028,18 @@ static void mtk_pending_work(struct work
+               }
+       }
+-      /* enabe FE P3 and P4 */
+-      val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3;
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+-              val &= ~MTK_FE_LINK_DOWN_P4;
+-      mtk_w32(eth, val, MTK_FE_GLO_CFG);
++      /* set FE PPE ports link up */
++      for (i = MTK_GMAC1_ID;
++           i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID);
++           i += 2) {
++              val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) & ~MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++                      val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
++                      val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT);
++
++              mtk_w32(eth, val, MTK_FE_GLO_CFG(i));
++      }
+       clear_bit(MTK_RESETTING, &eth->state);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -76,9 +76,8 @@
+ #define       MTK_HW_LRO_SDL_REMAIN_ROOM      1522
+ /* Frame Engine Global Configuration */
+-#define MTK_FE_GLO_CFG                0x00
+-#define MTK_FE_LINK_DOWN_P3   BIT(11)
+-#define MTK_FE_LINK_DOWN_P4   BIT(12)
++#define MTK_FE_GLO_CFG(x)     (((x) == MTK_GMAC3_ID) ? 0x24 : 0x00)
++#define MTK_FE_LINK_DOWN_P(x) BIT(((x) + 8) % 16)
+ /* Frame Engine Global Reset Register */
+ #define MTK_RST_GL            0x04
+@@ -519,9 +518,15 @@
+ /* ethernet reset control register */
+ #define ETHSYS_RSTCTRL                        0x34
+ #define RSTCTRL_FE                    BIT(6)
++#define RSTCTRL_WDMA0                 BIT(24)
++#define RSTCTRL_WDMA1                 BIT(25)
++#define RSTCTRL_WDMA2                 BIT(26)
+ #define RSTCTRL_PPE0                  BIT(31)
+ #define RSTCTRL_PPE0_V2                       BIT(30)
+ #define RSTCTRL_PPE1                  BIT(31)
++#define RSTCTRL_PPE0_V3                       BIT(29)
++#define RSTCTRL_PPE1_V3                       BIT(30)
++#define RSTCTRL_PPE2                  BIT(31)
+ #define RSTCTRL_ETH                   BIT(23)
+ /* ethernet reset check idle register */
+@@ -928,6 +933,7 @@ enum mkt_eth_capabilities {
+       MTK_QDMA_BIT,
+       MTK_SOC_MT7628_BIT,
+       MTK_RSTCTRL_PPE1_BIT,
++      MTK_RSTCTRL_PPE2_BIT,
+       MTK_U3_COPHY_V2_BIT,
+       /* MUX BITS*/
+@@ -962,6 +968,7 @@ enum mkt_eth_capabilities {
+ #define MTK_QDMA              BIT_ULL(MTK_QDMA_BIT)
+ #define MTK_SOC_MT7628                BIT_ULL(MTK_SOC_MT7628_BIT)
+ #define MTK_RSTCTRL_PPE1      BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
++#define MTK_RSTCTRL_PPE2      BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
+ #define MTK_U3_COPHY_V2               BIT_ULL(MTK_U3_COPHY_V2_BIT)
+ #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
+@@ -1044,7 +1051,8 @@ enum mkt_eth_capabilities {
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_RSTCTRL_PPE1)
+-#define MT7988_CAPS  (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1)
++#define MT7988_CAPS  (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
++                    MTK_RSTCTRL_PPE2)
+ struct mtk_tx_dma_desc_info {
+       dma_addr_t      addr;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch b/target/linux/generic/backport-5.15/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch
new file mode 100644 (file)
index 0000000..67ba1a5
--- /dev/null
@@ -0,0 +1,254 @@
+From 25ce45fe40b574e5d7ffa407f7f2db03e7d5a910 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 22 Aug 2023 17:32:54 +0100
+Subject: [PATCH 112/250] net: ethernet: mtk_eth_soc: add support for in-SoC
+ SRAM
+
+MT7981, MT7986 and MT7988 come with in-SoC SRAM dedicated for Ethernet
+DMA rings. Support using the SRAM without breaking existing device tree
+bindings, ie. only new SoC starting from MT7988 will have the SRAM
+declared as additional resource in device tree. For MT7981 and MT7986
+an offset on top of the main I/O base is used.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/e45e0f230c63ad58869e8fe35b95a2fb8925b625.1692721443.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 88 ++++++++++++++++-----
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++-
+ 2 files changed, 78 insertions(+), 22 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1075,10 +1075,13 @@ static int mtk_init_fq_dma(struct mtk_et
+       dma_addr_t dma_addr;
+       int i;
+-      eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
+-                                             cnt * soc->txrx.txd_size,
+-                                             &eth->phy_scratch_ring,
+-                                             GFP_KERNEL);
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM))
++              eth->scratch_ring = eth->sram_base;
++      else
++              eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
++                                                     cnt * soc->txrx.txd_size,
++                                                     &eth->phy_scratch_ring,
++                                                     GFP_KERNEL);
+       if (unlikely(!eth->scratch_ring))
+               return -ENOMEM;
+@@ -2376,8 +2379,14 @@ static int mtk_tx_alloc(struct mtk_eth *
+       if (!ring->buf)
+               goto no_tx_mem;
+-      ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
+-                                     &ring->phys, GFP_KERNEL);
++      if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) {
++              ring->dma = eth->sram_base + ring_size * sz;
++              ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz;
++      } else {
++              ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
++                                             &ring->phys, GFP_KERNEL);
++      }
++
+       if (!ring->dma)
+               goto no_tx_mem;
+@@ -2476,8 +2485,7 @@ static void mtk_tx_clean(struct mtk_eth
+               kfree(ring->buf);
+               ring->buf = NULL;
+       }
+-
+-      if (ring->dma) {
++      if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) {
+               dma_free_coherent(eth->dma_dev,
+                                 ring->dma_size * soc->txrx.txd_size,
+                                 ring->dma, ring->phys);
+@@ -2496,9 +2504,14 @@ static int mtk_rx_alloc(struct mtk_eth *
+ {
+       const struct mtk_reg_map *reg_map = eth->soc->reg_map;
+       struct mtk_rx_ring *ring;
+-      int rx_data_len, rx_dma_size;
++      int rx_data_len, rx_dma_size, tx_ring_size;
+       int i;
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
++              tx_ring_size = MTK_QDMA_RING_SIZE;
++      else
++              tx_ring_size = MTK_DMA_SIZE;
++
+       if (rx_flag == MTK_RX_FLAGS_QDMA) {
+               if (ring_no)
+                       return -EINVAL;
+@@ -2533,9 +2546,20 @@ static int mtk_rx_alloc(struct mtk_eth *
+               ring->page_pool = pp;
+       }
+-      ring->dma = dma_alloc_coherent(eth->dma_dev,
+-                                     rx_dma_size * eth->soc->txrx.rxd_size,
+-                                     &ring->phys, GFP_KERNEL);
++      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) ||
++          rx_flag != MTK_RX_FLAGS_NORMAL) {
++              ring->dma = dma_alloc_coherent(eth->dma_dev,
++                                             rx_dma_size * eth->soc->txrx.rxd_size,
++                                             &ring->phys, GFP_KERNEL);
++      } else {
++              struct mtk_tx_ring *tx_ring = &eth->tx_ring;
++
++              ring->dma = tx_ring->dma + tx_ring_size *
++                          eth->soc->txrx.txd_size * (ring_no + 1);
++              ring->phys = tx_ring->phys + tx_ring_size *
++                           eth->soc->txrx.txd_size * (ring_no + 1);
++      }
++
+       if (!ring->dma)
+               return -ENOMEM;
+@@ -2618,7 +2642,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+       return 0;
+ }
+-static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring)
++static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram)
+ {
+       int i;
+@@ -2641,7 +2665,7 @@ static void mtk_rx_clean(struct mtk_eth
+               ring->data = NULL;
+       }
+-      if (ring->dma) {
++      if (!in_sram && ring->dma) {
+               dma_free_coherent(eth->dma_dev,
+                                 ring->dma_size * eth->soc->txrx.rxd_size,
+                                 ring->dma, ring->phys);
+@@ -3001,7 +3025,7 @@ static void mtk_dma_free(struct mtk_eth
+       for (i = 0; i < MTK_MAX_DEVS; i++)
+               if (eth->netdev[i])
+                       netdev_reset_queue(eth->netdev[i]);
+-      if (eth->scratch_ring) {
++      if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
+               dma_free_coherent(eth->dma_dev,
+                                 MTK_QDMA_RING_SIZE * soc->txrx.txd_size,
+                                 eth->scratch_ring, eth->phy_scratch_ring);
+@@ -3009,13 +3033,13 @@ static void mtk_dma_free(struct mtk_eth
+               eth->phy_scratch_ring = 0;
+       }
+       mtk_tx_clean(eth);
+-      mtk_rx_clean(eth, &eth->rx_ring[0]);
+-      mtk_rx_clean(eth, &eth->rx_ring_qdma);
++      mtk_rx_clean(eth, &eth->rx_ring[0], MTK_HAS_CAPS(soc->caps, MTK_SRAM));
++      mtk_rx_clean(eth, &eth->rx_ring_qdma, false);
+       if (eth->hwlro) {
+               mtk_hwlro_rx_uninit(eth);
+               for (i = 1; i < MTK_MAX_RX_RING_NUM; i++)
+-                      mtk_rx_clean(eth, &eth->rx_ring[i]);
++                      mtk_rx_clean(eth, &eth->rx_ring[i], false);
+       }
+       kfree(eth->scratch_head);
+@@ -4585,7 +4609,7 @@ static int mtk_sgmii_init(struct mtk_eth
+ static int mtk_probe(struct platform_device *pdev)
+ {
+-      struct resource *res = NULL;
++      struct resource *res = NULL, *res_sram;
+       struct device_node *mac_np;
+       struct mtk_eth *eth;
+       int err, i;
+@@ -4605,6 +4629,20 @@ static int mtk_probe(struct platform_dev
+       if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
+               eth->ip_align = NET_IP_ALIGN;
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) {
++              /* SRAM is actual memory and supports transparent access just like DRAM.
++               * Hence we don't require __iomem being set and don't need to use accessor
++               * functions to read from or write to SRAM.
++               */
++              if (mtk_is_netsys_v3_or_greater(eth)) {
++                      eth->sram_base = (void __force *)devm_platform_ioremap_resource(pdev, 1);
++                      if (IS_ERR(eth->sram_base))
++                              return PTR_ERR(eth->sram_base);
++              } else {
++                      eth->sram_base = (void __force *)eth->base + MTK_ETH_SRAM_OFFSET;
++              }
++      }
++
+       spin_lock_init(&eth->page_lock);
+       spin_lock_init(&eth->tx_irq_lock);
+       spin_lock_init(&eth->rx_irq_lock);
+@@ -4668,6 +4706,18 @@ static int mtk_probe(struct platform_dev
+                       err = -EINVAL;
+                       goto err_destroy_sgmii;
+               }
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) {
++                      if (mtk_is_netsys_v3_or_greater(eth)) {
++                              res_sram = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++                              if (!res_sram) {
++                                      err = -EINVAL;
++                                      goto err_destroy_sgmii;
++                              }
++                              eth->phy_scratch_ring = res_sram->start;
++                      } else {
++                              eth->phy_scratch_ring = res->start + MTK_ETH_SRAM_OFFSET;
++                      }
++              }
+       }
+       if (eth->soc->offload_version) {
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -139,6 +139,9 @@
+ #define MTK_GDMA_MAC_ADRH(x)  ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ?   \
+                                  0x54C : 0x50C + (_x * 0x1000); })
++/* Internal SRAM offset */
++#define MTK_ETH_SRAM_OFFSET   0x40000
++
+ /* FE global misc reg*/
+ #define MTK_FE_GLO_MISC         0x124
+@@ -935,6 +938,7 @@ enum mkt_eth_capabilities {
+       MTK_RSTCTRL_PPE1_BIT,
+       MTK_RSTCTRL_PPE2_BIT,
+       MTK_U3_COPHY_V2_BIT,
++      MTK_SRAM_BIT,
+       /* MUX BITS*/
+       MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
+@@ -970,6 +974,7 @@ enum mkt_eth_capabilities {
+ #define MTK_RSTCTRL_PPE1      BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
+ #define MTK_RSTCTRL_PPE2      BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
+ #define MTK_U3_COPHY_V2               BIT_ULL(MTK_U3_COPHY_V2_BIT)
++#define MTK_SRAM              BIT_ULL(MTK_SRAM_BIT)
+ #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
+       BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
+@@ -1045,14 +1050,14 @@ enum mkt_eth_capabilities {
+ #define MT7981_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
+-                    MTK_RSTCTRL_PPE1)
++                    MTK_RSTCTRL_PPE1 | MTK_SRAM)
+ #define MT7986_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+-                    MTK_RSTCTRL_PPE1)
++                    MTK_RSTCTRL_PPE1 | MTK_SRAM)
+ #define MT7988_CAPS  (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
+-                    MTK_RSTCTRL_PPE2)
++                    MTK_RSTCTRL_PPE2 | MTK_SRAM)
+ struct mtk_tx_dma_desc_info {
+       dma_addr_t      addr;
+@@ -1212,6 +1217,7 @@ struct mtk_eth {
+       struct device                   *dev;
+       struct device                   *dma_dev;
+       void __iomem                    *base;
++      void                            *sram_base;
+       spinlock_t                      page_lock;
+       spinlock_t                      tx_irq_lock;
+       spinlock_t                      rx_irq_lock;
diff --git a/target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch b/target/linux/generic/backport-5.15/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch
new file mode 100644 (file)
index 0000000..175db56
--- /dev/null
@@ -0,0 +1,166 @@
+From 0b0d606eb9650fa01dd5621e072aa29a10544399 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 22 Aug 2023 17:33:12 +0100
+Subject: [PATCH 113/250] net: ethernet: mtk_eth_soc: support 36-bit DMA
+ addressing on MT7988
+
+Systems having 4 GiB of RAM and more require DMA addressing beyond the
+current 32-bit limit. Starting from MT7988 the hardware now supports
+36-bit DMA addressing, let's use that new capability in the driver to
+avoid running into swiotlb on systems with 4 GiB of RAM or more.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/95b919c98876c9e49761e44662e7c937479eecb8.1692721443.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++--
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 22 +++++++++++++--
+ 2 files changed, 48 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1266,6 +1266,10 @@ static void mtk_tx_set_dma_desc_v2(struc
+       data = TX_DMA_PLEN0(info->size);
+       if (info->last)
+               data |= TX_DMA_LS0;
++
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
++              data |= TX_DMA_PREP_ADDR64(info->addr);
++
+       WRITE_ONCE(desc->txd3, data);
+        /* set forward port */
+@@ -1933,6 +1937,7 @@ static int mtk_poll_rx(struct napi_struc
+       bool xdp_flush = false;
+       int idx;
+       struct sk_buff *skb;
++      u64 addr64 = 0;
+       u8 *data, *new_data;
+       struct mtk_rx_dma_v2 *rxd, trxd;
+       int done = 0, bytes = 0;
+@@ -2048,7 +2053,10 @@ static int mtk_poll_rx(struct napi_struc
+                               goto release_desc;
+                       }
+-                      dma_unmap_single(eth->dma_dev, trxd.rxd1,
++                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
++                              addr64 = RX_DMA_GET_ADDR64(trxd.rxd2);
++
++                      dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64),
+                                        ring->buf_size, DMA_FROM_DEVICE);
+                       skb = build_skb(data, ring->frag_size);
+@@ -2114,6 +2122,9 @@ release_desc:
+               else
+                       rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
++                      rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
++
+               ring->calc_idx = idx;
+               done++;
+       }
+@@ -2598,6 +2609,9 @@ static int mtk_rx_alloc(struct mtk_eth *
+               else
+                       rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
++                      rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
++
+               rxd->rxd3 = 0;
+               rxd->rxd4 = 0;
+               if (mtk_is_netsys_v2_or_greater(eth)) {
+@@ -2644,6 +2658,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+ static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram)
+ {
++      u64 addr64 = 0;
+       int i;
+       if (ring->data && ring->dma) {
+@@ -2657,7 +2672,10 @@ static void mtk_rx_clean(struct mtk_eth
+                       if (!rxd->rxd1)
+                               continue;
+-                      dma_unmap_single(eth->dma_dev, rxd->rxd1,
++                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
++                              addr64 = RX_DMA_GET_ADDR64(rxd->rxd2);
++
++                      dma_unmap_single(eth->dma_dev, ((u64)rxd->rxd1 | addr64),
+                                        ring->buf_size, DMA_FROM_DEVICE);
+                       mtk_rx_put_buff(ring, ring->data[i], false);
+               }
+@@ -4643,6 +4661,14 @@ static int mtk_probe(struct platform_dev
+               }
+       }
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
++              err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
++              if (err) {
++                      dev_err(&pdev->dev, "Wrong DMA config\n");
++                      return -EINVAL;
++              }
++      }
++
+       spin_lock_init(&eth->page_lock);
+       spin_lock_init(&eth->tx_irq_lock);
+       spin_lock_init(&eth->rx_irq_lock);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -331,6 +331,14 @@
+ #define TX_DMA_PLEN1(x)               ((x) & eth->soc->txrx.dma_max_len)
+ #define TX_DMA_SWC            BIT(14)
+ #define TX_DMA_PQID           GENMASK(3, 0)
++#define TX_DMA_ADDR64_MASK    GENMASK(3, 0)
++#if IS_ENABLED(CONFIG_64BIT)
++# define TX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(TX_DMA_ADDR64_MASK, (x))) << 32)
++# define TX_DMA_PREP_ADDR64(x)        FIELD_PREP(TX_DMA_ADDR64_MASK, ((x) >> 32))
++#else
++# define TX_DMA_GET_ADDR64(x) (0)
++# define TX_DMA_PREP_ADDR64(x)        (0)
++#endif
+ /* PDMA on MT7628 */
+ #define TX_DMA_DONE           BIT(31)
+@@ -343,6 +351,14 @@
+ #define RX_DMA_PREP_PLEN0(x)  (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
+ #define RX_DMA_GET_PLEN0(x)   (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len)
+ #define RX_DMA_VTAG           BIT(15)
++#define RX_DMA_ADDR64_MASK    GENMASK(3, 0)
++#if IS_ENABLED(CONFIG_64BIT)
++# define RX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(RX_DMA_ADDR64_MASK, (x))) << 32)
++# define RX_DMA_PREP_ADDR64(x)        FIELD_PREP(RX_DMA_ADDR64_MASK, ((x) >> 32))
++#else
++# define RX_DMA_GET_ADDR64(x) (0)
++# define RX_DMA_PREP_ADDR64(x)        (0)
++#endif
+ /* QDMA descriptor rxd3 */
+ #define RX_DMA_VID(x)         ((x) & VLAN_VID_MASK)
+@@ -939,6 +955,7 @@ enum mkt_eth_capabilities {
+       MTK_RSTCTRL_PPE2_BIT,
+       MTK_U3_COPHY_V2_BIT,
+       MTK_SRAM_BIT,
++      MTK_36BIT_DMA_BIT,
+       /* MUX BITS*/
+       MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
+@@ -975,6 +992,7 @@ enum mkt_eth_capabilities {
+ #define MTK_RSTCTRL_PPE2      BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
+ #define MTK_U3_COPHY_V2               BIT_ULL(MTK_U3_COPHY_V2_BIT)
+ #define MTK_SRAM              BIT_ULL(MTK_SRAM_BIT)
++#define MTK_36BIT_DMA BIT_ULL(MTK_36BIT_DMA_BIT)
+ #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
+       BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
+@@ -1056,8 +1074,8 @@ enum mkt_eth_capabilities {
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_RSTCTRL_PPE1 | MTK_SRAM)
+-#define MT7988_CAPS  (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
+-                    MTK_RSTCTRL_PPE2 | MTK_SRAM)
++#define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \
++                    MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
+ struct mtk_tx_dma_desc_info {
+       dma_addr_t      addr;
diff --git a/target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch b/target/linux/generic/backport-5.15/792-01-v6.0-net-phylink-disable-PCS-polling-over-major-configura.patch
new file mode 100644 (file)
index 0000000..cda77e3
--- /dev/null
@@ -0,0 +1,81 @@
+From bfac8c490d605bea03b1f1927582b6f396462164 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Mon, 27 Jun 2022 12:44:43 +0100
+Subject: [PATCH] net: phylink: disable PCS polling over major configuration
+
+While we are performing a major configuration, there is no point having
+the PCS polling timer running. Stop it before we begin preparing for
+the configuration change, and restart it only once we've successfully
+completed the change.
+
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c | 30 ++++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -756,6 +756,18 @@ static void phylink_resolve_flow(struct
+       }
+ }
++static void phylink_pcs_poll_stop(struct phylink *pl)
++{
++      if (pl->cfg_link_an_mode == MLO_AN_INBAND)
++              del_timer(&pl->link_poll);
++}
++
++static void phylink_pcs_poll_start(struct phylink *pl)
++{
++      if (pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND)
++              mod_timer(&pl->link_poll, jiffies + HZ);
++}
++
+ static void phylink_mac_config(struct phylink *pl,
+                              const struct phylink_link_state *state)
+ {
+@@ -787,6 +799,7 @@ static void phylink_major_config(struct
+                                 const struct phylink_link_state *state)
+ {
+       struct phylink_pcs *pcs = NULL;
++      bool pcs_changed = false;
+       int err;
+       phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
+@@ -799,8 +812,12 @@ static void phylink_major_config(struct
+                                   pcs);
+                       return;
+               }
++
++              pcs_changed = pcs && pl->pcs != pcs;
+       }
++      phylink_pcs_poll_stop(pl);
++
+       if (pl->mac_ops->mac_prepare) {
+               err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
+                                              state->interface);
+@@ -814,8 +831,10 @@ static void phylink_major_config(struct
+       /* If we have a new PCS, switch to the new PCS after preparing the MAC
+        * for the change.
+        */
+-      if (pcs)
+-              phylink_set_pcs(pl, pcs);
++      if (pcs_changed) {
++              pl->pcs = pcs;
++              pl->pcs_ops = pcs->ops;
++      }
+       phylink_mac_config(pl, state);
+@@ -841,6 +860,8 @@ static void phylink_major_config(struct
+                       phylink_err(pl, "mac_finish failed: %pe\n",
+                                   ERR_PTR(err));
+       }
++
++      phylink_pcs_poll_start(pl);
+ }
+ /*
diff --git a/target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch b/target/linux/generic/backport-5.15/792-02-v6.0-net-phylink-fix-NULL-pl-pcs-dereference-during-phyli.patch
new file mode 100644 (file)
index 0000000..f1f359b
--- /dev/null
@@ -0,0 +1,38 @@
+From b7d78b46d5e8dc77c656c13885d31e931923b915 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Wed, 29 Jun 2022 22:33:58 +0300
+Subject: [PATCH] net: phylink: fix NULL pl->pcs dereference during
+ phylink_pcs_poll_start
+
+The current link mode of the phylink instance may not require an
+attached PCS. However, phylink_major_config() unconditionally
+dereferences this potentially NULL pointer when restarting the link poll
+timer, which will panic the kernel.
+
+Fix the problem by checking whether a PCS exists in phylink_pcs_poll_start(),
+otherwise do nothing. The code prior to the blamed patch also only
+looked at pcs->poll within an "if (pcs)" block.
+
+Fixes: bfac8c490d60 ("net: phylink: disable PCS polling over major configuration")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Tested-by: Gerhard Engleder <gerhard@engleder-embedded.com>
+Tested-by: Michael Walle <michael@walle.cc> # on kontron-kbox-a-230-ls
+Tested-by: Nicolas Ferre <nicolas.ferre@microchip.com> # on sam9x60ek
+Link: https://lore.kernel.org/r/20220629193358.4007923-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -764,7 +764,7 @@ static void phylink_pcs_poll_stop(struct
+ static void phylink_pcs_poll_start(struct phylink *pl)
+ {
+-      if (pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND)
++      if (pl->pcs && pl->pcs->poll && pl->cfg_link_an_mode == MLO_AN_INBAND)
+               mod_timer(&pl->link_poll, jiffies + HZ);
+ }
diff --git a/target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch b/target/linux/generic/backport-5.15/792-03-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch
new file mode 100644 (file)
index 0000000..ceec584
--- /dev/null
@@ -0,0 +1,172 @@
+From 90ef0a7b0622c62758b2638604927867775479ea Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 13 Jul 2023 09:42:07 +0100
+Subject: [PATCH] net: phylink: add pcs_enable()/pcs_disable() methods
+
+Add phylink PCS enable/disable callbacks that will allow us to place
+IEEE 802.3 register compliant PCS in power-down mode while not being
+used.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/phylink.c | 48 +++++++++++++++++++++++++++++++--------
+ include/linux/phylink.h   | 16 +++++++++++++
+ 2 files changed, 55 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -34,6 +34,10 @@ enum {
+       PHYLINK_DISABLE_STOPPED,
+       PHYLINK_DISABLE_LINK,
+       PHYLINK_DISABLE_MAC_WOL,
++
++      PCS_STATE_DOWN = 0,
++      PCS_STATE_STARTING,
++      PCS_STATE_STARTED,
+ };
+ /**
+@@ -72,6 +76,7 @@ struct phylink {
+       struct mutex state_mutex;
+       struct phylink_link_state phy_state;
+       struct work_struct resolve;
++      unsigned int pcs_state;
+       bool mac_link_dropped;
+       bool using_mac_select_pcs;
+@@ -795,6 +800,22 @@ static void phylink_mac_pcs_an_restart(s
+       }
+ }
++static void phylink_pcs_disable(struct phylink_pcs *pcs)
++{
++      if (pcs && pcs->ops->pcs_disable)
++              pcs->ops->pcs_disable(pcs);
++}
++
++static int phylink_pcs_enable(struct phylink_pcs *pcs)
++{
++      int err = 0;
++
++      if (pcs && pcs->ops->pcs_enable)
++              err = pcs->ops->pcs_enable(pcs);
++
++      return err;
++}
++
+ static void phylink_major_config(struct phylink *pl, bool restart,
+                                 const struct phylink_link_state *state)
+ {
+@@ -832,12 +853,16 @@ static void phylink_major_config(struct
+        * for the change.
+        */
+       if (pcs_changed) {
++              phylink_pcs_disable(pl->pcs);
+               pl->pcs = pcs;
+               pl->pcs_ops = pcs->ops;
+       }
+       phylink_mac_config(pl, state);
++      if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed)
++              phylink_pcs_enable(pl->pcs);
++
+       if (pl->pcs_ops) {
+               err = pl->pcs_ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
+                                             state->interface,
+@@ -1260,6 +1285,7 @@ struct phylink *phylink_create(struct ph
+       pl->link_config.speed = SPEED_UNKNOWN;
+       pl->link_config.duplex = DUPLEX_UNKNOWN;
+       pl->link_config.an_enabled = true;
++      pl->pcs_state = PCS_STATE_DOWN;
+       pl->mac_ops = mac_ops;
+       __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
+       timer_setup(&pl->link_poll, phylink_fixed_poll, 0);
+@@ -1651,6 +1677,8 @@ void phylink_start(struct phylink *pl)
+       if (pl->netdev)
+               netif_carrier_off(pl->netdev);
++      pl->pcs_state = PCS_STATE_STARTING;
++
+       /* Apply the link configuration to the MAC when starting. This allows
+        * a fixed-link to start with the correct parameters, and also
+        * ensures that we set the appropriate advertisement for Serdes links.
+@@ -1661,6 +1689,8 @@ void phylink_start(struct phylink *pl)
+        */
+       phylink_mac_initial_config(pl, true);
++      pl->pcs_state = PCS_STATE_STARTED;
++
+       clear_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
+       phylink_run_resolve(pl);
+@@ -1680,16 +1710,9 @@ void phylink_start(struct phylink *pl)
+                       poll = true;
+       }
+-      switch (pl->cfg_link_an_mode) {
+-      case MLO_AN_FIXED:
++      if (pl->cfg_link_an_mode == MLO_AN_FIXED)
+               poll |= pl->config->poll_fixed_state;
+-              break;
+-      case MLO_AN_INBAND:
+-              poll |= pl->config->pcs_poll;
+-              if (pl->pcs)
+-                      poll |= pl->pcs->poll;
+-              break;
+-      }
++
+       if (poll)
+               mod_timer(&pl->link_poll, jiffies + HZ);
+       if (pl->phydev)
+@@ -1726,6 +1749,10 @@ void phylink_stop(struct phylink *pl)
+       }
+       phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
++
++      pl->pcs_state = PCS_STATE_DOWN;
++
++      phylink_pcs_disable(pl->pcs);
+ }
+ EXPORT_SYMBOL_GPL(phylink_stop);
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -419,6 +419,8 @@ struct phylink_pcs {
+ /**
+  * struct phylink_pcs_ops - MAC PCS operations structure.
+  * @pcs_validate: validate the link configuration.
++ * @pcs_enable: enable the PCS.
++ * @pcs_disable: disable the PCS.
+  * @pcs_get_state: read the current MAC PCS link state from the hardware.
+  * @pcs_config: configure the MAC PCS for the selected mode and state.
+  * @pcs_an_restart: restart 802.3z BaseX autonegotiation.
+@@ -428,6 +430,8 @@ struct phylink_pcs {
+ struct phylink_pcs_ops {
+       int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
+                           const struct phylink_link_state *state);
++      int (*pcs_enable)(struct phylink_pcs *pcs);
++      void (*pcs_disable)(struct phylink_pcs *pcs);
+       void (*pcs_get_state)(struct phylink_pcs *pcs,
+                             struct phylink_link_state *state);
+       int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
+@@ -458,6 +462,18 @@ int pcs_validate(struct phylink_pcs *pcs
+                const struct phylink_link_state *state);
+ /**
++ * pcs_enable() - enable the PCS.
++ * @pcs: a pointer to a &struct phylink_pcs.
++ */
++int pcs_enable(struct phylink_pcs *pcs);
++
++/**
++ * pcs_disable() - disable the PCS.
++ * @pcs: a pointer to a &struct phylink_pcs.
++ */
++void pcs_disable(struct phylink_pcs *pcs);
++
++/**
+  * pcs_get_state() - Read the current inband link state from the hardware
+  * @pcs: a pointer to a &struct phylink_pcs.
+  * @state: a pointer to a &struct phylink_link_state.
diff --git a/target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch b/target/linux/generic/backport-5.15/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch
new file mode 100644 (file)
index 0000000..eb9b4b7
--- /dev/null
@@ -0,0 +1,44 @@
+From e4ccdfb78a47132f2d215658aab8902fc457c4b4 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 18 Aug 2023 04:07:46 +0100
+Subject: [PATCH 082/125] net: pcs: lynxi: implement pcs_disable op
+
+When switching from 10GBase-R/5GBase-R/USXGMII to one of the interface
+modes provided by mtk-pcs-lynxi we need to make sure to always perform
+a full configuration of the PHYA.
+
+Implement pcs_disable op which resets the stored interface mode to
+PHY_INTERFACE_MODE_NA to trigger a full reconfiguration once the LynxI
+PCS driver had previously been deselected in favor of another PCS
+driver such as the to-be-added driver for the USXGMII PCS found in
+MT7988.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/f23d1a60d2c9d2fb72e32dcb0eaa5f7e867a3d68.1692327891.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/pcs/pcs-mtk-lynxi.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/pcs/pcs-mtk-lynxi.c
++++ b/drivers/net/pcs/pcs-mtk-lynxi.c
+@@ -241,11 +241,19 @@ static void mtk_pcs_lynxi_link_up(struct
+       }
+ }
++static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs)
++{
++      struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
++
++      mpcs->interface = PHY_INTERFACE_MODE_NA;
++}
++
+ static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
+       .pcs_get_state = mtk_pcs_lynxi_get_state,
+       .pcs_config = mtk_pcs_lynxi_config,
+       .pcs_an_restart = mtk_pcs_lynxi_restart_an,
+       .pcs_link_up = mtk_pcs_lynxi_link_up,
++      .pcs_disable = mtk_pcs_lynxi_disable,
+ };
+ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
diff --git a/target/linux/generic/backport-6.1/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/backport-6.1/730-07-v6.3-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch
deleted file mode 100644 (file)
index 31a8ca3..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 27 Oct 2022 23:39:52 +0200
-Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code
- on mt7621
-
-Avoid some branches in the hot path on low-end devices with limited CPU power,
-and reduce code size
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -921,7 +921,13 @@ enum mkt_eth_capabilities {
- #define MTK_MUX_GMAC12_TO_GEPHY_SGMII   \
-       (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
--#define MTK_HAS_CAPS(caps, _x)                (((caps) & (_x)) == (_x))
-+#ifdef CONFIG_SOC_MT7621
-+#define MTK_CAP_MASK MTK_NETSYS_V2
-+#else
-+#define MTK_CAP_MASK 0
-+#endif
-+
-+#define MTK_HAS_CAPS(caps, _x)                (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x))
- #define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
-                     MTK_GMAC2_RGMII | MTK_SHARED_INT | \
index 3a2780aff63b4f5763420ea1b7b8a27c69e5c1c6..fda017f7fc105bcf3b2dc87c62bbd0a915e646db 100644 (file)
@@ -181,7 +181,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  /* CDMP Ingress Control Register */
  #define MTK_CDMP_IG_CTRL      0x400
  #define MTK_CDMP_STAG_EN      BIT(0)
-@@ -1170,6 +1176,8 @@ struct mtk_eth {
+@@ -1164,6 +1170,8 @@ struct mtk_eth {
  
        int                             ip_align;
  
index 7db59ad871b70cff1472f65a1d649cdd8ee06d7c..a02c583deba4fa3aecac52969c83ad216158b397 100644 (file)
@@ -34,7 +34,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1073,11 +1073,13 @@ struct mtk_soc_data {
+@@ -1067,11 +1067,13 @@ struct mtk_soc_data {
   * @regmap:            The register map pointing at the range used to setup
   *                     SGMII modes
   * @ana_rgc3:          The offset refers to register ANA_RGC3 related to regmap
index 8c0f320fa8f9ad2465a53507ec4d2b2b7cf29a84..4b53ef903a25f22a4e931e8f12d352adb5bd7897 100644 (file)
@@ -14,6 +14,12 @@ new device-tree attribute 'mediatek,pn_swap' to support them.
 
 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_path.c | 14 +++++++--
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c  | 21 +++++++++++++
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 31 ++++++++++++++++++++
+ drivers/net/ethernet/mediatek/mtk_sgmii.c    | 10 +++++++
+ 4 files changed, 73 insertions(+), 3 deletions(-)
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
@@ -145,7 +151,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  
  #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
        BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-@@ -966,6 +990,11 @@ enum mkt_eth_capabilities {
+@@ -960,6 +984,11 @@ enum mkt_eth_capabilities {
                      MTK_MUX_U3_GMAC2_TO_QPHY | \
                      MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
  
@@ -157,7 +163,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  #define MT7986_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
                      MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
                      MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-@@ -1079,12 +1108,14 @@ struct mtk_soc_data {
+@@ -1073,12 +1102,14 @@ struct mtk_soc_data {
   * @ana_rgc3:          The offset refers to register ANA_RGC3 related to regmap
   * @interface:         Currently configured interface mode
   * @pcs:               Phylink PCS structure
index 95647835fa8c0c72bb158ed6caf2db0bcc5a5942..e40d658ddcfb1a0199b44b9a647da7df4fa0b2de 100644 (file)
@@ -228,7 +228,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  /* Infrasys subsystem config registers */
  #define INFRA_MISC2            0x70c
  #define CO_QPHY_SEL            BIT(0)
-@@ -1108,31 +1049,6 @@ struct mtk_soc_data {
+@@ -1102,31 +1043,6 @@ struct mtk_soc_data {
  /* currently no SoC has more than 2 macs */
  #define MTK_MAX_DEVS                  2
  
@@ -260,7 +260,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  /* struct mtk_eth -   This is the main datasructure for holding the state
   *                    of the driver
   * @dev:              The device pointer
-@@ -1152,6 +1068,7 @@ struct mtk_sgmii {
+@@ -1146,6 +1062,7 @@ struct mtk_sgmii {
   *                    MII modes
   * @infra:              The register map pointing at the range used to setup
   *                      SGMII and GePHY path
@@ -268,7 +268,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
   * @pctl:             The register map pointing at the range used to setup
   *                    GMAC port drive/slew values
   * @dma_refcnt:               track how many netdevs are using the DMA engine
-@@ -1192,8 +1109,8 @@ struct mtk_eth {
+@@ -1186,8 +1103,8 @@ struct mtk_eth {
        u32                             msg_enable;
        unsigned long                   sysclk;
        struct regmap                   *ethsys;
@@ -279,7 +279,7 @@ Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        struct regmap                   *pctl;
        bool                            hwlro;
        refcount_t                      dma_refcnt;
-@@ -1355,10 +1272,6 @@ void mtk_stats_update_mac(struct mtk_mac
+@@ -1349,10 +1266,6 @@ void mtk_stats_update_mac(struct mtk_mac
  void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
  u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
  
diff --git a/target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch b/target/linux/generic/backport-6.1/733-v6.4-23-net-ethernet-mtk_eth_soc-ppe-add-support-for-flow-ac.patch
new file mode 100644 (file)
index 0000000..3384086
--- /dev/null
@@ -0,0 +1,403 @@
+From f601293f37c4be618c5efaef85d2ee21f97e82e0 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Sun, 19 Mar 2023 12:57:35 +0000
+Subject: [PATCH 092/250] net: ethernet: mtk_eth_soc: ppe: add support for flow
+ accounting
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The PPE units found in MT7622 and newer support packet and byte
+accounting of hw-offloaded flows. Add support for reading those counters
+as found in MediaTek's SDK[1].
+
+[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/bc6a6a375c800dc2b80e1a325a2c732d1737df92
+Tested-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c   |   8 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h   |   3 +
+ drivers/net/ethernet/mediatek/mtk_ppe.c       | 114 +++++++++++++++++-
+ drivers/net/ethernet/mediatek/mtk_ppe.h       |  25 +++-
+ .../net/ethernet/mediatek/mtk_ppe_debugfs.c   |   9 +-
+ .../net/ethernet/mediatek/mtk_ppe_offload.c   |   8 ++
+ drivers/net/ethernet/mediatek/mtk_ppe_regs.h  |  14 +++
+ 7 files changed, 172 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4689,8 +4689,8 @@ static int mtk_probe(struct platform_dev
+               for (i = 0; i < num_ppe; i++) {
+                       u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
+-                      eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr,
+-                                                 eth->soc->offload_version, i);
++                      eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
++
+                       if (!eth->ppe[i]) {
+                               err = -ENOMEM;
+                               goto err_deinit_ppe;
+@@ -4814,6 +4814,7 @@ static const struct mtk_soc_data mt7622_
+       .required_pctl = false,
+       .offload_version = 2,
+       .hash_offset = 2,
++      .has_accounting = true,
+       .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+@@ -4851,6 +4852,7 @@ static const struct mtk_soc_data mt7629_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7629_CLKS_BITMAP,
+       .required_pctl = false,
++      .has_accounting = true,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+@@ -4871,6 +4873,7 @@ static const struct mtk_soc_data mt7981_
+       .offload_version = 2,
+       .hash_offset = 4,
+       .foe_entry_size = sizeof(struct mtk_foe_entry),
++      .has_accounting = true,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma_v2),
+               .rxd_size = sizeof(struct mtk_rx_dma_v2),
+@@ -4891,6 +4894,7 @@ static const struct mtk_soc_data mt7986_
+       .offload_version = 2,
+       .hash_offset = 4,
+       .foe_entry_size = sizeof(struct mtk_foe_entry),
++      .has_accounting = true,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma_v2),
+               .rxd_size = sizeof(struct mtk_rx_dma_v2),
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1011,6 +1011,8 @@ struct mtk_reg_map {
+  *                            the extra setup for those pins used by GMAC.
+  * @hash_offset                       Flow table hash offset.
+  * @foe_entry_size            Foe table entry size.
++ * @has_accounting            Bool indicating support for accounting of
++ *                            offloaded flows.
+  * @txd_size                  Tx DMA descriptor size.
+  * @rxd_size                  Rx DMA descriptor size.
+  * @rx_irq_done_mask          Rx irq done register mask.
+@@ -1028,6 +1030,7 @@ struct mtk_soc_data {
+       u8              hash_offset;
+       u16             foe_entry_size;
+       netdev_features_t hw_features;
++      bool            has_accounting;
+       struct {
+               u32     txd_size;
+               u32     rxd_size;
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -74,6 +74,48 @@ static int mtk_ppe_wait_busy(struct mtk_
+       return ret;
+ }
++static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe)
++{
++      int ret;
++      u32 val;
++
++      ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val,
++                               !(val & MTK_PPE_MIB_SER_CR_ST),
++                               20, MTK_PPE_WAIT_TIMEOUT_US);
++
++      if (ret)
++              dev_err(ppe->dev, "MIB table busy");
++
++      return ret;
++}
++
++static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
++{
++      u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
++      u32 val, cnt_r0, cnt_r1, cnt_r2;
++      int ret;
++
++      val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST;
++      ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val);
++
++      ret = mtk_ppe_mib_wait_busy(ppe);
++      if (ret)
++              return ret;
++
++      cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0);
++      cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
++      cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
++
++      byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
++      byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
++      pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
++      pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
++      *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
++      *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
++
++      return 0;
++}
++
+ static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
+ {
+       ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR);
+@@ -459,6 +501,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
+               hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
+               dma_wmb();
+               mtk_ppe_cache_clear(ppe);
++              if (ppe->accounting) {
++                      struct mtk_foe_accounting *acct;
++
++                      acct = ppe->acct_table + entry->hash * sizeof(*acct);
++                      acct->packets = 0;
++                      acct->bytes = 0;
++              }
+       }
+       entry->hash = 0xffff;
+@@ -566,6 +615,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+       wmb();
+       hwe->ib1 = entry->ib1;
++      if (ppe->accounting)
++              *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
++
+       dma_wmb();
+       mtk_ppe_cache_clear(ppe);
+@@ -757,11 +809,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
+       return mtk_ppe_wait_busy(ppe);
+ }
+-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
+-                           int version, int index)
++struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
++                                               struct mtk_foe_accounting *diff)
++{
++      struct mtk_foe_accounting *acct;
++      int size = sizeof(struct mtk_foe_accounting);
++      u64 bytes, packets;
++
++      if (!ppe->accounting)
++              return NULL;
++
++      if (mtk_mib_entry_read(ppe, index, &bytes, &packets))
++              return NULL;
++
++      acct = ppe->acct_table + index * size;
++
++      acct->bytes += bytes;
++      acct->packets += packets;
++
++      if (diff) {
++              diff->bytes = bytes;
++              diff->packets = packets;
++      }
++
++      return acct;
++}
++
++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
+ {
++      bool accounting = eth->soc->has_accounting;
+       const struct mtk_soc_data *soc = eth->soc;
++      struct mtk_foe_accounting *acct;
+       struct device *dev = eth->dev;
++      struct mtk_mib_entry *mib;
+       struct mtk_ppe *ppe;
+       u32 foe_flow_size;
+       void *foe;
+@@ -778,7 +858,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
+       ppe->base = base;
+       ppe->eth = eth;
+       ppe->dev = dev;
+-      ppe->version = version;
++      ppe->version = eth->soc->offload_version;
++      ppe->accounting = accounting;
+       foe = dmam_alloc_coherent(ppe->dev,
+                                 MTK_PPE_ENTRIES * soc->foe_entry_size,
+@@ -794,6 +875,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
+       if (!ppe->foe_flow)
+               goto err_free_l2_flows;
++      if (accounting) {
++              mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib),
++                                        &ppe->mib_phys, GFP_KERNEL);
++              if (!mib)
++                      return NULL;
++
++              ppe->mib_table = mib;
++
++              acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct),
++                                  GFP_KERNEL);
++
++              if (!acct)
++                      return NULL;
++
++              ppe->acct_table = acct;
++      }
++
+       mtk_ppe_debugfs_init(ppe, index);
+       return ppe;
+@@ -923,6 +1021,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
+               ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
+               ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
+       }
++
++      if (ppe->accounting && ppe->mib_phys) {
++              ppe_w32(ppe, MTK_PPE_MIB_TB_BASE, ppe->mib_phys);
++              ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_EN,
++                      MTK_PPE_MIB_CFG_EN);
++              ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_RD_CLR,
++                      MTK_PPE_MIB_CFG_RD_CLR);
++              ppe_m32(ppe, MTK_PPE_MIB_CACHE_CTL, MTK_PPE_MIB_CACHE_CTL_EN,
++                      MTK_PPE_MIB_CFG_RD_CLR);
++      }
+ }
+ int mtk_ppe_stop(struct mtk_ppe *ppe)
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -57,6 +57,7 @@ enum {
+ #define MTK_FOE_IB2_MULTICAST         BIT(8)
+ #define MTK_FOE_IB2_WDMA_QID2         GENMASK(13, 12)
++#define MTK_FOE_IB2_MIB_CNT           BIT(15)
+ #define MTK_FOE_IB2_WDMA_DEVIDX               BIT(16)
+ #define MTK_FOE_IB2_WDMA_WINFO                BIT(17)
+@@ -285,16 +286,34 @@ struct mtk_flow_entry {
+       unsigned long cookie;
+ };
++struct mtk_mib_entry {
++      u32     byt_cnt_l;
++      u16     byt_cnt_h;
++      u32     pkt_cnt_l;
++      u8      pkt_cnt_h;
++      u8      _rsv0;
++      u32     _rsv1;
++} __packed;
++
++struct mtk_foe_accounting {
++      u64     bytes;
++      u64     packets;
++};
++
+ struct mtk_ppe {
+       struct mtk_eth *eth;
+       struct device *dev;
+       void __iomem *base;
+       int version;
+       char dirname[5];
++      bool accounting;
+       void *foe_table;
+       dma_addr_t foe_phys;
++      struct mtk_mib_entry *mib_table;
++      dma_addr_t mib_phys;
++
+       u16 foe_check_time[MTK_PPE_ENTRIES];
+       struct hlist_head *foe_flow;
+@@ -303,8 +322,8 @@ struct mtk_ppe {
+       void *acct_table;
+ };
+-struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
+-                           int version, int index);
++struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
++
+ void mtk_ppe_deinit(struct mtk_eth *eth);
+ void mtk_ppe_start(struct mtk_ppe *ppe);
+ int mtk_ppe_stop(struct mtk_ppe *ppe);
+@@ -359,5 +378,7 @@ int mtk_foe_entry_commit(struct mtk_ppe
+ void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
+ int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
+ int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
++struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
++                                               struct mtk_foe_accounting *diff);
+ #endif
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
+@@ -82,6 +82,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
+               struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
+               struct mtk_foe_mac_info *l2;
+               struct mtk_flow_addr_info ai = {};
++              struct mtk_foe_accounting *acct;
+               unsigned char h_source[ETH_ALEN];
+               unsigned char h_dest[ETH_ALEN];
+               int type, state;
+@@ -95,6 +96,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file
+               if (bind && state != MTK_FOE_STATE_BIND)
+                       continue;
++              acct = mtk_foe_entry_get_mib(ppe, i, NULL);
++
+               type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
+               seq_printf(m, "%05x %s %7s", i,
+                          mtk_foe_entry_state_str(state),
+@@ -153,9 +156,11 @@ mtk_ppe_debugfs_foe_show(struct seq_file
+               *((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo);
+               seq_printf(m, " eth=%pM->%pM etype=%04x"
+-                            " vlan=%d,%d ib1=%08x ib2=%08x\n",
++                            " vlan=%d,%d ib1=%08x ib2=%08x"
++                            " packets=%llu bytes=%llu\n",
+                          h_source, h_dest, ntohs(l2->etype),
+-                         l2->vlan1, l2->vlan2, entry->ib1, ib2);
++                         l2->vlan1, l2->vlan2, entry->ib1, ib2,
++                         acct ? acct->packets : 0, acct ? acct->bytes : 0);
+       }
+       return 0;
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+@@ -497,6 +497,7 @@ static int
+ mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
+ {
+       struct mtk_flow_entry *entry;
++      struct mtk_foe_accounting diff;
+       u32 idle;
+       entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
+@@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *e
+       idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
+       f->stats.lastused = jiffies - idle * HZ;
++      if (entry->hash != 0xFFFF &&
++          mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash,
++                                &diff)) {
++              f->stats.pkts += diff.packets;
++              f->stats.bytes += diff.bytes;
++      }
++
+       return 0;
+ }
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
+@@ -149,6 +149,20 @@ enum {
+ #define MTK_PPE_MIB_TB_BASE                   0x338
++#define MTK_PPE_MIB_SER_CR                    0x33C
++#define MTK_PPE_MIB_SER_CR_ST                 BIT(16)
++#define MTK_PPE_MIB_SER_CR_ADDR                       GENMASK(13, 0)
++
++#define MTK_PPE_MIB_SER_R0                    0x340
++#define MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW               GENMASK(31, 0)
++
++#define MTK_PPE_MIB_SER_R1                    0x344
++#define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW                GENMASK(31, 16)
++#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH      GENMASK(15, 0)
++
++#define MTK_PPE_MIB_SER_R2                    0x348
++#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH               GENMASK(23, 0)
++
+ #define MTK_PPE_MIB_CACHE_CTL                 0x350
+ #define MTK_PPE_MIB_CACHE_CTL_EN              BIT(0)
+ #define MTK_PPE_MIB_CACHE_CTL_FLUSH           BIT(2)
diff --git a/target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch b/target/linux/generic/backport-6.1/733-v6.4-24-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch
new file mode 100644 (file)
index 0000000..6435242
--- /dev/null
@@ -0,0 +1,58 @@
+From 88a0fd5927b7c2c7aecd6dc747d898eb38043d2b Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 20 Apr 2023 22:06:42 +0100
+Subject: [PATCH 093/250] net: mtk_eth_soc: mediatek: fix ppe flow accounting
+ for v1 hardware
+
+Older chips (like MT7622) use a different bit in ib2 to enable hardware
+counter support. Add macros for both and select the appropriate bit.
+
+Fixes: 3fbe4d8c0e53 ("net: ethernet: mtk_eth_soc: ppe: add support for flow accounting")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_ppe.c | 10 ++++++++--
+ drivers/net/ethernet/mediatek/mtk_ppe.h |  3 ++-
+ 2 files changed, 10 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -599,6 +599,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+       struct mtk_eth *eth = ppe->eth;
+       u16 timestamp = mtk_eth_timestamp(eth);
+       struct mtk_foe_entry *hwe;
++      u32 val;
+       if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+               entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
+@@ -615,8 +616,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+       wmb();
+       hwe->ib1 = entry->ib1;
+-      if (ppe->accounting)
+-              *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
++      if (ppe->accounting) {
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++                      val = MTK_FOE_IB2_MIB_CNT_V2;
++              else
++                      val = MTK_FOE_IB2_MIB_CNT;
++              *mtk_foe_entry_ib2(eth, hwe) |= val;
++      }
+       dma_wmb();
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -55,9 +55,10 @@ enum {
+ #define MTK_FOE_IB2_PSE_QOS           BIT(4)
+ #define MTK_FOE_IB2_DEST_PORT         GENMASK(7, 5)
+ #define MTK_FOE_IB2_MULTICAST         BIT(8)
++#define MTK_FOE_IB2_MIB_CNT           BIT(10)
+ #define MTK_FOE_IB2_WDMA_QID2         GENMASK(13, 12)
+-#define MTK_FOE_IB2_MIB_CNT           BIT(15)
++#define MTK_FOE_IB2_MIB_CNT_V2                BIT(15)
+ #define MTK_FOE_IB2_WDMA_DEVIDX               BIT(16)
+ #define MTK_FOE_IB2_WDMA_WINFO                BIT(17)
diff --git a/target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/backport-6.1/733-v6.4-25-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch
new file mode 100644 (file)
index 0000000..3a4cc91
--- /dev/null
@@ -0,0 +1,201 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sun, 20 Nov 2022 23:01:00 +0100
+Subject: [PATCH] net: ethernet: mtk_eth_soc: drop generic vlan rx offload,
+ only use DSA untagging
+
+Through testing I found out that hardware vlan rx offload support seems to
+have some hardware issues. At least when using multiple MACs and when receiving
+tagged packets on the secondary MAC, the hardware can sometimes start to emit
+wrong tags on the first MAC as well.
+
+In order to avoid such issues, drop the feature configuration and use the
+offload feature only for DSA hardware untagging on MT7621/MT7622 devices which
+only use one MAC.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1898,9 +1898,7 @@ static int mtk_poll_rx(struct napi_struc
+       while (done < budget) {
+               unsigned int pktlen, *rxdcsum;
+-              bool has_hwaccel_tag = false;
+               struct net_device *netdev;
+-              u16 vlan_proto, vlan_tci;
+               dma_addr_t dma_addr;
+               u32 hash, reason;
+               int mac = 0;
+@@ -2035,36 +2033,21 @@ static int mtk_poll_rx(struct napi_struc
+                       skb_checksum_none_assert(skb);
+               skb->protocol = eth_type_trans(skb, netdev);
+-              if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
+-                      mtk_ppe_check_skb(eth->ppe[0], skb, hash);
+-
+-              if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
+-                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+-                              if (trxd.rxd3 & RX_DMA_VTAG_V2) {
+-                                      vlan_proto = RX_DMA_VPID(trxd.rxd4);
+-                                      vlan_tci = RX_DMA_VID(trxd.rxd4);
+-                                      has_hwaccel_tag = true;
+-                              }
+-                      } else if (trxd.rxd2 & RX_DMA_VTAG) {
+-                              vlan_proto = RX_DMA_VPID(trxd.rxd3);
+-                              vlan_tci = RX_DMA_VID(trxd.rxd3);
+-                              has_hwaccel_tag = true;
+-                      }
+-              }
+-
+               /* When using VLAN untagging in combination with DSA, the
+                * hardware treats the MTK special tag as a VLAN and untags it.
+                */
+-              if (has_hwaccel_tag && netdev_uses_dsa(netdev)) {
+-                      unsigned int port = vlan_proto & GENMASK(2, 0);
++              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
++                  (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
++                      unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
+                       if (port < ARRAY_SIZE(eth->dsa_meta) &&
+                           eth->dsa_meta[port])
+                               skb_dst_set_noref(skb, &eth->dsa_meta[port]->dst);
+-              } else if (has_hwaccel_tag) {
+-                      __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci);
+               }
++              if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
++                      mtk_ppe_check_skb(eth->ppe[0], skb, hash);
++
+               skb_record_rx_queue(skb, 0);
+               napi_gro_receive(napi, skb);
+@@ -2887,29 +2870,11 @@ static netdev_features_t mtk_fix_feature
+ static int mtk_set_features(struct net_device *dev, netdev_features_t features)
+ {
+-      struct mtk_mac *mac = netdev_priv(dev);
+-      struct mtk_eth *eth = mac->hw;
+       netdev_features_t diff = dev->features ^ features;
+-      int i;
+       if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO))
+               mtk_hwlro_netdev_disable(dev);
+-      /* Set RX VLAN offloading */
+-      if (!(diff & NETIF_F_HW_VLAN_CTAG_RX))
+-              return 0;
+-
+-      mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX),
+-              MTK_CDMP_EG_CTRL);
+-
+-      /* sync features with other MAC */
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
+-              if (!eth->netdev[i] || eth->netdev[i] == dev)
+-                      continue;
+-              eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
+-              eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX;
+-      }
+-
+       return 0;
+ }
+@@ -3223,30 +3188,6 @@ static int mtk_open(struct net_device *d
+       struct mtk_eth *eth = mac->hw;
+       int i, err;
+-      if (mtk_uses_dsa(dev) && !eth->prog) {
+-              for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
+-                      struct metadata_dst *md_dst = eth->dsa_meta[i];
+-
+-                      if (md_dst)
+-                              continue;
+-
+-                      md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
+-                                                  GFP_KERNEL);
+-                      if (!md_dst)
+-                              return -ENOMEM;
+-
+-                      md_dst->u.port_info.port_id = i;
+-                      eth->dsa_meta[i] = md_dst;
+-              }
+-      } else {
+-              /* Hardware special tag parsing needs to be disabled if at least
+-               * one MAC does not use DSA.
+-               */
+-              u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
+-              val &= ~MTK_CDMP_STAG_EN;
+-              mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
+-      }
+-
+       err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
+       if (err) {
+               netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
+@@ -3285,6 +3226,35 @@ static int mtk_open(struct net_device *d
+       phylink_start(mac->phylink);
+       netif_tx_start_all_queues(dev);
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++              return 0;
++
++      if (mtk_uses_dsa(dev) && !eth->prog) {
++              for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
++                      struct metadata_dst *md_dst = eth->dsa_meta[i];
++
++                      if (md_dst)
++                              continue;
++
++                      md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
++                                                  GFP_KERNEL);
++                      if (!md_dst)
++                              return -ENOMEM;
++
++                      md_dst->u.port_info.port_id = i;
++                      eth->dsa_meta[i] = md_dst;
++              }
++      } else {
++              /* Hardware special tag parsing needs to be disabled if at least
++               * one MAC does not use DSA.
++               */
++              u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
++              val &= ~MTK_CDMP_STAG_EN;
++              mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
++
++              mtk_w32(eth, 0, MTK_CDMP_EG_CTRL);
++      }
++
+       return 0;
+ }
+@@ -3769,10 +3739,9 @@ static int mtk_hw_init(struct mtk_eth *e
+       if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
+               val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
+               mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
+-      }
+-      /* Enable RX VLan Offloading */
+-      mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
++              mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
++      }
+       /* set interrupt delays based on current Net DIM sample */
+       mtk_dim_rx(&eth->rx_dim.work);
+@@ -4412,7 +4381,7 @@ static int mtk_add_mac(struct mtk_eth *e
+               eth->netdev[id]->hw_features |= NETIF_F_LRO;
+       eth->netdev[id]->vlan_features = eth->soc->hw_features &
+-              ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
++              ~NETIF_F_HW_VLAN_CTAG_TX;
+       eth->netdev[id]->features |= eth->soc->hw_features;
+       eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -48,7 +48,6 @@
+ #define MTK_HW_FEATURES               (NETIF_F_IP_CSUM | \
+                                NETIF_F_RXCSUM | \
+                                NETIF_F_HW_VLAN_CTAG_TX | \
+-                               NETIF_F_HW_VLAN_CTAG_RX | \
+                                NETIF_F_SG | NETIF_F_TSO | \
+                                NETIF_F_TSO6 | \
+                                NETIF_F_IPV6_CSUM |\
diff --git a/target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch b/target/linux/generic/backport-6.1/733-v6.5-26-net-ethernet-mtk_eth_soc-always-mtk_get_ib1_pkt_type.patch
new file mode 100644 (file)
index 0000000..2704fae
--- /dev/null
@@ -0,0 +1,31 @@
+From b804f765485109f9644cc05d1e8fc79ca6c6e4aa Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 19 Jul 2023 01:39:36 +0100
+Subject: [PATCH 094/250] net: ethernet: mtk_eth_soc: always
+ mtk_get_ib1_pkt_type
+
+entries and bind debugfs files would display wrong data on NETSYS_V2 and
+later because instead of using mtk_get_ib1_pkt_type the driver would use
+MTK_FOE_IB1_PACKET_TYPE which corresponds to NETSYS_V1(.x) SoCs.
+Use mtk_get_ib1_pkt_type so entries and bind records display correctly.
+
+Fixes: 03a3180e5c09e ("net: ethernet: mtk_eth_soc: introduce flow offloading support for mt7986")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/r/c0ae03d0182f4d27b874cbdf0059bc972c317f3c.1689727134.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
+@@ -98,7 +98,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
+               acct = mtk_foe_entry_get_mib(ppe, i, NULL);
+-              type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
++              type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1);
+               seq_printf(m, "%05x %s %7s", i,
+                          mtk_foe_entry_state_str(state),
+                          mtk_foe_pkt_type_str(type));
diff --git a/target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch b/target/linux/generic/backport-6.1/750-v6.5-01-net-ethernet-mtk_ppe-add-MTK_FOE_ENTRY_V-1-2-_SIZE-m.patch
new file mode 100644 (file)
index 0000000..aceeaa9
--- /dev/null
@@ -0,0 +1,78 @@
+From 5ea0e1312bcfebc06b5f91d1bb82b823d6395125 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Wed, 19 Jul 2023 12:29:49 +0200
+Subject: [PATCH 095/250] net: ethernet: mtk_ppe: add MTK_FOE_ENTRY_V{1,2}_SIZE
+ macros
+
+Introduce MTK_FOE_ENTRY_V{1,2}_SIZE macros in order to make more
+explicit foe_entry size for different chipset revisions.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Reviewed-by: Simon Horman <simon.horman@corigine.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 10 +++++-----
+ drivers/net/ethernet/mediatek/mtk_ppe.h     |  3 +++
+ 2 files changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -4763,7 +4763,7 @@ static const struct mtk_soc_data mt7621_
+       .required_pctl = false,
+       .offload_version = 1,
+       .hash_offset = 2,
+-      .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
++      .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+@@ -4784,7 +4784,7 @@ static const struct mtk_soc_data mt7622_
+       .offload_version = 2,
+       .hash_offset = 2,
+       .has_accounting = true,
+-      .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
++      .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+@@ -4803,7 +4803,7 @@ static const struct mtk_soc_data mt7623_
+       .required_pctl = true,
+       .offload_version = 1,
+       .hash_offset = 2,
+-      .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
++      .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+@@ -4841,8 +4841,8 @@ static const struct mtk_soc_data mt7981_
+       .required_pctl = false,
+       .offload_version = 2,
+       .hash_offset = 4,
+-      .foe_entry_size = sizeof(struct mtk_foe_entry),
+       .has_accounting = true,
++      .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma_v2),
+               .rxd_size = sizeof(struct mtk_rx_dma_v2),
+@@ -4862,8 +4862,8 @@ static const struct mtk_soc_data mt7986_
+       .required_pctl = false,
+       .offload_version = 2,
+       .hash_offset = 4,
+-      .foe_entry_size = sizeof(struct mtk_foe_entry),
+       .has_accounting = true,
++      .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma_v2),
+               .rxd_size = sizeof(struct mtk_rx_dma_v2),
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -216,6 +216,9 @@ struct mtk_foe_ipv6_6rd {
+       struct mtk_foe_mac_info l2;
+ };
++#define MTK_FOE_ENTRY_V1_SIZE 80
++#define MTK_FOE_ENTRY_V2_SIZE 96
++
+ struct mtk_foe_entry {
+       u32 ib1;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch b/target/linux/generic/backport-6.1/750-v6.5-02-net-ethernet-mtk_eth_soc-remove-incorrect-PLL-config.patch
new file mode 100644 (file)
index 0000000..ae56a99
--- /dev/null
@@ -0,0 +1,141 @@
+From 8cfa2576d79f9379d167a8994f0fca935c07a8bc Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Sat, 22 Jul 2023 21:32:49 +0100
+Subject: [PATCH 096/250] net: ethernet: mtk_eth_soc: remove incorrect PLL
+ configuration
+
+MT7623 GMAC0 attempts to configure the system clocking according to the
+required speed in the .mac_config callback for non-SGMII, non-baseX and
+non-TRGMII modes.
+
+state->speed setting has never been reliable in the .mac_config
+callback - there are cases where this is not the link speed,
+particularly via ethtool paths, so this has always been unreliable (as
+detailed in phylink's documentation.)
+
+There is the additional issue that mtk_gmac0_rgmii_adjust() will only
+be called if state->interface changes, which means it only configures
+the system clocking on the very first .mac_config call, which will be
+made when the network device is first brought up before any link is
+established.
+
+Essentially, this code is incredibly buggy, and probably never worked.
+
+Moreover, checking the in-kernel DT files, it seems no platform makes
+use of this code path.
+
+Therefore, let's remove it, and disable interface modes for port 0 that
+are not SGMII, 1000base-X, 2500base-X or TRGMII on the MT7623.
+
+Reviewed-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Frank Wunderlich <frank-w@public-files.de>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 54 ++++++---------------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  1 +
+ 2 files changed, 17 insertions(+), 38 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -352,7 +352,7 @@ static int mt7621_gmac0_rgmii_adjust(str
+ }
+ static void mtk_gmac0_rgmii_adjust(struct mtk_eth *eth,
+-                                 phy_interface_t interface, int speed)
++                                 phy_interface_t interface)
+ {
+       u32 val;
+       int ret;
+@@ -366,26 +366,7 @@ static void mtk_gmac0_rgmii_adjust(struc
+               return;
+       }
+-      val = (speed == SPEED_1000) ?
+-              INTF_MODE_RGMII_1000 : INTF_MODE_RGMII_10_100;
+-      mtk_w32(eth, val, INTF_MODE);
+-
+-      regmap_update_bits(eth->ethsys, ETHSYS_CLKCFG0,
+-                         ETHSYS_TRGMII_CLK_SEL362_5,
+-                         ETHSYS_TRGMII_CLK_SEL362_5);
+-
+-      val = (speed == SPEED_1000) ? 250000000 : 500000000;
+-      ret = clk_set_rate(eth->clks[MTK_CLK_TRGPLL], val);
+-      if (ret)
+-              dev_err(eth->dev, "Failed to set trgmii pll: %d\n", ret);
+-
+-      val = (speed == SPEED_1000) ?
+-              RCK_CTRL_RGMII_1000 : RCK_CTRL_RGMII_10_100;
+-      mtk_w32(eth, val, TRGMII_RCK_CTRL);
+-
+-      val = (speed == SPEED_1000) ?
+-              TCK_CTRL_RGMII_1000 : TCK_CTRL_RGMII_10_100;
+-      mtk_w32(eth, val, TRGMII_TCK_CTRL);
++      dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n");
+ }
+ static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
+@@ -471,17 +452,8 @@ static void mtk_mac_config(struct phylin
+                                                             state->interface))
+                                       goto err_phy;
+                       } else {
+-                              /* FIXME: this is incorrect. Not only does it
+-                               * use state->speed (which is not guaranteed
+-                               * to be correct) but it also makes use of it
+-                               * in a code path that will only be reachable
+-                               * when the PHY interface mode changes, not
+-                               * when the speed changes. Consequently, RGMII
+-                               * is probably broken.
+-                               */
+                               mtk_gmac0_rgmii_adjust(mac->hw,
+-                                                     state->interface,
+-                                                     state->speed);
++                                                     state->interface);
+                               /* mt7623_pad_clk_setup */
+                               for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
+@@ -4340,13 +4312,19 @@ static int mtk_add_mac(struct mtk_eth *e
+       mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+               MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
+-      __set_bit(PHY_INTERFACE_MODE_MII,
+-                mac->phylink_config.supported_interfaces);
+-      __set_bit(PHY_INTERFACE_MODE_GMII,
+-                mac->phylink_config.supported_interfaces);
++      /* MT7623 gmac0 is now missing its speed-specific PLL configuration
++       * in its .mac_config method (since state->speed is not valid there.
++       * Disable support for MII, GMII and RGMII.
++       */
++      if (!mac->hw->soc->disable_pll_modes || mac->id != 0) {
++              __set_bit(PHY_INTERFACE_MODE_MII,
++                        mac->phylink_config.supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_GMII,
++                        mac->phylink_config.supported_interfaces);
+-      if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
+-              phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
++              if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
++                      phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
++      }
+       if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id)
+               __set_bit(PHY_INTERFACE_MODE_TRGMII,
+@@ -4804,6 +4782,7 @@ static const struct mtk_soc_data mt7623_
+       .offload_version = 1,
+       .hash_offset = 2,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
++      .disable_pll_modes = true,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1030,6 +1030,7 @@ struct mtk_soc_data {
+       u16             foe_entry_size;
+       netdev_features_t hw_features;
+       bool            has_accounting;
++      bool            disable_pll_modes;
+       struct {
+               u32     txd_size;
+               u32     rxd_size;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch b/target/linux/generic/backport-6.1/750-v6.5-03-net-ethernet-mtk_eth_soc-remove-mac_pcs_get_state-an.patch
new file mode 100644 (file)
index 0000000..2893a07
--- /dev/null
@@ -0,0 +1,81 @@
+From a4c2233b1e4359b6c64b6f9ba98c8718a11fffee Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Sat, 22 Jul 2023 21:32:54 +0100
+Subject: [PATCH 097/250] net: ethernet: mtk_eth_soc: remove mac_pcs_get_state
+ and modernise
+
+Remove the .mac_pcs_get_state function, since as far as I can tell is
+never called - no DT appears to specify an in-band-status management
+nor SFP support for this driver.
+
+Removal of this, along with the previous patch to remove the incorrect
+clocking configuration, means that the driver becomes non-legacy, so
+we can remove the "legacy_pre_march2020" status from this driver.
+
+Reviewed-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Frank Wunderlich <frank-w@public-files.de>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 35 ---------------------
+ 1 file changed, 35 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -555,38 +555,6 @@ static int mtk_mac_finish(struct phylink
+       return 0;
+ }
+-static void mtk_mac_pcs_get_state(struct phylink_config *config,
+-                                struct phylink_link_state *state)
+-{
+-      struct mtk_mac *mac = container_of(config, struct mtk_mac,
+-                                         phylink_config);
+-      u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id));
+-
+-      state->link = (pmsr & MAC_MSR_LINK);
+-      state->duplex = (pmsr & MAC_MSR_DPX) >> 1;
+-
+-      switch (pmsr & (MAC_MSR_SPEED_1000 | MAC_MSR_SPEED_100)) {
+-      case 0:
+-              state->speed = SPEED_10;
+-              break;
+-      case MAC_MSR_SPEED_100:
+-              state->speed = SPEED_100;
+-              break;
+-      case MAC_MSR_SPEED_1000:
+-              state->speed = SPEED_1000;
+-              break;
+-      default:
+-              state->speed = SPEED_UNKNOWN;
+-              break;
+-      }
+-
+-      state->pause &= (MLO_PAUSE_RX | MLO_PAUSE_TX);
+-      if (pmsr & MAC_MSR_RX_FC)
+-              state->pause |= MLO_PAUSE_RX;
+-      if (pmsr & MAC_MSR_TX_FC)
+-              state->pause |= MLO_PAUSE_TX;
+-}
+-
+ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
+                             phy_interface_t interface)
+ {
+@@ -709,7 +677,6 @@ static void mtk_mac_link_up(struct phyli
+ static const struct phylink_mac_ops mtk_phylink_ops = {
+       .validate = phylink_generic_validate,
+       .mac_select_pcs = mtk_mac_select_pcs,
+-      .mac_pcs_get_state = mtk_mac_pcs_get_state,
+       .mac_config = mtk_mac_config,
+       .mac_finish = mtk_mac_finish,
+       .mac_link_down = mtk_mac_link_down,
+@@ -4307,8 +4274,6 @@ static int mtk_add_mac(struct mtk_eth *e
+       mac->phylink_config.dev = &eth->netdev[id]->dev;
+       mac->phylink_config.type = PHYLINK_NETDEV;
+-      /* This driver makes use of state->speed in mac_config */
+-      mac->phylink_config.legacy_pre_march2020 = true;
+       mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+               MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch b/target/linux/generic/backport-6.1/750-v6.5-05-net-ethernet-mtk_eth_soc-add-version-in-mtk_soc_data.patch
new file mode 100644 (file)
index 0000000..9151702
--- /dev/null
@@ -0,0 +1,550 @@
+From 5d8d05fbf804b4485646d39551ac27452e45afd3 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 25 Jul 2023 01:52:02 +0100
+Subject: [PATCH 099/250] net: ethernet: mtk_eth_soc: add version in
+ mtk_soc_data
+
+Introduce version field in mtk_soc_data data structure in order to
+make mtk_eth driver easier to maintain for chipset configuration
+codebase. Get rid of MTK_NETSYS_V2 bit in chip capabilities.
+This is a preliminary patch to introduce support for MT7988 SoC.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/e52fae302ca135436e5cdd26d38d87be2da63055.1690246066.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 55 +++++++++++--------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h   | 36 +++++++-----
+ drivers/net/ethernet/mediatek/mtk_ppe.c       | 18 +++---
+ .../net/ethernet/mediatek/mtk_ppe_offload.c   |  2 +-
+ drivers/net/ethernet/mediatek/mtk_wed.c       |  4 +-
+ 5 files changed, 66 insertions(+), 49 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -580,7 +580,7 @@ static void mtk_set_queue_speed(struct m
+             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
+             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
+             MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
+-      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v1(eth))
+               val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
+       if (IS_ENABLED(CONFIG_SOC_MT7621)) {
+@@ -956,7 +956,7 @@ static bool mtk_rx_get_desc(struct mtk_e
+       rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
+       rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
+       rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
+               rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
+       }
+@@ -1014,7 +1014,7 @@ static int mtk_init_fq_dma(struct mtk_et
+               txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
+               txd->txd4 = 0;
+-              if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
++              if (mtk_is_netsys_v2_or_greater(eth)) {
+                       txd->txd5 = 0;
+                       txd->txd6 = 0;
+                       txd->txd7 = 0;
+@@ -1205,7 +1205,7 @@ static void mtk_tx_set_dma_desc(struct n
+       struct mtk_mac *mac = netdev_priv(dev);
+       struct mtk_eth *eth = mac->hw;
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               mtk_tx_set_dma_desc_v2(dev, txd, info);
+       else
+               mtk_tx_set_dma_desc_v1(dev, txd, info);
+@@ -1512,7 +1512,7 @@ static void mtk_update_rx_cpu_idx(struct
+ static bool mtk_page_pool_enabled(struct mtk_eth *eth)
+ {
+-      return MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2);
++      return eth->soc->version == 2;
+ }
+ static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
+@@ -1854,7 +1854,7 @@ static int mtk_poll_rx(struct napi_struc
+                       break;
+               /* find out which mac the packet come from. values start at 1 */
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++              if (mtk_is_netsys_v2_or_greater(eth))
+                       mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
+               else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
+                        !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
+@@ -1950,7 +1950,7 @@ static int mtk_poll_rx(struct napi_struc
+               skb->dev = netdev;
+               bytes += skb->len;
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++              if (mtk_is_netsys_v2_or_greater(eth)) {
+                       reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
+                       hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
+                       if (hash != MTK_RXD5_FOE_ENTRY)
+@@ -1975,8 +1975,8 @@ static int mtk_poll_rx(struct napi_struc
+               /* When using VLAN untagging in combination with DSA, the
+                * hardware treats the MTK special tag as a VLAN and untags it.
+                */
+-              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
+-                  (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
++              if (mtk_is_netsys_v1(eth) && (trxd.rxd2 & RX_DMA_VTAG) &&
++                  netdev_uses_dsa(netdev)) {
+                       unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
+                       if (port < ARRAY_SIZE(eth->dsa_meta) &&
+@@ -2286,7 +2286,7 @@ static int mtk_tx_alloc(struct mtk_eth *
+               txd->txd2 = next_ptr;
+               txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
+               txd->txd4 = 0;
+-              if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
++              if (mtk_is_netsys_v2_or_greater(eth)) {
+                       txd->txd5 = 0;
+                       txd->txd6 = 0;
+                       txd->txd7 = 0;
+@@ -2339,14 +2339,14 @@ static int mtk_tx_alloc(struct mtk_eth *
+                             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
+                             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
+                             MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
+-                      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++                      if (mtk_is_netsys_v1(eth))
+                               val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
+                       mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
+                       ofs += MTK_QTX_OFFSET;
+               }
+               val = MTK_QDMA_TX_SCH_MAX_WFQ | (MTK_QDMA_TX_SCH_MAX_WFQ << 16);
+               mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate);
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++              if (mtk_is_netsys_v2_or_greater(eth))
+                       mtk_w32(eth, val, soc->reg_map->qdma.tx_sch_rate + 4);
+       } else {
+               mtk_w32(eth, ring->phys_pdma, MT7628_TX_BASE_PTR0);
+@@ -2475,7 +2475,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+               rxd->rxd3 = 0;
+               rxd->rxd4 = 0;
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++              if (mtk_is_netsys_v2_or_greater(eth)) {
+                       rxd->rxd5 = 0;
+                       rxd->rxd6 = 0;
+                       rxd->rxd7 = 0;
+@@ -3023,7 +3023,7 @@ static int mtk_start_dma(struct mtk_eth
+                      MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
+                      MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++              if (mtk_is_netsys_v2_or_greater(eth))
+                       val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
+                              MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
+                              MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
+@@ -3165,7 +3165,7 @@ static int mtk_open(struct net_device *d
+       phylink_start(mac->phylink);
+       netif_tx_start_all_queues(dev);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return 0;
+       if (mtk_uses_dsa(dev) && !eth->prog) {
+@@ -3430,7 +3430,7 @@ static void mtk_hw_reset(struct mtk_eth
+ {
+       u32 val;
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
+               val = RSTCTRL_PPE0_V2;
+       } else {
+@@ -3442,7 +3442,7 @@ static void mtk_hw_reset(struct mtk_eth
+       ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
+                            0x3ffffff);
+ }
+@@ -3468,7 +3468,7 @@ static void mtk_hw_warm_reset(struct mtk
+               return;
+       }
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
+       else
+               rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
+@@ -3638,7 +3638,7 @@ static int mtk_hw_init(struct mtk_eth *e
+       else
+               mtk_hw_reset(eth);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               /* Set FE to PDMAv2 if necessary */
+               val = mtk_r32(eth, MTK_FE_GLO_MISC);
+               mtk_w32(eth,  val | BIT(4), MTK_FE_GLO_MISC);
+@@ -3675,7 +3675,7 @@ static int mtk_hw_init(struct mtk_eth *e
+        */
+       val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
+       mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
+-      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v1(eth)) {
+               val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
+               mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
+@@ -3697,7 +3697,7 @@ static int mtk_hw_init(struct mtk_eth *e
+       mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
+       mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               /* PSE should not drop port8 and port9 packets from WDMA Tx */
+               mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
+@@ -4486,7 +4486,7 @@ static int mtk_probe(struct platform_dev
+               }
+       }
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               if (!res) {
+                       err = -EINVAL;
+@@ -4594,9 +4594,8 @@ static int mtk_probe(struct platform_dev
+       }
+       if (eth->soc->offload_version) {
+-              u32 num_ppe;
++              u32 num_ppe = mtk_is_netsys_v2_or_greater(eth) ? 2 : 1;
+-              num_ppe = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
+               num_ppe = min_t(u32, ARRAY_SIZE(eth->ppe), num_ppe);
+               for (i = 0; i < num_ppe; i++) {
+                       u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
+@@ -4688,6 +4687,7 @@ static const struct mtk_soc_data mt2701_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7623_CLKS_BITMAP,
+       .required_pctl = true,
++      .version = 1,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+@@ -4704,6 +4704,7 @@ static const struct mtk_soc_data mt7621_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7621_CLKS_BITMAP,
+       .required_pctl = false,
++      .version = 1,
+       .offload_version = 1,
+       .hash_offset = 2,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+@@ -4724,6 +4725,7 @@ static const struct mtk_soc_data mt7622_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7622_CLKS_BITMAP,
+       .required_pctl = false,
++      .version = 1,
+       .offload_version = 2,
+       .hash_offset = 2,
+       .has_accounting = true,
+@@ -4744,6 +4746,7 @@ static const struct mtk_soc_data mt7623_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7623_CLKS_BITMAP,
+       .required_pctl = true,
++      .version = 1,
+       .offload_version = 1,
+       .hash_offset = 2,
+       .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
+@@ -4766,6 +4769,7 @@ static const struct mtk_soc_data mt7629_
+       .required_clks = MT7629_CLKS_BITMAP,
+       .required_pctl = false,
+       .has_accounting = true,
++      .version = 1,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+@@ -4783,6 +4787,7 @@ static const struct mtk_soc_data mt7981_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7981_CLKS_BITMAP,
+       .required_pctl = false,
++      .version = 2,
+       .offload_version = 2,
+       .hash_offset = 4,
+       .has_accounting = true,
+@@ -4804,6 +4809,7 @@ static const struct mtk_soc_data mt7986_
+       .hw_features = MTK_HW_FEATURES,
+       .required_clks = MT7986_CLKS_BITMAP,
+       .required_pctl = false,
++      .version = 2,
+       .offload_version = 2,
+       .hash_offset = 4,
+       .has_accounting = true,
+@@ -4824,6 +4830,7 @@ static const struct mtk_soc_data rt5350_
+       .hw_features = MTK_HW_FEATURES_MT7628,
+       .required_clks = MT7628_CLKS_BITMAP,
+       .required_pctl = false,
++      .version = 1,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma),
+               .rxd_size = sizeof(struct mtk_rx_dma),
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -820,7 +820,6 @@ enum mkt_eth_capabilities {
+       MTK_SHARED_INT_BIT,
+       MTK_TRGMII_MT7621_CLK_BIT,
+       MTK_QDMA_BIT,
+-      MTK_NETSYS_V2_BIT,
+       MTK_SOC_MT7628_BIT,
+       MTK_RSTCTRL_PPE1_BIT,
+       MTK_U3_COPHY_V2_BIT,
+@@ -855,7 +854,6 @@ enum mkt_eth_capabilities {
+ #define MTK_SHARED_INT                BIT(MTK_SHARED_INT_BIT)
+ #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
+ #define MTK_QDMA              BIT(MTK_QDMA_BIT)
+-#define MTK_NETSYS_V2         BIT(MTK_NETSYS_V2_BIT)
+ #define MTK_SOC_MT7628                BIT(MTK_SOC_MT7628_BIT)
+ #define MTK_RSTCTRL_PPE1      BIT(MTK_RSTCTRL_PPE1_BIT)
+ #define MTK_U3_COPHY_V2               BIT(MTK_U3_COPHY_V2_BIT)
+@@ -934,11 +932,11 @@ enum mkt_eth_capabilities {
+ #define MT7981_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
+-                    MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
++                    MTK_RSTCTRL_PPE1)
+ #define MT7986_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+-                    MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
++                    MTK_RSTCTRL_PPE1)
+ struct mtk_tx_dma_desc_info {
+       dma_addr_t      addr;
+@@ -1009,6 +1007,7 @@ struct mtk_reg_map {
+  * @required_pctl             A bool value to show whether the SoC requires
+  *                            the extra setup for those pins used by GMAC.
+  * @hash_offset                       Flow table hash offset.
++ * @version                   SoC version.
+  * @foe_entry_size            Foe table entry size.
+  * @has_accounting            Bool indicating support for accounting of
+  *                            offloaded flows.
+@@ -1027,6 +1026,7 @@ struct mtk_soc_data {
+       bool            required_pctl;
+       u8              offload_version;
+       u8              hash_offset;
++      u8              version;
+       u16             foe_entry_size;
+       netdev_features_t hw_features;
+       bool            has_accounting;
+@@ -1183,6 +1183,16 @@ struct mtk_mac {
+ /* the struct describing the SoC. these are declared in the soc_xyz.c files */
+ extern const struct of_device_id of_mtk_match[];
++static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
++{
++      return eth->soc->version == 1;
++}
++
++static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth)
++{
++      return eth->soc->version > 1;
++}
++
+ static inline struct mtk_foe_entry *
+ mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
+ {
+@@ -1193,7 +1203,7 @@ mtk_foe_get_entry(struct mtk_ppe *ppe, u
+ static inline u32 mtk_get_ib1_ts_mask(struct mtk_eth *eth)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return MTK_FOE_IB1_BIND_TIMESTAMP_V2;
+       return MTK_FOE_IB1_BIND_TIMESTAMP;
+@@ -1201,7 +1211,7 @@ static inline u32 mtk_get_ib1_ts_mask(st
+ static inline u32 mtk_get_ib1_ppoe_mask(struct mtk_eth *eth)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return MTK_FOE_IB1_BIND_PPPOE_V2;
+       return MTK_FOE_IB1_BIND_PPPOE;
+@@ -1209,7 +1219,7 @@ static inline u32 mtk_get_ib1_ppoe_mask(
+ static inline u32 mtk_get_ib1_vlan_tag_mask(struct mtk_eth *eth)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return MTK_FOE_IB1_BIND_VLAN_TAG_V2;
+       return MTK_FOE_IB1_BIND_VLAN_TAG;
+@@ -1217,7 +1227,7 @@ static inline u32 mtk_get_ib1_vlan_tag_m
+ static inline u32 mtk_get_ib1_vlan_layer_mask(struct mtk_eth *eth)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return MTK_FOE_IB1_BIND_VLAN_LAYER_V2;
+       return MTK_FOE_IB1_BIND_VLAN_LAYER;
+@@ -1225,7 +1235,7 @@ static inline u32 mtk_get_ib1_vlan_layer
+ static inline u32 mtk_prep_ib1_vlan_layer(struct mtk_eth *eth, u32 val)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val);
+       return FIELD_PREP(MTK_FOE_IB1_BIND_VLAN_LAYER, val);
+@@ -1233,7 +1243,7 @@ static inline u32 mtk_prep_ib1_vlan_laye
+ static inline u32 mtk_get_ib1_vlan_layer(struct mtk_eth *eth, u32 val)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER_V2, val);
+       return FIELD_GET(MTK_FOE_IB1_BIND_VLAN_LAYER, val);
+@@ -1241,7 +1251,7 @@ static inline u32 mtk_get_ib1_vlan_layer
+ static inline u32 mtk_get_ib1_pkt_type_mask(struct mtk_eth *eth)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return MTK_FOE_IB1_PACKET_TYPE_V2;
+       return MTK_FOE_IB1_PACKET_TYPE;
+@@ -1249,7 +1259,7 @@ static inline u32 mtk_get_ib1_pkt_type_m
+ static inline u32 mtk_get_ib1_pkt_type(struct mtk_eth *eth, u32 val)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE_V2, val);
+       return FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, val);
+@@ -1257,7 +1267,7 @@ static inline u32 mtk_get_ib1_pkt_type(s
+ static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth)
+ {
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(eth))
+               return MTK_FOE_IB2_MULTICAST_V2;
+       return MTK_FOE_IB2_MULTICAST;
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -207,7 +207,7 @@ int mtk_foe_entry_prepare(struct mtk_eth
+       memset(entry, 0, sizeof(*entry));
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               val = FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_BIND) |
+                     FIELD_PREP(MTK_FOE_IB1_PACKET_TYPE_V2, type) |
+                     FIELD_PREP(MTK_FOE_IB1_UDP, l4proto == IPPROTO_UDP) |
+@@ -271,7 +271,7 @@ int mtk_foe_entry_set_pse_port(struct mt
+       u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
+       u32 val = *ib2;
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               val &= ~MTK_FOE_IB2_DEST_PORT_V2;
+               val |= FIELD_PREP(MTK_FOE_IB2_DEST_PORT_V2, port);
+       } else {
+@@ -422,7 +422,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
+       struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
+       u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
+               *ib2 |=  FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
+                        MTK_FOE_IB2_WDMA_WINFO_V2;
+@@ -446,7 +446,7 @@ int mtk_foe_entry_set_queue(struct mtk_e
+ {
+       u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               *ib2 &= ~MTK_FOE_IB2_QID_V2;
+               *ib2 |= FIELD_PREP(MTK_FOE_IB2_QID_V2, queue);
+               *ib2 |= MTK_FOE_IB2_PSE_QOS_V2;
+@@ -601,7 +601,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+       struct mtk_foe_entry *hwe;
+       u32 val;
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(eth)) {
+               entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
+               entry->ib1 |= FIELD_PREP(MTK_FOE_IB1_BIND_TIMESTAMP_V2,
+                                        timestamp);
+@@ -617,7 +617,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+       hwe->ib1 = entry->ib1;
+       if (ppe->accounting) {
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++              if (mtk_is_netsys_v2_or_greater(eth))
+                       val = MTK_FOE_IB2_MIB_CNT_V2;
+               else
+                       val = MTK_FOE_IB2_MIB_CNT;
+@@ -965,7 +965,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
+                        MTK_PPE_SCAN_MODE_KEEPALIVE_AGE) |
+             FIELD_PREP(MTK_PPE_TB_CFG_ENTRY_NUM,
+                        MTK_PPE_ENTRIES_SHIFT);
+-      if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(ppe->eth))
+               val |= MTK_PPE_TB_CFG_INFO_SEL;
+       ppe_w32(ppe, MTK_PPE_TB_CFG, val);
+@@ -981,7 +981,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
+             MTK_PPE_FLOW_CFG_IP4_NAPT |
+             MTK_PPE_FLOW_CFG_IP4_DSLITE |
+             MTK_PPE_FLOW_CFG_IP4_NAT_FRAG;
+-      if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2))
++      if (mtk_is_netsys_v2_or_greater(ppe->eth))
+               val |= MTK_PPE_MD_TOAP_BYP_CRSN0 |
+                      MTK_PPE_MD_TOAP_BYP_CRSN1 |
+                      MTK_PPE_MD_TOAP_BYP_CRSN2 |
+@@ -1023,7 +1023,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
+       ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT, 0);
+-      if (MTK_HAS_CAPS(ppe->eth->soc->caps, MTK_NETSYS_V2)) {
++      if (mtk_is_netsys_v2_or_greater(ppe->eth)) {
+               ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
+               ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
+       }
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
+@@ -193,7 +193,7 @@ mtk_flow_set_output_device(struct mtk_et
+       if (mtk_flow_get_wdma_info(dev, dest_mac, &info) == 0) {
+               mtk_foe_entry_set_wdma(eth, foe, info.wdma_idx, info.queue,
+                                      info.bss, info.wcid);
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
++              if (mtk_is_netsys_v2_or_greater(eth)) {
+                       switch (info.wdma_idx) {
+                       case 0:
+                               pse_port = 8;
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -1084,7 +1084,7 @@ mtk_wed_rx_reset(struct mtk_wed_device *
+       } else {
+               struct mtk_eth *eth = dev->hw->eth;
+-              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
++              if (mtk_is_netsys_v2_or_greater(eth))
+                       wed_set(dev, MTK_WED_RESET_IDX,
+                               MTK_WED_RESET_IDX_RX_V2);
+               else
+@@ -1806,7 +1806,7 @@ void mtk_wed_add_hw(struct device_node *
+       hw->wdma = wdma;
+       hw->index = index;
+       hw->irq = irq;
+-      hw->version = MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) ? 2 : 1;
++      hw->version = mtk_is_netsys_v1(eth) ? 1 : 2;
+       if (hw->version == 1) {
+               hw->mirror = syscon_regmap_lookup_by_phandle(eth_np,
diff --git a/target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch b/target/linux/generic/backport-6.1/750-v6.5-06-net-ethernet-mtk_eth_soc-increase-MAX_DEVS-to-3.patch
new file mode 100644 (file)
index 0000000..7b945bb
--- /dev/null
@@ -0,0 +1,29 @@
+From f8fb8dbd158c585be7574faf92db7d614b6722ff Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 25 Jul 2023 01:52:27 +0100
+Subject: [PATCH 100/250] net: ethernet: mtk_eth_soc: increase MAX_DEVS to 3
+
+This is a preliminary patch to add MT7988 SoC support since it runs 3
+macs instead of 2.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/3563e5fab367e7d79a7f1296fabaa5c20f202d7a.1690246066.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1043,8 +1043,8 @@ struct mtk_soc_data {
+ #define MTK_DMA_MONITOR_TIMEOUT               msecs_to_jiffies(1000)
+-/* currently no SoC has more than 2 macs */
+-#define MTK_MAX_DEVS                  2
++/* currently no SoC has more than 3 macs */
++#define MTK_MAX_DEVS  3
+ /* struct mtk_eth -   This is the main datasructure for holding the state
+  *                    of the driver
diff --git a/target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch b/target/linux/generic/backport-6.1/750-v6.5-07-net-ethernet-mtk_eth_soc-rely-on-MTK_MAX_DEVS-and-re.patch
new file mode 100644 (file)
index 0000000..d7ba0d4
--- /dev/null
@@ -0,0 +1,186 @@
+From 856be974290f28d7943be2ac5a382c4139486196 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 25 Jul 2023 01:52:44 +0100
+Subject: [PATCH 101/250] net: ethernet: mtk_eth_soc: rely on MTK_MAX_DEVS and
+ remove MTK_MAC_COUNT
+
+Get rid of MTK_MAC_COUNT since it is a duplicated of MTK_MAX_DEVS.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/1856f4266f2fc80677807b1bad867659e7b00c65.1690246066.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++++++---------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  1 -
+ 2 files changed, 27 insertions(+), 23 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -882,7 +882,7 @@ static void mtk_stats_update(struct mtk_
+ {
+       int i;
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               if (!eth->mac[i] || !eth->mac[i]->hw_stats)
+                       continue;
+               if (spin_trylock(&eth->mac[i]->hw_stats->stats_lock)) {
+@@ -1387,7 +1387,7 @@ static int mtk_queue_stopped(struct mtk_
+ {
+       int i;
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               if (!eth->netdev[i])
+                       continue;
+               if (netif_queue_stopped(eth->netdev[i]))
+@@ -1401,7 +1401,7 @@ static void mtk_wake_queue(struct mtk_et
+ {
+       int i;
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               if (!eth->netdev[i])
+                       continue;
+               netif_tx_wake_all_queues(eth->netdev[i]);
+@@ -1860,7 +1860,7 @@ static int mtk_poll_rx(struct napi_struc
+                        !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
+                       mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
+-              if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
++              if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS ||
+                            !eth->netdev[mac]))
+                       goto release_desc;
+@@ -2897,7 +2897,7 @@ static void mtk_dma_free(struct mtk_eth
+       const struct mtk_soc_data *soc = eth->soc;
+       int i;
+-      for (i = 0; i < MTK_MAC_COUNT; i++)
++      for (i = 0; i < MTK_MAX_DEVS; i++)
+               if (eth->netdev[i])
+                       netdev_reset_queue(eth->netdev[i]);
+       if (eth->scratch_ring) {
+@@ -3051,8 +3051,13 @@ static void mtk_gdm_config(struct mtk_et
+       if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
+               return;
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
+-              u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
++              u32 val;
++
++              if (!eth->netdev[i])
++                      continue;
++
++              val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
+               /* default setup the forward port to send frame to PDMA */
+               val &= ~0xffff;
+@@ -3062,7 +3067,7 @@ static void mtk_gdm_config(struct mtk_et
+               val |= config;
+-              if (eth->netdev[i] && netdev_uses_dsa(eth->netdev[i]))
++              if (netdev_uses_dsa(eth->netdev[i]))
+                       val |= MTK_GDMA_SPECIAL_TAG;
+               mtk_w32(eth, val, MTK_GDMA_FWD_CFG(i));
+@@ -3659,15 +3664,15 @@ static int mtk_hw_init(struct mtk_eth *e
+        * up with the more appropriate value when mtk_mac_config call is being
+        * invoked.
+        */
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               struct net_device *dev = eth->netdev[i];
+-              mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
+-              if (dev) {
+-                      struct mtk_mac *mac = netdev_priv(dev);
++              if (!dev)
++                      continue;
+-                      mtk_set_mcr_max_rx(mac, dev->mtu + MTK_RX_ETH_HLEN);
+-              }
++              mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
++              mtk_set_mcr_max_rx(netdev_priv(dev),
++                                 dev->mtu + MTK_RX_ETH_HLEN);
+       }
+       /* Indicates CDM to parse the MTK special tag from CPU
+@@ -3847,7 +3852,7 @@ static void mtk_pending_work(struct work
+       mtk_prepare_for_reset(eth);
+       /* stop all devices to make sure that dma is properly shut down */
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
+                       continue;
+@@ -3863,8 +3868,8 @@ static void mtk_pending_work(struct work
+       mtk_hw_init(eth, true);
+       /* restart DMA and enable IRQs */
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
+-              if (!test_bit(i, &restart))
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
++              if (!eth->netdev[i] || !test_bit(i, &restart))
+                       continue;
+               if (mtk_open(eth->netdev[i])) {
+@@ -3891,7 +3896,7 @@ static int mtk_free_dev(struct mtk_eth *
+ {
+       int i;
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               if (!eth->netdev[i])
+                       continue;
+               free_netdev(eth->netdev[i]);
+@@ -3910,7 +3915,7 @@ static int mtk_unreg_dev(struct mtk_eth
+ {
+       int i;
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               struct mtk_mac *mac;
+               if (!eth->netdev[i])
+                       continue;
+@@ -4211,7 +4216,7 @@ static int mtk_add_mac(struct mtk_eth *e
+       }
+       id = be32_to_cpup(_id);
+-      if (id >= MTK_MAC_COUNT) {
++      if (id >= MTK_MAX_DEVS) {
+               dev_err(eth->dev, "%d is not a valid mac id\n", id);
+               return -EINVAL;
+       }
+@@ -4356,7 +4361,7 @@ void mtk_eth_set_dma_device(struct mtk_e
+       rtnl_lock();
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               dev = eth->netdev[i];
+               if (!dev || !(dev->flags & IFF_UP))
+@@ -4662,7 +4667,7 @@ static int mtk_remove(struct platform_de
+       int i;
+       /* stop all devices to make sure that dma is properly shut down */
+-      for (i = 0; i < MTK_MAC_COUNT; i++) {
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
+               if (!eth->netdev[i])
+                       continue;
+               mtk_stop(eth->netdev[i]);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -33,7 +33,6 @@
+ #define MTK_TX_DMA_BUF_LEN_V2 0xffff
+ #define MTK_QDMA_RING_SIZE    2048
+ #define MTK_DMA_SIZE          512
+-#define MTK_MAC_COUNT         2
+ #define MTK_RX_ETH_HLEN               (VLAN_ETH_HLEN + ETH_FCS_LEN)
+ #define MTK_RX_HLEN           (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
+ #define MTK_DMA_DUMMY_DESC    0xffffffff
diff --git a/target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch b/target/linux/generic/backport-6.1/750-v6.5-08-net-ethernet-mtk_eth_soc-add-NETSYS_V3-version-suppo.patch
new file mode 100644 (file)
index 0000000..f06fcce
--- /dev/null
@@ -0,0 +1,307 @@
+From a41d535855976838d246c079143c948dcf0f7931 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 25 Jul 2023 01:52:59 +0100
+Subject: [PATCH 102/250] net: ethernet: mtk_eth_soc: add NETSYS_V3 version
+ support
+
+Introduce NETSYS_V3 chipset version support.
+This is a preliminary patch to introduce support for MT7988 SoC.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/0db2260910755d76fa48e303b9f9bdf4e5a82340.1690246066.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 105 ++++++++++++++------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  48 +++++++--
+ 2 files changed, 116 insertions(+), 37 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -862,17 +862,32 @@ void mtk_stats_update_mac(struct mtk_mac
+                       mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
+               hw_stats->rx_flow_control_packets +=
+                       mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
+-              hw_stats->tx_skip +=
+-                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
+-              hw_stats->tx_collisions +=
+-                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
+-              hw_stats->tx_bytes +=
+-                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
+-              stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
+-              if (stats)
+-                      hw_stats->tx_bytes += (stats << 32);
+-              hw_stats->tx_packets +=
+-                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
++
++              if (mtk_is_netsys_v3_or_greater(eth)) {
++                      hw_stats->tx_skip +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs);
++                      hw_stats->tx_collisions +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs);
++                      hw_stats->tx_bytes +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs);
++                      stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs);
++                      if (stats)
++                              hw_stats->tx_bytes += (stats << 32);
++                      hw_stats->tx_packets +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs);
++              } else {
++                      hw_stats->tx_skip +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
++                      hw_stats->tx_collisions +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
++                      hw_stats->tx_bytes +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
++                      stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
++                      if (stats)
++                              hw_stats->tx_bytes += (stats << 32);
++                      hw_stats->tx_packets +=
++                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
++              }
+       }
+       u64_stats_update_end(&hw_stats->syncp);
+@@ -1176,7 +1191,10 @@ static void mtk_tx_set_dma_desc_v2(struc
+               data |= TX_DMA_LS0;
+       WRITE_ONCE(desc->txd3, data);
+-      data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
++      if (mac->id == MTK_GMAC3_ID)
++              data = PSE_GDM3_PORT;
++      else
++              data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
+       data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
+       WRITE_ONCE(desc->txd4, data);
+@@ -1187,6 +1205,8 @@ static void mtk_tx_set_dma_desc_v2(struc
+               /* tx checksum offload */
+               if (info->csum)
+                       data |= TX_DMA_CHKSUM_V2;
++              if (mtk_is_netsys_v3_or_greater(eth) && netdev_uses_dsa(dev))
++                      data |= TX_DMA_SPTAG_V3;
+       }
+       WRITE_ONCE(desc->txd5, data);
+@@ -1252,8 +1272,7 @@ static int mtk_tx_map(struct sk_buff *sk
+       mtk_tx_set_dma_desc(dev, itxd, &txd_info);
+       itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
+-      itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
+-                        MTK_TX_FLAGS_FPORT1;
++      itx_buf->mac_id = mac->id;
+       setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
+                    k++);
+@@ -1301,8 +1320,7 @@ static int mtk_tx_map(struct sk_buff *sk
+                               memset(tx_buf, 0, sizeof(*tx_buf));
+                       tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
+                       tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
+-                      tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
+-                                       MTK_TX_FLAGS_FPORT1;
++                      tx_buf->mac_id = mac->id;
+                       setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
+                                    txd_info.size, k++);
+@@ -1604,7 +1622,7 @@ static int mtk_xdp_frame_map(struct mtk_
+       }
+       mtk_tx_set_dma_desc(dev, txd, txd_info);
+-      tx_buf->flags |= !mac->id ? MTK_TX_FLAGS_FPORT0 : MTK_TX_FLAGS_FPORT1;
++      tx_buf->mac_id = mac->id;
+       tx_buf->type = dma_map ? MTK_TYPE_XDP_NDO : MTK_TYPE_XDP_TX;
+       tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
+@@ -1854,11 +1872,24 @@ static int mtk_poll_rx(struct napi_struc
+                       break;
+               /* find out which mac the packet come from. values start at 1 */
+-              if (mtk_is_netsys_v2_or_greater(eth))
+-                      mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
+-              else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
+-                       !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
++              if (mtk_is_netsys_v2_or_greater(eth)) {
++                      u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
++
++                      switch (val) {
++                      case PSE_GDM1_PORT:
++                      case PSE_GDM2_PORT:
++                              mac = val - 1;
++                              break;
++                      case PSE_GDM3_PORT:
++                              mac = MTK_GMAC3_ID;
++                              break;
++                      default:
++                              break;
++                      }
++              } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
++                         !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
+                       mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
++              }
+               if (unlikely(mac < 0 || mac >= MTK_MAX_DEVS ||
+                            !eth->netdev[mac]))
+@@ -2080,7 +2111,6 @@ static int mtk_poll_tx_qdma(struct mtk_e
+       while ((cpu != dma) && budget) {
+               u32 next_cpu = desc->txd2;
+-              int mac = 0;
+               desc = mtk_qdma_phys_to_virt(ring, desc->txd2);
+               if ((desc->txd3 & TX_DMA_OWNER_CPU) == 0)
+@@ -2088,15 +2118,13 @@ static int mtk_poll_tx_qdma(struct mtk_e
+               tx_buf = mtk_desc_to_tx_buf(ring, desc,
+                                           eth->soc->txrx.txd_size);
+-              if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
+-                      mac = 1;
+-
+               if (!tx_buf->data)
+                       break;
+               if (tx_buf->data != (void *)MTK_DMA_DUMMY_DESC) {
+                       if (tx_buf->type == MTK_TYPE_SKB)
+-                              mtk_poll_tx_done(eth, state, mac, tx_buf->data);
++                              mtk_poll_tx_done(eth, state, tx_buf->mac_id,
++                                               tx_buf->data);
+                       budget--;
+               }
+@@ -3702,7 +3730,24 @@ static int mtk_hw_init(struct mtk_eth *e
+       mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
+       mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
+-      if (mtk_is_netsys_v2_or_greater(eth)) {
++      if (mtk_is_netsys_v3_or_greater(eth)) {
++              /* PSE should not drop port1, port8 and port9 packets */
++              mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
++
++              /* GDM and CDM Threshold */
++              mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
++              mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
++
++              /* Disable GDM1 RX CRC stripping */
++              mtk_m32(eth, MTK_GDMA_STRP_CRC, 0, MTK_GDMA_FWD_CFG(0));
++
++              /* PSE GDM3 MIB counter has incorrect hw default values,
++               * so the driver ought to read clear the values beforehand
++               * in case ethtool retrieve wrong mib values.
++               */
++              for (i = 0; i < 0x80; i += 0x4)
++                      mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i);
++      } else if (!mtk_is_netsys_v1(eth)) {
+               /* PSE should not drop port8 and port9 packets from WDMA Tx */
+               mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
+@@ -4264,7 +4309,11 @@ static int mtk_add_mac(struct mtk_eth *e
+       }
+       spin_lock_init(&mac->hw_stats->stats_lock);
+       u64_stats_init(&mac->hw_stats->syncp);
+-      mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
++
++      if (mtk_is_netsys_v3_or_greater(eth))
++              mac->hw_stats->reg_offset = id * 0x80;
++      else
++              mac->hw_stats->reg_offset = id * 0x40;
+       /* phylink create */
+       err = of_get_phy_mode(np, &phy_mode);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -122,6 +122,7 @@
+ #define MTK_GDMA_ICS_EN               BIT(22)
+ #define MTK_GDMA_TCS_EN               BIT(21)
+ #define MTK_GDMA_UCS_EN               BIT(20)
++#define MTK_GDMA_STRP_CRC     BIT(16)
+ #define MTK_GDMA_TO_PDMA      0x0
+ #define MTK_GDMA_DROP_ALL       0x7777
+@@ -287,8 +288,6 @@
+ /* QDMA Interrupt grouping registers */
+ #define MTK_RLS_DONE_INT      BIT(0)
+-#define MTK_STAT_OFFSET               0x40
+-
+ /* QDMA TX NUM */
+ #define QID_BITS_V2(x)                (((x) & 0x3f) << 16)
+ #define MTK_QDMA_GMAC2_QID    8
+@@ -301,6 +300,8 @@
+ #define TX_DMA_CHKSUM_V2      (0x7 << 28)
+ #define TX_DMA_TSO_V2         BIT(31)
++#define TX_DMA_SPTAG_V3         BIT(27)
++
+ /* QDMA V2 descriptor txd4 */
+ #define TX_DMA_FPORT_SHIFT_V2 8
+ #define TX_DMA_FPORT_MASK_V2  0xf
+@@ -634,12 +635,6 @@ enum mtk_tx_flags {
+        */
+       MTK_TX_FLAGS_SINGLE0    = 0x01,
+       MTK_TX_FLAGS_PAGE0      = 0x02,
+-
+-      /* MTK_TX_FLAGS_FPORTx allows tracking which port the transmitted
+-       * SKB out instead of looking up through hardware TX descriptor.
+-       */
+-      MTK_TX_FLAGS_FPORT0     = 0x04,
+-      MTK_TX_FLAGS_FPORT1     = 0x08,
+ };
+ /* This enum allows us to identify how the clock is defined on the array of the
+@@ -725,6 +720,35 @@ enum mtk_dev_state {
+       MTK_RESETTING
+ };
++/* PSE Port Definition */
++enum mtk_pse_port {
++      PSE_ADMA_PORT = 0,
++      PSE_GDM1_PORT,
++      PSE_GDM2_PORT,
++      PSE_PPE0_PORT,
++      PSE_PPE1_PORT,
++      PSE_QDMA_TX_PORT,
++      PSE_QDMA_RX_PORT,
++      PSE_DROP_PORT,
++      PSE_WDMA0_PORT,
++      PSE_WDMA1_PORT,
++      PSE_TDMA_PORT,
++      PSE_NONE_PORT,
++      PSE_PPE2_PORT,
++      PSE_WDMA2_PORT,
++      PSE_EIP197_PORT,
++      PSE_GDM3_PORT,
++      PSE_PORT_MAX
++};
++
++/* GMAC Identifier */
++enum mtk_gmac_id {
++      MTK_GMAC1_ID = 0,
++      MTK_GMAC2_ID,
++      MTK_GMAC3_ID,
++      MTK_GMAC_ID_MAX
++};
++
+ enum mtk_tx_buf_type {
+       MTK_TYPE_SKB,
+       MTK_TYPE_XDP_TX,
+@@ -743,7 +767,8 @@ struct mtk_tx_buf {
+       enum mtk_tx_buf_type type;
+       void *data;
+-      u32 flags;
++      u16 mac_id;
++      u16 flags;
+       DEFINE_DMA_UNMAP_ADDR(dma_addr0);
+       DEFINE_DMA_UNMAP_LEN(dma_len0);
+       DEFINE_DMA_UNMAP_ADDR(dma_addr1);
+@@ -1192,6 +1217,11 @@ static inline bool mtk_is_netsys_v2_or_g
+       return eth->soc->version > 1;
+ }
++static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth)
++{
++      return eth->soc->version > 2;
++}
++
+ static inline struct mtk_foe_entry *
+ mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
+ {
diff --git a/target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch b/target/linux/generic/backport-6.1/750-v6.5-09-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch
new file mode 100644 (file)
index 0000000..7a0b285
--- /dev/null
@@ -0,0 +1,193 @@
+From db797ae0542220a98658229397da464c383c991c Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 25 Jul 2023 01:53:13 +0100
+Subject: [PATCH 103/250] net: ethernet: mtk_eth_soc: convert caps in
+ mtk_soc_data struct to u64
+
+This is a preliminary patch to introduce support for MT7988 SoC.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/9499ac3670b2fc5b444404b84e8a4a169beabbf2.1690246066.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 ++++----
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 56 ++++++++++----------
+ 2 files changed, 39 insertions(+), 39 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
+@@ -15,10 +15,10 @@
+ struct mtk_eth_muxc {
+       const char      *name;
+       int             cap_bit;
+-      int             (*set_path)(struct mtk_eth *eth, int path);
++      int             (*set_path)(struct mtk_eth *eth, u64 path);
+ };
+-static const char *mtk_eth_path_name(int path)
++static const char *mtk_eth_path_name(u64 path)
+ {
+       switch (path) {
+       case MTK_ETH_PATH_GMAC1_RGMII:
+@@ -40,7 +40,7 @@ static const char *mtk_eth_path_name(int
+       }
+ }
+-static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
++static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
+ {
+       bool updated = true;
+       u32 val, mask, set;
+@@ -71,7 +71,7 @@ static int set_mux_gdm1_to_gmac1_esw(str
+       return 0;
+ }
+-static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
++static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0;
+       bool updated = true;
+@@ -94,7 +94,7 @@ static int set_mux_gmac2_gmac0_to_gephy(
+       return 0;
+ }
+-static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
++static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0, mask = 0, reg = 0;
+       bool updated = true;
+@@ -125,7 +125,7 @@ static int set_mux_u3_gmac2_to_qphy(stru
+       return 0;
+ }
+-static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
++static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0;
+       bool updated = true;
+@@ -163,7 +163,7 @@ static int set_mux_gmac1_gmac2_to_sgmii_
+       return 0;
+ }
+-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
++static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0;
+       bool updated = true;
+@@ -218,7 +218,7 @@ static const struct mtk_eth_muxc mtk_eth
+       },
+ };
+-static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
++static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
+ {
+       int i, err = 0;
+@@ -249,7 +249,7 @@ out:
+ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
+ {
+-      int path;
++      u64 path;
+       path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
+                               MTK_ETH_PATH_GMAC2_SGMII;
+@@ -260,7 +260,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk
+ int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
+ {
+-      int path = 0;
++      u64 path = 0;
+       if (mac_id == 1)
+               path = MTK_ETH_PATH_GMAC2_GEPHY;
+@@ -274,7 +274,7 @@ int mtk_gmac_gephy_path_setup(struct mtk
+ int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
+ {
+-      int path;
++      u64 path;
+       path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_RGMII :
+                               MTK_ETH_PATH_GMAC2_RGMII;
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -866,41 +866,41 @@ enum mkt_eth_capabilities {
+ };
+ /* Supported hardware group on SoCs */
+-#define MTK_RGMII             BIT(MTK_RGMII_BIT)
+-#define MTK_TRGMII            BIT(MTK_TRGMII_BIT)
+-#define MTK_SGMII             BIT(MTK_SGMII_BIT)
+-#define MTK_ESW                       BIT(MTK_ESW_BIT)
+-#define MTK_GEPHY             BIT(MTK_GEPHY_BIT)
+-#define MTK_MUX                       BIT(MTK_MUX_BIT)
+-#define MTK_INFRA             BIT(MTK_INFRA_BIT)
+-#define MTK_SHARED_SGMII      BIT(MTK_SHARED_SGMII_BIT)
+-#define MTK_HWLRO             BIT(MTK_HWLRO_BIT)
+-#define MTK_SHARED_INT                BIT(MTK_SHARED_INT_BIT)
+-#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
+-#define MTK_QDMA              BIT(MTK_QDMA_BIT)
+-#define MTK_SOC_MT7628                BIT(MTK_SOC_MT7628_BIT)
+-#define MTK_RSTCTRL_PPE1      BIT(MTK_RSTCTRL_PPE1_BIT)
+-#define MTK_U3_COPHY_V2               BIT(MTK_U3_COPHY_V2_BIT)
++#define MTK_RGMII             BIT_ULL(MTK_RGMII_BIT)
++#define MTK_TRGMII            BIT_ULL(MTK_TRGMII_BIT)
++#define MTK_SGMII             BIT_ULL(MTK_SGMII_BIT)
++#define MTK_ESW                       BIT_ULL(MTK_ESW_BIT)
++#define MTK_GEPHY             BIT_ULL(MTK_GEPHY_BIT)
++#define MTK_MUX                       BIT_ULL(MTK_MUX_BIT)
++#define MTK_INFRA             BIT_ULL(MTK_INFRA_BIT)
++#define MTK_SHARED_SGMII      BIT_ULL(MTK_SHARED_SGMII_BIT)
++#define MTK_HWLRO             BIT_ULL(MTK_HWLRO_BIT)
++#define MTK_SHARED_INT                BIT_ULL(MTK_SHARED_INT_BIT)
++#define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT)
++#define MTK_QDMA              BIT_ULL(MTK_QDMA_BIT)
++#define MTK_SOC_MT7628                BIT_ULL(MTK_SOC_MT7628_BIT)
++#define MTK_RSTCTRL_PPE1      BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
++#define MTK_U3_COPHY_V2               BIT_ULL(MTK_U3_COPHY_V2_BIT)
+ #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
+-      BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
++      BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
+ #define MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY      \
+-      BIT(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
++      BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
+ #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY          \
+-      BIT(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
++      BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
+ #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII        \
+-      BIT(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
++      BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
+ #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII     \
+-      BIT(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
++      BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
+ /* Supported path present on SoCs */
+-#define MTK_ETH_PATH_GMAC1_RGMII      BIT(MTK_ETH_PATH_GMAC1_RGMII_BIT)
+-#define MTK_ETH_PATH_GMAC1_TRGMII     BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
+-#define MTK_ETH_PATH_GMAC1_SGMII      BIT(MTK_ETH_PATH_GMAC1_SGMII_BIT)
+-#define MTK_ETH_PATH_GMAC2_RGMII      BIT(MTK_ETH_PATH_GMAC2_RGMII_BIT)
+-#define MTK_ETH_PATH_GMAC2_SGMII      BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT)
+-#define MTK_ETH_PATH_GMAC2_GEPHY      BIT(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
+-#define MTK_ETH_PATH_GDM1_ESW         BIT(MTK_ETH_PATH_GDM1_ESW_BIT)
++#define MTK_ETH_PATH_GMAC1_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
++#define MTK_ETH_PATH_GMAC1_TRGMII     BIT_ULL(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
++#define MTK_ETH_PATH_GMAC1_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
++#define MTK_ETH_PATH_GMAC2_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
++#define MTK_ETH_PATH_GMAC2_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
++#define MTK_ETH_PATH_GMAC2_GEPHY      BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
++#define MTK_ETH_PATH_GDM1_ESW         BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
+ #define MTK_GMAC1_RGMII               (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
+ #define MTK_GMAC1_TRGMII      (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
+@@ -1045,7 +1045,7 @@ struct mtk_reg_map {
+ struct mtk_soc_data {
+       const struct mtk_reg_map *reg_map;
+       u32             ana_rgc3;
+-      u32             caps;
++      u64             caps;
+       u32             required_clks;
+       bool            required_pctl;
+       u8              offload_version;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch b/target/linux/generic/backport-6.1/750-v6.5-10-net-ethernet-mtk_eth_soc-convert-clock-bitmap-to-u64.patch
new file mode 100644 (file)
index 0000000..5947d38
--- /dev/null
@@ -0,0 +1,132 @@
+From a1c9f7d1d24e90294f6a6755b137fcf306851e93 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 25 Jul 2023 01:53:28 +0100
+Subject: [PATCH 104/250] net: ethernet: mtk_eth_soc: convert clock bitmap to
+ u64
+
+The to-be-added MT7988 SoC adds many new clocks which need to be
+controlled by the Ethernet driver, which will result in their total
+number exceeding 32.
+Prepare by converting clock bitmaps into 64-bit types.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/6960a39bb0078cf84d7642a9558e6a91c6cc9df3.1690246066.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 96 +++++++++++----------
+ 1 file changed, 49 insertions(+), 47 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -666,54 +666,56 @@ enum mtk_clks_map {
+       MTK_CLK_MAX
+ };
+-#define MT7623_CLKS_BITMAP    (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) |  \
+-                               BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \
+-                               BIT(MTK_CLK_TRGPLL))
+-#define MT7622_CLKS_BITMAP    (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) |  \
+-                               BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
+-                               BIT(MTK_CLK_GP2) | \
+-                               BIT(MTK_CLK_SGMII_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII_CDR_FB) | \
+-                               BIT(MTK_CLK_SGMII_CK) | \
+-                               BIT(MTK_CLK_ETH2PLL))
++#define MT7623_CLKS_BITMAP    (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) |  \
++                               BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
++                               BIT_ULL(MTK_CLK_TRGPLL))
++#define MT7622_CLKS_BITMAP    (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) |  \
++                               BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
++                               BIT_ULL(MTK_CLK_GP2) | \
++                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
++                               BIT_ULL(MTK_CLK_SGMII_CK) | \
++                               BIT_ULL(MTK_CLK_ETH2PLL))
+ #define MT7621_CLKS_BITMAP    (0)
+ #define MT7628_CLKS_BITMAP    (0)
+-#define MT7629_CLKS_BITMAP    (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) |  \
+-                               BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
+-                               BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \
+-                               BIT(MTK_CLK_SGMII_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII_CDR_FB) | \
+-                               BIT(MTK_CLK_SGMII2_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII2_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII2_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII2_CDR_FB) | \
+-                               BIT(MTK_CLK_SGMII_CK) | \
+-                               BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
+-#define MT7981_CLKS_BITMAP    (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
+-                               BIT(MTK_CLK_WOCPU0) | \
+-                               BIT(MTK_CLK_SGMII_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII_CDR_FB) | \
+-                               BIT(MTK_CLK_SGMII2_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII2_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII2_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII2_CDR_FB) | \
+-                               BIT(MTK_CLK_SGMII_CK))
+-#define MT7986_CLKS_BITMAP    (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
+-                               BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
+-                               BIT(MTK_CLK_SGMII_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII_CDR_FB) | \
+-                               BIT(MTK_CLK_SGMII2_TX_250M) | \
+-                               BIT(MTK_CLK_SGMII2_RX_250M) | \
+-                               BIT(MTK_CLK_SGMII2_CDR_REF) | \
+-                               BIT(MTK_CLK_SGMII2_CDR_FB))
++#define MT7629_CLKS_BITMAP    (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) |  \
++                               BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
++                               BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \
++                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
++                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
++                               BIT_ULL(MTK_CLK_SGMII_CK) | \
++                               BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP))
++#define MT7981_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \
++                               BIT_ULL(MTK_CLK_GP1) | \
++                               BIT_ULL(MTK_CLK_WOCPU0) | \
++                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
++                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
++                               BIT_ULL(MTK_CLK_SGMII_CK))
++#define MT7986_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | \
++                               BIT_ULL(MTK_CLK_GP1) | \
++                               BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \
++                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
++                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
++                               BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
+ enum mtk_dev_state {
+       MTK_HW_INIT,
+@@ -1046,7 +1048,7 @@ struct mtk_soc_data {
+       const struct mtk_reg_map *reg_map;
+       u32             ana_rgc3;
+       u64             caps;
+-      u32             required_clks;
++      u64             required_clks;
+       bool            required_pctl;
+       u8              offload_version;
+       u8              hash_offset;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch b/target/linux/generic/backport-6.1/750-v6.5-11-net-ethernet-mtk_eth_soc-add-basic-support-for-MT798.patch
new file mode 100644 (file)
index 0000000..a719523
--- /dev/null
@@ -0,0 +1,477 @@
+From 94f825a7eadfc8b4c8828efdb7705d9703f9c73e Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Tue, 25 Jul 2023 01:57:42 +0100
+Subject: [PATCH 105/250] net: ethernet: mtk_eth_soc: add basic support for
+ MT7988 SoC
+
+Introduce support for ethernet chip available in MT7988 SoC to
+mtk_eth_soc driver. As a first step support only the first GMAC which
+is hard-wired to the internal DSA switch having 4 built-in gigabit
+Ethernet PHYs.
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/25c8377095b95d186872eeda7aa055da83e8f0ca.1690246605.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_path.c |  14 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c  | 201 +++++++++++++++++--
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h  |  86 +++++++-
+ 3 files changed, 273 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
+@@ -43,7 +43,7 @@ static const char *mtk_eth_path_name(u64
+ static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
+ {
+       bool updated = true;
+-      u32 val, mask, set;
++      u32 mask, set, reg;
+       switch (path) {
+       case MTK_ETH_PATH_GMAC1_SGMII:
+@@ -59,11 +59,13 @@ static int set_mux_gdm1_to_gmac1_esw(str
+               break;
+       }
+-      if (updated) {
+-              val = mtk_r32(eth, MTK_MAC_MISC);
+-              val = (val & mask) | set;
+-              mtk_w32(eth, val, MTK_MAC_MISC);
+-      }
++      if (mtk_is_netsys_v3_or_greater(eth))
++              reg = MTK_MAC_MISC_V3;
++      else
++              reg = MTK_MAC_MISC;
++
++      if (updated)
++              mtk_m32(eth, mask, set, reg);
+       dev_dbg(eth->dev, "path %s in %s updated = %d\n",
+               mtk_eth_path_name(path), __func__, updated);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r
+       .pse_oq_sta             = 0x01a0,
+ };
++static const struct mtk_reg_map mt7988_reg_map = {
++      .tx_irq_mask            = 0x461c,
++      .tx_irq_status          = 0x4618,
++      .pdma = {
++              .rx_ptr         = 0x6900,
++              .rx_cnt_cfg     = 0x6904,
++              .pcrx_ptr       = 0x6908,
++              .glo_cfg        = 0x6a04,
++              .rst_idx        = 0x6a08,
++              .delay_irq      = 0x6a0c,
++              .irq_status     = 0x6a20,
++              .irq_mask       = 0x6a28,
++              .adma_rx_dbg0   = 0x6a38,
++              .int_grp        = 0x6a50,
++      },
++      .qdma = {
++              .qtx_cfg        = 0x4400,
++              .qtx_sch        = 0x4404,
++              .rx_ptr         = 0x4500,
++              .rx_cnt_cfg     = 0x4504,
++              .qcrx_ptr       = 0x4508,
++              .glo_cfg        = 0x4604,
++              .rst_idx        = 0x4608,
++              .delay_irq      = 0x460c,
++              .fc_th          = 0x4610,
++              .int_grp        = 0x4620,
++              .hred           = 0x4644,
++              .ctx_ptr        = 0x4700,
++              .dtx_ptr        = 0x4704,
++              .crx_ptr        = 0x4710,
++              .drx_ptr        = 0x4714,
++              .fq_head        = 0x4720,
++              .fq_tail        = 0x4724,
++              .fq_count       = 0x4728,
++              .fq_blen        = 0x472c,
++              .tx_sch_rate    = 0x4798,
++      },
++      .gdm1_cnt               = 0x1c00,
++      .gdma_to_ppe            = 0x3333,
++      .ppe_base               = 0x2000,
++      .wdma_base = {
++              [0]             = 0x4800,
++              [1]             = 0x4c00,
++      },
++      .pse_iq_sta             = 0x0180,
++      .pse_oq_sta             = 0x01a0,
++};
++
+ /* strings used by ethtool */
+ static const struct mtk_ethtool_stats {
+       char str[ETH_GSTRING_LEN];
+@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats {
+ };
+ static const char * const mtk_clks_source_name[] = {
+-      "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll",
+-      "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb",
+-      "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb",
+-      "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1"
++      "ethif",
++      "sgmiitop",
++      "esw",
++      "gp0",
++      "gp1",
++      "gp2",
++      "gp3",
++      "xgp1",
++      "xgp2",
++      "xgp3",
++      "crypto",
++      "fe",
++      "trgpll",
++      "sgmii_tx250m",
++      "sgmii_rx250m",
++      "sgmii_cdr_ref",
++      "sgmii_cdr_fb",
++      "sgmii2_tx250m",
++      "sgmii2_rx250m",
++      "sgmii2_cdr_ref",
++      "sgmii2_cdr_fb",
++      "sgmii_ck",
++      "eth2pll",
++      "wocpu0",
++      "wocpu1",
++      "netsys0",
++      "netsys1",
++      "ethwarp_wocpu2",
++      "ethwarp_wocpu1",
++      "ethwarp_wocpu0",
++      "top_usxgmii0_sel",
++      "top_usxgmii1_sel",
++      "top_sgm0_sel",
++      "top_sgm1_sel",
++      "top_xfi_phy0_xtal_sel",
++      "top_xfi_phy1_xtal_sel",
++      "top_eth_gmii_sel",
++      "top_eth_refck_50m_sel",
++      "top_eth_sys_200m_sel",
++      "top_eth_sys_sel",
++      "top_eth_xgmii_sel",
++      "top_eth_mii_sel",
++      "top_netsys_sel",
++      "top_netsys_500m_sel",
++      "top_netsys_pao_2x_sel",
++      "top_netsys_sync_250m_sel",
++      "top_netsys_ppefb_250m_sel",
++      "top_netsys_warp_sel",
+ };
+ void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
+@@ -195,7 +287,7 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
+       return __raw_readl(eth->base + reg);
+ }
+-static u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned reg)
++u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg)
+ {
+       u32 val;
+@@ -369,6 +461,19 @@ static void mtk_gmac0_rgmii_adjust(struc
+       dev_err(eth->dev, "Missing PLL configuration, ethernet may not work\n");
+ }
++static void mtk_setup_bridge_switch(struct mtk_eth *eth)
++{
++      /* Force Port1 XGMAC Link Up */
++      mtk_m32(eth, 0, MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID),
++              MTK_XGMAC_STS(MTK_GMAC1_ID));
++
++      /* Adjust GSW bridge IPG to 11 */
++      mtk_m32(eth, GSWTX_IPG_MASK | GSWRX_IPG_MASK,
++              (GSW_IPG_11 << GSWTX_IPG_SHIFT) |
++              (GSW_IPG_11 << GSWRX_IPG_SHIFT),
++              MTK_GSW_CFG);
++}
++
+ static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
+                                             phy_interface_t interface)
+ {
+@@ -438,6 +543,8 @@ static void mtk_mac_config(struct phylin
+                                       goto init_err;
+                       }
+                       break;
++              case PHY_INTERFACE_MODE_INTERNAL:
++                      break;
+               default:
+                       goto err_phy;
+               }
+@@ -515,6 +622,15 @@ static void mtk_mac_config(struct phylin
+               return;
+       }
++      /* Setup gmac */
++      if (mtk_is_netsys_v3_or_greater(eth) &&
++          mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
++              mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
++              mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
++
++              mtk_setup_bridge_switch(eth);
++      }
++
+       return;
+ err_phy:
+@@ -726,11 +842,15 @@ static int mtk_mdio_init(struct mtk_eth
+       }
+       divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
++      /* Configure MDC Turbo Mode */
++      if (mtk_is_netsys_v3_or_greater(eth))
++              mtk_m32(eth, 0, MISC_MDC_TURBO, MTK_MAC_MISC_V3);
++
+       /* Configure MDC Divider */
+-      val = mtk_r32(eth, MTK_PPSC);
+-      val &= ~PPSC_MDC_CFG;
+-      val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO;
+-      mtk_w32(eth, val, MTK_PPSC);
++      val = FIELD_PREP(PPSC_MDC_CFG, divider);
++      if (!mtk_is_netsys_v3_or_greater(eth))
++              val |= PPSC_MDC_TURBO;
++      mtk_m32(eth, PPSC_MDC_CFG, val, MTK_PPSC);
+       dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
+@@ -1191,10 +1311,19 @@ static void mtk_tx_set_dma_desc_v2(struc
+               data |= TX_DMA_LS0;
+       WRITE_ONCE(desc->txd3, data);
+-      if (mac->id == MTK_GMAC3_ID)
+-              data = PSE_GDM3_PORT;
+-      else
+-              data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
++       /* set forward port */
++      switch (mac->id) {
++      case MTK_GMAC1_ID:
++              data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2;
++              break;
++      case MTK_GMAC2_ID:
++              data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2;
++              break;
++      case MTK_GMAC3_ID:
++              data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2;
++              break;
++      }
++
+       data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
+       WRITE_ONCE(desc->txd4, data);
+@@ -4358,6 +4487,17 @@ static int mtk_add_mac(struct mtk_eth *e
+                         mac->phylink_config.supported_interfaces);
+       }
++      if (mtk_is_netsys_v3_or_greater(mac->hw) &&
++          MTK_HAS_CAPS(mac->hw->soc->caps, MTK_ESW_BIT) &&
++          id == MTK_GMAC1_ID) {
++              mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE |
++                                                     MAC_SYM_PAUSE |
++                                                     MAC_10000FD;
++              phy_interface_zero(mac->phylink_config.supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_INTERNAL,
++                        mac->phylink_config.supported_interfaces);
++      }
++
+       phylink = phylink_create(&mac->phylink_config,
+                                of_fwnode_handle(mac->of_node),
+                                phy_mode, &mtk_phylink_ops);
+@@ -4878,6 +5018,24 @@ static const struct mtk_soc_data mt7986_
+       },
+ };
++static const struct mtk_soc_data mt7988_data = {
++      .reg_map = &mt7988_reg_map,
++      .ana_rgc3 = 0x128,
++      .caps = MT7988_CAPS,
++      .hw_features = MTK_HW_FEATURES,
++      .required_clks = MT7988_CLKS_BITMAP,
++      .required_pctl = false,
++      .version = 3,
++      .txrx = {
++              .txd_size = sizeof(struct mtk_tx_dma_v2),
++              .rxd_size = sizeof(struct mtk_rx_dma_v2),
++              .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
++              .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
++              .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
++              .dma_len_offset = 8,
++      },
++};
++
+ static const struct mtk_soc_data rt5350_data = {
+       .reg_map = &mt7628_reg_map,
+       .caps = MT7628_CAPS,
+@@ -4896,14 +5054,15 @@ static const struct mtk_soc_data rt5350_
+ };
+ const struct of_device_id of_mtk_match[] = {
+-      { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
+-      { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
+-      { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
+-      { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
+-      { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
+-      { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
+-      { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
+-      { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
++      { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data },
++      { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data },
++      { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data },
++      { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data },
++      { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data },
++      { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data },
++      { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data },
++      { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data },
++      { .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, of_mtk_match);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -117,7 +117,8 @@
+ #define MTK_CDMP_EG_CTRL      0x404
+ /* GDM Exgress Control Register */
+-#define MTK_GDMA_FWD_CFG(x)   (0x500 + (x * 0x1000))
++#define MTK_GDMA_FWD_CFG(x)   ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ?   \
++                                 0x540 : 0x500 + (_x * 0x1000); })
+ #define MTK_GDMA_SPECIAL_TAG  BIT(24)
+ #define MTK_GDMA_ICS_EN               BIT(22)
+ #define MTK_GDMA_TCS_EN               BIT(21)
+@@ -126,6 +127,11 @@
+ #define MTK_GDMA_TO_PDMA      0x0
+ #define MTK_GDMA_DROP_ALL       0x7777
++/* GDM Egress Control Register */
++#define MTK_GDMA_EG_CTRL(x)   ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ?   \
++                                 0x544 : 0x504 + (_x * 0x1000); })
++#define MTK_GDMA_XGDM_SEL     BIT(31)
++
+ /* Unicast Filter MAC Address Register - Low */
+ #define MTK_GDMA_MAC_ADRL(x)  (0x508 + (x * 0x1000))
+@@ -389,7 +395,26 @@
+ #define PHY_IAC_TIMEOUT               HZ
+ #define MTK_MAC_MISC          0x1000c
++#define MTK_MAC_MISC_V3               0x10010
+ #define MTK_MUX_TO_ESW                BIT(0)
++#define MISC_MDC_TURBO                BIT(4)
++
++/* XMAC status registers */
++#define MTK_XGMAC_STS(x)      (((x) == MTK_GMAC3_ID) ? 0x1001C : 0x1000C)
++#define MTK_XGMAC_FORCE_LINK(x)       (((x) == MTK_GMAC2_ID) ? BIT(31) : BIT(15))
++#define MTK_USXGMII_PCS_LINK  BIT(8)
++#define MTK_XGMAC_RX_FC               BIT(5)
++#define MTK_XGMAC_TX_FC               BIT(4)
++#define MTK_USXGMII_PCS_MODE  GENMASK(3, 1)
++#define MTK_XGMAC_LINK_STS    BIT(0)
++
++/* GSW bridge registers */
++#define MTK_GSW_CFG           (0x10080)
++#define GSWTX_IPG_MASK                GENMASK(19, 16)
++#define GSWTX_IPG_SHIFT               16
++#define GSWRX_IPG_MASK                GENMASK(3, 0)
++#define GSWRX_IPG_SHIFT               0
++#define GSW_IPG_11            11
+ /* Mac control registers */
+ #define MTK_MAC_MCR(x)                (0x10100 + (x * 0x100))
+@@ -647,6 +672,11 @@ enum mtk_clks_map {
+       MTK_CLK_GP0,
+       MTK_CLK_GP1,
+       MTK_CLK_GP2,
++      MTK_CLK_GP3,
++      MTK_CLK_XGP1,
++      MTK_CLK_XGP2,
++      MTK_CLK_XGP3,
++      MTK_CLK_CRYPTO,
+       MTK_CLK_FE,
+       MTK_CLK_TRGPLL,
+       MTK_CLK_SGMII_TX_250M,
+@@ -663,6 +693,27 @@ enum mtk_clks_map {
+       MTK_CLK_WOCPU1,
+       MTK_CLK_NETSYS0,
+       MTK_CLK_NETSYS1,
++      MTK_CLK_ETHWARP_WOCPU2,
++      MTK_CLK_ETHWARP_WOCPU1,
++      MTK_CLK_ETHWARP_WOCPU0,
++      MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
++      MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
++      MTK_CLK_TOP_SGM_0_SEL,
++      MTK_CLK_TOP_SGM_1_SEL,
++      MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
++      MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
++      MTK_CLK_TOP_ETH_GMII_SEL,
++      MTK_CLK_TOP_ETH_REFCK_50M_SEL,
++      MTK_CLK_TOP_ETH_SYS_200M_SEL,
++      MTK_CLK_TOP_ETH_SYS_SEL,
++      MTK_CLK_TOP_ETH_XGMII_SEL,
++      MTK_CLK_TOP_ETH_MII_SEL,
++      MTK_CLK_TOP_NETSYS_SEL,
++      MTK_CLK_TOP_NETSYS_500M_SEL,
++      MTK_CLK_TOP_NETSYS_PAO_2X_SEL,
++      MTK_CLK_TOP_NETSYS_SYNC_250M_SEL,
++      MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL,
++      MTK_CLK_TOP_NETSYS_WARP_SEL,
+       MTK_CLK_MAX
+ };
+@@ -716,6 +767,36 @@ enum mtk_clks_map {
+                                BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
+                                BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
+                                BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
++#define MT7988_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \
++                               BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
++                               BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
++                               BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
++                               BIT_ULL(MTK_CLK_CRYPTO) | \
++                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
++                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
++                               BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
++                               BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
++                               BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
++                               BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \
++                               BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL))
+ enum mtk_dev_state {
+       MTK_HW_INIT,
+@@ -964,6 +1045,8 @@ enum mkt_eth_capabilities {
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_RSTCTRL_PPE1)
++#define MT7988_CAPS  (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1)
++
+ struct mtk_tx_dma_desc_info {
+       dma_addr_t      addr;
+       u32             size;
+@@ -1309,6 +1392,7 @@ void mtk_stats_update_mac(struct mtk_mac
+ void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
+ u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
++u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
+ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
+ int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
diff --git a/target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch b/target/linux/generic/backport-6.1/750-v6.5-12-net-ethernet-mtk_eth_soc-enable-page_pool-support-fo.patch
new file mode 100644 (file)
index 0000000..62c38c7
--- /dev/null
@@ -0,0 +1,27 @@
+From 38a7eb76220731eff40602cf433f24880be0a6c2 Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Thu, 27 Jul 2023 09:02:26 +0200
+Subject: [PATCH 106/250] net: ethernet: mtk_eth_soc: enable page_pool support
+ for MT7988 SoC
+
+In order to recycle pages, enable page_pool allocator for MT7988 SoC.
+
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/r/fd4e8693980e47385a543e7b002eec0b88bd09df.1690440675.git.lorenzo@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1659,7 +1659,7 @@ static void mtk_update_rx_cpu_idx(struct
+ static bool mtk_page_pool_enabled(struct mtk_eth *eth)
+ {
+-      return eth->soc->version == 2;
++      return mtk_is_netsys_v2_or_greater(eth);
+ }
+ static struct page_pool *mtk_create_page_pool(struct mtk_eth *eth,
diff --git a/target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch b/target/linux/generic/backport-6.1/750-v6.5-13-net-ethernet-mtk_eth_soc-enable-nft-hw-flowtable_off.patch
new file mode 100644 (file)
index 0000000..49f4bd6
--- /dev/null
@@ -0,0 +1,135 @@
+From 199e7d5a7f03dd377f3a7a458360dbedd71d50ba Mon Sep 17 00:00:00 2001
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+Date: Thu, 27 Jul 2023 09:07:28 +0200
+Subject: [PATCH 107/250] net: ethernet: mtk_eth_soc: enable nft hw
+ flowtable_offload for MT7988 SoC
+
+Enable hw Packet Process Engine (PPE) for MT7988 SoC.
+
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/r/5e86341b0220a49620dadc02d77970de5ded9efc.1690441576.git.lorenzo@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c |  3 +++
+ drivers/net/ethernet/mediatek/mtk_ppe.c     | 19 +++++++++++++++----
+ drivers/net/ethernet/mediatek/mtk_ppe.h     | 19 ++++++++++++++++++-
+ 3 files changed, 36 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -5026,6 +5026,9 @@ static const struct mtk_soc_data mt7988_
+       .required_clks = MT7988_CLKS_BITMAP,
+       .required_pctl = false,
+       .version = 3,
++      .offload_version = 2,
++      .hash_offset = 4,
++      .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma_v2),
+               .rxd_size = sizeof(struct mtk_rx_dma_v2),
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -422,13 +422,22 @@ int mtk_foe_entry_set_wdma(struct mtk_et
+       struct mtk_foe_mac_info *l2 = mtk_foe_entry_l2(eth, entry);
+       u32 *ib2 = mtk_foe_entry_ib2(eth, entry);
+-      if (mtk_is_netsys_v2_or_greater(eth)) {
++      switch (eth->soc->version) {
++      case 3:
++              *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
++              *ib2 |=  FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
++                       MTK_FOE_IB2_WDMA_WINFO_V2;
++              l2->w3info = FIELD_PREP(MTK_FOE_WINFO_WCID_V3, wcid) |
++                           FIELD_PREP(MTK_FOE_WINFO_BSS_V3, bss);
++              break;
++      case 2:
+               *ib2 &= ~MTK_FOE_IB2_PORT_MG_V2;
+               *ib2 |=  FIELD_PREP(MTK_FOE_IB2_RX_IDX, txq) |
+                        MTK_FOE_IB2_WDMA_WINFO_V2;
+               l2->winfo = FIELD_PREP(MTK_FOE_WINFO_WCID, wcid) |
+                           FIELD_PREP(MTK_FOE_WINFO_BSS, bss);
+-      } else {
++              break;
++      default:
+               *ib2 &= ~MTK_FOE_IB2_PORT_MG;
+               *ib2 |= MTK_FOE_IB2_WDMA_WINFO;
+               if (wdma_idx)
+@@ -436,6 +445,7 @@ int mtk_foe_entry_set_wdma(struct mtk_et
+               l2->vlan2 = FIELD_PREP(MTK_FOE_VLAN2_WINFO_BSS, bss) |
+                           FIELD_PREP(MTK_FOE_VLAN2_WINFO_WCID, wcid) |
+                           FIELD_PREP(MTK_FOE_VLAN2_WINFO_RING, txq);
++              break;
+       }
+       return 0;
+@@ -950,8 +960,7 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
+       mtk_ppe_init_foe_table(ppe);
+       ppe_w32(ppe, MTK_PPE_TB_BASE, ppe->foe_phys);
+-      val = MTK_PPE_TB_CFG_ENTRY_80B |
+-            MTK_PPE_TB_CFG_AGE_NON_L4 |
++      val = MTK_PPE_TB_CFG_AGE_NON_L4 |
+             MTK_PPE_TB_CFG_AGE_UNBIND |
+             MTK_PPE_TB_CFG_AGE_TCP |
+             MTK_PPE_TB_CFG_AGE_UDP |
+@@ -967,6 +976,8 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
+                        MTK_PPE_ENTRIES_SHIFT);
+       if (mtk_is_netsys_v2_or_greater(ppe->eth))
+               val |= MTK_PPE_TB_CFG_INFO_SEL;
++      if (!mtk_is_netsys_v3_or_greater(ppe->eth))
++              val |= MTK_PPE_TB_CFG_ENTRY_80B;
+       ppe_w32(ppe, MTK_PPE_TB_CFG, val);
+       ppe_w32(ppe, MTK_PPE_IP_PROTO_CHK,
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
+@@ -85,6 +85,17 @@ enum {
+ #define MTK_FOE_WINFO_BSS             GENMASK(5, 0)
+ #define MTK_FOE_WINFO_WCID            GENMASK(15, 6)
++#define MTK_FOE_WINFO_BSS_V3          GENMASK(23, 16)
++#define MTK_FOE_WINFO_WCID_V3         GENMASK(15, 0)
++
++#define MTK_FOE_WINFO_PAO_USR_INFO    GENMASK(15, 0)
++#define MTK_FOE_WINFO_PAO_TID         GENMASK(19, 16)
++#define MTK_FOE_WINFO_PAO_IS_FIXEDRATE        BIT(20)
++#define MTK_FOE_WINFO_PAO_IS_PRIOR    BIT(21)
++#define MTK_FOE_WINFO_PAO_IS_SP               BIT(22)
++#define MTK_FOE_WINFO_PAO_HF          BIT(23)
++#define MTK_FOE_WINFO_PAO_AMSDU_EN    BIT(24)
++
+ enum {
+       MTK_FOE_STATE_INVALID,
+       MTK_FOE_STATE_UNBIND,
+@@ -106,8 +117,13 @@ struct mtk_foe_mac_info {
+       u16 pppoe_id;
+       u16 src_mac_lo;
++      /* netsys_v2 */
+       u16 minfo;
+       u16 winfo;
++
++      /* netsys_v3 */
++      u32 w3info;
++      u32 wpao;
+ };
+ /* software-only entry type */
+@@ -218,6 +234,7 @@ struct mtk_foe_ipv6_6rd {
+ #define MTK_FOE_ENTRY_V1_SIZE 80
+ #define MTK_FOE_ENTRY_V2_SIZE 96
++#define MTK_FOE_ENTRY_V3_SIZE 128
+ struct mtk_foe_entry {
+       u32 ib1;
+@@ -228,7 +245,7 @@ struct mtk_foe_entry {
+               struct mtk_foe_ipv4_dslite dslite;
+               struct mtk_foe_ipv6 ipv6;
+               struct mtk_foe_ipv6_6rd ipv6_6rd;
+-              u32 data[23];
++              u32 data[31];
+       };
+ };
diff --git a/target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch b/target/linux/generic/backport-6.1/750-v6.5-14-net-ethernet-mtk_eth_soc-support-per-flow-accounting.patch
new file mode 100644 (file)
index 0000000..88987d7
--- /dev/null
@@ -0,0 +1,78 @@
+From 0c024632c1e7ff69914329bfd87bec749b9c0aed Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 2 Aug 2023 04:31:09 +0100
+Subject: [PATCH 108/250] net: ethernet: mtk_eth_soc: support per-flow
+ accounting on MT7988
+
+NETSYS_V3 uses 64 bits for each counters while older SoCs are using
+48/40 bits for each counter.
+Support reading per-flow byte and package counters on NETSYS_V3.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/37a0928fa8c1253b197884c68ce1f54239421ac5.1690946442.git.daniel@makrotopia.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c  |  1 +
+ drivers/net/ethernet/mediatek/mtk_ppe.c      | 21 +++++++++++++-------
+ drivers/net/ethernet/mediatek/mtk_ppe_regs.h |  2 ++
+ 3 files changed, 17 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -5028,6 +5028,7 @@ static const struct mtk_soc_data mt7988_
+       .version = 3,
+       .offload_version = 2,
+       .hash_offset = 4,
++      .has_accounting = true,
+       .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
+       .txrx = {
+               .txd_size = sizeof(struct mtk_tx_dma_v2),
+--- a/drivers/net/ethernet/mediatek/mtk_ppe.c
++++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
+@@ -91,7 +91,6 @@ static int mtk_ppe_mib_wait_busy(struct
+ static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
+ {
+-      u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
+       u32 val, cnt_r0, cnt_r1, cnt_r2;
+       int ret;
+@@ -106,12 +105,20 @@ static int mtk_mib_entry_read(struct mtk
+       cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
+       cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
+-      byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
+-      byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
+-      pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
+-      pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
+-      *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
+-      *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
++      if (mtk_is_netsys_v3_or_greater(ppe->eth)) {
++              /* 64 bit for each counter */
++              u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3);
++              *bytes = ((u64)cnt_r1 << 32) | cnt_r0;
++              *packets = ((u64)cnt_r3 << 32) | cnt_r2;
++      } else {
++              /* 48 bit byte counter, 40 bit packet counter */
++              u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
++              u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
++              u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
++              u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
++              *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
++              *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
++      }
+       return 0;
+ }
+--- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
++++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
+@@ -163,6 +163,8 @@ enum {
+ #define MTK_PPE_MIB_SER_R2                    0x348
+ #define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH               GENMASK(23, 0)
++#define MTK_PPE_MIB_SER_R3                    0x34c
++
+ #define MTK_PPE_MIB_CACHE_CTL                 0x350
+ #define MTK_PPE_MIB_CACHE_CTL_EN              BIT(0)
+ #define MTK_PPE_MIB_CACHE_CTL_FLUSH           BIT(2)
diff --git a/target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch b/target/linux/generic/backport-6.1/750-v6.5-15-net-ethernet-mtk_eth_soc-fix-NULL-pointer-on-hw-rese.patch
new file mode 100644 (file)
index 0000000..6f1639a
--- /dev/null
@@ -0,0 +1,52 @@
+From 3b12f42772c26869d60398c1710aa27b27cd945c Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 21 Aug 2023 17:12:44 +0100
+Subject: [PATCH 109/250] net: ethernet: mtk_eth_soc: fix NULL pointer on hw
+ reset
+
+When a hardware reset is triggered on devices not initializing WED the
+calls to mtk_wed_fe_reset and mtk_wed_fe_reset_complete dereference a
+pointer on uninitialized stack memory.
+Break out of both functions in case a hw_list entry is 0.
+
+Fixes: 08a764a7c51b ("net: ethernet: mtk_wed: add reset/reset_complete callbacks")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Link: https://lore.kernel.org/r/5465c1609b464cc7407ae1530c40821dcdf9d3e6.1692634266.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_wed.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_wed.c
++++ b/drivers/net/ethernet/mediatek/mtk_wed.c
+@@ -214,9 +214,13 @@ void mtk_wed_fe_reset(void)
+       for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
+               struct mtk_wed_hw *hw = hw_list[i];
+-              struct mtk_wed_device *dev = hw->wed_dev;
++              struct mtk_wed_device *dev;
+               int err;
++              if (!hw)
++                      break;
++
++              dev = hw->wed_dev;
+               if (!dev || !dev->wlan.reset)
+                       continue;
+@@ -237,8 +241,12 @@ void mtk_wed_fe_reset_complete(void)
+       for (i = 0; i < ARRAY_SIZE(hw_list); i++) {
+               struct mtk_wed_hw *hw = hw_list[i];
+-              struct mtk_wed_device *dev = hw->wed_dev;
++              struct mtk_wed_device *dev;
++
++              if (!hw)
++                      break;
++              dev = hw->wed_dev;
+               if (!dev || !dev->wlan.reset_complete)
+                       continue;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch b/target/linux/generic/backport-6.1/750-v6.5-16-net-ethernet-mtk_eth_soc-fix-register-definitions-fo.patch
new file mode 100644 (file)
index 0000000..2190761
--- /dev/null
@@ -0,0 +1,44 @@
+From 489aea123d74a846ce746bfdb3efe1e7ad512e0d Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 22 Aug 2023 17:31:24 +0100
+Subject: [PATCH 110/250] net: ethernet: mtk_eth_soc: fix register definitions
+ for MT7988
+
+More register macros need to be adjusted for the 3rd GMAC on MT7988.
+Account for added bit in SYSCFG0_SGMII_MASK.
+
+Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/1c8da012e2ca80939906d85f314138c552139f0f.1692721443.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -133,10 +133,12 @@
+ #define MTK_GDMA_XGDM_SEL     BIT(31)
+ /* Unicast Filter MAC Address Register - Low */
+-#define MTK_GDMA_MAC_ADRL(x)  (0x508 + (x * 0x1000))
++#define MTK_GDMA_MAC_ADRL(x)  ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ?   \
++                                 0x548 : 0x508 + (_x * 0x1000); })
+ /* Unicast Filter MAC Address Register - High */
+-#define MTK_GDMA_MAC_ADRH(x)  (0x50C + (x * 0x1000))
++#define MTK_GDMA_MAC_ADRH(x)  ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ?   \
++                                 0x54C : 0x50C + (_x * 0x1000); })
+ /* FE global misc reg*/
+ #define MTK_FE_GLO_MISC         0x124
+@@ -503,7 +505,7 @@
+ #define ETHSYS_SYSCFG0                0x14
+ #define SYSCFG0_GE_MASK               0x3
+ #define SYSCFG0_GE_MODE(x, y) (x << (12 + (y * 2)))
+-#define SYSCFG0_SGMII_MASK     GENMASK(9, 8)
++#define SYSCFG0_SGMII_MASK     GENMASK(9, 7)
+ #define SYSCFG0_SGMII_GMAC1    ((2 << 8) & SYSCFG0_SGMII_MASK)
+ #define SYSCFG0_SGMII_GMAC2    ((3 << 8) & SYSCFG0_SGMII_MASK)
+ #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
diff --git a/target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch b/target/linux/generic/backport-6.1/750-v6.5-17-net-ethernet-mtk_eth_soc-add-reset-bits-for-MT7988.patch
new file mode 100644 (file)
index 0000000..b94ca7e
--- /dev/null
@@ -0,0 +1,188 @@
+From 15a84d1c44ae8c1451c265ee60500588a24e8cd6 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 22 Aug 2023 17:32:03 +0100
+Subject: [PATCH 111/250] net: ethernet: mtk_eth_soc: add reset bits for MT7988
+
+Add bits needed to reset the frame engine on MT7988.
+
+Fixes: 445eb6448ed3 ("net: ethernet: mtk_eth_soc: add basic support for MT7988 SoC")
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/89b6c38380e7a3800c1362aa7575600717bc7543.1692721443.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 76 +++++++++++++++------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++--
+ 2 files changed, 68 insertions(+), 24 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3592,19 +3592,34 @@ static void mtk_hw_reset(struct mtk_eth
+ {
+       u32 val;
+-      if (mtk_is_netsys_v2_or_greater(eth)) {
++      if (mtk_is_netsys_v2_or_greater(eth))
+               regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
++
++      if (mtk_is_netsys_v3_or_greater(eth)) {
++              val = RSTCTRL_PPE0_V3;
++
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++                      val |= RSTCTRL_PPE1_V3;
++
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
++                      val |= RSTCTRL_PPE2;
++
++              val |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2;
++      } else if (mtk_is_netsys_v2_or_greater(eth)) {
+               val = RSTCTRL_PPE0_V2;
++
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++                      val |= RSTCTRL_PPE1;
+       } else {
+               val = RSTCTRL_PPE0;
+       }
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+-              val |= RSTCTRL_PPE1;
+-
+       ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
+-      if (mtk_is_netsys_v2_or_greater(eth))
++      if (mtk_is_netsys_v3_or_greater(eth))
++              regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
++                           0x6f8ff);
++      else if (mtk_is_netsys_v2_or_greater(eth))
+               regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
+                            0x3ffffff);
+ }
+@@ -3630,13 +3645,21 @@ static void mtk_hw_warm_reset(struct mtk
+               return;
+       }
+-      if (mtk_is_netsys_v2_or_greater(eth))
++      if (mtk_is_netsys_v3_or_greater(eth)) {
++              rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V3;
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++                      rst_mask |= RSTCTRL_PPE1_V3;
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
++                      rst_mask |= RSTCTRL_PPE2;
++
++              rst_mask |= RSTCTRL_WDMA0 | RSTCTRL_WDMA1 | RSTCTRL_WDMA2;
++      } else if (mtk_is_netsys_v2_or_greater(eth)) {
+               rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0_V2;
+-      else
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++                      rst_mask |= RSTCTRL_PPE1;
++      } else {
+               rst_mask = RSTCTRL_ETH | RSTCTRL_PPE0;
+-
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+-              rst_mask |= RSTCTRL_PPE1;
++      }
+       regmap_update_bits(eth->ethsys, ETHSYS_RSTCTRL, rst_mask, rst_mask);
+@@ -3988,11 +4011,17 @@ static void mtk_prepare_for_reset(struct
+       u32 val;
+       int i;
+-      /* disabe FE P3 and P4 */
+-      val = mtk_r32(eth, MTK_FE_GLO_CFG) | MTK_FE_LINK_DOWN_P3;
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+-              val |= MTK_FE_LINK_DOWN_P4;
+-      mtk_w32(eth, val, MTK_FE_GLO_CFG);
++      /* set FE PPE ports link down */
++      for (i = MTK_GMAC1_ID;
++           i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID);
++           i += 2) {
++              val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) | MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++                      val |= MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
++                      val |= MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT);
++              mtk_w32(eth, val, MTK_FE_GLO_CFG(i));
++      }
+       /* adjust PPE configurations to prepare for reset */
+       for (i = 0; i < ARRAY_SIZE(eth->ppe); i++)
+@@ -4053,11 +4082,18 @@ static void mtk_pending_work(struct work
+               }
+       }
+-      /* enabe FE P3 and P4 */
+-      val = mtk_r32(eth, MTK_FE_GLO_CFG) & ~MTK_FE_LINK_DOWN_P3;
+-      if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
+-              val &= ~MTK_FE_LINK_DOWN_P4;
+-      mtk_w32(eth, val, MTK_FE_GLO_CFG);
++      /* set FE PPE ports link up */
++      for (i = MTK_GMAC1_ID;
++           i <= (mtk_is_netsys_v3_or_greater(eth) ? MTK_GMAC3_ID : MTK_GMAC2_ID);
++           i += 2) {
++              val = mtk_r32(eth, MTK_FE_GLO_CFG(i)) & ~MTK_FE_LINK_DOWN_P(PSE_PPE0_PORT);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE1))
++                      val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE1_PORT);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_RSTCTRL_PPE2))
++                      val &= ~MTK_FE_LINK_DOWN_P(PSE_PPE2_PORT);
++
++              mtk_w32(eth, val, MTK_FE_GLO_CFG(i));
++      }
+       clear_bit(MTK_RESETTING, &eth->state);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -76,9 +76,8 @@
+ #define       MTK_HW_LRO_SDL_REMAIN_ROOM      1522
+ /* Frame Engine Global Configuration */
+-#define MTK_FE_GLO_CFG                0x00
+-#define MTK_FE_LINK_DOWN_P3   BIT(11)
+-#define MTK_FE_LINK_DOWN_P4   BIT(12)
++#define MTK_FE_GLO_CFG(x)     (((x) == MTK_GMAC3_ID) ? 0x24 : 0x00)
++#define MTK_FE_LINK_DOWN_P(x) BIT(((x) + 8) % 16)
+ /* Frame Engine Global Reset Register */
+ #define MTK_RST_GL            0x04
+@@ -522,9 +521,15 @@
+ /* ethernet reset control register */
+ #define ETHSYS_RSTCTRL                        0x34
+ #define RSTCTRL_FE                    BIT(6)
++#define RSTCTRL_WDMA0                 BIT(24)
++#define RSTCTRL_WDMA1                 BIT(25)
++#define RSTCTRL_WDMA2                 BIT(26)
+ #define RSTCTRL_PPE0                  BIT(31)
+ #define RSTCTRL_PPE0_V2                       BIT(30)
+ #define RSTCTRL_PPE1                  BIT(31)
++#define RSTCTRL_PPE0_V3                       BIT(29)
++#define RSTCTRL_PPE1_V3                       BIT(30)
++#define RSTCTRL_PPE2                  BIT(31)
+ #define RSTCTRL_ETH                   BIT(23)
+ /* ethernet reset check idle register */
+@@ -931,6 +936,7 @@ enum mkt_eth_capabilities {
+       MTK_QDMA_BIT,
+       MTK_SOC_MT7628_BIT,
+       MTK_RSTCTRL_PPE1_BIT,
++      MTK_RSTCTRL_PPE2_BIT,
+       MTK_U3_COPHY_V2_BIT,
+       /* MUX BITS*/
+@@ -965,6 +971,7 @@ enum mkt_eth_capabilities {
+ #define MTK_QDMA              BIT_ULL(MTK_QDMA_BIT)
+ #define MTK_SOC_MT7628                BIT_ULL(MTK_SOC_MT7628_BIT)
+ #define MTK_RSTCTRL_PPE1      BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
++#define MTK_RSTCTRL_PPE2      BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
+ #define MTK_U3_COPHY_V2               BIT_ULL(MTK_U3_COPHY_V2_BIT)
+ #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
+@@ -1047,7 +1054,8 @@ enum mkt_eth_capabilities {
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_RSTCTRL_PPE1)
+-#define MT7988_CAPS  (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1)
++#define MT7988_CAPS  (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
++                    MTK_RSTCTRL_PPE2)
+ struct mtk_tx_dma_desc_info {
+       dma_addr_t      addr;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch b/target/linux/generic/backport-6.1/750-v6.5-18-net-ethernet-mtk_eth_soc-add-support-for-in-SoC-SRAM.patch
new file mode 100644 (file)
index 0000000..43fbffc
--- /dev/null
@@ -0,0 +1,254 @@
+From 25ce45fe40b574e5d7ffa407f7f2db03e7d5a910 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 22 Aug 2023 17:32:54 +0100
+Subject: [PATCH 112/250] net: ethernet: mtk_eth_soc: add support for in-SoC
+ SRAM
+
+MT7981, MT7986 and MT7988 come with in-SoC SRAM dedicated for Ethernet
+DMA rings. Support using the SRAM without breaking existing device tree
+bindings, ie. only new SoC starting from MT7988 will have the SRAM
+declared as additional resource in device tree. For MT7981 and MT7986
+an offset on top of the main I/O base is used.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/e45e0f230c63ad58869e8fe35b95a2fb8925b625.1692721443.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 88 ++++++++++++++++-----
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 12 ++-
+ 2 files changed, 78 insertions(+), 22 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1119,10 +1119,13 @@ static int mtk_init_fq_dma(struct mtk_et
+       dma_addr_t dma_addr;
+       int i;
+-      eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
+-                                             cnt * soc->txrx.txd_size,
+-                                             &eth->phy_scratch_ring,
+-                                             GFP_KERNEL);
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM))
++              eth->scratch_ring = eth->sram_base;
++      else
++              eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
++                                                     cnt * soc->txrx.txd_size,
++                                                     &eth->phy_scratch_ring,
++                                                     GFP_KERNEL);
+       if (unlikely(!eth->scratch_ring))
+               return -ENOMEM;
+@@ -2430,8 +2433,14 @@ static int mtk_tx_alloc(struct mtk_eth *
+       if (!ring->buf)
+               goto no_tx_mem;
+-      ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
+-                                     &ring->phys, GFP_KERNEL);
++      if (MTK_HAS_CAPS(soc->caps, MTK_SRAM)) {
++              ring->dma = eth->sram_base + ring_size * sz;
++              ring->phys = eth->phy_scratch_ring + ring_size * (dma_addr_t)sz;
++      } else {
++              ring->dma = dma_alloc_coherent(eth->dma_dev, ring_size * sz,
++                                             &ring->phys, GFP_KERNEL);
++      }
++
+       if (!ring->dma)
+               goto no_tx_mem;
+@@ -2530,8 +2539,7 @@ static void mtk_tx_clean(struct mtk_eth
+               kfree(ring->buf);
+               ring->buf = NULL;
+       }
+-
+-      if (ring->dma) {
++      if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) {
+               dma_free_coherent(eth->dma_dev,
+                                 ring->dma_size * soc->txrx.txd_size,
+                                 ring->dma, ring->phys);
+@@ -2550,9 +2558,14 @@ static int mtk_rx_alloc(struct mtk_eth *
+ {
+       const struct mtk_reg_map *reg_map = eth->soc->reg_map;
+       struct mtk_rx_ring *ring;
+-      int rx_data_len, rx_dma_size;
++      int rx_data_len, rx_dma_size, tx_ring_size;
+       int i;
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_QDMA))
++              tx_ring_size = MTK_QDMA_RING_SIZE;
++      else
++              tx_ring_size = MTK_DMA_SIZE;
++
+       if (rx_flag == MTK_RX_FLAGS_QDMA) {
+               if (ring_no)
+                       return -EINVAL;
+@@ -2587,9 +2600,20 @@ static int mtk_rx_alloc(struct mtk_eth *
+               ring->page_pool = pp;
+       }
+-      ring->dma = dma_alloc_coherent(eth->dma_dev,
+-                                     rx_dma_size * eth->soc->txrx.rxd_size,
+-                                     &ring->phys, GFP_KERNEL);
++      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) ||
++          rx_flag != MTK_RX_FLAGS_NORMAL) {
++              ring->dma = dma_alloc_coherent(eth->dma_dev,
++                                             rx_dma_size * eth->soc->txrx.rxd_size,
++                                             &ring->phys, GFP_KERNEL);
++      } else {
++              struct mtk_tx_ring *tx_ring = &eth->tx_ring;
++
++              ring->dma = tx_ring->dma + tx_ring_size *
++                          eth->soc->txrx.txd_size * (ring_no + 1);
++              ring->phys = tx_ring->phys + tx_ring_size *
++                           eth->soc->txrx.txd_size * (ring_no + 1);
++      }
++
+       if (!ring->dma)
+               return -ENOMEM;
+@@ -2674,7 +2698,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+       return 0;
+ }
+-static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring)
++static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram)
+ {
+       int i;
+@@ -2697,7 +2721,7 @@ static void mtk_rx_clean(struct mtk_eth
+               ring->data = NULL;
+       }
+-      if (ring->dma) {
++      if (!in_sram && ring->dma) {
+               dma_free_coherent(eth->dma_dev,
+                                 ring->dma_size * eth->soc->txrx.rxd_size,
+                                 ring->dma, ring->phys);
+@@ -3057,7 +3081,7 @@ static void mtk_dma_free(struct mtk_eth
+       for (i = 0; i < MTK_MAX_DEVS; i++)
+               if (eth->netdev[i])
+                       netdev_reset_queue(eth->netdev[i]);
+-      if (eth->scratch_ring) {
++      if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
+               dma_free_coherent(eth->dma_dev,
+                                 MTK_QDMA_RING_SIZE * soc->txrx.txd_size,
+                                 eth->scratch_ring, eth->phy_scratch_ring);
+@@ -3065,13 +3089,13 @@ static void mtk_dma_free(struct mtk_eth
+               eth->phy_scratch_ring = 0;
+       }
+       mtk_tx_clean(eth);
+-      mtk_rx_clean(eth, &eth->rx_ring[0]);
+-      mtk_rx_clean(eth, &eth->rx_ring_qdma);
++      mtk_rx_clean(eth, &eth->rx_ring[0], MTK_HAS_CAPS(soc->caps, MTK_SRAM));
++      mtk_rx_clean(eth, &eth->rx_ring_qdma, false);
+       if (eth->hwlro) {
+               mtk_hwlro_rx_uninit(eth);
+               for (i = 1; i < MTK_MAX_RX_RING_NUM; i++)
+-                      mtk_rx_clean(eth, &eth->rx_ring[i]);
++                      mtk_rx_clean(eth, &eth->rx_ring[i], false);
+       }
+       kfree(eth->scratch_head);
+@@ -4639,7 +4663,7 @@ static int mtk_sgmii_init(struct mtk_eth
+ static int mtk_probe(struct platform_device *pdev)
+ {
+-      struct resource *res = NULL;
++      struct resource *res = NULL, *res_sram;
+       struct device_node *mac_np;
+       struct mtk_eth *eth;
+       int err, i;
+@@ -4659,6 +4683,20 @@ static int mtk_probe(struct platform_dev
+       if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
+               eth->ip_align = NET_IP_ALIGN;
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) {
++              /* SRAM is actual memory and supports transparent access just like DRAM.
++               * Hence we don't require __iomem being set and don't need to use accessor
++               * functions to read from or write to SRAM.
++               */
++              if (mtk_is_netsys_v3_or_greater(eth)) {
++                      eth->sram_base = (void __force *)devm_platform_ioremap_resource(pdev, 1);
++                      if (IS_ERR(eth->sram_base))
++                              return PTR_ERR(eth->sram_base);
++              } else {
++                      eth->sram_base = (void __force *)eth->base + MTK_ETH_SRAM_OFFSET;
++              }
++      }
++
+       spin_lock_init(&eth->page_lock);
+       spin_lock_init(&eth->tx_irq_lock);
+       spin_lock_init(&eth->rx_irq_lock);
+@@ -4722,6 +4760,18 @@ static int mtk_probe(struct platform_dev
+                       err = -EINVAL;
+                       goto err_destroy_sgmii;
+               }
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM)) {
++                      if (mtk_is_netsys_v3_or_greater(eth)) {
++                              res_sram = platform_get_resource(pdev, IORESOURCE_MEM, 1);
++                              if (!res_sram) {
++                                      err = -EINVAL;
++                                      goto err_destroy_sgmii;
++                              }
++                              eth->phy_scratch_ring = res_sram->start;
++                      } else {
++                              eth->phy_scratch_ring = res->start + MTK_ETH_SRAM_OFFSET;
++                      }
++              }
+       }
+       if (eth->soc->offload_version) {
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -139,6 +139,9 @@
+ #define MTK_GDMA_MAC_ADRH(x)  ({ typeof(x) _x = (x); (_x == MTK_GMAC3_ID) ?   \
+                                  0x54C : 0x50C + (_x * 0x1000); })
++/* Internal SRAM offset */
++#define MTK_ETH_SRAM_OFFSET   0x40000
++
+ /* FE global misc reg*/
+ #define MTK_FE_GLO_MISC         0x124
+@@ -938,6 +941,7 @@ enum mkt_eth_capabilities {
+       MTK_RSTCTRL_PPE1_BIT,
+       MTK_RSTCTRL_PPE2_BIT,
+       MTK_U3_COPHY_V2_BIT,
++      MTK_SRAM_BIT,
+       /* MUX BITS*/
+       MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
+@@ -973,6 +977,7 @@ enum mkt_eth_capabilities {
+ #define MTK_RSTCTRL_PPE1      BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
+ #define MTK_RSTCTRL_PPE2      BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
+ #define MTK_U3_COPHY_V2               BIT_ULL(MTK_U3_COPHY_V2_BIT)
++#define MTK_SRAM              BIT_ULL(MTK_SRAM_BIT)
+ #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
+       BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
+@@ -1048,14 +1053,14 @@ enum mkt_eth_capabilities {
+ #define MT7981_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
+-                    MTK_RSTCTRL_PPE1)
++                    MTK_RSTCTRL_PPE1 | MTK_SRAM)
+ #define MT7986_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+-                    MTK_RSTCTRL_PPE1)
++                    MTK_RSTCTRL_PPE1 | MTK_SRAM)
+ #define MT7988_CAPS  (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
+-                    MTK_RSTCTRL_PPE2)
++                    MTK_RSTCTRL_PPE2 | MTK_SRAM)
+ struct mtk_tx_dma_desc_info {
+       dma_addr_t      addr;
+@@ -1215,6 +1220,7 @@ struct mtk_eth {
+       struct device                   *dev;
+       struct device                   *dma_dev;
+       void __iomem                    *base;
++      void                            *sram_base;
+       spinlock_t                      page_lock;
+       spinlock_t                      tx_irq_lock;
+       spinlock_t                      rx_irq_lock;
diff --git a/target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch b/target/linux/generic/backport-6.1/750-v6.5-19-net-ethernet-mtk_eth_soc-support-36-bit-DMA-addressi.patch
new file mode 100644 (file)
index 0000000..3933997
--- /dev/null
@@ -0,0 +1,166 @@
+From 0b0d606eb9650fa01dd5621e072aa29a10544399 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 22 Aug 2023 17:33:12 +0100
+Subject: [PATCH 113/250] net: ethernet: mtk_eth_soc: support 36-bit DMA
+ addressing on MT7988
+
+Systems having 4 GiB of RAM and more require DMA addressing beyond the
+current 32-bit limit. Starting from MT7988 the hardware now supports
+36-bit DMA addressing, let's use that new capability in the driver to
+avoid running into swiotlb on systems with 4 GiB of RAM or more.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/95b919c98876c9e49761e44662e7c937479eecb8.1692721443.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++++++++++++++--
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 22 +++++++++++++--
+ 2 files changed, 48 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -1312,6 +1312,10 @@ static void mtk_tx_set_dma_desc_v2(struc
+       data = TX_DMA_PLEN0(info->size);
+       if (info->last)
+               data |= TX_DMA_LS0;
++
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
++              data |= TX_DMA_PREP_ADDR64(info->addr);
++
+       WRITE_ONCE(desc->txd3, data);
+        /* set forward port */
+@@ -1981,6 +1985,7 @@ static int mtk_poll_rx(struct napi_struc
+       bool xdp_flush = false;
+       int idx;
+       struct sk_buff *skb;
++      u64 addr64 = 0;
+       u8 *data, *new_data;
+       struct mtk_rx_dma_v2 *rxd, trxd;
+       int done = 0, bytes = 0;
+@@ -2096,7 +2101,10 @@ static int mtk_poll_rx(struct napi_struc
+                               goto release_desc;
+                       }
+-                      dma_unmap_single(eth->dma_dev, trxd.rxd1,
++                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
++                              addr64 = RX_DMA_GET_ADDR64(trxd.rxd2);
++
++                      dma_unmap_single(eth->dma_dev, ((u64)trxd.rxd1 | addr64),
+                                        ring->buf_size, DMA_FROM_DEVICE);
+                       skb = build_skb(data, ring->frag_size);
+@@ -2162,6 +2170,9 @@ release_desc:
+               else
+                       rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
++                      rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
++
+               ring->calc_idx = idx;
+               done++;
+       }
+@@ -2654,6 +2665,9 @@ static int mtk_rx_alloc(struct mtk_eth *
+               else
+                       rxd->rxd2 = RX_DMA_PREP_PLEN0(ring->buf_size);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
++                      rxd->rxd2 |= RX_DMA_PREP_ADDR64(dma_addr);
++
+               rxd->rxd3 = 0;
+               rxd->rxd4 = 0;
+               if (mtk_is_netsys_v2_or_greater(eth)) {
+@@ -2700,6 +2714,7 @@ static int mtk_rx_alloc(struct mtk_eth *
+ static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_sram)
+ {
++      u64 addr64 = 0;
+       int i;
+       if (ring->data && ring->dma) {
+@@ -2713,7 +2728,10 @@ static void mtk_rx_clean(struct mtk_eth
+                       if (!rxd->rxd1)
+                               continue;
+-                      dma_unmap_single(eth->dma_dev, rxd->rxd1,
++                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA))
++                              addr64 = RX_DMA_GET_ADDR64(rxd->rxd2);
++
++                      dma_unmap_single(eth->dma_dev, ((u64)rxd->rxd1 | addr64),
+                                        ring->buf_size, DMA_FROM_DEVICE);
+                       mtk_rx_put_buff(ring, ring->data[i], false);
+               }
+@@ -4697,6 +4715,14 @@ static int mtk_probe(struct platform_dev
+               }
+       }
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_36BIT_DMA)) {
++              err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
++              if (err) {
++                      dev_err(&pdev->dev, "Wrong DMA config\n");
++                      return -EINVAL;
++              }
++      }
++
+       spin_lock_init(&eth->page_lock);
+       spin_lock_init(&eth->tx_irq_lock);
+       spin_lock_init(&eth->rx_irq_lock);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -331,6 +331,14 @@
+ #define TX_DMA_PLEN1(x)               ((x) & eth->soc->txrx.dma_max_len)
+ #define TX_DMA_SWC            BIT(14)
+ #define TX_DMA_PQID           GENMASK(3, 0)
++#define TX_DMA_ADDR64_MASK    GENMASK(3, 0)
++#if IS_ENABLED(CONFIG_64BIT)
++# define TX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(TX_DMA_ADDR64_MASK, (x))) << 32)
++# define TX_DMA_PREP_ADDR64(x)        FIELD_PREP(TX_DMA_ADDR64_MASK, ((x) >> 32))
++#else
++# define TX_DMA_GET_ADDR64(x) (0)
++# define TX_DMA_PREP_ADDR64(x)        (0)
++#endif
+ /* PDMA on MT7628 */
+ #define TX_DMA_DONE           BIT(31)
+@@ -343,6 +351,14 @@
+ #define RX_DMA_PREP_PLEN0(x)  (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset)
+ #define RX_DMA_GET_PLEN0(x)   (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len)
+ #define RX_DMA_VTAG           BIT(15)
++#define RX_DMA_ADDR64_MASK    GENMASK(3, 0)
++#if IS_ENABLED(CONFIG_64BIT)
++# define RX_DMA_GET_ADDR64(x) (((u64)FIELD_GET(RX_DMA_ADDR64_MASK, (x))) << 32)
++# define RX_DMA_PREP_ADDR64(x)        FIELD_PREP(RX_DMA_ADDR64_MASK, ((x) >> 32))
++#else
++# define RX_DMA_GET_ADDR64(x) (0)
++# define RX_DMA_PREP_ADDR64(x)        (0)
++#endif
+ /* QDMA descriptor rxd3 */
+ #define RX_DMA_VID(x)         ((x) & VLAN_VID_MASK)
+@@ -942,6 +958,7 @@ enum mkt_eth_capabilities {
+       MTK_RSTCTRL_PPE2_BIT,
+       MTK_U3_COPHY_V2_BIT,
+       MTK_SRAM_BIT,
++      MTK_36BIT_DMA_BIT,
+       /* MUX BITS*/
+       MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
+@@ -978,6 +995,7 @@ enum mkt_eth_capabilities {
+ #define MTK_RSTCTRL_PPE2      BIT_ULL(MTK_RSTCTRL_PPE2_BIT)
+ #define MTK_U3_COPHY_V2               BIT_ULL(MTK_U3_COPHY_V2_BIT)
+ #define MTK_SRAM              BIT_ULL(MTK_SRAM_BIT)
++#define MTK_36BIT_DMA BIT_ULL(MTK_36BIT_DMA_BIT)
+ #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
+       BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
+@@ -1059,8 +1077,8 @@ enum mkt_eth_capabilities {
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_RSTCTRL_PPE1 | MTK_SRAM)
+-#define MT7988_CAPS  (MTK_GDM1_ESW | MTK_QDMA | MTK_RSTCTRL_PPE1 | \
+-                    MTK_RSTCTRL_PPE2 | MTK_SRAM)
++#define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \
++                    MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
+ struct mtk_tx_dma_desc_info {
+       dma_addr_t      addr;
index 4dac4464feec4f18ecf2e64c8bcbf7d389e1c400..abe6bbb04c48a982a4c62a5f94a1aa4880cbed12 100644 (file)
@@ -21,9 +21,9 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  drivers/net/dsa/Kconfig       |  12 +++
  drivers/net/dsa/Makefile      |   1 +
  drivers/net/dsa/mt7530-mmio.c | 101 +++++++++++++++++++++++++
- drivers/net/dsa/mt7530.c      | 137 +++++++++++++++++++++++++++++++++-
+ drivers/net/dsa/mt7530.c      | 135 +++++++++++++++++++++++++++++++++-
  drivers/net/dsa/mt7530.h      |  12 +--
- 6 files changed, 255 insertions(+), 10 deletions(-)
+ 6 files changed, 253 insertions(+), 10 deletions(-)
  create mode 100644 drivers/net/dsa/mt7530-mmio.c
 
 --- a/MAINTAINERS
diff --git a/target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch b/target/linux/generic/backport-6.1/792-v6.6-net-phylink-add-pcs_enable-pcs_disable-methods.patch
new file mode 100644 (file)
index 0000000..6ade45e
--- /dev/null
@@ -0,0 +1,172 @@
+From 90ef0a7b0622c62758b2638604927867775479ea Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 13 Jul 2023 09:42:07 +0100
+Subject: [PATCH] net: phylink: add pcs_enable()/pcs_disable() methods
+
+Add phylink PCS enable/disable callbacks that will allow us to place
+IEEE 802.3 register compliant PCS in power-down mode while not being
+used.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/phylink.c | 48 +++++++++++++++++++++++++++++++--------
+ include/linux/phylink.h   | 16 +++++++++++++
+ 2 files changed, 55 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -34,6 +34,10 @@ enum {
+       PHYLINK_DISABLE_STOPPED,
+       PHYLINK_DISABLE_LINK,
+       PHYLINK_DISABLE_MAC_WOL,
++
++      PCS_STATE_DOWN = 0,
++      PCS_STATE_STARTING,
++      PCS_STATE_STARTED,
+ };
+ /**
+@@ -71,6 +75,7 @@ struct phylink {
+       struct mutex state_mutex;
+       struct phylink_link_state phy_state;
+       struct work_struct resolve;
++      unsigned int pcs_state;
+       bool mac_link_dropped;
+       bool using_mac_select_pcs;
+@@ -987,6 +992,22 @@ static void phylink_mac_pcs_an_restart(s
+       }
+ }
++static void phylink_pcs_disable(struct phylink_pcs *pcs)
++{
++      if (pcs && pcs->ops->pcs_disable)
++              pcs->ops->pcs_disable(pcs);
++}
++
++static int phylink_pcs_enable(struct phylink_pcs *pcs)
++{
++      int err = 0;
++
++      if (pcs && pcs->ops->pcs_enable)
++              err = pcs->ops->pcs_enable(pcs);
++
++      return err;
++}
++
+ static void phylink_major_config(struct phylink *pl, bool restart,
+                                 const struct phylink_link_state *state)
+ {
+@@ -1023,11 +1044,16 @@ static void phylink_major_config(struct
+       /* If we have a new PCS, switch to the new PCS after preparing the MAC
+        * for the change.
+        */
+-      if (pcs_changed)
++      if (pcs_changed) {
++              phylink_pcs_disable(pl->pcs);
+               pl->pcs = pcs;
++      }
+       phylink_mac_config(pl, state);
++      if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed)
++              phylink_pcs_enable(pl->pcs);
++
+       if (pl->pcs) {
+               err = pl->pcs->ops->pcs_config(pl->pcs, pl->cur_link_an_mode,
+                                              state->interface,
+@@ -1498,6 +1524,7 @@ struct phylink *phylink_create(struct ph
+       pl->link_config.speed = SPEED_UNKNOWN;
+       pl->link_config.duplex = DUPLEX_UNKNOWN;
+       pl->link_config.an_enabled = true;
++      pl->pcs_state = PCS_STATE_DOWN;
+       pl->mac_ops = mac_ops;
+       __set_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state);
+       timer_setup(&pl->link_poll, phylink_fixed_poll, 0);
+@@ -1899,6 +1926,8 @@ void phylink_start(struct phylink *pl)
+       if (pl->netdev)
+               netif_carrier_off(pl->netdev);
++      pl->pcs_state = PCS_STATE_STARTING;
++
+       /* Apply the link configuration to the MAC when starting. This allows
+        * a fixed-link to start with the correct parameters, and also
+        * ensures that we set the appropriate advertisement for Serdes links.
+@@ -1909,6 +1938,8 @@ void phylink_start(struct phylink *pl)
+        */
+       phylink_mac_initial_config(pl, true);
++      pl->pcs_state = PCS_STATE_STARTED;
++
+       phylink_enable_and_run_resolve(pl, PHYLINK_DISABLE_STOPPED);
+       if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->link_gpio) {
+@@ -1927,15 +1958,9 @@ void phylink_start(struct phylink *pl)
+                       poll = true;
+       }
+-      switch (pl->cfg_link_an_mode) {
+-      case MLO_AN_FIXED:
++      if (pl->cfg_link_an_mode == MLO_AN_FIXED)
+               poll |= pl->config->poll_fixed_state;
+-              break;
+-      case MLO_AN_INBAND:
+-              if (pl->pcs)
+-                      poll |= pl->pcs->poll;
+-              break;
+-      }
++
+       if (poll)
+               mod_timer(&pl->link_poll, jiffies + HZ);
+       if (pl->phydev)
+@@ -1972,6 +1997,10 @@ void phylink_stop(struct phylink *pl)
+       }
+       phylink_run_resolve_and_disable(pl, PHYLINK_DISABLE_STOPPED);
++
++      pl->pcs_state = PCS_STATE_DOWN;
++
++      phylink_pcs_disable(pl->pcs);
+ }
+ EXPORT_SYMBOL_GPL(phylink_stop);
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -446,6 +446,8 @@ struct phylink_pcs {
+ /**
+  * struct phylink_pcs_ops - MAC PCS operations structure.
+  * @pcs_validate: validate the link configuration.
++ * @pcs_enable: enable the PCS.
++ * @pcs_disable: disable the PCS.
+  * @pcs_get_state: read the current MAC PCS link state from the hardware.
+  * @pcs_config: configure the MAC PCS for the selected mode and state.
+  * @pcs_an_restart: restart 802.3z BaseX autonegotiation.
+@@ -455,6 +457,8 @@ struct phylink_pcs {
+ struct phylink_pcs_ops {
+       int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
+                           const struct phylink_link_state *state);
++      int (*pcs_enable)(struct phylink_pcs *pcs);
++      void (*pcs_disable)(struct phylink_pcs *pcs);
+       void (*pcs_get_state)(struct phylink_pcs *pcs,
+                             struct phylink_link_state *state);
+       int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
+@@ -485,6 +489,18 @@ int pcs_validate(struct phylink_pcs *pcs
+                const struct phylink_link_state *state);
+ /**
++ * pcs_enable() - enable the PCS.
++ * @pcs: a pointer to a &struct phylink_pcs.
++ */
++int pcs_enable(struct phylink_pcs *pcs);
++
++/**
++ * pcs_disable() - disable the PCS.
++ * @pcs: a pointer to a &struct phylink_pcs.
++ */
++void pcs_disable(struct phylink_pcs *pcs);
++
++/**
+  * pcs_get_state() - Read the current inband link state from the hardware
+  * @pcs: a pointer to a &struct phylink_pcs.
+  * @state: a pointer to a &struct phylink_link_state.
diff --git a/target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch b/target/linux/generic/backport-6.1/793-v6.6-net-pcs-lynxi-implement-pcs_disable-op.patch
new file mode 100644 (file)
index 0000000..eb9b4b7
--- /dev/null
@@ -0,0 +1,44 @@
+From e4ccdfb78a47132f2d215658aab8902fc457c4b4 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Fri, 18 Aug 2023 04:07:46 +0100
+Subject: [PATCH 082/125] net: pcs: lynxi: implement pcs_disable op
+
+When switching from 10GBase-R/5GBase-R/USXGMII to one of the interface
+modes provided by mtk-pcs-lynxi we need to make sure to always perform
+a full configuration of the PHYA.
+
+Implement pcs_disable op which resets the stored interface mode to
+PHY_INTERFACE_MODE_NA to trigger a full reconfiguration once the LynxI
+PCS driver had previously been deselected in favor of another PCS
+driver such as the to-be-added driver for the USXGMII PCS found in
+MT7988.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Link: https://lore.kernel.org/r/f23d1a60d2c9d2fb72e32dcb0eaa5f7e867a3d68.1692327891.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/pcs/pcs-mtk-lynxi.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/pcs/pcs-mtk-lynxi.c
++++ b/drivers/net/pcs/pcs-mtk-lynxi.c
+@@ -241,11 +241,19 @@ static void mtk_pcs_lynxi_link_up(struct
+       }
+ }
++static void mtk_pcs_lynxi_disable(struct phylink_pcs *pcs)
++{
++      struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
++
++      mpcs->interface = PHY_INTERFACE_MODE_NA;
++}
++
+ static const struct phylink_pcs_ops mtk_pcs_lynxi_ops = {
+       .pcs_get_state = mtk_pcs_lynxi_get_state,
+       .pcs_config = mtk_pcs_lynxi_config,
+       .pcs_an_restart = mtk_pcs_lynxi_restart_an,
+       .pcs_link_up = mtk_pcs_lynxi_link_up,
++      .pcs_disable = mtk_pcs_lynxi_disable,
+ };
+ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
index b1e7065a8b91f9443b49301c005d9356d3d7183b..33c5c271212a3dc20aa60f22ef1a56e382f7e75e 100644 (file)
@@ -17,7 +17,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 
 --- a/include/linux/phylink.h
 +++ b/include/linux/phylink.h
-@@ -584,10 +584,37 @@ int phylink_speed_up(struct phylink *pl)
+@@ -600,10 +600,37 @@ int phylink_speed_up(struct phylink *pl)
  #define phylink_test(bm, mode)        __phylink_do_bit(test_bit, bm, mode)
  
  void phylink_set_port_modes(unsigned long *bits);
@@ -57,7 +57,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                                          const unsigned long *advertising);
 --- a/drivers/net/phy/phylink.c
 +++ b/drivers/net/phy/phylink.c
-@@ -885,7 +885,6 @@ static int phylink_change_inband_advert(
+@@ -931,7 +931,6 @@ static int phylink_change_inband_advert(
  
        return 0;
  }
@@ -65,7 +65,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
  static void phylink_mac_pcs_get_state(struct phylink *pl,
                                      struct phylink_link_state *state)
  {
-@@ -2966,6 +2965,52 @@ void phylink_mii_c22_pcs_get_state(struc
+@@ -3014,6 +3013,52 @@ void phylink_mii_c22_pcs_get_state(struc
  EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_get_state);
  
  /**
@@ -118,7 +118,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
   * phylink_mii_c22_pcs_set_advertisement() - configure the clause 37 PCS
   *    advertisement
   * @pcs: a pointer to a &struct mdio_device.
-@@ -3037,6 +3082,46 @@ int phylink_mii_c22_pcs_set_advertisemen
+@@ -3085,6 +3130,46 @@ int phylink_mii_c22_pcs_set_advertisemen
  EXPORT_SYMBOL_GPL(phylink_mii_c22_pcs_set_advertisement);
  
  /**
index 2bc78fa05e56ccd3976267877bf4566ef5b2270b..9a1c26e7aeb36adb985a7b9c9dcda4475e5ba5e6 100644 (file)
@@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2992,8 +2992,8 @@ static irqreturn_t mtk_handle_irq_rx(int
+@@ -3095,8 +3095,8 @@ static irqreturn_t mtk_handle_irq_rx(int
  
        eth->rx_events++;
        if (likely(napi_schedule_prep(&eth->rx_napi))) {
@@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        }
  
        return IRQ_HANDLED;
-@@ -3005,8 +3005,8 @@ static irqreturn_t mtk_handle_irq_tx(int
+@@ -3108,8 +3108,8 @@ static irqreturn_t mtk_handle_irq_tx(int
  
        eth->tx_events++;
        if (likely(napi_schedule_prep(&eth->tx_napi))) {
@@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        }
  
        return IRQ_HANDLED;
-@@ -4666,6 +4666,8 @@ static int mtk_probe(struct platform_dev
+@@ -4883,6 +4883,8 @@ static int mtk_probe(struct platform_dev
         * for NAPI to work
         */
        init_dummy_netdev(&eth->dummy_dev);
diff --git a/target/linux/generic/pending-5.15/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch b/target/linux/generic/pending-5.15/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch
deleted file mode 100644 (file)
index 91ffd65..0000000
+++ /dev/null
@@ -1,428 +0,0 @@
-From patchwork Wed Nov  2 00:58:01 2022
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
-X-Patchwork-Id: 13027653
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@kernel.org>
-Date: Wed, 2 Nov 2022 00:58:01 +0000
-From: Daniel Golle <daniel@makrotopia.org>
-To: Felix Fietkau <nbd@nbd.name>, John Crispin <john@phrozen.org>,
-        Sean Wang <sean.wang@mediatek.com>,
-        Mark Lee <Mark-MC.Lee@mediatek.com>,
-        "David S. Miller" <davem@davemloft.net>,
-        Eric Dumazet <edumazet@google.com>,
-        Jakub Kicinski <kuba@kernel.org>,
-        Paolo Abeni <pabeni@redhat.com>,
-        Matthias Brugger <matthias.bgg@gmail.com>,
-        netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-        linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org
-Subject: [PATCH v4] net: ethernet: mediatek: ppe: add support for flow
- accounting
-Message-ID: <Y2HAmYYPd77dz+K5@makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-The PPE units found in MT7622 and newer support packet and byte
-accounting of hw-offloaded flows. Add support for reading those
-counters as found in MediaTek's SDK[1].
-
-[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/bc6a6a375c800dc2b80e1a325a2c732d1737df92
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
-v4: declare function mtk_mib_entry_read as static
-v3: don't bother to set 'false' values in any zero-initialized struct
-    use mtk_foe_entry_ib2
-    both changes were requested by Felix Fietkau
-
-v2: fix wrong variable name in return value check spotted by Denis Kirjanov
-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c   |   7 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h   |   1 +
- drivers/net/ethernet/mediatek/mtk_ppe.c       | 110 +++++++++++++++++-
- drivers/net/ethernet/mediatek/mtk_ppe.h       |  23 +++-
- .../net/ethernet/mediatek/mtk_ppe_debugfs.c   |   9 +-
- .../net/ethernet/mediatek/mtk_ppe_offload.c   |   7 ++
- drivers/net/ethernet/mediatek/mtk_ppe_regs.h  |  14 +++
- 7 files changed, 166 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4635,8 +4635,8 @@ static int mtk_probe(struct platform_dev
-               for (i = 0; i < num_ppe; i++) {
-                       u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
--                      eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr,
--                                                 eth->soc->offload_version, i);
-+                      eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
-+
-                       if (!eth->ppe[i]) {
-                               err = -ENOMEM;
-                               goto err_free_dev;
-@@ -4763,6 +4763,7 @@ static const struct mtk_soc_data mt7622_
-       .required_pctl = false,
-       .offload_version = 2,
-       .hash_offset = 2,
-+      .has_accounting = true,
-       .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-@@ -4800,6 +4801,7 @@ static const struct mtk_soc_data mt7629_
-       .hw_features = MTK_HW_FEATURES,
-       .required_clks = MT7629_CLKS_BITMAP,
-       .required_pctl = false,
-+      .has_accounting = true,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-               .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4820,6 +4822,7 @@ static const struct mtk_soc_data mt7981_
-       .offload_version = 2,
-       .hash_offset = 4,
-       .foe_entry_size = sizeof(struct mtk_foe_entry),
-+      .has_accounting = true,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma_v2),
-               .rxd_size = sizeof(struct mtk_rx_dma_v2),
-@@ -4840,6 +4843,7 @@ static const struct mtk_soc_data mt7986_
-       .offload_version = 2,
-       .hash_offset = 4,
-       .foe_entry_size = sizeof(struct mtk_foe_entry),
-+      .has_accounting = true,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma_v2),
-               .rxd_size = sizeof(struct mtk_rx_dma_v2),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1014,6 +1014,8 @@ struct mtk_reg_map {
-  *                            the extra setup for those pins used by GMAC.
-  * @hash_offset                       Flow table hash offset.
-  * @foe_entry_size            Foe table entry size.
-+ * @has_accounting            Bool indicating support for accounting of
-+ *                            offloaded flows.
-  * @txd_size                  Tx DMA descriptor size.
-  * @rxd_size                  Rx DMA descriptor size.
-  * @rx_irq_done_mask          Rx irq done register mask.
-@@ -1031,6 +1033,7 @@ struct mtk_soc_data {
-       u8              hash_offset;
-       u16             foe_entry_size;
-       netdev_features_t hw_features;
-+      bool            has_accounting;
-       struct {
-               u32     txd_size;
-               u32     rxd_size;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -74,6 +74,48 @@ static int mtk_ppe_wait_busy(struct mtk_
-       return ret;
- }
-+static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe)
-+{
-+      int ret;
-+      u32 val;
-+
-+      ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val,
-+                               !(val & MTK_PPE_MIB_SER_CR_ST),
-+                               20, MTK_PPE_WAIT_TIMEOUT_US);
-+
-+      if (ret)
-+              dev_err(ppe->dev, "MIB table busy");
-+
-+      return ret;
-+}
-+
-+static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
-+{
-+      u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
-+      u32 val, cnt_r0, cnt_r1, cnt_r2;
-+      int ret;
-+
-+      val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST;
-+      ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val);
-+
-+      ret = mtk_ppe_mib_wait_busy(ppe);
-+      if (ret)
-+              return ret;
-+
-+      cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0);
-+      cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
-+      cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
-+
-+      byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
-+      byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
-+      pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
-+      pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
-+      *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
-+      *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
-+
-+      return 0;
-+}
-+
- static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
- {
-       ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR);
-@@ -464,6 +506,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
-               hwe->ib1 &= ~MTK_FOE_IB1_STATE;
-               hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
-               dma_wmb();
-+              if (ppe->accounting) {
-+                      struct mtk_foe_accounting *acct;
-+
-+                      acct = ppe->acct_table + entry->hash * sizeof(*acct);
-+                      acct->packets = 0;
-+                      acct->bytes = 0;
-+              }
-       }
-       entry->hash = 0xffff;
-@@ -571,6 +620,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
-       wmb();
-       hwe->ib1 = entry->ib1;
-+      if (ppe->accounting)
-+              *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
-+
-       dma_wmb();
-       mtk_ppe_cache_clear(ppe);
-@@ -762,11 +814,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
-       return mtk_ppe_wait_busy(ppe);
- }
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
--                           int version, int index)
-+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
-+                                               struct mtk_foe_accounting *diff)
-+{
-+      struct mtk_foe_accounting *acct;
-+      int size = sizeof(struct mtk_foe_accounting);
-+      u64 bytes, packets;
-+
-+      if (!ppe->accounting)
-+              return NULL;
-+
-+      if (mtk_mib_entry_read(ppe, index, &bytes, &packets))
-+              return NULL;
-+
-+      acct = ppe->acct_table + index * size;
-+
-+      acct->bytes += bytes;
-+      acct->packets += packets;
-+
-+      if (diff) {
-+              diff->bytes = bytes;
-+              diff->packets = packets;
-+      }
-+
-+      return acct;
-+}
-+
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
- {
-+      bool accounting = eth->soc->has_accounting;
-       const struct mtk_soc_data *soc = eth->soc;
-+      struct mtk_foe_accounting *acct;
-       struct device *dev = eth->dev;
-+      struct mtk_mib_entry *mib;
-       struct mtk_ppe *ppe;
-       u32 foe_flow_size;
-       void *foe;
-@@ -783,7 +863,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
-       ppe->base = base;
-       ppe->eth = eth;
-       ppe->dev = dev;
--      ppe->version = version;
-+      ppe->version = eth->soc->offload_version;
-+      ppe->accounting = accounting;
-       foe = dmam_alloc_coherent(ppe->dev,
-                                 MTK_PPE_ENTRIES * soc->foe_entry_size,
-@@ -799,6 +880,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
-       if (!ppe->foe_flow)
-               return NULL;
-+      if (accounting) {
-+              mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib),
-+                                        &ppe->mib_phys, GFP_KERNEL);
-+              if (!mib)
-+                      return NULL;
-+
-+              ppe->mib_table = mib;
-+
-+              acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct),
-+                                  GFP_KERNEL);
-+
-+              if (!acct)
-+                      return NULL;
-+
-+              ppe->acct_table = acct;
-+      }
-+
-       mtk_ppe_debugfs_init(ppe, index);
-       return ppe;
-@@ -913,6 +1011,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
-               ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
-               ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
-       }
-+
-+      if (ppe->accounting && ppe->mib_phys) {
-+              ppe_w32(ppe, MTK_PPE_MIB_TB_BASE, ppe->mib_phys);
-+              ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_EN,
-+                      MTK_PPE_MIB_CFG_EN);
-+              ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_RD_CLR,
-+                      MTK_PPE_MIB_CFG_RD_CLR);
-+              ppe_m32(ppe, MTK_PPE_MIB_CACHE_CTL, MTK_PPE_MIB_CACHE_CTL_EN,
-+                      MTK_PPE_MIB_CFG_RD_CLR);
-+      }
- }
- int mtk_ppe_stop(struct mtk_ppe *ppe)
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -57,6 +57,7 @@ enum {
- #define MTK_FOE_IB2_MULTICAST         BIT(8)
- #define MTK_FOE_IB2_WDMA_QID2         GENMASK(13, 12)
-+#define MTK_FOE_IB2_MIB_CNT           BIT(15)
- #define MTK_FOE_IB2_WDMA_DEVIDX               BIT(16)
- #define MTK_FOE_IB2_WDMA_WINFO                BIT(17)
-@@ -285,16 +286,34 @@ struct mtk_flow_entry {
-       unsigned long cookie;
- };
-+struct mtk_mib_entry {
-+      u32     byt_cnt_l;
-+      u16     byt_cnt_h;
-+      u32     pkt_cnt_l;
-+      u8      pkt_cnt_h;
-+      u8      _rsv0;
-+      u32     _rsv1;
-+} __packed;
-+
-+struct mtk_foe_accounting {
-+      u64     bytes;
-+      u64     packets;
-+};
-+
- struct mtk_ppe {
-       struct mtk_eth *eth;
-       struct device *dev;
-       void __iomem *base;
-       int version;
-       char dirname[5];
-+      bool accounting;
-       void *foe_table;
-       dma_addr_t foe_phys;
-+      struct mtk_mib_entry *mib_table;
-+      dma_addr_t mib_phys;
-+
-       u16 foe_check_time[MTK_PPE_ENTRIES];
-       struct hlist_head *foe_flow;
-@@ -303,8 +322,7 @@ struct mtk_ppe {
-       void *acct_table;
- };
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
--                           int version, int index);
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
- void mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
- int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
-@@ -358,5 +376,7 @@ int mtk_foe_entry_commit(struct mtk_ppe
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
-+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
-+                                               struct mtk_foe_accounting *diff);
- #endif
---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-@@ -82,6 +82,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
-               struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
-               struct mtk_foe_mac_info *l2;
-               struct mtk_flow_addr_info ai = {};
-+              struct mtk_foe_accounting *acct;
-               unsigned char h_source[ETH_ALEN];
-               unsigned char h_dest[ETH_ALEN];
-               int type, state;
-@@ -95,6 +96,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file
-               if (bind && state != MTK_FOE_STATE_BIND)
-                       continue;
-+              acct = mtk_foe_entry_get_mib(ppe, i, NULL);
-+
-               type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
-               seq_printf(m, "%05x %s %7s", i,
-                          mtk_foe_entry_state_str(state),
-@@ -153,9 +156,11 @@ mtk_ppe_debugfs_foe_show(struct seq_file
-               *((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo);
-               seq_printf(m, " eth=%pM->%pM etype=%04x"
--                            " vlan=%d,%d ib1=%08x ib2=%08x\n",
-+                            " vlan=%d,%d ib1=%08x ib2=%08x"
-+                            " packets=%llu bytes=%llu\n",
-                          h_source, h_dest, ntohs(l2->etype),
--                         l2->vlan1, l2->vlan2, entry->ib1, ib2);
-+                         l2->vlan1, l2->vlan2, entry->ib1, ib2,
-+                         acct ? acct->packets : 0, acct ? acct->bytes : 0);
-       }
-       return 0;
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -497,6 +497,7 @@ static int
- mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
- {
-       struct mtk_flow_entry *entry;
-+      struct mtk_foe_accounting diff;
-       u32 idle;
-       entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
-@@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *e
-       idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
-       f->stats.lastused = jiffies - idle * HZ;
-+      if (entry->hash != 0xFFFF &&
-+          mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash,
-+                                &diff)) {
-+              f->stats.pkts += diff.packets;
-+              f->stats.bytes += diff.bytes;
-+      }
-+
-       return 0;
- }
---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-@@ -149,6 +149,20 @@ enum {
- #define MTK_PPE_MIB_TB_BASE                   0x338
-+#define MTK_PPE_MIB_SER_CR                    0x33C
-+#define MTK_PPE_MIB_SER_CR_ST                 BIT(16)
-+#define MTK_PPE_MIB_SER_CR_ADDR                       GENMASK(13, 0)
-+
-+#define MTK_PPE_MIB_SER_R0                    0x340
-+#define MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW               GENMASK(31, 0)
-+
-+#define MTK_PPE_MIB_SER_R1                    0x344
-+#define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW                GENMASK(31, 16)
-+#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH      GENMASK(15, 0)
-+
-+#define MTK_PPE_MIB_SER_R2                    0x348
-+#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH               GENMASK(23, 0)
-+
- #define MTK_PPE_MIB_CACHE_CTL                 0x350
- #define MTK_PPE_MIB_CACHE_CTL_EN              BIT(0)
- #define MTK_PPE_MIB_CACHE_CTL_FLUSH           BIT(2)
diff --git a/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch
new file mode 100644 (file)
index 0000000..1d84ea9
--- /dev/null
@@ -0,0 +1,44 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 27 Oct 2022 23:39:52 +0200
+Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code
+ on mt7621
+
+Avoid some branches in the hot path on low-end devices with limited CPU power,
+and reduce code size
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1323,6 +1323,22 @@ struct mtk_mac {
+ /* the struct describing the SoC. these are declared in the soc_xyz.c files */
+ extern const struct of_device_id of_mtk_match[];
++#ifdef CONFIG_SOC_MT7621
++static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
++{
++      return true;
++}
++
++static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth)
++{
++      return false;
++}
++
++static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth)
++{
++      return false;
++}
++#else
+ static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
+ {
+       return eth->soc->version == 1;
+@@ -1337,6 +1353,7 @@ static inline bool mtk_is_netsys_v3_or_g
+ {
+       return eth->soc->version > 2;
+ }
++#endif
+ static inline struct mtk_foe_entry *
+ mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
diff --git a/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/pending-5.15/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch
deleted file mode 100644 (file)
index f6c70e7..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 20 Nov 2022 23:01:00 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: drop generic vlan rx offload,
- only use DSA untagging
-
-Through testing I found out that hardware vlan rx offload support seems to
-have some hardware issues. At least when using multiple MACs and when receiving
-tagged packets on the secondary MAC, the hardware can sometimes start to emit
-wrong tags on the first MAC as well.
-
-In order to avoid such issues, drop the feature configuration and use the
-offload feature only for DSA hardware untagging on MT7621/MT7622 devices which
-only use one MAC.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1850,9 +1850,7 @@ static int mtk_poll_rx(struct napi_struc
-       while (done < budget) {
-               unsigned int pktlen, *rxdcsum;
--              bool has_hwaccel_tag = false;
-               struct net_device *netdev;
--              u16 vlan_proto, vlan_tci;
-               dma_addr_t dma_addr;
-               u32 hash, reason;
-               int mac = 0;
-@@ -1987,36 +1985,21 @@ static int mtk_poll_rx(struct napi_struc
-                       skb_checksum_none_assert(skb);
-               skb->protocol = eth_type_trans(skb, netdev);
--              if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
--                      mtk_ppe_check_skb(eth->ppe[0], skb, hash);
--
--              if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
--                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
--                              if (trxd.rxd3 & RX_DMA_VTAG_V2) {
--                                      vlan_proto = RX_DMA_VPID(trxd.rxd4);
--                                      vlan_tci = RX_DMA_VID(trxd.rxd4);
--                                      has_hwaccel_tag = true;
--                              }
--                      } else if (trxd.rxd2 & RX_DMA_VTAG) {
--                              vlan_proto = RX_DMA_VPID(trxd.rxd3);
--                              vlan_tci = RX_DMA_VID(trxd.rxd3);
--                              has_hwaccel_tag = true;
--                      }
--              }
--
-               /* When using VLAN untagging in combination with DSA, the
-                * hardware treats the MTK special tag as a VLAN and untags it.
-                */
--              if (has_hwaccel_tag && netdev_uses_dsa(netdev)) {
--                      unsigned int port = vlan_proto & GENMASK(2, 0);
-+              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
-+                  (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
-+                      unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
-                       if (port < ARRAY_SIZE(eth->dsa_meta) &&
-                           eth->dsa_meta[port])
-                               skb_dst_set_noref(skb, &eth->dsa_meta[port]->dst);
--              } else if (has_hwaccel_tag) {
--                      __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci);
-               }
-+              if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-+                      mtk_ppe_check_skb(eth->ppe[0], skb, hash);
-+
-               skb_record_rx_queue(skb, 0);
-               napi_gro_receive(napi, skb);
-@@ -2831,29 +2814,11 @@ static netdev_features_t mtk_fix_feature
- static int mtk_set_features(struct net_device *dev, netdev_features_t features)
- {
--      struct mtk_mac *mac = netdev_priv(dev);
--      struct mtk_eth *eth = mac->hw;
-       netdev_features_t diff = dev->features ^ features;
--      int i;
-       if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO))
-               mtk_hwlro_netdev_disable(dev);
--      /* Set RX VLAN offloading */
--      if (!(diff & NETIF_F_HW_VLAN_CTAG_RX))
--              return 0;
--
--      mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX),
--              MTK_CDMP_EG_CTRL);
--
--      /* sync features with other MAC */
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
--              if (!eth->netdev[i] || eth->netdev[i] == dev)
--                      continue;
--              eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
--              eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX;
--      }
--
-       return 0;
- }
-@@ -3167,30 +3132,6 @@ static int mtk_open(struct net_device *d
-       struct mtk_eth *eth = mac->hw;
-       int i, err;
--      if (mtk_uses_dsa(dev) && !eth->prog) {
--              for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
--                      struct metadata_dst *md_dst = eth->dsa_meta[i];
--
--                      if (md_dst)
--                              continue;
--
--                      md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
--                                                  GFP_KERNEL);
--                      if (!md_dst)
--                              return -ENOMEM;
--
--                      md_dst->u.port_info.port_id = i;
--                      eth->dsa_meta[i] = md_dst;
--              }
--      } else {
--              /* Hardware special tag parsing needs to be disabled if at least
--               * one MAC does not use DSA.
--               */
--              u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
--              val &= ~MTK_CDMP_STAG_EN;
--              mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
--      }
--
-       err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
-       if (err) {
-               netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
-@@ -3231,6 +3172,35 @@ static int mtk_open(struct net_device *d
-       phylink_start(mac->phylink);
-       netif_tx_start_all_queues(dev);
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+              return 0;
-+
-+      if (mtk_uses_dsa(dev) && !eth->prog) {
-+              for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
-+                      struct metadata_dst *md_dst = eth->dsa_meta[i];
-+
-+                      if (md_dst)
-+                              continue;
-+
-+                      md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
-+                                                  GFP_KERNEL);
-+                      if (!md_dst)
-+                              return -ENOMEM;
-+
-+                      md_dst->u.port_info.port_id = i;
-+                      eth->dsa_meta[i] = md_dst;
-+              }
-+      } else {
-+              /* Hardware special tag parsing needs to be disabled if at least
-+               * one MAC does not use DSA.
-+               */
-+              u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-+              val &= ~MTK_CDMP_STAG_EN;
-+              mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
-+
-+              mtk_w32(eth, 0, MTK_CDMP_EG_CTRL);
-+      }
-+
-       return 0;
- }
-@@ -3715,10 +3685,9 @@ static int mtk_hw_init(struct mtk_eth *e
-       if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-               val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-               mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
--      }
--      /* Enable RX VLan Offloading */
--      mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-+              mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-+      }
-       /* set interrupt delays based on current Net DIM sample */
-       mtk_dim_rx(&eth->rx_dim.work);
-@@ -4358,7 +4327,7 @@ static int mtk_add_mac(struct mtk_eth *e
-               eth->netdev[id]->hw_features |= NETIF_F_LRO;
-       eth->netdev[id]->vlan_features = eth->soc->hw_features &
--              ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
-+              ~NETIF_F_HW_VLAN_CTAG_TX;
-       eth->netdev[id]->features |= eth->soc->hw_features;
-       eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -48,7 +48,6 @@
- #define MTK_HW_FEATURES               (NETIF_F_IP_CSUM | \
-                                NETIF_F_RXCSUM | \
-                                NETIF_F_HW_VLAN_CTAG_TX | \
--                               NETIF_F_HW_VLAN_CTAG_RX | \
-                                NETIF_F_SG | NETIF_F_TSO | \
-                                NETIF_F_TSO6 | \
-                                NETIF_F_IPV6_CSUM |\
index fbf0cb5735eb2b58f6a58333874d8b33ff5997dd..56edb63234539e02b7f8ea023038811bf0a6b263 100644 (file)
@@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1423,12 +1423,28 @@ static void mtk_wake_queue(struct mtk_et
+@@ -1516,12 +1516,28 @@ static void mtk_wake_queue(struct mtk_et
        }
  }
  
@@ -45,11 +45,11 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        bool gso = false;
        int tx_num;
  
-@@ -1450,6 +1466,18 @@ static netdev_tx_t mtk_start_xmit(struct
+@@ -1543,6 +1559,18 @@ static netdev_tx_t mtk_start_xmit(struct
                return NETDEV_TX_BUSY;
        }
  
-+      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
++      if (mtk_is_netsys_v1(eth) &&
 +          skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) {
 +              segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO);
 +              if (IS_ERR(segs))
@@ -64,14 +64,14 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        /* TSO: fill MSS info in tcp checksum field */
        if (skb_is_gso(skb)) {
                if (skb_cow_head(skb, 0)) {
-@@ -1465,8 +1493,14 @@ static netdev_tx_t mtk_start_xmit(struct
+@@ -1558,8 +1586,14 @@ static netdev_tx_t mtk_start_xmit(struct
                }
        }
  
 -      if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0)
 -              goto drop;
 +      skb_list_walk_safe(skb, skb, next) {
-+              if ((!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
++              if ((mtk_is_netsys_v1(eth) &&
 +                   mtk_skb_has_small_frag(skb) && skb_linearize(skb)) ||
 +                  mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) {
 +                              stats->tx_dropped++;
@@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                netif_tx_stop_all_queues(dev);
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -258,7 +258,7 @@
+@@ -268,7 +268,7 @@
  #define MTK_CHK_DDONE_EN      BIT(28)
  #define MTK_DMAD_WR_WDONE     BIT(26)
  #define MTK_WCOMP_EN          BIT(24)
index 3c6359ee419a767dd95bc5f236ca5d46aed5b99a..11a81dd0bfdc9bc1a0a37ff18bbd0b7966fe1a46 100644 (file)
@@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -48,8 +48,7 @@
+@@ -47,8 +47,7 @@
  #define MTK_HW_FEATURES               (NETIF_F_IP_CSUM | \
                                 NETIF_F_RXCSUM | \
                                 NETIF_F_HW_VLAN_CTAG_TX | \
index 0aa9382b6bdd91ed95df28913efabbd513ceede7..452e486e8969e251942ff83bd17bfa86d1980f08 100644 (file)
@@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -667,6 +667,7 @@ static void mtk_mac_link_up(struct phyli
+@@ -723,6 +723,7 @@ static void mtk_mac_link_up(struct phyli
                 MAC_MCR_FORCE_RX_FC);
  
        /* Configure speed */
@@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        switch (speed) {
        case SPEED_2500:
        case SPEED_1000:
-@@ -3145,6 +3146,9 @@ found:
+@@ -3288,6 +3289,9 @@ found:
        if (dp->index >= MTK_QDMA_NUM_QUEUES)
                return NOTIFY_DONE;
  
index 9ef65ec16f7bb768ff273310652cf523b44e015f..104ce00b7eb1bf2ec1a6e0ae749ff327e239aa0b 100644 (file)
@@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  #include <net/dsa.h>
  #include "mtk_eth_soc.h"
  #include "mtk_ppe.h"
-@@ -757,7 +758,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe
+@@ -781,7 +782,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe
                    skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK)
                        goto out;
  
index 4f765c5c1451c3eb0fddbc44c25f4a2b6954dda5..d648ba4dc7fb3c3cf04e4d66484af28ffd4b3de1 100644 (file)
@@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1277,6 +1277,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk
+@@ -1448,6 +1448,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk
  int mtk_eth_offload_init(struct mtk_eth *eth);
  int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
                     void *type_data);
@@ -120,7 +120,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  static void
  wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val)
  {
-@@ -1752,6 +1759,99 @@ out:
+@@ -1760,6 +1767,99 @@ out:
        mutex_unlock(&hw_lock);
  }
  
@@ -220,7 +220,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
                    void __iomem *wdma, phys_addr_t wdma_phy,
                    int index)
-@@ -1771,6 +1871,7 @@ void mtk_wed_add_hw(struct device_node *
+@@ -1779,6 +1879,7 @@ void mtk_wed_add_hw(struct device_node *
                .irq_set_mask = mtk_wed_irq_set_mask,
                .detach = mtk_wed_detach,
                .ppe_check = mtk_wed_ppe_check,
index 6e17e4dc529f751054cc99b0517ac212f5152a7c..e89d4cd97b9f75cafeb191b84076da112ff59edf 100644 (file)
@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -639,10 +639,20 @@ void mtk_foe_entry_clear(struct mtk_ppe
+@@ -663,10 +663,20 @@ void mtk_foe_entry_clear(struct mtk_ppe
  static int
  mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
  {
index 29d6e0b09918cc27533447419b028bc9d907562d..c8be7a9e2b2953707b6e870ef24e2dc2ec96300e 100644 (file)
@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -466,42 +466,43 @@ int mtk_foe_entry_set_queue(struct mtk_e
+@@ -483,42 +483,43 @@ int mtk_foe_entry_set_queue(struct mtk_e
        return 0;
  }
  
@@ -72,7 +72,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash);
  
                hwe->ib1 &= ~MTK_FOE_IB1_STATE;
-@@ -520,7 +521,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
+@@ -538,7 +539,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
        if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW)
                return;
  
@@ -82,7 +82,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        kfree(entry);
  }
  
-@@ -536,66 +538,55 @@ static int __mtk_foe_entry_idle_time(str
+@@ -554,66 +556,55 @@ static int __mtk_foe_entry_idle_time(str
                return now - timestamp;
  }
  
@@ -178,7 +178,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  }
  
  static void
-@@ -632,7 +623,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+@@ -656,7 +647,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
  void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
  {
        spin_lock_bh(&ppe_lock);
@@ -188,7 +188,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        spin_unlock_bh(&ppe_lock);
  }
  
-@@ -679,8 +671,8 @@ mtk_foe_entry_commit_subflow(struct mtk_
+@@ -703,8 +695,8 @@ mtk_foe_entry_commit_subflow(struct mtk_
  {
        const struct mtk_soc_data *soc = ppe->eth->soc;
        struct mtk_flow_entry *flow_info;
@@ -198,7 +198,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP;
        int type;
  
-@@ -688,30 +680,30 @@ mtk_foe_entry_commit_subflow(struct mtk_
+@@ -712,30 +704,30 @@ mtk_foe_entry_commit_subflow(struct mtk_
        if (!flow_info)
                return;
  
@@ -239,7 +239,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  }
  
  void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
-@@ -721,9 +713,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe
+@@ -745,9 +737,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe
        struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash);
        struct mtk_flow_entry *entry;
        struct mtk_foe_bridge key = {};
@@ -251,7 +251,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        u8 *tag;
  
        spin_lock_bh(&ppe_lock);
-@@ -731,20 +725,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe
+@@ -755,20 +749,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe
        if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND)
                goto out;
  
@@ -278,7 +278,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                        continue;
                }
  
-@@ -795,9 +783,17 @@ out:
+@@ -819,9 +807,17 @@ out:
  
  int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
  {
@@ -300,7 +300,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -265,7 +265,12 @@ enum {
+@@ -286,7 +286,12 @@ enum {
  
  struct mtk_flow_entry {
        union {
@@ -314,7 +314,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                struct {
                        struct rhash_head l2_node;
                        struct hlist_head l2_flows;
-@@ -275,13 +280,7 @@ struct mtk_flow_entry {
+@@ -296,13 +301,7 @@ struct mtk_flow_entry {
        s8 wed_index;
        u8 ppe_index;
        u16 hash;
index fdc3d520c119fc29e090ea9fc1af1818195b627a..7f04fd9fa8648ca0b745bb13ab395e3a56b134a0 100644 (file)
@@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
        if (ret)
                dev_err(ppe->dev, "MIB table busy");
-@@ -90,18 +90,32 @@ static int mtk_ppe_mib_wait_busy(struct
+@@ -90,17 +90,31 @@ static int mtk_ppe_mib_wait_busy(struct
        return ret;
  }
  
@@ -43,7 +43,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 +
 +struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index)
  {
-       u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
        u32 val, cnt_r0, cnt_r1, cnt_r2;
 +      struct mtk_foe_accounting *acct;
        int ret;
@@ -62,25 +61,35 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
        cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0);
        cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
-@@ -111,10 +125,11 @@ static int mtk_mib_entry_read(struct mtk
-       byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
-       pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
-       pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
--      *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
--      *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
+@@ -109,19 +123,19 @@ static int mtk_mib_entry_read(struct mtk
+       if (mtk_is_netsys_v3_or_greater(ppe->eth)) {
+               /* 64 bit for each counter */
+               u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3);
+-              *bytes = ((u64)cnt_r1 << 32) | cnt_r0;
+-              *packets = ((u64)cnt_r3 << 32) | cnt_r2;
++              acct->bytes += ((u64)cnt_r1 << 32) | cnt_r0;
++              acct->packets += ((u64)cnt_r3 << 32) | cnt_r2;
+       } else {
+               /* 48 bit byte counter, 40 bit packet counter */
+               u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
+               u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
+               u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
+               u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
+-              *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
+-              *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
++              acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low;
++              acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low;
+       }
  
 -      return 0;
-+      acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low;
-+      acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low;
-+
 +      return acct;
  }
  
  static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
-@@ -508,13 +523,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
-               hwe->ib1 &= ~MTK_FOE_IB1_STATE;
+@@ -526,13 +540,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
                hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
                dma_wmb();
+               mtk_ppe_cache_clear(ppe);
 -              if (ppe->accounting) {
 -                      struct mtk_foe_accounting *acct;
 -
@@ -91,7 +100,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        }
        entry->hash = 0xffff;
  
-@@ -539,11 +547,14 @@ static int __mtk_foe_entry_idle_time(str
+@@ -557,11 +564,14 @@ static int __mtk_foe_entry_idle_time(str
  }
  
  static bool
@@ -107,7 +116,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        int len;
  
        if (hash == 0xffff)
-@@ -554,18 +565,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp
+@@ -572,18 +582,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp
        memcpy(&foe, hwe, len);
  
        if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) ||
@@ -146,7 +155,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        struct mtk_flow_entry *cur;
        struct hlist_node *tmp;
        int idle;
-@@ -574,7 +602,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe
+@@ -592,7 +619,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe
        hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) {
                int cur_idle;
  
@@ -157,7 +166,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                        __mtk_foe_entry_clear(ppe, entry, false);
                        continue;
                }
-@@ -589,10 +619,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe
+@@ -607,10 +636,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe
        }
  }
  
@@ -187,7 +196,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        struct mtk_eth *eth = ppe->eth;
        u16 timestamp = mtk_eth_timestamp(eth);
        struct mtk_foe_entry *hwe;
-@@ -617,6 +666,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+@@ -641,6 +689,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
  
        dma_wmb();
  
@@ -200,7 +209,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        mtk_ppe_cache_clear(ppe);
  }
  
-@@ -781,21 +836,6 @@ out:
+@@ -805,21 +859,6 @@ out:
        spin_unlock_bh(&ppe_lock);
  }
  
@@ -222,7 +231,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
  {
        if (!ppe)
-@@ -823,32 +863,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
+@@ -847,32 +886,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
        return mtk_ppe_wait_busy(ppe);
  }
  
@@ -257,7 +266,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        bool accounting = eth->soc->has_accounting;
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -283,6 +283,8 @@ struct mtk_flow_entry {
+@@ -304,6 +304,8 @@ struct mtk_flow_entry {
        struct mtk_foe_entry data;
        struct rhash_head node;
        unsigned long cookie;
@@ -266,7 +275,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  };
  
  struct mtk_mib_entry {
-@@ -325,6 +327,7 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
+@@ -347,6 +349,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth)
  void mtk_ppe_start(struct mtk_ppe *ppe);
  int mtk_ppe_stop(struct mtk_ppe *ppe);
  int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
@@ -274,7 +283,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
  void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
  
-@@ -373,9 +376,8 @@ int mtk_foe_entry_set_queue(struct mtk_e
+@@ -395,9 +398,8 @@ int mtk_foe_entry_set_queue(struct mtk_e
                            unsigned int queue);
  int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
  void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
@@ -295,7 +304,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 -              acct = mtk_foe_entry_get_mib(ppe, i, NULL);
 +              acct = mtk_ppe_mib_entry_read(ppe, i);
  
-               type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
+               type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1);
                seq_printf(m, "%05x %s %7s", i,
 --- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
diff --git a/target/linux/generic/pending-5.15/736-05-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch b/target/linux/generic/pending-5.15/736-05-net-ethernet-mtk_eth_soc-add-missing-ppe-cache-flush.patch
deleted file mode 100644 (file)
index 3083931..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 23 Mar 2023 11:19:14 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: add missing ppe cache flush when
- deleting a flow
-
-The cache needs to be flushed to ensure that the hardware stops offloading
-the flow immediately.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -523,6 +523,7 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
-               hwe->ib1 &= ~MTK_FOE_IB1_STATE;
-               hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
-               dma_wmb();
-+              mtk_ppe_cache_clear(ppe);
-       }
-       entry->hash = 0xffff;
diff --git a/target/linux/generic/pending-5.15/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch b/target/linux/generic/pending-5.15/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch
deleted file mode 100644 (file)
index 3dfa193..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 23 Mar 2023 21:45:43 +0100
-Subject: [PATCH] net: ethernet: mediatek: fix ppe flow accounting for v1
- hardware
-
-Older chips (like MT7622) use a different bit in ib2 to enable hardware
-counter support.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -646,6 +646,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
-       struct mtk_eth *eth = ppe->eth;
-       u16 timestamp = mtk_eth_timestamp(eth);
-       struct mtk_foe_entry *hwe;
-+      u32 val;
-       if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-               entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
-@@ -662,8 +663,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
-       wmb();
-       hwe->ib1 = entry->ib1;
--      if (ppe->accounting)
--              *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
-+      if (ppe->accounting) {
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+                      val = MTK_FOE_IB2_MIB_CNT_V2;
-+              else
-+                      val = MTK_FOE_IB2_MIB_CNT;
-+              *mtk_foe_entry_ib2(eth, hwe) |= val;
-+      }
-       dma_wmb();
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -55,9 +55,10 @@ enum {
- #define MTK_FOE_IB2_PSE_QOS           BIT(4)
- #define MTK_FOE_IB2_DEST_PORT         GENMASK(7, 5)
- #define MTK_FOE_IB2_MULTICAST         BIT(8)
-+#define MTK_FOE_IB2_MIB_CNT           BIT(10)
- #define MTK_FOE_IB2_WDMA_QID2         GENMASK(13, 12)
--#define MTK_FOE_IB2_MIB_CNT           BIT(15)
-+#define MTK_FOE_IB2_MIB_CNT_V2                BIT(15)
- #define MTK_FOE_IB2_WDMA_DEVIDX               BIT(16)
- #define MTK_FOE_IB2_WDMA_WINFO                BIT(17)
diff --git a/target/linux/generic/pending-5.15/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch b/target/linux/generic/pending-5.15/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch
deleted file mode 100644 (file)
index 621a7b0..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-From 663fa1b7e0cb2c929008482014a70c6625caad75 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 7 Mar 2023 15:55:13 +0000
-Subject: [PATCH 1/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V1 capability
- bit
-
-Introduce MTK_NETSYS_V1 bit in the device capabilities for
-MT7621/MT7622/MT7623/MT7628/MT7629 SoCs.
-Use !MTK_NETSYS_V1 instead of MTK_NETSYS_V2 in the driver codebase.
-This is a preliminary patch to introduce support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++-------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 45 ++++++++++++---------
- 2 files changed, 41 insertions(+), 34 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -597,7 +597,7 @@ static void mtk_set_queue_speed(struct m
-             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
-             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
-             MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
--      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-               val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
-       if (IS_ENABLED(CONFIG_SOC_MT7621)) {
-@@ -974,7 +974,7 @@ static bool mtk_rx_get_desc(struct mtk_e
-       rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
-       rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
-       rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
--      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-               rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
-               rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
-       }
-@@ -1032,7 +1032,7 @@ static int mtk_init_fq_dma(struct mtk_et
-               txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
-               txd->txd4 = 0;
--              if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
-+              if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) {
-                       txd->txd5 = 0;
-                       txd->txd6 = 0;
-                       txd->txd7 = 0;
-@@ -1221,7 +1221,7 @@ static void mtk_tx_set_dma_desc(struct n
-       struct mtk_mac *mac = netdev_priv(dev);
-       struct mtk_eth *eth = mac->hw;
--      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-               mtk_tx_set_dma_desc_v2(dev, txd, info);
-       else
-               mtk_tx_set_dma_desc_v1(dev, txd, info);
-@@ -1902,7 +1902,7 @@ static int mtk_poll_rx(struct napi_struc
-                       break;
-               /* find out which mac the packet come from. values start at 1 */
--              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-                       mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
-               else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
-                        !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-@@ -1998,7 +1998,7 @@ static int mtk_poll_rx(struct napi_struc
-               skb->dev = netdev;
-               bytes += skb->len;
--              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-                       reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
-                       hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
-                       if (hash != MTK_RXD5_FOE_ENTRY)
-@@ -2023,7 +2023,7 @@ static int mtk_poll_rx(struct napi_struc
-               /* When using VLAN untagging in combination with DSA, the
-                * hardware treats the MTK special tag as a VLAN and untags it.
-                */
--              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1) &&
-                   (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
-                       unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
-@@ -2328,7 +2328,7 @@ static int mtk_tx_alloc(struct mtk_eth *
-               txd->txd2 = next_ptr;
-               txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
-               txd->txd4 = 0;
--              if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
-+              if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) {
-                       txd->txd5 = 0;
-                       txd->txd6 = 0;
-                       txd->txd7 = 0;
-@@ -2381,7 +2381,7 @@ static int mtk_tx_alloc(struct mtk_eth *
-                             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
-                             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
-                             MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
--                      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-                               val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
-                       mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
-                       ofs += MTK_QTX_OFFSET;
-@@ -2515,7 +2515,7 @@ static int mtk_rx_alloc(struct mtk_eth *
-               rxd->rxd3 = 0;
-               rxd->rxd4 = 0;
--              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-                       rxd->rxd5 = 0;
-                       rxd->rxd6 = 0;
-                       rxd->rxd7 = 0;
-@@ -3063,7 +3063,7 @@ static int mtk_start_dma(struct mtk_eth
-                      MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
-                      MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
--              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-                       val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
-                              MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
-                              MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
-@@ -3475,7 +3475,7 @@ static void mtk_hw_reset(struct mtk_eth
- {
-       u32 val;
--      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-               regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
-               val = RSTCTRL_PPE0_V2;
-       } else {
-@@ -3487,7 +3487,7 @@ static void mtk_hw_reset(struct mtk_eth
-       ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
--      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-               regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
-                            0x3ffffff);
- }
-@@ -3683,7 +3683,7 @@ static int mtk_hw_init(struct mtk_eth *e
-       else
-               mtk_hw_reset(eth);
--      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-               /* Set FE to PDMAv2 if necessary */
-               val = mtk_r32(eth, MTK_FE_GLO_MISC);
-               mtk_w32(eth,  val | BIT(4), MTK_FE_GLO_MISC);
-@@ -3720,7 +3720,7 @@ static int mtk_hw_init(struct mtk_eth *e
-        */
-       val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
-       mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
--      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-               val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-               mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -816,6 +816,7 @@ enum mkt_eth_capabilities {
-       MTK_SHARED_INT_BIT,
-       MTK_TRGMII_MT7621_CLK_BIT,
-       MTK_QDMA_BIT,
-+      MTK_NETSYS_V1_BIT,
-       MTK_NETSYS_V2_BIT,
-       MTK_SOC_MT7628_BIT,
-       MTK_RSTCTRL_PPE1_BIT,
-@@ -851,6 +852,7 @@ enum mkt_eth_capabilities {
- #define MTK_SHARED_INT                BIT(MTK_SHARED_INT_BIT)
- #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
- #define MTK_QDMA              BIT(MTK_QDMA_BIT)
-+#define MTK_NETSYS_V1         BIT(MTK_NETSYS_V1_BIT)
- #define MTK_NETSYS_V2         BIT(MTK_NETSYS_V2_BIT)
- #define MTK_SOC_MT7628                BIT(MTK_SOC_MT7628_BIT)
- #define MTK_RSTCTRL_PPE1      BIT(MTK_RSTCTRL_PPE1_BIT)
-@@ -913,25 +915,30 @@ enum mkt_eth_capabilities {
- #define MTK_HAS_CAPS(caps, _x)                (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x))
--#define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
--                    MTK_GMAC2_RGMII | MTK_SHARED_INT | \
--                    MTK_TRGMII_MT7621_CLK | MTK_QDMA)
--
--#define MT7622_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | MTK_GMAC2_RGMII | \
--                    MTK_GMAC2_SGMII | MTK_GDM1_ESW | \
--                    MTK_MUX_GDM1_TO_GMAC1_ESW | \
--                    MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_QDMA)
--
--#define MT7623_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | MTK_GMAC2_RGMII | \
--                    MTK_QDMA)
--
--#define MT7628_CAPS  (MTK_SHARED_INT | MTK_SOC_MT7628)
--
--#define MT7629_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
--                    MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW | \
--                    MTK_MUX_GMAC2_GMAC0_TO_GEPHY | \
--                    MTK_MUX_U3_GMAC2_TO_QPHY | \
--                    MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
-+#define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII |    \
-+                    MTK_GMAC2_RGMII | MTK_SHARED_INT |        \
-+                    MTK_TRGMII_MT7621_CLK | MTK_QDMA |        \
-+                    MTK_NETSYS_V1)
-+
-+#define MT7622_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII |     \
-+                    MTK_GMAC2_RGMII | MTK_GMAC2_SGMII |       \
-+                    MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW |\
-+                    MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII |      \
-+                    MTK_QDMA | MTK_NETSYS_V1)
-+
-+#define MT7623_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII |    \
-+                    MTK_GMAC2_RGMII | MTK_QDMA |              \
-+                    MTK_NETSYS_V1)
-+
-+#define MT7628_CAPS  (MTK_SHARED_INT | MTK_SOC_MT7628 |               \
-+                    MTK_NETSYS_V1)
-+
-+#define MT7629_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII |     \
-+                    MTK_GMAC2_GEPHY | MTK_GDM1_ESW |          \
-+                    MTK_MUX_GMAC2_GMAC0_TO_GEPHY | MTK_QDMA | \
-+                    MTK_MUX_U3_GMAC2_TO_QPHY | MTK_NETSYS_V1 |\
-+                    MTK_MUX_GDM1_TO_GMAC1_ESW |               \
-+                    MTK_MUX_GMAC12_TO_GEPHY_SGMII)
- #define MT7981_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
-                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
diff --git a/target/linux/generic/pending-5.15/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch b/target/linux/generic/pending-5.15/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch
deleted file mode 100644 (file)
index 837a8bf..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-From 5af2b2dc4d6ba0ff7696e79f18e5b2bf862194eb Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 7 Mar 2023 15:55:24 +0000
-Subject: [PATCH 2/7] net: ethernet: mtk_eth_soc: move MAX_DEVS in mtk_soc_data
-
-This is a preliminary patch to add MT7988 SoC support since it runs 3
-macs instead of 2.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +++++++++++++++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 +++----
- 2 files changed, 36 insertions(+), 9 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3972,7 +3972,10 @@ static void mtk_sgmii_destroy(struct mtk
- {
-       int i;
--      for (i = 0; i < MTK_MAX_DEVS; i++)
-+      if (!eth->sgmii_pcs)
-+              return;
-+
-+      for (i = 0; i < eth->soc->num_devs; i++)
-               mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]);
- }
-@@ -4425,7 +4428,12 @@ static int mtk_sgmii_init(struct mtk_eth
-       u32 flags;
-       int i;
--      for (i = 0; i < MTK_MAX_DEVS; i++) {
-+      eth->sgmii_pcs = devm_kzalloc(eth->dev,
-+                                    sizeof(*eth->sgmii_pcs) *
-+                                    eth->soc->num_devs,
-+                                    GFP_KERNEL);
-+
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i);
-               if (!np)
-                       break;
-@@ -4470,6 +4478,18 @@ static int mtk_probe(struct platform_dev
-       if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
-               eth->ip_align = NET_IP_ALIGN;
-+      eth->netdev = devm_kzalloc(eth->dev,
-+                                 sizeof(*eth->netdev) * eth->soc->num_devs,
-+                                 GFP_KERNEL);
-+      if (!eth->netdev)
-+              return -ENOMEM;
-+
-+      eth->mac = devm_kzalloc(eth->dev,
-+                              sizeof(*eth->mac) * eth->soc->num_devs,
-+                              GFP_KERNEL);
-+      if (!eth->mac)
-+              return -ENOMEM;
-+
-       spin_lock_init(&eth->page_lock);
-       spin_lock_init(&eth->tx_irq_lock);
-       spin_lock_init(&eth->rx_irq_lock);
-@@ -4655,7 +4675,7 @@ static int mtk_probe(struct platform_dev
-                       goto err_free_dev;
-       }
--      for (i = 0; i < MTK_MAX_DEVS; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->netdev[i])
-                       continue;
-@@ -4732,6 +4752,7 @@ static const struct mtk_soc_data mt2701_
-       .hw_features = MTK_HW_FEATURES,
-       .required_clks = MT7623_CLKS_BITMAP,
-       .required_pctl = true,
-+      .num_devs = 2,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-               .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4750,6 +4771,7 @@ static const struct mtk_soc_data mt7621_
-       .required_pctl = false,
-       .offload_version = 1,
-       .hash_offset = 2,
-+      .num_devs = 2,
-       .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-@@ -4771,6 +4793,7 @@ static const struct mtk_soc_data mt7622_
-       .offload_version = 2,
-       .hash_offset = 2,
-       .has_accounting = true,
-+      .num_devs = 2,
-       .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-@@ -4790,6 +4813,7 @@ static const struct mtk_soc_data mt7623_
-       .required_pctl = true,
-       .offload_version = 1,
-       .hash_offset = 2,
-+      .num_devs = 2,
-       .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-@@ -4809,6 +4833,7 @@ static const struct mtk_soc_data mt7629_
-       .required_clks = MT7629_CLKS_BITMAP,
-       .required_pctl = false,
-       .has_accounting = true,
-+      .num_devs = 2,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-               .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4830,6 +4855,7 @@ static const struct mtk_soc_data mt7981_
-       .hash_offset = 4,
-       .foe_entry_size = sizeof(struct mtk_foe_entry),
-       .has_accounting = true,
-+      .num_devs = 2,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma_v2),
-               .rxd_size = sizeof(struct mtk_rx_dma_v2),
-@@ -4849,6 +4875,7 @@ static const struct mtk_soc_data mt7986_
-       .required_pctl = false,
-       .offload_version = 2,
-       .hash_offset = 4,
-+      .num_devs = 2,
-       .foe_entry_size = sizeof(struct mtk_foe_entry),
-       .has_accounting = true,
-       .txrx = {
-@@ -4867,6 +4894,7 @@ static const struct mtk_soc_data rt5350_
-       .hw_features = MTK_HW_FEATURES_MT7628,
-       .required_clks = MT7628_CLKS_BITMAP,
-       .required_pctl = false,
-+      .num_devs = 2,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-               .rxd_size = sizeof(struct mtk_rx_dma),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1018,6 +1018,7 @@ struct mtk_reg_map {
-  * @required_pctl             A bool value to show whether the SoC requires
-  *                            the extra setup for those pins used by GMAC.
-  * @hash_offset                       Flow table hash offset.
-+ * @num_devs                  SoC number of macs.
-  * @foe_entry_size            Foe table entry size.
-  * @has_accounting            Bool indicating support for accounting of
-  *                            offloaded flows.
-@@ -1036,6 +1037,7 @@ struct mtk_soc_data {
-       bool            required_pctl;
-       u8              offload_version;
-       u8              hash_offset;
-+      u8              num_devs;
-       u16             foe_entry_size;
-       netdev_features_t hw_features;
-       bool            has_accounting;
-@@ -1051,9 +1053,6 @@ struct mtk_soc_data {
- #define MTK_DMA_MONITOR_TIMEOUT               msecs_to_jiffies(1000)
--/* currently no SoC has more than 2 macs */
--#define MTK_MAX_DEVS                  2
--
- /* struct mtk_eth -   This is the main datasructure for holding the state
-  *                    of the driver
-  * @dev:              The device pointer
-@@ -1108,14 +1107,14 @@ struct mtk_eth {
-       spinlock_t                      tx_irq_lock;
-       spinlock_t                      rx_irq_lock;
-       struct net_device               dummy_dev;
--      struct net_device               *netdev[MTK_MAX_DEVS];
--      struct mtk_mac                  *mac[MTK_MAX_DEVS];
-+      struct net_device               **netdev;
-+      struct mtk_mac                  **mac;
-       int                             irq[3];
-       u32                             msg_enable;
-       unsigned long                   sysclk;
-       struct regmap                   *ethsys;
-       struct regmap                   *infra;
--      struct phylink_pcs              *sgmii_pcs[MTK_MAX_DEVS];
-+      struct phylink_pcs              **sgmii_pcs;
-       struct regmap                   *pctl;
-       bool                            hwlro;
-       refcount_t                      dma_refcnt;
diff --git a/target/linux/generic/pending-5.15/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch b/target/linux/generic/pending-5.15/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch
deleted file mode 100644 (file)
index b11915e..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-From 4e35e80750b33727e606be9e7ce447bde2e0deb7 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 7 Mar 2023 15:55:35 +0000
-Subject: [PATCH 3/7] net: ethernet: mtk_eth_soc: rely on num_devs and remove
- MTK_MAC_COUNT
-
-Get rid of MTK_MAC_COUNT since it is a duplicated of eth->soc->num_devs.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 ++++++++++-----------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h |  1 -
- 2 files changed, 15 insertions(+), 16 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -900,7 +900,7 @@ static void mtk_stats_update(struct mtk_
- {
-       int i;
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->mac[i] || !eth->mac[i]->hw_stats)
-                       continue;
-               if (spin_trylock(&eth->mac[i]->hw_stats->stats_lock)) {
-@@ -1403,7 +1403,7 @@ static int mtk_queue_stopped(struct mtk_
- {
-       int i;
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->netdev[i])
-                       continue;
-               if (netif_queue_stopped(eth->netdev[i]))
-@@ -1417,7 +1417,7 @@ static void mtk_wake_queue(struct mtk_et
- {
-       int i;
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->netdev[i])
-                       continue;
-               netif_tx_wake_all_queues(eth->netdev[i]);
-@@ -1908,7 +1908,7 @@ static int mtk_poll_rx(struct napi_struc
-                        !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-                       mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
--              if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
-+              if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
-                            !eth->netdev[mac]))
-                       goto release_desc;
-@@ -2937,7 +2937,7 @@ static void mtk_dma_free(struct mtk_eth
-       const struct mtk_soc_data *soc = eth->soc;
-       int i;
--      for (i = 0; i < MTK_MAC_COUNT; i++)
-+      for (i = 0; i < soc->num_devs; i++)
-               if (eth->netdev[i])
-                       netdev_reset_queue(eth->netdev[i]);
-       if (eth->scratch_ring) {
-@@ -3091,7 +3091,7 @@ static void mtk_gdm_config(struct mtk_et
-       if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
-               return;
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
-               /* default setup the forward port to send frame to PDMA */
-@@ -3704,7 +3704,7 @@ static int mtk_hw_init(struct mtk_eth *e
-        * up with the more appropriate value when mtk_mac_config call is being
-        * invoked.
-        */
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               struct net_device *dev = eth->netdev[i];
-               mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
-@@ -3892,7 +3892,7 @@ static void mtk_pending_work(struct work
-       mtk_prepare_for_reset(eth);
-       /* stop all devices to make sure that dma is properly shut down */
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
-                       continue;
-@@ -3908,7 +3908,7 @@ static void mtk_pending_work(struct work
-       mtk_hw_init(eth, true);
-       /* restart DMA and enable IRQs */
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!test_bit(i, &restart))
-                       continue;
-@@ -3936,7 +3936,7 @@ static int mtk_free_dev(struct mtk_eth *
- {
-       int i;
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->netdev[i])
-                       continue;
-               free_netdev(eth->netdev[i]);
-@@ -3955,7 +3955,7 @@ static int mtk_unreg_dev(struct mtk_eth
- {
-       int i;
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               struct mtk_mac *mac;
-               if (!eth->netdev[i])
-                       continue;
-@@ -4259,7 +4259,7 @@ static int mtk_add_mac(struct mtk_eth *e
-       }
-       id = be32_to_cpup(_id);
--      if (id >= MTK_MAC_COUNT) {
-+      if (id >= eth->soc->num_devs) {
-               dev_err(eth->dev, "%d is not a valid mac id\n", id);
-               return -EINVAL;
-       }
-@@ -4400,7 +4400,7 @@ void mtk_eth_set_dma_device(struct mtk_e
-       rtnl_lock();
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               dev = eth->netdev[i];
-               if (!dev || !(dev->flags & IFF_UP))
-@@ -4727,7 +4727,7 @@ static int mtk_remove(struct platform_de
-       int i;
-       /* stop all devices to make sure that dma is properly shut down */
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->netdev[i])
-                       continue;
-               mtk_stop(eth->netdev[i]);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -33,7 +33,6 @@
- #define MTK_TX_DMA_BUF_LEN_V2 0xffff
- #define MTK_QDMA_RING_SIZE    2048
- #define MTK_DMA_SIZE          512
--#define MTK_MAC_COUNT         2
- #define MTK_RX_ETH_HLEN               (VLAN_ETH_HLEN + ETH_FCS_LEN)
- #define MTK_RX_HLEN           (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
- #define MTK_DMA_DUMMY_DESC    0xffffffff
diff --git a/target/linux/generic/pending-5.15/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch b/target/linux/generic/pending-5.15/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch
deleted file mode 100644 (file)
index 54b3fd0..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-From ab817f559d505329d8a413c7d29250f6d87d77a0 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 7 Mar 2023 15:55:47 +0000
-Subject: [PATCH 4/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V3 capability
- bit
-
-Introduce MTK_NETSYS_V3 bit in the device capabilities.
-This is a preliminary patch to introduce support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 115 ++++++++++++++++----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h |  44 +++++++-
- 2 files changed, 134 insertions(+), 25 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -880,17 +880,32 @@ void mtk_stats_update_mac(struct mtk_mac
-                       mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
-               hw_stats->rx_flow_control_packets +=
-                       mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
--              hw_stats->tx_skip +=
--                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
--              hw_stats->tx_collisions +=
--                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
--              hw_stats->tx_bytes +=
--                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
--              stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
--              if (stats)
--                      hw_stats->tx_bytes += (stats << 32);
--              hw_stats->tx_packets +=
--                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
-+
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+                      hw_stats->tx_skip +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs);
-+                      hw_stats->tx_collisions +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs);
-+                      hw_stats->tx_bytes +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs);
-+                      stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs);
-+                      if (stats)
-+                              hw_stats->tx_bytes += (stats << 32);
-+                      hw_stats->tx_packets +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs);
-+              } else {
-+                      hw_stats->tx_skip +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
-+                      hw_stats->tx_collisions +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
-+                      hw_stats->tx_bytes +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
-+                      stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
-+                      if (stats)
-+                              hw_stats->tx_bytes += (stats << 32);
-+                      hw_stats->tx_packets +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
-+              }
-       }
-       u64_stats_update_end(&hw_stats->syncp);
-@@ -1192,7 +1207,10 @@ static void mtk_tx_set_dma_desc_v2(struc
-               data |= TX_DMA_LS0;
-       WRITE_ONCE(desc->txd3, data);
--      data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
-+      if (mac->id == MTK_GMAC3_ID)
-+              data = PSE_GDM3_PORT;
-+      else
-+              data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
-       data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
-       WRITE_ONCE(desc->txd4, data);
-@@ -1203,6 +1221,9 @@ static void mtk_tx_set_dma_desc_v2(struc
-               /* tx checksum offload */
-               if (info->csum)
-                       data |= TX_DMA_CHKSUM_V2;
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
-+                  netdev_uses_dsa(dev))
-+                      data |= TX_DMA_SPTAG_V3;
-       }
-       WRITE_ONCE(desc->txd5, data);
-@@ -1268,8 +1289,13 @@ static int mtk_tx_map(struct sk_buff *sk
-       mtk_tx_set_dma_desc(dev, itxd, &txd_info);
-       itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
--      itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
--                        MTK_TX_FLAGS_FPORT1;
-+      if (mac->id == MTK_GMAC1_ID)
-+              itx_buf->flags |= MTK_TX_FLAGS_FPORT0;
-+      else if (mac->id == MTK_GMAC2_ID)
-+              itx_buf->flags |= MTK_TX_FLAGS_FPORT1;
-+      else
-+              itx_buf->flags |= MTK_TX_FLAGS_FPORT2;
-+
-       setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
-                    k++);
-@@ -1317,8 +1343,13 @@ static int mtk_tx_map(struct sk_buff *sk
-                               memset(tx_buf, 0, sizeof(*tx_buf));
-                       tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
-                       tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
--                      tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
--                                       MTK_TX_FLAGS_FPORT1;
-+
-+                      if (mac->id == MTK_GMAC1_ID)
-+                              tx_buf->flags |= MTK_TX_FLAGS_FPORT0;
-+                      else if (mac->id == MTK_GMAC2_ID)
-+                              tx_buf->flags |= MTK_TX_FLAGS_FPORT1;
-+                      else
-+                              tx_buf->flags |= MTK_TX_FLAGS_FPORT2;
-                       setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
-                                    txd_info.size, k++);
-@@ -1902,11 +1933,24 @@ static int mtk_poll_rx(struct napi_struc
-                       break;
-               /* find out which mac the packet come from. values start at 1 */
--              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
--                      mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
--              else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
--                       !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-+              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-+                      u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
-+
-+                      switch (val) {
-+                      case PSE_GDM1_PORT:
-+                      case PSE_GDM2_PORT:
-+                              mac = val - 1;
-+                              break;
-+                      case PSE_GDM3_PORT:
-+                              mac = MTK_GMAC3_ID;
-+                              break;
-+                      default:
-+                              break;
-+                      }
-+              } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
-+                       !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
-                       mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
-+              }
-               if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
-                            !eth->netdev[mac]))
-@@ -2135,7 +2179,9 @@ static int mtk_poll_tx_qdma(struct mtk_e
-               tx_buf = mtk_desc_to_tx_buf(ring, desc,
-                                           eth->soc->txrx.txd_size);
-               if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
--                      mac = 1;
-+                      mac = MTK_GMAC2_ID;
-+              else if (tx_buf->flags & MTK_TX_FLAGS_FPORT2)
-+                      mac = MTK_GMAC3_ID;
-               if (!tx_buf->data)
-                       break;
-@@ -3742,7 +3788,26 @@ static int mtk_hw_init(struct mtk_eth *e
-       mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
-       mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
--      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+              /* PSE should not drop port1, port8 and port9 packets */
-+              mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
-+
-+              /* GDM and CDM Threshold */
-+              mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
-+              mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
-+
-+              /* Disable GDM1 RX CRC stripping */
-+              val = mtk_r32(eth, MTK_GDMA_FWD_CFG(0));
-+              val &= ~MTK_GDMA_STRP_CRC;
-+              mtk_w32(eth, val, MTK_GDMA_FWD_CFG(0));
-+
-+              /* PSE GDM3 MIB counter has incorrect hw default values,
-+               * so the driver ought to read clear the values beforehand
-+               * in case ethtool retrieve wrong mib values.
-+               */
-+              for (i = 0; i < 0x80; i += 0x4)
-+                      mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i);
-+      } else if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-               /* PSE should not drop port8 and port9 packets from WDMA Tx */
-               mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
-@@ -4307,7 +4372,11 @@ static int mtk_add_mac(struct mtk_eth *e
-       }
-       spin_lock_init(&mac->hw_stats->stats_lock);
-       u64_stats_init(&mac->hw_stats->syncp);
--      mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
-+
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
-+              mac->hw_stats->reg_offset = id * 0x80;
-+      else
-+              mac->hw_stats->reg_offset = id * 0x40;
-       /* phylink create */
-       err = of_get_phy_mode(np, &phy_mode);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -121,6 +121,7 @@
- #define MTK_GDMA_ICS_EN               BIT(22)
- #define MTK_GDMA_TCS_EN               BIT(21)
- #define MTK_GDMA_UCS_EN               BIT(20)
-+#define MTK_GDMA_STRP_CRC     BIT(16)
- #define MTK_GDMA_TO_PDMA      0x0
- #define MTK_GDMA_DROP_ALL       0x7777
-@@ -286,8 +287,6 @@
- /* QDMA Interrupt grouping registers */
- #define MTK_RLS_DONE_INT      BIT(0)
--#define MTK_STAT_OFFSET               0x40
--
- /* QDMA TX NUM */
- #define QID_BITS_V2(x)                (((x) & 0x3f) << 16)
- #define MTK_QDMA_GMAC2_QID    8
-@@ -300,6 +299,8 @@
- #define TX_DMA_CHKSUM_V2      (0x7 << 28)
- #define TX_DMA_TSO_V2         BIT(31)
-+#define TX_DMA_SPTAG_V3         BIT(27)
-+
- /* QDMA V2 descriptor txd4 */
- #define TX_DMA_FPORT_SHIFT_V2 8
- #define TX_DMA_FPORT_MASK_V2  0xf
-@@ -636,6 +637,7 @@ enum mtk_tx_flags {
-        */
-       MTK_TX_FLAGS_FPORT0     = 0x04,
-       MTK_TX_FLAGS_FPORT1     = 0x08,
-+      MTK_TX_FLAGS_FPORT2     = 0x10,
- };
- /* This enum allows us to identify how the clock is defined on the array of the
-@@ -721,6 +723,42 @@ enum mtk_dev_state {
-       MTK_RESETTING
- };
-+/* PSE Port Definition */
-+enum mtk_pse_port {
-+      PSE_ADMA_PORT = 0,
-+      PSE_GDM1_PORT,
-+      PSE_GDM2_PORT,
-+      PSE_PPE0_PORT,
-+      PSE_PPE1_PORT,
-+      PSE_QDMA_TX_PORT,
-+      PSE_QDMA_RX_PORT,
-+      PSE_DROP_PORT,
-+      PSE_WDMA0_PORT,
-+      PSE_WDMA1_PORT,
-+      PSE_TDMA_PORT,
-+      PSE_NONE_PORT,
-+      PSE_PPE2_PORT,
-+      PSE_WDMA2_PORT,
-+      PSE_EIP197_PORT,
-+      PSE_GDM3_PORT,
-+      PSE_PORT_MAX
-+};
-+
-+/* GMAC Identifier */
-+enum mtk_gmac_id {
-+      MTK_GMAC1_ID = 0,
-+      MTK_GMAC2_ID,
-+      MTK_GMAC3_ID,
-+      MTK_GMAC_ID_MAX
-+};
-+
-+/* GDM Type */
-+enum mtk_gdm_type {
-+      MTK_GDM_TYPE = 0,
-+      MTK_XGDM_TYPE,
-+      MTK_GDM_TYPE_MAX
-+};
-+
- enum mtk_tx_buf_type {
-       MTK_TYPE_SKB,
-       MTK_TYPE_XDP_TX,
-@@ -817,6 +855,7 @@ enum mkt_eth_capabilities {
-       MTK_QDMA_BIT,
-       MTK_NETSYS_V1_BIT,
-       MTK_NETSYS_V2_BIT,
-+      MTK_NETSYS_V3_BIT,
-       MTK_SOC_MT7628_BIT,
-       MTK_RSTCTRL_PPE1_BIT,
-       MTK_U3_COPHY_V2_BIT,
-@@ -853,6 +892,7 @@ enum mkt_eth_capabilities {
- #define MTK_QDMA              BIT(MTK_QDMA_BIT)
- #define MTK_NETSYS_V1         BIT(MTK_NETSYS_V1_BIT)
- #define MTK_NETSYS_V2         BIT(MTK_NETSYS_V2_BIT)
-+#define MTK_NETSYS_V3         BIT(MTK_NETSYS_V3_BIT)
- #define MTK_SOC_MT7628                BIT(MTK_SOC_MT7628_BIT)
- #define MTK_RSTCTRL_PPE1      BIT(MTK_RSTCTRL_PPE1_BIT)
- #define MTK_U3_COPHY_V2               BIT(MTK_U3_COPHY_V2_BIT)
diff --git a/target/linux/generic/pending-5.15/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch b/target/linux/generic/pending-5.15/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch
deleted file mode 100644 (file)
index bd26cca..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-From 45b575fd9e6a455090820248bf1b98b1f2c7b6c8 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 7 Mar 2023 15:56:00 +0000
-Subject: [PATCH 5/7] net: ethernet: mtk_eth_soc: convert caps in mtk_soc_data
- struct to u64
-
-This is a preliminary patch to introduce support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 +++----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 62 ++++++++++----------
- 2 files changed, 42 insertions(+), 42 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
-@@ -15,10 +15,10 @@
- struct mtk_eth_muxc {
-       const char      *name;
-       int             cap_bit;
--      int             (*set_path)(struct mtk_eth *eth, int path);
-+      int             (*set_path)(struct mtk_eth *eth, u64 path);
- };
--static const char *mtk_eth_path_name(int path)
-+static const char *mtk_eth_path_name(u64 path)
- {
-       switch (path) {
-       case MTK_ETH_PATH_GMAC1_RGMII:
-@@ -40,7 +40,7 @@ static const char *mtk_eth_path_name(int
-       }
- }
--static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
-+static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
- {
-       bool updated = true;
-       u32 val, mask, set;
-@@ -71,7 +71,7 @@ static int set_mux_gdm1_to_gmac1_esw(str
-       return 0;
- }
--static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
-+static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path)
- {
-       unsigned int val = 0;
-       bool updated = true;
-@@ -94,7 +94,7 @@ static int set_mux_gmac2_gmac0_to_gephy(
-       return 0;
- }
--static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
-+static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
- {
-       unsigned int val = 0, mask = 0, reg = 0;
-       bool updated = true;
-@@ -125,7 +125,7 @@ static int set_mux_u3_gmac2_to_qphy(stru
-       return 0;
- }
--static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
-+static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
- {
-       unsigned int val = 0;
-       bool updated = true;
-@@ -163,7 +163,7 @@ static int set_mux_gmac1_gmac2_to_sgmii_
-       return 0;
- }
--static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
-+static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
- {
-       unsigned int val = 0;
-       bool updated = true;
-@@ -218,7 +218,7 @@ static const struct mtk_eth_muxc mtk_eth
-       },
- };
--static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
-+static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
- {
-       int i, err = 0;
-@@ -249,7 +249,7 @@ out:
- int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
- {
--      int path;
-+      u64 path;
-       path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
-                               MTK_ETH_PATH_GMAC2_SGMII;
-@@ -260,7 +260,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk
- int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
- {
--      int path = 0;
-+      u64 path = 0;
-       if (mac_id == 1)
-               path = MTK_ETH_PATH_GMAC2_GEPHY;
-@@ -274,7 +274,7 @@ int mtk_gmac_gephy_path_setup(struct mtk
- int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
- {
--      int path;
-+      u64 path;
-       path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_RGMII :
-                               MTK_ETH_PATH_GMAC2_RGMII;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -878,44 +878,44 @@ enum mkt_eth_capabilities {
- };
- /* Supported hardware group on SoCs */
--#define MTK_RGMII             BIT(MTK_RGMII_BIT)
--#define MTK_TRGMII            BIT(MTK_TRGMII_BIT)
--#define MTK_SGMII             BIT(MTK_SGMII_BIT)
--#define MTK_ESW                       BIT(MTK_ESW_BIT)
--#define MTK_GEPHY             BIT(MTK_GEPHY_BIT)
--#define MTK_MUX                       BIT(MTK_MUX_BIT)
--#define MTK_INFRA             BIT(MTK_INFRA_BIT)
--#define MTK_SHARED_SGMII      BIT(MTK_SHARED_SGMII_BIT)
--#define MTK_HWLRO             BIT(MTK_HWLRO_BIT)
--#define MTK_SHARED_INT                BIT(MTK_SHARED_INT_BIT)
--#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
--#define MTK_QDMA              BIT(MTK_QDMA_BIT)
--#define MTK_NETSYS_V1         BIT(MTK_NETSYS_V1_BIT)
--#define MTK_NETSYS_V2         BIT(MTK_NETSYS_V2_BIT)
--#define MTK_NETSYS_V3         BIT(MTK_NETSYS_V3_BIT)
--#define MTK_SOC_MT7628                BIT(MTK_SOC_MT7628_BIT)
--#define MTK_RSTCTRL_PPE1      BIT(MTK_RSTCTRL_PPE1_BIT)
--#define MTK_U3_COPHY_V2               BIT(MTK_U3_COPHY_V2_BIT)
-+#define MTK_RGMII             BIT_ULL(MTK_RGMII_BIT)
-+#define MTK_TRGMII            BIT_ULL(MTK_TRGMII_BIT)
-+#define MTK_SGMII             BIT_ULL(MTK_SGMII_BIT)
-+#define MTK_ESW                       BIT_ULL(MTK_ESW_BIT)
-+#define MTK_GEPHY             BIT_ULL(MTK_GEPHY_BIT)
-+#define MTK_MUX                       BIT_ULL(MTK_MUX_BIT)
-+#define MTK_INFRA             BIT_ULL(MTK_INFRA_BIT)
-+#define MTK_SHARED_SGMII      BIT_ULL(MTK_SHARED_SGMII_BIT)
-+#define MTK_HWLRO             BIT_ULL(MTK_HWLRO_BIT)
-+#define MTK_SHARED_INT                BIT_ULL(MTK_SHARED_INT_BIT)
-+#define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT)
-+#define MTK_QDMA              BIT_ULL(MTK_QDMA_BIT)
-+#define MTK_NETSYS_V1         BIT_ULL(MTK_NETSYS_V1_BIT)
-+#define MTK_NETSYS_V2         BIT_ULL(MTK_NETSYS_V2_BIT)
-+#define MTK_NETSYS_V3         BIT_ULL(MTK_NETSYS_V3_BIT)
-+#define MTK_SOC_MT7628                BIT_ULL(MTK_SOC_MT7628_BIT)
-+#define MTK_RSTCTRL_PPE1      BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
-+#define MTK_U3_COPHY_V2               BIT_ULL(MTK_U3_COPHY_V2_BIT)
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
--      BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-+      BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
- #define MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY      \
--      BIT(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
-+      BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
- #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY          \
--      BIT(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
-+      BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
- #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII        \
--      BIT(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
-+      BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
- #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII     \
--      BIT(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
-+      BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
- /* Supported path present on SoCs */
--#define MTK_ETH_PATH_GMAC1_RGMII      BIT(MTK_ETH_PATH_GMAC1_RGMII_BIT)
--#define MTK_ETH_PATH_GMAC1_TRGMII     BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
--#define MTK_ETH_PATH_GMAC1_SGMII      BIT(MTK_ETH_PATH_GMAC1_SGMII_BIT)
--#define MTK_ETH_PATH_GMAC2_RGMII      BIT(MTK_ETH_PATH_GMAC2_RGMII_BIT)
--#define MTK_ETH_PATH_GMAC2_SGMII      BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT)
--#define MTK_ETH_PATH_GMAC2_GEPHY      BIT(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
--#define MTK_ETH_PATH_GDM1_ESW         BIT(MTK_ETH_PATH_GDM1_ESW_BIT)
-+#define MTK_ETH_PATH_GMAC1_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
-+#define MTK_ETH_PATH_GMAC1_TRGMII     BIT_ULL(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
-+#define MTK_ETH_PATH_GMAC1_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_GEPHY      BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
-+#define MTK_ETH_PATH_GDM1_ESW         BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
- #define MTK_GMAC1_RGMII               (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
- #define MTK_GMAC1_TRGMII      (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
-@@ -1071,7 +1071,7 @@ struct mtk_reg_map {
- struct mtk_soc_data {
-       const struct mtk_reg_map *reg_map;
-       u32             ana_rgc3;
--      u32             caps;
-+      u64             caps;
-       u32             required_clks;
-       bool            required_pctl;
-       u8              offload_version;
diff --git a/target/linux/generic/pending-5.15/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch b/target/linux/generic/pending-5.15/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch
deleted file mode 100644 (file)
index e8402c0..0000000
+++ /dev/null
@@ -1,495 +0,0 @@
-From 661bacf4363ca68939c15e20056b5f72fbd034e7 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 25 Feb 2023 00:08:24 +0100
-Subject: [PATCH 6/7] net: ethernet: mtk_eth_soc: add support for MT7988 SoC
-
-Introduce support for ethernet chip available in MT7988 SoC to
-mtk_eth_soc driver.
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 153 ++++++++++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 193 ++++++++++++++------
- 2 files changed, 279 insertions(+), 67 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r
-       .pse_oq_sta             = 0x01a0,
- };
-+static const struct mtk_reg_map mt7988_reg_map = {
-+      .tx_irq_mask            = 0x461c,
-+      .tx_irq_status          = 0x4618,
-+      .pdma = {
-+              .rx_ptr         = 0x6900,
-+              .rx_cnt_cfg     = 0x6904,
-+              .pcrx_ptr       = 0x6908,
-+              .glo_cfg        = 0x6a04,
-+              .rst_idx        = 0x6a08,
-+              .delay_irq      = 0x6a0c,
-+              .irq_status     = 0x6a20,
-+              .irq_mask       = 0x6a28,
-+              .adma_rx_dbg0   = 0x6a38,
-+              .int_grp        = 0x6a50,
-+      },
-+      .qdma = {
-+              .qtx_cfg        = 0x4400,
-+              .qtx_sch        = 0x4404,
-+              .rx_ptr         = 0x4500,
-+              .rx_cnt_cfg     = 0x4504,
-+              .qcrx_ptr       = 0x4508,
-+              .glo_cfg        = 0x4604,
-+              .rst_idx        = 0x4608,
-+              .delay_irq      = 0x460c,
-+              .fc_th          = 0x4610,
-+              .int_grp        = 0x4620,
-+              .hred           = 0x4644,
-+              .ctx_ptr        = 0x4700,
-+              .dtx_ptr        = 0x4704,
-+              .crx_ptr        = 0x4710,
-+              .drx_ptr        = 0x4714,
-+              .fq_head        = 0x4720,
-+              .fq_tail        = 0x4724,
-+              .fq_count       = 0x4728,
-+              .fq_blen        = 0x472c,
-+              .tx_sch_rate    = 0x4798,
-+      },
-+      .gdm1_cnt               = 0x1c00,
-+      .gdma_to_ppe0           = 0x3333,
-+      .ppe_base               = 0x2200,
-+      .wdma_base = {
-+              [0]             = 0x4800,
-+              [1]             = 0x4c00,
-+      },
-+      .pse_iq_sta             = 0x0180,
-+      .pse_oq_sta             = 0x01a0,
-+};
-+
- /* strings used by ethtool */
- static const struct mtk_ethtool_stats {
-       char str[ETH_GSTRING_LEN];
-@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats {
- };
- static const char * const mtk_clks_source_name[] = {
--      "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll",
--      "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb",
--      "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb",
--      "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1"
-+      "ethif",
-+      "sgmiitop",
-+      "esw",
-+      "gp0",
-+      "gp1",
-+      "gp2",
-+      "gp3",
-+      "xgp1",
-+      "xgp2",
-+      "xgp3",
-+      "crypto",
-+      "fe",
-+      "trgpll",
-+      "sgmii_tx250m",
-+      "sgmii_rx250m",
-+      "sgmii_cdr_ref",
-+      "sgmii_cdr_fb",
-+      "sgmii2_tx250m",
-+      "sgmii2_rx250m",
-+      "sgmii2_cdr_ref",
-+      "sgmii2_cdr_fb",
-+      "sgmii_ck",
-+      "eth2pll",
-+      "wocpu0",
-+      "wocpu1",
-+      "netsys0",
-+      "netsys1",
-+      "ethwarp_wocpu2",
-+      "ethwarp_wocpu1",
-+      "ethwarp_wocpu0",
-+      "top_usxgmii0_sel",
-+      "top_usxgmii1_sel",
-+      "top_sgm0_sel",
-+      "top_sgm1_sel",
-+      "top_xfi_phy0_xtal_sel",
-+      "top_xfi_phy1_xtal_sel",
-+      "top_eth_gmii_sel",
-+      "top_eth_refck_50m_sel",
-+      "top_eth_sys_200m_sel",
-+      "top_eth_sys_sel",
-+      "top_eth_xgmii_sel",
-+      "top_eth_mii_sel",
-+      "top_netsys_sel",
-+      "top_netsys_500m_sel",
-+      "top_netsys_pao_2x_sel",
-+      "top_netsys_sync_250m_sel",
-+      "top_netsys_ppefb_250m_sel",
-+      "top_netsys_warp_sel",
- };
- void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
-@@ -1207,10 +1299,19 @@ static void mtk_tx_set_dma_desc_v2(struc
-               data |= TX_DMA_LS0;
-       WRITE_ONCE(desc->txd3, data);
--      if (mac->id == MTK_GMAC3_ID)
--              data = PSE_GDM3_PORT;
--      else
--              data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
-+       /* set forward port */
-+      switch (mac->id) {
-+      case MTK_GMAC1_ID:
-+              data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2;
-+              break;
-+      case MTK_GMAC2_ID:
-+              data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2;
-+              break;
-+      case MTK_GMAC3_ID:
-+              data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2;
-+              break;
-+      }
-+
-       data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
-       WRITE_ONCE(desc->txd4, data);
-@@ -4957,6 +5058,25 @@ static const struct mtk_soc_data mt7986_
-       },
- };
-+static const struct mtk_soc_data mt7988_data = {
-+      .reg_map = &mt7988_reg_map,
-+      .ana_rgc3 = 0x128,
-+      .caps = MT7988_CAPS,
-+      .hw_features = MTK_HW_FEATURES,
-+      .required_clks = MT7988_CLKS_BITMAP,
-+      .required_pctl = false,
-+      .num_devs = 3,
-+      .txrx = {
-+              .txd_size = sizeof(struct mtk_tx_dma_v2),
-+              .rxd_size = sizeof(struct mtk_rx_dma_v2),
-+              .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-+              .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
-+              .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
-+              .dma_len_offset = 8,
-+      },
-+};
-+
-+
- static const struct mtk_soc_data rt5350_data = {
-       .reg_map = &mt7628_reg_map,
-       .caps = MT7628_CAPS,
-@@ -4975,14 +5095,15 @@ static const struct mtk_soc_data rt5350_
- };
- const struct of_device_id of_mtk_match[] = {
--      { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
--      { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
--      { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
--      { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
--      { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
--      { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
--      { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
--      { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
-+      { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data },
-+      { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data },
-+      { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data },
-+      { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data },
-+      { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data },
-+      { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data },
-+      { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data },
-+      { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data },
-+      { .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
-       {},
- };
- MODULE_DEVICE_TABLE(of, of_mtk_match);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -116,7 +116,8 @@
- #define MTK_CDMP_EG_CTRL      0x404
- /* GDM Exgress Control Register */
--#define MTK_GDMA_FWD_CFG(x)   (0x500 + (x * 0x1000))
-+#define MTK_GDMA_FWD_CFG(x)   ((x == MTK_GMAC3_ID) ?          \
-+                               0x540 : 0x500 + (x * 0x1000))
- #define MTK_GDMA_SPECIAL_TAG  BIT(24)
- #define MTK_GDMA_ICS_EN               BIT(22)
- #define MTK_GDMA_TCS_EN               BIT(21)
-@@ -650,6 +651,11 @@ enum mtk_clks_map {
-       MTK_CLK_GP0,
-       MTK_CLK_GP1,
-       MTK_CLK_GP2,
-+      MTK_CLK_GP3,
-+      MTK_CLK_XGP1,
-+      MTK_CLK_XGP2,
-+      MTK_CLK_XGP3,
-+      MTK_CLK_CRYPTO,
-       MTK_CLK_FE,
-       MTK_CLK_TRGPLL,
-       MTK_CLK_SGMII_TX_250M,
-@@ -666,57 +672,108 @@ enum mtk_clks_map {
-       MTK_CLK_WOCPU1,
-       MTK_CLK_NETSYS0,
-       MTK_CLK_NETSYS1,
-+      MTK_CLK_ETHWARP_WOCPU2,
-+      MTK_CLK_ETHWARP_WOCPU1,
-+      MTK_CLK_ETHWARP_WOCPU0,
-+      MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
-+      MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
-+      MTK_CLK_TOP_SGM_0_SEL,
-+      MTK_CLK_TOP_SGM_1_SEL,
-+      MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
-+      MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
-+      MTK_CLK_TOP_ETH_GMII_SEL,
-+      MTK_CLK_TOP_ETH_REFCK_50M_SEL,
-+      MTK_CLK_TOP_ETH_SYS_200M_SEL,
-+      MTK_CLK_TOP_ETH_SYS_SEL,
-+      MTK_CLK_TOP_ETH_XGMII_SEL,
-+      MTK_CLK_TOP_ETH_MII_SEL,
-+      MTK_CLK_TOP_NETSYS_SEL,
-+      MTK_CLK_TOP_NETSYS_500M_SEL,
-+      MTK_CLK_TOP_NETSYS_PAO_2X_SEL,
-+      MTK_CLK_TOP_NETSYS_SYNC_250M_SEL,
-+      MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL,
-+      MTK_CLK_TOP_NETSYS_WARP_SEL,
-       MTK_CLK_MAX
- };
--#define MT7623_CLKS_BITMAP    (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) |  \
--                               BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \
--                               BIT(MTK_CLK_TRGPLL))
--#define MT7622_CLKS_BITMAP    (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) |  \
--                               BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
--                               BIT(MTK_CLK_GP2) | \
--                               BIT(MTK_CLK_SGMII_TX_250M) | \
--                               BIT(MTK_CLK_SGMII_RX_250M) | \
--                               BIT(MTK_CLK_SGMII_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII_CDR_FB) | \
--                               BIT(MTK_CLK_SGMII_CK) | \
--                               BIT(MTK_CLK_ETH2PLL))
-+#define MT7623_CLKS_BITMAP    (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) |  \
-+                               BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
-+                               BIT_ULL(MTK_CLK_TRGPLL))
-+#define MT7622_CLKS_BITMAP    (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) |  \
-+                               BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
-+                               BIT_ULL(MTK_CLK_GP2) | \
-+                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CK) | \
-+                               BIT_ULL(MTK_CLK_ETH2PLL))
- #define MT7621_CLKS_BITMAP    (0)
- #define MT7628_CLKS_BITMAP    (0)
--#define MT7629_CLKS_BITMAP    (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) |  \
--                               BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
--                               BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \
--                               BIT(MTK_CLK_SGMII_TX_250M) | \
--                               BIT(MTK_CLK_SGMII_RX_250M) | \
--                               BIT(MTK_CLK_SGMII_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII_CDR_FB) | \
--                               BIT(MTK_CLK_SGMII2_TX_250M) | \
--                               BIT(MTK_CLK_SGMII2_RX_250M) | \
--                               BIT(MTK_CLK_SGMII2_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII2_CDR_FB) | \
--                               BIT(MTK_CLK_SGMII_CK) | \
--                               BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
--#define MT7981_CLKS_BITMAP    (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
--                               BIT(MTK_CLK_WOCPU0) | \
--                               BIT(MTK_CLK_SGMII_TX_250M) | \
--                               BIT(MTK_CLK_SGMII_RX_250M) | \
--                               BIT(MTK_CLK_SGMII_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII_CDR_FB) | \
--                               BIT(MTK_CLK_SGMII2_TX_250M) | \
--                               BIT(MTK_CLK_SGMII2_RX_250M) | \
--                               BIT(MTK_CLK_SGMII2_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII2_CDR_FB) | \
--                               BIT(MTK_CLK_SGMII_CK))
--#define MT7986_CLKS_BITMAP    (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
--                               BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
--                               BIT(MTK_CLK_SGMII_TX_250M) | \
--                               BIT(MTK_CLK_SGMII_RX_250M) | \
--                               BIT(MTK_CLK_SGMII_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII_CDR_FB) | \
--                               BIT(MTK_CLK_SGMII2_TX_250M) | \
--                               BIT(MTK_CLK_SGMII2_RX_250M) | \
--                               BIT(MTK_CLK_SGMII2_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII2_CDR_FB))
-+#define MT7629_CLKS_BITMAP    (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) |  \
-+                               BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
-+                               BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \
-+                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CK) | \
-+                               BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP))
-+#define MT7981_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \
-+                               BIT_ULL(MTK_CLK_WOCPU0) | \
-+                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CK))
-+#define MT7986_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \
-+                               BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \
-+                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
-+#define MT7988_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \
-+                               BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
-+                               BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
-+                               BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
-+                               BIT_ULL(MTK_CLK_CRYPTO) | \
-+                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
-+                               BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
-+                               BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
-+                               BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL))
- enum mtk_dev_state {
-       MTK_HW_INIT,
-@@ -844,6 +901,7 @@ enum mkt_eth_capabilities {
-       MTK_RGMII_BIT = 0,
-       MTK_TRGMII_BIT,
-       MTK_SGMII_BIT,
-+      MTK_USXGMII_BIT,
-       MTK_ESW_BIT,
-       MTK_GEPHY_BIT,
-       MTK_MUX_BIT,
-@@ -866,6 +924,8 @@ enum mkt_eth_capabilities {
-       MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
-       MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
-       MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
-+      MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
-+      MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
-       /* PATH BITS */
-       MTK_ETH_PATH_GMAC1_RGMII_BIT,
-@@ -874,13 +934,18 @@ enum mkt_eth_capabilities {
-       MTK_ETH_PATH_GMAC2_RGMII_BIT,
-       MTK_ETH_PATH_GMAC2_SGMII_BIT,
-       MTK_ETH_PATH_GMAC2_GEPHY_BIT,
-+      MTK_ETH_PATH_GMAC3_SGMII_BIT,
-       MTK_ETH_PATH_GDM1_ESW_BIT,
-+      MTK_ETH_PATH_GMAC1_USXGMII_BIT,
-+      MTK_ETH_PATH_GMAC2_USXGMII_BIT,
-+      MTK_ETH_PATH_GMAC3_USXGMII_BIT,
- };
- /* Supported hardware group on SoCs */
- #define MTK_RGMII             BIT_ULL(MTK_RGMII_BIT)
- #define MTK_TRGMII            BIT_ULL(MTK_TRGMII_BIT)
- #define MTK_SGMII             BIT_ULL(MTK_SGMII_BIT)
-+#define MTK_USXGMII           BIT_ULL(MTK_USXGMII_BIT)
- #define MTK_ESW                       BIT_ULL(MTK_ESW_BIT)
- #define MTK_GEPHY             BIT_ULL(MTK_GEPHY_BIT)
- #define MTK_MUX                       BIT_ULL(MTK_MUX_BIT)
-@@ -907,6 +972,10 @@ enum mkt_eth_capabilities {
-       BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
- #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII     \
-       BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
-+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII    \
-+      BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT)
-+#define MTK_ETH_MUX_GMAC123_TO_USXGMII        \
-+      BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
- /* Supported path present on SoCs */
- #define MTK_ETH_PATH_GMAC1_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
-@@ -915,7 +984,11 @@ enum mkt_eth_capabilities {
- #define MTK_ETH_PATH_GMAC2_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
- #define MTK_ETH_PATH_GMAC2_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
- #define MTK_ETH_PATH_GMAC2_GEPHY      BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
-+#define MTK_ETH_PATH_GMAC3_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
- #define MTK_ETH_PATH_GDM1_ESW         BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
-+#define MTK_ETH_PATH_GMAC1_USXGMII    BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_USXGMII    BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
-+#define MTK_ETH_PATH_GMAC3_USXGMII    BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
- #define MTK_GMAC1_RGMII               (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
- #define MTK_GMAC1_TRGMII      (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
-@@ -923,7 +996,11 @@ enum mkt_eth_capabilities {
- #define MTK_GMAC2_RGMII               (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
- #define MTK_GMAC2_SGMII               (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
- #define MTK_GMAC2_GEPHY               (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
-+#define MTK_GMAC3_SGMII               (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
- #define MTK_GDM1_ESW          (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
-+#define MTK_GMAC1_USXGMII     (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
-+#define MTK_GMAC2_USXGMII     (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
-+#define MTK_GMAC3_USXGMII     (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
- /* MUXes present on SoCs */
- /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
-@@ -946,6 +1023,12 @@ enum mkt_eth_capabilities {
- #define MTK_MUX_GMAC12_TO_GEPHY_SGMII   \
-       (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
-+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII   \
-+      (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX)
-+
-+#define MTK_MUX_GMAC123_TO_USXGMII   \
-+      (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
-+
- #ifdef CONFIG_SOC_MT7621
- #define MTK_CAP_MASK MTK_NETSYS_V2
- #else
-@@ -984,9 +1067,17 @@ enum mkt_eth_capabilities {
-                     MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
-                     MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
--#define MT7986_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
--                    MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
--                    MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-+#define MT7986_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII |     \
-+                    MTK_MUX_GMAC12_TO_GEPHY_SGMII |           \
-+                    MTK_QDMA | MTK_NETSYS_V2 |                \
-+                    MTK_RSTCTRL_PPE1)
-+
-+#define MT7988_CAPS   (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII |    \
-+                     MTK_GMAC3_SGMII | MTK_QDMA |             \
-+                     MTK_MUX_GMAC123_TO_GEPHY_SGMII |         \
-+                     MTK_NETSYS_V3 | MTK_RSTCTRL_PPE1 |       \
-+                     MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII |  \
-+                     MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII)
- struct mtk_tx_dma_desc_info {
-       dma_addr_t      addr;
-@@ -1072,7 +1163,7 @@ struct mtk_soc_data {
-       const struct mtk_reg_map *reg_map;
-       u32             ana_rgc3;
-       u64             caps;
--      u32             required_clks;
-+      u64             required_clks;
-       bool            required_pctl;
-       u8              offload_version;
-       u8              hash_offset;
diff --git a/target/linux/generic/pending-5.15/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-5.15/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
deleted file mode 100644 (file)
index 4518bcb..0000000
+++ /dev/null
@@ -1,1867 +0,0 @@
-From 3d833ad2cfc1ab503d9aae2967b7f10811bb3c9c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 1 Mar 2023 11:56:04 +0000
-Subject: [PATCH 7/7] net: ethernet: mtk_eth_soc: add paths and SerDes modes 
- for MT7988
-
-MT7988 comes with a built-in 2.5G PHY as well as
-USXGMII/10GBase-KR/5GBase-KR compatible SerDes lanes for external PHYs.
-Add support for configuring the MAC and SerDes parts for the new paths.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/Kconfig        |   7 +
- drivers/net/ethernet/mediatek/Makefile       |   1 +
- drivers/net/ethernet/mediatek/mtk_eth_path.c | 154 +++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c  | 270 +++++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 194 ++++-
- drivers/net/ethernet/mediatek/mtk_usxgmii.c  | 835 +++++++++++++++++++
- 6 files changed, 1428 insertions(+), 33 deletions(-)
- create mode 100644 drivers/net/ethernet/mediatek/mtk_usxgmii.c
-
---- a/drivers/net/ethernet/mediatek/Kconfig
-+++ b/drivers/net/ethernet/mediatek/Kconfig
-@@ -24,6 +24,13 @@ config NET_MEDIATEK_SOC
-         This driver supports the gigabit ethernet MACs in the
-         MediaTek SoC family.
-+config NET_MEDIATEK_SOC_USXGMII
-+      bool "Support USXGMII SerDes on MT7988"
-+      depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
-+      def_bool NET_MEDIATEK_SOC != n
-+      help
-+        Include support for 10G SerDes which can be found on MT7988.
-+
- config NET_MEDIATEK_STAR_EMAC
-       tristate "MediaTek STAR Ethernet MAC support"
-       select PHYLIB
---- a/drivers/net/ethernet/mediatek/Makefile
-+++ b/drivers/net/ethernet/mediatek/Makefile
-@@ -5,6 +5,7 @@
- obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
- mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
-+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_USXGMII) += mtk_usxgmii.o
- mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o
- ifdef CONFIG_DEBUG_FS
- mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
-@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64
-               return "gmac2_rgmii";
-       case MTK_ETH_PATH_GMAC2_SGMII:
-               return "gmac2_sgmii";
-+      case MTK_ETH_PATH_GMAC2_2P5GPHY:
-+              return "gmac2_2p5gphy";
-       case MTK_ETH_PATH_GMAC2_GEPHY:
-               return "gmac2_gephy";
-+      case MTK_ETH_PATH_GMAC3_SGMII:
-+              return "gmac3_sgmii";
-       case MTK_ETH_PATH_GDM1_ESW:
-               return "gdm1_esw";
-+      case MTK_ETH_PATH_GMAC1_USXGMII:
-+              return "gmac1_usxgmii";
-+      case MTK_ETH_PATH_GMAC2_USXGMII:
-+              return "gmac2_usxgmii";
-+      case MTK_ETH_PATH_GMAC3_USXGMII:
-+              return "gmac3_usxgmii";
-       default:
-               return "unknown path";
-       }
-@@ -42,8 +52,8 @@ static const char *mtk_eth_path_name(u64
- static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
- {
-+      u32 val, mask, set, reg;
-       bool updated = true;
--      u32 val, mask, set;
-       switch (path) {
-       case MTK_ETH_PATH_GMAC1_SGMII:
-@@ -59,10 +69,15 @@ static int set_mux_gdm1_to_gmac1_esw(str
-               break;
-       }
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
-+              reg = MTK_MAC_MISC_V3;
-+      else
-+              reg = MTK_MAC_MISC;
-+
-       if (updated) {
--              val = mtk_r32(eth, MTK_MAC_MISC);
-+              val = mtk_r32(eth, reg);
-               val = (val & mask) | set;
--              mtk_w32(eth, val, MTK_MAC_MISC);
-+              mtk_w32(eth, val, reg);
-       }
-       dev_dbg(eth->dev, "path %s in %s updated = %d\n",
-@@ -125,6 +140,31 @@ static int set_mux_u3_gmac2_to_qphy(stru
-       return 0;
- }
-+static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path)
-+{
-+      unsigned int val = 0;
-+      bool updated = true;
-+      int mac_id = 0;
-+
-+      regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
-+
-+      switch (path) {
-+      case MTK_ETH_PATH_GMAC2_2P5GPHY:
-+              val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
-+              mac_id = MTK_GMAC2_ID;
-+              break;
-+      default:
-+              updated = false;
-+              break;
-+      };
-+
-+      if (updated)
-+              regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
-+                                 SYSCFG0_SGMII_MASK, val);
-+
-+      return 0;
-+}
-+
- static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
- {
-       unsigned int val = 0;
-@@ -163,7 +203,61 @@ static int set_mux_gmac1_gmac2_to_sgmii_
-       return 0;
- }
--static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
-+static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path)
-+{
-+      unsigned int val = 0;
-+      bool updated = true;
-+      int mac_id = 0;
-+
-+      dev_dbg(eth->dev, "path %s in %s updated = %d\n",
-+              mtk_eth_path_name(path), __func__, updated);
-+
-+      /* Disable SYSCFG1 SGMII */
-+      regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
-+
-+      switch (path) {
-+      case MTK_ETH_PATH_GMAC1_USXGMII:
-+              val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2;
-+              mac_id = MTK_GMAC1_ID;
-+              break;
-+      case MTK_ETH_PATH_GMAC2_USXGMII:
-+              val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
-+              mac_id = MTK_GMAC2_ID;
-+              break;
-+      case MTK_ETH_PATH_GMAC3_USXGMII:
-+              val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2;
-+              mac_id = MTK_GMAC3_ID;
-+              break;
-+      default:
-+              updated = false;
-+      };
-+
-+      if (updated) {
-+              regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
-+                                 SYSCFG0_SGMII_MASK, val);
-+
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
-+                  mac_id == MTK_GMAC2_ID) {
-+                      regmap_update_bits(eth->infra,
-+                                         TOP_MISC_NETSYS_PCS_MUX,
-+                                         NETSYS_PCS_MUX_MASK,
-+                                         MUX_G2_USXGMII_SEL);
-+              }
-+      }
-+
-+      /* Enable XGDM Path */
-+      val = mtk_r32(eth, MTK_GDMA_EG_CTRL(mac_id));
-+      val |= MTK_GDMA_XGDM_SEL;
-+      mtk_w32(eth, val, MTK_GDMA_EG_CTRL(mac_id));
-+
-+      dev_dbg(eth->dev, "path %s in %s updated = %d\n",
-+              mtk_eth_path_name(path), __func__, updated);
-+
-+
-+      return 0;
-+}
-+
-+static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
- {
-       unsigned int val = 0;
-       bool updated = true;
-@@ -180,6 +274,9 @@ static int set_mux_gmac12_to_gephy_sgmii
-       case MTK_ETH_PATH_GMAC2_SGMII:
-               val |= SYSCFG0_SGMII_GMAC2_V2;
-               break;
-+      case MTK_ETH_PATH_GMAC3_SGMII:
-+              val |= SYSCFG0_SGMII_GMAC3_V2;
-+              break;
-       default:
-               updated = false;
-       }
-@@ -208,13 +305,25 @@ static const struct mtk_eth_muxc mtk_eth
-               .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
-               .set_path = set_mux_u3_gmac2_to_qphy,
-       }, {
-+              .name = "mux_gmac2_to_2p5gphy",
-+              .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY,
-+              .set_path = set_mux_gmac2_to_2p5gphy,
-+      }, {
-               .name = "mux_gmac1_gmac2_to_sgmii_rgmii",
-               .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
-               .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii,
-       }, {
-               .name = "mux_gmac12_to_gephy_sgmii",
-               .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
--              .set_path = set_mux_gmac12_to_gephy_sgmii,
-+              .set_path = set_mux_gmac123_to_gephy_sgmii,
-+      }, {
-+              .name = "mux_gmac123_to_gephy_sgmii",
-+              .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII,
-+              .set_path = set_mux_gmac123_to_gephy_sgmii,
-+      }, {
-+              .name = "mux_gmac123_to_usxgmii",
-+              .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII,
-+              .set_path = set_mux_gmac123_to_usxgmii,
-       },
- };
-@@ -243,16 +352,46 @@ static int mtk_eth_mux_setup(struct mtk_
-               }
-       }
-+      dev_dbg(eth->dev, "leaving mux_setup %s\n",
-+              mtk_eth_path_name(path));
-+
- out:
-       return err;
- }
-+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id)
-+{
-+      u64 path;
-+
-+      path = (mac_id == MTK_GMAC1_ID) ?  MTK_ETH_PATH_GMAC1_USXGMII :
-+             (mac_id == MTK_GMAC2_ID) ?  MTK_ETH_PATH_GMAC2_USXGMII :
-+                                         MTK_ETH_PATH_GMAC3_USXGMII;
-+
-+      /* Setup proper MUXes along the path */
-+      return mtk_eth_mux_setup(eth, path);
-+}
-+
- int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
- {
-       u64 path;
--      path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
--                              MTK_ETH_PATH_GMAC2_SGMII;
-+      path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII :
-+             (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII :
-+                                        MTK_ETH_PATH_GMAC3_SGMII;
-+
-+      /* Setup proper MUXes along the path */
-+      return mtk_eth_mux_setup(eth, path);
-+}
-+
-+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id)
-+{
-+      u64 path = 0;
-+
-+      if (mac_id == MTK_GMAC2_ID)
-+              path = MTK_ETH_PATH_GMAC2_2P5GPHY;
-+
-+      if (!path)
-+              return -EINVAL;
-       /* Setup proper MUXes along the path */
-       return mtk_eth_mux_setup(eth, path);
-@@ -282,4 +421,3 @@ int mtk_gmac_rgmii_path_setup(struct mtk
-       /* Setup proper MUXes along the path */
-       return mtk_eth_mux_setup(eth, path);
- }
--
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -437,6 +437,23 @@ static void mtk_gmac0_rgmii_adjust(struc
-       mtk_w32(eth, val, TRGMII_TCK_CTRL);
- }
-+static void mtk_setup_bridge_switch(struct mtk_eth *eth)
-+{
-+      int val;
-+
-+      /* Force Port1 XGMAC Link Up */
-+      val = mtk_r32(eth, MTK_XGMAC_STS(MTK_GMAC1_ID));
-+      mtk_w32(eth, val | MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID),
-+              MTK_XGMAC_STS(MTK_GMAC1_ID));
-+
-+      /* Adjust GSW bridge IPG to 11*/
-+      val = mtk_r32(eth, MTK_GSW_CFG);
-+      val &= ~(GSWTX_IPG_MASK | GSWRX_IPG_MASK);
-+      val |= (GSW_IPG_11 << GSWTX_IPG_SHIFT) |
-+             (GSW_IPG_11 << GSWRX_IPG_SHIFT);
-+      mtk_w32(eth, val, MTK_GSW_CFG);
-+}
-+
- static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
-                                             phy_interface_t interface)
- {
-@@ -451,6 +468,12 @@ static struct phylink_pcs *mtk_mac_selec
-                      0 : mac->id;
-               return eth->sgmii_pcs[sid];
-+      } else if ((interface == PHY_INTERFACE_MODE_USXGMII ||
-+                  interface == PHY_INTERFACE_MODE_10GKR ||
-+                  interface == PHY_INTERFACE_MODE_5GBASER) &&
-+                 MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
-+                 mac->id != MTK_GMAC1_ID) {
-+                      return mtk_usxgmii_select_pcs(eth, mac->id);
-       }
-       return NULL;
-@@ -462,7 +485,7 @@ static void mtk_mac_config(struct phylin
-       struct mtk_mac *mac = container_of(config, struct mtk_mac,
-                                          phylink_config);
-       struct mtk_eth *eth = mac->hw;
--      int val, ge_mode, err = 0;
-+      int val, ge_mode, force_link, err = 0;
-       u32 i;
-       /* MT76x8 has no hardware settings between for the MAC */
-@@ -506,6 +529,23 @@ static void mtk_mac_config(struct phylin
-                                       goto init_err;
-                       }
-                       break;
-+              case PHY_INTERFACE_MODE_USXGMII:
-+              case PHY_INTERFACE_MODE_10GKR:
-+              case PHY_INTERFACE_MODE_5GBASER:
-+                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
-+                              err = mtk_gmac_usxgmii_path_setup(eth, mac->id);
-+                              if (err)
-+                                      goto init_err;
-+                      }
-+                      break;
-+              case PHY_INTERFACE_MODE_INTERNAL:
-+                      if (mac->id == MTK_GMAC2_ID &&
-+                          MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) {
-+                              err = mtk_gmac_2p5gphy_path_setup(eth, mac->id);
-+                              if (err)
-+                                      goto init_err;
-+                      }
-+                      break;
-               default:
-                       goto err_phy;
-               }
-@@ -584,14 +624,78 @@ static void mtk_mac_config(struct phylin
-                                  SYSCFG0_SGMII_MASK,
-                                  ~(u32)SYSCFG0_SGMII_MASK);
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+                      mtk_xfi_pll_enable(eth);
-+                      mtk_sgmii_reset(eth, mac->id);
-+                      if (phylink_autoneg_inband(mode))
-+                              mtk_sgmii_setup_phya_gen1(eth, mac->id);
-+                      else
-+                              mtk_sgmii_setup_phya_gen2(eth, mac->id);
-+              }
-               /* Save the syscfg0 value for mac_finish */
-               mac->syscfg0 = val;
--      } else if (phylink_autoneg_inband(mode)) {
-+      } else if (state->interface != PHY_INTERFACE_MODE_USXGMII &&
-+                 state->interface != PHY_INTERFACE_MODE_10GKR &&
-+                 state->interface != PHY_INTERFACE_MODE_5GBASER &&
-+                 phylink_autoneg_inband(mode)) {
-               dev_err(eth->dev,
--                      "In-band mode not supported in non SGMII mode!\n");
-+                      "In-band mode not supported in non-SerDes modes!\n");
-               return;
-       }
-+      /* Setup gmac */
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
-+          (mtk_interface_mode_is_xgmii(state->interface) ||
-+           mac->interface == PHY_INTERFACE_MODE_INTERNAL)) {
-+              mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
-+              mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
-+
-+              switch (mac->id) {
-+              case MTK_GMAC1_ID:
-+                      mtk_setup_bridge_switch(eth);
-+                      break;
-+              case MTK_GMAC2_ID:
-+                      force_link = (mac->interface ==
-+                                    PHY_INTERFACE_MODE_INTERNAL) ?
-+                                    MTK_XGMAC_FORCE_LINK(mac->id) : 0;
-+                      val = mtk_r32(eth, MTK_XGMAC_STS(mac->id));
-+                      mtk_w32(eth, val | force_link,
-+                              MTK_XGMAC_STS(mac->id));
-+                      break;
-+              case MTK_GMAC3_ID:
-+                      val = mtk_r32(eth, MTK_XGMAC_STS(mac->id));
-+                      mtk_w32(eth, val | MTK_XGMAC_FORCE_LINK(mac->id),
-+                              MTK_XGMAC_STS(mac->id));
-+                      break;
-+              }
-+      } else {
-+              val = mtk_r32(eth, MTK_GDMA_EG_CTRL(mac->id));
-+              mtk_w32(eth, val & ~MTK_GDMA_XGDM_SEL,
-+                      MTK_GDMA_EG_CTRL(mac->id));
-+
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+                      switch (mac->id) {
-+                      case MTK_GMAC2_ID:
-+                      case MTK_GMAC3_ID:
-+                              val = mtk_r32(eth, MTK_XGMAC_STS(mac->id));
-+                              mtk_w32(eth,
-+                                      val & ~MTK_XGMAC_FORCE_LINK(mac->id),
-+                                      MTK_XGMAC_STS(mac->id));
-+                              break;
-+                      }
-+              }
-+
-+/*
-+              if (mac->type != mac_type) {
-+                      if (atomic_read(&reset_pending) == 0) {
-+                              atomic_inc(&force);
-+                              schedule_work(&eth->pending_work);
-+                              atomic_inc(&reset_pending);
-+                      } else
-+                              atomic_dec(&reset_pending);
-+              }
-+*/
-+      }
-       return;
- err_phy:
-@@ -632,11 +736,40 @@ static int mtk_mac_finish(struct phylink
-       return 0;
- }
--static void mtk_mac_pcs_get_state(struct phylink_config *config,
-+static void mtk_xgdm_pcs_get_state(struct mtk_mac *mac,
-+                                struct phylink_link_state *state)
-+{
-+      u32 sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
-+
-+      if (mac->id == MTK_GMAC2_ID)
-+              sts = sts >> 16;
-+
-+      state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, sts);
-+      if (!state->link)
-+              return;
-+
-+      state->duplex = DUPLEX_FULL;
-+      state->interface = mac->interface;
-+
-+      switch (FIELD_GET(MTK_USXGMII_PCS_MODE, sts)) {
-+      case 0:
-+              state->speed = SPEED_10000;
-+              break;
-+      case 1:
-+              state->speed = SPEED_5000;
-+              break;
-+      case 2:
-+              state->speed = SPEED_2500;
-+              break;
-+      case 3:
-+              state->speed = SPEED_1000;
-+              break;
-+      }
-+}
-+
-+static void mtk_gdm_pcs_get_state(struct mtk_mac *mac,
-                                 struct phylink_link_state *state)
- {
--      struct mtk_mac *mac = container_of(config, struct mtk_mac,
--                                         phylink_config);
-       u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id));
-       state->link = (pmsr & MAC_MSR_LINK);
-@@ -664,15 +797,35 @@ static void mtk_mac_pcs_get_state(struct
-               state->pause |= MLO_PAUSE_TX;
- }
-+static void mtk_mac_pcs_get_state(struct phylink_config *config,
-+                                struct phylink_link_state *state)
-+{
-+      struct mtk_mac *mac = container_of(config, struct mtk_mac,
-+                                         phylink_config);
-+
-+      if (mtk_interface_mode_is_xgmii(state->interface))
-+              mtk_xgdm_pcs_get_state(mac, state);
-+      else
-+              mtk_gdm_pcs_get_state(mac, state);
-+}
-+
- static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
-                             phy_interface_t interface)
- {
-       struct mtk_mac *mac = container_of(config, struct mtk_mac,
-                                          phylink_config);
--      u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-+      u32 mcr;
--      mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
--      mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
-+      if (!mtk_interface_mode_is_xgmii(interface)) {
-+              mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-+              mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
-+              mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
-+      } else if (mac->id != MTK_GMAC1_ID) {
-+              mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
-+              mcr &= 0xfffffff0;
-+              mcr |= XMAC_MCR_TRX_DISABLE;
-+              mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
-+      }
- }
- static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
-@@ -744,13 +897,11 @@ static void mtk_set_queue_speed(struct m
-       mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
- }
--static void mtk_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)
-+static void mtk_gdm_mac_link_up(struct mtk_mac *mac,
-+                              struct phy_device *phy,
-+                              unsigned int mode, phy_interface_t interface,
-+                              int speed, int duplex, bool tx_pause, bool rx_pause)
- {
--      struct mtk_mac *mac = container_of(config, struct mtk_mac,
--                                         phylink_config);
-       u32 mcr;
-       mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-@@ -784,6 +935,47 @@ static void mtk_mac_link_up(struct phyli
-       mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
- }
-+static void mtk_xgdm_mac_link_up(struct mtk_mac *mac,
-+                               struct phy_device *phy,
-+                               unsigned int mode, phy_interface_t interface,
-+                               int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+      u32 mcr;
-+
-+      if (mac->id == MTK_GMAC1_ID)
-+              return;
-+
-+      mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
-+
-+      mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC);
-+      /* Configure pause modes -
-+       * phylink will avoid these for half duplex
-+       */
-+      if (tx_pause)
-+              mcr |= XMAC_MCR_FORCE_TX_FC;
-+      if (rx_pause)
-+              mcr |= XMAC_MCR_FORCE_RX_FC;
-+
-+      mcr &= ~(XMAC_MCR_TRX_DISABLE);
-+      mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
-+}
-+
-+static void mtk_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)
-+{
-+      struct mtk_mac *mac = container_of(config, struct mtk_mac,
-+                                         phylink_config);
-+
-+      if (mtk_interface_mode_is_xgmii(interface))
-+              mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
-+                                   tx_pause, rx_pause);
-+      else
-+              mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
-+                                  tx_pause, rx_pause);
-+}
-+
- static const struct phylink_mac_ops mtk_phylink_ops = {
-       .validate = phylink_generic_validate,
-       .mac_select_pcs = mtk_mac_select_pcs,
-@@ -836,10 +1028,21 @@ static int mtk_mdio_init(struct mtk_eth
-       }
-       divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
-+      /* Configure MDC Turbo Mode */
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+              val = mtk_r32(eth, MTK_MAC_MISC_V3);
-+              val |= MISC_MDC_TURBO;
-+              mtk_w32(eth, val, MTK_MAC_MISC_V3);
-+      } else {
-+              val = mtk_r32(eth, MTK_PPSC);
-+              val |= PPSC_MDC_TURBO;
-+              mtk_w32(eth, val, MTK_PPSC);
-+      }
-+
-       /* Configure MDC Divider */
-       val = mtk_r32(eth, MTK_PPSC);
-       val &= ~PPSC_MDC_CFG;
--      val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO;
-+      val |= FIELD_PREP(PPSC_MDC_CFG, divider);
-       mtk_w32(eth, val, MTK_PPSC);
-       dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
-@@ -4415,8 +4618,8 @@ static int mtk_add_mac(struct mtk_eth *e
-       const __be32 *_id = of_get_property(np, "reg", NULL);
-       phy_interface_t phy_mode;
-       struct phylink *phylink;
--      struct mtk_mac *mac;
-       int id, err;
-+      struct mtk_mac *mac;
-       int txqs = 1;
-       if (!_id) {
-@@ -4518,6 +4721,32 @@ static int mtk_add_mac(struct mtk_eth *e
-                         mac->phylink_config.supported_interfaces);
-       }
-+      if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) {
-+              if (id == MTK_GMAC1_ID) {
-+                      mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE |
-+                                                             MAC_SYM_PAUSE |
-+                                                             MAC_10000FD;
-+                      phy_interface_zero(
-+                              mac->phylink_config.supported_interfaces);
-+                      __set_bit(PHY_INTERFACE_MODE_INTERNAL,
-+                                mac->phylink_config.supported_interfaces);
-+              } else {
-+                      mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD;
-+                      __set_bit(PHY_INTERFACE_MODE_5GBASER,
-+                                mac->phylink_config.supported_interfaces);
-+                      __set_bit(PHY_INTERFACE_MODE_10GKR,
-+                                mac->phylink_config.supported_interfaces);
-+                      __set_bit(PHY_INTERFACE_MODE_USXGMII,
-+                                mac->phylink_config.supported_interfaces);
-+              }
-+      }
-+
-+      if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY)) {
-+              if (id == MTK_GMAC2_ID)
-+                      __set_bit(PHY_INTERFACE_MODE_INTERNAL,
-+                                mac->phylink_config.supported_interfaces);
-+      }
-+
-       phylink = phylink_create(&mac->phylink_config,
-                                of_fwnode_handle(mac->of_node),
-                                phy_mode, &mtk_phylink_ops);
-@@ -4705,6 +4934,13 @@ static int mtk_probe(struct platform_dev
-               if (err)
-                       return err;
-+      }
-+
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
-+              err = mtk_usxgmii_init(eth);
-+
-+              if (err)
-+                      return err;
-       }
-       if (eth->soc->required_pctl) {
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -126,6 +126,11 @@
- #define MTK_GDMA_TO_PDMA      0x0
- #define MTK_GDMA_DROP_ALL       0x7777
-+/* GDM Egress Control Register */
-+#define MTK_GDMA_EG_CTRL(x)   ((x == MTK_GMAC3_ID) ?          \
-+                               0x544 : 0x504 + (x * 0x1000))
-+#define MTK_GDMA_XGDM_SEL     BIT(31)
-+
- /* Unicast Filter MAC Address Register - Low */
- #define MTK_GDMA_MAC_ADRL(x)  (0x508 + (x * 0x1000))
-@@ -386,7 +391,26 @@
- #define PHY_IAC_TIMEOUT               HZ
- #define MTK_MAC_MISC          0x1000c
-+#define MTK_MAC_MISC_V3               0x10010
- #define MTK_MUX_TO_ESW                BIT(0)
-+#define MISC_MDC_TURBO                BIT(4)
-+
-+/* XMAC status registers */
-+#define MTK_XGMAC_STS(x)      ((x == MTK_GMAC3_ID) ? 0x1001C : 0x1000C)
-+#define MTK_XGMAC_FORCE_LINK(x)       ((x == MTK_GMAC2_ID) ? BIT(31) : BIT(15))
-+#define MTK_USXGMII_PCS_LINK  BIT(8)
-+#define MTK_XGMAC_RX_FC               BIT(5)
-+#define MTK_XGMAC_TX_FC               BIT(4)
-+#define MTK_USXGMII_PCS_MODE  GENMASK(3, 1)
-+#define MTK_XGMAC_LINK_STS    BIT(0)
-+
-+/* GSW bridge registers */
-+#define MTK_GSW_CFG           (0x10080)
-+#define GSWTX_IPG_MASK                GENMASK(19, 16)
-+#define GSWTX_IPG_SHIFT               16
-+#define GSWRX_IPG_MASK                GENMASK(3, 0)
-+#define GSWRX_IPG_SHIFT               0
-+#define GSW_IPG_11            11
- /* Mac control registers */
- #define MTK_MAC_MCR(x)                (0x10100 + (x * 0x100))
-@@ -411,6 +435,17 @@
- #define MAC_MCR_FORCE_LINK    BIT(0)
- #define MAC_MCR_FORCE_LINK_DOWN       (MAC_MCR_FORCE_MODE)
-+/* Mac EEE control registers */
-+#define MTK_MAC_EEE(x)                (0x10104 + (x * 0x100))
-+#define MAC_EEE_WAKEUP_TIME_1000      GENMASK(31, 24)
-+#define MAC_EEE_WAKEUP_TIME_100       GENMASK(23, 16)
-+#define MAC_EEE_LPI_TXIDLE_THD        GENMASK(15, 8)
-+#define MAC_EEE_RESV0         GENMASK(7, 4)
-+#define MAC_EEE_CKG_TXILDE    BIT(3)
-+#define MAC_EEE_CKG_RXLPI     BIT(2)
-+#define MAC_EEE_TX_DOWN_REQ   BIT(1)
-+#define MAC_EEE_LPI_MODE      BIT(0)
-+
- /* Mac status registers */
- #define MTK_MAC_MSR(x)                (0x10108 + (x * 0x100))
- #define MAC_MSR_EEE1G         BIT(7)
-@@ -455,6 +490,12 @@
- #define INTF_MODE_RGMII_1000    (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
- #define INTF_MODE_RGMII_10_100  0
-+/* XFI Mac control registers */
-+#define MTK_XMAC_MCR(x)               (0x12000 + ((x - 1) * 0x1000))
-+#define XMAC_MCR_TRX_DISABLE  0xf
-+#define XMAC_MCR_FORCE_TX_FC  BIT(5)
-+#define XMAC_MCR_FORCE_RX_FC  BIT(4)
-+
- /* GPIO port control registers for GMAC 2*/
- #define GPIO_OD33_CTRL8               0x4c0
- #define GPIO_BIAS_CTRL                0xed0
-@@ -480,6 +521,7 @@
- #define SYSCFG0_SGMII_GMAC2    ((3 << 8) & SYSCFG0_SGMII_MASK)
- #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
- #define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
-+#define SYSCFG0_SGMII_GMAC3_V2 BIT(7)
- /* ethernet subsystem clock register */
-@@ -506,16 +548,91 @@
- #define ETHSYS_DMA_AG_MAP_QDMA        BIT(1)
- #define ETHSYS_DMA_AG_MAP_PPE BIT(2)
-+/* USXGMII subsystem config registers */
-+/* Register to control speed */
-+#define RG_PHY_TOP_SPEED_CTRL1        0x80C
-+#define USXGMII_RATE_UPDATE_MODE      BIT(31)
-+#define USXGMII_MAC_CK_GATED  BIT(29)
-+#define USXGMII_IF_FORCE_EN   BIT(28)
-+#define USXGMII_RATE_ADAPT_MODE       GENMASK(10, 8)
-+#define USXGMII_RATE_ADAPT_MODE_X1    0
-+#define USXGMII_RATE_ADAPT_MODE_X2    1
-+#define USXGMII_RATE_ADAPT_MODE_X4    2
-+#define USXGMII_RATE_ADAPT_MODE_X10   3
-+#define USXGMII_RATE_ADAPT_MODE_X100  4
-+#define USXGMII_RATE_ADAPT_MODE_X5    5
-+#define USXGMII_RATE_ADAPT_MODE_X50   6
-+#define USXGMII_XFI_RX_MODE   GENMASK(6, 4)
-+#define USXGMII_XFI_RX_MODE_10G       0
-+#define USXGMII_XFI_RX_MODE_5G        1
-+#define USXGMII_XFI_TX_MODE   GENMASK(2, 0)
-+#define USXGMII_XFI_TX_MODE_10G       0
-+#define USXGMII_XFI_TX_MODE_5G        1
-+
-+/* Register to control PCS AN */
-+#define RG_PCS_AN_CTRL0               0x810
-+#define USXGMII_AN_RESTART    BIT(31)
-+#define USXGMII_AN_SYNC_CNT   GENMASK(30, 11)
-+#define USXGMII_AN_ENABLE     BIT(0)
-+
-+#define RG_PCS_AN_CTRL2               0x818
-+#define USXGMII_LINK_TIMER_IDLE_DETECT        GENMASK(29, 20)
-+#define USXGMII_LINK_TIMER_COMP_ACK_DETECT    GENMASK(19, 10)
-+#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0)
-+
-+/* Register to read PCS AN status */
-+#define RG_PCS_AN_STS0                0x81c
-+#define USXGMII_LPA_SPEED_MASK        GENMASK(11, 9)
-+#define USXGMII_LPA_SPEED_10  0
-+#define USXGMII_LPA_SPEED_100 1
-+#define USXGMII_LPA_SPEED_1000        2
-+#define USXGMII_LPA_SPEED_10000       3
-+#define USXGMII_LPA_SPEED_2500        4
-+#define USXGMII_LPA_SPEED_5000        5
-+#define USXGMII_LPA_DUPLEX    BIT(12)
-+#define USXGMII_LPA_LINK      BIT(15)
-+#define USXGMII_LPA_LATCH     BIT(31)
-+
-+/* Register to control USXGMII XFI PLL digital */
-+#define XFI_PLL_DIG_GLB8      0x08
-+#define RG_XFI_PLL_EN         BIT(31)
-+
-+/* Register to control USXGMII XFI PLL analog */
-+#define XFI_PLL_ANA_GLB8      0x108
-+#define RG_XFI_PLL_ANA_SWWA   0x02283248
-+
- /* Infrasys subsystem config registers */
- #define INFRA_MISC2            0x70c
- #define CO_QPHY_SEL            BIT(0)
- #define GEPHY_MAC_SEL          BIT(1)
-+/* Toprgu subsystem config registers */
-+#define TOPRGU_SWSYSRST               0x18
-+#define SWSYSRST_UNLOCK_KEY   GENMASK(31, 24)
-+#define SWSYSRST_XFI_PLL_GRST BIT(16)
-+#define SWSYSRST_XFI_PEXPT1_GRST      BIT(15)
-+#define SWSYSRST_XFI_PEXPT0_GRST      BIT(14)
-+#define SWSYSRST_XFI1_GRST    BIT(13)
-+#define SWSYSRST_XFI0_GRST    BIT(12)
-+#define SWSYSRST_SGMII1_GRST  BIT(2)
-+#define SWSYSRST_SGMII0_GRST  BIT(1)
-+#define TOPRGU_SWSYSRST_EN            0xFC
-+
- /* Top misc registers */
-+#define TOP_MISC_NETSYS_PCS_MUX       0x84
-+#define NETSYS_PCS_MUX_MASK   GENMASK(1, 0)
-+#define       MUX_G2_USXGMII_SEL      BIT(1)
-+#define MUX_HSGMII1_G1_SEL    BIT(0)
-+
- #define USB_PHY_SWITCH_REG    0x218
- #define QPHY_SEL_MASK         GENMASK(1, 0)
- #define SGMII_QPHY_SEL                0x2
-+/* MDIO control */
-+#define MII_MMD_ACC_CTL_REG   0x0d
-+#define MII_MMD_ADDR_DATA_REG 0x0e
-+#define MMD_OP_MODE_DATA      BIT(14)
-+
- /* MT7628/88 specific stuff */
- #define MT7628_PDMA_OFFSET    0x0800
- #define MT7628_SDM_OFFSET     0x0c00
-@@ -809,13 +926,6 @@ enum mtk_gmac_id {
-       MTK_GMAC_ID_MAX
- };
--/* GDM Type */
--enum mtk_gdm_type {
--      MTK_GDM_TYPE = 0,
--      MTK_XGDM_TYPE,
--      MTK_GDM_TYPE_MAX
--};
--
- enum mtk_tx_buf_type {
-       MTK_TYPE_SKB,
-       MTK_TYPE_XDP_TX,
-@@ -902,6 +1012,7 @@ enum mkt_eth_capabilities {
-       MTK_TRGMII_BIT,
-       MTK_SGMII_BIT,
-       MTK_USXGMII_BIT,
-+      MTK_2P5GPHY_BIT,
-       MTK_ESW_BIT,
-       MTK_GEPHY_BIT,
-       MTK_MUX_BIT,
-@@ -922,6 +1033,7 @@ enum mkt_eth_capabilities {
-       MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
-       MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
-       MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
-+      MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT,
-       MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
-       MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
-       MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
-@@ -933,6 +1045,7 @@ enum mkt_eth_capabilities {
-       MTK_ETH_PATH_GMAC1_SGMII_BIT,
-       MTK_ETH_PATH_GMAC2_RGMII_BIT,
-       MTK_ETH_PATH_GMAC2_SGMII_BIT,
-+      MTK_ETH_PATH_GMAC2_2P5GPHY_BIT,
-       MTK_ETH_PATH_GMAC2_GEPHY_BIT,
-       MTK_ETH_PATH_GMAC3_SGMII_BIT,
-       MTK_ETH_PATH_GDM1_ESW_BIT,
-@@ -946,6 +1059,7 @@ enum mkt_eth_capabilities {
- #define MTK_TRGMII            BIT_ULL(MTK_TRGMII_BIT)
- #define MTK_SGMII             BIT_ULL(MTK_SGMII_BIT)
- #define MTK_USXGMII           BIT_ULL(MTK_USXGMII_BIT)
-+#define MTK_2P5GPHY           BIT_ULL(MTK_2P5GPHY_BIT)
- #define MTK_ESW                       BIT_ULL(MTK_ESW_BIT)
- #define MTK_GEPHY             BIT_ULL(MTK_GEPHY_BIT)
- #define MTK_MUX                       BIT_ULL(MTK_MUX_BIT)
-@@ -968,6 +1082,8 @@ enum mkt_eth_capabilities {
-       BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
- #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY          \
-       BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
-+#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY          \
-+      BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT)
- #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII        \
-       BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
- #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII     \
-@@ -983,6 +1099,7 @@ enum mkt_eth_capabilities {
- #define MTK_ETH_PATH_GMAC1_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
- #define MTK_ETH_PATH_GMAC2_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
- #define MTK_ETH_PATH_GMAC2_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_2P5GPHY    BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT)
- #define MTK_ETH_PATH_GMAC2_GEPHY      BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
- #define MTK_ETH_PATH_GMAC3_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
- #define MTK_ETH_PATH_GDM1_ESW         BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
-@@ -996,6 +1113,7 @@ enum mkt_eth_capabilities {
- #define MTK_GMAC2_RGMII               (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
- #define MTK_GMAC2_SGMII               (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
- #define MTK_GMAC2_GEPHY               (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
-+#define MTK_GMAC2_2P5GPHY     (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY)
- #define MTK_GMAC3_SGMII               (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
- #define MTK_GDM1_ESW          (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
- #define MTK_GMAC1_USXGMII     (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
-@@ -1019,6 +1137,10 @@ enum mkt_eth_capabilities {
-       (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
-       MTK_SHARED_SGMII)
-+/* 2: GMAC2 -> XGMII */
-+#define MTK_MUX_GMAC2_TO_2P5GPHY      \
-+      (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA)
-+
- /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */
- #define MTK_MUX_GMAC12_TO_GEPHY_SGMII   \
-       (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
-@@ -1077,7 +1199,8 @@ enum mkt_eth_capabilities {
-                      MTK_MUX_GMAC123_TO_GEPHY_SGMII |         \
-                      MTK_NETSYS_V3 | MTK_RSTCTRL_PPE1 |       \
-                      MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII |  \
--                     MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII)
-+                     MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII | \
-+                     MTK_GMAC2_2P5GPHY | MTK_MUX_GMAC2_TO_2P5GPHY)
- struct mtk_tx_dma_desc_info {
-       dma_addr_t      addr;
-@@ -1183,6 +1306,22 @@ struct mtk_soc_data {
- #define MTK_DMA_MONITOR_TIMEOUT               msecs_to_jiffies(1000)
-+/* struct mtk_usxgmii_pcs - This structure holds each usxgmii regmap and
-+ *                    associated data
-+ * @regmap:           The register map pointing at the range used to setup
-+ *                    USXGMII modes
-+ * @interface:                Currently selected interface mode
-+ * @id:                       The element is used to record the index of PCS
-+ * @pcs:              Phylink PCS structure
-+ */
-+struct mtk_usxgmii_pcs {
-+      struct mtk_eth          *eth;
-+      struct regmap           *regmap;
-+      phy_interface_t         interface;
-+      u8                      id;
-+      struct phylink_pcs      pcs;
-+};
-+
- /* struct mtk_eth -   This is the main datasructure for holding the state
-  *                    of the driver
-  * @dev:              The device pointer
-@@ -1203,6 +1342,11 @@ struct mtk_soc_data {
-  * @infra:              The register map pointing at the range used to setup
-  *                      SGMII and GePHY path
-  * @sgmii_pcs:                Pointers to mtk-pcs-lynxi phylink_pcs instances
-+ * @usxgmii_pll:      The register map pointing at the range used to control
-+ *                    the USXGMII SerDes PLL
-+ * @regmap_pextp:     The register map pointing at the range used to setup
-+ *                    PHYA
-+ * @usxgmii_pcs:      Pointer to array of pointers to struct for USXGMII PCS
-  * @pctl:             The register map pointing at the range used to setup
-  *                    GMAC port drive/slew values
-  * @dma_refcnt:               track how many netdevs are using the DMA engine
-@@ -1244,7 +1388,11 @@ struct mtk_eth {
-       unsigned long                   sysclk;
-       struct regmap                   *ethsys;
-       struct regmap                   *infra;
-+      struct regmap                   *toprgu;
-       struct phylink_pcs              **sgmii_pcs;
-+      struct regmap                   *usxgmii_pll;
-+      struct regmap                   **regmap_pextp;
-+      struct mtk_usxgmii_pcs          **usxgmii_pcs;
-       struct regmap                   *pctl;
-       bool                            hwlro;
-       refcount_t                      dma_refcnt;
-@@ -1400,6 +1548,19 @@ static inline u32 mtk_get_ib2_multicast_
-       return MTK_FOE_IB2_MULTICAST;
- }
-+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
-+{
-+      switch (interface) {
-+      case PHY_INTERFACE_MODE_USXGMII:
-+      case PHY_INTERFACE_MODE_10GKR:
-+      case PHY_INTERFACE_MODE_5GBASER:
-+              return true;
-+              break;
-+      default:
-+              return false;
-+      }
-+}
-+
- /* read the hardware status register */
- void mtk_stats_update_mac(struct mtk_mac *mac);
-@@ -1407,8 +1568,10 @@ void mtk_w32(struct mtk_eth *eth, u32 va
- u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
- int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
-+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id);
- int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
- int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
-+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id);
- int mtk_eth_offload_init(struct mtk_eth *eth);
- int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
-@@ -1418,5 +1581,20 @@ int mtk_flow_offload_cmd(struct mtk_eth
- void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list);
- void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
-+#ifdef CONFIG_NET_MEDIATEK_SOC_USXGMII
-+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id);
-+int mtk_usxgmii_init(struct mtk_eth *eth);
-+int mtk_xfi_pll_enable(struct mtk_eth *eth);
-+void mtk_sgmii_setup_phya_gen1(struct mtk_eth *eth, int mac_id);
-+void mtk_sgmii_setup_phya_gen2(struct mtk_eth *eth, int mac_id);
-+void mtk_sgmii_reset(struct mtk_eth *eth, int mac_id);
-+#else
-+static inline struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id) { return NULL; }
-+static inline int mtk_usxgmii_init(struct mtk_eth *eth) { return 0; }
-+static inline int mtk_xfi_pll_enable(struct mtk_eth *eth) { return 0; }
-+static inline void mtk_sgmii_setup_phya_gen1(struct mtk_eth *eth, int mac_id) { }
-+static inline void mtk_sgmii_setup_phya_gen2(struct mtk_eth *eth, int mac_id) { }
-+static inline void mtk_sgmii_reset(struct mtk_eth *eth, int mac_id) { }
-+#endif /* NET_MEDIATEK_SOC_USXGMII */
- #endif /* MTK_ETH_H */
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_usxgmii.c
-@@ -0,0 +1,835 @@
-+/* SPDX-License-Identifier: GPL-2.0
-+ *
-+ * Copyright (c) 2022 MediaTek Inc.
-+ * Author: Henry Yen <henry.yen@mediatek.com>
-+ *         Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+#include <linux/mfd/syscon.h>
-+#include <linux/of.h>
-+#include <linux/regmap.h>
-+#include "mtk_eth_soc.h"
-+
-+static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs)
-+{
-+      return container_of(pcs, struct mtk_usxgmii_pcs, pcs);
-+}
-+
-+static int mtk_xfi_pextp_init(struct mtk_eth *eth)
-+{
-+      struct device *dev = eth->dev;
-+      struct device_node *r = dev->of_node;
-+      struct device_node *np;
-+      int i;
-+
-+      eth->regmap_pextp = devm_kcalloc(dev, eth->soc->num_devs, sizeof(eth->regmap_pextp), GFP_KERNEL);
-+      if (!eth->regmap_pextp)
-+              return -ENOMEM;
-+
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-+              np = of_parse_phandle(r, "mediatek,xfi_pextp", i);
-+              if (!np)
-+                      break;
-+
-+              eth->regmap_pextp[i] = syscon_node_to_regmap(np);
-+              if (IS_ERR(eth->regmap_pextp[i]))
-+                      return PTR_ERR(eth->regmap_pextp[i]);
-+      }
-+
-+      return 0;
-+}
-+
-+static int mtk_xfi_pll_init(struct mtk_eth *eth)
-+{
-+      struct device_node *r = eth->dev->of_node;
-+      struct device_node *np;
-+
-+      np = of_parse_phandle(r, "mediatek,xfi_pll", 0);
-+      if (!np)
-+              return -1;
-+
-+      eth->usxgmii_pll = syscon_node_to_regmap(np);
-+      if (IS_ERR(eth->usxgmii_pll))
-+              return PTR_ERR(eth->usxgmii_pll);
-+
-+      return 0;
-+}
-+
-+static int mtk_toprgu_init(struct mtk_eth *eth)
-+{
-+      struct device_node *r = eth->dev->of_node;
-+      struct device_node *np;
-+
-+      np = of_parse_phandle(r, "mediatek,toprgu", 0);
-+      if (!np)
-+              return -1;
-+
-+      eth->toprgu = syscon_node_to_regmap(np);
-+      if (IS_ERR(eth->toprgu))
-+              return PTR_ERR(eth->toprgu);
-+
-+      return 0;
-+}
-+
-+int mtk_xfi_pll_enable(struct mtk_eth *eth)
-+{
-+      u32 val = 0;
-+
-+      if (!eth->usxgmii_pll)
-+              return -EINVAL;
-+
-+      /* Add software workaround for USXGMII PLL TCL issue */
-+      regmap_write(eth->usxgmii_pll, XFI_PLL_ANA_GLB8, RG_XFI_PLL_ANA_SWWA);
-+
-+      regmap_read(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, &val);
-+      val |= RG_XFI_PLL_EN;
-+      regmap_write(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, val);
-+
-+      return 0;
-+}
-+
-+static int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id)
-+{
-+      int xgmii_id = mac_id;
-+
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+              switch (mac_id) {
-+              case MTK_GMAC1_ID:
-+              case MTK_GMAC2_ID:
-+                      xgmii_id = 1;
-+                      break;
-+              case MTK_GMAC3_ID:
-+                      xgmii_id = 0;
-+                      break;
-+              default:
-+                      xgmii_id = -1;
-+              }
-+      }
-+
-+      return xgmii_id;
-+}
-+
-+static int mtk_xgmii2mac_id(struct mtk_eth *eth, int xgmii_id)
-+{
-+      int mac_id = xgmii_id;
-+
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+              switch (xgmii_id) {
-+              case 0:
-+                      mac_id = 2;
-+                      break;
-+              case 1:
-+                      mac_id = 1;
-+                      break;
-+              default:
-+                      mac_id = -1;
-+              }
-+      }
-+
-+      return mac_id;
-+}
-+
-+
-+static void mtk_usxgmii_setup_phya_usxgmii(struct mtk_usxgmii_pcs *mpcs)
-+{
-+      struct regmap *pextp;
-+
-+      if (!mpcs->eth)
-+              return;
-+
-+      pextp = mpcs->eth->regmap_pextp[mpcs->id];
-+      if (!pextp)
-+              return;
-+
-+      /* Setup operation mode */
-+      regmap_write(pextp, 0x9024, 0x00C9071C);
-+      regmap_write(pextp, 0x2020, 0xAA8585AA);
-+      regmap_write(pextp, 0x2030, 0x0C020707);
-+      regmap_write(pextp, 0x2034, 0x0E050F0F);
-+      regmap_write(pextp, 0x2040, 0x00140032);
-+      regmap_write(pextp, 0x50F0, 0x00C014AA);
-+      regmap_write(pextp, 0x50E0, 0x3777C12B);
-+      regmap_write(pextp, 0x506C, 0x005F9CFF);
-+      regmap_write(pextp, 0x5070, 0x9D9DFAFA);
-+      regmap_write(pextp, 0x5074, 0x27273F3F);
-+      regmap_write(pextp, 0x5078, 0xA7883C68);
-+      regmap_write(pextp, 0x507C, 0x11661166);
-+      regmap_write(pextp, 0x5080, 0x0E000AAF);
-+      regmap_write(pextp, 0x5084, 0x08080D0D);
-+      regmap_write(pextp, 0x5088, 0x02030909);
-+      regmap_write(pextp, 0x50E4, 0x0C0C0000);
-+      regmap_write(pextp, 0x50E8, 0x04040000);
-+      regmap_write(pextp, 0x50EC, 0x0F0F0C06);
-+      regmap_write(pextp, 0x50A8, 0x506E8C8C);
-+      regmap_write(pextp, 0x6004, 0x18190000);
-+      regmap_write(pextp, 0x00F8, 0x01423342);
-+      /* Force SGDT_OUT off and select PCS */
-+      regmap_write(pextp, 0x00F4, 0x80201F20);
-+      /* Force GLB_CKDET_OUT */
-+      regmap_write(pextp, 0x0030, 0x00050C00);
-+      /* Force AEQ on */
-+      regmap_write(pextp, 0x0070, 0x02002800);
-+      ndelay(1020);
-+      /* Setup DA default value */
-+      regmap_write(pextp, 0x30B0, 0x00000020);
-+      regmap_write(pextp, 0x3028, 0x00008A01);
-+      regmap_write(pextp, 0x302C, 0x0000A884);
-+      regmap_write(pextp, 0x3024, 0x00083002);
-+      regmap_write(pextp, 0x3010, 0x00022220);
-+      regmap_write(pextp, 0x5064, 0x0F020A01);
-+      regmap_write(pextp, 0x50B4, 0x06100600);
-+      regmap_write(pextp, 0x3048, 0x40704000);
-+      regmap_write(pextp, 0x3050, 0xA8000000);
-+      regmap_write(pextp, 0x3054, 0x000000AA);
-+      regmap_write(pextp, 0x306C, 0x00000F00);
-+      regmap_write(pextp, 0xA060, 0x00040000);
-+      regmap_write(pextp, 0x90D0, 0x00000001);
-+      /* Release reset */
-+      regmap_write(pextp, 0x0070, 0x0200E800);
-+      udelay(150);
-+      /* Switch to P0 */
-+      regmap_write(pextp, 0x0070, 0x0200C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0200C101);
-+      udelay(15);
-+      /* Switch to Gen3 */
-+      regmap_write(pextp, 0x0070, 0x0202C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0202C101);
-+      udelay(100);
-+      regmap_write(pextp, 0x30B0, 0x00000030);
-+      regmap_write(pextp, 0x00F4, 0x80201F00);
-+      regmap_write(pextp, 0x3040, 0x30000000);
-+      udelay(400);
-+}
-+
-+static void mtk_usxgmii_setup_phya_5gbaser(struct mtk_usxgmii_pcs *mpcs)
-+{
-+      struct regmap *pextp;
-+
-+      if (!mpcs->eth)
-+              return;
-+
-+      pextp = mpcs->eth->regmap_pextp[mpcs->id];
-+      if (!pextp)
-+              return;
-+
-+      /* Setup operation mode */
-+      regmap_write(pextp, 0x9024, 0x00D9071C);
-+      regmap_write(pextp, 0x2020, 0xAAA5A5AA);
-+      regmap_write(pextp, 0x2030, 0x0C020707);
-+      regmap_write(pextp, 0x2034, 0x0E050F0F);
-+      regmap_write(pextp, 0x2040, 0x00140032);
-+      regmap_write(pextp, 0x50F0, 0x00C018AA);
-+      regmap_write(pextp, 0x50E0, 0x3777812B);
-+      regmap_write(pextp, 0x506C, 0x005C9CFF);
-+      regmap_write(pextp, 0x5070, 0x9DFAFAFA);
-+      regmap_write(pextp, 0x5074, 0x273F3F3F);
-+      regmap_write(pextp, 0x5078, 0xA8883868);
-+      regmap_write(pextp, 0x507C, 0x14661466);
-+      regmap_write(pextp, 0x5080, 0x0E001ABF);
-+      regmap_write(pextp, 0x5084, 0x080B0D0D);
-+      regmap_write(pextp, 0x5088, 0x02050909);
-+      regmap_write(pextp, 0x50E4, 0x0C000000);
-+      regmap_write(pextp, 0x50E8, 0x04000000);
-+      regmap_write(pextp, 0x50EC, 0x0F0F0C06);
-+      regmap_write(pextp, 0x50A8, 0x50808C8C);
-+      regmap_write(pextp, 0x6004, 0x18000000);
-+      regmap_write(pextp, 0x00F8, 0x00A132A1);
-+      /* Force SGDT_OUT off and select PCS */
-+      regmap_write(pextp, 0x00F4, 0x80201F20);
-+      /* Force GLB_CKDET_OUT */
-+      regmap_write(pextp, 0x0030, 0x00050C00);
-+      /* Force AEQ on */
-+      regmap_write(pextp, 0x0070, 0x02002800);
-+      ndelay(1020);
-+      /* Setup DA default value */
-+      regmap_write(pextp, 0x30B0, 0x00000020);
-+      regmap_write(pextp, 0x3028, 0x00008A01);
-+      regmap_write(pextp, 0x302C, 0x0000A884);
-+      regmap_write(pextp, 0x3024, 0x00083002);
-+      regmap_write(pextp, 0x3010, 0x00022220);
-+      regmap_write(pextp, 0x5064, 0x0F020A01);
-+      regmap_write(pextp, 0x50B4, 0x06100600);
-+      regmap_write(pextp, 0x3048, 0x40704000);
-+      regmap_write(pextp, 0x3050, 0xA8000000);
-+      regmap_write(pextp, 0x3054, 0x000000AA);
-+      regmap_write(pextp, 0x306C, 0x00000F00);
-+      regmap_write(pextp, 0xA060, 0x00040000);
-+      regmap_write(pextp, 0x90D0, 0x00000003);
-+      /* Release reset */
-+      regmap_write(pextp, 0x0070, 0x0200E800);
-+      udelay(150);
-+      /* Switch to P0 */
-+      regmap_write(pextp, 0x0070, 0x0200C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0200C101);
-+      udelay(15);
-+      /* Switch to Gen3 */
-+      regmap_write(pextp, 0x0070, 0x0202C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0202C101);
-+      udelay(100);
-+      regmap_write(pextp, 0x30B0, 0x00000030);
-+      regmap_write(pextp, 0x00F4, 0x80201F00);
-+      regmap_write(pextp, 0x3040, 0x30000000);
-+      udelay(400);
-+}
-+
-+static void mtk_usxgmii_setup_phya_10gbaser(struct mtk_usxgmii_pcs *mpcs)
-+{
-+      struct regmap *pextp;
-+
-+      if (!mpcs->eth)
-+              return;
-+
-+      pextp = mpcs->eth->regmap_pextp[mpcs->id];
-+      if (!pextp)
-+              return;
-+
-+      /* Setup operation mode */
-+      regmap_write(pextp, 0x9024, 0x00C9071C);
-+      regmap_write(pextp, 0x2020, 0xAA8585AA);
-+      regmap_write(pextp, 0x2030, 0x0C020707);
-+      regmap_write(pextp, 0x2034, 0x0E050F0F);
-+      regmap_write(pextp, 0x2040, 0x00140032);
-+      regmap_write(pextp, 0x50F0, 0x00C014AA);
-+      regmap_write(pextp, 0x50E0, 0x3777C12B);
-+      regmap_write(pextp, 0x506C, 0x005F9CFF);
-+      regmap_write(pextp, 0x5070, 0x9D9DFAFA);
-+      regmap_write(pextp, 0x5074, 0x27273F3F);
-+      regmap_write(pextp, 0x5078, 0xA7883C68);
-+      regmap_write(pextp, 0x507C, 0x11661166);
-+      regmap_write(pextp, 0x5080, 0x0E000AAF);
-+      regmap_write(pextp, 0x5084, 0x08080D0D);
-+      regmap_write(pextp, 0x5088, 0x02030909);
-+      regmap_write(pextp, 0x50E4, 0x0C0C0000);
-+      regmap_write(pextp, 0x50E8, 0x04040000);
-+      regmap_write(pextp, 0x50EC, 0x0F0F0C06);
-+      regmap_write(pextp, 0x50A8, 0x506E8C8C);
-+      regmap_write(pextp, 0x6004, 0x18190000);
-+      regmap_write(pextp, 0x00F8, 0x01423342);
-+      /* Force SGDT_OUT off and select PCS */
-+      regmap_write(pextp, 0x00F4, 0x80201F20);
-+      /* Force GLB_CKDET_OUT */
-+      regmap_write(pextp, 0x0030, 0x00050C00);
-+      /* Force AEQ on */
-+      regmap_write(pextp, 0x0070, 0x02002800);
-+      ndelay(1020);
-+      /* Setup DA default value */
-+      regmap_write(pextp, 0x30B0, 0x00000020);
-+      regmap_write(pextp, 0x3028, 0x00008A01);
-+      regmap_write(pextp, 0x302C, 0x0000A884);
-+      regmap_write(pextp, 0x3024, 0x00083002);
-+      regmap_write(pextp, 0x3010, 0x00022220);
-+      regmap_write(pextp, 0x5064, 0x0F020A01);
-+      regmap_write(pextp, 0x50B4, 0x06100600);
-+      regmap_write(pextp, 0x3048, 0x47684100);
-+      regmap_write(pextp, 0x3050, 0x00000000);
-+      regmap_write(pextp, 0x3054, 0x00000000);
-+      regmap_write(pextp, 0x306C, 0x00000F00);
-+      if (mpcs->id == 0)
-+              regmap_write(pextp, 0xA008, 0x0007B400);
-+
-+      regmap_write(pextp, 0xA060, 0x00040000);
-+      regmap_write(pextp, 0x90D0, 0x00000001);
-+      /* Release reset */
-+      regmap_write(pextp, 0x0070, 0x0200E800);
-+      udelay(150);
-+      /* Switch to P0 */
-+      regmap_write(pextp, 0x0070, 0x0200C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0200C101);
-+      udelay(15);
-+      /* Switch to Gen3 */
-+      regmap_write(pextp, 0x0070, 0x0202C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0202C101);
-+      udelay(100);
-+      regmap_write(pextp, 0x30B0, 0x00000030);
-+      regmap_write(pextp, 0x00F4, 0x80201F00);
-+      regmap_write(pextp, 0x3040, 0x30000000);
-+      udelay(400);
-+}
-+
-+void mtk_sgmii_setup_phya_gen1(struct mtk_eth *eth, int mac_id)
-+{
-+      u32 id = mtk_mac2xgmii_id(eth, mac_id);
-+      struct regmap *pextp;
-+
-+      if (id >= eth->soc->num_devs)
-+              return;
-+
-+      pextp = eth->regmap_pextp[id];
-+      if (!pextp)
-+              return;
-+
-+      /* Setup operation mode */
-+      regmap_write(pextp, 0x9024, 0x00D9071C);
-+      regmap_write(pextp, 0x2020, 0xAA8585AA);
-+      regmap_write(pextp, 0x2030, 0x0C020207);
-+      regmap_write(pextp, 0x2034, 0x0E05050F);
-+      regmap_write(pextp, 0x2040, 0x00200032);
-+      regmap_write(pextp, 0x50F0, 0x00C014BA);
-+      regmap_write(pextp, 0x50E0, 0x3777C12B);
-+      regmap_write(pextp, 0x506C, 0x005F9CFF);
-+      regmap_write(pextp, 0x5070, 0x9D9DFAFA);
-+      regmap_write(pextp, 0x5074, 0x27273F3F);
-+      regmap_write(pextp, 0x5078, 0xA7883C68);
-+      regmap_write(pextp, 0x507C, 0x11661166);
-+      regmap_write(pextp, 0x5080, 0x0E000EAF);
-+      regmap_write(pextp, 0x5084, 0x08080E0D);
-+      regmap_write(pextp, 0x5088, 0x02030B09);
-+      regmap_write(pextp, 0x50E4, 0x0C0C0000);
-+      regmap_write(pextp, 0x50E8, 0x04040000);
-+      regmap_write(pextp, 0x50EC, 0x0F0F0606);
-+      regmap_write(pextp, 0x50A8, 0x506E8C8C);
-+      regmap_write(pextp, 0x6004, 0x18190000);
-+      regmap_write(pextp, 0x00F8, 0x00FA32FA);
-+      /* Force SGDT_OUT off and select PCS */
-+      regmap_write(pextp, 0x00F4, 0x80201F21);
-+      /* Force GLB_CKDET_OUT */
-+      regmap_write(pextp, 0x0030, 0x00050C00);
-+      /* Force AEQ on */
-+      regmap_write(pextp, 0x0070, 0x02002800);
-+      ndelay(1020);
-+      /* Setup DA default value */
-+      regmap_write(pextp, 0x30B0, 0x00000020);
-+      regmap_write(pextp, 0x3028, 0x00008A01);
-+      regmap_write(pextp, 0x302C, 0x0000A884);
-+      regmap_write(pextp, 0x3024, 0x00083002);
-+      regmap_write(pextp, 0x3010, 0x00011110);
-+      regmap_write(pextp, 0x3048, 0x40704000);
-+      regmap_write(pextp, 0x3064, 0x0000C000);
-+      regmap_write(pextp, 0x3050, 0xA8000000);
-+      regmap_write(pextp, 0x3054, 0x000000AA);
-+      regmap_write(pextp, 0x306C, 0x20200F00);
-+      regmap_write(pextp, 0xA060, 0x00050000);
-+      regmap_write(pextp, 0x90D0, 0x00000007);
-+      /* Release reset */
-+      regmap_write(pextp, 0x0070, 0x0200E800);
-+      udelay(150);
-+      /* Switch to P0 */
-+      regmap_write(pextp, 0x0070, 0x0200C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0200C101);
-+      udelay(15);
-+      /* Switch to Gen2 */
-+      regmap_write(pextp, 0x0070, 0x0201C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0201C101);
-+      udelay(100);
-+      regmap_write(pextp, 0x30B0, 0x00000030);
-+      regmap_write(pextp, 0x00F4, 0x80201F01);
-+      regmap_write(pextp, 0x3040, 0x30000000);
-+      udelay(400);
-+}
-+
-+void mtk_sgmii_setup_phya_gen2(struct mtk_eth *eth, int mac_id)
-+{
-+      u32 id = mtk_mac2xgmii_id(eth, mac_id);
-+      struct regmap *pextp;
-+
-+      if (id >= eth->soc->num_devs)
-+              return;
-+
-+      pextp = eth->regmap_pextp[id];
-+      if (!pextp)
-+              return;
-+
-+      /* Setup operation mode */
-+      regmap_write(pextp, 0x9024, 0x00D9071C);
-+      regmap_write(pextp, 0x2020, 0xAA8585AA);
-+      regmap_write(pextp, 0x2030, 0x0C020707);
-+      regmap_write(pextp, 0x2034, 0x0E050F0F);
-+      regmap_write(pextp, 0x2040, 0x00140032);
-+      regmap_write(pextp, 0x50F0, 0x00C014AA);
-+      regmap_write(pextp, 0x50E0, 0x3777C12B);
-+      regmap_write(pextp, 0x506C, 0x005F9CFF);
-+      regmap_write(pextp, 0x5070, 0x9D9DFAFA);
-+      regmap_write(pextp, 0x5074, 0x27273F3F);
-+      regmap_write(pextp, 0x5078, 0xA7883C68);
-+      regmap_write(pextp, 0x507C, 0x11661166);
-+      regmap_write(pextp, 0x5080, 0x0E000AAF);
-+      regmap_write(pextp, 0x5084, 0x08080D0D);
-+      regmap_write(pextp, 0x5088, 0x02030909);
-+      regmap_write(pextp, 0x50E4, 0x0C0C0000);
-+      regmap_write(pextp, 0x50E8, 0x04040000);
-+      regmap_write(pextp, 0x50EC, 0x0F0F0C06);
-+      regmap_write(pextp, 0x50A8, 0x506E8C8C);
-+      regmap_write(pextp, 0x6004, 0x18190000);
-+      regmap_write(pextp, 0x00F8, 0x009C329C);
-+      /* Force SGDT_OUT off and select PCS */
-+      regmap_write(pextp, 0x00F4, 0x80201F21);
-+      /* Force GLB_CKDET_OUT */
-+      regmap_write(pextp, 0x0030, 0x00050C00);
-+      /* Force AEQ on */
-+      regmap_write(pextp, 0x0070, 0x02002800);
-+      ndelay(1020);
-+      /* Setup DA default value */
-+      regmap_write(pextp, 0x30B0, 0x00000020);
-+      regmap_write(pextp, 0x3028, 0x00008A01);
-+      regmap_write(pextp, 0x302C, 0x0000A884);
-+      regmap_write(pextp, 0x3024, 0x00083002);
-+      regmap_write(pextp, 0x3010, 0x00011110);
-+      regmap_write(pextp, 0x3048, 0x40704000);
-+      regmap_write(pextp, 0x3050, 0xA8000000);
-+      regmap_write(pextp, 0x3054, 0x000000AA);
-+      regmap_write(pextp, 0x306C, 0x22000F00);
-+      regmap_write(pextp, 0xA060, 0x00050000);
-+      regmap_write(pextp, 0x90D0, 0x00000005);
-+      /* Release reset */
-+      regmap_write(pextp, 0x0070, 0x0200E800);
-+      udelay(150);
-+      /* Switch to P0 */
-+      regmap_write(pextp, 0x0070, 0x0200C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0200C101);
-+      udelay(15);
-+      /* Switch to Gen2 */
-+      regmap_write(pextp, 0x0070, 0x0201C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0201C101);
-+      udelay(100);
-+      regmap_write(pextp, 0x30B0, 0x00000030);
-+      regmap_write(pextp, 0x00F4, 0x80201F01);
-+      regmap_write(pextp, 0x3040, 0x30000000);
-+      udelay(400);
-+}
-+
-+static void mtk_usxgmii_reset(struct mtk_eth *eth, int id)
-+{
-+      u32 val = 0;
-+
-+      if (id >= eth->soc->num_devs || !eth->toprgu)
-+              return;
-+
-+      switch (id) {
-+      case 0:
-+              /* Enable software reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
-+              val |= SWSYSRST_XFI_PEXPT0_GRST |
-+                     SWSYSRST_XFI0_GRST;
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
-+
-+              /* Assert USXGMII reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
-+              val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) |
-+                     SWSYSRST_XFI_PEXPT0_GRST |
-+                     SWSYSRST_XFI0_GRST;
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
-+
-+              udelay(100);
-+
-+              /* De-assert USXGMII reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
-+              val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
-+              val &= ~(SWSYSRST_XFI_PEXPT0_GRST |
-+                       SWSYSRST_XFI0_GRST);
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
-+
-+              /* Disable software reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
-+              val &= ~(SWSYSRST_XFI_PEXPT0_GRST |
-+                       SWSYSRST_XFI0_GRST);
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
-+              break;
-+      case 1:
-+              /* Enable software reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
-+              val |= SWSYSRST_XFI_PEXPT1_GRST |
-+                     SWSYSRST_XFI1_GRST;
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
-+
-+              /* Assert USXGMII reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
-+              val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) |
-+                     SWSYSRST_XFI_PEXPT1_GRST |
-+                     SWSYSRST_XFI1_GRST;
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
-+
-+              udelay(100);
-+
-+              /* De-assert USXGMII reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
-+              val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
-+              val &= ~(SWSYSRST_XFI_PEXPT1_GRST |
-+                       SWSYSRST_XFI1_GRST);
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
-+
-+              /* Disable software reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
-+              val &= ~(SWSYSRST_XFI_PEXPT1_GRST |
-+                       SWSYSRST_XFI1_GRST);
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
-+              break;
-+      }
-+
-+      mdelay(10);
-+}
-+
-+void mtk_sgmii_reset(struct mtk_eth *eth, int mac_id)
-+{
-+      u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id);
-+
-+      mtk_usxgmii_reset(eth, xgmii_id);
-+}
-+
-+
-+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-+                                phy_interface_t interface,
-+                                const unsigned long *advertising,
-+                                bool permit_pause_to_mac)
-+{
-+      struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
-+      struct mtk_eth *eth = mpcs->eth;
-+      unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0;
-+      bool mode_changed = false;
-+
-+      if (interface == PHY_INTERFACE_MODE_USXGMII) {
-+              an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) |
-+                        USXGMII_AN_ENABLE;
-+              link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
-+                           FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
-+                           FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
-+              xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) |
-+                         FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G);
-+      } else if (interface == PHY_INTERFACE_MODE_10GKR) {
-+              an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF);
-+              link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
-+                           FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
-+                           FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
-+              xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) |
-+                         FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G);
-+              adapt_mode = USXGMII_RATE_UPDATE_MODE;
-+      } else if (interface == PHY_INTERFACE_MODE_5GBASER) {
-+              an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF);
-+              link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) |
-+                           FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) |
-+                           FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D);
-+              xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_5G) |
-+                         FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_5G);
-+              adapt_mode = USXGMII_RATE_UPDATE_MODE;
-+      } else
-+              return -EINVAL;
-+
-+      adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1);
-+
-+      if (mpcs->interface != interface) {
-+              mpcs->interface = interface;
-+              mode_changed = true;
-+      }
-+
-+      mtk_xfi_pll_enable(eth);
-+      mtk_usxgmii_reset(eth, mpcs->id);
-+
-+      /* Setup USXGMII AN ctrl */
-+      regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL0,
-+                         USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
-+                         an_ctrl);
-+
-+      regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL2,
-+                         USXGMII_LINK_TIMER_IDLE_DETECT |
-+                         USXGMII_LINK_TIMER_COMP_ACK_DETECT |
-+                         USXGMII_LINK_TIMER_AN_RESTART,
-+                         link_timer);
-+
-+      /* Gated MAC CK */
-+      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+                         USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED);
-+
-+      /* Enable interface force mode */
-+      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+                         USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN);
-+
-+      /* Setup USXGMII adapt mode */
-+      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+                         USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE,
-+                         adapt_mode);
-+
-+      /* Setup USXGMII speed */
-+      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+                         USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE,
-+                         xfi_mode);
-+
-+      udelay(1);
-+
-+      /* Un-gated MAC CK */
-+      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+                         USXGMII_MAC_CK_GATED, 0);
-+
-+      udelay(1);
-+
-+      /* Disable interface force mode for the AN mode */
-+      if (an_ctrl & USXGMII_AN_ENABLE)
-+              regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+                                 USXGMII_IF_FORCE_EN, 0);
-+
-+      /* Setup USXGMIISYS with the determined property */
-+      if (interface == PHY_INTERFACE_MODE_USXGMII)
-+              mtk_usxgmii_setup_phya_usxgmii(mpcs);
-+      else if (interface == PHY_INTERFACE_MODE_10GKR)
-+              mtk_usxgmii_setup_phya_10gbaser(mpcs);
-+      else if (interface == PHY_INTERFACE_MODE_5GBASER)
-+              mtk_usxgmii_setup_phya_5gbaser(mpcs);
-+
-+      return mode_changed;
-+}
-+
-+static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs,
-+                                  struct phylink_link_state *state)
-+{
-+      struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
-+      struct mtk_eth *eth = mpcs->eth;
-+      struct mtk_mac *mac = eth->mac[mtk_xgmii2mac_id(eth, mpcs->id)];
-+      u32 val = 0;
-+
-+      regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
-+      if (FIELD_GET(USXGMII_AN_ENABLE, val)) {
-+              /* Refresh LPA by inverting LPA_LATCH */
-+              regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val);
-+              regmap_update_bits(mpcs->regmap, RG_PCS_AN_STS0,
-+                                 USXGMII_LPA_LATCH,
-+                                 !(val & USXGMII_LPA_LATCH));
-+
-+              regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val);
-+
-+              state->interface = mpcs->interface;
-+              state->link = FIELD_GET(USXGMII_LPA_LINK, val);
-+              state->duplex = FIELD_GET(USXGMII_LPA_DUPLEX, val);
-+
-+              switch (FIELD_GET(USXGMII_LPA_SPEED_MASK, val)) {
-+              case USXGMII_LPA_SPEED_10:
-+                      state->speed = SPEED_10;
-+                      break;
-+              case USXGMII_LPA_SPEED_100:
-+                      state->speed = SPEED_100;
-+                      break;
-+              case USXGMII_LPA_SPEED_1000:
-+                      state->speed = SPEED_1000;
-+                      break;
-+              case USXGMII_LPA_SPEED_2500:
-+                      state->speed = SPEED_2500;
-+                      break;
-+              case USXGMII_LPA_SPEED_5000:
-+                      state->speed = SPEED_5000;
-+                      break;
-+              case USXGMII_LPA_SPEED_10000:
-+                      state->speed = SPEED_10000;
-+                      break;
-+              }
-+      } else {
-+              val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
-+
-+              if (mac->id == MTK_GMAC2_ID)
-+                      val = val >> 16;
-+
-+              switch (FIELD_GET(MTK_USXGMII_PCS_MODE, val)) {
-+              case 0:
-+                      state->speed = SPEED_10000;
-+                      break;
-+              case 1:
-+                      state->speed = SPEED_5000;
-+                      break;
-+              case 2:
-+                      state->speed = SPEED_2500;
-+                      break;
-+              case 3:
-+                      state->speed = SPEED_1000;
-+                      break;
-+              }
-+
-+              state->interface = mpcs->interface;
-+              state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, val);
-+              state->duplex = DUPLEX_FULL;
-+      }
-+
-+      if (state->link == 0)
-+              mtk_usxgmii_pcs_config(pcs, MLO_AN_INBAND,
-+                                     state->interface, NULL, false);
-+}
-+
-+static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs)
-+{
-+      struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
-+      unsigned int val = 0;
-+
-+      if (!mpcs->regmap)
-+              return;
-+
-+      regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
-+      val |= USXGMII_AN_RESTART;
-+      regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val);
-+}
-+
-+static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-+                                  phy_interface_t interface,
-+                                  int speed, int duplex)
-+{
-+      /* Reconfiguring USXGMII to ensure the quality of the RX signal
-+       * after the line side link up.
-+       */
-+      mtk_usxgmii_pcs_config(pcs, mode,
-+                             interface, NULL, false);
-+}
-+
-+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = {
-+      .pcs_config = mtk_usxgmii_pcs_config,
-+      .pcs_get_state = mtk_usxgmii_pcs_get_state,
-+      .pcs_an_restart = mtk_usxgmii_pcs_restart_an,
-+      .pcs_link_up = mtk_usxgmii_pcs_link_up,
-+};
-+
-+int mtk_usxgmii_init(struct mtk_eth *eth)
-+{
-+      struct device_node *r = eth->dev->of_node;
-+      struct device *dev = eth->dev;
-+      struct device_node *np;
-+      int i, ret;
-+
-+      eth->usxgmii_pcs = devm_kcalloc(dev, eth->soc->num_devs, sizeof(eth->usxgmii_pcs), GFP_KERNEL);
-+      if (!eth->usxgmii_pcs)
-+              return -ENOMEM;
-+
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-+              np = of_parse_phandle(r, "mediatek,usxgmiisys", i);
-+              if (!np)
-+                      break;
-+
-+              eth->usxgmii_pcs[i] = devm_kzalloc(dev, sizeof(*eth->usxgmii_pcs), GFP_KERNEL);
-+              if (!eth->usxgmii_pcs[i])
-+                      return -ENOMEM;
-+
-+              eth->usxgmii_pcs[i]->id = i;
-+              eth->usxgmii_pcs[i]->eth = eth;
-+              eth->usxgmii_pcs[i]->regmap = syscon_node_to_regmap(np);
-+              if (IS_ERR(eth->usxgmii_pcs[i]->regmap))
-+                      return PTR_ERR(eth->usxgmii_pcs[i]->regmap);
-+
-+              eth->usxgmii_pcs[i]->pcs.ops = &mtk_usxgmii_pcs_ops;
-+              eth->usxgmii_pcs[i]->pcs.poll = true;
-+              eth->usxgmii_pcs[i]->interface = PHY_INTERFACE_MODE_NA;
-+
-+              of_node_put(np);
-+      }
-+
-+      ret = mtk_xfi_pextp_init(eth);
-+      if (ret)
-+              return ret;
-+
-+      ret = mtk_xfi_pll_init(eth);
-+      if (ret)
-+              return ret;
-+
-+      return mtk_toprgu_init(eth);
-+}
-+
-+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int mac_id)
-+{
-+      u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id);
-+
-+      if (!eth->usxgmii_pcs[xgmii_id]->regmap)
-+              return NULL;
-+
-+      return &eth->usxgmii_pcs[xgmii_id]->pcs;
-+}
diff --git a/target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-5.15/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
new file mode 100644 (file)
index 0000000..5b7591e
--- /dev/null
@@ -0,0 +1,1604 @@
+From 1e25ca1147579bda8b941be1b9851f5911d44eb0 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 22 Aug 2023 19:04:42 +0100
+Subject: [PATCH 098/125] net: ethernet: mtk_eth_soc: add paths and SerDes
+ modes for MT7988
+
+MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to
+connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R,
+2500Base-X, 1000Base-X and Cisco SGMII interface modes.
+
+Implement support for configuring for the new paths to SerDes interfaces
+and the internal 2.5G PHY.
+
+Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and
+setup the new PHYA on MT7988 to access the also still existing old
+LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface
+modes.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/ethernet/mediatek/Kconfig        |  16 +
+ drivers/net/ethernet/mediatek/Makefile       |   1 +
+ drivers/net/ethernet/mediatek/mtk_eth_path.c | 123 +++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c  | 182 ++++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 232 ++++++-
+ drivers/net/ethernet/mediatek/mtk_usxgmii.c  | 692 +++++++++++++++++++
+ 6 files changed, 1215 insertions(+), 31 deletions(-)
+ create mode 100644 drivers/net/ethernet/mediatek/mtk_usxgmii.c
+
+--- a/drivers/net/ethernet/mediatek/Kconfig
++++ b/drivers/net/ethernet/mediatek/Kconfig
+@@ -24,6 +24,22 @@ config NET_MEDIATEK_SOC
+         This driver supports the gigabit ethernet MACs in the
+         MediaTek SoC family.
++config NET_MEDIATEK_SOC_USXGMII
++      bool "Support USXGMII SerDes on MT7988"
++      depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
++      def_bool NET_MEDIATEK_SOC != n
++      help
++        Include support for 10GE SerDes which can be found on MT7988.
++        If this kernel should run on SoCs with 10 GBit/s Ethernet you
++        will need to select this option to use GMAC2 and GMAC3 with
++        external PHYs, SFP(+) cages in 10GBase-R, 5GBase-R or USXGMII
++        interface modes.
++
++        Note that as the 2500Base-X/1000Base-X/Cisco SGMII SerDes PCS
++        unit (MediaTek LynxI) in MT7988 is connected via the new 10GE
++        SerDes, you will also need to select this option in case you
++        want to use any of those SerDes modes.
++
+ config NET_MEDIATEK_STAR_EMAC
+       tristate "MediaTek STAR Ethernet MAC support"
+       select PHYLIB
+--- a/drivers/net/ethernet/mediatek/Makefile
++++ b/drivers/net/ethernet/mediatek/Makefile
+@@ -5,6 +5,7 @@
+ obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
+ mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
++mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_USXGMII) += mtk_usxgmii.o
+ mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o
+ ifdef CONFIG_DEBUG_FS
+ mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
+--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
+@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64
+               return "gmac2_rgmii";
+       case MTK_ETH_PATH_GMAC2_SGMII:
+               return "gmac2_sgmii";
++      case MTK_ETH_PATH_GMAC2_2P5GPHY:
++              return "gmac2_2p5gphy";
+       case MTK_ETH_PATH_GMAC2_GEPHY:
+               return "gmac2_gephy";
++      case MTK_ETH_PATH_GMAC3_SGMII:
++              return "gmac3_sgmii";
+       case MTK_ETH_PATH_GDM1_ESW:
+               return "gdm1_esw";
++      case MTK_ETH_PATH_GMAC1_USXGMII:
++              return "gmac1_usxgmii";
++      case MTK_ETH_PATH_GMAC2_USXGMII:
++              return "gmac2_usxgmii";
++      case MTK_ETH_PATH_GMAC3_USXGMII:
++              return "gmac3_usxgmii";
+       default:
+               return "unknown path";
+       }
+@@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(stru
+       return 0;
+ }
++static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path)
++{
++      int ret;
++
++      if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) {
++              ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2);
++              if (ret)
++                      return ret;
++
++              /* Setup mux to 2p5g PHY */
++              ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL);
++              if (ret)
++                      return ret;
++
++              dev_dbg(eth->dev, "path %s in %s updated\n",
++                      mtk_eth_path_name(path), __func__);
++      }
++
++      return 0;
++}
++
+ static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0;
+@@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_
+       return 0;
+ }
+-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
++static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path)
++{
++      unsigned int val = 0;
++      bool updated = true;
++      int mac_id = 0;
++
++      /* Disable SYSCFG1 SGMII */
++      regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
++
++      switch (path) {
++      case MTK_ETH_PATH_GMAC1_USXGMII:
++              val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2;
++              mac_id = MTK_GMAC1_ID;
++              break;
++      case MTK_ETH_PATH_GMAC2_USXGMII:
++              val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
++              mac_id = MTK_GMAC2_ID;
++              break;
++      case MTK_ETH_PATH_GMAC3_USXGMII:
++              val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2;
++              mac_id = MTK_GMAC3_ID;
++              break;
++      default:
++              updated = false;
++      };
++
++      if (updated) {
++              regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
++                                 SYSCFG0_SGMII_MASK, val);
++
++              if (mac_id == MTK_GMAC2_ID)
++                      regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX,
++                                      MUX_G2_USXGMII_SEL);
++      }
++
++      dev_dbg(eth->dev, "path %s in %s updated = %d\n",
++              mtk_eth_path_name(path), __func__, updated);
++
++      return 0;
++}
++
++static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0;
+       bool updated = true;
+@@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii
+       case MTK_ETH_PATH_GMAC2_SGMII:
+               val |= SYSCFG0_SGMII_GMAC2_V2;
+               break;
++      case MTK_ETH_PATH_GMAC3_SGMII:
++              val |= SYSCFG0_SGMII_GMAC3_V2;
++              break;
+       default:
+               updated = false;
+       }
+@@ -210,13 +285,25 @@ static const struct mtk_eth_muxc mtk_eth
+               .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
+               .set_path = set_mux_u3_gmac2_to_qphy,
+       }, {
++              .name = "mux_gmac2_to_2p5gphy",
++              .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY,
++              .set_path = set_mux_gmac2_to_2p5gphy,
++      }, {
+               .name = "mux_gmac1_gmac2_to_sgmii_rgmii",
+               .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
+               .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii,
+       }, {
+               .name = "mux_gmac12_to_gephy_sgmii",
+               .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
+-              .set_path = set_mux_gmac12_to_gephy_sgmii,
++              .set_path = set_mux_gmac123_to_gephy_sgmii,
++      }, {
++              .name = "mux_gmac123_to_gephy_sgmii",
++              .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII,
++              .set_path = set_mux_gmac123_to_gephy_sgmii,
++      }, {
++              .name = "mux_gmac123_to_usxgmii",
++              .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII,
++              .set_path = set_mux_gmac123_to_usxgmii,
+       },
+ };
+@@ -249,12 +336,39 @@ out:
+       return err;
+ }
++int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id)
++{
++      u64 path;
++
++      path = (mac_id == MTK_GMAC1_ID) ?  MTK_ETH_PATH_GMAC1_USXGMII :
++             (mac_id == MTK_GMAC2_ID) ?  MTK_ETH_PATH_GMAC2_USXGMII :
++                                         MTK_ETH_PATH_GMAC3_USXGMII;
++
++      /* Setup proper MUXes along the path */
++      return mtk_eth_mux_setup(eth, path);
++}
++
+ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
+ {
+       u64 path;
+-      path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
+-                              MTK_ETH_PATH_GMAC2_SGMII;
++      path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII :
++             (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII :
++                                        MTK_ETH_PATH_GMAC3_SGMII;
++
++      /* Setup proper MUXes along the path */
++      return mtk_eth_mux_setup(eth, path);
++}
++
++int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id)
++{
++      u64 path = 0;
++
++      if (mac_id == MTK_GMAC2_ID)
++              path = MTK_ETH_PATH_GMAC2_2P5GPHY;
++
++      if (!path)
++              return -EINVAL;
+       /* Setup proper MUXes along the path */
+       return mtk_eth_mux_setup(eth, path);
+@@ -284,4 +398,3 @@ int mtk_gmac_rgmii_path_setup(struct mtk
+       /* Setup proper MUXes along the path */
+       return mtk_eth_mux_setup(eth, path);
+ }
+-
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -431,6 +431,30 @@ static void mtk_setup_bridge_switch(stru
+               MTK_GSW_CFG);
+ }
++static bool mtk_check_gmac23_idle(struct mtk_mac *mac)
++{
++      u32 mac_fsm, gdm_fsm;
++
++      mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id));
++
++      switch (mac->id) {
++      case MTK_GMAC2_ID:
++              gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM);
++              break;
++      case MTK_GMAC3_ID:
++              gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM);
++              break;
++      default:
++              return true;
++      };
++
++      if ((mac_fsm & 0xFFFF0000) == 0x01010000 &&
++          (gdm_fsm & 0xFFFF0000) == 0x00000000)
++              return true;
++
++      return false;
++}
++
+ static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
+                                             phy_interface_t interface)
+ {
+@@ -439,12 +463,20 @@ static struct phylink_pcs *mtk_mac_selec
+       struct mtk_eth *eth = mac->hw;
+       unsigned int sid;
+-      if (interface == PHY_INTERFACE_MODE_SGMII ||
+-          phy_interface_mode_is_8023z(interface)) {
+-              sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
+-                     0 : mac->id;
+-
+-              return eth->sgmii_pcs[sid];
++      if ((interface == PHY_INTERFACE_MODE_SGMII ||
++           phy_interface_mode_is_8023z(interface)) &&
++          MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
++              sid = mtk_mac2xgmii_id(eth, mac->id);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII))
++                      return mtk_sgmii_wrapper_select_pcs(eth, mac->id);
++              else
++                      return eth->sgmii_pcs[sid];
++      } else if ((interface == PHY_INTERFACE_MODE_USXGMII ||
++                  interface == PHY_INTERFACE_MODE_10GBASER ||
++                  interface == PHY_INTERFACE_MODE_5GBASER) &&
++                 MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII) &&
++                 mac->id != MTK_GMAC1_ID) {
++              return mtk_usxgmii_select_pcs(eth, mac->id);
+       }
+       return NULL;
+@@ -500,7 +532,22 @@ static void mtk_mac_config(struct phylin
+                                       goto init_err;
+                       }
+                       break;
++              case PHY_INTERFACE_MODE_USXGMII:
++              case PHY_INTERFACE_MODE_10GBASER:
++              case PHY_INTERFACE_MODE_5GBASER:
++                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
++                              err = mtk_gmac_usxgmii_path_setup(eth, mac->id);
++                              if (err)
++                                      goto init_err;
++                      }
++                      break;
+               case PHY_INTERFACE_MODE_INTERNAL:
++                      if (mac->id == MTK_GMAC2_ID &&
++                          MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) {
++                              err = mtk_gmac_2p5gphy_path_setup(eth, mac->id);
++                              if (err)
++                                      goto init_err;
++                      }
+                       break;
+               default:
+                       goto err_phy;
+@@ -555,8 +602,6 @@ static void mtk_mac_config(struct phylin
+               val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
+               val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
+               regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
+-
+-              mac->interface = state->interface;
+       }
+       /* SGMII */
+@@ -573,21 +618,40 @@ static void mtk_mac_config(struct phylin
+               /* Save the syscfg0 value for mac_finish */
+               mac->syscfg0 = val;
+-      } else if (phylink_autoneg_inband(mode)) {
++      } else if (state->interface != PHY_INTERFACE_MODE_USXGMII &&
++                 state->interface != PHY_INTERFACE_MODE_10GBASER &&
++                 state->interface != PHY_INTERFACE_MODE_5GBASER &&
++                 phylink_autoneg_inband(mode)) {
+               dev_err(eth->dev,
+-                      "In-band mode not supported in non SGMII mode!\n");
++                      "In-band mode not supported in non-SerDes modes!\n");
+               return;
+       }
+       /* Setup gmac */
+-      if (mtk_is_netsys_v3_or_greater(eth) &&
+-          mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
+-              mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
+-              mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
++      if (mtk_is_netsys_v3_or_greater(eth)) {
++              if (mtk_interface_mode_is_xgmii(state->interface)) {
++                      mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
++                      mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
++
++                      if (mac->id == MTK_GMAC1_ID)
++                              mtk_setup_bridge_switch(eth);
++              } else {
++                      mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id));
+-              mtk_setup_bridge_switch(eth);
++                      /* FIXME: In current hardware design, we have to reset FE
++                       * when swtiching XGDM to GDM. Therefore, here trigger an SER
++                       * to let GDM go back to the initial state.
++                       */
++                      if ((mtk_interface_mode_is_xgmii(mac->interface) ||
++                           mac->interface == PHY_INTERFACE_MODE_NA) &&
++                          !mtk_check_gmac23_idle(mac) &&
++                          !test_bit(MTK_RESETTING, &eth->state))
++                              schedule_work(&eth->pending_work);
++              }
+       }
++      mac->interface = state->interface;
++
+       return;
+ err_phy:
+@@ -633,10 +697,13 @@ static void mtk_mac_link_down(struct phy
+ {
+       struct mtk_mac *mac = container_of(config, struct mtk_mac,
+                                          phylink_config);
+-      u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+-      mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
+-      mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
++      if (!mtk_interface_mode_is_xgmii(interface)) {
++              mtk_m32(mac->hw, MAC_MCR_TX_EN | MAC_MCR_RX_EN, 0, MTK_MAC_MCR(mac->id));
++              mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id));
++      } else if (mac->id != MTK_GMAC1_ID) {
++              mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id));
++      }
+ }
+ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
+@@ -708,13 +775,11 @@ static void mtk_set_queue_speed(struct m
+       mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
+ }
+-static void mtk_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)
++static void mtk_gdm_mac_link_up(struct mtk_mac *mac,
++                              struct phy_device *phy,
++                              unsigned int mode, phy_interface_t interface,
++                              int speed, int duplex, bool tx_pause, bool rx_pause)
+ {
+-      struct mtk_mac *mac = container_of(config, struct mtk_mac,
+-                                         phylink_config);
+       u32 mcr;
+       mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+@@ -748,6 +813,55 @@ static void mtk_mac_link_up(struct phyli
+       mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
+ }
++static void mtk_xgdm_mac_link_up(struct mtk_mac *mac,
++                               struct phy_device *phy,
++                               unsigned int mode, phy_interface_t interface,
++                               int speed, int duplex, bool tx_pause, bool rx_pause)
++{
++      u32 mcr, force_link = 0;
++
++      if (mac->id == MTK_GMAC1_ID)
++              return;
++
++      /* Eliminate the interference(before link-up) caused by PHY noise */
++      mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id));
++      mdelay(20);
++      mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id));
++
++      if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID)
++              force_link = MTK_XGMAC_FORCE_LINK(mac->id);
++
++      mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id));
++
++      mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
++      mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE);
++      /* Configure pause modes -
++       * phylink will avoid these for half duplex
++       */
++      if (tx_pause)
++              mcr |= XMAC_MCR_FORCE_TX_FC;
++      if (rx_pause)
++              mcr |= XMAC_MCR_FORCE_RX_FC;
++
++      mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
++}
++
++static void mtk_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)
++{
++      struct mtk_mac *mac = container_of(config, struct mtk_mac,
++                                         phylink_config);
++
++      if (mtk_interface_mode_is_xgmii(interface))
++              mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
++                                   tx_pause, rx_pause);
++      else
++              mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
++                                  tx_pause, rx_pause);
++}
++
+ static const struct phylink_mac_ops mtk_phylink_ops = {
+       .validate = phylink_generic_validate,
+       .mac_select_pcs = mtk_mac_select_pcs,
+@@ -4558,8 +4672,21 @@ static int mtk_add_mac(struct mtk_eth *e
+               phy_interface_zero(mac->phylink_config.supported_interfaces);
+               __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+                         mac->phylink_config.supported_interfaces);
++      } else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) {
++              mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD;
++              __set_bit(PHY_INTERFACE_MODE_5GBASER,
++                        mac->phylink_config.supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_10GBASER,
++                        mac->phylink_config.supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_USXGMII,
++                        mac->phylink_config.supported_interfaces);
+       }
++      if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) &&
++          id == MTK_GMAC2_ID)
++              __set_bit(PHY_INTERFACE_MODE_INTERNAL,
++                        mac->phylink_config.supported_interfaces);
++
+       phylink = phylink_create(&mac->phylink_config,
+                                of_fwnode_handle(mac->of_node),
+                                phy_mode, &mtk_phylink_ops);
+@@ -4752,6 +4879,13 @@ static int mtk_probe(struct platform_dev
+               if (err)
+                       return err;
++      }
++
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
++              err = mtk_usxgmii_init(eth);
++
++              if (err)
++                      return err;
+       }
+       if (eth->soc->required_pctl) {
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -499,6 +499,21 @@
+ #define INTF_MODE_RGMII_1000    (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
+ #define INTF_MODE_RGMII_10_100  0
++/* XFI Mac control registers */
++#define MTK_XMAC_BASE(x)      (0x12000 + (((x) - 1) * 0x1000))
++#define MTK_XMAC_MCR(x)               (MTK_XMAC_BASE(x))
++#define XMAC_MCR_TRX_DISABLE  0xf
++#define XMAC_MCR_FORCE_TX_FC  BIT(5)
++#define XMAC_MCR_FORCE_RX_FC  BIT(4)
++
++/* XFI Mac logic reset registers */
++#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + 0x10)
++#define XMAC_LOGIC_RST                BIT(0)
++
++/* XFI Mac count global control */
++#define MTK_XMAC_CNT_CTRL(x)  (MTK_XMAC_BASE(x) + 0x100)
++#define XMAC_GLB_CNTCLR               BIT(0)
++
+ /* GPIO port control registers for GMAC 2*/
+ #define GPIO_OD33_CTRL8               0x4c0
+ #define GPIO_BIAS_CTRL                0xed0
+@@ -524,6 +539,7 @@
+ #define SYSCFG0_SGMII_GMAC2    ((3 << 8) & SYSCFG0_SGMII_MASK)
+ #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
+ #define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
++#define SYSCFG0_SGMII_GMAC3_V2 BIT(7)
+ /* ethernet subsystem clock register */
+@@ -556,12 +572,74 @@
+ #define ETHSYS_DMA_AG_MAP_QDMA        BIT(1)
+ #define ETHSYS_DMA_AG_MAP_PPE BIT(2)
++/* USXGMII subsystem config registers */
++/* Register to control speed */
++#define RG_PHY_TOP_SPEED_CTRL1        0x80C
++#define USXGMII_RATE_UPDATE_MODE      BIT(31)
++#define USXGMII_MAC_CK_GATED  BIT(29)
++#define USXGMII_IF_FORCE_EN   BIT(28)
++#define USXGMII_RATE_ADAPT_MODE       GENMASK(10, 8)
++#define USXGMII_RATE_ADAPT_MODE_X1    0
++#define USXGMII_RATE_ADAPT_MODE_X2    1
++#define USXGMII_RATE_ADAPT_MODE_X4    2
++#define USXGMII_RATE_ADAPT_MODE_X10   3
++#define USXGMII_RATE_ADAPT_MODE_X100  4
++#define USXGMII_RATE_ADAPT_MODE_X5    5
++#define USXGMII_RATE_ADAPT_MODE_X50   6
++#define USXGMII_XFI_RX_MODE   GENMASK(6, 4)
++#define USXGMII_XFI_RX_MODE_10G       0
++#define USXGMII_XFI_RX_MODE_5G        1
++#define USXGMII_XFI_TX_MODE   GENMASK(2, 0)
++#define USXGMII_XFI_TX_MODE_10G       0
++#define USXGMII_XFI_TX_MODE_5G        1
++
++/* Register to control PCS AN */
++#define RG_PCS_AN_CTRL0               0x810
++#define USXGMII_AN_RESTART    BIT(31)
++#define USXGMII_AN_SYNC_CNT   GENMASK(30, 11)
++#define USXGMII_AN_ENABLE     BIT(0)
++
++#define RG_PCS_AN_CTRL2               0x818
++#define USXGMII_LINK_TIMER_IDLE_DETECT        GENMASK(29, 20)
++#define USXGMII_LINK_TIMER_COMP_ACK_DETECT    GENMASK(19, 10)
++#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0)
++
++/* Register to read PCS AN status */
++#define RG_PCS_AN_STS0                0x81c
++#define USXGMII_PCS_AN_WORD   GENMASK(15, 0)
++#define USXGMII_LPA_LATCH     BIT(31)
++
++/* Register to control USXGMII XFI PLL digital */
++#define XFI_PLL_DIG_GLB8      0x08
++#define RG_XFI_PLL_EN         BIT(31)
++
++/* Register to control USXGMII XFI PLL analog */
++#define XFI_PLL_ANA_GLB8      0x108
++#define RG_XFI_PLL_ANA_SWWA   0x02283248
++
+ /* Infrasys subsystem config registers */
+ #define INFRA_MISC2            0x70c
+ #define CO_QPHY_SEL            BIT(0)
+ #define GEPHY_MAC_SEL          BIT(1)
++/* Toprgu subsystem config registers */
++#define TOPRGU_SWSYSRST               0x18
++#define SWSYSRST_UNLOCK_KEY   GENMASK(31, 24)
++#define SWSYSRST_XFI_PLL_GRST BIT(16)
++#define SWSYSRST_XFI_PEXPT1_GRST      BIT(15)
++#define SWSYSRST_XFI_PEXPT0_GRST      BIT(14)
++#define SWSYSRST_XFI1_GRST    BIT(13)
++#define SWSYSRST_XFI0_GRST    BIT(12)
++#define SWSYSRST_SGMII1_GRST  BIT(2)
++#define SWSYSRST_SGMII0_GRST  BIT(1)
++#define TOPRGU_SWSYSRST_EN            0xFC
++
+ /* Top misc registers */
++#define TOP_MISC_NETSYS_PCS_MUX       0x84
++#define NETSYS_PCS_MUX_MASK   GENMASK(1, 0)
++#define       MUX_G2_USXGMII_SEL      BIT(1)
++#define MUX_HSGMII1_G1_SEL    BIT(0)
++
+ #define USB_PHY_SWITCH_REG    0x218
+ #define QPHY_SEL_MASK         GENMASK(1, 0)
+ #define SGMII_QPHY_SEL                0x2
+@@ -586,6 +664,8 @@
+ #define MT7628_SDM_RBCNT      (MT7628_SDM_OFFSET + 0x10c)
+ #define MT7628_SDM_CS_ERR     (MT7628_SDM_OFFSET + 0x110)
++/* Debug Purpose Register */
++#define MTK_PSE_FQFC_CFG      0x100
+ #define MTK_FE_CDM1_FSM               0x220
+ #define MTK_FE_CDM2_FSM               0x224
+ #define MTK_FE_CDM3_FSM               0x238
+@@ -594,6 +674,11 @@
+ #define MTK_FE_CDM6_FSM               0x328
+ #define MTK_FE_GDM1_FSM               0x228
+ #define MTK_FE_GDM2_FSM               0x22C
++#define MTK_FE_GDM3_FSM               0x23C
++#define MTK_FE_PSE_FREE               0x240
++#define MTK_FE_DROP_FQ                0x244
++#define MTK_FE_DROP_FC                0x248
++#define MTK_FE_DROP_PPE               0x24C
+ #define MTK_MAC_FSM(x)                (0x1010C + ((x) * 0x100))
+@@ -940,6 +1025,8 @@ enum mkt_eth_capabilities {
+       MTK_RGMII_BIT = 0,
+       MTK_TRGMII_BIT,
+       MTK_SGMII_BIT,
++      MTK_USXGMII_BIT,
++      MTK_2P5GPHY_BIT,
+       MTK_ESW_BIT,
+       MTK_GEPHY_BIT,
+       MTK_MUX_BIT,
+@@ -960,8 +1047,11 @@ enum mkt_eth_capabilities {
+       MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
+       MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
+       MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
++      MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT,
+       MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
+       MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
++      MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
++      MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
+       /* PATH BITS */
+       MTK_ETH_PATH_GMAC1_RGMII_BIT,
+@@ -969,14 +1059,21 @@ enum mkt_eth_capabilities {
+       MTK_ETH_PATH_GMAC1_SGMII_BIT,
+       MTK_ETH_PATH_GMAC2_RGMII_BIT,
+       MTK_ETH_PATH_GMAC2_SGMII_BIT,
++      MTK_ETH_PATH_GMAC2_2P5GPHY_BIT,
+       MTK_ETH_PATH_GMAC2_GEPHY_BIT,
++      MTK_ETH_PATH_GMAC3_SGMII_BIT,
+       MTK_ETH_PATH_GDM1_ESW_BIT,
++      MTK_ETH_PATH_GMAC1_USXGMII_BIT,
++      MTK_ETH_PATH_GMAC2_USXGMII_BIT,
++      MTK_ETH_PATH_GMAC3_USXGMII_BIT,
+ };
+ /* Supported hardware group on SoCs */
+ #define MTK_RGMII             BIT_ULL(MTK_RGMII_BIT)
+ #define MTK_TRGMII            BIT_ULL(MTK_TRGMII_BIT)
+ #define MTK_SGMII             BIT_ULL(MTK_SGMII_BIT)
++#define MTK_USXGMII           BIT_ULL(MTK_USXGMII_BIT)
++#define MTK_2P5GPHY           BIT_ULL(MTK_2P5GPHY_BIT)
+ #define MTK_ESW                       BIT_ULL(MTK_ESW_BIT)
+ #define MTK_GEPHY             BIT_ULL(MTK_GEPHY_BIT)
+ #define MTK_MUX                       BIT_ULL(MTK_MUX_BIT)
+@@ -999,10 +1096,16 @@ enum mkt_eth_capabilities {
+       BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
+ #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY          \
+       BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
++#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY          \
++      BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT)
+ #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII        \
+       BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
+ #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII     \
+       BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
++#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII    \
++      BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT)
++#define MTK_ETH_MUX_GMAC123_TO_USXGMII        \
++      BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
+ /* Supported path present on SoCs */
+ #define MTK_ETH_PATH_GMAC1_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
+@@ -1010,8 +1113,13 @@ enum mkt_eth_capabilities {
+ #define MTK_ETH_PATH_GMAC1_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
+ #define MTK_ETH_PATH_GMAC2_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
+ #define MTK_ETH_PATH_GMAC2_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
++#define MTK_ETH_PATH_GMAC2_2P5GPHY    BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT)
+ #define MTK_ETH_PATH_GMAC2_GEPHY      BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
++#define MTK_ETH_PATH_GMAC3_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
+ #define MTK_ETH_PATH_GDM1_ESW         BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
++#define MTK_ETH_PATH_GMAC1_USXGMII    BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
++#define MTK_ETH_PATH_GMAC2_USXGMII    BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
++#define MTK_ETH_PATH_GMAC3_USXGMII    BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
+ #define MTK_GMAC1_RGMII               (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
+ #define MTK_GMAC1_TRGMII      (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
+@@ -1019,7 +1127,12 @@ enum mkt_eth_capabilities {
+ #define MTK_GMAC2_RGMII               (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
+ #define MTK_GMAC2_SGMII               (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
+ #define MTK_GMAC2_GEPHY               (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
++#define MTK_GMAC2_2P5GPHY     (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY)
++#define MTK_GMAC3_SGMII               (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
+ #define MTK_GDM1_ESW          (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
++#define MTK_GMAC1_USXGMII     (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
++#define MTK_GMAC2_USXGMII     (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
++#define MTK_GMAC3_USXGMII     (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
+ /* MUXes present on SoCs */
+ /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
+@@ -1038,10 +1151,20 @@ enum mkt_eth_capabilities {
+       (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
+       MTK_SHARED_SGMII)
++/* 2: GMAC2 -> XGMII */
++#define MTK_MUX_GMAC2_TO_2P5GPHY      \
++      (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA)
++
+ /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */
+ #define MTK_MUX_GMAC12_TO_GEPHY_SGMII   \
+       (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
++#define MTK_MUX_GMAC123_TO_GEPHY_SGMII   \
++      (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX)
++
++#define MTK_MUX_GMAC123_TO_USXGMII   \
++      (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
++
+ #define MTK_HAS_CAPS(caps, _x)                (((caps) & (_x)) == (_x))
+ #define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
+@@ -1073,8 +1196,12 @@ enum mkt_eth_capabilities {
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_RSTCTRL_PPE1 | MTK_SRAM)
+-#define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \
+-                    MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
++#define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \
++                    MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \
++                    MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \
++                    MTK_MUX_GMAC123_TO_GEPHY_SGMII | \
++                    MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \
++                    MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
+ struct mtk_tx_dma_desc_info {
+       dma_addr_t      addr;
+@@ -1184,6 +1311,24 @@ struct mtk_soc_data {
+ /* currently no SoC has more than 3 macs */
+ #define MTK_MAX_DEVS  3
++/* struct mtk_usxgmii_pcs - This structure holds each usxgmii regmap and
++ *                    associated data
++ * @regmap:           The register map pointing at the range used to setup
++ *                    USXGMII modes
++ * @interface:                Currently selected interface mode
++ * @id:                       The element is used to record the index of PCS
++ * @pcs:              Phylink PCS structure
++ */
++struct mtk_usxgmii_pcs {
++      struct mtk_eth          *eth;
++      struct regmap           *regmap;
++      struct phylink_pcs      *wrapped_sgmii_pcs;
++      phy_interface_t         interface;
++      u8                      id;
++      unsigned int            mode;
++      struct phylink_pcs      pcs;
++};
++
+ /* struct mtk_eth -   This is the main datasructure for holding the state
+  *                    of the driver
+  * @dev:              The device pointer
+@@ -1204,6 +1349,12 @@ struct mtk_soc_data {
+  * @infra:              The register map pointing at the range used to setup
+  *                      SGMII and GePHY path
+  * @sgmii_pcs:                Pointers to mtk-pcs-lynxi phylink_pcs instances
++ * @sgmii_wrapped_pcs:        Pointers to NETSYSv3 wrapper PCS instances
++ * @usxgmii_pll:      The register map pointing at the range used to control
++ *                    the USXGMII SerDes PLL
++ * @regmap_pextp:     The register map pointing at the range used to setup
++ *                    PHYA
++ * @usxgmii_pcs:      Pointer to array of pointers to struct for USXGMII PCS
+  * @pctl:             The register map pointing at the range used to setup
+  *                    GMAC port drive/slew values
+  * @dma_refcnt:               track how many netdevs are using the DMA engine
+@@ -1247,6 +1398,10 @@ struct mtk_eth {
+       struct regmap                   *ethsys;
+       struct regmap                   *infra;
+       struct phylink_pcs              *sgmii_pcs[MTK_MAX_DEVS];
++      struct regmap                   *toprgu;
++      struct regmap                   *usxgmii_pll;
++      struct regmap                   *regmap_pextp[MTK_MAX_DEVS];
++      struct mtk_usxgmii_pcs          *usxgmii_pcs[MTK_MAX_DEVS];
+       struct regmap                   *pctl;
+       bool                            hwlro;
+       refcount_t                      dma_refcnt;
+@@ -1434,6 +1589,19 @@ static inline u32 mtk_get_ib2_multicast_
+       return MTK_FOE_IB2_MULTICAST;
+ }
++static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
++{
++      switch (interface) {
++      case PHY_INTERFACE_MODE_INTERNAL:
++      case PHY_INTERFACE_MODE_USXGMII:
++      case PHY_INTERFACE_MODE_10GBASER:
++      case PHY_INTERFACE_MODE_5GBASER:
++              return true;
++      default:
++              return false;
++      }
++}
++
+ /* read the hardware status register */
+ void mtk_stats_update_mac(struct mtk_mac *mac);
+@@ -1442,8 +1610,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
+ u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
+ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
++int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id);
+ int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
+ int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
++int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id);
+ int mtk_eth_offload_init(struct mtk_eth *eth);
+ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
+@@ -1453,5 +1623,63 @@ int mtk_flow_offload_cmd(struct mtk_eth
+ void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list);
+ void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
++static inline int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id)
++{
++      int xgmii_id = mac_id;
++
++      if (mtk_is_netsys_v3_or_greater(eth)) {
++              switch (mac_id) {
++              case MTK_GMAC1_ID:
++              case MTK_GMAC2_ID:
++                      xgmii_id = 1;
++                      break;
++              case MTK_GMAC3_ID:
++                      xgmii_id = 0;
++                      break;
++              default:
++                      xgmii_id = -1;
++              }
++      }
++
++      return MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII) ? 0 : xgmii_id;
++}
++
++static inline int mtk_xgmii2mac_id(struct mtk_eth *eth, int xgmii_id)
++{
++      int mac_id = xgmii_id;
++
++      if (mtk_is_netsys_v3_or_greater(eth)) {
++              switch (xgmii_id) {
++              case 0:
++                      mac_id = 2;
++                      break;
++              case 1:
++                      mac_id = 1;
++                      break;
++              default:
++                      mac_id = -1;
++              }
++      }
++
++      return mac_id;
++}
++
++#ifdef CONFIG_NET_MEDIATEK_SOC_USXGMII
++struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id);
++struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id);
++int mtk_usxgmii_init(struct mtk_eth *eth);
++#else
++static inline struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id)
++{
++      return NULL;
++}
++
++static inline struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id)
++{
++      return NULL;
++}
++
++static inline int mtk_usxgmii_init(struct mtk_eth *eth) { return 0; }
++#endif /* NET_MEDIATEK_SOC_USXGMII */
+ #endif /* MTK_ETH_H */
+--- /dev/null
++++ b/drivers/net/ethernet/mediatek/mtk_usxgmii.c
+@@ -0,0 +1,690 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2023 MediaTek Inc.
++ * Author: Henry Yen <henry.yen@mediatek.com>
++ *         Daniel Golle <daniel@makrotopia.org>
++ */
++
++#include <linux/mfd/syscon.h>
++#include <linux/of.h>
++#include <linux/regmap.h>
++#include "mtk_eth_soc.h"
++
++static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs)
++{
++      return container_of(pcs, struct mtk_usxgmii_pcs, pcs);
++}
++
++static int mtk_xfi_pextp_init(struct mtk_eth *eth)
++{
++      struct device *dev = eth->dev;
++      struct device_node *r = dev->of_node;
++      struct device_node *np;
++      int i;
++
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
++              np = of_parse_phandle(r, "mediatek,xfi-pextp", i);
++              if (!np)
++                      break;
++
++              eth->regmap_pextp[i] = syscon_node_to_regmap(np);
++              if (IS_ERR(eth->regmap_pextp[i]))
++                      return PTR_ERR(eth->regmap_pextp[i]);
++      }
++
++      return 0;
++}
++
++static int mtk_xfi_pll_init(struct mtk_eth *eth)
++{
++      struct device_node *r = eth->dev->of_node;
++      struct device_node *np;
++
++      np = of_parse_phandle(r, "mediatek,xfi-pll", 0);
++      if (!np)
++              return -1;
++
++      eth->usxgmii_pll = syscon_node_to_regmap(np);
++      if (IS_ERR(eth->usxgmii_pll))
++              return PTR_ERR(eth->usxgmii_pll);
++
++      return 0;
++}
++
++static int mtk_toprgu_init(struct mtk_eth *eth)
++{
++      struct device_node *r = eth->dev->of_node;
++      struct device_node *np;
++
++      np = of_parse_phandle(r, "mediatek,toprgu", 0);
++      if (!np)
++              return -1;
++
++      eth->toprgu = syscon_node_to_regmap(np);
++      if (IS_ERR(eth->toprgu))
++              return PTR_ERR(eth->toprgu);
++
++      return 0;
++}
++
++static int mtk_xfi_pll_enable(struct mtk_eth *eth)
++{
++      u32 val = 0;
++
++      if (!eth->usxgmii_pll)
++              return -EINVAL;
++
++      /* Add software workaround for USXGMII PLL TCL issue */
++      regmap_write(eth->usxgmii_pll, XFI_PLL_ANA_GLB8, RG_XFI_PLL_ANA_SWWA);
++
++      regmap_read(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, &val);
++      val |= RG_XFI_PLL_EN;
++      regmap_write(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, val);
++
++      return 0;
++}
++
++static void mtk_usxgmii_setup_phya(struct regmap *pextp, phy_interface_t interface, int id)
++{
++      bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
++                     interface == PHY_INTERFACE_MODE_USXGMII);
++      bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
++      bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
++
++      /* Setup operation mode */
++      if (is_10g)
++              regmap_write(pextp, 0x9024, 0x00C9071C);
++      else
++              regmap_write(pextp, 0x9024, 0x00D9071C);
++
++      if (is_5g)
++              regmap_write(pextp, 0x2020, 0xAAA5A5AA);
++      else
++              regmap_write(pextp, 0x2020, 0xAA8585AA);
++
++      if (is_2p5g || is_5g || is_10g) {
++              regmap_write(pextp, 0x2030, 0x0C020707);
++              regmap_write(pextp, 0x2034, 0x0E050F0F);
++              regmap_write(pextp, 0x2040, 0x00140032);
++      } else {
++              regmap_write(pextp, 0x2030, 0x0C020207);
++              regmap_write(pextp, 0x2034, 0x0E05050F);
++              regmap_write(pextp, 0x2040, 0x00200032);
++      }
++
++      if (is_2p5g || is_10g)
++              regmap_write(pextp, 0x50F0, 0x00C014AA);
++      else if (is_5g)
++              regmap_write(pextp, 0x50F0, 0x00C018AA);
++      else
++              regmap_write(pextp, 0x50F0, 0x00C014BA);
++
++      if (is_5g) {
++              regmap_write(pextp, 0x50E0, 0x3777812B);
++              regmap_write(pextp, 0x506C, 0x005C9CFF);
++              regmap_write(pextp, 0x5070, 0x9DFAFAFA);
++              regmap_write(pextp, 0x5074, 0x273F3F3F);
++              regmap_write(pextp, 0x5078, 0xA8883868);
++              regmap_write(pextp, 0x507C, 0x14661466);
++      } else {
++              regmap_write(pextp, 0x50E0, 0x3777C12B);
++              regmap_write(pextp, 0x506C, 0x005F9CFF);
++              regmap_write(pextp, 0x5070, 0x9D9DFAFA);
++              regmap_write(pextp, 0x5074, 0x27273F3F);
++              regmap_write(pextp, 0x5078, 0xA7883C68);
++              regmap_write(pextp, 0x507C, 0x11661166);
++      }
++
++      if (is_2p5g || is_10g) {
++              regmap_write(pextp, 0x5080, 0x0E000AAF);
++              regmap_write(pextp, 0x5084, 0x08080D0D);
++              regmap_write(pextp, 0x5088, 0x02030909);
++      } else if (is_5g) {
++              regmap_write(pextp, 0x5080, 0x0E001ABF);
++              regmap_write(pextp, 0x5084, 0x080B0D0D);
++              regmap_write(pextp, 0x5088, 0x02050909);
++      } else {
++              regmap_write(pextp, 0x5080, 0x0E000EAF);
++              regmap_write(pextp, 0x5084, 0x08080E0D);
++              regmap_write(pextp, 0x5088, 0x02030B09);
++      }
++
++      if (is_5g) {
++              regmap_write(pextp, 0x50E4, 0x0C000000);
++              regmap_write(pextp, 0x50E8, 0x04000000);
++      } else {
++              regmap_write(pextp, 0x50E4, 0x0C0C0000);
++              regmap_write(pextp, 0x50E8, 0x04040000);
++      }
++
++      if (is_2p5g || mtk_interface_mode_is_xgmii(interface))
++              regmap_write(pextp, 0x50EC, 0x0F0F0C06);
++      else
++              regmap_write(pextp, 0x50EC, 0x0F0F0606);
++
++      if (is_5g) {
++              regmap_write(pextp, 0x50A8, 0x50808C8C);
++              regmap_write(pextp, 0x6004, 0x18000000);
++      } else {
++              regmap_write(pextp, 0x50A8, 0x506E8C8C);
++              regmap_write(pextp, 0x6004, 0x18190000);
++      }
++
++      if (is_10g)
++              regmap_write(pextp, 0x00F8, 0x01423342);
++      else if (is_5g)
++              regmap_write(pextp, 0x00F8, 0x00A132A1);
++      else if (is_2p5g)
++              regmap_write(pextp, 0x00F8, 0x009C329C);
++      else
++              regmap_write(pextp, 0x00F8, 0x00FA32FA);
++
++      /* Force SGDT_OUT off and select PCS */
++      if (mtk_interface_mode_is_xgmii(interface))
++              regmap_write(pextp, 0x00F4, 0x80201F20);
++      else
++              regmap_write(pextp, 0x00F4, 0x80201F21);
++
++      /* Force GLB_CKDET_OUT */
++      regmap_write(pextp, 0x0030, 0x00050C00);
++
++      /* Force AEQ on */
++      regmap_write(pextp, 0x0070, 0x02002800);
++      ndelay(1020);
++
++      /* Setup DA default value */
++      regmap_write(pextp, 0x30B0, 0x00000020);
++      regmap_write(pextp, 0x3028, 0x00008A01);
++      regmap_write(pextp, 0x302C, 0x0000A884);
++      regmap_write(pextp, 0x3024, 0x00083002);
++      if (mtk_interface_mode_is_xgmii(interface)) {
++              regmap_write(pextp, 0x3010, 0x00022220);
++              regmap_write(pextp, 0x5064, 0x0F020A01);
++              regmap_write(pextp, 0x50B4, 0x06100600);
++              if (interface == PHY_INTERFACE_MODE_USXGMII)
++                      regmap_write(pextp, 0x3048, 0x40704000);
++              else
++                      regmap_write(pextp, 0x3048, 0x47684100);
++      } else {
++              regmap_write(pextp, 0x3010, 0x00011110);
++              regmap_write(pextp, 0x3048, 0x40704000);
++      }
++
++      if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g)
++              regmap_write(pextp, 0x3064, 0x0000C000);
++
++      if (interface == PHY_INTERFACE_MODE_USXGMII) {
++              regmap_write(pextp, 0x3050, 0xA8000000);
++              regmap_write(pextp, 0x3054, 0x000000AA);
++      } else if (mtk_interface_mode_is_xgmii(interface)) {
++              regmap_write(pextp, 0x3050, 0x00000000);
++              regmap_write(pextp, 0x3054, 0x00000000);
++      } else {
++              regmap_write(pextp, 0x3050, 0xA8000000);
++              regmap_write(pextp, 0x3054, 0x000000AA);
++      }
++
++      if (mtk_interface_mode_is_xgmii(interface))
++              regmap_write(pextp, 0x306C, 0x00000F00);
++      else if (is_2p5g)
++              regmap_write(pextp, 0x306C, 0x22000F00);
++      else
++              regmap_write(pextp, 0x306C, 0x20200F00);
++
++      if (interface == PHY_INTERFACE_MODE_10GBASER && id == 0)
++              regmap_write(pextp, 0xA008, 0x0007B400);
++
++      if (mtk_interface_mode_is_xgmii(interface))
++              regmap_write(pextp, 0xA060, 0x00040000);
++      else
++              regmap_write(pextp, 0xA060, 0x00050000);
++
++      if (is_10g)
++              regmap_write(pextp, 0x90D0, 0x00000001);
++      else if (is_5g)
++              regmap_write(pextp, 0x90D0, 0x00000003);
++      else if (is_2p5g)
++              regmap_write(pextp, 0x90D0, 0x00000005);
++      else
++              regmap_write(pextp, 0x90D0, 0x00000007);
++
++      /* Release reset */
++      regmap_write(pextp, 0x0070, 0x0200E800);
++      usleep_range(150, 500);
++
++      /* Switch to P0 */
++      regmap_write(pextp, 0x0070, 0x0200C111);
++      ndelay(1020);
++      regmap_write(pextp, 0x0070, 0x0200C101);
++      usleep_range(15, 50);
++
++      if (mtk_interface_mode_is_xgmii(interface)) {
++              /* Switch to Gen3 */
++              regmap_write(pextp, 0x0070, 0x0202C111);
++      } else {
++              /* Switch to Gen2 */
++              regmap_write(pextp, 0x0070, 0x0201C111);
++      }
++      ndelay(1020);
++      if (mtk_interface_mode_is_xgmii(interface))
++              regmap_write(pextp, 0x0070, 0x0202C101);
++      else
++              regmap_write(pextp, 0x0070, 0x0201C101);
++      usleep_range(100, 500);
++      regmap_write(pextp, 0x30B0, 0x00000030);
++      if (mtk_interface_mode_is_xgmii(interface))
++              regmap_write(pextp, 0x00F4, 0x80201F00);
++      else
++              regmap_write(pextp, 0x00F4, 0x80201F01);
++
++      regmap_write(pextp, 0x3040, 0x30000000);
++      usleep_range(400, 1000);
++}
++
++static void mtk_usxgmii_reset(struct mtk_eth *eth, int id)
++{
++      u32 toggle, val;
++
++      if (id >= MTK_MAX_DEVS || !eth->toprgu)
++              return;
++
++      switch (id) {
++      case 0:
++              toggle = SWSYSRST_XFI_PEXPT0_GRST | SWSYSRST_XFI0_GRST |
++                       SWSYSRST_SGMII0_GRST;
++              break;
++      case 1:
++              toggle = SWSYSRST_XFI_PEXPT1_GRST | SWSYSRST_XFI1_GRST |
++                       SWSYSRST_SGMII1_GRST;
++              break;
++      default:
++              return;
++      }
++
++      /* Enable software reset */
++      regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle);
++
++      /* Assert USXGMII reset */
++      regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST,
++                      FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) | toggle);
++
++      usleep_range(100, 500);
++
++      /* De-assert USXGMII reset */
++      regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
++      val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
++      val &= ~toggle;
++      regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
++
++      /* Disable software reset */
++      regmap_clear_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle);
++
++      mdelay(10);
++}
++
++/* As the USXGMII PHYA is shared with the 1000Base-X/2500Base-X/Cisco SGMII unit
++ * the psc-mtk-lynxi instance needs to be wrapped, so that calls to .pcs_config
++ * also trigger an initial reset and subsequent configuration of the PHYA.
++ */
++struct mtk_sgmii_wrapper_pcs {
++      struct mtk_eth          *eth;
++      struct phylink_pcs      *wrapped_pcs;
++      u8                      id;
++      struct phylink_pcs      pcs;
++};
++
++static int mtk_sgmii_wrapped_pcs_config(struct phylink_pcs *pcs,
++                                      unsigned int mode,
++                                      phy_interface_t interface,
++                                      const unsigned long *advertising,
++                                      bool permit_pause_to_mac)
++{
++      struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
++      bool full_reconf;
++      int ret;
++
++      full_reconf = interface != wp->eth->usxgmii_pcs[wp->id]->interface;
++      if (full_reconf) {
++              mtk_xfi_pll_enable(wp->eth);
++              mtk_usxgmii_reset(wp->eth, wp->id);
++      }
++
++      ret = wp->wrapped_pcs->ops->pcs_config(wp->wrapped_pcs, mode, interface,
++                                             advertising, permit_pause_to_mac);
++
++      if (full_reconf)
++              mtk_usxgmii_setup_phya(wp->eth->regmap_pextp[wp->id], interface, wp->id);
++
++      wp->eth->usxgmii_pcs[wp->id]->interface = interface;
++
++      return ret;
++}
++
++static void mtk_sgmii_wrapped_pcs_get_state(struct phylink_pcs *pcs,
++                                          struct phylink_link_state *state)
++{
++      struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
++
++      return wp->wrapped_pcs->ops->pcs_get_state(wp->wrapped_pcs, state);
++}
++
++static void mtk_sgmii_wrapped_pcs_an_restart(struct phylink_pcs *pcs)
++{
++      struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
++
++      wp->wrapped_pcs->ops->pcs_an_restart(wp->wrapped_pcs);
++}
++
++static void mtk_sgmii_wrapped_pcs_link_up(struct phylink_pcs *pcs,
++                                        unsigned int mode,
++                                        phy_interface_t interface, int speed,
++                                        int duplex)
++{
++      struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
++
++      wp->wrapped_pcs->ops->pcs_link_up(wp->wrapped_pcs, mode, interface, speed, duplex);
++}
++
++static void mtk_sgmii_wrapped_pcs_disable(struct phylink_pcs *pcs)
++{
++      struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
++
++      wp->wrapped_pcs->ops->pcs_disable(wp->wrapped_pcs);
++
++      wp->eth->usxgmii_pcs[wp->id]->interface = PHY_INTERFACE_MODE_NA;
++}
++
++static const struct phylink_pcs_ops mtk_sgmii_wrapped_pcs_ops = {
++      .pcs_get_state = mtk_sgmii_wrapped_pcs_get_state,
++      .pcs_config = mtk_sgmii_wrapped_pcs_config,
++      .pcs_an_restart = mtk_sgmii_wrapped_pcs_an_restart,
++      .pcs_link_up = mtk_sgmii_wrapped_pcs_link_up,
++      .pcs_disable = mtk_sgmii_wrapped_pcs_disable,
++};
++
++static int mtk_sgmii_wrapper_init(struct mtk_eth *eth)
++{
++      struct mtk_sgmii_wrapper_pcs *wp;
++      int i;
++
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
++              if (!eth->sgmii_pcs[i])
++                      continue;
++
++              if (!eth->usxgmii_pcs[i])
++                      continue;
++
++              /* Make sure all PCS ops are supported by wrapped PCS */
++              if (!eth->sgmii_pcs[i]->ops->pcs_get_state ||
++                  !eth->sgmii_pcs[i]->ops->pcs_config ||
++                  !eth->sgmii_pcs[i]->ops->pcs_an_restart ||
++                  !eth->sgmii_pcs[i]->ops->pcs_link_up ||
++                  !eth->sgmii_pcs[i]->ops->pcs_disable)
++                      return -EOPNOTSUPP;
++
++              wp = devm_kzalloc(eth->dev, sizeof(*wp), GFP_KERNEL);
++              if (!wp)
++                      return -ENOMEM;
++
++              wp->wrapped_pcs = eth->sgmii_pcs[i];
++              wp->id = i;
++              wp->pcs.poll = true;
++              wp->pcs.ops = &mtk_sgmii_wrapped_pcs_ops;
++              wp->eth = eth;
++
++              eth->usxgmii_pcs[i]->wrapped_sgmii_pcs = &wp->pcs;
++      }
++
++      return 0;
++}
++
++struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int mac_id)
++{
++      u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id);
++
++      if (!eth->usxgmii_pcs[xgmii_id])
++              return NULL;
++
++      return eth->usxgmii_pcs[xgmii_id]->wrapped_sgmii_pcs;
++}
++
++static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
++                                phy_interface_t interface,
++                                const unsigned long *advertising,
++                                bool permit_pause_to_mac)
++{
++      struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
++      struct mtk_eth *eth = mpcs->eth;
++      struct regmap *pextp = eth->regmap_pextp[mpcs->id];
++      unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0;
++      bool mode_changed = false;
++
++      if (!pextp)
++              return -ENODEV;
++
++      if (interface == PHY_INTERFACE_MODE_USXGMII) {
++              an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE;
++              link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
++                           FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
++                           FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
++              xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) |
++                         FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G);
++      } else if (interface == PHY_INTERFACE_MODE_10GBASER) {
++              an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF);
++              link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
++                           FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
++                           FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
++              xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) |
++                         FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G);
++              adapt_mode = USXGMII_RATE_UPDATE_MODE;
++      } else if (interface == PHY_INTERFACE_MODE_5GBASER) {
++              an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF);
++              link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) |
++                           FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) |
++                           FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D);
++              xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_5G) |
++                         FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_5G);
++              adapt_mode = USXGMII_RATE_UPDATE_MODE;
++      } else {
++              return -EINVAL;
++      }
++
++      adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1);
++
++      if (mpcs->interface != interface) {
++              mpcs->interface = interface;
++              mode_changed = true;
++      }
++
++      mtk_xfi_pll_enable(eth);
++      mtk_usxgmii_reset(eth, mpcs->id);
++
++      /* Setup USXGMII AN ctrl */
++      regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL0,
++                         USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
++                         an_ctrl);
++
++      regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL2,
++                         USXGMII_LINK_TIMER_IDLE_DETECT |
++                         USXGMII_LINK_TIMER_COMP_ACK_DETECT |
++                         USXGMII_LINK_TIMER_AN_RESTART,
++                         link_timer);
++
++      mpcs->mode = mode;
++
++      /* Gated MAC CK */
++      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
++                         USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED);
++
++      /* Enable interface force mode */
++      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
++                         USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN);
++
++      /* Setup USXGMII adapt mode */
++      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
++                         USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE,
++                         adapt_mode);
++
++      /* Setup USXGMII speed */
++      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
++                         USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE,
++                         xfi_mode);
++
++      usleep_range(1, 10);
++
++      /* Un-gated MAC CK */
++      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
++                         USXGMII_MAC_CK_GATED, 0);
++
++      usleep_range(1, 10);
++
++      /* Disable interface force mode for the AN mode */
++      if (an_ctrl & USXGMII_AN_ENABLE)
++              regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
++                                 USXGMII_IF_FORCE_EN, 0);
++
++      /* Setup USXGMIISYS with the determined property */
++      mtk_usxgmii_setup_phya(pextp, interface, mpcs->id);
++
++      return mode_changed;
++}
++
++static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs,
++                                    struct phylink_link_state *state)
++{
++      struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
++      struct mtk_eth *eth = mpcs->eth;
++      struct mtk_mac *mac = eth->mac[mtk_xgmii2mac_id(eth, mpcs->id)];
++      u32 val = 0;
++
++      regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
++      if (FIELD_GET(USXGMII_AN_ENABLE, val)) {
++              /* Refresh LPA by inverting LPA_LATCH */
++              regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val);
++              regmap_update_bits(mpcs->regmap, RG_PCS_AN_STS0,
++                                 USXGMII_LPA_LATCH,
++                                 !(val & USXGMII_LPA_LATCH));
++
++              regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val);
++
++              phylink_decode_usxgmii_word(state, FIELD_GET(USXGMII_PCS_AN_WORD,
++                                                           val));
++
++              state->interface = mpcs->interface;
++      } else {
++              val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
++
++              if (mac->id == MTK_GMAC2_ID)
++                      val >>= 16;
++
++              switch (FIELD_GET(MTK_USXGMII_PCS_MODE, val)) {
++              case 0:
++                      state->speed = SPEED_10000;
++                      break;
++              case 1:
++                      state->speed = SPEED_5000;
++                      break;
++              case 2:
++                      state->speed = SPEED_2500;
++                      break;
++              case 3:
++                      state->speed = SPEED_1000;
++                      break;
++              }
++
++              state->interface = mpcs->interface;
++              state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, val);
++              state->duplex = DUPLEX_FULL;
++      }
++
++      /* Continuously repeat re-configuration sequence until link comes up */
++      if (state->link == 0)
++              mtk_usxgmii_pcs_config(pcs, mpcs->mode,
++                                     state->interface, NULL, false);
++}
++
++static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs)
++{
++      struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
++      unsigned int val = 0;
++
++      if (!mpcs->regmap)
++              return;
++
++      regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
++      val |= USXGMII_AN_RESTART;
++      regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val);
++}
++
++static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
++                                  phy_interface_t interface,
++                                  int speed, int duplex)
++{
++      /* Reconfiguring USXGMII to ensure the quality of the RX signal
++       * after the line side link up.
++       */
++      mtk_usxgmii_pcs_config(pcs, mode,
++                             interface, NULL, false);
++}
++
++static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = {
++      .pcs_config = mtk_usxgmii_pcs_config,
++      .pcs_get_state = mtk_usxgmii_pcs_get_state,
++      .pcs_an_restart = mtk_usxgmii_pcs_restart_an,
++      .pcs_link_up = mtk_usxgmii_pcs_link_up,
++};
++
++int mtk_usxgmii_init(struct mtk_eth *eth)
++{
++      struct device_node *r = eth->dev->of_node;
++      struct device *dev = eth->dev;
++      struct device_node *np;
++      int i, ret;
++
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
++              np = of_parse_phandle(r, "mediatek,usxgmiisys", i);
++              if (!np)
++                      break;
++
++              eth->usxgmii_pcs[i] = devm_kzalloc(dev, sizeof(*eth->usxgmii_pcs[i]), GFP_KERNEL);
++              if (!eth->usxgmii_pcs[i])
++                      return -ENOMEM;
++
++              eth->usxgmii_pcs[i]->id = i;
++              eth->usxgmii_pcs[i]->eth = eth;
++              eth->usxgmii_pcs[i]->regmap = syscon_node_to_regmap(np);
++              if (IS_ERR(eth->usxgmii_pcs[i]->regmap))
++                      return PTR_ERR(eth->usxgmii_pcs[i]->regmap);
++
++              eth->usxgmii_pcs[i]->pcs.ops = &mtk_usxgmii_pcs_ops;
++              eth->usxgmii_pcs[i]->pcs.poll = true;
++              eth->usxgmii_pcs[i]->interface = PHY_INTERFACE_MODE_NA;
++              eth->usxgmii_pcs[i]->mode = -1;
++
++              of_node_put(np);
++      }
++
++      ret = mtk_xfi_pextp_init(eth);
++      if (ret)
++              return ret;
++
++      ret = mtk_xfi_pll_init(eth);
++      if (ret)
++              return ret;
++
++      ret = mtk_toprgu_init(eth);
++      if (ret)
++              return ret;
++
++      return mtk_sgmii_wrapper_init(eth);
++}
++
++struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int mac_id)
++{
++      u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id);
++
++      if (!eth->usxgmii_pcs[xgmii_id]->regmap)
++              return NULL;
++
++      return &eth->usxgmii_pcs[xgmii_id]->pcs;
++}
index 269c639d6c343b08f49b97c45760f3f7f46a3fd5..da7389689e5eb04584d0a43a0eeacb056bd24a23 100644 (file)
@@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3048,8 +3048,8 @@ static irqreturn_t mtk_handle_irq_rx(int
+@@ -3151,8 +3151,8 @@ static irqreturn_t mtk_handle_irq_rx(int
  
        eth->rx_events++;
        if (likely(napi_schedule_prep(&eth->rx_napi))) {
@@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        }
  
        return IRQ_HANDLED;
-@@ -3061,8 +3061,8 @@ static irqreturn_t mtk_handle_irq_tx(int
+@@ -3164,8 +3164,8 @@ static irqreturn_t mtk_handle_irq_tx(int
  
        eth->tx_events++;
        if (likely(napi_schedule_prep(&eth->tx_napi))) {
@@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        }
  
        return IRQ_HANDLED;
-@@ -4720,6 +4720,8 @@ static int mtk_probe(struct platform_dev
+@@ -4937,6 +4937,8 @@ static int mtk_probe(struct platform_dev
         * for NAPI to work
         */
        init_dummy_netdev(&eth->dummy_dev);
diff --git a/target/linux/generic/pending-6.1/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch b/target/linux/generic/pending-6.1/731-net-ethernet-mediatek-ppe-add-support-for-flow-accou.patch
deleted file mode 100644 (file)
index 4b4ffc6..0000000
+++ /dev/null
@@ -1,428 +0,0 @@
-From patchwork Wed Nov  2 00:58:01 2022
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Daniel Golle <daniel@makrotopia.org>
-X-Patchwork-Id: 13027653
-X-Patchwork-Delegate: kuba@kernel.org
-Return-Path: <netdev-owner@kernel.org>
-Date: Wed, 2 Nov 2022 00:58:01 +0000
-From: Daniel Golle <daniel@makrotopia.org>
-To: Felix Fietkau <nbd@nbd.name>, John Crispin <john@phrozen.org>,
-        Sean Wang <sean.wang@mediatek.com>,
-        Mark Lee <Mark-MC.Lee@mediatek.com>,
-        "David S. Miller" <davem@davemloft.net>,
-        Eric Dumazet <edumazet@google.com>,
-        Jakub Kicinski <kuba@kernel.org>,
-        Paolo Abeni <pabeni@redhat.com>,
-        Matthias Brugger <matthias.bgg@gmail.com>,
-        netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
-        linux-mediatek@lists.infradead.org, linux-kernel@vger.kernel.org
-Subject: [PATCH v4] net: ethernet: mediatek: ppe: add support for flow
- accounting
-Message-ID: <Y2HAmYYPd77dz+K5@makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev@vger.kernel.org
-X-Patchwork-Delegate: kuba@kernel.org
-
-The PPE units found in MT7622 and newer support packet and byte
-accounting of hw-offloaded flows. Add support for reading those
-counters as found in MediaTek's SDK[1].
-
-[1]: https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/bc6a6a375c800dc2b80e1a325a2c732d1737df92
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
-v4: declare function mtk_mib_entry_read as static
-v3: don't bother to set 'false' values in any zero-initialized struct
-    use mtk_foe_entry_ib2
-    both changes were requested by Felix Fietkau
-
-v2: fix wrong variable name in return value check spotted by Denis Kirjanov
-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c   |   7 +-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h   |   1 +
- drivers/net/ethernet/mediatek/mtk_ppe.c       | 110 +++++++++++++++++-
- drivers/net/ethernet/mediatek/mtk_ppe.h       |  23 +++-
- .../net/ethernet/mediatek/mtk_ppe_debugfs.c   |   9 +-
- .../net/ethernet/mediatek/mtk_ppe_offload.c   |   7 ++
- drivers/net/ethernet/mediatek/mtk_ppe_regs.h  |  14 +++
- 7 files changed, 166 insertions(+), 5 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4689,8 +4689,8 @@ static int mtk_probe(struct platform_dev
-               for (i = 0; i < num_ppe; i++) {
-                       u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
--                      eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr,
--                                                 eth->soc->offload_version, i);
-+                      eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
-+
-                       if (!eth->ppe[i]) {
-                               err = -ENOMEM;
-                               goto err_deinit_ppe;
-@@ -4816,6 +4816,7 @@ static const struct mtk_soc_data mt7622_
-       .required_pctl = false,
-       .offload_version = 2,
-       .hash_offset = 2,
-+      .has_accounting = true,
-       .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-@@ -4853,6 +4854,7 @@ static const struct mtk_soc_data mt7629_
-       .hw_features = MTK_HW_FEATURES,
-       .required_clks = MT7629_CLKS_BITMAP,
-       .required_pctl = false,
-+      .has_accounting = true,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-               .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4873,6 +4875,7 @@ static const struct mtk_soc_data mt7981_
-       .offload_version = 2,
-       .hash_offset = 4,
-       .foe_entry_size = sizeof(struct mtk_foe_entry),
-+      .has_accounting = true,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma_v2),
-               .rxd_size = sizeof(struct mtk_rx_dma_v2),
-@@ -4893,6 +4896,7 @@ static const struct mtk_soc_data mt7986_
-       .offload_version = 2,
-       .hash_offset = 4,
-       .foe_entry_size = sizeof(struct mtk_foe_entry),
-+      .has_accounting = true,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma_v2),
-               .rxd_size = sizeof(struct mtk_rx_dma_v2),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1017,6 +1017,8 @@ struct mtk_reg_map {
-  *                            the extra setup for those pins used by GMAC.
-  * @hash_offset                       Flow table hash offset.
-  * @foe_entry_size            Foe table entry size.
-+ * @has_accounting            Bool indicating support for accounting of
-+ *                            offloaded flows.
-  * @txd_size                  Tx DMA descriptor size.
-  * @rxd_size                  Rx DMA descriptor size.
-  * @rx_irq_done_mask          Rx irq done register mask.
-@@ -1034,6 +1036,7 @@ struct mtk_soc_data {
-       u8              hash_offset;
-       u16             foe_entry_size;
-       netdev_features_t hw_features;
-+      bool            has_accounting;
-       struct {
-               u32     txd_size;
-               u32     rxd_size;
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -74,6 +74,48 @@ static int mtk_ppe_wait_busy(struct mtk_
-       return ret;
- }
-+static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe)
-+{
-+      int ret;
-+      u32 val;
-+
-+      ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val,
-+                               !(val & MTK_PPE_MIB_SER_CR_ST),
-+                               20, MTK_PPE_WAIT_TIMEOUT_US);
-+
-+      if (ret)
-+              dev_err(ppe->dev, "MIB table busy");
-+
-+      return ret;
-+}
-+
-+static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
-+{
-+      u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
-+      u32 val, cnt_r0, cnt_r1, cnt_r2;
-+      int ret;
-+
-+      val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST;
-+      ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val);
-+
-+      ret = mtk_ppe_mib_wait_busy(ppe);
-+      if (ret)
-+              return ret;
-+
-+      cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0);
-+      cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
-+      cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
-+
-+      byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
-+      byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
-+      pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
-+      pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
-+      *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
-+      *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
-+
-+      return 0;
-+}
-+
- static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
- {
-       ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR);
-@@ -459,6 +501,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
-               hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
-               dma_wmb();
-               mtk_ppe_cache_clear(ppe);
-+              if (ppe->accounting) {
-+                      struct mtk_foe_accounting *acct;
-+
-+                      acct = ppe->acct_table + entry->hash * sizeof(*acct);
-+                      acct->packets = 0;
-+                      acct->bytes = 0;
-+              }
-       }
-       entry->hash = 0xffff;
-@@ -566,6 +615,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
-       wmb();
-       hwe->ib1 = entry->ib1;
-+      if (ppe->accounting)
-+              *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
-+
-       dma_wmb();
-       mtk_ppe_cache_clear(ppe);
-@@ -757,11 +809,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
-       return mtk_ppe_wait_busy(ppe);
- }
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
--                           int version, int index)
-+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
-+                                               struct mtk_foe_accounting *diff)
-+{
-+      struct mtk_foe_accounting *acct;
-+      int size = sizeof(struct mtk_foe_accounting);
-+      u64 bytes, packets;
-+
-+      if (!ppe->accounting)
-+              return NULL;
-+
-+      if (mtk_mib_entry_read(ppe, index, &bytes, &packets))
-+              return NULL;
-+
-+      acct = ppe->acct_table + index * size;
-+
-+      acct->bytes += bytes;
-+      acct->packets += packets;
-+
-+      if (diff) {
-+              diff->bytes = bytes;
-+              diff->packets = packets;
-+      }
-+
-+      return acct;
-+}
-+
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
- {
-+      bool accounting = eth->soc->has_accounting;
-       const struct mtk_soc_data *soc = eth->soc;
-+      struct mtk_foe_accounting *acct;
-       struct device *dev = eth->dev;
-+      struct mtk_mib_entry *mib;
-       struct mtk_ppe *ppe;
-       u32 foe_flow_size;
-       void *foe;
-@@ -778,7 +858,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
-       ppe->base = base;
-       ppe->eth = eth;
-       ppe->dev = dev;
--      ppe->version = version;
-+      ppe->version = eth->soc->offload_version;
-+      ppe->accounting = accounting;
-       foe = dmam_alloc_coherent(ppe->dev,
-                                 MTK_PPE_ENTRIES * soc->foe_entry_size,
-@@ -794,6 +875,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_
-       if (!ppe->foe_flow)
-               goto err_free_l2_flows;
-+      if (accounting) {
-+              mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib),
-+                                        &ppe->mib_phys, GFP_KERNEL);
-+              if (!mib)
-+                      return NULL;
-+
-+              ppe->mib_table = mib;
-+
-+              acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct),
-+                                  GFP_KERNEL);
-+
-+              if (!acct)
-+                      return NULL;
-+
-+              ppe->acct_table = acct;
-+      }
-+
-       mtk_ppe_debugfs_init(ppe, index);
-       return ppe;
-@@ -923,6 +1021,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
-               ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
-               ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
-       }
-+
-+      if (ppe->accounting && ppe->mib_phys) {
-+              ppe_w32(ppe, MTK_PPE_MIB_TB_BASE, ppe->mib_phys);
-+              ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_EN,
-+                      MTK_PPE_MIB_CFG_EN);
-+              ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_RD_CLR,
-+                      MTK_PPE_MIB_CFG_RD_CLR);
-+              ppe_m32(ppe, MTK_PPE_MIB_CACHE_CTL, MTK_PPE_MIB_CACHE_CTL_EN,
-+                      MTK_PPE_MIB_CFG_RD_CLR);
-+      }
- }
- int mtk_ppe_stop(struct mtk_ppe *ppe)
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -57,6 +57,7 @@ enum {
- #define MTK_FOE_IB2_MULTICAST         BIT(8)
- #define MTK_FOE_IB2_WDMA_QID2         GENMASK(13, 12)
-+#define MTK_FOE_IB2_MIB_CNT           BIT(15)
- #define MTK_FOE_IB2_WDMA_DEVIDX               BIT(16)
- #define MTK_FOE_IB2_WDMA_WINFO                BIT(17)
-@@ -285,16 +286,34 @@ struct mtk_flow_entry {
-       unsigned long cookie;
- };
-+struct mtk_mib_entry {
-+      u32     byt_cnt_l;
-+      u16     byt_cnt_h;
-+      u32     pkt_cnt_l;
-+      u8      pkt_cnt_h;
-+      u8      _rsv0;
-+      u32     _rsv1;
-+} __packed;
-+
-+struct mtk_foe_accounting {
-+      u64     bytes;
-+      u64     packets;
-+};
-+
- struct mtk_ppe {
-       struct mtk_eth *eth;
-       struct device *dev;
-       void __iomem *base;
-       int version;
-       char dirname[5];
-+      bool accounting;
-       void *foe_table;
-       dma_addr_t foe_phys;
-+      struct mtk_mib_entry *mib_table;
-+      dma_addr_t mib_phys;
-+
-       u16 foe_check_time[MTK_PPE_ENTRIES];
-       struct hlist_head *foe_flow;
-@@ -303,8 +322,7 @@ struct mtk_ppe {
-       void *acct_table;
- };
--struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
--                           int version, int index);
-+struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
- void mtk_ppe_deinit(struct mtk_eth *eth);
- void mtk_ppe_start(struct mtk_ppe *ppe);
- int mtk_ppe_stop(struct mtk_ppe *ppe);
-@@ -359,5 +377,7 @@ int mtk_foe_entry_commit(struct mtk_ppe
- void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
- int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
-+struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
-+                                               struct mtk_foe_accounting *diff);
- #endif
---- a/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_debugfs.c
-@@ -82,6 +82,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file
-               struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
-               struct mtk_foe_mac_info *l2;
-               struct mtk_flow_addr_info ai = {};
-+              struct mtk_foe_accounting *acct;
-               unsigned char h_source[ETH_ALEN];
-               unsigned char h_dest[ETH_ALEN];
-               int type, state;
-@@ -95,6 +96,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file
-               if (bind && state != MTK_FOE_STATE_BIND)
-                       continue;
-+              acct = mtk_foe_entry_get_mib(ppe, i, NULL);
-+
-               type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
-               seq_printf(m, "%05x %s %7s", i,
-                          mtk_foe_entry_state_str(state),
-@@ -153,9 +156,11 @@ mtk_ppe_debugfs_foe_show(struct seq_file
-               *((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo);
-               seq_printf(m, " eth=%pM->%pM etype=%04x"
--                            " vlan=%d,%d ib1=%08x ib2=%08x\n",
-+                            " vlan=%d,%d ib1=%08x ib2=%08x"
-+                            " packets=%llu bytes=%llu\n",
-                          h_source, h_dest, ntohs(l2->etype),
--                         l2->vlan1, l2->vlan2, entry->ib1, ib2);
-+                         l2->vlan1, l2->vlan2, entry->ib1, ib2,
-+                         acct ? acct->packets : 0, acct ? acct->bytes : 0);
-       }
-       return 0;
---- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
-@@ -497,6 +497,7 @@ static int
- mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
- {
-       struct mtk_flow_entry *entry;
-+      struct mtk_foe_accounting diff;
-       u32 idle;
-       entry = rhashtable_lookup(&eth->flow_table, &f->cookie,
-@@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *e
-       idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
-       f->stats.lastused = jiffies - idle * HZ;
-+      if (entry->hash != 0xFFFF &&
-+          mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash,
-+                                &diff)) {
-+              f->stats.pkts += diff.packets;
-+              f->stats.bytes += diff.bytes;
-+      }
-+
-       return 0;
- }
---- a/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe_regs.h
-@@ -149,6 +149,20 @@ enum {
- #define MTK_PPE_MIB_TB_BASE                   0x338
-+#define MTK_PPE_MIB_SER_CR                    0x33C
-+#define MTK_PPE_MIB_SER_CR_ST                 BIT(16)
-+#define MTK_PPE_MIB_SER_CR_ADDR                       GENMASK(13, 0)
-+
-+#define MTK_PPE_MIB_SER_R0                    0x340
-+#define MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW               GENMASK(31, 0)
-+
-+#define MTK_PPE_MIB_SER_R1                    0x344
-+#define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW                GENMASK(31, 16)
-+#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH      GENMASK(15, 0)
-+
-+#define MTK_PPE_MIB_SER_R2                    0x348
-+#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH               GENMASK(23, 0)
-+
- #define MTK_PPE_MIB_CACHE_CTL                 0x350
- #define MTK_PPE_MIB_CACHE_CTL_EN              BIT(0)
- #define MTK_PPE_MIB_CACHE_CTL_FLUSH           BIT(2)
diff --git a/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch b/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-compile-out-netsys-v2-code-.patch
new file mode 100644 (file)
index 0000000..decf647
--- /dev/null
@@ -0,0 +1,44 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 27 Oct 2022 23:39:52 +0200
+Subject: [PATCH] net: ethernet: mtk_eth_soc: compile out netsys v2 code
+ on mt7621
+
+Avoid some branches in the hot path on low-end devices with limited CPU power,
+and reduce code size
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1326,6 +1326,22 @@ struct mtk_mac {
+ /* the struct describing the SoC. these are declared in the soc_xyz.c files */
+ extern const struct of_device_id of_mtk_match[];
++#ifdef CONFIG_SOC_MT7621
++static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
++{
++      return true;
++}
++
++static inline bool mtk_is_netsys_v2_or_greater(struct mtk_eth *eth)
++{
++      return false;
++}
++
++static inline bool mtk_is_netsys_v3_or_greater(struct mtk_eth *eth)
++{
++      return false;
++}
++#else
+ static inline bool mtk_is_netsys_v1(struct mtk_eth *eth)
+ {
+       return eth->soc->version == 1;
+@@ -1340,6 +1356,7 @@ static inline bool mtk_is_netsys_v3_or_g
+ {
+       return eth->soc->version > 2;
+ }
++#endif
+ static inline struct mtk_foe_entry *
+ mtk_foe_get_entry(struct mtk_ppe *ppe, u16 hash)
diff --git a/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch b/target/linux/generic/pending-6.1/732-00-net-ethernet-mtk_eth_soc-drop-generic-vlan-rx-offloa.patch
deleted file mode 100644 (file)
index 3a4cc91..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Sun, 20 Nov 2022 23:01:00 +0100
-Subject: [PATCH] net: ethernet: mtk_eth_soc: drop generic vlan rx offload,
- only use DSA untagging
-
-Through testing I found out that hardware vlan rx offload support seems to
-have some hardware issues. At least when using multiple MACs and when receiving
-tagged packets on the secondary MAC, the hardware can sometimes start to emit
-wrong tags on the first MAC as well.
-
-In order to avoid such issues, drop the feature configuration and use the
-offload feature only for DSA hardware untagging on MT7621/MT7622 devices which
-only use one MAC.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1898,9 +1898,7 @@ static int mtk_poll_rx(struct napi_struc
-       while (done < budget) {
-               unsigned int pktlen, *rxdcsum;
--              bool has_hwaccel_tag = false;
-               struct net_device *netdev;
--              u16 vlan_proto, vlan_tci;
-               dma_addr_t dma_addr;
-               u32 hash, reason;
-               int mac = 0;
-@@ -2035,36 +2033,21 @@ static int mtk_poll_rx(struct napi_struc
-                       skb_checksum_none_assert(skb);
-               skb->protocol = eth_type_trans(skb, netdev);
--              if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
--                      mtk_ppe_check_skb(eth->ppe[0], skb, hash);
--
--              if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) {
--                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
--                              if (trxd.rxd3 & RX_DMA_VTAG_V2) {
--                                      vlan_proto = RX_DMA_VPID(trxd.rxd4);
--                                      vlan_tci = RX_DMA_VID(trxd.rxd4);
--                                      has_hwaccel_tag = true;
--                              }
--                      } else if (trxd.rxd2 & RX_DMA_VTAG) {
--                              vlan_proto = RX_DMA_VPID(trxd.rxd3);
--                              vlan_tci = RX_DMA_VID(trxd.rxd3);
--                              has_hwaccel_tag = true;
--                      }
--              }
--
-               /* When using VLAN untagging in combination with DSA, the
-                * hardware treats the MTK special tag as a VLAN and untags it.
-                */
--              if (has_hwaccel_tag && netdev_uses_dsa(netdev)) {
--                      unsigned int port = vlan_proto & GENMASK(2, 0);
-+              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
-+                  (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
-+                      unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
-                       if (port < ARRAY_SIZE(eth->dsa_meta) &&
-                           eth->dsa_meta[port])
-                               skb_dst_set_noref(skb, &eth->dsa_meta[port]->dst);
--              } else if (has_hwaccel_tag) {
--                      __vlan_hwaccel_put_tag(skb, htons(vlan_proto), vlan_tci);
-               }
-+              if (reason == MTK_PPE_CPU_REASON_HIT_UNBIND_RATE_REACHED)
-+                      mtk_ppe_check_skb(eth->ppe[0], skb, hash);
-+
-               skb_record_rx_queue(skb, 0);
-               napi_gro_receive(napi, skb);
-@@ -2887,29 +2870,11 @@ static netdev_features_t mtk_fix_feature
- static int mtk_set_features(struct net_device *dev, netdev_features_t features)
- {
--      struct mtk_mac *mac = netdev_priv(dev);
--      struct mtk_eth *eth = mac->hw;
-       netdev_features_t diff = dev->features ^ features;
--      int i;
-       if ((diff & NETIF_F_LRO) && !(features & NETIF_F_LRO))
-               mtk_hwlro_netdev_disable(dev);
--      /* Set RX VLAN offloading */
--      if (!(diff & NETIF_F_HW_VLAN_CTAG_RX))
--              return 0;
--
--      mtk_w32(eth, !!(features & NETIF_F_HW_VLAN_CTAG_RX),
--              MTK_CDMP_EG_CTRL);
--
--      /* sync features with other MAC */
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
--              if (!eth->netdev[i] || eth->netdev[i] == dev)
--                      continue;
--              eth->netdev[i]->features &= ~NETIF_F_HW_VLAN_CTAG_RX;
--              eth->netdev[i]->features |= features & NETIF_F_HW_VLAN_CTAG_RX;
--      }
--
-       return 0;
- }
-@@ -3223,30 +3188,6 @@ static int mtk_open(struct net_device *d
-       struct mtk_eth *eth = mac->hw;
-       int i, err;
--      if (mtk_uses_dsa(dev) && !eth->prog) {
--              for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
--                      struct metadata_dst *md_dst = eth->dsa_meta[i];
--
--                      if (md_dst)
--                              continue;
--
--                      md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
--                                                  GFP_KERNEL);
--                      if (!md_dst)
--                              return -ENOMEM;
--
--                      md_dst->u.port_info.port_id = i;
--                      eth->dsa_meta[i] = md_dst;
--              }
--      } else {
--              /* Hardware special tag parsing needs to be disabled if at least
--               * one MAC does not use DSA.
--               */
--              u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
--              val &= ~MTK_CDMP_STAG_EN;
--              mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
--      }
--
-       err = phylink_of_phy_connect(mac->phylink, mac->of_node, 0);
-       if (err) {
-               netdev_err(dev, "%s: could not attach PHY: %d\n", __func__,
-@@ -3285,6 +3226,35 @@ static int mtk_open(struct net_device *d
-       phylink_start(mac->phylink);
-       netif_tx_start_all_queues(dev);
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+              return 0;
-+
-+      if (mtk_uses_dsa(dev) && !eth->prog) {
-+              for (i = 0; i < ARRAY_SIZE(eth->dsa_meta); i++) {
-+                      struct metadata_dst *md_dst = eth->dsa_meta[i];
-+
-+                      if (md_dst)
-+                              continue;
-+
-+                      md_dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
-+                                                  GFP_KERNEL);
-+                      if (!md_dst)
-+                              return -ENOMEM;
-+
-+                      md_dst->u.port_info.port_id = i;
-+                      eth->dsa_meta[i] = md_dst;
-+              }
-+      } else {
-+              /* Hardware special tag parsing needs to be disabled if at least
-+               * one MAC does not use DSA.
-+               */
-+              u32 val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-+              val &= ~MTK_CDMP_STAG_EN;
-+              mtk_w32(eth, val, MTK_CDMP_IG_CTRL);
-+
-+              mtk_w32(eth, 0, MTK_CDMP_EG_CTRL);
-+      }
-+
-       return 0;
- }
-@@ -3769,10 +3739,9 @@ static int mtk_hw_init(struct mtk_eth *e
-       if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-               val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-               mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
--      }
--      /* Enable RX VLan Offloading */
--      mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-+              mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
-+      }
-       /* set interrupt delays based on current Net DIM sample */
-       mtk_dim_rx(&eth->rx_dim.work);
-@@ -4412,7 +4381,7 @@ static int mtk_add_mac(struct mtk_eth *e
-               eth->netdev[id]->hw_features |= NETIF_F_LRO;
-       eth->netdev[id]->vlan_features = eth->soc->hw_features &
--              ~(NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX);
-+              ~NETIF_F_HW_VLAN_CTAG_TX;
-       eth->netdev[id]->features |= eth->soc->hw_features;
-       eth->netdev[id]->ethtool_ops = &mtk_ethtool_ops;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -48,7 +48,6 @@
- #define MTK_HW_FEATURES               (NETIF_F_IP_CSUM | \
-                                NETIF_F_RXCSUM | \
-                                NETIF_F_HW_VLAN_CTAG_TX | \
--                               NETIF_F_HW_VLAN_CTAG_RX | \
-                                NETIF_F_SG | NETIF_F_TSO | \
-                                NETIF_F_TSO6 | \
-                                NETIF_F_IPV6_CSUM |\
index c0a5a93a456302334ba5cd9d80f3fd25c02b5c4c..a1cc109050e1df8ed24a52e1989b978a986063a4 100644 (file)
@@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -1469,12 +1469,28 @@ static void mtk_wake_queue(struct mtk_et
+@@ -1562,12 +1562,28 @@ static void mtk_wake_queue(struct mtk_et
        }
  }
  
@@ -45,11 +45,11 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        bool gso = false;
        int tx_num;
  
-@@ -1496,6 +1512,18 @@ static netdev_tx_t mtk_start_xmit(struct
+@@ -1589,6 +1605,18 @@ static netdev_tx_t mtk_start_xmit(struct
                return NETDEV_TX_BUSY;
        }
  
-+      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
++      if (mtk_is_netsys_v1(eth) &&
 +          skb_is_gso(skb) && mtk_skb_has_small_frag(skb)) {
 +              segs = skb_gso_segment(skb, dev->features & ~NETIF_F_ALL_TSO);
 +              if (IS_ERR(segs))
@@ -64,14 +64,14 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        /* TSO: fill MSS info in tcp checksum field */
        if (skb_is_gso(skb)) {
                if (skb_cow_head(skb, 0)) {
-@@ -1511,8 +1539,14 @@ static netdev_tx_t mtk_start_xmit(struct
+@@ -1604,8 +1632,14 @@ static netdev_tx_t mtk_start_xmit(struct
                }
        }
  
 -      if (mtk_tx_map(skb, dev, tx_num, ring, gso) < 0)
 -              goto drop;
 +      skb_list_walk_safe(skb, skb, next) {
-+              if ((!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
++              if ((mtk_is_netsys_v1(eth) &&
 +                   mtk_skb_has_small_frag(skb) && skb_linearize(skb)) ||
 +                  mtk_tx_map(skb, dev, tx_num, ring, gso) < 0) {
 +                              stats->tx_dropped++;
@@ -83,7 +83,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                netif_tx_stop_all_queues(dev);
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -258,7 +258,7 @@
+@@ -268,7 +268,7 @@
  #define MTK_CHK_DDONE_EN      BIT(28)
  #define MTK_DMAD_WR_WDONE     BIT(26)
  #define MTK_WCOMP_EN          BIT(24)
index 3c6359ee419a767dd95bc5f236ca5d46aed5b99a..11a81dd0bfdc9bc1a0a37ff18bbd0b7966fe1a46 100644 (file)
@@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -48,8 +48,7 @@
+@@ -47,8 +47,7 @@
  #define MTK_HW_FEATURES               (NETIF_F_IP_CSUM | \
                                 NETIF_F_RXCSUM | \
                                 NETIF_F_HW_VLAN_CTAG_TX | \
index 77973180f639987740953639d2b328ce547450b4..6790ebd94cf34d9e9ac7c229aea7926c17598ad5 100644 (file)
@@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -710,6 +710,7 @@ static void mtk_mac_link_up(struct phyli
+@@ -766,6 +766,7 @@ static void mtk_mac_link_up(struct phyli
                 MAC_MCR_FORCE_RX_FC);
  
        /* Configure speed */
@@ -30,7 +30,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        switch (speed) {
        case SPEED_2500:
        case SPEED_1000:
-@@ -3201,6 +3202,9 @@ found:
+@@ -3344,6 +3345,9 @@ found:
        if (dp->index >= MTK_QDMA_NUM_QUEUES)
                return NOTIFY_DONE;
  
index dc2163959d13281e3de2e82ad00cd580fc64fdb0..72d57434026230fd2157e3158f995b49d9be3e54 100644 (file)
@@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  #include <net/dsa.h>
  #include "mtk_eth_soc.h"
  #include "mtk_ppe.h"
-@@ -752,7 +753,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe
+@@ -775,7 +776,9 @@ void __mtk_ppe_check_skb(struct mtk_ppe
                    skb->dev->dsa_ptr->tag_ops->proto != DSA_TAG_PROTO_MTK)
                        goto out;
  
index c5654a60619a9283d3d62fb13b05444971af31e5..c29c63bb1dae89de3daa41dec3d07e97f8f4b3ba 100644 (file)
@@ -11,10 +11,15 @@ PPE device.
 
 Signed-off-by: Felix Fietkau <nbd@nbd.name>
 ---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h   |   3 +
+ .../net/ethernet/mediatek/mtk_ppe_offload.c   |  37 ++++---
+ drivers/net/ethernet/mediatek/mtk_wed.c       | 101 ++++++++++++++++++
+ include/linux/soc/mediatek/mtk_wed.h          |   6 ++
+ 4 files changed, 133 insertions(+), 14 deletions(-)
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1280,6 +1280,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk
+@@ -1451,6 +1451,9 @@ int mtk_gmac_rgmii_path_setup(struct mtk
  int mtk_eth_offload_init(struct mtk_eth *eth);
  int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
                     void *type_data);
@@ -120,7 +125,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  static void
  wed_m32(struct mtk_wed_device *dev, u32 reg, u32 mask, u32 val)
  {
-@@ -1745,6 +1752,99 @@ out:
+@@ -1753,6 +1760,99 @@ out:
        mutex_unlock(&hw_lock);
  }
  
@@ -220,7 +225,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
                    void __iomem *wdma, phys_addr_t wdma_phy,
                    int index)
-@@ -1764,6 +1864,7 @@ void mtk_wed_add_hw(struct device_node *
+@@ -1772,6 +1872,7 @@ void mtk_wed_add_hw(struct device_node *
                .irq_set_mask = mtk_wed_irq_set_mask,
                .detach = mtk_wed_detach,
                .ppe_check = mtk_wed_ppe_check,
index 08036e0b17d9cfbbf0c3c55cd1acefa9606ff288..74cb562a51017c97fb7a56a90f9490803858d2b7 100644 (file)
@@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -634,10 +634,20 @@ void mtk_foe_entry_clear(struct mtk_ppe
+@@ -657,10 +657,20 @@ void mtk_foe_entry_clear(struct mtk_ppe
  static int
  mtk_foe_entry_commit_l2(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
  {
index ec04fb354256bc56f4879803ded34d798a1ecd1c..ecdb345d69905e4d8ef91e366cc8b361f45344ab 100644 (file)
@@ -9,10 +9,13 @@ flow accounting support.
 
 Signed-off-by: Felix Fietkau <nbd@nbd.name>
 ---
+ drivers/net/ethernet/mediatek/mtk_ppe.c | 162 ++++++++++++------------
+ drivers/net/ethernet/mediatek/mtk_ppe.h |  15 +--
+ 2 files changed, 86 insertions(+), 91 deletions(-)
 
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -460,42 +460,43 @@ int mtk_foe_entry_set_queue(struct mtk_e
+@@ -477,42 +477,43 @@ int mtk_foe_entry_set_queue(struct mtk_e
        return 0;
  }
  
@@ -72,7 +75,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, entry->hash);
  
                hwe->ib1 &= ~MTK_FOE_IB1_STATE;
-@@ -515,7 +516,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
+@@ -532,7 +533,8 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
        if (entry->type != MTK_FLOW_TYPE_L2_SUBFLOW)
                return;
  
@@ -82,7 +85,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        kfree(entry);
  }
  
-@@ -531,66 +533,55 @@ static int __mtk_foe_entry_idle_time(str
+@@ -548,66 +550,55 @@ static int __mtk_foe_entry_idle_time(str
                return now - timestamp;
  }
  
@@ -178,7 +181,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  }
  
  static void
-@@ -627,7 +618,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+@@ -650,7 +641,8 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
  void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
  {
        spin_lock_bh(&ppe_lock);
@@ -188,7 +191,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        spin_unlock_bh(&ppe_lock);
  }
  
-@@ -674,8 +666,8 @@ mtk_foe_entry_commit_subflow(struct mtk_
+@@ -697,8 +689,8 @@ mtk_foe_entry_commit_subflow(struct mtk_
  {
        const struct mtk_soc_data *soc = ppe->eth->soc;
        struct mtk_flow_entry *flow_info;
@@ -198,7 +201,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP;
        int type;
  
-@@ -683,30 +675,30 @@ mtk_foe_entry_commit_subflow(struct mtk_
+@@ -706,30 +698,30 @@ mtk_foe_entry_commit_subflow(struct mtk_
        if (!flow_info)
                return;
  
@@ -239,7 +242,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  }
  
  void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash)
-@@ -716,9 +708,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe
+@@ -739,9 +731,11 @@ void __mtk_ppe_check_skb(struct mtk_ppe
        struct mtk_foe_entry *hwe = mtk_foe_get_entry(ppe, hash);
        struct mtk_flow_entry *entry;
        struct mtk_foe_bridge key = {};
@@ -251,7 +254,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        u8 *tag;
  
        spin_lock_bh(&ppe_lock);
-@@ -726,20 +720,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe
+@@ -749,20 +743,14 @@ void __mtk_ppe_check_skb(struct mtk_ppe
        if (FIELD_GET(MTK_FOE_IB1_STATE, hwe->ib1) == MTK_FOE_STATE_BIND)
                goto out;
  
@@ -278,7 +281,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                        continue;
                }
  
-@@ -790,9 +778,17 @@ out:
+@@ -813,9 +801,17 @@ out:
  
  int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
  {
@@ -300,7 +303,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -265,7 +265,12 @@ enum {
+@@ -286,7 +286,12 @@ enum {
  
  struct mtk_flow_entry {
        union {
@@ -314,7 +317,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                struct {
                        struct rhash_head l2_node;
                        struct hlist_head l2_flows;
-@@ -275,13 +280,7 @@ struct mtk_flow_entry {
+@@ -296,13 +301,7 @@ struct mtk_flow_entry {
        s8 wed_index;
        u8 ppe_index;
        u16 hash;
index 79386d6cf909e2567e2c00a707726a5542869740..e323baeb184a7d084099bf91816c12958f0c567d 100644 (file)
@@ -27,7 +27,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
        if (ret)
                dev_err(ppe->dev, "MIB table busy");
-@@ -90,18 +90,32 @@ static int mtk_ppe_mib_wait_busy(struct
+@@ -90,17 +90,31 @@ static int mtk_ppe_mib_wait_busy(struct
        return ret;
  }
  
@@ -43,7 +43,6 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 +
 +struct mtk_foe_accounting *mtk_ppe_mib_entry_read(struct mtk_ppe *ppe, u16 index)
  {
-       u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
        u32 val, cnt_r0, cnt_r1, cnt_r2;
 +      struct mtk_foe_accounting *acct;
        int ret;
@@ -62,22 +61,32 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
        cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0);
        cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
-@@ -111,10 +125,11 @@ static int mtk_mib_entry_read(struct mtk
-       byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
-       pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
-       pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
--      *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
--      *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
+@@ -109,19 +123,19 @@ static int mtk_mib_entry_read(struct mtk
+       if (mtk_is_netsys_v3_or_greater(ppe->eth)) {
+               /* 64 bit for each counter */
+               u32 cnt_r3 = readl(ppe->base + MTK_PPE_MIB_SER_R3);
+-              *bytes = ((u64)cnt_r1 << 32) | cnt_r0;
+-              *packets = ((u64)cnt_r3 << 32) | cnt_r2;
++              acct->bytes += ((u64)cnt_r1 << 32) | cnt_r0;
++              acct->packets += ((u64)cnt_r3 << 32) | cnt_r2;
+       } else {
+               /* 48 bit byte counter, 40 bit packet counter */
+               u32 byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
+               u32 byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
+               u32 pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
+               u32 pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
+-              *bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
+-              *packets = (pkt_cnt_high << 16) | pkt_cnt_low;
++              acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low;
++              acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low;
+       }
  
 -      return 0;
-+      acct->bytes += ((u64)byte_cnt_high << 32) | byte_cnt_low;
-+      acct->packets += (pkt_cnt_high << 16) | pkt_cnt_low;
-+
 +      return acct;
  }
  
  static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
-@@ -503,13 +518,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
+@@ -520,13 +534,6 @@ __mtk_foe_entry_clear(struct mtk_ppe *pp
                hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
                dma_wmb();
                mtk_ppe_cache_clear(ppe);
@@ -91,7 +100,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        }
        entry->hash = 0xffff;
  
-@@ -534,11 +542,14 @@ static int __mtk_foe_entry_idle_time(str
+@@ -551,11 +558,14 @@ static int __mtk_foe_entry_idle_time(str
  }
  
  static bool
@@ -107,7 +116,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        int len;
  
        if (hash == 0xffff)
-@@ -549,18 +560,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp
+@@ -566,18 +576,35 @@ mtk_flow_entry_update(struct mtk_ppe *pp
        memcpy(&foe, hwe, len);
  
        if (!mtk_flow_entry_match(ppe->eth, entry, &foe, len) ||
@@ -146,7 +155,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        struct mtk_flow_entry *cur;
        struct hlist_node *tmp;
        int idle;
-@@ -569,7 +597,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe
+@@ -586,7 +613,9 @@ mtk_flow_entry_update_l2(struct mtk_ppe
        hlist_for_each_entry_safe(cur, tmp, &entry->l2_flows, l2_list) {
                int cur_idle;
  
@@ -157,7 +166,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
                        __mtk_foe_entry_clear(ppe, entry, false);
                        continue;
                }
-@@ -584,10 +614,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe
+@@ -601,10 +630,29 @@ mtk_flow_entry_update_l2(struct mtk_ppe
        }
  }
  
@@ -187,7 +196,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        struct mtk_eth *eth = ppe->eth;
        u16 timestamp = mtk_eth_timestamp(eth);
        struct mtk_foe_entry *hwe;
-@@ -612,6 +661,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
+@@ -635,6 +683,12 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
  
        dma_wmb();
  
@@ -200,7 +209,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        mtk_ppe_cache_clear(ppe);
  }
  
-@@ -776,21 +831,6 @@ out:
+@@ -799,21 +853,6 @@ out:
        spin_unlock_bh(&ppe_lock);
  }
  
@@ -222,7 +231,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
  {
        if (!ppe)
-@@ -818,32 +858,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
+@@ -841,32 +880,6 @@ int mtk_ppe_prepare_reset(struct mtk_ppe
        return mtk_ppe_wait_busy(ppe);
  }
  
@@ -257,7 +266,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        bool accounting = eth->soc->has_accounting;
 --- a/drivers/net/ethernet/mediatek/mtk_ppe.h
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -283,6 +283,8 @@ struct mtk_flow_entry {
+@@ -304,6 +304,8 @@ struct mtk_flow_entry {
        struct mtk_foe_entry data;
        struct rhash_head node;
        unsigned long cookie;
@@ -266,7 +275,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  };
  
  struct mtk_mib_entry {
-@@ -326,6 +328,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth)
+@@ -348,6 +350,7 @@ void mtk_ppe_deinit(struct mtk_eth *eth)
  void mtk_ppe_start(struct mtk_ppe *ppe);
  int mtk_ppe_stop(struct mtk_ppe *ppe);
  int mtk_ppe_prepare_reset(struct mtk_ppe *ppe);
@@ -274,7 +283,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  
  void __mtk_ppe_check_skb(struct mtk_ppe *ppe, struct sk_buff *skb, u16 hash);
  
-@@ -374,9 +377,8 @@ int mtk_foe_entry_set_queue(struct mtk_e
+@@ -396,9 +399,8 @@ int mtk_foe_entry_set_queue(struct mtk_e
                            unsigned int queue);
  int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
  void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
@@ -295,7 +304,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 -              acct = mtk_foe_entry_get_mib(ppe, i, NULL);
 +              acct = mtk_ppe_mib_entry_read(ppe, i);
  
-               type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
+               type = mtk_get_ib1_pkt_type(ppe->eth, entry->ib1);
                seq_printf(m, "%05x %s %7s", i,
 --- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
 +++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
diff --git a/target/linux/generic/pending-6.1/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch b/target/linux/generic/pending-6.1/736-06-net-ethernet-mediatek-fix-ppe-flow-accounting-for-v1.patch
deleted file mode 100644 (file)
index 33c9838..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 23 Mar 2023 21:45:43 +0100
-Subject: [PATCH] net: ethernet: mediatek: fix ppe flow accounting for v1
- hardware
-
-Older chips (like MT7622) use a different bit in ib2 to enable hardware
-counter support.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/ethernet/mediatek/mtk_ppe.c
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.c
-@@ -640,6 +640,7 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
-       struct mtk_eth *eth = ppe->eth;
-       u16 timestamp = mtk_eth_timestamp(eth);
-       struct mtk_foe_entry *hwe;
-+      u32 val;
-       if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-               entry->ib1 &= ~MTK_FOE_IB1_BIND_TIMESTAMP_V2;
-@@ -656,8 +657,13 @@ __mtk_foe_entry_commit(struct mtk_ppe *p
-       wmb();
-       hwe->ib1 = entry->ib1;
--      if (ppe->accounting)
--              *mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
-+      if (ppe->accounting) {
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+                      val = MTK_FOE_IB2_MIB_CNT_V2;
-+              else
-+                      val = MTK_FOE_IB2_MIB_CNT;
-+              *mtk_foe_entry_ib2(eth, hwe) |= val;
-+      }
-       dma_wmb();
---- a/drivers/net/ethernet/mediatek/mtk_ppe.h
-+++ b/drivers/net/ethernet/mediatek/mtk_ppe.h
-@@ -55,9 +55,10 @@ enum {
- #define MTK_FOE_IB2_PSE_QOS           BIT(4)
- #define MTK_FOE_IB2_DEST_PORT         GENMASK(7, 5)
- #define MTK_FOE_IB2_MULTICAST         BIT(8)
-+#define MTK_FOE_IB2_MIB_CNT           BIT(10)
- #define MTK_FOE_IB2_WDMA_QID2         GENMASK(13, 12)
--#define MTK_FOE_IB2_MIB_CNT           BIT(15)
-+#define MTK_FOE_IB2_MIB_CNT_V2                BIT(15)
- #define MTK_FOE_IB2_WDMA_DEVIDX               BIT(16)
- #define MTK_FOE_IB2_WDMA_WINFO                BIT(17)
diff --git a/target/linux/generic/pending-6.1/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch b/target/linux/generic/pending-6.1/737-01-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V1-capabilit.patch
deleted file mode 100644 (file)
index bf1bc78..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-From 663fa1b7e0cb2c929008482014a70c6625caad75 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 7 Mar 2023 15:55:13 +0000
-Subject: [PATCH 1/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V1 capability
- bit
-
-Introduce MTK_NETSYS_V1 bit in the device capabilities for
-MT7621/MT7622/MT7623/MT7628/MT7629 SoCs.
-Use !MTK_NETSYS_V1 instead of MTK_NETSYS_V2 in the driver codebase.
-This is a preliminary patch to introduce support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++-------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 45 ++++++++++++---------
- 2 files changed, 41 insertions(+), 34 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -640,7 +640,7 @@ static void mtk_set_queue_speed(struct m
-             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
-             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
-             MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
--      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-               val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
-       if (IS_ENABLED(CONFIG_SOC_MT7621)) {
-@@ -1018,7 +1018,7 @@ static bool mtk_rx_get_desc(struct mtk_e
-       rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
-       rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
-       rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
--      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-               rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
-               rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
-       }
-@@ -1076,7 +1076,7 @@ static int mtk_init_fq_dma(struct mtk_et
-               txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
-               txd->txd4 = 0;
--              if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
-+              if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) {
-                       txd->txd5 = 0;
-                       txd->txd6 = 0;
-                       txd->txd7 = 0;
-@@ -1267,7 +1267,7 @@ static void mtk_tx_set_dma_desc(struct n
-       struct mtk_mac *mac = netdev_priv(dev);
-       struct mtk_eth *eth = mac->hw;
--      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-               mtk_tx_set_dma_desc_v2(dev, txd, info);
-       else
-               mtk_tx_set_dma_desc_v1(dev, txd, info);
-@@ -1950,7 +1950,7 @@ static int mtk_poll_rx(struct napi_struc
-                       break;
-               /* find out which mac the packet come from. values start at 1 */
--              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-                       mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
-               else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
-                        !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-@@ -2046,7 +2046,7 @@ static int mtk_poll_rx(struct napi_struc
-               skb->dev = netdev;
-               bytes += skb->len;
--              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-                       reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
-                       hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
-                       if (hash != MTK_RXD5_FOE_ENTRY)
-@@ -2071,7 +2071,7 @@ static int mtk_poll_rx(struct napi_struc
-               /* When using VLAN untagging in combination with DSA, the
-                * hardware treats the MTK special tag as a VLAN and untags it.
-                */
--              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1) &&
-                   (trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
-                       unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
-@@ -2382,7 +2382,7 @@ static int mtk_tx_alloc(struct mtk_eth *
-               txd->txd2 = next_ptr;
-               txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
-               txd->txd4 = 0;
--              if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
-+              if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) {
-                       txd->txd5 = 0;
-                       txd->txd6 = 0;
-                       txd->txd7 = 0;
-@@ -2435,7 +2435,7 @@ static int mtk_tx_alloc(struct mtk_eth *
-                             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
-                             FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
-                             MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
--                      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-                               val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
-                       mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
-                       ofs += MTK_QTX_OFFSET;
-@@ -2571,7 +2571,7 @@ static int mtk_rx_alloc(struct mtk_eth *
-               rxd->rxd3 = 0;
-               rxd->rxd4 = 0;
--              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-                       rxd->rxd5 = 0;
-                       rxd->rxd6 = 0;
-                       rxd->rxd7 = 0;
-@@ -3119,7 +3119,7 @@ static int mtk_start_dma(struct mtk_eth
-                      MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
-                      MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
--              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-                       val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
-                              MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
-                              MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
-@@ -3529,7 +3529,7 @@ static void mtk_hw_reset(struct mtk_eth
- {
-       u32 val;
--      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-               regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
-               val = RSTCTRL_PPE0_V2;
-       } else {
-@@ -3541,7 +3541,7 @@ static void mtk_hw_reset(struct mtk_eth
-       ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
--      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
-+      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
-               regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
-                            0x3ffffff);
- }
-@@ -3737,7 +3737,7 @@ static int mtk_hw_init(struct mtk_eth *e
-       else
-               mtk_hw_reset(eth);
--      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-               /* Set FE to PDMAv2 if necessary */
-               val = mtk_r32(eth, MTK_FE_GLO_MISC);
-               mtk_w32(eth,  val | BIT(4), MTK_FE_GLO_MISC);
-@@ -3774,7 +3774,7 @@ static int mtk_hw_init(struct mtk_eth *e
-        */
-       val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
-       mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
--      if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-               val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
-               mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -819,6 +819,7 @@ enum mkt_eth_capabilities {
-       MTK_SHARED_INT_BIT,
-       MTK_TRGMII_MT7621_CLK_BIT,
-       MTK_QDMA_BIT,
-+      MTK_NETSYS_V1_BIT,
-       MTK_NETSYS_V2_BIT,
-       MTK_SOC_MT7628_BIT,
-       MTK_RSTCTRL_PPE1_BIT,
-@@ -854,6 +855,7 @@ enum mkt_eth_capabilities {
- #define MTK_SHARED_INT                BIT(MTK_SHARED_INT_BIT)
- #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
- #define MTK_QDMA              BIT(MTK_QDMA_BIT)
-+#define MTK_NETSYS_V1         BIT(MTK_NETSYS_V1_BIT)
- #define MTK_NETSYS_V2         BIT(MTK_NETSYS_V2_BIT)
- #define MTK_SOC_MT7628                BIT(MTK_SOC_MT7628_BIT)
- #define MTK_RSTCTRL_PPE1      BIT(MTK_RSTCTRL_PPE1_BIT)
-@@ -916,25 +918,30 @@ enum mkt_eth_capabilities {
- #define MTK_HAS_CAPS(caps, _x)                (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x))
--#define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
--                    MTK_GMAC2_RGMII | MTK_SHARED_INT | \
--                    MTK_TRGMII_MT7621_CLK | MTK_QDMA)
--
--#define MT7622_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | MTK_GMAC2_RGMII | \
--                    MTK_GMAC2_SGMII | MTK_GDM1_ESW | \
--                    MTK_MUX_GDM1_TO_GMAC1_ESW | \
--                    MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_QDMA)
--
--#define MT7623_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | MTK_GMAC2_RGMII | \
--                    MTK_QDMA)
--
--#define MT7628_CAPS  (MTK_SHARED_INT | MTK_SOC_MT7628)
--
--#define MT7629_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
--                    MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW | \
--                    MTK_MUX_GMAC2_GMAC0_TO_GEPHY | \
--                    MTK_MUX_U3_GMAC2_TO_QPHY | \
--                    MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
-+#define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII |    \
-+                    MTK_GMAC2_RGMII | MTK_SHARED_INT |        \
-+                    MTK_TRGMII_MT7621_CLK | MTK_QDMA |        \
-+                    MTK_NETSYS_V1)
-+
-+#define MT7622_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII |     \
-+                    MTK_GMAC2_RGMII | MTK_GMAC2_SGMII |       \
-+                    MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW |\
-+                    MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII |      \
-+                    MTK_QDMA | MTK_NETSYS_V1)
-+
-+#define MT7623_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII |    \
-+                    MTK_GMAC2_RGMII | MTK_QDMA |              \
-+                    MTK_NETSYS_V1)
-+
-+#define MT7628_CAPS  (MTK_SHARED_INT | MTK_SOC_MT7628 |               \
-+                    MTK_NETSYS_V1)
-+
-+#define MT7629_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII |     \
-+                    MTK_GMAC2_GEPHY | MTK_GDM1_ESW |          \
-+                    MTK_MUX_GMAC2_GMAC0_TO_GEPHY | MTK_QDMA | \
-+                    MTK_MUX_U3_GMAC2_TO_QPHY | MTK_NETSYS_V1 |\
-+                    MTK_MUX_GDM1_TO_GMAC1_ESW |               \
-+                    MTK_MUX_GMAC12_TO_GEPHY_SGMII)
- #define MT7981_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
-                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
diff --git a/target/linux/generic/pending-6.1/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch b/target/linux/generic/pending-6.1/737-02-net-ethernet-mtk_eth_soc-move-MAX_DEVS-in-mtk_soc_da.patch
deleted file mode 100644 (file)
index bdd62a7..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-From 5af2b2dc4d6ba0ff7696e79f18e5b2bf862194eb Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 7 Mar 2023 15:55:24 +0000
-Subject: [PATCH 2/7] net: ethernet: mtk_eth_soc: move MAX_DEVS in mtk_soc_data
-
-This is a preliminary patch to add MT7988 SoC support since it runs 3
-macs instead of 2.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +++++++++++++++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 +++----
- 2 files changed, 36 insertions(+), 9 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4026,7 +4026,10 @@ static void mtk_sgmii_destroy(struct mtk
- {
-       int i;
--      for (i = 0; i < MTK_MAX_DEVS; i++)
-+      if (!eth->sgmii_pcs)
-+              return;
-+
-+      for (i = 0; i < eth->soc->num_devs; i++)
-               mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]);
- }
-@@ -4479,7 +4482,12 @@ static int mtk_sgmii_init(struct mtk_eth
-       u32 flags;
-       int i;
--      for (i = 0; i < MTK_MAX_DEVS; i++) {
-+      eth->sgmii_pcs = devm_kzalloc(eth->dev,
-+                                    sizeof(*eth->sgmii_pcs) *
-+                                    eth->soc->num_devs,
-+                                    GFP_KERNEL);
-+
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i);
-               if (!np)
-                       break;
-@@ -4524,6 +4532,18 @@ static int mtk_probe(struct platform_dev
-       if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
-               eth->ip_align = NET_IP_ALIGN;
-+      eth->netdev = devm_kzalloc(eth->dev,
-+                                 sizeof(*eth->netdev) * eth->soc->num_devs,
-+                                 GFP_KERNEL);
-+      if (!eth->netdev)
-+              return -ENOMEM;
-+
-+      eth->mac = devm_kzalloc(eth->dev,
-+                              sizeof(*eth->mac) * eth->soc->num_devs,
-+                              GFP_KERNEL);
-+      if (!eth->mac)
-+              return -ENOMEM;
-+
-       spin_lock_init(&eth->page_lock);
-       spin_lock_init(&eth->tx_irq_lock);
-       spin_lock_init(&eth->rx_irq_lock);
-@@ -4709,7 +4729,7 @@ static int mtk_probe(struct platform_dev
-                       goto err_deinit_ppe;
-       }
--      for (i = 0; i < MTK_MAX_DEVS; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->netdev[i])
-                       continue;
-@@ -4785,6 +4805,7 @@ static const struct mtk_soc_data mt2701_
-       .hw_features = MTK_HW_FEATURES,
-       .required_clks = MT7623_CLKS_BITMAP,
-       .required_pctl = true,
-+      .num_devs = 2,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-               .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4803,6 +4824,7 @@ static const struct mtk_soc_data mt7621_
-       .required_pctl = false,
-       .offload_version = 1,
-       .hash_offset = 2,
-+      .num_devs = 2,
-       .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-@@ -4824,6 +4846,7 @@ static const struct mtk_soc_data mt7622_
-       .offload_version = 2,
-       .hash_offset = 2,
-       .has_accounting = true,
-+      .num_devs = 2,
-       .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-@@ -4843,6 +4866,7 @@ static const struct mtk_soc_data mt7623_
-       .required_pctl = true,
-       .offload_version = 1,
-       .hash_offset = 2,
-+      .num_devs = 2,
-       .foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-@@ -4862,6 +4886,7 @@ static const struct mtk_soc_data mt7629_
-       .required_clks = MT7629_CLKS_BITMAP,
-       .required_pctl = false,
-       .has_accounting = true,
-+      .num_devs = 2,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-               .rxd_size = sizeof(struct mtk_rx_dma),
-@@ -4883,6 +4908,7 @@ static const struct mtk_soc_data mt7981_
-       .hash_offset = 4,
-       .foe_entry_size = sizeof(struct mtk_foe_entry),
-       .has_accounting = true,
-+      .num_devs = 2,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma_v2),
-               .rxd_size = sizeof(struct mtk_rx_dma_v2),
-@@ -4902,6 +4928,7 @@ static const struct mtk_soc_data mt7986_
-       .required_pctl = false,
-       .offload_version = 2,
-       .hash_offset = 4,
-+      .num_devs = 2,
-       .foe_entry_size = sizeof(struct mtk_foe_entry),
-       .has_accounting = true,
-       .txrx = {
-@@ -4920,6 +4947,7 @@ static const struct mtk_soc_data rt5350_
-       .hw_features = MTK_HW_FEATURES_MT7628,
-       .required_clks = MT7628_CLKS_BITMAP,
-       .required_pctl = false,
-+      .num_devs = 2,
-       .txrx = {
-               .txd_size = sizeof(struct mtk_tx_dma),
-               .rxd_size = sizeof(struct mtk_rx_dma),
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -1021,6 +1021,7 @@ struct mtk_reg_map {
-  * @required_pctl             A bool value to show whether the SoC requires
-  *                            the extra setup for those pins used by GMAC.
-  * @hash_offset                       Flow table hash offset.
-+ * @num_devs                  SoC number of macs.
-  * @foe_entry_size            Foe table entry size.
-  * @has_accounting            Bool indicating support for accounting of
-  *                            offloaded flows.
-@@ -1039,6 +1040,7 @@ struct mtk_soc_data {
-       bool            required_pctl;
-       u8              offload_version;
-       u8              hash_offset;
-+      u8              num_devs;
-       u16             foe_entry_size;
-       netdev_features_t hw_features;
-       bool            has_accounting;
-@@ -1054,9 +1056,6 @@ struct mtk_soc_data {
- #define MTK_DMA_MONITOR_TIMEOUT               msecs_to_jiffies(1000)
--/* currently no SoC has more than 2 macs */
--#define MTK_MAX_DEVS                  2
--
- /* struct mtk_eth -   This is the main datasructure for holding the state
-  *                    of the driver
-  * @dev:              The device pointer
-@@ -1111,14 +1110,14 @@ struct mtk_eth {
-       spinlock_t                      tx_irq_lock;
-       spinlock_t                      rx_irq_lock;
-       struct net_device               dummy_dev;
--      struct net_device               *netdev[MTK_MAX_DEVS];
--      struct mtk_mac                  *mac[MTK_MAX_DEVS];
-+      struct net_device               **netdev;
-+      struct mtk_mac                  **mac;
-       int                             irq[3];
-       u32                             msg_enable;
-       unsigned long                   sysclk;
-       struct regmap                   *ethsys;
-       struct regmap                   *infra;
--      struct phylink_pcs              *sgmii_pcs[MTK_MAX_DEVS];
-+      struct phylink_pcs              **sgmii_pcs;
-       struct regmap                   *pctl;
-       bool                            hwlro;
-       refcount_t                      dma_refcnt;
diff --git a/target/linux/generic/pending-6.1/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch b/target/linux/generic/pending-6.1/737-03-net-ethernet-mtk_eth_soc-rely-on-num_devs-and-remove.patch
deleted file mode 100644 (file)
index 1989eb6..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-From 4e35e80750b33727e606be9e7ce447bde2e0deb7 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 7 Mar 2023 15:55:35 +0000
-Subject: [PATCH 3/7] net: ethernet: mtk_eth_soc: rely on num_devs and remove
- MTK_MAC_COUNT
-
-Get rid of MTK_MAC_COUNT since it is a duplicated of eth->soc->num_devs.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 ++++++++++-----------
- drivers/net/ethernet/mediatek/mtk_eth_soc.h |  1 -
- 2 files changed, 15 insertions(+), 16 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -944,7 +944,7 @@ static void mtk_stats_update(struct mtk_
- {
-       int i;
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->mac[i] || !eth->mac[i]->hw_stats)
-                       continue;
-               if (spin_trylock(&eth->mac[i]->hw_stats->stats_lock)) {
-@@ -1449,7 +1449,7 @@ static int mtk_queue_stopped(struct mtk_
- {
-       int i;
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->netdev[i])
-                       continue;
-               if (netif_queue_stopped(eth->netdev[i]))
-@@ -1463,7 +1463,7 @@ static void mtk_wake_queue(struct mtk_et
- {
-       int i;
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->netdev[i])
-                       continue;
-               netif_tx_wake_all_queues(eth->netdev[i]);
-@@ -1956,7 +1956,7 @@ static int mtk_poll_rx(struct napi_struc
-                        !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-                       mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
--              if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
-+              if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
-                            !eth->netdev[mac]))
-                       goto release_desc;
-@@ -2993,7 +2993,7 @@ static void mtk_dma_free(struct mtk_eth
-       const struct mtk_soc_data *soc = eth->soc;
-       int i;
--      for (i = 0; i < MTK_MAC_COUNT; i++)
-+      for (i = 0; i < soc->num_devs; i++)
-               if (eth->netdev[i])
-                       netdev_reset_queue(eth->netdev[i]);
-       if (eth->scratch_ring) {
-@@ -3147,7 +3147,7 @@ static void mtk_gdm_config(struct mtk_et
-       if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
-               return;
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
-               /* default setup the forward port to send frame to PDMA */
-@@ -3758,7 +3758,7 @@ static int mtk_hw_init(struct mtk_eth *e
-        * up with the more appropriate value when mtk_mac_config call is being
-        * invoked.
-        */
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               struct net_device *dev = eth->netdev[i];
-               mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
-@@ -3946,7 +3946,7 @@ static void mtk_pending_work(struct work
-       mtk_prepare_for_reset(eth);
-       /* stop all devices to make sure that dma is properly shut down */
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
-                       continue;
-@@ -3962,7 +3962,7 @@ static void mtk_pending_work(struct work
-       mtk_hw_init(eth, true);
-       /* restart DMA and enable IRQs */
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!test_bit(i, &restart))
-                       continue;
-@@ -3990,7 +3990,7 @@ static int mtk_free_dev(struct mtk_eth *
- {
-       int i;
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->netdev[i])
-                       continue;
-               free_netdev(eth->netdev[i]);
-@@ -4009,7 +4009,7 @@ static int mtk_unreg_dev(struct mtk_eth
- {
-       int i;
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               struct mtk_mac *mac;
-               if (!eth->netdev[i])
-                       continue;
-@@ -4313,7 +4313,7 @@ static int mtk_add_mac(struct mtk_eth *e
-       }
-       id = be32_to_cpup(_id);
--      if (id >= MTK_MAC_COUNT) {
-+      if (id >= eth->soc->num_devs) {
-               dev_err(eth->dev, "%d is not a valid mac id\n", id);
-               return -EINVAL;
-       }
-@@ -4454,7 +4454,7 @@ void mtk_eth_set_dma_device(struct mtk_e
-       rtnl_lock();
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               dev = eth->netdev[i];
-               if (!dev || !(dev->flags & IFF_UP))
-@@ -4780,7 +4780,7 @@ static int mtk_remove(struct platform_de
-       int i;
-       /* stop all devices to make sure that dma is properly shut down */
--      for (i = 0; i < MTK_MAC_COUNT; i++) {
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-               if (!eth->netdev[i])
-                       continue;
-               mtk_stop(eth->netdev[i]);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -33,7 +33,6 @@
- #define MTK_TX_DMA_BUF_LEN_V2 0xffff
- #define MTK_QDMA_RING_SIZE    2048
- #define MTK_DMA_SIZE          512
--#define MTK_MAC_COUNT         2
- #define MTK_RX_ETH_HLEN               (VLAN_ETH_HLEN + ETH_FCS_LEN)
- #define MTK_RX_HLEN           (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
- #define MTK_DMA_DUMMY_DESC    0xffffffff
diff --git a/target/linux/generic/pending-6.1/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch b/target/linux/generic/pending-6.1/737-04-net-ethernet-mtk_eth_soc-add-MTK_NETSYS_V3-capabilit.patch
deleted file mode 100644 (file)
index 9c7b47f..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-From ab817f559d505329d8a413c7d29250f6d87d77a0 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 7 Mar 2023 15:55:47 +0000
-Subject: [PATCH 4/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V3 capability
- bit
-
-Introduce MTK_NETSYS_V3 bit in the device capabilities.
-This is a preliminary patch to introduce support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 115 ++++++++++++++++----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h |  44 +++++++-
- 2 files changed, 134 insertions(+), 25 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -924,17 +924,32 @@ void mtk_stats_update_mac(struct mtk_mac
-                       mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
-               hw_stats->rx_flow_control_packets +=
-                       mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
--              hw_stats->tx_skip +=
--                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
--              hw_stats->tx_collisions +=
--                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
--              hw_stats->tx_bytes +=
--                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
--              stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
--              if (stats)
--                      hw_stats->tx_bytes += (stats << 32);
--              hw_stats->tx_packets +=
--                      mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
-+
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+                      hw_stats->tx_skip +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs);
-+                      hw_stats->tx_collisions +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs);
-+                      hw_stats->tx_bytes +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs);
-+                      stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs);
-+                      if (stats)
-+                              hw_stats->tx_bytes += (stats << 32);
-+                      hw_stats->tx_packets +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs);
-+              } else {
-+                      hw_stats->tx_skip +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
-+                      hw_stats->tx_collisions +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
-+                      hw_stats->tx_bytes +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
-+                      stats =  mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
-+                      if (stats)
-+                              hw_stats->tx_bytes += (stats << 32);
-+                      hw_stats->tx_packets +=
-+                              mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
-+              }
-       }
-       u64_stats_update_end(&hw_stats->syncp);
-@@ -1238,7 +1253,10 @@ static void mtk_tx_set_dma_desc_v2(struc
-               data |= TX_DMA_LS0;
-       WRITE_ONCE(desc->txd3, data);
--      data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
-+      if (mac->id == MTK_GMAC3_ID)
-+              data = PSE_GDM3_PORT;
-+      else
-+              data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
-       data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
-       WRITE_ONCE(desc->txd4, data);
-@@ -1249,6 +1267,9 @@ static void mtk_tx_set_dma_desc_v2(struc
-               /* tx checksum offload */
-               if (info->csum)
-                       data |= TX_DMA_CHKSUM_V2;
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
-+                  netdev_uses_dsa(dev))
-+                      data |= TX_DMA_SPTAG_V3;
-       }
-       WRITE_ONCE(desc->txd5, data);
-@@ -1314,8 +1335,13 @@ static int mtk_tx_map(struct sk_buff *sk
-       mtk_tx_set_dma_desc(dev, itxd, &txd_info);
-       itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
--      itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
--                        MTK_TX_FLAGS_FPORT1;
-+      if (mac->id == MTK_GMAC1_ID)
-+              itx_buf->flags |= MTK_TX_FLAGS_FPORT0;
-+      else if (mac->id == MTK_GMAC2_ID)
-+              itx_buf->flags |= MTK_TX_FLAGS_FPORT1;
-+      else
-+              itx_buf->flags |= MTK_TX_FLAGS_FPORT2;
-+
-       setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
-                    k++);
-@@ -1363,8 +1389,13 @@ static int mtk_tx_map(struct sk_buff *sk
-                               memset(tx_buf, 0, sizeof(*tx_buf));
-                       tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
-                       tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
--                      tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
--                                       MTK_TX_FLAGS_FPORT1;
-+
-+                      if (mac->id == MTK_GMAC1_ID)
-+                              tx_buf->flags |= MTK_TX_FLAGS_FPORT0;
-+                      else if (mac->id == MTK_GMAC2_ID)
-+                              tx_buf->flags |= MTK_TX_FLAGS_FPORT1;
-+                      else
-+                              tx_buf->flags |= MTK_TX_FLAGS_FPORT2;
-                       setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
-                                    txd_info.size, k++);
-@@ -1950,11 +1981,24 @@ static int mtk_poll_rx(struct napi_struc
-                       break;
-               /* find out which mac the packet come from. values start at 1 */
--              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
--                      mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
--              else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
--                       !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
-+              if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
-+                      u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
-+
-+                      switch (val) {
-+                      case PSE_GDM1_PORT:
-+                      case PSE_GDM2_PORT:
-+                              mac = val - 1;
-+                              break;
-+                      case PSE_GDM3_PORT:
-+                              mac = MTK_GMAC3_ID;
-+                              break;
-+                      default:
-+                              break;
-+                      }
-+              } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
-+                       !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
-                       mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
-+              }
-               if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
-                            !eth->netdev[mac]))
-@@ -2185,7 +2229,9 @@ static int mtk_poll_tx_qdma(struct mtk_e
-               tx_buf = mtk_desc_to_tx_buf(ring, desc,
-                                           eth->soc->txrx.txd_size);
-               if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
--                      mac = 1;
-+                      mac = MTK_GMAC2_ID;
-+              else if (tx_buf->flags & MTK_TX_FLAGS_FPORT2)
-+                      mac = MTK_GMAC3_ID;
-               if (!tx_buf->data)
-                       break;
-@@ -3796,7 +3842,26 @@ static int mtk_hw_init(struct mtk_eth *e
-       mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
-       mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
--      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+              /* PSE should not drop port1, port8 and port9 packets */
-+              mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
-+
-+              /* GDM and CDM Threshold */
-+              mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
-+              mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
-+
-+              /* Disable GDM1 RX CRC stripping */
-+              val = mtk_r32(eth, MTK_GDMA_FWD_CFG(0));
-+              val &= ~MTK_GDMA_STRP_CRC;
-+              mtk_w32(eth, val, MTK_GDMA_FWD_CFG(0));
-+
-+              /* PSE GDM3 MIB counter has incorrect hw default values,
-+               * so the driver ought to read clear the values beforehand
-+               * in case ethtool retrieve wrong mib values.
-+               */
-+              for (i = 0; i < 0x80; i += 0x4)
-+                      mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i);
-+      } else if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
-               /* PSE should not drop port8 and port9 packets from WDMA Tx */
-               mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
-@@ -4361,7 +4426,11 @@ static int mtk_add_mac(struct mtk_eth *e
-       }
-       spin_lock_init(&mac->hw_stats->stats_lock);
-       u64_stats_init(&mac->hw_stats->syncp);
--      mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
-+
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
-+              mac->hw_stats->reg_offset = id * 0x80;
-+      else
-+              mac->hw_stats->reg_offset = id * 0x40;
-       /* phylink create */
-       err = of_get_phy_mode(np, &phy_mode);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -121,6 +121,7 @@
- #define MTK_GDMA_ICS_EN               BIT(22)
- #define MTK_GDMA_TCS_EN               BIT(21)
- #define MTK_GDMA_UCS_EN               BIT(20)
-+#define MTK_GDMA_STRP_CRC     BIT(16)
- #define MTK_GDMA_TO_PDMA      0x0
- #define MTK_GDMA_DROP_ALL       0x7777
-@@ -286,8 +287,6 @@
- /* QDMA Interrupt grouping registers */
- #define MTK_RLS_DONE_INT      BIT(0)
--#define MTK_STAT_OFFSET               0x40
--
- /* QDMA TX NUM */
- #define QID_BITS_V2(x)                (((x) & 0x3f) << 16)
- #define MTK_QDMA_GMAC2_QID    8
-@@ -300,6 +299,8 @@
- #define TX_DMA_CHKSUM_V2      (0x7 << 28)
- #define TX_DMA_TSO_V2         BIT(31)
-+#define TX_DMA_SPTAG_V3         BIT(27)
-+
- /* QDMA V2 descriptor txd4 */
- #define TX_DMA_FPORT_SHIFT_V2 8
- #define TX_DMA_FPORT_MASK_V2  0xf
-@@ -639,6 +640,7 @@ enum mtk_tx_flags {
-        */
-       MTK_TX_FLAGS_FPORT0     = 0x04,
-       MTK_TX_FLAGS_FPORT1     = 0x08,
-+      MTK_TX_FLAGS_FPORT2     = 0x10,
- };
- /* This enum allows us to identify how the clock is defined on the array of the
-@@ -724,6 +726,42 @@ enum mtk_dev_state {
-       MTK_RESETTING
- };
-+/* PSE Port Definition */
-+enum mtk_pse_port {
-+      PSE_ADMA_PORT = 0,
-+      PSE_GDM1_PORT,
-+      PSE_GDM2_PORT,
-+      PSE_PPE0_PORT,
-+      PSE_PPE1_PORT,
-+      PSE_QDMA_TX_PORT,
-+      PSE_QDMA_RX_PORT,
-+      PSE_DROP_PORT,
-+      PSE_WDMA0_PORT,
-+      PSE_WDMA1_PORT,
-+      PSE_TDMA_PORT,
-+      PSE_NONE_PORT,
-+      PSE_PPE2_PORT,
-+      PSE_WDMA2_PORT,
-+      PSE_EIP197_PORT,
-+      PSE_GDM3_PORT,
-+      PSE_PORT_MAX
-+};
-+
-+/* GMAC Identifier */
-+enum mtk_gmac_id {
-+      MTK_GMAC1_ID = 0,
-+      MTK_GMAC2_ID,
-+      MTK_GMAC3_ID,
-+      MTK_GMAC_ID_MAX
-+};
-+
-+/* GDM Type */
-+enum mtk_gdm_type {
-+      MTK_GDM_TYPE = 0,
-+      MTK_XGDM_TYPE,
-+      MTK_GDM_TYPE_MAX
-+};
-+
- enum mtk_tx_buf_type {
-       MTK_TYPE_SKB,
-       MTK_TYPE_XDP_TX,
-@@ -820,6 +858,7 @@ enum mkt_eth_capabilities {
-       MTK_QDMA_BIT,
-       MTK_NETSYS_V1_BIT,
-       MTK_NETSYS_V2_BIT,
-+      MTK_NETSYS_V3_BIT,
-       MTK_SOC_MT7628_BIT,
-       MTK_RSTCTRL_PPE1_BIT,
-       MTK_U3_COPHY_V2_BIT,
-@@ -856,6 +895,7 @@ enum mkt_eth_capabilities {
- #define MTK_QDMA              BIT(MTK_QDMA_BIT)
- #define MTK_NETSYS_V1         BIT(MTK_NETSYS_V1_BIT)
- #define MTK_NETSYS_V2         BIT(MTK_NETSYS_V2_BIT)
-+#define MTK_NETSYS_V3         BIT(MTK_NETSYS_V3_BIT)
- #define MTK_SOC_MT7628                BIT(MTK_SOC_MT7628_BIT)
- #define MTK_RSTCTRL_PPE1      BIT(MTK_RSTCTRL_PPE1_BIT)
- #define MTK_U3_COPHY_V2               BIT(MTK_U3_COPHY_V2_BIT)
diff --git a/target/linux/generic/pending-6.1/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch b/target/linux/generic/pending-6.1/737-05-net-ethernet-mtk_eth_soc-convert-caps-in-mtk_soc_dat.patch
deleted file mode 100644 (file)
index 068201c..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-From 45b575fd9e6a455090820248bf1b98b1f2c7b6c8 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Tue, 7 Mar 2023 15:56:00 +0000
-Subject: [PATCH 5/7] net: ethernet: mtk_eth_soc: convert caps in mtk_soc_data
- struct to u64
-
-This is a preliminary patch to introduce support for MT7988 SoC.
-
-Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 +++----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 62 ++++++++++----------
- 2 files changed, 42 insertions(+), 42 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
-@@ -15,10 +15,10 @@
- struct mtk_eth_muxc {
-       const char      *name;
-       int             cap_bit;
--      int             (*set_path)(struct mtk_eth *eth, int path);
-+      int             (*set_path)(struct mtk_eth *eth, u64 path);
- };
--static const char *mtk_eth_path_name(int path)
-+static const char *mtk_eth_path_name(u64 path)
- {
-       switch (path) {
-       case MTK_ETH_PATH_GMAC1_RGMII:
-@@ -40,7 +40,7 @@ static const char *mtk_eth_path_name(int
-       }
- }
--static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
-+static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
- {
-       bool updated = true;
-       u32 val, mask, set;
-@@ -71,7 +71,7 @@ static int set_mux_gdm1_to_gmac1_esw(str
-       return 0;
- }
--static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
-+static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path)
- {
-       unsigned int val = 0;
-       bool updated = true;
-@@ -94,7 +94,7 @@ static int set_mux_gmac2_gmac0_to_gephy(
-       return 0;
- }
--static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
-+static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
- {
-       unsigned int val = 0, mask = 0, reg = 0;
-       bool updated = true;
-@@ -125,7 +125,7 @@ static int set_mux_u3_gmac2_to_qphy(stru
-       return 0;
- }
--static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
-+static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
- {
-       unsigned int val = 0;
-       bool updated = true;
-@@ -163,7 +163,7 @@ static int set_mux_gmac1_gmac2_to_sgmii_
-       return 0;
- }
--static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
-+static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
- {
-       unsigned int val = 0;
-       bool updated = true;
-@@ -218,7 +218,7 @@ static const struct mtk_eth_muxc mtk_eth
-       },
- };
--static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
-+static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
- {
-       int i, err = 0;
-@@ -249,7 +249,7 @@ out:
- int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
- {
--      int path;
-+      u64 path;
-       path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
-                               MTK_ETH_PATH_GMAC2_SGMII;
-@@ -260,7 +260,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk
- int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
- {
--      int path = 0;
-+      u64 path = 0;
-       if (mac_id == 1)
-               path = MTK_ETH_PATH_GMAC2_GEPHY;
-@@ -274,7 +274,7 @@ int mtk_gmac_gephy_path_setup(struct mtk
- int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
- {
--      int path;
-+      u64 path;
-       path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_RGMII :
-                               MTK_ETH_PATH_GMAC2_RGMII;
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -881,44 +881,44 @@ enum mkt_eth_capabilities {
- };
- /* Supported hardware group on SoCs */
--#define MTK_RGMII             BIT(MTK_RGMII_BIT)
--#define MTK_TRGMII            BIT(MTK_TRGMII_BIT)
--#define MTK_SGMII             BIT(MTK_SGMII_BIT)
--#define MTK_ESW                       BIT(MTK_ESW_BIT)
--#define MTK_GEPHY             BIT(MTK_GEPHY_BIT)
--#define MTK_MUX                       BIT(MTK_MUX_BIT)
--#define MTK_INFRA             BIT(MTK_INFRA_BIT)
--#define MTK_SHARED_SGMII      BIT(MTK_SHARED_SGMII_BIT)
--#define MTK_HWLRO             BIT(MTK_HWLRO_BIT)
--#define MTK_SHARED_INT                BIT(MTK_SHARED_INT_BIT)
--#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
--#define MTK_QDMA              BIT(MTK_QDMA_BIT)
--#define MTK_NETSYS_V1         BIT(MTK_NETSYS_V1_BIT)
--#define MTK_NETSYS_V2         BIT(MTK_NETSYS_V2_BIT)
--#define MTK_NETSYS_V3         BIT(MTK_NETSYS_V3_BIT)
--#define MTK_SOC_MT7628                BIT(MTK_SOC_MT7628_BIT)
--#define MTK_RSTCTRL_PPE1      BIT(MTK_RSTCTRL_PPE1_BIT)
--#define MTK_U3_COPHY_V2               BIT(MTK_U3_COPHY_V2_BIT)
-+#define MTK_RGMII             BIT_ULL(MTK_RGMII_BIT)
-+#define MTK_TRGMII            BIT_ULL(MTK_TRGMII_BIT)
-+#define MTK_SGMII             BIT_ULL(MTK_SGMII_BIT)
-+#define MTK_ESW                       BIT_ULL(MTK_ESW_BIT)
-+#define MTK_GEPHY             BIT_ULL(MTK_GEPHY_BIT)
-+#define MTK_MUX                       BIT_ULL(MTK_MUX_BIT)
-+#define MTK_INFRA             BIT_ULL(MTK_INFRA_BIT)
-+#define MTK_SHARED_SGMII      BIT_ULL(MTK_SHARED_SGMII_BIT)
-+#define MTK_HWLRO             BIT_ULL(MTK_HWLRO_BIT)
-+#define MTK_SHARED_INT                BIT_ULL(MTK_SHARED_INT_BIT)
-+#define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT)
-+#define MTK_QDMA              BIT_ULL(MTK_QDMA_BIT)
-+#define MTK_NETSYS_V1         BIT_ULL(MTK_NETSYS_V1_BIT)
-+#define MTK_NETSYS_V2         BIT_ULL(MTK_NETSYS_V2_BIT)
-+#define MTK_NETSYS_V3         BIT_ULL(MTK_NETSYS_V3_BIT)
-+#define MTK_SOC_MT7628                BIT_ULL(MTK_SOC_MT7628_BIT)
-+#define MTK_RSTCTRL_PPE1      BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
-+#define MTK_U3_COPHY_V2               BIT_ULL(MTK_U3_COPHY_V2_BIT)
- #define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW         \
--      BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
-+      BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
- #define MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY      \
--      BIT(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
-+      BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
- #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY          \
--      BIT(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
-+      BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
- #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII        \
--      BIT(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
-+      BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
- #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII     \
--      BIT(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
-+      BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
- /* Supported path present on SoCs */
--#define MTK_ETH_PATH_GMAC1_RGMII      BIT(MTK_ETH_PATH_GMAC1_RGMII_BIT)
--#define MTK_ETH_PATH_GMAC1_TRGMII     BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
--#define MTK_ETH_PATH_GMAC1_SGMII      BIT(MTK_ETH_PATH_GMAC1_SGMII_BIT)
--#define MTK_ETH_PATH_GMAC2_RGMII      BIT(MTK_ETH_PATH_GMAC2_RGMII_BIT)
--#define MTK_ETH_PATH_GMAC2_SGMII      BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT)
--#define MTK_ETH_PATH_GMAC2_GEPHY      BIT(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
--#define MTK_ETH_PATH_GDM1_ESW         BIT(MTK_ETH_PATH_GDM1_ESW_BIT)
-+#define MTK_ETH_PATH_GMAC1_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
-+#define MTK_ETH_PATH_GMAC1_TRGMII     BIT_ULL(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
-+#define MTK_ETH_PATH_GMAC1_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_GEPHY      BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
-+#define MTK_ETH_PATH_GDM1_ESW         BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
- #define MTK_GMAC1_RGMII               (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
- #define MTK_GMAC1_TRGMII      (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
-@@ -1074,7 +1074,7 @@ struct mtk_reg_map {
- struct mtk_soc_data {
-       const struct mtk_reg_map *reg_map;
-       u32             ana_rgc3;
--      u32             caps;
-+      u64             caps;
-       u32             required_clks;
-       bool            required_pctl;
-       u8              offload_version;
diff --git a/target/linux/generic/pending-6.1/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch b/target/linux/generic/pending-6.1/737-06-net-ethernet-mtk_eth_soc-add-support-for-MT7988-SoC.patch
deleted file mode 100644 (file)
index 9c4408c..0000000
+++ /dev/null
@@ -1,495 +0,0 @@
-From 661bacf4363ca68939c15e20056b5f72fbd034e7 Mon Sep 17 00:00:00 2001
-From: Lorenzo Bianconi <lorenzo@kernel.org>
-Date: Sat, 25 Feb 2023 00:08:24 +0100
-Subject: [PATCH 6/7] net: ethernet: mtk_eth_soc: add support for MT7988 SoC
-
-Introduce support for ethernet chip available in MT7988 SoC to
-mtk_eth_soc driver.
----
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 153 ++++++++++++++--
- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 193 ++++++++++++++------
- 2 files changed, 279 insertions(+), 67 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r
-       .pse_oq_sta             = 0x01a0,
- };
-+static const struct mtk_reg_map mt7988_reg_map = {
-+      .tx_irq_mask            = 0x461c,
-+      .tx_irq_status          = 0x4618,
-+      .pdma = {
-+              .rx_ptr         = 0x6900,
-+              .rx_cnt_cfg     = 0x6904,
-+              .pcrx_ptr       = 0x6908,
-+              .glo_cfg        = 0x6a04,
-+              .rst_idx        = 0x6a08,
-+              .delay_irq      = 0x6a0c,
-+              .irq_status     = 0x6a20,
-+              .irq_mask       = 0x6a28,
-+              .adma_rx_dbg0   = 0x6a38,
-+              .int_grp        = 0x6a50,
-+      },
-+      .qdma = {
-+              .qtx_cfg        = 0x4400,
-+              .qtx_sch        = 0x4404,
-+              .rx_ptr         = 0x4500,
-+              .rx_cnt_cfg     = 0x4504,
-+              .qcrx_ptr       = 0x4508,
-+              .glo_cfg        = 0x4604,
-+              .rst_idx        = 0x4608,
-+              .delay_irq      = 0x460c,
-+              .fc_th          = 0x4610,
-+              .int_grp        = 0x4620,
-+              .hred           = 0x4644,
-+              .ctx_ptr        = 0x4700,
-+              .dtx_ptr        = 0x4704,
-+              .crx_ptr        = 0x4710,
-+              .drx_ptr        = 0x4714,
-+              .fq_head        = 0x4720,
-+              .fq_tail        = 0x4724,
-+              .fq_count       = 0x4728,
-+              .fq_blen        = 0x472c,
-+              .tx_sch_rate    = 0x4798,
-+      },
-+      .gdm1_cnt               = 0x1c00,
-+      .gdma_to_ppe            = 0x3333,
-+      .ppe_base               = 0x2200,
-+      .wdma_base = {
-+              [0]             = 0x4800,
-+              [1]             = 0x4c00,
-+      },
-+      .pse_iq_sta             = 0x0180,
-+      .pse_oq_sta             = 0x01a0,
-+};
-+
- /* strings used by ethtool */
- static const struct mtk_ethtool_stats {
-       char str[ETH_GSTRING_LEN];
-@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats {
- };
- static const char * const mtk_clks_source_name[] = {
--      "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll",
--      "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb",
--      "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb",
--      "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1"
-+      "ethif",
-+      "sgmiitop",
-+      "esw",
-+      "gp0",
-+      "gp1",
-+      "gp2",
-+      "gp3",
-+      "xgp1",
-+      "xgp2",
-+      "xgp3",
-+      "crypto",
-+      "fe",
-+      "trgpll",
-+      "sgmii_tx250m",
-+      "sgmii_rx250m",
-+      "sgmii_cdr_ref",
-+      "sgmii_cdr_fb",
-+      "sgmii2_tx250m",
-+      "sgmii2_rx250m",
-+      "sgmii2_cdr_ref",
-+      "sgmii2_cdr_fb",
-+      "sgmii_ck",
-+      "eth2pll",
-+      "wocpu0",
-+      "wocpu1",
-+      "netsys0",
-+      "netsys1",
-+      "ethwarp_wocpu2",
-+      "ethwarp_wocpu1",
-+      "ethwarp_wocpu0",
-+      "top_usxgmii0_sel",
-+      "top_usxgmii1_sel",
-+      "top_sgm0_sel",
-+      "top_sgm1_sel",
-+      "top_xfi_phy0_xtal_sel",
-+      "top_xfi_phy1_xtal_sel",
-+      "top_eth_gmii_sel",
-+      "top_eth_refck_50m_sel",
-+      "top_eth_sys_200m_sel",
-+      "top_eth_sys_sel",
-+      "top_eth_xgmii_sel",
-+      "top_eth_mii_sel",
-+      "top_netsys_sel",
-+      "top_netsys_500m_sel",
-+      "top_netsys_pao_2x_sel",
-+      "top_netsys_sync_250m_sel",
-+      "top_netsys_ppefb_250m_sel",
-+      "top_netsys_warp_sel",
- };
- void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
-@@ -1253,10 +1345,19 @@ static void mtk_tx_set_dma_desc_v2(struc
-               data |= TX_DMA_LS0;
-       WRITE_ONCE(desc->txd3, data);
--      if (mac->id == MTK_GMAC3_ID)
--              data = PSE_GDM3_PORT;
--      else
--              data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
-+       /* set forward port */
-+      switch (mac->id) {
-+      case MTK_GMAC1_ID:
-+              data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2;
-+              break;
-+      case MTK_GMAC2_ID:
-+              data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2;
-+              break;
-+      case MTK_GMAC3_ID:
-+              data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2;
-+              break;
-+      }
-+
-       data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
-       WRITE_ONCE(desc->txd4, data);
-@@ -5010,6 +5111,25 @@ static const struct mtk_soc_data mt7986_
-       },
- };
-+static const struct mtk_soc_data mt7988_data = {
-+      .reg_map = &mt7988_reg_map,
-+      .ana_rgc3 = 0x128,
-+      .caps = MT7988_CAPS,
-+      .hw_features = MTK_HW_FEATURES,
-+      .required_clks = MT7988_CLKS_BITMAP,
-+      .required_pctl = false,
-+      .num_devs = 3,
-+      .txrx = {
-+              .txd_size = sizeof(struct mtk_tx_dma_v2),
-+              .rxd_size = sizeof(struct mtk_rx_dma_v2),
-+              .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
-+              .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
-+              .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
-+              .dma_len_offset = 8,
-+      },
-+};
-+
-+
- static const struct mtk_soc_data rt5350_data = {
-       .reg_map = &mt7628_reg_map,
-       .caps = MT7628_CAPS,
-@@ -5028,14 +5148,15 @@ static const struct mtk_soc_data rt5350_
- };
- const struct of_device_id of_mtk_match[] = {
--      { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
--      { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
--      { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
--      { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
--      { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
--      { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
--      { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
--      { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
-+      { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data },
-+      { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data },
-+      { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data },
-+      { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data },
-+      { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data },
-+      { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data },
-+      { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data },
-+      { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data },
-+      { .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
-       {},
- };
- MODULE_DEVICE_TABLE(of, of_mtk_match);
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -116,7 +116,8 @@
- #define MTK_CDMP_EG_CTRL      0x404
- /* GDM Exgress Control Register */
--#define MTK_GDMA_FWD_CFG(x)   (0x500 + (x * 0x1000))
-+#define MTK_GDMA_FWD_CFG(x)   ((x == MTK_GMAC3_ID) ?          \
-+                               0x540 : 0x500 + (x * 0x1000))
- #define MTK_GDMA_SPECIAL_TAG  BIT(24)
- #define MTK_GDMA_ICS_EN               BIT(22)
- #define MTK_GDMA_TCS_EN               BIT(21)
-@@ -653,6 +654,11 @@ enum mtk_clks_map {
-       MTK_CLK_GP0,
-       MTK_CLK_GP1,
-       MTK_CLK_GP2,
-+      MTK_CLK_GP3,
-+      MTK_CLK_XGP1,
-+      MTK_CLK_XGP2,
-+      MTK_CLK_XGP3,
-+      MTK_CLK_CRYPTO,
-       MTK_CLK_FE,
-       MTK_CLK_TRGPLL,
-       MTK_CLK_SGMII_TX_250M,
-@@ -669,57 +675,108 @@ enum mtk_clks_map {
-       MTK_CLK_WOCPU1,
-       MTK_CLK_NETSYS0,
-       MTK_CLK_NETSYS1,
-+      MTK_CLK_ETHWARP_WOCPU2,
-+      MTK_CLK_ETHWARP_WOCPU1,
-+      MTK_CLK_ETHWARP_WOCPU0,
-+      MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
-+      MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
-+      MTK_CLK_TOP_SGM_0_SEL,
-+      MTK_CLK_TOP_SGM_1_SEL,
-+      MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
-+      MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
-+      MTK_CLK_TOP_ETH_GMII_SEL,
-+      MTK_CLK_TOP_ETH_REFCK_50M_SEL,
-+      MTK_CLK_TOP_ETH_SYS_200M_SEL,
-+      MTK_CLK_TOP_ETH_SYS_SEL,
-+      MTK_CLK_TOP_ETH_XGMII_SEL,
-+      MTK_CLK_TOP_ETH_MII_SEL,
-+      MTK_CLK_TOP_NETSYS_SEL,
-+      MTK_CLK_TOP_NETSYS_500M_SEL,
-+      MTK_CLK_TOP_NETSYS_PAO_2X_SEL,
-+      MTK_CLK_TOP_NETSYS_SYNC_250M_SEL,
-+      MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL,
-+      MTK_CLK_TOP_NETSYS_WARP_SEL,
-       MTK_CLK_MAX
- };
--#define MT7623_CLKS_BITMAP    (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) |  \
--                               BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \
--                               BIT(MTK_CLK_TRGPLL))
--#define MT7622_CLKS_BITMAP    (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) |  \
--                               BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
--                               BIT(MTK_CLK_GP2) | \
--                               BIT(MTK_CLK_SGMII_TX_250M) | \
--                               BIT(MTK_CLK_SGMII_RX_250M) | \
--                               BIT(MTK_CLK_SGMII_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII_CDR_FB) | \
--                               BIT(MTK_CLK_SGMII_CK) | \
--                               BIT(MTK_CLK_ETH2PLL))
-+#define MT7623_CLKS_BITMAP    (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) |  \
-+                               BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
-+                               BIT_ULL(MTK_CLK_TRGPLL))
-+#define MT7622_CLKS_BITMAP    (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) |  \
-+                               BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
-+                               BIT_ULL(MTK_CLK_GP2) | \
-+                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CK) | \
-+                               BIT_ULL(MTK_CLK_ETH2PLL))
- #define MT7621_CLKS_BITMAP    (0)
- #define MT7628_CLKS_BITMAP    (0)
--#define MT7629_CLKS_BITMAP    (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) |  \
--                               BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
--                               BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \
--                               BIT(MTK_CLK_SGMII_TX_250M) | \
--                               BIT(MTK_CLK_SGMII_RX_250M) | \
--                               BIT(MTK_CLK_SGMII_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII_CDR_FB) | \
--                               BIT(MTK_CLK_SGMII2_TX_250M) | \
--                               BIT(MTK_CLK_SGMII2_RX_250M) | \
--                               BIT(MTK_CLK_SGMII2_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII2_CDR_FB) | \
--                               BIT(MTK_CLK_SGMII_CK) | \
--                               BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
--#define MT7981_CLKS_BITMAP    (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
--                               BIT(MTK_CLK_WOCPU0) | \
--                               BIT(MTK_CLK_SGMII_TX_250M) | \
--                               BIT(MTK_CLK_SGMII_RX_250M) | \
--                               BIT(MTK_CLK_SGMII_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII_CDR_FB) | \
--                               BIT(MTK_CLK_SGMII2_TX_250M) | \
--                               BIT(MTK_CLK_SGMII2_RX_250M) | \
--                               BIT(MTK_CLK_SGMII2_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII2_CDR_FB) | \
--                               BIT(MTK_CLK_SGMII_CK))
--#define MT7986_CLKS_BITMAP    (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
--                               BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
--                               BIT(MTK_CLK_SGMII_TX_250M) | \
--                               BIT(MTK_CLK_SGMII_RX_250M) | \
--                               BIT(MTK_CLK_SGMII_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII_CDR_FB) | \
--                               BIT(MTK_CLK_SGMII2_TX_250M) | \
--                               BIT(MTK_CLK_SGMII2_RX_250M) | \
--                               BIT(MTK_CLK_SGMII2_CDR_REF) | \
--                               BIT(MTK_CLK_SGMII2_CDR_FB))
-+#define MT7629_CLKS_BITMAP    (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) |  \
-+                               BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
-+                               BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \
-+                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CK) | \
-+                               BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP))
-+#define MT7981_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \
-+                               BIT_ULL(MTK_CLK_WOCPU0) | \
-+                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CK))
-+#define MT7986_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \
-+                               BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \
-+                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
-+#define MT7988_CLKS_BITMAP    (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \
-+                               BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
-+                               BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
-+                               BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
-+                               BIT_ULL(MTK_CLK_CRYPTO) | \
-+                               BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-+                               BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
-+                               BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
-+                               BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
-+                               BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
-+                               BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \
-+                               BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL))
- enum mtk_dev_state {
-       MTK_HW_INIT,
-@@ -847,6 +904,7 @@ enum mkt_eth_capabilities {
-       MTK_RGMII_BIT = 0,
-       MTK_TRGMII_BIT,
-       MTK_SGMII_BIT,
-+      MTK_USXGMII_BIT,
-       MTK_ESW_BIT,
-       MTK_GEPHY_BIT,
-       MTK_MUX_BIT,
-@@ -869,6 +927,8 @@ enum mkt_eth_capabilities {
-       MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
-       MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
-       MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
-+      MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
-+      MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
-       /* PATH BITS */
-       MTK_ETH_PATH_GMAC1_RGMII_BIT,
-@@ -877,13 +937,18 @@ enum mkt_eth_capabilities {
-       MTK_ETH_PATH_GMAC2_RGMII_BIT,
-       MTK_ETH_PATH_GMAC2_SGMII_BIT,
-       MTK_ETH_PATH_GMAC2_GEPHY_BIT,
-+      MTK_ETH_PATH_GMAC3_SGMII_BIT,
-       MTK_ETH_PATH_GDM1_ESW_BIT,
-+      MTK_ETH_PATH_GMAC1_USXGMII_BIT,
-+      MTK_ETH_PATH_GMAC2_USXGMII_BIT,
-+      MTK_ETH_PATH_GMAC3_USXGMII_BIT,
- };
- /* Supported hardware group on SoCs */
- #define MTK_RGMII             BIT_ULL(MTK_RGMII_BIT)
- #define MTK_TRGMII            BIT_ULL(MTK_TRGMII_BIT)
- #define MTK_SGMII             BIT_ULL(MTK_SGMII_BIT)
-+#define MTK_USXGMII           BIT_ULL(MTK_USXGMII_BIT)
- #define MTK_ESW                       BIT_ULL(MTK_ESW_BIT)
- #define MTK_GEPHY             BIT_ULL(MTK_GEPHY_BIT)
- #define MTK_MUX                       BIT_ULL(MTK_MUX_BIT)
-@@ -910,6 +975,10 @@ enum mkt_eth_capabilities {
-       BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
- #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII     \
-       BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
-+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII    \
-+      BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT)
-+#define MTK_ETH_MUX_GMAC123_TO_USXGMII        \
-+      BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
- /* Supported path present on SoCs */
- #define MTK_ETH_PATH_GMAC1_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
-@@ -918,7 +987,11 @@ enum mkt_eth_capabilities {
- #define MTK_ETH_PATH_GMAC2_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
- #define MTK_ETH_PATH_GMAC2_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
- #define MTK_ETH_PATH_GMAC2_GEPHY      BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
-+#define MTK_ETH_PATH_GMAC3_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
- #define MTK_ETH_PATH_GDM1_ESW         BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
-+#define MTK_ETH_PATH_GMAC1_USXGMII    BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_USXGMII    BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
-+#define MTK_ETH_PATH_GMAC3_USXGMII    BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
- #define MTK_GMAC1_RGMII               (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
- #define MTK_GMAC1_TRGMII      (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
-@@ -926,7 +999,11 @@ enum mkt_eth_capabilities {
- #define MTK_GMAC2_RGMII               (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
- #define MTK_GMAC2_SGMII               (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
- #define MTK_GMAC2_GEPHY               (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
-+#define MTK_GMAC3_SGMII               (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
- #define MTK_GDM1_ESW          (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
-+#define MTK_GMAC1_USXGMII     (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
-+#define MTK_GMAC2_USXGMII     (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
-+#define MTK_GMAC3_USXGMII     (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
- /* MUXes present on SoCs */
- /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
-@@ -949,6 +1026,12 @@ enum mkt_eth_capabilities {
- #define MTK_MUX_GMAC12_TO_GEPHY_SGMII   \
-       (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
-+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII   \
-+      (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX)
-+
-+#define MTK_MUX_GMAC123_TO_USXGMII   \
-+      (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
-+
- #ifdef CONFIG_SOC_MT7621
- #define MTK_CAP_MASK MTK_NETSYS_V2
- #else
-@@ -987,9 +1070,17 @@ enum mkt_eth_capabilities {
-                     MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
-                     MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
--#define MT7986_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
--                    MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
--                    MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
-+#define MT7986_CAPS  (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII |     \
-+                    MTK_MUX_GMAC12_TO_GEPHY_SGMII |           \
-+                    MTK_QDMA | MTK_NETSYS_V2 |                \
-+                    MTK_RSTCTRL_PPE1)
-+
-+#define MT7988_CAPS   (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII |    \
-+                     MTK_GMAC3_SGMII | MTK_QDMA |             \
-+                     MTK_MUX_GMAC123_TO_GEPHY_SGMII |         \
-+                     MTK_NETSYS_V3 | MTK_RSTCTRL_PPE1 |       \
-+                     MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII |  \
-+                     MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII)
- struct mtk_tx_dma_desc_info {
-       dma_addr_t      addr;
-@@ -1075,7 +1166,7 @@ struct mtk_soc_data {
-       const struct mtk_reg_map *reg_map;
-       u32             ana_rgc3;
-       u64             caps;
--      u32             required_clks;
-+      u64             required_clks;
-       bool            required_pctl;
-       u8              offload_version;
-       u8              hash_offset;
diff --git a/target/linux/generic/pending-6.1/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-6.1/737-07-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
deleted file mode 100644 (file)
index 81b0d2e..0000000
+++ /dev/null
@@ -1,1867 +0,0 @@
-From 3d833ad2cfc1ab503d9aae2967b7f10811bb3c9c Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Wed, 1 Mar 2023 11:56:04 +0000
-Subject: [PATCH 7/7] net: ethernet: mtk_eth_soc: add paths and SerDes modes 
- for MT7988
-
-MT7988 comes with a built-in 2.5G PHY as well as
-USXGMII/10GBase-KR/5GBase-KR compatible SerDes lanes for external PHYs.
-Add support for configuring the MAC and SerDes parts for the new paths.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/ethernet/mediatek/Kconfig        |   7 +
- drivers/net/ethernet/mediatek/Makefile       |   1 +
- drivers/net/ethernet/mediatek/mtk_eth_path.c | 154 +++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c  | 270 +++++-
- drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 194 ++++-
- drivers/net/ethernet/mediatek/mtk_usxgmii.c  | 835 +++++++++++++++++++
- 6 files changed, 1428 insertions(+), 33 deletions(-)
- create mode 100644 drivers/net/ethernet/mediatek/mtk_usxgmii.c
-
---- a/drivers/net/ethernet/mediatek/Kconfig
-+++ b/drivers/net/ethernet/mediatek/Kconfig
-@@ -25,6 +25,13 @@ config NET_MEDIATEK_SOC
-         This driver supports the gigabit ethernet MACs in the
-         MediaTek SoC family.
-+config NET_MEDIATEK_SOC_USXGMII
-+      bool "Support USXGMII SerDes on MT7988"
-+      depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
-+      def_bool NET_MEDIATEK_SOC != n
-+      help
-+        Include support for 10G SerDes which can be found on MT7988.
-+
- config NET_MEDIATEK_STAR_EMAC
-       tristate "MediaTek STAR Ethernet MAC support"
-       select PHYLIB
---- a/drivers/net/ethernet/mediatek/Makefile
-+++ b/drivers/net/ethernet/mediatek/Makefile
-@@ -5,6 +5,7 @@
- obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
- mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
-+mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_USXGMII) += mtk_usxgmii.o
- mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o
- ifdef CONFIG_DEBUG_FS
- mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
---- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
-@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64
-               return "gmac2_rgmii";
-       case MTK_ETH_PATH_GMAC2_SGMII:
-               return "gmac2_sgmii";
-+      case MTK_ETH_PATH_GMAC2_2P5GPHY:
-+              return "gmac2_2p5gphy";
-       case MTK_ETH_PATH_GMAC2_GEPHY:
-               return "gmac2_gephy";
-+      case MTK_ETH_PATH_GMAC3_SGMII:
-+              return "gmac3_sgmii";
-       case MTK_ETH_PATH_GDM1_ESW:
-               return "gdm1_esw";
-+      case MTK_ETH_PATH_GMAC1_USXGMII:
-+              return "gmac1_usxgmii";
-+      case MTK_ETH_PATH_GMAC2_USXGMII:
-+              return "gmac2_usxgmii";
-+      case MTK_ETH_PATH_GMAC3_USXGMII:
-+              return "gmac3_usxgmii";
-       default:
-               return "unknown path";
-       }
-@@ -42,8 +52,8 @@ static const char *mtk_eth_path_name(u64
- static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
- {
-+      u32 val, mask, set, reg;
-       bool updated = true;
--      u32 val, mask, set;
-       switch (path) {
-       case MTK_ETH_PATH_GMAC1_SGMII:
-@@ -59,10 +69,15 @@ static int set_mux_gdm1_to_gmac1_esw(str
-               break;
-       }
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
-+              reg = MTK_MAC_MISC_V3;
-+      else
-+              reg = MTK_MAC_MISC;
-+
-       if (updated) {
--              val = mtk_r32(eth, MTK_MAC_MISC);
-+              val = mtk_r32(eth, reg);
-               val = (val & mask) | set;
--              mtk_w32(eth, val, MTK_MAC_MISC);
-+              mtk_w32(eth, val, reg);
-       }
-       dev_dbg(eth->dev, "path %s in %s updated = %d\n",
-@@ -125,6 +140,31 @@ static int set_mux_u3_gmac2_to_qphy(stru
-       return 0;
- }
-+static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path)
-+{
-+      unsigned int val = 0;
-+      bool updated = true;
-+      int mac_id = 0;
-+
-+      regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
-+
-+      switch (path) {
-+      case MTK_ETH_PATH_GMAC2_2P5GPHY:
-+              val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
-+              mac_id = MTK_GMAC2_ID;
-+              break;
-+      default:
-+              updated = false;
-+              break;
-+      };
-+
-+      if (updated)
-+              regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
-+                                 SYSCFG0_SGMII_MASK, val);
-+
-+      return 0;
-+}
-+
- static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
- {
-       unsigned int val = 0;
-@@ -163,7 +203,61 @@ static int set_mux_gmac1_gmac2_to_sgmii_
-       return 0;
- }
--static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
-+static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path)
-+{
-+      unsigned int val = 0;
-+      bool updated = true;
-+      int mac_id = 0;
-+
-+      dev_dbg(eth->dev, "path %s in %s updated = %d\n",
-+              mtk_eth_path_name(path), __func__, updated);
-+
-+      /* Disable SYSCFG1 SGMII */
-+      regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
-+
-+      switch (path) {
-+      case MTK_ETH_PATH_GMAC1_USXGMII:
-+              val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2;
-+              mac_id = MTK_GMAC1_ID;
-+              break;
-+      case MTK_ETH_PATH_GMAC2_USXGMII:
-+              val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
-+              mac_id = MTK_GMAC2_ID;
-+              break;
-+      case MTK_ETH_PATH_GMAC3_USXGMII:
-+              val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2;
-+              mac_id = MTK_GMAC3_ID;
-+              break;
-+      default:
-+              updated = false;
-+      };
-+
-+      if (updated) {
-+              regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
-+                                 SYSCFG0_SGMII_MASK, val);
-+
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
-+                  mac_id == MTK_GMAC2_ID) {
-+                      regmap_update_bits(eth->infra,
-+                                         TOP_MISC_NETSYS_PCS_MUX,
-+                                         NETSYS_PCS_MUX_MASK,
-+                                         MUX_G2_USXGMII_SEL);
-+              }
-+      }
-+
-+      /* Enable XGDM Path */
-+      val = mtk_r32(eth, MTK_GDMA_EG_CTRL(mac_id));
-+      val |= MTK_GDMA_XGDM_SEL;
-+      mtk_w32(eth, val, MTK_GDMA_EG_CTRL(mac_id));
-+
-+      dev_dbg(eth->dev, "path %s in %s updated = %d\n",
-+              mtk_eth_path_name(path), __func__, updated);
-+
-+
-+      return 0;
-+}
-+
-+static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
- {
-       unsigned int val = 0;
-       bool updated = true;
-@@ -180,6 +274,9 @@ static int set_mux_gmac12_to_gephy_sgmii
-       case MTK_ETH_PATH_GMAC2_SGMII:
-               val |= SYSCFG0_SGMII_GMAC2_V2;
-               break;
-+      case MTK_ETH_PATH_GMAC3_SGMII:
-+              val |= SYSCFG0_SGMII_GMAC3_V2;
-+              break;
-       default:
-               updated = false;
-       }
-@@ -208,13 +305,25 @@ static const struct mtk_eth_muxc mtk_eth
-               .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
-               .set_path = set_mux_u3_gmac2_to_qphy,
-       }, {
-+              .name = "mux_gmac2_to_2p5gphy",
-+              .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY,
-+              .set_path = set_mux_gmac2_to_2p5gphy,
-+      }, {
-               .name = "mux_gmac1_gmac2_to_sgmii_rgmii",
-               .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
-               .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii,
-       }, {
-               .name = "mux_gmac12_to_gephy_sgmii",
-               .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
--              .set_path = set_mux_gmac12_to_gephy_sgmii,
-+              .set_path = set_mux_gmac123_to_gephy_sgmii,
-+      }, {
-+              .name = "mux_gmac123_to_gephy_sgmii",
-+              .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII,
-+              .set_path = set_mux_gmac123_to_gephy_sgmii,
-+      }, {
-+              .name = "mux_gmac123_to_usxgmii",
-+              .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII,
-+              .set_path = set_mux_gmac123_to_usxgmii,
-       },
- };
-@@ -243,16 +352,46 @@ static int mtk_eth_mux_setup(struct mtk_
-               }
-       }
-+      dev_dbg(eth->dev, "leaving mux_setup %s\n",
-+              mtk_eth_path_name(path));
-+
- out:
-       return err;
- }
-+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id)
-+{
-+      u64 path;
-+
-+      path = (mac_id == MTK_GMAC1_ID) ?  MTK_ETH_PATH_GMAC1_USXGMII :
-+             (mac_id == MTK_GMAC2_ID) ?  MTK_ETH_PATH_GMAC2_USXGMII :
-+                                         MTK_ETH_PATH_GMAC3_USXGMII;
-+
-+      /* Setup proper MUXes along the path */
-+      return mtk_eth_mux_setup(eth, path);
-+}
-+
- int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
- {
-       u64 path;
--      path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
--                              MTK_ETH_PATH_GMAC2_SGMII;
-+      path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII :
-+             (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII :
-+                                        MTK_ETH_PATH_GMAC3_SGMII;
-+
-+      /* Setup proper MUXes along the path */
-+      return mtk_eth_mux_setup(eth, path);
-+}
-+
-+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id)
-+{
-+      u64 path = 0;
-+
-+      if (mac_id == MTK_GMAC2_ID)
-+              path = MTK_ETH_PATH_GMAC2_2P5GPHY;
-+
-+      if (!path)
-+              return -EINVAL;
-       /* Setup proper MUXes along the path */
-       return mtk_eth_mux_setup(eth, path);
-@@ -282,4 +421,3 @@ int mtk_gmac_rgmii_path_setup(struct mtk
-       /* Setup proper MUXes along the path */
-       return mtk_eth_mux_setup(eth, path);
- }
--
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -480,6 +480,23 @@ static void mtk_gmac0_rgmii_adjust(struc
-       mtk_w32(eth, val, TRGMII_TCK_CTRL);
- }
-+static void mtk_setup_bridge_switch(struct mtk_eth *eth)
-+{
-+      int val;
-+
-+      /* Force Port1 XGMAC Link Up */
-+      val = mtk_r32(eth, MTK_XGMAC_STS(MTK_GMAC1_ID));
-+      mtk_w32(eth, val | MTK_XGMAC_FORCE_LINK(MTK_GMAC1_ID),
-+              MTK_XGMAC_STS(MTK_GMAC1_ID));
-+
-+      /* Adjust GSW bridge IPG to 11*/
-+      val = mtk_r32(eth, MTK_GSW_CFG);
-+      val &= ~(GSWTX_IPG_MASK | GSWRX_IPG_MASK);
-+      val |= (GSW_IPG_11 << GSWTX_IPG_SHIFT) |
-+             (GSW_IPG_11 << GSWRX_IPG_SHIFT);
-+      mtk_w32(eth, val, MTK_GSW_CFG);
-+}
-+
- static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
-                                             phy_interface_t interface)
- {
-@@ -494,6 +511,12 @@ static struct phylink_pcs *mtk_mac_selec
-                      0 : mac->id;
-               return eth->sgmii_pcs[sid];
-+      } else if ((interface == PHY_INTERFACE_MODE_USXGMII ||
-+                  interface == PHY_INTERFACE_MODE_10GKR ||
-+                  interface == PHY_INTERFACE_MODE_5GBASER) &&
-+                 MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
-+                 mac->id != MTK_GMAC1_ID) {
-+                      return mtk_usxgmii_select_pcs(eth, mac->id);
-       }
-       return NULL;
-@@ -505,7 +528,7 @@ static void mtk_mac_config(struct phylin
-       struct mtk_mac *mac = container_of(config, struct mtk_mac,
-                                          phylink_config);
-       struct mtk_eth *eth = mac->hw;
--      int val, ge_mode, err = 0;
-+      int val, ge_mode, force_link, err = 0;
-       u32 i;
-       /* MT76x8 has no hardware settings between for the MAC */
-@@ -549,6 +572,23 @@ static void mtk_mac_config(struct phylin
-                                       goto init_err;
-                       }
-                       break;
-+              case PHY_INTERFACE_MODE_USXGMII:
-+              case PHY_INTERFACE_MODE_10GKR:
-+              case PHY_INTERFACE_MODE_5GBASER:
-+                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
-+                              err = mtk_gmac_usxgmii_path_setup(eth, mac->id);
-+                              if (err)
-+                                      goto init_err;
-+                      }
-+                      break;
-+              case PHY_INTERFACE_MODE_INTERNAL:
-+                      if (mac->id == MTK_GMAC2_ID &&
-+                          MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) {
-+                              err = mtk_gmac_2p5gphy_path_setup(eth, mac->id);
-+                              if (err)
-+                                      goto init_err;
-+                      }
-+                      break;
-               default:
-                       goto err_phy;
-               }
-@@ -627,14 +667,78 @@ static void mtk_mac_config(struct phylin
-                                  SYSCFG0_SGMII_MASK,
-                                  ~(u32)SYSCFG0_SGMII_MASK);
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+                      mtk_xfi_pll_enable(eth);
-+                      mtk_sgmii_reset(eth, mac->id);
-+                      if (phylink_autoneg_inband(mode))
-+                              mtk_sgmii_setup_phya_gen1(eth, mac->id);
-+                      else
-+                              mtk_sgmii_setup_phya_gen2(eth, mac->id);
-+              }
-               /* Save the syscfg0 value for mac_finish */
-               mac->syscfg0 = val;
--      } else if (phylink_autoneg_inband(mode)) {
-+      } else if (state->interface != PHY_INTERFACE_MODE_USXGMII &&
-+                 state->interface != PHY_INTERFACE_MODE_10GKR &&
-+                 state->interface != PHY_INTERFACE_MODE_5GBASER &&
-+                 phylink_autoneg_inband(mode)) {
-               dev_err(eth->dev,
--                      "In-band mode not supported in non SGMII mode!\n");
-+                      "In-band mode not supported in non-SerDes modes!\n");
-               return;
-       }
-+      /* Setup gmac */
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
-+          (mtk_interface_mode_is_xgmii(state->interface) ||
-+           mac->interface == PHY_INTERFACE_MODE_INTERNAL)) {
-+              mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
-+              mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
-+
-+              switch (mac->id) {
-+              case MTK_GMAC1_ID:
-+                      mtk_setup_bridge_switch(eth);
-+                      break;
-+              case MTK_GMAC2_ID:
-+                      force_link = (mac->interface ==
-+                                    PHY_INTERFACE_MODE_INTERNAL) ?
-+                                    MTK_XGMAC_FORCE_LINK(mac->id) : 0;
-+                      val = mtk_r32(eth, MTK_XGMAC_STS(mac->id));
-+                      mtk_w32(eth, val | force_link,
-+                              MTK_XGMAC_STS(mac->id));
-+                      break;
-+              case MTK_GMAC3_ID:
-+                      val = mtk_r32(eth, MTK_XGMAC_STS(mac->id));
-+                      mtk_w32(eth, val | MTK_XGMAC_FORCE_LINK(mac->id),
-+                              MTK_XGMAC_STS(mac->id));
-+                      break;
-+              }
-+      } else {
-+              val = mtk_r32(eth, MTK_GDMA_EG_CTRL(mac->id));
-+              mtk_w32(eth, val & ~MTK_GDMA_XGDM_SEL,
-+                      MTK_GDMA_EG_CTRL(mac->id));
-+
-+              if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+                      switch (mac->id) {
-+                      case MTK_GMAC2_ID:
-+                      case MTK_GMAC3_ID:
-+                              val = mtk_r32(eth, MTK_XGMAC_STS(mac->id));
-+                              mtk_w32(eth,
-+                                      val & ~MTK_XGMAC_FORCE_LINK(mac->id),
-+                                      MTK_XGMAC_STS(mac->id));
-+                              break;
-+                      }
-+              }
-+
-+/*
-+              if (mac->type != mac_type) {
-+                      if (atomic_read(&reset_pending) == 0) {
-+                              atomic_inc(&force);
-+                              schedule_work(&eth->pending_work);
-+                              atomic_inc(&reset_pending);
-+                      } else
-+                              atomic_dec(&reset_pending);
-+              }
-+*/
-+      }
-       return;
- err_phy:
-@@ -675,11 +779,40 @@ static int mtk_mac_finish(struct phylink
-       return 0;
- }
--static void mtk_mac_pcs_get_state(struct phylink_config *config,
-+static void mtk_xgdm_pcs_get_state(struct mtk_mac *mac,
-+                                struct phylink_link_state *state)
-+{
-+      u32 sts = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
-+
-+      if (mac->id == MTK_GMAC2_ID)
-+              sts = sts >> 16;
-+
-+      state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, sts);
-+      if (!state->link)
-+              return;
-+
-+      state->duplex = DUPLEX_FULL;
-+      state->interface = mac->interface;
-+
-+      switch (FIELD_GET(MTK_USXGMII_PCS_MODE, sts)) {
-+      case 0:
-+              state->speed = SPEED_10000;
-+              break;
-+      case 1:
-+              state->speed = SPEED_5000;
-+              break;
-+      case 2:
-+              state->speed = SPEED_2500;
-+              break;
-+      case 3:
-+              state->speed = SPEED_1000;
-+              break;
-+      }
-+}
-+
-+static void mtk_gdm_pcs_get_state(struct mtk_mac *mac,
-                                 struct phylink_link_state *state)
- {
--      struct mtk_mac *mac = container_of(config, struct mtk_mac,
--                                         phylink_config);
-       u32 pmsr = mtk_r32(mac->hw, MTK_MAC_MSR(mac->id));
-       state->link = (pmsr & MAC_MSR_LINK);
-@@ -707,15 +840,35 @@ static void mtk_mac_pcs_get_state(struct
-               state->pause |= MLO_PAUSE_TX;
- }
-+static void mtk_mac_pcs_get_state(struct phylink_config *config,
-+                                struct phylink_link_state *state)
-+{
-+      struct mtk_mac *mac = container_of(config, struct mtk_mac,
-+                                         phylink_config);
-+
-+      if (mtk_interface_mode_is_xgmii(state->interface))
-+              mtk_xgdm_pcs_get_state(mac, state);
-+      else
-+              mtk_gdm_pcs_get_state(mac, state);
-+}
-+
- static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
-                             phy_interface_t interface)
- {
-       struct mtk_mac *mac = container_of(config, struct mtk_mac,
-                                          phylink_config);
--      u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-+      u32 mcr;
--      mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
--      mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
-+      if (!mtk_interface_mode_is_xgmii(interface)) {
-+              mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-+              mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
-+              mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
-+      } else if (mac->id != MTK_GMAC1_ID) {
-+              mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
-+              mcr &= 0xfffffff0;
-+              mcr |= XMAC_MCR_TRX_DISABLE;
-+              mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
-+      }
- }
- static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
-@@ -787,13 +940,11 @@ static void mtk_set_queue_speed(struct m
-       mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
- }
--static void mtk_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)
-+static void mtk_gdm_mac_link_up(struct mtk_mac *mac,
-+                              struct phy_device *phy,
-+                              unsigned int mode, phy_interface_t interface,
-+                              int speed, int duplex, bool tx_pause, bool rx_pause)
- {
--      struct mtk_mac *mac = container_of(config, struct mtk_mac,
--                                         phylink_config);
-       u32 mcr;
-       mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
-@@ -827,6 +978,47 @@ static void mtk_mac_link_up(struct phyli
-       mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
- }
-+static void mtk_xgdm_mac_link_up(struct mtk_mac *mac,
-+                               struct phy_device *phy,
-+                               unsigned int mode, phy_interface_t interface,
-+                               int speed, int duplex, bool tx_pause, bool rx_pause)
-+{
-+      u32 mcr;
-+
-+      if (mac->id == MTK_GMAC1_ID)
-+              return;
-+
-+      mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
-+
-+      mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC);
-+      /* Configure pause modes -
-+       * phylink will avoid these for half duplex
-+       */
-+      if (tx_pause)
-+              mcr |= XMAC_MCR_FORCE_TX_FC;
-+      if (rx_pause)
-+              mcr |= XMAC_MCR_FORCE_RX_FC;
-+
-+      mcr &= ~(XMAC_MCR_TRX_DISABLE);
-+      mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
-+}
-+
-+static void mtk_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)
-+{
-+      struct mtk_mac *mac = container_of(config, struct mtk_mac,
-+                                         phylink_config);
-+
-+      if (mtk_interface_mode_is_xgmii(interface))
-+              mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
-+                                   tx_pause, rx_pause);
-+      else
-+              mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
-+                                  tx_pause, rx_pause);
-+}
-+
- static const struct phylink_mac_ops mtk_phylink_ops = {
-       .validate = phylink_generic_validate,
-       .mac_select_pcs = mtk_mac_select_pcs,
-@@ -880,10 +1072,21 @@ static int mtk_mdio_init(struct mtk_eth
-       }
-       divider = min_t(unsigned int, DIV_ROUND_UP(MDC_MAX_FREQ, max_clk), 63);
-+      /* Configure MDC Turbo Mode */
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+              val = mtk_r32(eth, MTK_MAC_MISC_V3);
-+              val |= MISC_MDC_TURBO;
-+              mtk_w32(eth, val, MTK_MAC_MISC_V3);
-+      } else {
-+              val = mtk_r32(eth, MTK_PPSC);
-+              val |= PPSC_MDC_TURBO;
-+              mtk_w32(eth, val, MTK_PPSC);
-+      }
-+
-       /* Configure MDC Divider */
-       val = mtk_r32(eth, MTK_PPSC);
-       val &= ~PPSC_MDC_CFG;
--      val |= FIELD_PREP(PPSC_MDC_CFG, divider) | PPSC_MDC_TURBO;
-+      val |= FIELD_PREP(PPSC_MDC_CFG, divider);
-       mtk_w32(eth, val, MTK_PPSC);
-       dev_dbg(eth->dev, "MDC is running on %d Hz\n", MDC_MAX_FREQ / divider);
-@@ -4469,8 +4672,8 @@ static int mtk_add_mac(struct mtk_eth *e
-       const __be32 *_id = of_get_property(np, "reg", NULL);
-       phy_interface_t phy_mode;
-       struct phylink *phylink;
--      struct mtk_mac *mac;
-       int id, err;
-+      struct mtk_mac *mac;
-       int txqs = 1;
-       if (!_id) {
-@@ -4572,6 +4775,32 @@ static int mtk_add_mac(struct mtk_eth *e
-                         mac->phylink_config.supported_interfaces);
-       }
-+      if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) {
-+              if (id == MTK_GMAC1_ID) {
-+                      mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE |
-+                                                             MAC_SYM_PAUSE |
-+                                                             MAC_10000FD;
-+                      phy_interface_zero(
-+                              mac->phylink_config.supported_interfaces);
-+                      __set_bit(PHY_INTERFACE_MODE_INTERNAL,
-+                                mac->phylink_config.supported_interfaces);
-+              } else {
-+                      mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD;
-+                      __set_bit(PHY_INTERFACE_MODE_5GBASER,
-+                                mac->phylink_config.supported_interfaces);
-+                      __set_bit(PHY_INTERFACE_MODE_10GKR,
-+                                mac->phylink_config.supported_interfaces);
-+                      __set_bit(PHY_INTERFACE_MODE_USXGMII,
-+                                mac->phylink_config.supported_interfaces);
-+              }
-+      }
-+
-+      if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY)) {
-+              if (id == MTK_GMAC2_ID)
-+                      __set_bit(PHY_INTERFACE_MODE_INTERNAL,
-+                                mac->phylink_config.supported_interfaces);
-+      }
-+
-       phylink = phylink_create(&mac->phylink_config,
-                                of_fwnode_handle(mac->of_node),
-                                phy_mode, &mtk_phylink_ops);
-@@ -4759,6 +4988,13 @@ static int mtk_probe(struct platform_dev
-               if (err)
-                       return err;
-+      }
-+
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
-+              err = mtk_usxgmii_init(eth);
-+
-+              if (err)
-+                      return err;
-       }
-       if (eth->soc->required_pctl) {
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -126,6 +126,11 @@
- #define MTK_GDMA_TO_PDMA      0x0
- #define MTK_GDMA_DROP_ALL       0x7777
-+/* GDM Egress Control Register */
-+#define MTK_GDMA_EG_CTRL(x)   ((x == MTK_GMAC3_ID) ?          \
-+                               0x544 : 0x504 + (x * 0x1000))
-+#define MTK_GDMA_XGDM_SEL     BIT(31)
-+
- /* Unicast Filter MAC Address Register - Low */
- #define MTK_GDMA_MAC_ADRL(x)  (0x508 + (x * 0x1000))
-@@ -389,7 +394,26 @@
- #define PHY_IAC_TIMEOUT               HZ
- #define MTK_MAC_MISC          0x1000c
-+#define MTK_MAC_MISC_V3               0x10010
- #define MTK_MUX_TO_ESW                BIT(0)
-+#define MISC_MDC_TURBO                BIT(4)
-+
-+/* XMAC status registers */
-+#define MTK_XGMAC_STS(x)      ((x == MTK_GMAC3_ID) ? 0x1001C : 0x1000C)
-+#define MTK_XGMAC_FORCE_LINK(x)       ((x == MTK_GMAC2_ID) ? BIT(31) : BIT(15))
-+#define MTK_USXGMII_PCS_LINK  BIT(8)
-+#define MTK_XGMAC_RX_FC               BIT(5)
-+#define MTK_XGMAC_TX_FC               BIT(4)
-+#define MTK_USXGMII_PCS_MODE  GENMASK(3, 1)
-+#define MTK_XGMAC_LINK_STS    BIT(0)
-+
-+/* GSW bridge registers */
-+#define MTK_GSW_CFG           (0x10080)
-+#define GSWTX_IPG_MASK                GENMASK(19, 16)
-+#define GSWTX_IPG_SHIFT               16
-+#define GSWRX_IPG_MASK                GENMASK(3, 0)
-+#define GSWRX_IPG_SHIFT               0
-+#define GSW_IPG_11            11
- /* Mac control registers */
- #define MTK_MAC_MCR(x)                (0x10100 + (x * 0x100))
-@@ -414,6 +438,17 @@
- #define MAC_MCR_FORCE_LINK    BIT(0)
- #define MAC_MCR_FORCE_LINK_DOWN       (MAC_MCR_FORCE_MODE)
-+/* Mac EEE control registers */
-+#define MTK_MAC_EEE(x)                (0x10104 + (x * 0x100))
-+#define MAC_EEE_WAKEUP_TIME_1000      GENMASK(31, 24)
-+#define MAC_EEE_WAKEUP_TIME_100       GENMASK(23, 16)
-+#define MAC_EEE_LPI_TXIDLE_THD        GENMASK(15, 8)
-+#define MAC_EEE_RESV0         GENMASK(7, 4)
-+#define MAC_EEE_CKG_TXILDE    BIT(3)
-+#define MAC_EEE_CKG_RXLPI     BIT(2)
-+#define MAC_EEE_TX_DOWN_REQ   BIT(1)
-+#define MAC_EEE_LPI_MODE      BIT(0)
-+
- /* Mac status registers */
- #define MTK_MAC_MSR(x)                (0x10108 + (x * 0x100))
- #define MAC_MSR_EEE1G         BIT(7)
-@@ -458,6 +493,12 @@
- #define INTF_MODE_RGMII_1000    (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
- #define INTF_MODE_RGMII_10_100  0
-+/* XFI Mac control registers */
-+#define MTK_XMAC_MCR(x)               (0x12000 + ((x - 1) * 0x1000))
-+#define XMAC_MCR_TRX_DISABLE  0xf
-+#define XMAC_MCR_FORCE_TX_FC  BIT(5)
-+#define XMAC_MCR_FORCE_RX_FC  BIT(4)
-+
- /* GPIO port control registers for GMAC 2*/
- #define GPIO_OD33_CTRL8               0x4c0
- #define GPIO_BIAS_CTRL                0xed0
-@@ -483,6 +524,7 @@
- #define SYSCFG0_SGMII_GMAC2    ((3 << 8) & SYSCFG0_SGMII_MASK)
- #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
- #define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
-+#define SYSCFG0_SGMII_GMAC3_V2 BIT(7)
- /* ethernet subsystem clock register */
-@@ -509,16 +551,91 @@
- #define ETHSYS_DMA_AG_MAP_QDMA        BIT(1)
- #define ETHSYS_DMA_AG_MAP_PPE BIT(2)
-+/* USXGMII subsystem config registers */
-+/* Register to control speed */
-+#define RG_PHY_TOP_SPEED_CTRL1        0x80C
-+#define USXGMII_RATE_UPDATE_MODE      BIT(31)
-+#define USXGMII_MAC_CK_GATED  BIT(29)
-+#define USXGMII_IF_FORCE_EN   BIT(28)
-+#define USXGMII_RATE_ADAPT_MODE       GENMASK(10, 8)
-+#define USXGMII_RATE_ADAPT_MODE_X1    0
-+#define USXGMII_RATE_ADAPT_MODE_X2    1
-+#define USXGMII_RATE_ADAPT_MODE_X4    2
-+#define USXGMII_RATE_ADAPT_MODE_X10   3
-+#define USXGMII_RATE_ADAPT_MODE_X100  4
-+#define USXGMII_RATE_ADAPT_MODE_X5    5
-+#define USXGMII_RATE_ADAPT_MODE_X50   6
-+#define USXGMII_XFI_RX_MODE   GENMASK(6, 4)
-+#define USXGMII_XFI_RX_MODE_10G       0
-+#define USXGMII_XFI_RX_MODE_5G        1
-+#define USXGMII_XFI_TX_MODE   GENMASK(2, 0)
-+#define USXGMII_XFI_TX_MODE_10G       0
-+#define USXGMII_XFI_TX_MODE_5G        1
-+
-+/* Register to control PCS AN */
-+#define RG_PCS_AN_CTRL0               0x810
-+#define USXGMII_AN_RESTART    BIT(31)
-+#define USXGMII_AN_SYNC_CNT   GENMASK(30, 11)
-+#define USXGMII_AN_ENABLE     BIT(0)
-+
-+#define RG_PCS_AN_CTRL2               0x818
-+#define USXGMII_LINK_TIMER_IDLE_DETECT        GENMASK(29, 20)
-+#define USXGMII_LINK_TIMER_COMP_ACK_DETECT    GENMASK(19, 10)
-+#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0)
-+
-+/* Register to read PCS AN status */
-+#define RG_PCS_AN_STS0                0x81c
-+#define USXGMII_LPA_SPEED_MASK        GENMASK(11, 9)
-+#define USXGMII_LPA_SPEED_10  0
-+#define USXGMII_LPA_SPEED_100 1
-+#define USXGMII_LPA_SPEED_1000        2
-+#define USXGMII_LPA_SPEED_10000       3
-+#define USXGMII_LPA_SPEED_2500        4
-+#define USXGMII_LPA_SPEED_5000        5
-+#define USXGMII_LPA_DUPLEX    BIT(12)
-+#define USXGMII_LPA_LINK      BIT(15)
-+#define USXGMII_LPA_LATCH     BIT(31)
-+
-+/* Register to control USXGMII XFI PLL digital */
-+#define XFI_PLL_DIG_GLB8      0x08
-+#define RG_XFI_PLL_EN         BIT(31)
-+
-+/* Register to control USXGMII XFI PLL analog */
-+#define XFI_PLL_ANA_GLB8      0x108
-+#define RG_XFI_PLL_ANA_SWWA   0x02283248
-+
- /* Infrasys subsystem config registers */
- #define INFRA_MISC2            0x70c
- #define CO_QPHY_SEL            BIT(0)
- #define GEPHY_MAC_SEL          BIT(1)
-+/* Toprgu subsystem config registers */
-+#define TOPRGU_SWSYSRST               0x18
-+#define SWSYSRST_UNLOCK_KEY   GENMASK(31, 24)
-+#define SWSYSRST_XFI_PLL_GRST BIT(16)
-+#define SWSYSRST_XFI_PEXPT1_GRST      BIT(15)
-+#define SWSYSRST_XFI_PEXPT0_GRST      BIT(14)
-+#define SWSYSRST_XFI1_GRST    BIT(13)
-+#define SWSYSRST_XFI0_GRST    BIT(12)
-+#define SWSYSRST_SGMII1_GRST  BIT(2)
-+#define SWSYSRST_SGMII0_GRST  BIT(1)
-+#define TOPRGU_SWSYSRST_EN            0xFC
-+
- /* Top misc registers */
-+#define TOP_MISC_NETSYS_PCS_MUX       0x84
-+#define NETSYS_PCS_MUX_MASK   GENMASK(1, 0)
-+#define       MUX_G2_USXGMII_SEL      BIT(1)
-+#define MUX_HSGMII1_G1_SEL    BIT(0)
-+
- #define USB_PHY_SWITCH_REG    0x218
- #define QPHY_SEL_MASK         GENMASK(1, 0)
- #define SGMII_QPHY_SEL                0x2
-+/* MDIO control */
-+#define MII_MMD_ACC_CTL_REG   0x0d
-+#define MII_MMD_ADDR_DATA_REG 0x0e
-+#define MMD_OP_MODE_DATA      BIT(14)
-+
- /* MT7628/88 specific stuff */
- #define MT7628_PDMA_OFFSET    0x0800
- #define MT7628_SDM_OFFSET     0x0c00
-@@ -812,13 +929,6 @@ enum mtk_gmac_id {
-       MTK_GMAC_ID_MAX
- };
--/* GDM Type */
--enum mtk_gdm_type {
--      MTK_GDM_TYPE = 0,
--      MTK_XGDM_TYPE,
--      MTK_GDM_TYPE_MAX
--};
--
- enum mtk_tx_buf_type {
-       MTK_TYPE_SKB,
-       MTK_TYPE_XDP_TX,
-@@ -905,6 +1015,7 @@ enum mkt_eth_capabilities {
-       MTK_TRGMII_BIT,
-       MTK_SGMII_BIT,
-       MTK_USXGMII_BIT,
-+      MTK_2P5GPHY_BIT,
-       MTK_ESW_BIT,
-       MTK_GEPHY_BIT,
-       MTK_MUX_BIT,
-@@ -925,6 +1036,7 @@ enum mkt_eth_capabilities {
-       MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
-       MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
-       MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
-+      MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT,
-       MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
-       MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
-       MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
-@@ -936,6 +1048,7 @@ enum mkt_eth_capabilities {
-       MTK_ETH_PATH_GMAC1_SGMII_BIT,
-       MTK_ETH_PATH_GMAC2_RGMII_BIT,
-       MTK_ETH_PATH_GMAC2_SGMII_BIT,
-+      MTK_ETH_PATH_GMAC2_2P5GPHY_BIT,
-       MTK_ETH_PATH_GMAC2_GEPHY_BIT,
-       MTK_ETH_PATH_GMAC3_SGMII_BIT,
-       MTK_ETH_PATH_GDM1_ESW_BIT,
-@@ -949,6 +1062,7 @@ enum mkt_eth_capabilities {
- #define MTK_TRGMII            BIT_ULL(MTK_TRGMII_BIT)
- #define MTK_SGMII             BIT_ULL(MTK_SGMII_BIT)
- #define MTK_USXGMII           BIT_ULL(MTK_USXGMII_BIT)
-+#define MTK_2P5GPHY           BIT_ULL(MTK_2P5GPHY_BIT)
- #define MTK_ESW                       BIT_ULL(MTK_ESW_BIT)
- #define MTK_GEPHY             BIT_ULL(MTK_GEPHY_BIT)
- #define MTK_MUX                       BIT_ULL(MTK_MUX_BIT)
-@@ -971,6 +1085,8 @@ enum mkt_eth_capabilities {
-       BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
- #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY          \
-       BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
-+#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY          \
-+      BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT)
- #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII        \
-       BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
- #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII     \
-@@ -986,6 +1102,7 @@ enum mkt_eth_capabilities {
- #define MTK_ETH_PATH_GMAC1_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
- #define MTK_ETH_PATH_GMAC2_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
- #define MTK_ETH_PATH_GMAC2_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
-+#define MTK_ETH_PATH_GMAC2_2P5GPHY    BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT)
- #define MTK_ETH_PATH_GMAC2_GEPHY      BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
- #define MTK_ETH_PATH_GMAC3_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
- #define MTK_ETH_PATH_GDM1_ESW         BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
-@@ -999,6 +1116,7 @@ enum mkt_eth_capabilities {
- #define MTK_GMAC2_RGMII               (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
- #define MTK_GMAC2_SGMII               (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
- #define MTK_GMAC2_GEPHY               (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
-+#define MTK_GMAC2_2P5GPHY     (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY)
- #define MTK_GMAC3_SGMII               (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
- #define MTK_GDM1_ESW          (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
- #define MTK_GMAC1_USXGMII     (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
-@@ -1022,6 +1140,10 @@ enum mkt_eth_capabilities {
-       (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
-       MTK_SHARED_SGMII)
-+/* 2: GMAC2 -> XGMII */
-+#define MTK_MUX_GMAC2_TO_2P5GPHY      \
-+      (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA)
-+
- /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */
- #define MTK_MUX_GMAC12_TO_GEPHY_SGMII   \
-       (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
-@@ -1080,7 +1202,8 @@ enum mkt_eth_capabilities {
-                      MTK_MUX_GMAC123_TO_GEPHY_SGMII |         \
-                      MTK_NETSYS_V3 | MTK_RSTCTRL_PPE1 |       \
-                      MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII |  \
--                     MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII)
-+                     MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII | \
-+                     MTK_GMAC2_2P5GPHY | MTK_MUX_GMAC2_TO_2P5GPHY)
- struct mtk_tx_dma_desc_info {
-       dma_addr_t      addr;
-@@ -1186,6 +1309,22 @@ struct mtk_soc_data {
- #define MTK_DMA_MONITOR_TIMEOUT               msecs_to_jiffies(1000)
-+/* struct mtk_usxgmii_pcs - This structure holds each usxgmii regmap and
-+ *                    associated data
-+ * @regmap:           The register map pointing at the range used to setup
-+ *                    USXGMII modes
-+ * @interface:                Currently selected interface mode
-+ * @id:                       The element is used to record the index of PCS
-+ * @pcs:              Phylink PCS structure
-+ */
-+struct mtk_usxgmii_pcs {
-+      struct mtk_eth          *eth;
-+      struct regmap           *regmap;
-+      phy_interface_t         interface;
-+      u8                      id;
-+      struct phylink_pcs      pcs;
-+};
-+
- /* struct mtk_eth -   This is the main datasructure for holding the state
-  *                    of the driver
-  * @dev:              The device pointer
-@@ -1206,6 +1345,11 @@ struct mtk_soc_data {
-  * @infra:              The register map pointing at the range used to setup
-  *                      SGMII and GePHY path
-  * @sgmii_pcs:                Pointers to mtk-pcs-lynxi phylink_pcs instances
-+ * @usxgmii_pll:      The register map pointing at the range used to control
-+ *                    the USXGMII SerDes PLL
-+ * @regmap_pextp:     The register map pointing at the range used to setup
-+ *                    PHYA
-+ * @usxgmii_pcs:      Pointer to array of pointers to struct for USXGMII PCS
-  * @pctl:             The register map pointing at the range used to setup
-  *                    GMAC port drive/slew values
-  * @dma_refcnt:               track how many netdevs are using the DMA engine
-@@ -1247,7 +1391,11 @@ struct mtk_eth {
-       unsigned long                   sysclk;
-       struct regmap                   *ethsys;
-       struct regmap                   *infra;
-+      struct regmap                   *toprgu;
-       struct phylink_pcs              **sgmii_pcs;
-+      struct regmap                   *usxgmii_pll;
-+      struct regmap                   **regmap_pextp;
-+      struct mtk_usxgmii_pcs          **usxgmii_pcs;
-       struct regmap                   *pctl;
-       bool                            hwlro;
-       refcount_t                      dma_refcnt;
-@@ -1403,6 +1551,19 @@ static inline u32 mtk_get_ib2_multicast_
-       return MTK_FOE_IB2_MULTICAST;
- }
-+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
-+{
-+      switch (interface) {
-+      case PHY_INTERFACE_MODE_USXGMII:
-+      case PHY_INTERFACE_MODE_10GKR:
-+      case PHY_INTERFACE_MODE_5GBASER:
-+              return true;
-+              break;
-+      default:
-+              return false;
-+      }
-+}
-+
- /* read the hardware status register */
- void mtk_stats_update_mac(struct mtk_mac *mac);
-@@ -1410,8 +1571,10 @@ void mtk_w32(struct mtk_eth *eth, u32 va
- u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
- int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
-+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id);
- int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
- int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
-+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id);
- int mtk_eth_offload_init(struct mtk_eth *eth);
- int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
-@@ -1421,5 +1584,20 @@ int mtk_flow_offload_cmd(struct mtk_eth
- void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list);
- void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
-+#ifdef CONFIG_NET_MEDIATEK_SOC_USXGMII
-+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id);
-+int mtk_usxgmii_init(struct mtk_eth *eth);
-+int mtk_xfi_pll_enable(struct mtk_eth *eth);
-+void mtk_sgmii_setup_phya_gen1(struct mtk_eth *eth, int mac_id);
-+void mtk_sgmii_setup_phya_gen2(struct mtk_eth *eth, int mac_id);
-+void mtk_sgmii_reset(struct mtk_eth *eth, int mac_id);
-+#else
-+static inline struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id) { return NULL; }
-+static inline int mtk_usxgmii_init(struct mtk_eth *eth) { return 0; }
-+static inline int mtk_xfi_pll_enable(struct mtk_eth *eth) { return 0; }
-+static inline void mtk_sgmii_setup_phya_gen1(struct mtk_eth *eth, int mac_id) { }
-+static inline void mtk_sgmii_setup_phya_gen2(struct mtk_eth *eth, int mac_id) { }
-+static inline void mtk_sgmii_reset(struct mtk_eth *eth, int mac_id) { }
-+#endif /* NET_MEDIATEK_SOC_USXGMII */
- #endif /* MTK_ETH_H */
---- /dev/null
-+++ b/drivers/net/ethernet/mediatek/mtk_usxgmii.c
-@@ -0,0 +1,835 @@
-+/* SPDX-License-Identifier: GPL-2.0
-+ *
-+ * Copyright (c) 2022 MediaTek Inc.
-+ * Author: Henry Yen <henry.yen@mediatek.com>
-+ *         Daniel Golle <daniel@makrotopia.org>
-+ */
-+
-+#include <linux/mfd/syscon.h>
-+#include <linux/of.h>
-+#include <linux/regmap.h>
-+#include "mtk_eth_soc.h"
-+
-+static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs)
-+{
-+      return container_of(pcs, struct mtk_usxgmii_pcs, pcs);
-+}
-+
-+static int mtk_xfi_pextp_init(struct mtk_eth *eth)
-+{
-+      struct device *dev = eth->dev;
-+      struct device_node *r = dev->of_node;
-+      struct device_node *np;
-+      int i;
-+
-+      eth->regmap_pextp = devm_kcalloc(dev, eth->soc->num_devs, sizeof(eth->regmap_pextp), GFP_KERNEL);
-+      if (!eth->regmap_pextp)
-+              return -ENOMEM;
-+
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-+              np = of_parse_phandle(r, "mediatek,xfi_pextp", i);
-+              if (!np)
-+                      break;
-+
-+              eth->regmap_pextp[i] = syscon_node_to_regmap(np);
-+              if (IS_ERR(eth->regmap_pextp[i]))
-+                      return PTR_ERR(eth->regmap_pextp[i]);
-+      }
-+
-+      return 0;
-+}
-+
-+static int mtk_xfi_pll_init(struct mtk_eth *eth)
-+{
-+      struct device_node *r = eth->dev->of_node;
-+      struct device_node *np;
-+
-+      np = of_parse_phandle(r, "mediatek,xfi_pll", 0);
-+      if (!np)
-+              return -1;
-+
-+      eth->usxgmii_pll = syscon_node_to_regmap(np);
-+      if (IS_ERR(eth->usxgmii_pll))
-+              return PTR_ERR(eth->usxgmii_pll);
-+
-+      return 0;
-+}
-+
-+static int mtk_toprgu_init(struct mtk_eth *eth)
-+{
-+      struct device_node *r = eth->dev->of_node;
-+      struct device_node *np;
-+
-+      np = of_parse_phandle(r, "mediatek,toprgu", 0);
-+      if (!np)
-+              return -1;
-+
-+      eth->toprgu = syscon_node_to_regmap(np);
-+      if (IS_ERR(eth->toprgu))
-+              return PTR_ERR(eth->toprgu);
-+
-+      return 0;
-+}
-+
-+int mtk_xfi_pll_enable(struct mtk_eth *eth)
-+{
-+      u32 val = 0;
-+
-+      if (!eth->usxgmii_pll)
-+              return -EINVAL;
-+
-+      /* Add software workaround for USXGMII PLL TCL issue */
-+      regmap_write(eth->usxgmii_pll, XFI_PLL_ANA_GLB8, RG_XFI_PLL_ANA_SWWA);
-+
-+      regmap_read(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, &val);
-+      val |= RG_XFI_PLL_EN;
-+      regmap_write(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, val);
-+
-+      return 0;
-+}
-+
-+static int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id)
-+{
-+      int xgmii_id = mac_id;
-+
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+              switch (mac_id) {
-+              case MTK_GMAC1_ID:
-+              case MTK_GMAC2_ID:
-+                      xgmii_id = 1;
-+                      break;
-+              case MTK_GMAC3_ID:
-+                      xgmii_id = 0;
-+                      break;
-+              default:
-+                      xgmii_id = -1;
-+              }
-+      }
-+
-+      return xgmii_id;
-+}
-+
-+static int mtk_xgmii2mac_id(struct mtk_eth *eth, int xgmii_id)
-+{
-+      int mac_id = xgmii_id;
-+
-+      if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
-+              switch (xgmii_id) {
-+              case 0:
-+                      mac_id = 2;
-+                      break;
-+              case 1:
-+                      mac_id = 1;
-+                      break;
-+              default:
-+                      mac_id = -1;
-+              }
-+      }
-+
-+      return mac_id;
-+}
-+
-+
-+static void mtk_usxgmii_setup_phya_usxgmii(struct mtk_usxgmii_pcs *mpcs)
-+{
-+      struct regmap *pextp;
-+
-+      if (!mpcs->eth)
-+              return;
-+
-+      pextp = mpcs->eth->regmap_pextp[mpcs->id];
-+      if (!pextp)
-+              return;
-+
-+      /* Setup operation mode */
-+      regmap_write(pextp, 0x9024, 0x00C9071C);
-+      regmap_write(pextp, 0x2020, 0xAA8585AA);
-+      regmap_write(pextp, 0x2030, 0x0C020707);
-+      regmap_write(pextp, 0x2034, 0x0E050F0F);
-+      regmap_write(pextp, 0x2040, 0x00140032);
-+      regmap_write(pextp, 0x50F0, 0x00C014AA);
-+      regmap_write(pextp, 0x50E0, 0x3777C12B);
-+      regmap_write(pextp, 0x506C, 0x005F9CFF);
-+      regmap_write(pextp, 0x5070, 0x9D9DFAFA);
-+      regmap_write(pextp, 0x5074, 0x27273F3F);
-+      regmap_write(pextp, 0x5078, 0xA7883C68);
-+      regmap_write(pextp, 0x507C, 0x11661166);
-+      regmap_write(pextp, 0x5080, 0x0E000AAF);
-+      regmap_write(pextp, 0x5084, 0x08080D0D);
-+      regmap_write(pextp, 0x5088, 0x02030909);
-+      regmap_write(pextp, 0x50E4, 0x0C0C0000);
-+      regmap_write(pextp, 0x50E8, 0x04040000);
-+      regmap_write(pextp, 0x50EC, 0x0F0F0C06);
-+      regmap_write(pextp, 0x50A8, 0x506E8C8C);
-+      regmap_write(pextp, 0x6004, 0x18190000);
-+      regmap_write(pextp, 0x00F8, 0x01423342);
-+      /* Force SGDT_OUT off and select PCS */
-+      regmap_write(pextp, 0x00F4, 0x80201F20);
-+      /* Force GLB_CKDET_OUT */
-+      regmap_write(pextp, 0x0030, 0x00050C00);
-+      /* Force AEQ on */
-+      regmap_write(pextp, 0x0070, 0x02002800);
-+      ndelay(1020);
-+      /* Setup DA default value */
-+      regmap_write(pextp, 0x30B0, 0x00000020);
-+      regmap_write(pextp, 0x3028, 0x00008A01);
-+      regmap_write(pextp, 0x302C, 0x0000A884);
-+      regmap_write(pextp, 0x3024, 0x00083002);
-+      regmap_write(pextp, 0x3010, 0x00022220);
-+      regmap_write(pextp, 0x5064, 0x0F020A01);
-+      regmap_write(pextp, 0x50B4, 0x06100600);
-+      regmap_write(pextp, 0x3048, 0x40704000);
-+      regmap_write(pextp, 0x3050, 0xA8000000);
-+      regmap_write(pextp, 0x3054, 0x000000AA);
-+      regmap_write(pextp, 0x306C, 0x00000F00);
-+      regmap_write(pextp, 0xA060, 0x00040000);
-+      regmap_write(pextp, 0x90D0, 0x00000001);
-+      /* Release reset */
-+      regmap_write(pextp, 0x0070, 0x0200E800);
-+      udelay(150);
-+      /* Switch to P0 */
-+      regmap_write(pextp, 0x0070, 0x0200C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0200C101);
-+      udelay(15);
-+      /* Switch to Gen3 */
-+      regmap_write(pextp, 0x0070, 0x0202C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0202C101);
-+      udelay(100);
-+      regmap_write(pextp, 0x30B0, 0x00000030);
-+      regmap_write(pextp, 0x00F4, 0x80201F00);
-+      regmap_write(pextp, 0x3040, 0x30000000);
-+      udelay(400);
-+}
-+
-+static void mtk_usxgmii_setup_phya_5gbaser(struct mtk_usxgmii_pcs *mpcs)
-+{
-+      struct regmap *pextp;
-+
-+      if (!mpcs->eth)
-+              return;
-+
-+      pextp = mpcs->eth->regmap_pextp[mpcs->id];
-+      if (!pextp)
-+              return;
-+
-+      /* Setup operation mode */
-+      regmap_write(pextp, 0x9024, 0x00D9071C);
-+      regmap_write(pextp, 0x2020, 0xAAA5A5AA);
-+      regmap_write(pextp, 0x2030, 0x0C020707);
-+      regmap_write(pextp, 0x2034, 0x0E050F0F);
-+      regmap_write(pextp, 0x2040, 0x00140032);
-+      regmap_write(pextp, 0x50F0, 0x00C018AA);
-+      regmap_write(pextp, 0x50E0, 0x3777812B);
-+      regmap_write(pextp, 0x506C, 0x005C9CFF);
-+      regmap_write(pextp, 0x5070, 0x9DFAFAFA);
-+      regmap_write(pextp, 0x5074, 0x273F3F3F);
-+      regmap_write(pextp, 0x5078, 0xA8883868);
-+      regmap_write(pextp, 0x507C, 0x14661466);
-+      regmap_write(pextp, 0x5080, 0x0E001ABF);
-+      regmap_write(pextp, 0x5084, 0x080B0D0D);
-+      regmap_write(pextp, 0x5088, 0x02050909);
-+      regmap_write(pextp, 0x50E4, 0x0C000000);
-+      regmap_write(pextp, 0x50E8, 0x04000000);
-+      regmap_write(pextp, 0x50EC, 0x0F0F0C06);
-+      regmap_write(pextp, 0x50A8, 0x50808C8C);
-+      regmap_write(pextp, 0x6004, 0x18000000);
-+      regmap_write(pextp, 0x00F8, 0x00A132A1);
-+      /* Force SGDT_OUT off and select PCS */
-+      regmap_write(pextp, 0x00F4, 0x80201F20);
-+      /* Force GLB_CKDET_OUT */
-+      regmap_write(pextp, 0x0030, 0x00050C00);
-+      /* Force AEQ on */
-+      regmap_write(pextp, 0x0070, 0x02002800);
-+      ndelay(1020);
-+      /* Setup DA default value */
-+      regmap_write(pextp, 0x30B0, 0x00000020);
-+      regmap_write(pextp, 0x3028, 0x00008A01);
-+      regmap_write(pextp, 0x302C, 0x0000A884);
-+      regmap_write(pextp, 0x3024, 0x00083002);
-+      regmap_write(pextp, 0x3010, 0x00022220);
-+      regmap_write(pextp, 0x5064, 0x0F020A01);
-+      regmap_write(pextp, 0x50B4, 0x06100600);
-+      regmap_write(pextp, 0x3048, 0x40704000);
-+      regmap_write(pextp, 0x3050, 0xA8000000);
-+      regmap_write(pextp, 0x3054, 0x000000AA);
-+      regmap_write(pextp, 0x306C, 0x00000F00);
-+      regmap_write(pextp, 0xA060, 0x00040000);
-+      regmap_write(pextp, 0x90D0, 0x00000003);
-+      /* Release reset */
-+      regmap_write(pextp, 0x0070, 0x0200E800);
-+      udelay(150);
-+      /* Switch to P0 */
-+      regmap_write(pextp, 0x0070, 0x0200C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0200C101);
-+      udelay(15);
-+      /* Switch to Gen3 */
-+      regmap_write(pextp, 0x0070, 0x0202C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0202C101);
-+      udelay(100);
-+      regmap_write(pextp, 0x30B0, 0x00000030);
-+      regmap_write(pextp, 0x00F4, 0x80201F00);
-+      regmap_write(pextp, 0x3040, 0x30000000);
-+      udelay(400);
-+}
-+
-+static void mtk_usxgmii_setup_phya_10gbaser(struct mtk_usxgmii_pcs *mpcs)
-+{
-+      struct regmap *pextp;
-+
-+      if (!mpcs->eth)
-+              return;
-+
-+      pextp = mpcs->eth->regmap_pextp[mpcs->id];
-+      if (!pextp)
-+              return;
-+
-+      /* Setup operation mode */
-+      regmap_write(pextp, 0x9024, 0x00C9071C);
-+      regmap_write(pextp, 0x2020, 0xAA8585AA);
-+      regmap_write(pextp, 0x2030, 0x0C020707);
-+      regmap_write(pextp, 0x2034, 0x0E050F0F);
-+      regmap_write(pextp, 0x2040, 0x00140032);
-+      regmap_write(pextp, 0x50F0, 0x00C014AA);
-+      regmap_write(pextp, 0x50E0, 0x3777C12B);
-+      regmap_write(pextp, 0x506C, 0x005F9CFF);
-+      regmap_write(pextp, 0x5070, 0x9D9DFAFA);
-+      regmap_write(pextp, 0x5074, 0x27273F3F);
-+      regmap_write(pextp, 0x5078, 0xA7883C68);
-+      regmap_write(pextp, 0x507C, 0x11661166);
-+      regmap_write(pextp, 0x5080, 0x0E000AAF);
-+      regmap_write(pextp, 0x5084, 0x08080D0D);
-+      regmap_write(pextp, 0x5088, 0x02030909);
-+      regmap_write(pextp, 0x50E4, 0x0C0C0000);
-+      regmap_write(pextp, 0x50E8, 0x04040000);
-+      regmap_write(pextp, 0x50EC, 0x0F0F0C06);
-+      regmap_write(pextp, 0x50A8, 0x506E8C8C);
-+      regmap_write(pextp, 0x6004, 0x18190000);
-+      regmap_write(pextp, 0x00F8, 0x01423342);
-+      /* Force SGDT_OUT off and select PCS */
-+      regmap_write(pextp, 0x00F4, 0x80201F20);
-+      /* Force GLB_CKDET_OUT */
-+      regmap_write(pextp, 0x0030, 0x00050C00);
-+      /* Force AEQ on */
-+      regmap_write(pextp, 0x0070, 0x02002800);
-+      ndelay(1020);
-+      /* Setup DA default value */
-+      regmap_write(pextp, 0x30B0, 0x00000020);
-+      regmap_write(pextp, 0x3028, 0x00008A01);
-+      regmap_write(pextp, 0x302C, 0x0000A884);
-+      regmap_write(pextp, 0x3024, 0x00083002);
-+      regmap_write(pextp, 0x3010, 0x00022220);
-+      regmap_write(pextp, 0x5064, 0x0F020A01);
-+      regmap_write(pextp, 0x50B4, 0x06100600);
-+      regmap_write(pextp, 0x3048, 0x47684100);
-+      regmap_write(pextp, 0x3050, 0x00000000);
-+      regmap_write(pextp, 0x3054, 0x00000000);
-+      regmap_write(pextp, 0x306C, 0x00000F00);
-+      if (mpcs->id == 0)
-+              regmap_write(pextp, 0xA008, 0x0007B400);
-+
-+      regmap_write(pextp, 0xA060, 0x00040000);
-+      regmap_write(pextp, 0x90D0, 0x00000001);
-+      /* Release reset */
-+      regmap_write(pextp, 0x0070, 0x0200E800);
-+      udelay(150);
-+      /* Switch to P0 */
-+      regmap_write(pextp, 0x0070, 0x0200C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0200C101);
-+      udelay(15);
-+      /* Switch to Gen3 */
-+      regmap_write(pextp, 0x0070, 0x0202C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0202C101);
-+      udelay(100);
-+      regmap_write(pextp, 0x30B0, 0x00000030);
-+      regmap_write(pextp, 0x00F4, 0x80201F00);
-+      regmap_write(pextp, 0x3040, 0x30000000);
-+      udelay(400);
-+}
-+
-+void mtk_sgmii_setup_phya_gen1(struct mtk_eth *eth, int mac_id)
-+{
-+      u32 id = mtk_mac2xgmii_id(eth, mac_id);
-+      struct regmap *pextp;
-+
-+      if (id >= eth->soc->num_devs)
-+              return;
-+
-+      pextp = eth->regmap_pextp[id];
-+      if (!pextp)
-+              return;
-+
-+      /* Setup operation mode */
-+      regmap_write(pextp, 0x9024, 0x00D9071C);
-+      regmap_write(pextp, 0x2020, 0xAA8585AA);
-+      regmap_write(pextp, 0x2030, 0x0C020207);
-+      regmap_write(pextp, 0x2034, 0x0E05050F);
-+      regmap_write(pextp, 0x2040, 0x00200032);
-+      regmap_write(pextp, 0x50F0, 0x00C014BA);
-+      regmap_write(pextp, 0x50E0, 0x3777C12B);
-+      regmap_write(pextp, 0x506C, 0x005F9CFF);
-+      regmap_write(pextp, 0x5070, 0x9D9DFAFA);
-+      regmap_write(pextp, 0x5074, 0x27273F3F);
-+      regmap_write(pextp, 0x5078, 0xA7883C68);
-+      regmap_write(pextp, 0x507C, 0x11661166);
-+      regmap_write(pextp, 0x5080, 0x0E000EAF);
-+      regmap_write(pextp, 0x5084, 0x08080E0D);
-+      regmap_write(pextp, 0x5088, 0x02030B09);
-+      regmap_write(pextp, 0x50E4, 0x0C0C0000);
-+      regmap_write(pextp, 0x50E8, 0x04040000);
-+      regmap_write(pextp, 0x50EC, 0x0F0F0606);
-+      regmap_write(pextp, 0x50A8, 0x506E8C8C);
-+      regmap_write(pextp, 0x6004, 0x18190000);
-+      regmap_write(pextp, 0x00F8, 0x00FA32FA);
-+      /* Force SGDT_OUT off and select PCS */
-+      regmap_write(pextp, 0x00F4, 0x80201F21);
-+      /* Force GLB_CKDET_OUT */
-+      regmap_write(pextp, 0x0030, 0x00050C00);
-+      /* Force AEQ on */
-+      regmap_write(pextp, 0x0070, 0x02002800);
-+      ndelay(1020);
-+      /* Setup DA default value */
-+      regmap_write(pextp, 0x30B0, 0x00000020);
-+      regmap_write(pextp, 0x3028, 0x00008A01);
-+      regmap_write(pextp, 0x302C, 0x0000A884);
-+      regmap_write(pextp, 0x3024, 0x00083002);
-+      regmap_write(pextp, 0x3010, 0x00011110);
-+      regmap_write(pextp, 0x3048, 0x40704000);
-+      regmap_write(pextp, 0x3064, 0x0000C000);
-+      regmap_write(pextp, 0x3050, 0xA8000000);
-+      regmap_write(pextp, 0x3054, 0x000000AA);
-+      regmap_write(pextp, 0x306C, 0x20200F00);
-+      regmap_write(pextp, 0xA060, 0x00050000);
-+      regmap_write(pextp, 0x90D0, 0x00000007);
-+      /* Release reset */
-+      regmap_write(pextp, 0x0070, 0x0200E800);
-+      udelay(150);
-+      /* Switch to P0 */
-+      regmap_write(pextp, 0x0070, 0x0200C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0200C101);
-+      udelay(15);
-+      /* Switch to Gen2 */
-+      regmap_write(pextp, 0x0070, 0x0201C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0201C101);
-+      udelay(100);
-+      regmap_write(pextp, 0x30B0, 0x00000030);
-+      regmap_write(pextp, 0x00F4, 0x80201F01);
-+      regmap_write(pextp, 0x3040, 0x30000000);
-+      udelay(400);
-+}
-+
-+void mtk_sgmii_setup_phya_gen2(struct mtk_eth *eth, int mac_id)
-+{
-+      u32 id = mtk_mac2xgmii_id(eth, mac_id);
-+      struct regmap *pextp;
-+
-+      if (id >= eth->soc->num_devs)
-+              return;
-+
-+      pextp = eth->regmap_pextp[id];
-+      if (!pextp)
-+              return;
-+
-+      /* Setup operation mode */
-+      regmap_write(pextp, 0x9024, 0x00D9071C);
-+      regmap_write(pextp, 0x2020, 0xAA8585AA);
-+      regmap_write(pextp, 0x2030, 0x0C020707);
-+      regmap_write(pextp, 0x2034, 0x0E050F0F);
-+      regmap_write(pextp, 0x2040, 0x00140032);
-+      regmap_write(pextp, 0x50F0, 0x00C014AA);
-+      regmap_write(pextp, 0x50E0, 0x3777C12B);
-+      regmap_write(pextp, 0x506C, 0x005F9CFF);
-+      regmap_write(pextp, 0x5070, 0x9D9DFAFA);
-+      regmap_write(pextp, 0x5074, 0x27273F3F);
-+      regmap_write(pextp, 0x5078, 0xA7883C68);
-+      regmap_write(pextp, 0x507C, 0x11661166);
-+      regmap_write(pextp, 0x5080, 0x0E000AAF);
-+      regmap_write(pextp, 0x5084, 0x08080D0D);
-+      regmap_write(pextp, 0x5088, 0x02030909);
-+      regmap_write(pextp, 0x50E4, 0x0C0C0000);
-+      regmap_write(pextp, 0x50E8, 0x04040000);
-+      regmap_write(pextp, 0x50EC, 0x0F0F0C06);
-+      regmap_write(pextp, 0x50A8, 0x506E8C8C);
-+      regmap_write(pextp, 0x6004, 0x18190000);
-+      regmap_write(pextp, 0x00F8, 0x009C329C);
-+      /* Force SGDT_OUT off and select PCS */
-+      regmap_write(pextp, 0x00F4, 0x80201F21);
-+      /* Force GLB_CKDET_OUT */
-+      regmap_write(pextp, 0x0030, 0x00050C00);
-+      /* Force AEQ on */
-+      regmap_write(pextp, 0x0070, 0x02002800);
-+      ndelay(1020);
-+      /* Setup DA default value */
-+      regmap_write(pextp, 0x30B0, 0x00000020);
-+      regmap_write(pextp, 0x3028, 0x00008A01);
-+      regmap_write(pextp, 0x302C, 0x0000A884);
-+      regmap_write(pextp, 0x3024, 0x00083002);
-+      regmap_write(pextp, 0x3010, 0x00011110);
-+      regmap_write(pextp, 0x3048, 0x40704000);
-+      regmap_write(pextp, 0x3050, 0xA8000000);
-+      regmap_write(pextp, 0x3054, 0x000000AA);
-+      regmap_write(pextp, 0x306C, 0x22000F00);
-+      regmap_write(pextp, 0xA060, 0x00050000);
-+      regmap_write(pextp, 0x90D0, 0x00000005);
-+      /* Release reset */
-+      regmap_write(pextp, 0x0070, 0x0200E800);
-+      udelay(150);
-+      /* Switch to P0 */
-+      regmap_write(pextp, 0x0070, 0x0200C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0200C101);
-+      udelay(15);
-+      /* Switch to Gen2 */
-+      regmap_write(pextp, 0x0070, 0x0201C111);
-+      ndelay(1020);
-+      regmap_write(pextp, 0x0070, 0x0201C101);
-+      udelay(100);
-+      regmap_write(pextp, 0x30B0, 0x00000030);
-+      regmap_write(pextp, 0x00F4, 0x80201F01);
-+      regmap_write(pextp, 0x3040, 0x30000000);
-+      udelay(400);
-+}
-+
-+static void mtk_usxgmii_reset(struct mtk_eth *eth, int id)
-+{
-+      u32 val = 0;
-+
-+      if (id >= eth->soc->num_devs || !eth->toprgu)
-+              return;
-+
-+      switch (id) {
-+      case 0:
-+              /* Enable software reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
-+              val |= SWSYSRST_XFI_PEXPT0_GRST |
-+                     SWSYSRST_XFI0_GRST;
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
-+
-+              /* Assert USXGMII reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
-+              val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) |
-+                     SWSYSRST_XFI_PEXPT0_GRST |
-+                     SWSYSRST_XFI0_GRST;
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
-+
-+              udelay(100);
-+
-+              /* De-assert USXGMII reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
-+              val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
-+              val &= ~(SWSYSRST_XFI_PEXPT0_GRST |
-+                       SWSYSRST_XFI0_GRST);
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
-+
-+              /* Disable software reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
-+              val &= ~(SWSYSRST_XFI_PEXPT0_GRST |
-+                       SWSYSRST_XFI0_GRST);
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
-+              break;
-+      case 1:
-+              /* Enable software reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
-+              val |= SWSYSRST_XFI_PEXPT1_GRST |
-+                     SWSYSRST_XFI1_GRST;
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
-+
-+              /* Assert USXGMII reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
-+              val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) |
-+                     SWSYSRST_XFI_PEXPT1_GRST |
-+                     SWSYSRST_XFI1_GRST;
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
-+
-+              udelay(100);
-+
-+              /* De-assert USXGMII reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
-+              val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
-+              val &= ~(SWSYSRST_XFI_PEXPT1_GRST |
-+                       SWSYSRST_XFI1_GRST);
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
-+
-+              /* Disable software reset */
-+              regmap_read(eth->toprgu, TOPRGU_SWSYSRST_EN, &val);
-+              val &= ~(SWSYSRST_XFI_PEXPT1_GRST |
-+                       SWSYSRST_XFI1_GRST);
-+              regmap_write(eth->toprgu, TOPRGU_SWSYSRST_EN, val);
-+              break;
-+      }
-+
-+      mdelay(10);
-+}
-+
-+void mtk_sgmii_reset(struct mtk_eth *eth, int mac_id)
-+{
-+      u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id);
-+
-+      mtk_usxgmii_reset(eth, xgmii_id);
-+}
-+
-+
-+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-+                                phy_interface_t interface,
-+                                const unsigned long *advertising,
-+                                bool permit_pause_to_mac)
-+{
-+      struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
-+      struct mtk_eth *eth = mpcs->eth;
-+      unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0;
-+      bool mode_changed = false;
-+
-+      if (interface == PHY_INTERFACE_MODE_USXGMII) {
-+              an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) |
-+                        USXGMII_AN_ENABLE;
-+              link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
-+                           FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
-+                           FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
-+              xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) |
-+                         FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G);
-+      } else if (interface == PHY_INTERFACE_MODE_10GKR) {
-+              an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF);
-+              link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
-+                           FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
-+                           FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
-+              xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) |
-+                         FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G);
-+              adapt_mode = USXGMII_RATE_UPDATE_MODE;
-+      } else if (interface == PHY_INTERFACE_MODE_5GBASER) {
-+              an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF);
-+              link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) |
-+                           FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) |
-+                           FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D);
-+              xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_5G) |
-+                         FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_5G);
-+              adapt_mode = USXGMII_RATE_UPDATE_MODE;
-+      } else
-+              return -EINVAL;
-+
-+      adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1);
-+
-+      if (mpcs->interface != interface) {
-+              mpcs->interface = interface;
-+              mode_changed = true;
-+      }
-+
-+      mtk_xfi_pll_enable(eth);
-+      mtk_usxgmii_reset(eth, mpcs->id);
-+
-+      /* Setup USXGMII AN ctrl */
-+      regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL0,
-+                         USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
-+                         an_ctrl);
-+
-+      regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL2,
-+                         USXGMII_LINK_TIMER_IDLE_DETECT |
-+                         USXGMII_LINK_TIMER_COMP_ACK_DETECT |
-+                         USXGMII_LINK_TIMER_AN_RESTART,
-+                         link_timer);
-+
-+      /* Gated MAC CK */
-+      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+                         USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED);
-+
-+      /* Enable interface force mode */
-+      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+                         USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN);
-+
-+      /* Setup USXGMII adapt mode */
-+      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+                         USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE,
-+                         adapt_mode);
-+
-+      /* Setup USXGMII speed */
-+      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+                         USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE,
-+                         xfi_mode);
-+
-+      udelay(1);
-+
-+      /* Un-gated MAC CK */
-+      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+                         USXGMII_MAC_CK_GATED, 0);
-+
-+      udelay(1);
-+
-+      /* Disable interface force mode for the AN mode */
-+      if (an_ctrl & USXGMII_AN_ENABLE)
-+              regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
-+                                 USXGMII_IF_FORCE_EN, 0);
-+
-+      /* Setup USXGMIISYS with the determined property */
-+      if (interface == PHY_INTERFACE_MODE_USXGMII)
-+              mtk_usxgmii_setup_phya_usxgmii(mpcs);
-+      else if (interface == PHY_INTERFACE_MODE_10GKR)
-+              mtk_usxgmii_setup_phya_10gbaser(mpcs);
-+      else if (interface == PHY_INTERFACE_MODE_5GBASER)
-+              mtk_usxgmii_setup_phya_5gbaser(mpcs);
-+
-+      return mode_changed;
-+}
-+
-+static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs,
-+                                  struct phylink_link_state *state)
-+{
-+      struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
-+      struct mtk_eth *eth = mpcs->eth;
-+      struct mtk_mac *mac = eth->mac[mtk_xgmii2mac_id(eth, mpcs->id)];
-+      u32 val = 0;
-+
-+      regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
-+      if (FIELD_GET(USXGMII_AN_ENABLE, val)) {
-+              /* Refresh LPA by inverting LPA_LATCH */
-+              regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val);
-+              regmap_update_bits(mpcs->regmap, RG_PCS_AN_STS0,
-+                                 USXGMII_LPA_LATCH,
-+                                 !(val & USXGMII_LPA_LATCH));
-+
-+              regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val);
-+
-+              state->interface = mpcs->interface;
-+              state->link = FIELD_GET(USXGMII_LPA_LINK, val);
-+              state->duplex = FIELD_GET(USXGMII_LPA_DUPLEX, val);
-+
-+              switch (FIELD_GET(USXGMII_LPA_SPEED_MASK, val)) {
-+              case USXGMII_LPA_SPEED_10:
-+                      state->speed = SPEED_10;
-+                      break;
-+              case USXGMII_LPA_SPEED_100:
-+                      state->speed = SPEED_100;
-+                      break;
-+              case USXGMII_LPA_SPEED_1000:
-+                      state->speed = SPEED_1000;
-+                      break;
-+              case USXGMII_LPA_SPEED_2500:
-+                      state->speed = SPEED_2500;
-+                      break;
-+              case USXGMII_LPA_SPEED_5000:
-+                      state->speed = SPEED_5000;
-+                      break;
-+              case USXGMII_LPA_SPEED_10000:
-+                      state->speed = SPEED_10000;
-+                      break;
-+              }
-+      } else {
-+              val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
-+
-+              if (mac->id == MTK_GMAC2_ID)
-+                      val = val >> 16;
-+
-+              switch (FIELD_GET(MTK_USXGMII_PCS_MODE, val)) {
-+              case 0:
-+                      state->speed = SPEED_10000;
-+                      break;
-+              case 1:
-+                      state->speed = SPEED_5000;
-+                      break;
-+              case 2:
-+                      state->speed = SPEED_2500;
-+                      break;
-+              case 3:
-+                      state->speed = SPEED_1000;
-+                      break;
-+              }
-+
-+              state->interface = mpcs->interface;
-+              state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, val);
-+              state->duplex = DUPLEX_FULL;
-+      }
-+
-+      if (state->link == 0)
-+              mtk_usxgmii_pcs_config(pcs, MLO_AN_INBAND,
-+                                     state->interface, NULL, false);
-+}
-+
-+static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs)
-+{
-+      struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
-+      unsigned int val = 0;
-+
-+      if (!mpcs->regmap)
-+              return;
-+
-+      regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
-+      val |= USXGMII_AN_RESTART;
-+      regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val);
-+}
-+
-+static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
-+                                  phy_interface_t interface,
-+                                  int speed, int duplex)
-+{
-+      /* Reconfiguring USXGMII to ensure the quality of the RX signal
-+       * after the line side link up.
-+       */
-+      mtk_usxgmii_pcs_config(pcs, mode,
-+                             interface, NULL, false);
-+}
-+
-+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = {
-+      .pcs_config = mtk_usxgmii_pcs_config,
-+      .pcs_get_state = mtk_usxgmii_pcs_get_state,
-+      .pcs_an_restart = mtk_usxgmii_pcs_restart_an,
-+      .pcs_link_up = mtk_usxgmii_pcs_link_up,
-+};
-+
-+int mtk_usxgmii_init(struct mtk_eth *eth)
-+{
-+      struct device_node *r = eth->dev->of_node;
-+      struct device *dev = eth->dev;
-+      struct device_node *np;
-+      int i, ret;
-+
-+      eth->usxgmii_pcs = devm_kcalloc(dev, eth->soc->num_devs, sizeof(eth->usxgmii_pcs), GFP_KERNEL);
-+      if (!eth->usxgmii_pcs)
-+              return -ENOMEM;
-+
-+      for (i = 0; i < eth->soc->num_devs; i++) {
-+              np = of_parse_phandle(r, "mediatek,usxgmiisys", i);
-+              if (!np)
-+                      break;
-+
-+              eth->usxgmii_pcs[i] = devm_kzalloc(dev, sizeof(*eth->usxgmii_pcs), GFP_KERNEL);
-+              if (!eth->usxgmii_pcs[i])
-+                      return -ENOMEM;
-+
-+              eth->usxgmii_pcs[i]->id = i;
-+              eth->usxgmii_pcs[i]->eth = eth;
-+              eth->usxgmii_pcs[i]->regmap = syscon_node_to_regmap(np);
-+              if (IS_ERR(eth->usxgmii_pcs[i]->regmap))
-+                      return PTR_ERR(eth->usxgmii_pcs[i]->regmap);
-+
-+              eth->usxgmii_pcs[i]->pcs.ops = &mtk_usxgmii_pcs_ops;
-+              eth->usxgmii_pcs[i]->pcs.poll = true;
-+              eth->usxgmii_pcs[i]->interface = PHY_INTERFACE_MODE_NA;
-+
-+              of_node_put(np);
-+      }
-+
-+      ret = mtk_xfi_pextp_init(eth);
-+      if (ret)
-+              return ret;
-+
-+      ret = mtk_xfi_pll_init(eth);
-+      if (ret)
-+              return ret;
-+
-+      return mtk_toprgu_init(eth);
-+}
-+
-+struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int mac_id)
-+{
-+      u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id);
-+
-+      if (!eth->usxgmii_pcs[xgmii_id]->regmap)
-+              return NULL;
-+
-+      return &eth->usxgmii_pcs[xgmii_id]->pcs;
-+}
diff --git a/target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch b/target/linux/generic/pending-6.1/737-net-ethernet-mtk_eth_soc-add-paths-and-SerDes-modes-.patch
new file mode 100644 (file)
index 0000000..4a9b088
--- /dev/null
@@ -0,0 +1,1604 @@
+From 1e25ca1147579bda8b941be1b9851f5911d44eb0 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Tue, 22 Aug 2023 19:04:42 +0100
+Subject: [PATCH 098/125] net: ethernet: mtk_eth_soc: add paths and SerDes
+ modes for MT7988
+
+MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to
+connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R,
+2500Base-X, 1000Base-X and Cisco SGMII interface modes.
+
+Implement support for configuring for the new paths to SerDes interfaces
+and the internal 2.5G PHY.
+
+Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and
+setup the new PHYA on MT7988 to access the also still existing old
+LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface
+modes.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+---
+ drivers/net/ethernet/mediatek/Kconfig        |  16 +
+ drivers/net/ethernet/mediatek/Makefile       |   1 +
+ drivers/net/ethernet/mediatek/mtk_eth_path.c | 123 +++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c  | 182 ++++-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 232 ++++++-
+ drivers/net/ethernet/mediatek/mtk_usxgmii.c  | 692 +++++++++++++++++++
+ 6 files changed, 1215 insertions(+), 31 deletions(-)
+ create mode 100644 drivers/net/ethernet/mediatek/mtk_usxgmii.c
+
+--- a/drivers/net/ethernet/mediatek/Kconfig
++++ b/drivers/net/ethernet/mediatek/Kconfig
+@@ -25,6 +25,22 @@ config NET_MEDIATEK_SOC
+         This driver supports the gigabit ethernet MACs in the
+         MediaTek SoC family.
++config NET_MEDIATEK_SOC_USXGMII
++      bool "Support USXGMII SerDes on MT7988"
++      depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
++      def_bool NET_MEDIATEK_SOC != n
++      help
++        Include support for 10GE SerDes which can be found on MT7988.
++        If this kernel should run on SoCs with 10 GBit/s Ethernet you
++        will need to select this option to use GMAC2 and GMAC3 with
++        external PHYs, SFP(+) cages in 10GBase-R, 5GBase-R or USXGMII
++        interface modes.
++
++        Note that as the 2500Base-X/1000Base-X/Cisco SGMII SerDes PCS
++        unit (MediaTek LynxI) in MT7988 is connected via the new 10GE
++        SerDes, you will also need to select this option in case you
++        want to use any of those SerDes modes.
++
+ config NET_MEDIATEK_STAR_EMAC
+       tristate "MediaTek STAR Ethernet MAC support"
+       select PHYLIB
+--- a/drivers/net/ethernet/mediatek/Makefile
++++ b/drivers/net/ethernet/mediatek/Makefile
+@@ -5,6 +5,7 @@
+ obj-$(CONFIG_NET_MEDIATEK_SOC) += mtk_eth.o
+ mtk_eth-y := mtk_eth_soc.o mtk_eth_path.o mtk_ppe.o mtk_ppe_debugfs.o mtk_ppe_offload.o
++mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_USXGMII) += mtk_usxgmii.o
+ mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed.o mtk_wed_mcu.o mtk_wed_wo.o
+ ifdef CONFIG_DEBUG_FS
+ mtk_eth-$(CONFIG_NET_MEDIATEK_SOC_WED) += mtk_wed_debugfs.o
+--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
+@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64
+               return "gmac2_rgmii";
+       case MTK_ETH_PATH_GMAC2_SGMII:
+               return "gmac2_sgmii";
++      case MTK_ETH_PATH_GMAC2_2P5GPHY:
++              return "gmac2_2p5gphy";
+       case MTK_ETH_PATH_GMAC2_GEPHY:
+               return "gmac2_gephy";
++      case MTK_ETH_PATH_GMAC3_SGMII:
++              return "gmac3_sgmii";
+       case MTK_ETH_PATH_GDM1_ESW:
+               return "gdm1_esw";
++      case MTK_ETH_PATH_GMAC1_USXGMII:
++              return "gmac1_usxgmii";
++      case MTK_ETH_PATH_GMAC2_USXGMII:
++              return "gmac2_usxgmii";
++      case MTK_ETH_PATH_GMAC3_USXGMII:
++              return "gmac3_usxgmii";
+       default:
+               return "unknown path";
+       }
+@@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(stru
+       return 0;
+ }
++static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path)
++{
++      int ret;
++
++      if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) {
++              ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2);
++              if (ret)
++                      return ret;
++
++              /* Setup mux to 2p5g PHY */
++              ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL);
++              if (ret)
++                      return ret;
++
++              dev_dbg(eth->dev, "path %s in %s updated\n",
++                      mtk_eth_path_name(path), __func__);
++      }
++
++      return 0;
++}
++
+ static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0;
+@@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_
+       return 0;
+ }
+-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
++static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path)
++{
++      unsigned int val = 0;
++      bool updated = true;
++      int mac_id = 0;
++
++      /* Disable SYSCFG1 SGMII */
++      regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
++
++      switch (path) {
++      case MTK_ETH_PATH_GMAC1_USXGMII:
++              val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2;
++              mac_id = MTK_GMAC1_ID;
++              break;
++      case MTK_ETH_PATH_GMAC2_USXGMII:
++              val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
++              mac_id = MTK_GMAC2_ID;
++              break;
++      case MTK_ETH_PATH_GMAC3_USXGMII:
++              val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2;
++              mac_id = MTK_GMAC3_ID;
++              break;
++      default:
++              updated = false;
++      };
++
++      if (updated) {
++              regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
++                                 SYSCFG0_SGMII_MASK, val);
++
++              if (mac_id == MTK_GMAC2_ID)
++                      regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX,
++                                      MUX_G2_USXGMII_SEL);
++      }
++
++      dev_dbg(eth->dev, "path %s in %s updated = %d\n",
++              mtk_eth_path_name(path), __func__, updated);
++
++      return 0;
++}
++
++static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
+ {
+       unsigned int val = 0;
+       bool updated = true;
+@@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii
+       case MTK_ETH_PATH_GMAC2_SGMII:
+               val |= SYSCFG0_SGMII_GMAC2_V2;
+               break;
++      case MTK_ETH_PATH_GMAC3_SGMII:
++              val |= SYSCFG0_SGMII_GMAC3_V2;
++              break;
+       default:
+               updated = false;
+       }
+@@ -210,13 +285,25 @@ static const struct mtk_eth_muxc mtk_eth
+               .cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
+               .set_path = set_mux_u3_gmac2_to_qphy,
+       }, {
++              .name = "mux_gmac2_to_2p5gphy",
++              .cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY,
++              .set_path = set_mux_gmac2_to_2p5gphy,
++      }, {
+               .name = "mux_gmac1_gmac2_to_sgmii_rgmii",
+               .cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
+               .set_path = set_mux_gmac1_gmac2_to_sgmii_rgmii,
+       }, {
+               .name = "mux_gmac12_to_gephy_sgmii",
+               .cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
+-              .set_path = set_mux_gmac12_to_gephy_sgmii,
++              .set_path = set_mux_gmac123_to_gephy_sgmii,
++      }, {
++              .name = "mux_gmac123_to_gephy_sgmii",
++              .cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII,
++              .set_path = set_mux_gmac123_to_gephy_sgmii,
++      }, {
++              .name = "mux_gmac123_to_usxgmii",
++              .cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII,
++              .set_path = set_mux_gmac123_to_usxgmii,
+       },
+ };
+@@ -249,12 +336,39 @@ out:
+       return err;
+ }
++int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id)
++{
++      u64 path;
++
++      path = (mac_id == MTK_GMAC1_ID) ?  MTK_ETH_PATH_GMAC1_USXGMII :
++             (mac_id == MTK_GMAC2_ID) ?  MTK_ETH_PATH_GMAC2_USXGMII :
++                                         MTK_ETH_PATH_GMAC3_USXGMII;
++
++      /* Setup proper MUXes along the path */
++      return mtk_eth_mux_setup(eth, path);
++}
++
+ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
+ {
+       u64 path;
+-      path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
+-                              MTK_ETH_PATH_GMAC2_SGMII;
++      path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII :
++             (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII :
++                                        MTK_ETH_PATH_GMAC3_SGMII;
++
++      /* Setup proper MUXes along the path */
++      return mtk_eth_mux_setup(eth, path);
++}
++
++int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id)
++{
++      u64 path = 0;
++
++      if (mac_id == MTK_GMAC2_ID)
++              path = MTK_ETH_PATH_GMAC2_2P5GPHY;
++
++      if (!path)
++              return -EINVAL;
+       /* Setup proper MUXes along the path */
+       return mtk_eth_mux_setup(eth, path);
+@@ -284,4 +398,3 @@ int mtk_gmac_rgmii_path_setup(struct mtk
+       /* Setup proper MUXes along the path */
+       return mtk_eth_mux_setup(eth, path);
+ }
+-
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -474,6 +474,30 @@ static void mtk_setup_bridge_switch(stru
+               MTK_GSW_CFG);
+ }
++static bool mtk_check_gmac23_idle(struct mtk_mac *mac)
++{
++      u32 mac_fsm, gdm_fsm;
++
++      mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id));
++
++      switch (mac->id) {
++      case MTK_GMAC2_ID:
++              gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM);
++              break;
++      case MTK_GMAC3_ID:
++              gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM);
++              break;
++      default:
++              return true;
++      };
++
++      if ((mac_fsm & 0xFFFF0000) == 0x01010000 &&
++          (gdm_fsm & 0xFFFF0000) == 0x00000000)
++              return true;
++
++      return false;
++}
++
+ static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
+                                             phy_interface_t interface)
+ {
+@@ -482,12 +506,20 @@ static struct phylink_pcs *mtk_mac_selec
+       struct mtk_eth *eth = mac->hw;
+       unsigned int sid;
+-      if (interface == PHY_INTERFACE_MODE_SGMII ||
+-          phy_interface_mode_is_8023z(interface)) {
+-              sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
+-                     0 : mac->id;
+-
+-              return eth->sgmii_pcs[sid];
++      if ((interface == PHY_INTERFACE_MODE_SGMII ||
++           phy_interface_mode_is_8023z(interface)) &&
++          MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
++              sid = mtk_mac2xgmii_id(eth, mac->id);
++              if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII))
++                      return mtk_sgmii_wrapper_select_pcs(eth, mac->id);
++              else
++                      return eth->sgmii_pcs[sid];
++      } else if ((interface == PHY_INTERFACE_MODE_USXGMII ||
++                  interface == PHY_INTERFACE_MODE_10GBASER ||
++                  interface == PHY_INTERFACE_MODE_5GBASER) &&
++                 MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII) &&
++                 mac->id != MTK_GMAC1_ID) {
++              return mtk_usxgmii_select_pcs(eth, mac->id);
+       }
+       return NULL;
+@@ -543,7 +575,22 @@ static void mtk_mac_config(struct phylin
+                                       goto init_err;
+                       }
+                       break;
++              case PHY_INTERFACE_MODE_USXGMII:
++              case PHY_INTERFACE_MODE_10GBASER:
++              case PHY_INTERFACE_MODE_5GBASER:
++                      if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
++                              err = mtk_gmac_usxgmii_path_setup(eth, mac->id);
++                              if (err)
++                                      goto init_err;
++                      }
++                      break;
+               case PHY_INTERFACE_MODE_INTERNAL:
++                      if (mac->id == MTK_GMAC2_ID &&
++                          MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) {
++                              err = mtk_gmac_2p5gphy_path_setup(eth, mac->id);
++                              if (err)
++                                      goto init_err;
++                      }
+                       break;
+               default:
+                       goto err_phy;
+@@ -598,8 +645,6 @@ static void mtk_mac_config(struct phylin
+               val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
+               val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
+               regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
+-
+-              mac->interface = state->interface;
+       }
+       /* SGMII */
+@@ -616,21 +661,40 @@ static void mtk_mac_config(struct phylin
+               /* Save the syscfg0 value for mac_finish */
+               mac->syscfg0 = val;
+-      } else if (phylink_autoneg_inband(mode)) {
++      } else if (state->interface != PHY_INTERFACE_MODE_USXGMII &&
++                 state->interface != PHY_INTERFACE_MODE_10GBASER &&
++                 state->interface != PHY_INTERFACE_MODE_5GBASER &&
++                 phylink_autoneg_inband(mode)) {
+               dev_err(eth->dev,
+-                      "In-band mode not supported in non SGMII mode!\n");
++                      "In-band mode not supported in non-SerDes modes!\n");
+               return;
+       }
+       /* Setup gmac */
+-      if (mtk_is_netsys_v3_or_greater(eth) &&
+-          mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
+-              mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
+-              mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
++      if (mtk_is_netsys_v3_or_greater(eth)) {
++              if (mtk_interface_mode_is_xgmii(state->interface)) {
++                      mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
++                      mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
++
++                      if (mac->id == MTK_GMAC1_ID)
++                              mtk_setup_bridge_switch(eth);
++              } else {
++                      mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id));
+-              mtk_setup_bridge_switch(eth);
++                      /* FIXME: In current hardware design, we have to reset FE
++                       * when swtiching XGDM to GDM. Therefore, here trigger an SER
++                       * to let GDM go back to the initial state.
++                       */
++                      if ((mtk_interface_mode_is_xgmii(mac->interface) ||
++                           mac->interface == PHY_INTERFACE_MODE_NA) &&
++                          !mtk_check_gmac23_idle(mac) &&
++                          !test_bit(MTK_RESETTING, &eth->state))
++                              schedule_work(&eth->pending_work);
++              }
+       }
++      mac->interface = state->interface;
++
+       return;
+ err_phy:
+@@ -676,10 +740,13 @@ static void mtk_mac_link_down(struct phy
+ {
+       struct mtk_mac *mac = container_of(config, struct mtk_mac,
+                                          phylink_config);
+-      u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+-      mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
+-      mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
++      if (!mtk_interface_mode_is_xgmii(interface)) {
++              mtk_m32(mac->hw, MAC_MCR_TX_EN | MAC_MCR_RX_EN, 0, MTK_MAC_MCR(mac->id));
++              mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id));
++      } else if (mac->id != MTK_GMAC1_ID) {
++              mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id));
++      }
+ }
+ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
+@@ -751,13 +818,11 @@ static void mtk_set_queue_speed(struct m
+       mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
+ }
+-static void mtk_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)
++static void mtk_gdm_mac_link_up(struct mtk_mac *mac,
++                              struct phy_device *phy,
++                              unsigned int mode, phy_interface_t interface,
++                              int speed, int duplex, bool tx_pause, bool rx_pause)
+ {
+-      struct mtk_mac *mac = container_of(config, struct mtk_mac,
+-                                         phylink_config);
+       u32 mcr;
+       mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+@@ -791,6 +856,55 @@ static void mtk_mac_link_up(struct phyli
+       mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
+ }
++static void mtk_xgdm_mac_link_up(struct mtk_mac *mac,
++                               struct phy_device *phy,
++                               unsigned int mode, phy_interface_t interface,
++                               int speed, int duplex, bool tx_pause, bool rx_pause)
++{
++      u32 mcr, force_link = 0;
++
++      if (mac->id == MTK_GMAC1_ID)
++              return;
++
++      /* Eliminate the interference(before link-up) caused by PHY noise */
++      mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id));
++      mdelay(20);
++      mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id));
++
++      if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID)
++              force_link = MTK_XGMAC_FORCE_LINK(mac->id);
++
++      mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id));
++
++      mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
++      mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE);
++      /* Configure pause modes -
++       * phylink will avoid these for half duplex
++       */
++      if (tx_pause)
++              mcr |= XMAC_MCR_FORCE_TX_FC;
++      if (rx_pause)
++              mcr |= XMAC_MCR_FORCE_RX_FC;
++
++      mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
++}
++
++static void mtk_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)
++{
++      struct mtk_mac *mac = container_of(config, struct mtk_mac,
++                                         phylink_config);
++
++      if (mtk_interface_mode_is_xgmii(interface))
++              mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
++                                   tx_pause, rx_pause);
++      else
++              mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
++                                  tx_pause, rx_pause);
++}
++
+ static const struct phylink_mac_ops mtk_phylink_ops = {
+       .validate = phylink_generic_validate,
+       .mac_select_pcs = mtk_mac_select_pcs,
+@@ -4612,8 +4726,21 @@ static int mtk_add_mac(struct mtk_eth *e
+               phy_interface_zero(mac->phylink_config.supported_interfaces);
+               __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+                         mac->phylink_config.supported_interfaces);
++      } else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) {
++              mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD;
++              __set_bit(PHY_INTERFACE_MODE_5GBASER,
++                        mac->phylink_config.supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_10GBASER,
++                        mac->phylink_config.supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_USXGMII,
++                        mac->phylink_config.supported_interfaces);
+       }
++      if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) &&
++          id == MTK_GMAC2_ID)
++              __set_bit(PHY_INTERFACE_MODE_INTERNAL,
++                        mac->phylink_config.supported_interfaces);
++
+       phylink = phylink_create(&mac->phylink_config,
+                                of_fwnode_handle(mac->of_node),
+                                phy_mode, &mtk_phylink_ops);
+@@ -4806,6 +4933,13 @@ static int mtk_probe(struct platform_dev
+               if (err)
+                       return err;
++      }
++
++      if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
++              err = mtk_usxgmii_init(eth);
++
++              if (err)
++                      return err;
+       }
+       if (eth->soc->required_pctl) {
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -502,6 +502,21 @@
+ #define INTF_MODE_RGMII_1000    (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
+ #define INTF_MODE_RGMII_10_100  0
++/* XFI Mac control registers */
++#define MTK_XMAC_BASE(x)      (0x12000 + (((x) - 1) * 0x1000))
++#define MTK_XMAC_MCR(x)               (MTK_XMAC_BASE(x))
++#define XMAC_MCR_TRX_DISABLE  0xf
++#define XMAC_MCR_FORCE_TX_FC  BIT(5)
++#define XMAC_MCR_FORCE_RX_FC  BIT(4)
++
++/* XFI Mac logic reset registers */
++#define MTK_XMAC_LOGIC_RST(x) (MTK_XMAC_BASE(x) + 0x10)
++#define XMAC_LOGIC_RST                BIT(0)
++
++/* XFI Mac count global control */
++#define MTK_XMAC_CNT_CTRL(x)  (MTK_XMAC_BASE(x) + 0x100)
++#define XMAC_GLB_CNTCLR               BIT(0)
++
+ /* GPIO port control registers for GMAC 2*/
+ #define GPIO_OD33_CTRL8               0x4c0
+ #define GPIO_BIAS_CTRL                0xed0
+@@ -527,6 +542,7 @@
+ #define SYSCFG0_SGMII_GMAC2    ((3 << 8) & SYSCFG0_SGMII_MASK)
+ #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
+ #define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
++#define SYSCFG0_SGMII_GMAC3_V2 BIT(7)
+ /* ethernet subsystem clock register */
+@@ -559,12 +575,74 @@
+ #define ETHSYS_DMA_AG_MAP_QDMA        BIT(1)
+ #define ETHSYS_DMA_AG_MAP_PPE BIT(2)
++/* USXGMII subsystem config registers */
++/* Register to control speed */
++#define RG_PHY_TOP_SPEED_CTRL1        0x80C
++#define USXGMII_RATE_UPDATE_MODE      BIT(31)
++#define USXGMII_MAC_CK_GATED  BIT(29)
++#define USXGMII_IF_FORCE_EN   BIT(28)
++#define USXGMII_RATE_ADAPT_MODE       GENMASK(10, 8)
++#define USXGMII_RATE_ADAPT_MODE_X1    0
++#define USXGMII_RATE_ADAPT_MODE_X2    1
++#define USXGMII_RATE_ADAPT_MODE_X4    2
++#define USXGMII_RATE_ADAPT_MODE_X10   3
++#define USXGMII_RATE_ADAPT_MODE_X100  4
++#define USXGMII_RATE_ADAPT_MODE_X5    5
++#define USXGMII_RATE_ADAPT_MODE_X50   6
++#define USXGMII_XFI_RX_MODE   GENMASK(6, 4)
++#define USXGMII_XFI_RX_MODE_10G       0
++#define USXGMII_XFI_RX_MODE_5G        1
++#define USXGMII_XFI_TX_MODE   GENMASK(2, 0)
++#define USXGMII_XFI_TX_MODE_10G       0
++#define USXGMII_XFI_TX_MODE_5G        1
++
++/* Register to control PCS AN */
++#define RG_PCS_AN_CTRL0               0x810
++#define USXGMII_AN_RESTART    BIT(31)
++#define USXGMII_AN_SYNC_CNT   GENMASK(30, 11)
++#define USXGMII_AN_ENABLE     BIT(0)
++
++#define RG_PCS_AN_CTRL2               0x818
++#define USXGMII_LINK_TIMER_IDLE_DETECT        GENMASK(29, 20)
++#define USXGMII_LINK_TIMER_COMP_ACK_DETECT    GENMASK(19, 10)
++#define USXGMII_LINK_TIMER_AN_RESTART GENMASK(9, 0)
++
++/* Register to read PCS AN status */
++#define RG_PCS_AN_STS0                0x81c
++#define USXGMII_PCS_AN_WORD   GENMASK(15, 0)
++#define USXGMII_LPA_LATCH     BIT(31)
++
++/* Register to control USXGMII XFI PLL digital */
++#define XFI_PLL_DIG_GLB8      0x08
++#define RG_XFI_PLL_EN         BIT(31)
++
++/* Register to control USXGMII XFI PLL analog */
++#define XFI_PLL_ANA_GLB8      0x108
++#define RG_XFI_PLL_ANA_SWWA   0x02283248
++
+ /* Infrasys subsystem config registers */
+ #define INFRA_MISC2            0x70c
+ #define CO_QPHY_SEL            BIT(0)
+ #define GEPHY_MAC_SEL          BIT(1)
++/* Toprgu subsystem config registers */
++#define TOPRGU_SWSYSRST               0x18
++#define SWSYSRST_UNLOCK_KEY   GENMASK(31, 24)
++#define SWSYSRST_XFI_PLL_GRST BIT(16)
++#define SWSYSRST_XFI_PEXPT1_GRST      BIT(15)
++#define SWSYSRST_XFI_PEXPT0_GRST      BIT(14)
++#define SWSYSRST_XFI1_GRST    BIT(13)
++#define SWSYSRST_XFI0_GRST    BIT(12)
++#define SWSYSRST_SGMII1_GRST  BIT(2)
++#define SWSYSRST_SGMII0_GRST  BIT(1)
++#define TOPRGU_SWSYSRST_EN            0xFC
++
+ /* Top misc registers */
++#define TOP_MISC_NETSYS_PCS_MUX       0x84
++#define NETSYS_PCS_MUX_MASK   GENMASK(1, 0)
++#define       MUX_G2_USXGMII_SEL      BIT(1)
++#define MUX_HSGMII1_G1_SEL    BIT(0)
++
+ #define USB_PHY_SWITCH_REG    0x218
+ #define QPHY_SEL_MASK         GENMASK(1, 0)
+ #define SGMII_QPHY_SEL                0x2
+@@ -589,6 +667,8 @@
+ #define MT7628_SDM_RBCNT      (MT7628_SDM_OFFSET + 0x10c)
+ #define MT7628_SDM_CS_ERR     (MT7628_SDM_OFFSET + 0x110)
++/* Debug Purpose Register */
++#define MTK_PSE_FQFC_CFG      0x100
+ #define MTK_FE_CDM1_FSM               0x220
+ #define MTK_FE_CDM2_FSM               0x224
+ #define MTK_FE_CDM3_FSM               0x238
+@@ -597,6 +677,11 @@
+ #define MTK_FE_CDM6_FSM               0x328
+ #define MTK_FE_GDM1_FSM               0x228
+ #define MTK_FE_GDM2_FSM               0x22C
++#define MTK_FE_GDM3_FSM               0x23C
++#define MTK_FE_PSE_FREE               0x240
++#define MTK_FE_DROP_FQ                0x244
++#define MTK_FE_DROP_FC                0x248
++#define MTK_FE_DROP_PPE               0x24C
+ #define MTK_MAC_FSM(x)                (0x1010C + ((x) * 0x100))
+@@ -943,6 +1028,8 @@ enum mkt_eth_capabilities {
+       MTK_RGMII_BIT = 0,
+       MTK_TRGMII_BIT,
+       MTK_SGMII_BIT,
++      MTK_USXGMII_BIT,
++      MTK_2P5GPHY_BIT,
+       MTK_ESW_BIT,
+       MTK_GEPHY_BIT,
+       MTK_MUX_BIT,
+@@ -963,8 +1050,11 @@ enum mkt_eth_capabilities {
+       MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
+       MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
+       MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
++      MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT,
+       MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
+       MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
++      MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
++      MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
+       /* PATH BITS */
+       MTK_ETH_PATH_GMAC1_RGMII_BIT,
+@@ -972,14 +1062,21 @@ enum mkt_eth_capabilities {
+       MTK_ETH_PATH_GMAC1_SGMII_BIT,
+       MTK_ETH_PATH_GMAC2_RGMII_BIT,
+       MTK_ETH_PATH_GMAC2_SGMII_BIT,
++      MTK_ETH_PATH_GMAC2_2P5GPHY_BIT,
+       MTK_ETH_PATH_GMAC2_GEPHY_BIT,
++      MTK_ETH_PATH_GMAC3_SGMII_BIT,
+       MTK_ETH_PATH_GDM1_ESW_BIT,
++      MTK_ETH_PATH_GMAC1_USXGMII_BIT,
++      MTK_ETH_PATH_GMAC2_USXGMII_BIT,
++      MTK_ETH_PATH_GMAC3_USXGMII_BIT,
+ };
+ /* Supported hardware group on SoCs */
+ #define MTK_RGMII             BIT_ULL(MTK_RGMII_BIT)
+ #define MTK_TRGMII            BIT_ULL(MTK_TRGMII_BIT)
+ #define MTK_SGMII             BIT_ULL(MTK_SGMII_BIT)
++#define MTK_USXGMII           BIT_ULL(MTK_USXGMII_BIT)
++#define MTK_2P5GPHY           BIT_ULL(MTK_2P5GPHY_BIT)
+ #define MTK_ESW                       BIT_ULL(MTK_ESW_BIT)
+ #define MTK_GEPHY             BIT_ULL(MTK_GEPHY_BIT)
+ #define MTK_MUX                       BIT_ULL(MTK_MUX_BIT)
+@@ -1002,10 +1099,16 @@ enum mkt_eth_capabilities {
+       BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
+ #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY          \
+       BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
++#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY          \
++      BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT)
+ #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII        \
+       BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
+ #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII     \
+       BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
++#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII    \
++      BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT)
++#define MTK_ETH_MUX_GMAC123_TO_USXGMII        \
++      BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
+ /* Supported path present on SoCs */
+ #define MTK_ETH_PATH_GMAC1_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
+@@ -1013,8 +1116,13 @@ enum mkt_eth_capabilities {
+ #define MTK_ETH_PATH_GMAC1_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
+ #define MTK_ETH_PATH_GMAC2_RGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
+ #define MTK_ETH_PATH_GMAC2_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
++#define MTK_ETH_PATH_GMAC2_2P5GPHY    BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT)
+ #define MTK_ETH_PATH_GMAC2_GEPHY      BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
++#define MTK_ETH_PATH_GMAC3_SGMII      BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
+ #define MTK_ETH_PATH_GDM1_ESW         BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
++#define MTK_ETH_PATH_GMAC1_USXGMII    BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
++#define MTK_ETH_PATH_GMAC2_USXGMII    BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
++#define MTK_ETH_PATH_GMAC3_USXGMII    BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
+ #define MTK_GMAC1_RGMII               (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
+ #define MTK_GMAC1_TRGMII      (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
+@@ -1022,7 +1130,12 @@ enum mkt_eth_capabilities {
+ #define MTK_GMAC2_RGMII               (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
+ #define MTK_GMAC2_SGMII               (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
+ #define MTK_GMAC2_GEPHY               (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
++#define MTK_GMAC2_2P5GPHY     (MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY)
++#define MTK_GMAC3_SGMII               (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
+ #define MTK_GDM1_ESW          (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
++#define MTK_GMAC1_USXGMII     (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
++#define MTK_GMAC2_USXGMII     (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
++#define MTK_GMAC3_USXGMII     (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
+ /* MUXes present on SoCs */
+ /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
+@@ -1041,10 +1154,20 @@ enum mkt_eth_capabilities {
+       (MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
+       MTK_SHARED_SGMII)
++/* 2: GMAC2 -> XGMII */
++#define MTK_MUX_GMAC2_TO_2P5GPHY      \
++      (MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA)
++
+ /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */
+ #define MTK_MUX_GMAC12_TO_GEPHY_SGMII   \
+       (MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
++#define MTK_MUX_GMAC123_TO_GEPHY_SGMII   \
++      (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX)
++
++#define MTK_MUX_GMAC123_TO_USXGMII   \
++      (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
++
+ #define MTK_HAS_CAPS(caps, _x)                (((caps) & (_x)) == (_x))
+ #define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
+@@ -1076,8 +1199,12 @@ enum mkt_eth_capabilities {
+                     MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
+                     MTK_RSTCTRL_PPE1 | MTK_SRAM)
+-#define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \
+-                    MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
++#define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \
++                    MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \
++                    MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \
++                    MTK_MUX_GMAC123_TO_GEPHY_SGMII | \
++                    MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \
++                    MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
+ struct mtk_tx_dma_desc_info {
+       dma_addr_t      addr;
+@@ -1187,6 +1314,24 @@ struct mtk_soc_data {
+ /* currently no SoC has more than 3 macs */
+ #define MTK_MAX_DEVS  3
++/* struct mtk_usxgmii_pcs - This structure holds each usxgmii regmap and
++ *                    associated data
++ * @regmap:           The register map pointing at the range used to setup
++ *                    USXGMII modes
++ * @interface:                Currently selected interface mode
++ * @id:                       The element is used to record the index of PCS
++ * @pcs:              Phylink PCS structure
++ */
++struct mtk_usxgmii_pcs {
++      struct mtk_eth          *eth;
++      struct regmap           *regmap;
++      struct phylink_pcs      *wrapped_sgmii_pcs;
++      phy_interface_t         interface;
++      u8                      id;
++      unsigned int            mode;
++      struct phylink_pcs      pcs;
++};
++
+ /* struct mtk_eth -   This is the main datasructure for holding the state
+  *                    of the driver
+  * @dev:              The device pointer
+@@ -1207,6 +1352,12 @@ struct mtk_soc_data {
+  * @infra:              The register map pointing at the range used to setup
+  *                      SGMII and GePHY path
+  * @sgmii_pcs:                Pointers to mtk-pcs-lynxi phylink_pcs instances
++ * @sgmii_wrapped_pcs:        Pointers to NETSYSv3 wrapper PCS instances
++ * @usxgmii_pll:      The register map pointing at the range used to control
++ *                    the USXGMII SerDes PLL
++ * @regmap_pextp:     The register map pointing at the range used to setup
++ *                    PHYA
++ * @usxgmii_pcs:      Pointer to array of pointers to struct for USXGMII PCS
+  * @pctl:             The register map pointing at the range used to setup
+  *                    GMAC port drive/slew values
+  * @dma_refcnt:               track how many netdevs are using the DMA engine
+@@ -1250,6 +1401,10 @@ struct mtk_eth {
+       struct regmap                   *ethsys;
+       struct regmap                   *infra;
+       struct phylink_pcs              *sgmii_pcs[MTK_MAX_DEVS];
++      struct regmap                   *toprgu;
++      struct regmap                   *usxgmii_pll;
++      struct regmap                   *regmap_pextp[MTK_MAX_DEVS];
++      struct mtk_usxgmii_pcs          *usxgmii_pcs[MTK_MAX_DEVS];
+       struct regmap                   *pctl;
+       bool                            hwlro;
+       refcount_t                      dma_refcnt;
+@@ -1437,6 +1592,19 @@ static inline u32 mtk_get_ib2_multicast_
+       return MTK_FOE_IB2_MULTICAST;
+ }
++static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
++{
++      switch (interface) {
++      case PHY_INTERFACE_MODE_INTERNAL:
++      case PHY_INTERFACE_MODE_USXGMII:
++      case PHY_INTERFACE_MODE_10GBASER:
++      case PHY_INTERFACE_MODE_5GBASER:
++              return true;
++      default:
++              return false;
++      }
++}
++
+ /* read the hardware status register */
+ void mtk_stats_update_mac(struct mtk_mac *mac);
+@@ -1445,8 +1613,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
+ u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
+ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
++int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id);
+ int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
+ int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
++int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id);
+ int mtk_eth_offload_init(struct mtk_eth *eth);
+ int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
+@@ -1456,5 +1626,63 @@ int mtk_flow_offload_cmd(struct mtk_eth
+ void mtk_flow_offload_cleanup(struct mtk_eth *eth, struct list_head *list);
+ void mtk_eth_set_dma_device(struct mtk_eth *eth, struct device *dma_dev);
++static inline int mtk_mac2xgmii_id(struct mtk_eth *eth, int mac_id)
++{
++      int xgmii_id = mac_id;
++
++      if (mtk_is_netsys_v3_or_greater(eth)) {
++              switch (mac_id) {
++              case MTK_GMAC1_ID:
++              case MTK_GMAC2_ID:
++                      xgmii_id = 1;
++                      break;
++              case MTK_GMAC3_ID:
++                      xgmii_id = 0;
++                      break;
++              default:
++                      xgmii_id = -1;
++              }
++      }
++
++      return MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII) ? 0 : xgmii_id;
++}
++
++static inline int mtk_xgmii2mac_id(struct mtk_eth *eth, int xgmii_id)
++{
++      int mac_id = xgmii_id;
++
++      if (mtk_is_netsys_v3_or_greater(eth)) {
++              switch (xgmii_id) {
++              case 0:
++                      mac_id = 2;
++                      break;
++              case 1:
++                      mac_id = 1;
++                      break;
++              default:
++                      mac_id = -1;
++              }
++      }
++
++      return mac_id;
++}
++
++#ifdef CONFIG_NET_MEDIATEK_SOC_USXGMII
++struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id);
++struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id);
++int mtk_usxgmii_init(struct mtk_eth *eth);
++#else
++static inline struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int id)
++{
++      return NULL;
++}
++
++static inline struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int id)
++{
++      return NULL;
++}
++
++static inline int mtk_usxgmii_init(struct mtk_eth *eth) { return 0; }
++#endif /* NET_MEDIATEK_SOC_USXGMII */
+ #endif /* MTK_ETH_H */
+--- /dev/null
++++ b/drivers/net/ethernet/mediatek/mtk_usxgmii.c
+@@ -0,0 +1,690 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Copyright (c) 2023 MediaTek Inc.
++ * Author: Henry Yen <henry.yen@mediatek.com>
++ *         Daniel Golle <daniel@makrotopia.org>
++ */
++
++#include <linux/mfd/syscon.h>
++#include <linux/of.h>
++#include <linux/regmap.h>
++#include "mtk_eth_soc.h"
++
++static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs)
++{
++      return container_of(pcs, struct mtk_usxgmii_pcs, pcs);
++}
++
++static int mtk_xfi_pextp_init(struct mtk_eth *eth)
++{
++      struct device *dev = eth->dev;
++      struct device_node *r = dev->of_node;
++      struct device_node *np;
++      int i;
++
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
++              np = of_parse_phandle(r, "mediatek,xfi-pextp", i);
++              if (!np)
++                      break;
++
++              eth->regmap_pextp[i] = syscon_node_to_regmap(np);
++              if (IS_ERR(eth->regmap_pextp[i]))
++                      return PTR_ERR(eth->regmap_pextp[i]);
++      }
++
++      return 0;
++}
++
++static int mtk_xfi_pll_init(struct mtk_eth *eth)
++{
++      struct device_node *r = eth->dev->of_node;
++      struct device_node *np;
++
++      np = of_parse_phandle(r, "mediatek,xfi-pll", 0);
++      if (!np)
++              return -1;
++
++      eth->usxgmii_pll = syscon_node_to_regmap(np);
++      if (IS_ERR(eth->usxgmii_pll))
++              return PTR_ERR(eth->usxgmii_pll);
++
++      return 0;
++}
++
++static int mtk_toprgu_init(struct mtk_eth *eth)
++{
++      struct device_node *r = eth->dev->of_node;
++      struct device_node *np;
++
++      np = of_parse_phandle(r, "mediatek,toprgu", 0);
++      if (!np)
++              return -1;
++
++      eth->toprgu = syscon_node_to_regmap(np);
++      if (IS_ERR(eth->toprgu))
++              return PTR_ERR(eth->toprgu);
++
++      return 0;
++}
++
++static int mtk_xfi_pll_enable(struct mtk_eth *eth)
++{
++      u32 val = 0;
++
++      if (!eth->usxgmii_pll)
++              return -EINVAL;
++
++      /* Add software workaround for USXGMII PLL TCL issue */
++      regmap_write(eth->usxgmii_pll, XFI_PLL_ANA_GLB8, RG_XFI_PLL_ANA_SWWA);
++
++      regmap_read(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, &val);
++      val |= RG_XFI_PLL_EN;
++      regmap_write(eth->usxgmii_pll, XFI_PLL_DIG_GLB8, val);
++
++      return 0;
++}
++
++static void mtk_usxgmii_setup_phya(struct regmap *pextp, phy_interface_t interface, int id)
++{
++      bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
++                     interface == PHY_INTERFACE_MODE_USXGMII);
++      bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
++      bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
++
++      /* Setup operation mode */
++      if (is_10g)
++              regmap_write(pextp, 0x9024, 0x00C9071C);
++      else
++              regmap_write(pextp, 0x9024, 0x00D9071C);
++
++      if (is_5g)
++              regmap_write(pextp, 0x2020, 0xAAA5A5AA);
++      else
++              regmap_write(pextp, 0x2020, 0xAA8585AA);
++
++      if (is_2p5g || is_5g || is_10g) {
++              regmap_write(pextp, 0x2030, 0x0C020707);
++              regmap_write(pextp, 0x2034, 0x0E050F0F);
++              regmap_write(pextp, 0x2040, 0x00140032);
++      } else {
++              regmap_write(pextp, 0x2030, 0x0C020207);
++              regmap_write(pextp, 0x2034, 0x0E05050F);
++              regmap_write(pextp, 0x2040, 0x00200032);
++      }
++
++      if (is_2p5g || is_10g)
++              regmap_write(pextp, 0x50F0, 0x00C014AA);
++      else if (is_5g)
++              regmap_write(pextp, 0x50F0, 0x00C018AA);
++      else
++              regmap_write(pextp, 0x50F0, 0x00C014BA);
++
++      if (is_5g) {
++              regmap_write(pextp, 0x50E0, 0x3777812B);
++              regmap_write(pextp, 0x506C, 0x005C9CFF);
++              regmap_write(pextp, 0x5070, 0x9DFAFAFA);
++              regmap_write(pextp, 0x5074, 0x273F3F3F);
++              regmap_write(pextp, 0x5078, 0xA8883868);
++              regmap_write(pextp, 0x507C, 0x14661466);
++      } else {
++              regmap_write(pextp, 0x50E0, 0x3777C12B);
++              regmap_write(pextp, 0x506C, 0x005F9CFF);
++              regmap_write(pextp, 0x5070, 0x9D9DFAFA);
++              regmap_write(pextp, 0x5074, 0x27273F3F);
++              regmap_write(pextp, 0x5078, 0xA7883C68);
++              regmap_write(pextp, 0x507C, 0x11661166);
++      }
++
++      if (is_2p5g || is_10g) {
++              regmap_write(pextp, 0x5080, 0x0E000AAF);
++              regmap_write(pextp, 0x5084, 0x08080D0D);
++              regmap_write(pextp, 0x5088, 0x02030909);
++      } else if (is_5g) {
++              regmap_write(pextp, 0x5080, 0x0E001ABF);
++              regmap_write(pextp, 0x5084, 0x080B0D0D);
++              regmap_write(pextp, 0x5088, 0x02050909);
++      } else {
++              regmap_write(pextp, 0x5080, 0x0E000EAF);
++              regmap_write(pextp, 0x5084, 0x08080E0D);
++              regmap_write(pextp, 0x5088, 0x02030B09);
++      }
++
++      if (is_5g) {
++              regmap_write(pextp, 0x50E4, 0x0C000000);
++              regmap_write(pextp, 0x50E8, 0x04000000);
++      } else {
++              regmap_write(pextp, 0x50E4, 0x0C0C0000);
++              regmap_write(pextp, 0x50E8, 0x04040000);
++      }
++
++      if (is_2p5g || mtk_interface_mode_is_xgmii(interface))
++              regmap_write(pextp, 0x50EC, 0x0F0F0C06);
++      else
++              regmap_write(pextp, 0x50EC, 0x0F0F0606);
++
++      if (is_5g) {
++              regmap_write(pextp, 0x50A8, 0x50808C8C);
++              regmap_write(pextp, 0x6004, 0x18000000);
++      } else {
++              regmap_write(pextp, 0x50A8, 0x506E8C8C);
++              regmap_write(pextp, 0x6004, 0x18190000);
++      }
++
++      if (is_10g)
++              regmap_write(pextp, 0x00F8, 0x01423342);
++      else if (is_5g)
++              regmap_write(pextp, 0x00F8, 0x00A132A1);
++      else if (is_2p5g)
++              regmap_write(pextp, 0x00F8, 0x009C329C);
++      else
++              regmap_write(pextp, 0x00F8, 0x00FA32FA);
++
++      /* Force SGDT_OUT off and select PCS */
++      if (mtk_interface_mode_is_xgmii(interface))
++              regmap_write(pextp, 0x00F4, 0x80201F20);
++      else
++              regmap_write(pextp, 0x00F4, 0x80201F21);
++
++      /* Force GLB_CKDET_OUT */
++      regmap_write(pextp, 0x0030, 0x00050C00);
++
++      /* Force AEQ on */
++      regmap_write(pextp, 0x0070, 0x02002800);
++      ndelay(1020);
++
++      /* Setup DA default value */
++      regmap_write(pextp, 0x30B0, 0x00000020);
++      regmap_write(pextp, 0x3028, 0x00008A01);
++      regmap_write(pextp, 0x302C, 0x0000A884);
++      regmap_write(pextp, 0x3024, 0x00083002);
++      if (mtk_interface_mode_is_xgmii(interface)) {
++              regmap_write(pextp, 0x3010, 0x00022220);
++              regmap_write(pextp, 0x5064, 0x0F020A01);
++              regmap_write(pextp, 0x50B4, 0x06100600);
++              if (interface == PHY_INTERFACE_MODE_USXGMII)
++                      regmap_write(pextp, 0x3048, 0x40704000);
++              else
++                      regmap_write(pextp, 0x3048, 0x47684100);
++      } else {
++              regmap_write(pextp, 0x3010, 0x00011110);
++              regmap_write(pextp, 0x3048, 0x40704000);
++      }
++
++      if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g)
++              regmap_write(pextp, 0x3064, 0x0000C000);
++
++      if (interface == PHY_INTERFACE_MODE_USXGMII) {
++              regmap_write(pextp, 0x3050, 0xA8000000);
++              regmap_write(pextp, 0x3054, 0x000000AA);
++      } else if (mtk_interface_mode_is_xgmii(interface)) {
++              regmap_write(pextp, 0x3050, 0x00000000);
++              regmap_write(pextp, 0x3054, 0x00000000);
++      } else {
++              regmap_write(pextp, 0x3050, 0xA8000000);
++              regmap_write(pextp, 0x3054, 0x000000AA);
++      }
++
++      if (mtk_interface_mode_is_xgmii(interface))
++              regmap_write(pextp, 0x306C, 0x00000F00);
++      else if (is_2p5g)
++              regmap_write(pextp, 0x306C, 0x22000F00);
++      else
++              regmap_write(pextp, 0x306C, 0x20200F00);
++
++      if (interface == PHY_INTERFACE_MODE_10GBASER && id == 0)
++              regmap_write(pextp, 0xA008, 0x0007B400);
++
++      if (mtk_interface_mode_is_xgmii(interface))
++              regmap_write(pextp, 0xA060, 0x00040000);
++      else
++              regmap_write(pextp, 0xA060, 0x00050000);
++
++      if (is_10g)
++              regmap_write(pextp, 0x90D0, 0x00000001);
++      else if (is_5g)
++              regmap_write(pextp, 0x90D0, 0x00000003);
++      else if (is_2p5g)
++              regmap_write(pextp, 0x90D0, 0x00000005);
++      else
++              regmap_write(pextp, 0x90D0, 0x00000007);
++
++      /* Release reset */
++      regmap_write(pextp, 0x0070, 0x0200E800);
++      usleep_range(150, 500);
++
++      /* Switch to P0 */
++      regmap_write(pextp, 0x0070, 0x0200C111);
++      ndelay(1020);
++      regmap_write(pextp, 0x0070, 0x0200C101);
++      usleep_range(15, 50);
++
++      if (mtk_interface_mode_is_xgmii(interface)) {
++              /* Switch to Gen3 */
++              regmap_write(pextp, 0x0070, 0x0202C111);
++      } else {
++              /* Switch to Gen2 */
++              regmap_write(pextp, 0x0070, 0x0201C111);
++      }
++      ndelay(1020);
++      if (mtk_interface_mode_is_xgmii(interface))
++              regmap_write(pextp, 0x0070, 0x0202C101);
++      else
++              regmap_write(pextp, 0x0070, 0x0201C101);
++      usleep_range(100, 500);
++      regmap_write(pextp, 0x30B0, 0x00000030);
++      if (mtk_interface_mode_is_xgmii(interface))
++              regmap_write(pextp, 0x00F4, 0x80201F00);
++      else
++              regmap_write(pextp, 0x00F4, 0x80201F01);
++
++      regmap_write(pextp, 0x3040, 0x30000000);
++      usleep_range(400, 1000);
++}
++
++static void mtk_usxgmii_reset(struct mtk_eth *eth, int id)
++{
++      u32 toggle, val;
++
++      if (id >= MTK_MAX_DEVS || !eth->toprgu)
++              return;
++
++      switch (id) {
++      case 0:
++              toggle = SWSYSRST_XFI_PEXPT0_GRST | SWSYSRST_XFI0_GRST |
++                       SWSYSRST_SGMII0_GRST;
++              break;
++      case 1:
++              toggle = SWSYSRST_XFI_PEXPT1_GRST | SWSYSRST_XFI1_GRST |
++                       SWSYSRST_SGMII1_GRST;
++              break;
++      default:
++              return;
++      }
++
++      /* Enable software reset */
++      regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle);
++
++      /* Assert USXGMII reset */
++      regmap_set_bits(eth->toprgu, TOPRGU_SWSYSRST,
++                      FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88) | toggle);
++
++      usleep_range(100, 500);
++
++      /* De-assert USXGMII reset */
++      regmap_read(eth->toprgu, TOPRGU_SWSYSRST, &val);
++      val |= FIELD_PREP(SWSYSRST_UNLOCK_KEY, 0x88);
++      val &= ~toggle;
++      regmap_write(eth->toprgu, TOPRGU_SWSYSRST, val);
++
++      /* Disable software reset */
++      regmap_clear_bits(eth->toprgu, TOPRGU_SWSYSRST_EN, toggle);
++
++      mdelay(10);
++}
++
++/* As the USXGMII PHYA is shared with the 1000Base-X/2500Base-X/Cisco SGMII unit
++ * the psc-mtk-lynxi instance needs to be wrapped, so that calls to .pcs_config
++ * also trigger an initial reset and subsequent configuration of the PHYA.
++ */
++struct mtk_sgmii_wrapper_pcs {
++      struct mtk_eth          *eth;
++      struct phylink_pcs      *wrapped_pcs;
++      u8                      id;
++      struct phylink_pcs      pcs;
++};
++
++static int mtk_sgmii_wrapped_pcs_config(struct phylink_pcs *pcs,
++                                      unsigned int mode,
++                                      phy_interface_t interface,
++                                      const unsigned long *advertising,
++                                      bool permit_pause_to_mac)
++{
++      struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
++      bool full_reconf;
++      int ret;
++
++      full_reconf = interface != wp->eth->usxgmii_pcs[wp->id]->interface;
++      if (full_reconf) {
++              mtk_xfi_pll_enable(wp->eth);
++              mtk_usxgmii_reset(wp->eth, wp->id);
++      }
++
++      ret = wp->wrapped_pcs->ops->pcs_config(wp->wrapped_pcs, mode, interface,
++                                             advertising, permit_pause_to_mac);
++
++      if (full_reconf)
++              mtk_usxgmii_setup_phya(wp->eth->regmap_pextp[wp->id], interface, wp->id);
++
++      wp->eth->usxgmii_pcs[wp->id]->interface = interface;
++
++      return ret;
++}
++
++static void mtk_sgmii_wrapped_pcs_get_state(struct phylink_pcs *pcs,
++                                          struct phylink_link_state *state)
++{
++      struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
++
++      return wp->wrapped_pcs->ops->pcs_get_state(wp->wrapped_pcs, state);
++}
++
++static void mtk_sgmii_wrapped_pcs_an_restart(struct phylink_pcs *pcs)
++{
++      struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
++
++      wp->wrapped_pcs->ops->pcs_an_restart(wp->wrapped_pcs);
++}
++
++static void mtk_sgmii_wrapped_pcs_link_up(struct phylink_pcs *pcs,
++                                        unsigned int mode,
++                                        phy_interface_t interface, int speed,
++                                        int duplex)
++{
++      struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
++
++      wp->wrapped_pcs->ops->pcs_link_up(wp->wrapped_pcs, mode, interface, speed, duplex);
++}
++
++static void mtk_sgmii_wrapped_pcs_disable(struct phylink_pcs *pcs)
++{
++      struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
++
++      wp->wrapped_pcs->ops->pcs_disable(wp->wrapped_pcs);
++
++      wp->eth->usxgmii_pcs[wp->id]->interface = PHY_INTERFACE_MODE_NA;
++}
++
++static const struct phylink_pcs_ops mtk_sgmii_wrapped_pcs_ops = {
++      .pcs_get_state = mtk_sgmii_wrapped_pcs_get_state,
++      .pcs_config = mtk_sgmii_wrapped_pcs_config,
++      .pcs_an_restart = mtk_sgmii_wrapped_pcs_an_restart,
++      .pcs_link_up = mtk_sgmii_wrapped_pcs_link_up,
++      .pcs_disable = mtk_sgmii_wrapped_pcs_disable,
++};
++
++static int mtk_sgmii_wrapper_init(struct mtk_eth *eth)
++{
++      struct mtk_sgmii_wrapper_pcs *wp;
++      int i;
++
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
++              if (!eth->sgmii_pcs[i])
++                      continue;
++
++              if (!eth->usxgmii_pcs[i])
++                      continue;
++
++              /* Make sure all PCS ops are supported by wrapped PCS */
++              if (!eth->sgmii_pcs[i]->ops->pcs_get_state ||
++                  !eth->sgmii_pcs[i]->ops->pcs_config ||
++                  !eth->sgmii_pcs[i]->ops->pcs_an_restart ||
++                  !eth->sgmii_pcs[i]->ops->pcs_link_up ||
++                  !eth->sgmii_pcs[i]->ops->pcs_disable)
++                      return -EOPNOTSUPP;
++
++              wp = devm_kzalloc(eth->dev, sizeof(*wp), GFP_KERNEL);
++              if (!wp)
++                      return -ENOMEM;
++
++              wp->wrapped_pcs = eth->sgmii_pcs[i];
++              wp->id = i;
++              wp->pcs.poll = true;
++              wp->pcs.ops = &mtk_sgmii_wrapped_pcs_ops;
++              wp->eth = eth;
++
++              eth->usxgmii_pcs[i]->wrapped_sgmii_pcs = &wp->pcs;
++      }
++
++      return 0;
++}
++
++struct phylink_pcs *mtk_sgmii_wrapper_select_pcs(struct mtk_eth *eth, int mac_id)
++{
++      u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id);
++
++      if (!eth->usxgmii_pcs[xgmii_id])
++              return NULL;
++
++      return eth->usxgmii_pcs[xgmii_id]->wrapped_sgmii_pcs;
++}
++
++static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
++                                phy_interface_t interface,
++                                const unsigned long *advertising,
++                                bool permit_pause_to_mac)
++{
++      struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
++      struct mtk_eth *eth = mpcs->eth;
++      struct regmap *pextp = eth->regmap_pextp[mpcs->id];
++      unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0;
++      bool mode_changed = false;
++
++      if (!pextp)
++              return -ENODEV;
++
++      if (interface == PHY_INTERFACE_MODE_USXGMII) {
++              an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE;
++              link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
++                           FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
++                           FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
++              xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) |
++                         FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G);
++      } else if (interface == PHY_INTERFACE_MODE_10GBASER) {
++              an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF);
++              link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
++                           FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
++                           FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
++              xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_10G) |
++                         FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_10G);
++              adapt_mode = USXGMII_RATE_UPDATE_MODE;
++      } else if (interface == PHY_INTERFACE_MODE_5GBASER) {
++              an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF);
++              link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) |
++                           FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) |
++                           FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D);
++              xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_RX_MODE_5G) |
++                         FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_TX_MODE_5G);
++              adapt_mode = USXGMII_RATE_UPDATE_MODE;
++      } else {
++              return -EINVAL;
++      }
++
++      adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1);
++
++      if (mpcs->interface != interface) {
++              mpcs->interface = interface;
++              mode_changed = true;
++      }
++
++      mtk_xfi_pll_enable(eth);
++      mtk_usxgmii_reset(eth, mpcs->id);
++
++      /* Setup USXGMII AN ctrl */
++      regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL0,
++                         USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
++                         an_ctrl);
++
++      regmap_update_bits(mpcs->regmap, RG_PCS_AN_CTRL2,
++                         USXGMII_LINK_TIMER_IDLE_DETECT |
++                         USXGMII_LINK_TIMER_COMP_ACK_DETECT |
++                         USXGMII_LINK_TIMER_AN_RESTART,
++                         link_timer);
++
++      mpcs->mode = mode;
++
++      /* Gated MAC CK */
++      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
++                         USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED);
++
++      /* Enable interface force mode */
++      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
++                         USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN);
++
++      /* Setup USXGMII adapt mode */
++      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
++                         USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE,
++                         adapt_mode);
++
++      /* Setup USXGMII speed */
++      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
++                         USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE,
++                         xfi_mode);
++
++      usleep_range(1, 10);
++
++      /* Un-gated MAC CK */
++      regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
++                         USXGMII_MAC_CK_GATED, 0);
++
++      usleep_range(1, 10);
++
++      /* Disable interface force mode for the AN mode */
++      if (an_ctrl & USXGMII_AN_ENABLE)
++              regmap_update_bits(mpcs->regmap, RG_PHY_TOP_SPEED_CTRL1,
++                                 USXGMII_IF_FORCE_EN, 0);
++
++      /* Setup USXGMIISYS with the determined property */
++      mtk_usxgmii_setup_phya(pextp, interface, mpcs->id);
++
++      return mode_changed;
++}
++
++static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs,
++                                    struct phylink_link_state *state)
++{
++      struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
++      struct mtk_eth *eth = mpcs->eth;
++      struct mtk_mac *mac = eth->mac[mtk_xgmii2mac_id(eth, mpcs->id)];
++      u32 val = 0;
++
++      regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
++      if (FIELD_GET(USXGMII_AN_ENABLE, val)) {
++              /* Refresh LPA by inverting LPA_LATCH */
++              regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val);
++              regmap_update_bits(mpcs->regmap, RG_PCS_AN_STS0,
++                                 USXGMII_LPA_LATCH,
++                                 !(val & USXGMII_LPA_LATCH));
++
++              regmap_read(mpcs->regmap, RG_PCS_AN_STS0, &val);
++
++              phylink_decode_usxgmii_word(state, FIELD_GET(USXGMII_PCS_AN_WORD,
++                                                           val));
++
++              state->interface = mpcs->interface;
++      } else {
++              val = mtk_r32(mac->hw, MTK_XGMAC_STS(mac->id));
++
++              if (mac->id == MTK_GMAC2_ID)
++                      val >>= 16;
++
++              switch (FIELD_GET(MTK_USXGMII_PCS_MODE, val)) {
++              case 0:
++                      state->speed = SPEED_10000;
++                      break;
++              case 1:
++                      state->speed = SPEED_5000;
++                      break;
++              case 2:
++                      state->speed = SPEED_2500;
++                      break;
++              case 3:
++                      state->speed = SPEED_1000;
++                      break;
++              }
++
++              state->interface = mpcs->interface;
++              state->link = FIELD_GET(MTK_USXGMII_PCS_LINK, val);
++              state->duplex = DUPLEX_FULL;
++      }
++
++      /* Continuously repeat re-configuration sequence until link comes up */
++      if (state->link == 0)
++              mtk_usxgmii_pcs_config(pcs, mpcs->mode,
++                                     state->interface, NULL, false);
++}
++
++static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs)
++{
++      struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
++      unsigned int val = 0;
++
++      if (!mpcs->regmap)
++              return;
++
++      regmap_read(mpcs->regmap, RG_PCS_AN_CTRL0, &val);
++      val |= USXGMII_AN_RESTART;
++      regmap_write(mpcs->regmap, RG_PCS_AN_CTRL0, val);
++}
++
++static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
++                                  phy_interface_t interface,
++                                  int speed, int duplex)
++{
++      /* Reconfiguring USXGMII to ensure the quality of the RX signal
++       * after the line side link up.
++       */
++      mtk_usxgmii_pcs_config(pcs, mode,
++                             interface, NULL, false);
++}
++
++static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = {
++      .pcs_config = mtk_usxgmii_pcs_config,
++      .pcs_get_state = mtk_usxgmii_pcs_get_state,
++      .pcs_an_restart = mtk_usxgmii_pcs_restart_an,
++      .pcs_link_up = mtk_usxgmii_pcs_link_up,
++};
++
++int mtk_usxgmii_init(struct mtk_eth *eth)
++{
++      struct device_node *r = eth->dev->of_node;
++      struct device *dev = eth->dev;
++      struct device_node *np;
++      int i, ret;
++
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
++              np = of_parse_phandle(r, "mediatek,usxgmiisys", i);
++              if (!np)
++                      break;
++
++              eth->usxgmii_pcs[i] = devm_kzalloc(dev, sizeof(*eth->usxgmii_pcs[i]), GFP_KERNEL);
++              if (!eth->usxgmii_pcs[i])
++                      return -ENOMEM;
++
++              eth->usxgmii_pcs[i]->id = i;
++              eth->usxgmii_pcs[i]->eth = eth;
++              eth->usxgmii_pcs[i]->regmap = syscon_node_to_regmap(np);
++              if (IS_ERR(eth->usxgmii_pcs[i]->regmap))
++                      return PTR_ERR(eth->usxgmii_pcs[i]->regmap);
++
++              eth->usxgmii_pcs[i]->pcs.ops = &mtk_usxgmii_pcs_ops;
++              eth->usxgmii_pcs[i]->pcs.poll = true;
++              eth->usxgmii_pcs[i]->interface = PHY_INTERFACE_MODE_NA;
++              eth->usxgmii_pcs[i]->mode = -1;
++
++              of_node_put(np);
++      }
++
++      ret = mtk_xfi_pextp_init(eth);
++      if (ret)
++              return ret;
++
++      ret = mtk_xfi_pll_init(eth);
++      if (ret)
++              return ret;
++
++      ret = mtk_toprgu_init(eth);
++      if (ret)
++              return ret;
++
++      return mtk_sgmii_wrapper_init(eth);
++}
++
++struct phylink_pcs *mtk_usxgmii_select_pcs(struct mtk_eth *eth, int mac_id)
++{
++      u32 xgmii_id = mtk_mac2xgmii_id(eth, mac_id);
++
++      if (!eth->usxgmii_pcs[xgmii_id]->regmap)
++              return NULL;
++
++      return &eth->usxgmii_pcs[xgmii_id]->pcs;
++}
index 7fbf38a7e34f3132f681235b012e03aefc6e33d8..ed5b7b60fb9adda4779f6bcb7c833e169e48dc01 100644 (file)
@@ -32,7 +32,7 @@ Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
        - rev-mii
 --- a/drivers/net/phy/phylink.c
 +++ b/drivers/net/phy/phylink.c
-@@ -366,6 +366,7 @@ void phylink_get_linkmodes(unsigned long
+@@ -371,6 +371,7 @@ void phylink_get_linkmodes(unsigned long
        case PHY_INTERFACE_MODE_RGMII_RXID:
        case PHY_INTERFACE_MODE_RGMII_ID:
        case PHY_INTERFACE_MODE_RGMII:
@@ -40,7 +40,7 @@ Signed-off-by: Gabor Juhos <j4g8y7@gmail.com>
        case PHY_INTERFACE_MODE_QSGMII:
        case PHY_INTERFACE_MODE_SGMII:
        case PHY_INTERFACE_MODE_GMII:
-@@ -629,6 +630,7 @@ static int phylink_parse_mode(struct phy
+@@ -634,6 +635,7 @@ static int phylink_parse_mode(struct phy
  
                switch (pl->link_config.interface) {
                case PHY_INTERFACE_MODE_SGMII:
index 30fc56e618503cbd2188bdda11d1f23791453315..46c304032db33bb22c3e68cc7e827ed4821c138e 100644 (file)
@@ -13,7 +13,7 @@ Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
 
 --- a/drivers/net/phy/phylink.c
 +++ b/drivers/net/phy/phylink.c
-@@ -393,6 +393,7 @@ void phylink_get_linkmodes(unsigned long
+@@ -398,6 +398,7 @@ void phylink_get_linkmodes(unsigned long
                caps |= MAC_1000FD;
                break;
  
@@ -21,7 +21,7 @@ Signed-off-by: Bhaskar Upadhaya <Bhaskar.Upadhaya@nxp.com>
        case PHY_INTERFACE_MODE_2500BASEX:
                caps |= MAC_2500FD;
                break;
-@@ -646,6 +647,10 @@ static int phylink_parse_mode(struct phy
+@@ -651,6 +652,10 @@ static int phylink_parse_mode(struct phy
                        phylink_set(pl->supported, 2500baseX_Full);
                        break;
  
index 334dfa8502bc33aef713ce4006038950509688fa..36cb9c1e4e6be8d145e208ec0c53795d99d16c56 100644 (file)
@@ -4,7 +4,6 @@ CONFIG_AQUANTIA_PHY=y
 CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
 CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
 CONFIG_ARCH_DMA_ADDR_T_64BIT=y
-CONFIG_ARCH_FORCE_MAX_ORDER=11
 CONFIG_ARCH_KEEP_MEMBLOCK=y
 CONFIG_ARCH_MEDIATEK=y
 CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y
@@ -150,7 +149,6 @@ CONFIG_FIT_PARTITION=y
 CONFIG_FIXED_PHY=y
 CONFIG_FIX_EARLYCON_MEM=y
 CONFIG_FRAME_POINTER=y
-CONFIG_FRAME_WARN=2048
 CONFIG_FS_IOMAP=y
 CONFIG_FS_MBCACHE=y
 CONFIG_FWNODE_MDIO=y
@@ -324,6 +322,7 @@ CONFIG_PCS_MTK_LYNXI=y
 CONFIG_PERF_EVENTS=y
 CONFIG_PGTABLE_LEVELS=3
 CONFIG_PHYLIB=y
+CONFIG_PHYLIB_LEDS=y
 CONFIG_PHYLINK=y
 CONFIG_PHYS_ADDR_T_64BIT=y
 # CONFIG_PHY_MTK_DP is not set
index 84718d300b5df7df04e55914a52204ea069b90e6..4c144a7b1ca9e9891b46c88500539d02b18211c7 100644 (file)
@@ -103,7 +103,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  
        ret = mtk_mdio_busy_wait(eth);
        if (ret < 0)
-@@ -1013,6 +1056,7 @@ static int mtk_mdio_init(struct mtk_eth
+@@ -898,6 +941,7 @@ static int mtk_mdio_init(struct mtk_eth
        eth->mii_bus->name = "mdio";
        eth->mii_bus->read = mtk_mdio_read;
        eth->mii_bus->write = mtk_mdio_write;
@@ -113,7 +113,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -382,9 +382,12 @@
+@@ -402,9 +402,12 @@
  #define PHY_IAC_ADDR_MASK     GENMASK(24, 20)
  #define PHY_IAC_ADDR(x)               FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
  #define PHY_IAC_CMD_MASK      GENMASK(19, 18)
index a455005504cead5f41035a08bfd8253509c58a6d..eed97b476944fb55f5a5836342b2c167e87a8199 100644 (file)
@@ -22,7 +22,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_wed.c
 +++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -813,6 +813,24 @@ mtk_wed_rro_alloc(struct mtk_wed_device
+@@ -821,6 +821,24 @@ mtk_wed_rro_alloc(struct mtk_wed_device
        struct device_node *np;
        int index;
  
@@ -47,7 +47,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        index = of_property_match_string(dev->hw->node, "memory-region-names",
                                         "wo-dlm");
        if (index < 0)
-@@ -829,6 +847,7 @@ mtk_wed_rro_alloc(struct mtk_wed_device
+@@ -837,6 +855,7 @@ mtk_wed_rro_alloc(struct mtk_wed_device
                return -ENODEV;
  
        dev->rro.miod_phys = rmem->base;
diff --git a/target/linux/mediatek/patches-6.1/731-net-phy-mediatek-ge-soc-initialize-MT7988-PHY-LEDs-d.patch b/target/linux/mediatek/patches-6.1/731-net-phy-mediatek-ge-soc-initialize-MT7988-PHY-LEDs-d.patch
deleted file mode 100644 (file)
index 83d0f26..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-From 5d2d78860f98eb5c03bc404eb024606878901ac8 Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Tue, 13 Jun 2023 03:27:14 +0100
-Subject: [PATCH] net: phy: mediatek-ge-soc: initialize MT7988 PHY LEDs default
- state
-
-Initialize LEDs and set sane default values.
-Read boottrap register and apply LED polarities accordingly to get
-uniform behavior from all LEDs on MT7988.
-Requires syscon phandle 'mediatek,pio' present in parenting MDIO bus
-which should point to the syscon holding the boottrap register.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/phy/mediatek-ge-soc.c | 144 ++++++++++++++++++++++++++++--
- 1 file changed, 136 insertions(+), 8 deletions(-)
-
---- a/drivers/net/phy/mediatek-ge-soc.c
-+++ b/drivers/net/phy/mediatek-ge-soc.c
-@@ -1,11 +1,13 @@
- // SPDX-License-Identifier: GPL-2.0+
- #include <linux/bitfield.h>
-+#include <linux/mfd/syscon.h>
- #include <linux/module.h>
- #include <linux/nvmem-consumer.h>
- #include <linux/of_address.h>
- #include <linux/of_platform.h>
- #include <linux/pinctrl/consumer.h>
- #include <linux/phy.h>
-+#include <linux/regmap.h>
- #define MTK_GPHY_ID_MT7981                    0x03a29461
- #define MTK_GPHY_ID_MT7988                    0x03a29481
-@@ -208,9 +210,40 @@
- #define MTK_PHY_DA_TX_R50_PAIR_C              0x53f
- #define MTK_PHY_DA_TX_R50_PAIR_D              0x540
-+/* Registers on MDIO_MMD_VEND2 */
-+#define MTK_PHY_LED0_ON_CTRL                  0x24
-+#define MTK_PHY_LED1_ON_CTRL                  0x26
-+#define   MTK_PHY_LED_ON_MASK                 GENMASK(6, 0)
-+#define   MTK_PHY_LED_ON_LINK1000             BIT(0)
-+#define   MTK_PHY_LED_ON_LINK100              BIT(1)
-+#define   MTK_PHY_LED_ON_LINK10                       BIT(2)
-+#define   MTK_PHY_LED_ON_LINKDOWN             BIT(3)
-+#define   MTK_PHY_LED_ON_FDX                  BIT(4) /* Full duplex */
-+#define   MTK_PHY_LED_ON_HDX                  BIT(5) /* Half duplex */
-+#define   MTK_PHY_LED_FORCE_ON                        BIT(6)
-+#define   MTK_PHY_LED_POLARITY                        BIT(14)
-+#define   MTK_PHY_LED_ENABLE                  BIT(15)
-+
-+#define MTK_PHY_LED0_BLINK_CTRL                       0x25
-+#define MTK_PHY_LED1_BLINK_CTRL                       0x27
-+#define   MTK_PHY_LED_1000TX                  BIT(0)
-+#define   MTK_PHY_LED_1000RX                  BIT(1)
-+#define   MTK_PHY_LED_100TX                   BIT(2)
-+#define   MTK_PHY_LED_100RX                   BIT(3)
-+#define   MTK_PHY_LED_10TX                    BIT(4)
-+#define   MTK_PHY_LED_10RX                    BIT(5)
-+#define   MTK_PHY_LED_COLLISION                       BIT(6)
-+#define   MTK_PHY_LED_RX_CRC_ERR              BIT(7)
-+#define   MTK_PHY_LED_RX_IDLE_ERR             BIT(8)
-+#define   MTK_PHY_LED_FORCE_BLINK             BIT(9)
-+
- #define MTK_PHY_RG_BG_RASEL                   0x115
- #define   MTK_PHY_RG_BG_RASEL_MASK            GENMASK(2, 0)
-+/* Register in boottrap syscon defining the initial state of the 4 PHY LEDs */
-+#define RG_GPIO_MISC_TPBANK0                  0x6f0
-+#define   RG_GPIO_MISC_TPBANK0_BOOTMODE               GENMASK(11, 8)
-+
- /* These macro privides efuse parsing for internal phy. */
- #define EFS_DA_TX_I2MPB_A(x)                  (((x) >> 0) & GENMASK(5, 0))
- #define EFS_DA_TX_I2MPB_B(x)                  (((x) >> 6) & GENMASK(5, 0))
-@@ -238,13 +271,6 @@ enum {
-       PAIR_D,
- };
--enum {
--      GPHY_PORT0,
--      GPHY_PORT1,
--      GPHY_PORT2,
--      GPHY_PORT3,
--};
--
- enum calibration_mode {
-       EFUSE_K,
-       SW_K
-@@ -263,6 +289,10 @@ enum CAL_MODE {
-       SW_M
- };
-+struct mtk_socphy_shared {
-+      u32                     boottrap;
-+};
-+
- static int mtk_socphy_read_page(struct phy_device *phydev)
- {
-       return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
-@@ -1073,6 +1103,104 @@ static int mt798x_phy_config_init(struct
-       return mt798x_phy_calibration(phydev);
- }
-+static int mt798x_phy_setup_led(struct phy_device *phydev, bool inverted)
-+{
-+      struct pinctrl *pinctrl;
-+      const u16 led_on_ctrl_defaults = MTK_PHY_LED_ENABLE      |
-+                                       MTK_PHY_LED_ON_LINK1000 |
-+                                       MTK_PHY_LED_ON_LINK100  |
-+                                       MTK_PHY_LED_ON_LINK10;
-+      const u16 led_blink_defaults = MTK_PHY_LED_1000TX |
-+                                     MTK_PHY_LED_1000RX |
-+                                     MTK_PHY_LED_100TX  |
-+                                     MTK_PHY_LED_100RX  |
-+                                     MTK_PHY_LED_10TX   |
-+                                     MTK_PHY_LED_10RX;
-+
-+      phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
-+                    led_on_ctrl_defaults ^
-+                    (inverted ? MTK_PHY_LED_POLARITY : 0));
-+
-+      phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL,
-+                    led_on_ctrl_defaults);
-+
-+      phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_BLINK_CTRL,
-+                    led_blink_defaults);
-+
-+      phy_write_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_BLINK_CTRL,
-+                    led_blink_defaults);
-+
-+      pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
-+      if (IS_ERR(pinctrl))
-+              dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED\n");
-+
-+      return 0;
-+}
-+
-+static int mt7988_phy_probe_shared(struct phy_device *phydev)
-+{
-+      struct device_node *np = dev_of_node(&phydev->mdio.bus->dev);
-+      struct mtk_socphy_shared *priv = phydev->shared->priv;
-+      struct regmap *regmap;
-+      u32 reg;
-+      int ret;
-+
-+      /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B,
-+       * LED_C and LED_D respectively. At the same time those pins are used to
-+       * bootstrap configuration of the reference clock source (LED_A),
-+       * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
-+       * In practise this is done using a LED and a resistor pulling the pin
-+       * either to GND or to VIO.
-+       * The detected value at boot time is accessible at run-time using the
-+       * TPBANK0 register located in the gpio base of the pinctrl, in order
-+       * to read it here it needs to be referenced by a phandle called
-+       * 'mediatek,pio' in the MDIO bus hosting the PHY.
-+       * The 4 bits in TPBANK0 are kept as package shared data and are used to
-+       * set LED polarity for each of the LED0.
-+       */
-+      regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio");
-+      if (IS_ERR(regmap))
-+              return PTR_ERR(regmap);
-+
-+      ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, &reg);
-+      if (ret)
-+              return ret;
-+
-+      priv->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg);
-+
-+      return 0;
-+}
-+
-+static bool mt7988_phy_get_boottrap_polarity(struct phy_device *phydev)
-+{
-+      struct mtk_socphy_shared *priv = phydev->shared->priv;
-+
-+      if (priv->boottrap & BIT(phydev->mdio.addr))
-+              return false;
-+
-+      return true;
-+}
-+
-+static int mt7988_phy_probe(struct phy_device *phydev)
-+{
-+      int err;
-+
-+      err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0,
-+                                  sizeof(struct mtk_socphy_shared));
-+      if (err)
-+              return err;
-+
-+      if (phy_package_probe_once(phydev)) {
-+              err = mt7988_phy_probe_shared(phydev);
-+              if (err)
-+                      return err;
-+      }
-+
-+      mt798x_phy_setup_led(phydev, mt7988_phy_get_boottrap_polarity(phydev));
-+
-+      return mt798x_phy_calibration(phydev);
-+}
-+
- static struct phy_driver mtk_socphy_driver[] = {
-       {
-               PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
-@@ -1092,7 +1220,7 @@ static struct phy_driver mtk_socphy_driv
-               .config_init    = mt798x_phy_config_init,
-               .config_intr    = genphy_no_config_intr,
-               .handle_interrupt = genphy_handle_interrupt_no_ack,
--              .probe          = mt798x_phy_calibration,
-+              .probe          = mt7988_phy_probe,
-               .suspend        = genphy_suspend,
-               .resume         = genphy_resume,
-               .read_page      = mtk_socphy_read_page,
diff --git a/target/linux/mediatek/patches-6.1/731-v6.5-net-phy-mediatek-ge-soc-support-PHY-LEDs.patch b/target/linux/mediatek/patches-6.1/731-v6.5-net-phy-mediatek-ge-soc-support-PHY-LEDs.patch
new file mode 100644 (file)
index 0000000..286ce96
--- /dev/null
@@ -0,0 +1,524 @@
+From c66937b0f8dbb4c6c043663c702b1053fb47fab2 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Mon, 14 Aug 2023 02:58:14 +0100
+Subject: [PATCH] net: phy: mediatek-ge-soc: support PHY LEDs
+
+Implement netdev trigger and primitive bliking offloading as well as
+simple set_brigthness function for both PHY LEDs of the in-SoC PHYs
+found in MT7981 and MT7988.
+
+For MT7988, read boottrap register and apply LED polarities accordingly
+to get uniform behavior from all LEDs on MT7988.
+This requires syscon phandle 'mediatek,pio' present in parenting MDIO bus
+which should point to the syscon holding the boottrap register.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://lore.kernel.org/r/dc324d48c00cd7350f3a506eaa785324cae97372.1691977904.git.daniel@makrotopia.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/mediatek-ge-soc.c | 435 +++++++++++++++++++++++++++++-
+ 1 file changed, 426 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/phy/mediatek-ge-soc.c
++++ b/drivers/net/phy/mediatek-ge-soc.c
+@@ -1,11 +1,14 @@
+ // SPDX-License-Identifier: GPL-2.0+
+ #include <linux/bitfield.h>
++#include <linux/bitmap.h>
++#include <linux/mfd/syscon.h>
+ #include <linux/module.h>
+ #include <linux/nvmem-consumer.h>
+ #include <linux/of_address.h>
+ #include <linux/of_platform.h>
+ #include <linux/pinctrl/consumer.h>
+ #include <linux/phy.h>
++#include <linux/regmap.h>
+ #define MTK_GPHY_ID_MT7981                    0x03a29461
+ #define MTK_GPHY_ID_MT7988                    0x03a29481
+@@ -208,9 +211,42 @@
+ #define MTK_PHY_DA_TX_R50_PAIR_C              0x53f
+ #define MTK_PHY_DA_TX_R50_PAIR_D              0x540
++/* Registers on MDIO_MMD_VEND2 */
++#define MTK_PHY_LED0_ON_CTRL                  0x24
++#define MTK_PHY_LED1_ON_CTRL                  0x26
++#define   MTK_PHY_LED_ON_MASK                 GENMASK(6, 0)
++#define   MTK_PHY_LED_ON_LINK1000             BIT(0)
++#define   MTK_PHY_LED_ON_LINK100              BIT(1)
++#define   MTK_PHY_LED_ON_LINK10                       BIT(2)
++#define   MTK_PHY_LED_ON_LINKDOWN             BIT(3)
++#define   MTK_PHY_LED_ON_FDX                  BIT(4) /* Full duplex */
++#define   MTK_PHY_LED_ON_HDX                  BIT(5) /* Half duplex */
++#define   MTK_PHY_LED_ON_FORCE_ON             BIT(6)
++#define   MTK_PHY_LED_ON_POLARITY             BIT(14)
++#define   MTK_PHY_LED_ON_ENABLE                       BIT(15)
++
++#define MTK_PHY_LED0_BLINK_CTRL                       0x25
++#define MTK_PHY_LED1_BLINK_CTRL                       0x27
++#define   MTK_PHY_LED_BLINK_1000TX            BIT(0)
++#define   MTK_PHY_LED_BLINK_1000RX            BIT(1)
++#define   MTK_PHY_LED_BLINK_100TX             BIT(2)
++#define   MTK_PHY_LED_BLINK_100RX             BIT(3)
++#define   MTK_PHY_LED_BLINK_10TX              BIT(4)
++#define   MTK_PHY_LED_BLINK_10RX              BIT(5)
++#define   MTK_PHY_LED_BLINK_COLLISION         BIT(6)
++#define   MTK_PHY_LED_BLINK_RX_CRC_ERR                BIT(7)
++#define   MTK_PHY_LED_BLINK_RX_IDLE_ERR               BIT(8)
++#define   MTK_PHY_LED_BLINK_FORCE_BLINK               BIT(9)
++
++#define MTK_PHY_LED1_DEFAULT_POLARITIES               BIT(1)
++
+ #define MTK_PHY_RG_BG_RASEL                   0x115
+ #define   MTK_PHY_RG_BG_RASEL_MASK            GENMASK(2, 0)
++/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */
++#define RG_GPIO_MISC_TPBANK0                  0x6f0
++#define   RG_GPIO_MISC_TPBANK0_BOOTMODE               GENMASK(11, 8)
++
+ /* These macro privides efuse parsing for internal phy. */
+ #define EFS_DA_TX_I2MPB_A(x)                  (((x) >> 0) & GENMASK(5, 0))
+ #define EFS_DA_TX_I2MPB_B(x)                  (((x) >> 6) & GENMASK(5, 0))
+@@ -238,13 +274,6 @@ enum {
+       PAIR_D,
+ };
+-enum {
+-      GPHY_PORT0,
+-      GPHY_PORT1,
+-      GPHY_PORT2,
+-      GPHY_PORT3,
+-};
+-
+ enum calibration_mode {
+       EFUSE_K,
+       SW_K
+@@ -263,6 +292,19 @@ enum CAL_MODE {
+       SW_M
+ };
++#define MTK_PHY_LED_STATE_FORCE_ON    0
++#define MTK_PHY_LED_STATE_FORCE_BLINK 1
++#define MTK_PHY_LED_STATE_NETDEV      2
++
++struct mtk_socphy_priv {
++      unsigned long           led_state;
++};
++
++struct mtk_socphy_shared {
++      u32                     boottrap;
++      struct mtk_socphy_priv  priv[4];
++};
++
+ static int mtk_socphy_read_page(struct phy_device *phydev)
+ {
+       return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+@@ -1073,6 +1115,371 @@ static int mt798x_phy_config_init(struct
+       return mt798x_phy_calibration(phydev);
+ }
++static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index,
++                                  bool on)
++{
++      unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
++      struct mtk_socphy_priv *priv = phydev->priv;
++      bool changed;
++
++      if (on)
++              changed = !test_and_set_bit(bit_on, &priv->led_state);
++      else
++              changed = !!test_and_clear_bit(bit_on, &priv->led_state);
++
++      changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV +
++                                      (index ? 16 : 0), &priv->led_state);
++      if (changed)
++              return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++                                    MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
++                                    MTK_PHY_LED_ON_MASK,
++                                    on ? MTK_PHY_LED_ON_FORCE_ON : 0);
++      else
++              return 0;
++}
++
++static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index,
++                                     bool blinking)
++{
++      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
++      struct mtk_socphy_priv *priv = phydev->priv;
++      bool changed;
++
++      if (blinking)
++              changed = !test_and_set_bit(bit_blink, &priv->led_state);
++      else
++              changed = !!test_and_clear_bit(bit_blink, &priv->led_state);
++
++      changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV +
++                            (index ? 16 : 0), &priv->led_state);
++      if (changed)
++              return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
++                                   MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL,
++                                   blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0);
++      else
++              return 0;
++}
++
++static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index,
++                                  unsigned long *delay_on,
++                                  unsigned long *delay_off)
++{
++      bool blinking = false;
++      int err = 0;
++
++      if (index > 1)
++              return -EINVAL;
++
++      if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) {
++              blinking = true;
++              *delay_on = 50;
++              *delay_off = 50;
++      }
++
++      err = mt798x_phy_hw_led_blink_set(phydev, index, blinking);
++      if (err)
++              return err;
++
++      return mt798x_phy_hw_led_on_set(phydev, index, false);
++}
++
++static int mt798x_phy_led_brightness_set(struct phy_device *phydev,
++                                       u8 index, enum led_brightness value)
++{
++      int err;
++
++      err = mt798x_phy_hw_led_blink_set(phydev, index, false);
++      if (err)
++              return err;
++
++      return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF));
++}
++
++static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) |
++                                               BIT(TRIGGER_NETDEV_HALF_DUPLEX) |
++                                               BIT(TRIGGER_NETDEV_LINK)        |
++                                               BIT(TRIGGER_NETDEV_LINK_10)     |
++                                               BIT(TRIGGER_NETDEV_LINK_100)    |
++                                               BIT(TRIGGER_NETDEV_LINK_1000)   |
++                                               BIT(TRIGGER_NETDEV_RX)          |
++                                               BIT(TRIGGER_NETDEV_TX));
++
++static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index,
++                                        unsigned long rules)
++{
++      if (index > 1)
++              return -EINVAL;
++
++      /* All combinations of the supported triggers are allowed */
++      if (rules & ~supported_triggers)
++              return -EOPNOTSUPP;
++
++      return 0;
++};
++
++static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index,
++                                       unsigned long *rules)
++{
++      unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0);
++      unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
++      unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0);
++      struct mtk_socphy_priv *priv = phydev->priv;
++      int on, blink;
++
++      if (index > 1)
++              return -EINVAL;
++
++      on = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++                        index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL);
++
++      if (on < 0)
++              return -EIO;
++
++      blink = phy_read_mmd(phydev, MDIO_MMD_VEND2,
++                           index ? MTK_PHY_LED1_BLINK_CTRL :
++                                   MTK_PHY_LED0_BLINK_CTRL);
++      if (blink < 0)
++              return -EIO;
++
++      if ((on & (MTK_PHY_LED_ON_LINK1000 | MTK_PHY_LED_ON_LINK100 |
++                 MTK_PHY_LED_ON_LINK10)) ||
++          (blink & (MTK_PHY_LED_BLINK_1000RX | MTK_PHY_LED_BLINK_100RX |
++                    MTK_PHY_LED_BLINK_10RX | MTK_PHY_LED_BLINK_1000TX |
++                    MTK_PHY_LED_BLINK_100TX | MTK_PHY_LED_BLINK_10TX)))
++              set_bit(bit_netdev, &priv->led_state);
++      else
++              clear_bit(bit_netdev, &priv->led_state);
++
++      if (on & MTK_PHY_LED_ON_FORCE_ON)
++              set_bit(bit_on, &priv->led_state);
++      else
++              clear_bit(bit_on, &priv->led_state);
++
++      if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK)
++              set_bit(bit_blink, &priv->led_state);
++      else
++              clear_bit(bit_blink, &priv->led_state);
++
++      if (!rules)
++              return 0;
++
++      if (on & (MTK_PHY_LED_ON_LINK1000 | MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK10))
++              *rules |= BIT(TRIGGER_NETDEV_LINK);
++
++      if (on & MTK_PHY_LED_ON_LINK10)
++              *rules |= BIT(TRIGGER_NETDEV_LINK_10);
++
++      if (on & MTK_PHY_LED_ON_LINK100)
++              *rules |= BIT(TRIGGER_NETDEV_LINK_100);
++
++      if (on & MTK_PHY_LED_ON_LINK1000)
++              *rules |= BIT(TRIGGER_NETDEV_LINK_1000);
++
++      if (on & MTK_PHY_LED_ON_FDX)
++              *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX);
++
++      if (on & MTK_PHY_LED_ON_HDX)
++              *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX);
++
++      if (blink & (MTK_PHY_LED_BLINK_1000RX | MTK_PHY_LED_BLINK_100RX | MTK_PHY_LED_BLINK_10RX))
++              *rules |= BIT(TRIGGER_NETDEV_RX);
++
++      if (blink & (MTK_PHY_LED_BLINK_1000TX | MTK_PHY_LED_BLINK_100TX | MTK_PHY_LED_BLINK_10TX))
++              *rules |= BIT(TRIGGER_NETDEV_TX);
++
++      return 0;
++};
++
++static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index,
++                                       unsigned long rules)
++{
++      unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0);
++      struct mtk_socphy_priv *priv = phydev->priv;
++      u16 on = 0, blink = 0;
++      int ret;
++
++      if (index > 1)
++              return -EINVAL;
++
++      if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX))
++              on |= MTK_PHY_LED_ON_FDX;
++
++      if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX))
++              on |= MTK_PHY_LED_ON_HDX;
++
++      if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK)))
++              on |= MTK_PHY_LED_ON_LINK10;
++
++      if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK)))
++              on |= MTK_PHY_LED_ON_LINK100;
++
++      if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK)))
++              on |= MTK_PHY_LED_ON_LINK1000;
++
++      if (rules & BIT(TRIGGER_NETDEV_RX)) {
++              blink |= MTK_PHY_LED_BLINK_10RX  |
++                       MTK_PHY_LED_BLINK_100RX |
++                       MTK_PHY_LED_BLINK_1000RX;
++      }
++
++      if (rules & BIT(TRIGGER_NETDEV_TX)) {
++              blink |= MTK_PHY_LED_BLINK_10TX  |
++                       MTK_PHY_LED_BLINK_100TX |
++                       MTK_PHY_LED_BLINK_1000TX;
++      }
++
++      if (blink || on)
++              set_bit(bit_netdev, &priv->led_state);
++      else
++              clear_bit(bit_netdev, &priv->led_state);
++
++      ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++                              MTK_PHY_LED1_ON_CTRL :
++                              MTK_PHY_LED0_ON_CTRL,
++                           MTK_PHY_LED_ON_FDX     |
++                           MTK_PHY_LED_ON_HDX     |
++                           MTK_PHY_LED_ON_LINK10  |
++                           MTK_PHY_LED_ON_LINK100 |
++                           MTK_PHY_LED_ON_LINK1000,
++                           on);
++
++      if (ret)
++              return ret;
++
++      return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ?
++                              MTK_PHY_LED1_BLINK_CTRL :
++                              MTK_PHY_LED0_BLINK_CTRL, blink);
++};
++
++static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num)
++{
++      struct mtk_socphy_shared *priv = phydev->shared->priv;
++      u32 polarities;
++
++      if (led_num == 0)
++              polarities = ~(priv->boottrap);
++      else
++              polarities = MTK_PHY_LED1_DEFAULT_POLARITIES;
++
++      if (polarities & BIT(phydev->mdio.addr))
++              return true;
++
++      return false;
++}
++
++static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev)
++{
++      struct pinctrl *pinctrl;
++      int index;
++
++      /* Setup LED polarity according to bootstrap use of LED pins */
++      for (index = 0; index < 2; ++index)
++              phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ?
++                              MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL,
++                             MTK_PHY_LED_ON_POLARITY,
++                             mt7988_phy_led_get_polarity(phydev, index) ?
++                              MTK_PHY_LED_ON_POLARITY : 0);
++
++      /* Only now setup pinctrl to avoid bogus blinking */
++      pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led");
++      if (IS_ERR(pinctrl))
++              dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n");
++
++      return 0;
++}
++
++static int mt7988_phy_probe_shared(struct phy_device *phydev)
++{
++      struct device_node *np = dev_of_node(&phydev->mdio.bus->dev);
++      struct mtk_socphy_shared *shared = phydev->shared->priv;
++      struct regmap *regmap;
++      u32 reg;
++      int ret;
++
++      /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B,
++       * LED_C and LED_D respectively. At the same time those pins are used to
++       * bootstrap configuration of the reference clock source (LED_A),
++       * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D).
++       * In practise this is done using a LED and a resistor pulling the pin
++       * either to GND or to VIO.
++       * The detected value at boot time is accessible at run-time using the
++       * TPBANK0 register located in the gpio base of the pinctrl, in order
++       * to read it here it needs to be referenced by a phandle called
++       * 'mediatek,pio' in the MDIO bus hosting the PHY.
++       * The 4 bits in TPBANK0 are kept as package shared data and are used to
++       * set LED polarity for each of the LED0.
++       */
++      regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio");
++      if (IS_ERR(regmap))
++              return PTR_ERR(regmap);
++
++      ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, &reg);
++      if (ret)
++              return ret;
++
++      shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg);
++
++      return 0;
++}
++
++static void mt798x_phy_leds_state_init(struct phy_device *phydev)
++{
++      int i;
++
++      for (i = 0; i < 2; ++i)
++              mt798x_phy_led_hw_control_get(phydev, i, NULL);
++}
++
++static int mt7988_phy_probe(struct phy_device *phydev)
++{
++      struct mtk_socphy_shared *shared;
++      struct mtk_socphy_priv *priv;
++      int err;
++
++      if (phydev->mdio.addr > 3)
++              return -EINVAL;
++
++      err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0,
++                                  sizeof(struct mtk_socphy_shared));
++      if (err)
++              return err;
++
++      if (phy_package_probe_once(phydev)) {
++              err = mt7988_phy_probe_shared(phydev);
++              if (err)
++                      return err;
++      }
++
++      shared = phydev->shared->priv;
++      priv = &shared->priv[phydev->mdio.addr];
++
++      phydev->priv = priv;
++
++      mt798x_phy_leds_state_init(phydev);
++
++      err = mt7988_phy_fix_leds_polarities(phydev);
++      if (err)
++              return err;
++
++      return mt798x_phy_calibration(phydev);
++}
++
++static int mt7981_phy_probe(struct phy_device *phydev)
++{
++      struct mtk_socphy_priv *priv;
++
++      priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv),
++                          GFP_KERNEL);
++      if (!priv)
++              return -ENOMEM;
++
++      phydev->priv = priv;
++
++      mt798x_phy_leds_state_init(phydev);
++
++      return mt798x_phy_calibration(phydev);
++}
++
+ static struct phy_driver mtk_socphy_driver[] = {
+       {
+               PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981),
+@@ -1080,11 +1487,16 @@ static struct phy_driver mtk_socphy_driv
+               .config_init    = mt798x_phy_config_init,
+               .config_intr    = genphy_no_config_intr,
+               .handle_interrupt = genphy_handle_interrupt_no_ack,
+-              .probe          = mt798x_phy_calibration,
++              .probe          = mt7981_phy_probe,
+               .suspend        = genphy_suspend,
+               .resume         = genphy_resume,
+               .read_page      = mtk_socphy_read_page,
+               .write_page     = mtk_socphy_write_page,
++              .led_blink_set  = mt798x_phy_led_blink_set,
++              .led_brightness_set = mt798x_phy_led_brightness_set,
++              .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
++              .led_hw_control_set = mt798x_phy_led_hw_control_set,
++              .led_hw_control_get = mt798x_phy_led_hw_control_get,
+       },
+       {
+               PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988),
+@@ -1092,11 +1504,16 @@ static struct phy_driver mtk_socphy_driv
+               .config_init    = mt798x_phy_config_init,
+               .config_intr    = genphy_no_config_intr,
+               .handle_interrupt = genphy_handle_interrupt_no_ack,
+-              .probe          = mt798x_phy_calibration,
++              .probe          = mt7988_phy_probe,
+               .suspend        = genphy_suspend,
+               .resume         = genphy_resume,
+               .read_page      = mtk_socphy_read_page,
+               .write_page     = mtk_socphy_write_page,
++              .led_blink_set  = mt798x_phy_led_blink_set,
++              .led_brightness_set = mt798x_phy_led_brightness_set,
++              .led_hw_is_supported = mt798x_phy_led_hw_is_supported,
++              .led_hw_control_set = mt798x_phy_led_hw_control_set,
++              .led_hw_control_get = mt798x_phy_led_hw_control_get,
+       },
+ };
index fb3940f5447f702c0962c90fdc1a8f95645166cd..209580d64a4541f3c6f919cc01dfaced46b33ee5 100644 (file)
@@ -22,7 +22,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
 
 --- a/drivers/net/ethernet/mediatek/mtk_wed.c
 +++ b/drivers/net/ethernet/mediatek/mtk_wed.c
-@@ -806,6 +806,24 @@ mtk_wed_rro_alloc(struct mtk_wed_device
+@@ -814,6 +814,24 @@ mtk_wed_rro_alloc(struct mtk_wed_device
        struct device_node *np;
        int index;
  
@@ -47,7 +47,7 @@ Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
        index = of_property_match_string(dev->hw->node, "memory-region-names",
                                         "wo-dlm");
        if (index < 0)
-@@ -822,6 +840,7 @@ mtk_wed_rro_alloc(struct mtk_wed_device
+@@ -830,6 +848,7 @@ mtk_wed_rro_alloc(struct mtk_wed_device
                return -ENODEV;
  
        dev->rro.miod_phys = rmem->base;
index fce5fc856f49bc9d91c4e2dfd1fea84b26d2912f..c458237f3902e83c2a064d78621219ed611ff7e3 100644 (file)
@@ -14,7 +14,7 @@ Signed-off-by: RenĂ© van Dorst <opensource@vdorst.com>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -4615,6 +4615,7 @@ static const struct net_device_ops mtk_n
+@@ -4553,6 +4553,7 @@ static const struct net_device_ops mtk_n
  
  static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
  {
@@ -22,7 +22,7 @@ Signed-off-by: RenĂ© van Dorst <opensource@vdorst.com>
        const __be32 *_id = of_get_property(np, "reg", NULL);
        phy_interface_t phy_mode;
        struct phylink *phylink;
-@@ -4784,6 +4785,9 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -4724,6 +4725,9 @@ static int mtk_add_mac(struct mtk_eth *e
                register_netdevice_notifier(&mac->device_notifier);
        }
  
index 87f319abb561309fb20bcb2486e6307e4309da25..b8461b0030ce160d999b7a26c5136bd0ccf2a27b 100644 (file)
@@ -95,7 +95,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
                phydev->mii_ts->link_state(phydev->mii_ts, phydev);
 --- a/drivers/net/phy/phylink.c
 +++ b/drivers/net/phy/phylink.c
-@@ -1322,7 +1322,8 @@ void phylink_destroy(struct phylink *pl)
+@@ -1369,7 +1369,8 @@ void phylink_destroy(struct phylink *pl)
  }
  EXPORT_SYMBOL_GPL(phylink_destroy);
  
index 591f0cea13a3f1ff3489791929e234a4acabc7cf..183c9dda2fdae1f09621c0068f49a82557b52589 100644 (file)
@@ -21,7 +21,7 @@ Submitted-by: John Crispin <john@phrozen.org>
 
 --- a/drivers/net/phy/phylink.c
 +++ b/drivers/net/phy/phylink.c
-@@ -1942,6 +1942,11 @@ int phylink_ethtool_ksettings_set(struct
+@@ -1990,6 +1990,11 @@ int phylink_ethtool_ksettings_set(struct
                 *   the presence of a PHY, this should not be changed as that
                 *   should be determined from the media side advertisement.
                 */
@@ -33,7 +33,7 @@ Submitted-by: John Crispin <john@phrozen.org>
                return phy_ethtool_ksettings_set(pl->phydev, kset);
        }
  
-@@ -2245,8 +2250,11 @@ int phylink_ethtool_get_eee(struct phyli
+@@ -2293,8 +2298,11 @@ int phylink_ethtool_get_eee(struct phyli
  
        ASSERT_RTNL();
  
@@ -46,7 +46,7 @@ Submitted-by: John Crispin <john@phrozen.org>
  
        return ret;
  }
-@@ -2263,8 +2271,11 @@ int phylink_ethtool_set_eee(struct phyli
+@@ -2311,8 +2319,11 @@ int phylink_ethtool_set_eee(struct phyli
  
        ASSERT_RTNL();
  
index f9411e47d32477cc4af00eb813756cb4f969bcdf..2048e22f2e5abaaa86cee9ad0bf33f05d217a026 100644 (file)
@@ -15,7 +15,7 @@ Submitted-by: Birger Koblitz <git@birger-koblitz.de>
 
 --- a/drivers/net/phy/phylink.c
 +++ b/drivers/net/phy/phylink.c
-@@ -403,6 +403,7 @@ void phylink_get_linkmodes(unsigned long
+@@ -408,6 +408,7 @@ void phylink_get_linkmodes(unsigned long
  
        case PHY_INTERFACE_MODE_XGMII:
        case PHY_INTERFACE_MODE_RXAUI:
@@ -23,7 +23,7 @@ Submitted-by: Birger Koblitz <git@birger-koblitz.de>
        case PHY_INTERFACE_MODE_XAUI:
        case PHY_INTERFACE_MODE_10GBASER:
        case PHY_INTERFACE_MODE_10GKR:
-@@ -657,6 +658,7 @@ static int phylink_parse_mode(struct phy
+@@ -662,6 +663,7 @@ static int phylink_parse_mode(struct phy
                        fallthrough;
                case PHY_INTERFACE_MODE_USXGMII:
                case PHY_INTERFACE_MODE_10GKR: