| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/04 11:39 | flow | patch-triage |
1mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch adds support for the MediaTek MT7628 Embedded Ethernet Switch, including a platform driver, a PHY driver, and a DSA tag driver. The platform driver requires specific MMIO resources and reset controllers that are not present in virtualized environments (QEMU/GCE). The PHY driver requires an MDIO bus with a specific hardware PHY ID. The DSA tag driver can only be reached if a DSA switch is configured to use the MT7628 tag protocol. The only mock DSA switch available in virtualized environments (dsa_loop) does not support changing its tag protocol at runtime. Therefore, the modified code paths are impossible to reach in a virtualized environment.",
"WorthFuzzing": false
} |
| 1/1 | 2026/07/04 11:39 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 2959f8ac93ddc43dc10b0b2333c877b861015334\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Sat Jul 4 11:39:25 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7628-esw.yaml b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7628-esw.yaml\nnew file mode 100644\nindex 00000000000000..e0e7ffef66482c\n--- /dev/null\n+++ b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7628-esw.yaml\n@@ -0,0 +1,96 @@\n+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)\n+%YAML 1.2\n+---\n+$id: http://devicetree.org/schemas/net/dsa/mediatek,mt7628-esw.yaml#\n+$schema: http://devicetree.org/meta-schemas/core.yaml#\n+\n+title: Mediatek MT7628 Embedded Ethernet Switch\n+\n+maintainers:\n+ - Joris Vaisvila \u003cjoey@tinyisr.com\u003e\n+\n+description:\n+ The MT7628 SoC's built-in Ethernet Switch has five user ports and one\n+ internally connected CPU port. The user ports are all connected to the SoC's\n+ integrated Fast Ethernet PHYs. The switch registers are directly mapped in\n+ the SoC's memory.\n+\n+allOf:\n+ - $ref: dsa.yaml#/$defs/ethernet-ports\n+\n+properties:\n+ compatible:\n+ const: mediatek,mt7628-esw\n+\n+ reg:\n+ maxItems: 1\n+\n+ resets:\n+ items:\n+ - description: internal switch block reset\n+ - description: internal phy package reset\n+\n+ reset-names:\n+ items:\n+ - const: esw\n+ - const: ephy\n+\n+required:\n+ - compatible\n+ - reg\n+ - resets\n+ - reset-names\n+ - ethernet-ports\n+\n+unevaluatedProperties: false\n+\n+examples:\n+ - |\n+ switch@10110000 {\n+ compatible = \"mediatek,mt7628-esw\";\n+ reg = \u003c0x10110000 0x8000\u003e;\n+\n+ resets = \u003c\u0026sysc 23\u003e, \u003c\u0026sysc 24\u003e;\n+ reset-names = \"esw\", \"ephy\";\n+\n+ ethernet-ports {\n+ #address-cells = \u003c1\u003e;\n+ #size-cells = \u003c0\u003e;\n+\n+ ethernet-port@0 {\n+ reg = \u003c0\u003e;\n+ phy-mode = \"internal\";\n+ };\n+\n+ ethernet-port@1 {\n+ reg = \u003c1\u003e;\n+ phy-mode = \"internal\";\n+ };\n+\n+ ethernet-port@2 {\n+ reg = \u003c2\u003e;\n+ phy-mode = \"internal\";\n+ };\n+\n+ ethernet-port@3 {\n+ reg = \u003c3\u003e;\n+ phy-mode = \"internal\";\n+ };\n+\n+ ethernet-port@4 {\n+ reg = \u003c4\u003e;\n+ phy-mode = \"internal\";\n+ };\n+\n+ ethernet-port@6 {\n+ reg = \u003c6\u003e;\n+ phy-mode = \"internal\";\n+ ethernet = \u003c\u0026ethernet\u003e;\n+\n+ fixed-link {\n+ speed = \u003c1000\u003e;\n+ full-duplex;\n+ };\n+ };\n+ };\n+ };\ndiff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig\nindex 4ab567c5bbafc6..daa1d3d4ba609e 100644\n--- a/drivers/net/dsa/Kconfig\n+++ b/drivers/net/dsa/Kconfig\n@@ -63,6 +63,14 @@ config NET_DSA_MT7530_MMIO\n \t are directly mapped into the SoCs register space rather than being\n \t accessible via MDIO.\n \n+config NET_DSA_MT7628\n+\ttristate \"MediaTek MT7628 Embedded Ethernet switch support\"\n+\tselect NET_DSA_TAG_MT7628\n+\tselect MEDIATEK_FE_SOC_PHY\n+\thelp\n+\t This enables support for the built-in Ethernet switch found\n+\t in the MT7628 SoC.\n+\n config NET_DSA_MV88E6060\n \ttristate \"Marvell 88E6060 ethernet switch chip support\"\n \tselect NET_DSA_TAG_TRAILER\ndiff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile\nindex d2975badffc093..6ceb78a755d777 100644\n--- a/drivers/net/dsa/Makefile\n+++ b/drivers/net/dsa/Makefile\n@@ -6,6 +6,7 @@ obj-$(CONFIG_NET_DSA_KS8995) \t+= ks8995.o\n obj-$(CONFIG_NET_DSA_MT7530)\t+= mt7530.o\n obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o\n obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o\n+obj-$(CONFIG_NET_DSA_MT7628) += mt7628.o\n obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o\n obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o\n obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o\ndiff --git a/drivers/net/dsa/mt7628.c b/drivers/net/dsa/mt7628.c\nnew file mode 100644\nindex 00000000000000..eccdb05fce9b71\n--- /dev/null\n+++ b/drivers/net/dsa/mt7628.c\n@@ -0,0 +1,649 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/*\n+ * Mediatek MT7628 Embedded Switch (ESW) DSA driver\n+ * Copyright (C) 2026 Joris Vaisvila \u003cjoey@tinyisr.com\u003e\n+ *\n+ * Portions derived from OpenWRT esw_rt3050 driver:\n+ * Copyright (C) 2009-2015 John Crispin \u003cblogic@openwrt.org\u003e\n+ * Copyright (C) 2009-2015 Felix Fietkau \u003cnbd@nbd.name\u003e\n+ * Copyright (C) 2013-2015 Michael Lee \u003cigvtee@gmail.com\u003e\n+ * Copyright (C) 2016 Vittorio Gambaletta \u003copenwrt@vittgam.net\u003e\n+ */\n+\n+#include \u003clinux/platform_device.h\u003e\n+#include \u003clinux/etherdevice.h\u003e\n+#include \u003clinux/netdevice.h\u003e\n+#include \u003clinux/dsa/8021q.h\u003e\n+#include \u003clinux/if_bridge.h\u003e\n+#include \u003clinux/module.h\u003e\n+#include \u003clinux/mdio.h\u003e\n+#include \u003clinux/of.h\u003e\n+#include \u003clinux/of_mdio.h\u003e\n+#include \u003clinux/of_net.h\u003e\n+#include \u003clinux/kernel.h\u003e\n+#include \u003clinux/regmap.h\u003e\n+#include \u003clinux/reset.h\u003e\n+#include \u003cnet/dsa.h\u003e\n+\n+#define MT7628_ESW_REG_IMR 0x04\n+#define MT7628_ESW_REG_FCT0 0x08\n+#define MT7628_ESW_REG_PFC1 0x14\n+#define MT7628_ESW_REG_PVIDC(port) (0x40 + 4 * ((port) / 2))\n+#define MT7628_ESW_REG_VLANI(vlan) (0x50 + 4 * ((vlan) / 2))\n+#define MT7628_ESW_REG_VMSC(vlan) (0x70 + 4 * ((vlan) / 4))\n+#define MT7628_ESW_REG_VUB(vlan) (0x100 + 4 * ((vlan) / 4))\n+#define MT7628_ESW_REG_SOCPC 0x8c\n+#define MT7628_ESW_REG_POC0 0x90\n+#define MT7628_ESW_REG_POC2 0x98\n+#define MT7628_ESW_REG_SGC 0x9c\n+#define MT7628_ESW_REG_PCR0 0xc0\n+#define MT7628_ESW_REG_PCR1 0xc4\n+#define MT7628_ESW_REG_FPA2 0xc8\n+#define MT7628_ESW_REG_FCT2 0xcc\n+#define MT7628_ESW_REG_SGC2 0xe4\n+\n+#define MT7628_ESW_FCT0_DROP_SET_TH GENMASK(7, 0)\n+#define MT7628_ESW_FCT0_DROP_RLS_TH GENMASK(15, 8)\n+#define MT7628_ESW_FCT0_FC_SET_TH GENMASK(23, 16)\n+#define MT7628_ESW_FCT0_FC_RLS_TH GENMASK(31, 24)\n+\n+#define MT7628_ESW_PFC1_EN_VLAN GENMASK(22, 16)\n+\n+#define MT7628_ESW_PVID_S 12\n+#define MT7628_ESW_PVID_M GENMASK(11, 0)\n+#define MT7628_ESW_PVID_SHIFT(port) \\\n+\t(MT7628_ESW_PVID_S * ((port) % 2))\n+#define MT7628_ESW_PVID_MASK(port) \\\n+\t(MT7628_ESW_PVID_M \u003c\u003c MT7628_ESW_PVID_SHIFT(port))\n+#define MT7628_ESW_PVID_PREP(port, pvid) \\\n+\t(((pvid) \u0026 MT7628_ESW_PVID_M) \u003c\u003c MT7628_ESW_PVID_SHIFT(port))\n+\n+#define MT7628_ESW_VID_S 12\n+#define MT7628_ESW_VID_M GENMASK(11, 0)\n+#define MT7628_ESW_VID_SHIFT(vlan) \\\n+\t(MT7628_ESW_VID_S * ((vlan) % 2))\n+#define MT7628_ESW_VID_MASK(vlan) \\\n+\t(MT7628_ESW_VID_M \u003c\u003c MT7628_ESW_VID_SHIFT(vlan))\n+#define MT7628_ESW_VID_PREP(vlan, vid) \\\n+\t(((vid) \u0026 MT7628_ESW_VID_M) \u003c\u003c MT7628_ESW_VID_SHIFT(vlan))\n+\n+#define MT7628_ESW_VMSC_S 8\n+#define MT7628_ESW_VMSC_M GENMASK(7, 0)\n+#define MT7628_ESW_VMSC_SHIFT(vlan) \\\n+\t(MT7628_ESW_VMSC_S * ((vlan) % 4))\n+#define MT7628_ESW_VMSC_MASK(vlan) \\\n+\t(MT7628_ESW_VMSC_M \u003c\u003c MT7628_ESW_VMSC_SHIFT(vlan))\n+#define MT7628_ESW_VMSC_PREP(vlan, vmsc) \\\n+\t(((vmsc) \u0026 MT7628_ESW_VMSC_M) \u003c\u003c MT7628_ESW_VMSC_SHIFT(vlan))\n+\n+#define MT7628_ESW_VUB_S 7\n+#define MT7628_ESW_VUB_M GENMASK(6, 0)\n+#define MT7628_ESW_VUB_SHIFT(vlan) \\\n+\t(MT7628_ESW_VUB_S * ((vlan) % 4))\n+#define MT7628_ESW_VUB_MASK(vlan) \\\n+\t(MT7628_ESW_VUB_M \u003c\u003c MT7628_ESW_VUB_SHIFT(vlan))\n+#define MT7628_ESW_VUB_PREP(vlan, vub) \\\n+\t(((vub) \u0026 MT7628_ESW_VUB_M) \u003c\u003c MT7628_ESW_VUB_SHIFT(vlan))\n+\n+#define MT7628_ESW_SOCPC_CRC_PADDING BIT(25)\n+#define MT7628_ESW_SOCPC_DISBC2CPU GENMASK(22, 16)\n+#define MT7628_ESW_SOCPC_DISMC2CPU GENMASK(14, 8)\n+#define MT7628_ESW_SOCPC_DISUN2CPU GENMASK(6, 0)\n+\n+#define MT7628_ESW_POC0_PORT_DISABLE GENMASK(29, 23)\n+\n+#define MT7628_ESW_POC2_PER_VLAN_UNTAG_EN BIT(15)\n+\n+#define MT7628_ESW_SGC_AGING_INTERVAL GENMASK(3, 0)\n+#define MT7628_ESW_BC_STORM_PROT GENMASK(5, 4)\n+#define MT7628_ESW_PKT_MAX_LEN GENMASK(7, 6)\n+#define MT7628_ESW_DIS_PKT_ABORT BIT(8)\n+#define MT7628_ESW_ADDRESS_HASH_ALG GENMASK(10, 9)\n+#define MT7628_ESW_DISABLE_TX_BACKOFF BIT(11)\n+#define MT7628_ESW_BP_JAM_CNT GENMASK(15, 12)\n+#define MT7628_ESW_DISMIIPORT_WASTX GENMASK(17, 16)\n+#define MT7628_ESW_BP_MODE GENMASK(19, 18)\n+#define MT7628_ESW_BISH_DIS BIT(20)\n+#define MT7628_ESW_BISH_TH GENMASK(22, 21)\n+#define MT7628_ESW_LED_FLASH_TIME GENMASK(24, 23)\n+#define MT7628_ESW_RMC_RULE GENMASK(26, 25)\n+#define MT7628_ESW_IP_MULT_RULE GENMASK(28, 27)\n+#define MT7628_ESW_LEN_ERR_CHK BIT(29)\n+#define MT7628_ESW_BKOFF_ALG BIT(30)\n+\n+#define MT7628_ESW_PCR0_WT_NWAY_DATA GENMASK(31, 16)\n+#define MT7628_ESW_PCR0_RD_PHY_CMD BIT(14)\n+#define MT7628_ESW_PCR0_WT_PHY_CMD BIT(13)\n+#define MT7628_ESW_PCR0_CPU_PHY_REG GENMASK(12, 8)\n+#define MT7628_ESW_PCR0_CPU_PHY_ADDR GENMASK(4, 0)\n+\n+#define MT7628_ESW_PCR1_RD_DATA GENMASK(31, 16)\n+#define MT7628_ESW_PCR1_RD_DONE BIT(1)\n+#define MT7628_ESW_PCR1_WT_DONE BIT(0)\n+\n+#define MT7628_ESW_FPA2_AP_EN BIT(29)\n+#define MT7628_ESW_FPA2_EXT_PHY_ADDR_BASE GENMASK(28, 24)\n+#define MT7628_ESW_FPA2_FORCE_RGMII_LINK1 BIT(13)\n+#define MT7628_ESW_FPA2_FORCE_RGMII_EN1 BIT(11)\n+\n+#define MT7628_ESW_FCT2_MUST_DROP_RLS_TH GENMASK(17, 13)\n+#define MT7628_ESW_FCT2_MUST_DROP_SET_TH GENMASK(12, 8)\n+#define MT7628_ESW_FCT2_MC_PER_PORT_TH GENMASK(5, 0)\n+\n+#define MT7628_ESW_SGC2_SPECIAL_TAG_EN BIT(23)\n+#define MT7628_ESW_SGC2_TX_CPU_TPID_BIT_MAP GENMASK(22, 16)\n+#define MT7628_ESW_SGC2_DOUBLE_TAG_EN GENMASK(6, 0)\n+\n+#define MT7628_ESW_PORTS_NOCPU GENMASK(5, 0)\n+#define MT7628_ESW_PORTS_CPU BIT(6)\n+#define MT7628_ESW_PORTS_ALL GENMASK(6, 0)\n+\n+#define MT7628_ESW_NUM_PORTS 7\n+#define MT7628_NUM_VLANS 16\n+\n+static const struct regmap_config mt7628_esw_regmap_cfg = {\n+\t.name = \"mt7628-esw\",\n+\t.reg_bits = 32,\n+\t.val_bits = 32,\n+\t.reg_stride = 4,\n+\t.fast_io = true,\n+\t.reg_format_endian = REGMAP_ENDIAN_LITTLE,\n+\t.val_format_endian = REGMAP_ENDIAN_LITTLE,\n+};\n+\n+struct mt7628_vlan {\n+\tbool active;\n+\tu8 members;\n+\tu8 untag;\n+\tu16 vid;\n+};\n+\n+struct mt7628_esw {\n+\tstruct reset_control *rst_ephy;\n+\tstruct reset_control *rst_esw;\n+\tstruct regmap *regmap;\n+\tstruct dsa_switch *ds;\n+\tu16 tag_8021q_pvid[MT7628_ESW_NUM_PORTS];\n+\tstruct mt7628_vlan vlans[MT7628_NUM_VLANS];\n+\tstruct device *dev;\n+};\n+\n+static int mt7628_mii_read(struct mii_bus *bus, int port, int regnum)\n+{\n+\tstruct mt7628_esw *esw = bus-\u003epriv;\n+\tint ret;\n+\tu32 val;\n+\n+\t/*\n+\t * RD_DONE bit is read to clear. Read PCR1 once to acknowledge any\n+\t * stale completion indicator before starting a new transaction.\n+\t */\n+\tret = regmap_read(esw-\u003eregmap, MT7628_ESW_REG_PCR1, \u0026val);\n+\tif (ret)\n+\t\tgoto out;\n+\n+\tret = regmap_write(esw-\u003eregmap, MT7628_ESW_REG_PCR0,\n+\t\t\t FIELD_PREP(MT7628_ESW_PCR0_CPU_PHY_REG,\n+\t\t\t\t regnum) |\n+\t\t\t FIELD_PREP(MT7628_ESW_PCR0_CPU_PHY_ADDR,\n+\t\t\t\t port) | MT7628_ESW_PCR0_RD_PHY_CMD);\n+\tif (ret)\n+\t\tgoto out;\n+\n+\tret = regmap_read_poll_timeout(esw-\u003eregmap, MT7628_ESW_REG_PCR1, val,\n+\t\t\t\t (val \u0026 MT7628_ESW_PCR1_RD_DONE), 10,\n+\t\t\t\t 5000);\n+\tif (ret)\n+\t\tgoto out;\n+\n+\treturn FIELD_GET(MT7628_ESW_PCR1_RD_DATA, val);\n+\n+out:\n+\tdev_err(\u0026bus-\u003edev, \"read failed. MDIO timeout?\\n\");\n+\treturn ret;\n+}\n+\n+static int mt7628_mii_write(struct mii_bus *bus, int port, int regnum, u16 dat)\n+{\n+\tstruct mt7628_esw *esw = bus-\u003epriv;\n+\tu32 val;\n+\tint ret;\n+\n+\t/*\n+\t * WT_DONE bit is read to clear. Read PCR1 once to acknowledge any\n+\t * stale completion indicator before starting a new transaction.\n+\t */\n+\tret = regmap_read(esw-\u003eregmap, MT7628_ESW_REG_PCR1, \u0026val);\n+\tif (ret)\n+\t\tgoto out;\n+\n+\tret = regmap_write(esw-\u003eregmap, MT7628_ESW_REG_PCR0,\n+\t\t\t FIELD_PREP(MT7628_ESW_PCR0_WT_NWAY_DATA, dat) |\n+\t\t\t FIELD_PREP(MT7628_ESW_PCR0_CPU_PHY_REG,\n+\t\t\t\t regnum) |\n+\t\t\t FIELD_PREP(MT7628_ESW_PCR0_CPU_PHY_ADDR,\n+\t\t\t\t port) | MT7628_ESW_PCR0_WT_PHY_CMD);\n+\tif (ret)\n+\t\tgoto out;\n+\n+\tret = regmap_read_poll_timeout(esw-\u003eregmap, MT7628_ESW_REG_PCR1, val,\n+\t\t\t\t (val \u0026 MT7628_ESW_PCR1_WT_DONE), 10,\n+\t\t\t\t 5000);\n+\tif (ret)\n+\t\tgoto out;\n+\n+\treturn 0;\n+\n+out:\n+\tdev_err(\u0026bus-\u003edev, \"write failed. MDIO timeout?\\n\");\n+\treturn ret;\n+}\n+\n+static int mt7628_setup_internal_mdio(struct dsa_switch *ds)\n+{\n+\tstruct mt7628_esw *esw = ds-\u003epriv;\n+\tstruct device *dev = ds-\u003edev;\n+\tstruct mii_bus *bus;\n+\n+\tbus = devm_mdiobus_alloc(dev);\n+\tif (!bus)\n+\t\treturn -ENOMEM;\n+\n+\tbus-\u003ename = \"MT7628 internal MDIO bus\";\n+\tsnprintf(bus-\u003eid, MII_BUS_ID_SIZE, \"%s-mii\", dev_name(dev));\n+\tbus-\u003epriv = esw;\n+\tbus-\u003eread = mt7628_mii_read;\n+\tbus-\u003ewrite = mt7628_mii_write;\n+\tbus-\u003eparent = dev;\n+\n+\tds-\u003euser_mii_bus = bus;\n+\tbus-\u003ephy_mask = ~ds-\u003ephys_mii_mask;\n+\n+\treturn devm_mdiobus_register(dev, bus);\n+}\n+\n+static void mt7628_switch_init(struct dsa_switch *ds)\n+{\n+\tstruct mt7628_esw *esw = ds-\u003epriv;\n+\n+\tregmap_write(esw-\u003eregmap, MT7628_ESW_REG_FCT0,\n+\t\t FIELD_PREP(MT7628_ESW_FCT0_DROP_SET_TH, 0x50) |\n+\t\t FIELD_PREP(MT7628_ESW_FCT0_DROP_RLS_TH, 0x78) |\n+\t\t FIELD_PREP(MT7628_ESW_FCT0_FC_SET_TH, 0xa0) |\n+\t\t FIELD_PREP(MT7628_ESW_FCT0_FC_RLS_TH, 0xc8));\n+\n+\tregmap_write(esw-\u003eregmap, MT7628_ESW_REG_FCT2,\n+\t\t FIELD_PREP(MT7628_ESW_FCT2_MC_PER_PORT_TH, 0xc) |\n+\t\t FIELD_PREP(MT7628_ESW_FCT2_MUST_DROP_SET_TH, 0x10) |\n+\t\t FIELD_PREP(MT7628_ESW_FCT2_MUST_DROP_RLS_TH, 0x12));\n+\n+\t/*\n+\t * general switch configuration:\n+\t * 300s aging interval\n+\t * broadcast storm prevention disabled\n+\t * max packet length 1536 bytes\n+\t * disable collision 16 packet abort and late collision abort\n+\t * use xor48 for address hashing\n+\t * disable tx backoff\n+\t * 10 packet back pressure jam\n+\t * disable was_transmit\n+\t * jam until BP condition released\n+\t * 30ms LED flash\n+\t * rmc tb fault to all ports\n+\t * unmatched IGMP as broadcast\n+\t */\n+\tregmap_write(esw-\u003eregmap, MT7628_ESW_REG_SGC,\n+\t\t FIELD_PREP(MT7628_ESW_SGC_AGING_INTERVAL, 1) |\n+\t\t FIELD_PREP(MT7628_ESW_BC_STORM_PROT, 0) |\n+\t\t FIELD_PREP(MT7628_ESW_PKT_MAX_LEN, 0) |\n+\t\t MT7628_ESW_DIS_PKT_ABORT |\n+\t\t FIELD_PREP(MT7628_ESW_ADDRESS_HASH_ALG, 1) |\n+\t\t MT7628_ESW_DISABLE_TX_BACKOFF |\n+\t\t FIELD_PREP(MT7628_ESW_BP_JAM_CNT, 10) |\n+\t\t FIELD_PREP(MT7628_ESW_DISMIIPORT_WASTX, 0) |\n+\t\t FIELD_PREP(MT7628_ESW_BP_MODE, 0b10) |\n+\t\t FIELD_PREP(MT7628_ESW_LED_FLASH_TIME, 0) |\n+\t\t FIELD_PREP(MT7628_ESW_RMC_RULE, 0) |\n+\t\t FIELD_PREP(MT7628_ESW_IP_MULT_RULE, 0));\n+\n+\tregmap_write(esw-\u003eregmap, MT7628_ESW_REG_SOCPC,\n+\t\t MT7628_ESW_SOCPC_CRC_PADDING |\n+\t\t FIELD_PREP(MT7628_ESW_SOCPC_DISUN2CPU,\n+\t\t\t\tMT7628_ESW_PORTS_CPU) |\n+\t\t FIELD_PREP(MT7628_ESW_SOCPC_DISMC2CPU,\n+\t\t\t\tMT7628_ESW_PORTS_CPU) |\n+\t\t FIELD_PREP(MT7628_ESW_SOCPC_DISBC2CPU,\n+\t\t\t\tMT7628_ESW_PORTS_CPU));\n+\n+\tregmap_set_bits(esw-\u003eregmap, MT7628_ESW_REG_FPA2,\n+\t\t\tMT7628_ESW_FPA2_FORCE_RGMII_EN1 |\n+\t\t\tMT7628_ESW_FPA2_FORCE_RGMII_LINK1 |\n+\t\t\tMT7628_ESW_FPA2_AP_EN);\n+\n+\tregmap_update_bits(esw-\u003eregmap, MT7628_ESW_REG_FPA2,\n+\t\t\t MT7628_ESW_FPA2_EXT_PHY_ADDR_BASE,\n+\t\t\t FIELD_PREP(MT7628_ESW_FPA2_EXT_PHY_ADDR_BASE, 31));\n+\n+\t/* disable all interrupts */\n+\tregmap_write(esw-\u003eregmap, MT7628_ESW_REG_IMR, 0);\n+\n+\t/* enable MT7628 DSA tag on CPU port */\n+\tregmap_write(esw-\u003eregmap, MT7628_ESW_REG_SGC2,\n+\t\t MT7628_ESW_SGC2_SPECIAL_TAG_EN |\n+\t\t FIELD_PREP(MT7628_ESW_SGC2_TX_CPU_TPID_BIT_MAP,\n+\t\t\t\tMT7628_ESW_PORTS_CPU));\n+\n+\t/*\n+\t * Double tag feature allows switch to always append the port PVID VLAN tag\n+\t * regardless of if the incoming packet already has a VLAN tag.\n+\t * This is enabled to simulate VLAN unawareness.\n+\t */\n+\tregmap_set_bits(esw-\u003eregmap, MT7628_ESW_REG_SGC2,\n+\t\t\tFIELD_PREP(MT7628_ESW_SGC2_DOUBLE_TAG_EN,\n+\t\t\t\t MT7628_ESW_PORTS_NOCPU));\n+\n+\tregmap_set_bits(esw-\u003eregmap, MT7628_ESW_REG_POC2,\n+\t\t\tMT7628_ESW_POC2_PER_VLAN_UNTAG_EN);\n+\n+\tregmap_update_bits(esw-\u003eregmap, MT7628_ESW_REG_PFC1,\n+\t\t\t MT7628_ESW_PFC1_EN_VLAN,\n+\t\t\t FIELD_PREP(MT7628_ESW_PFC1_EN_VLAN,\n+\t\t\t\t MT7628_ESW_PORTS_ALL));\n+}\n+\n+static void mt7628_esw_set_pvid(struct mt7628_esw *esw, unsigned int port,\n+\t\t\t\tunsigned int pvid)\n+{\n+\tregmap_update_bits(esw-\u003eregmap, MT7628_ESW_REG_PVIDC(port),\n+\t\t\t MT7628_ESW_PVID_MASK(port),\n+\t\t\t MT7628_ESW_PVID_PREP(port, pvid));\n+}\n+\n+static void mt7628_esw_set_vlan_id(struct mt7628_esw *esw, unsigned int vlan,\n+\t\t\t\t unsigned int vid)\n+{\n+\tregmap_update_bits(esw-\u003eregmap, MT7628_ESW_REG_VLANI(vlan),\n+\t\t\t MT7628_ESW_VID_MASK(vlan),\n+\t\t\t MT7628_ESW_VID_PREP(vlan, vid));\n+}\n+\n+static void mt7628_esw_set_vmsc(struct mt7628_esw *esw, unsigned int vlan,\n+\t\t\t\tunsigned int msc)\n+{\n+\tregmap_update_bits(esw-\u003eregmap, MT7628_ESW_REG_VMSC(vlan),\n+\t\t\t MT7628_ESW_VMSC_MASK(vlan),\n+\t\t\t MT7628_ESW_VMSC_PREP(vlan, msc));\n+}\n+\n+static void mt7628_esw_set_vub(struct mt7628_esw *esw, unsigned int vlan,\n+\t\t\t unsigned int vub)\n+{\n+\tregmap_update_bits(esw-\u003eregmap, MT7628_ESW_REG_VUB(vlan),\n+\t\t\t MT7628_ESW_VUB_MASK(vlan),\n+\t\t\t MT7628_ESW_VUB_PREP(vlan, vub));\n+}\n+\n+static void mt7628_vlan_sync(struct dsa_switch *ds)\n+{\n+\tstruct mt7628_esw *esw = ds-\u003epriv;\n+\tint i;\n+\n+\tfor (i = 0; i \u003c MT7628_NUM_VLANS; i++) {\n+\t\tstruct mt7628_vlan *vlan = \u0026esw-\u003evlans[i];\n+\n+\t\tmt7628_esw_set_vmsc(esw, i, vlan-\u003emembers);\n+\t\tmt7628_esw_set_vlan_id(esw, i, vlan-\u003evid);\n+\t\tmt7628_esw_set_vub(esw, i, vlan-\u003euntag);\n+\t}\n+\n+\tfor (i = 0; i \u003c ds-\u003enum_ports; i++)\n+\t\tmt7628_esw_set_pvid(esw, i, esw-\u003etag_8021q_pvid[i]);\n+}\n+\n+static int mt7628_setup(struct dsa_switch *ds)\n+{\n+\tstruct mt7628_esw *esw = ds-\u003epriv;\n+\tint ret;\n+\n+\tret = reset_control_reset(esw-\u003erst_esw);\n+\tif (ret)\n+\t\treturn ret;\n+\tusleep_range(1000, 2000);\n+\n+\tret = reset_control_reset(esw-\u003erst_ephy);\n+\tif (ret)\n+\t\treturn ret;\n+\tusleep_range(1000, 2000);\n+\t/*\n+\t * all MMIO reads hang if esw is not out of reset\n+\t * ephy needs extra time to get out of reset or it ends up misconfigured\n+\t */\n+\n+\tmt7628_switch_init(ds);\n+\n+\tret = mt7628_setup_internal_mdio(ds);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\trtnl_lock();\n+\tret = dsa_tag_8021q_register(ds, htons(ETH_P_8021Q));\n+\trtnl_unlock();\n+\n+\treturn ret;\n+}\n+\n+static int mt7628_port_enable(struct dsa_switch *ds, int port,\n+\t\t\t struct phy_device *phy)\n+{\n+\tstruct mt7628_esw *esw = ds-\u003epriv;\n+\n+\tregmap_clear_bits(esw-\u003eregmap, MT7628_ESW_REG_POC0,\n+\t\t\t FIELD_PREP(MT7628_ESW_POC0_PORT_DISABLE, BIT(port)));\n+\treturn 0;\n+}\n+\n+static void mt7628_port_disable(struct dsa_switch *ds, int port)\n+{\n+\tstruct mt7628_esw *esw = ds-\u003epriv;\n+\n+\tregmap_set_bits(esw-\u003eregmap, MT7628_ESW_REG_POC0,\n+\t\t\tFIELD_PREP(MT7628_ESW_POC0_PORT_DISABLE, BIT(port)));\n+}\n+\n+static enum dsa_tag_protocol\n+mt7628_get_tag_proto(struct dsa_switch *ds, int port, enum dsa_tag_protocol mp)\n+{\n+\treturn DSA_TAG_PROTO_MT7628;\n+}\n+\n+static void mt7628_phylink_get_caps(struct dsa_switch *ds, int port,\n+\t\t\t\t struct phylink_config *config)\n+{\n+\tswitch (port) {\n+\tcase 6:\n+\t\tconfig-\u003emac_capabilities |= MAC_1000;\n+\t\tfallthrough;\n+\tcase 0 ... 4:\n+\t\tconfig-\u003emac_capabilities |= MAC_100 | MAC_10;\n+\t\t__set_bit(PHY_INTERFACE_MODE_INTERNAL,\n+\t\t\t config-\u003esupported_interfaces);\n+\t\tbreak;\n+\tdefault:\n+\t\tbreak;\t\t/* port 5 does not exist on MT7628 */\n+\t}\n+}\n+\n+static int mt7628_dsa_8021q_vlan_add(struct dsa_switch *ds, int port,\n+\t\t\t\t u16 vid, u16 flags)\n+{\n+\tstruct mt7628_esw *esw = ds-\u003epriv;\n+\tstruct mt7628_vlan *vlan = NULL;\n+\tint i;\n+\n+\tfor (i = 0; i \u003c MT7628_NUM_VLANS; i++) {\n+\t\tstruct mt7628_vlan *check_vlan = \u0026esw-\u003evlans[i];\n+\n+\t\tif (!check_vlan-\u003eactive \u0026\u0026 !vlan)\n+\t\t\tvlan = check_vlan;\n+\n+\t\tif (check_vlan-\u003eactive \u0026\u0026 check_vlan-\u003evid == vid) {\n+\t\t\tvlan = check_vlan;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif (!vlan)\n+\t\treturn -ENOSPC;\n+\n+\tvlan-\u003evid = vid;\n+\tvlan-\u003eactive = true;\n+\tvlan-\u003emembers |= BIT(port);\n+\n+\tif (flags \u0026 BRIDGE_VLAN_INFO_PVID)\n+\t\tesw-\u003etag_8021q_pvid[port] = vid;\n+\n+\tif (flags \u0026 BRIDGE_VLAN_INFO_UNTAGGED)\n+\t\tvlan-\u003euntag |= BIT(port);\n+\n+\tmt7628_vlan_sync(ds);\n+\treturn 0;\n+}\n+\n+static int mt7628_dsa_8021q_vlan_del(struct dsa_switch *ds, int port, u16 vid)\n+{\n+\tstruct mt7628_esw *esw = ds-\u003epriv;\n+\tstruct mt7628_vlan *vlan = NULL;\n+\tint i;\n+\n+\tfor (i = 0; i \u003c MT7628_NUM_VLANS; i++) {\n+\t\tstruct mt7628_vlan *check_vlan = \u0026esw-\u003evlans[i];\n+\n+\t\tif (!check_vlan-\u003eactive || check_vlan-\u003evid != vid)\n+\t\t\tcontinue;\n+\t\tvlan = check_vlan;\n+\t\tbreak;\n+\t}\n+\tif (!vlan)\n+\t\treturn -ENOENT;\n+\n+\tif (esw-\u003etag_8021q_pvid[port] == vid)\n+\t\tesw-\u003etag_8021q_pvid[port] = 0;\n+\n+\tvlan-\u003emembers \u0026= ~BIT(port);\n+\tvlan-\u003euntag \u0026= ~BIT(port);\n+\n+\tif (!vlan-\u003emembers) {\n+\t\tvlan-\u003eactive = false;\n+\t\tvlan-\u003evid = 0;\n+\t}\n+\n+\tmt7628_vlan_sync(ds);\n+\treturn 0;\n+}\n+\n+static void mt7628_teardown(struct dsa_switch *ds)\n+{\n+\trtnl_lock();\n+\tdsa_tag_8021q_unregister(ds);\n+\trtnl_unlock();\n+}\n+\n+static const struct dsa_switch_ops mt7628_switch_ops = {\n+\t.get_tag_protocol = mt7628_get_tag_proto,\n+\t.setup = mt7628_setup,\n+\t.teardown = mt7628_teardown,\n+\t.port_enable = mt7628_port_enable,\n+\t.port_disable = mt7628_port_disable,\n+\t.phylink_get_caps = mt7628_phylink_get_caps,\n+\t.tag_8021q_vlan_add = mt7628_dsa_8021q_vlan_add,\n+\t.tag_8021q_vlan_del = mt7628_dsa_8021q_vlan_del,\n+};\n+\n+static int mt7628_probe(struct platform_device *pdev)\n+{\n+\tstruct device *dev = \u0026pdev-\u003edev;\n+\tstruct mt7628_esw *esw;\n+\tstruct dsa_switch *ds;\n+\tvoid __iomem *base;\n+\n+\tds = devm_kzalloc(\u0026pdev-\u003edev, sizeof(*ds), GFP_KERNEL);\n+\tif (!ds)\n+\t\treturn -ENOMEM;\n+\n+\tesw = devm_kzalloc(\u0026pdev-\u003edev, sizeof(*esw), GFP_KERNEL);\n+\tif (!esw)\n+\t\treturn -ENOMEM;\n+\n+\tbase = devm_platform_ioremap_resource(pdev, 0);\n+\tif (IS_ERR(base))\n+\t\treturn PTR_ERR(base);\n+\n+\tesw-\u003eregmap = devm_regmap_init_mmio(\u0026pdev-\u003edev, base,\n+\t\t\t\t\t \u0026mt7628_esw_regmap_cfg);\n+\tif (IS_ERR(esw-\u003eregmap))\n+\t\treturn PTR_ERR(esw-\u003eregmap);\n+\n+\tesw-\u003erst_ephy = devm_reset_control_get_exclusive(\u0026pdev-\u003edev, \"ephy\");\n+\tif (IS_ERR(esw-\u003erst_ephy))\n+\t\treturn dev_err_probe(dev, PTR_ERR(esw-\u003erst_ephy),\n+\t\t\t\t \"failed to get EPHY reset\\n\");\n+\n+\tesw-\u003erst_esw = devm_reset_control_get_exclusive(\u0026pdev-\u003edev, \"esw\");\n+\tif (IS_ERR(esw-\u003erst_esw))\n+\t\treturn dev_err_probe(dev, PTR_ERR(esw-\u003erst_esw),\n+\t\t\t\t \"failed to get ESW reset\\n\");\n+\n+\tds-\u003edev = dev;\n+\tds-\u003enum_ports = MT7628_ESW_NUM_PORTS;\n+\tds-\u003eops = \u0026mt7628_switch_ops;\n+\tds-\u003epriv = esw;\n+\tesw-\u003eds = ds;\n+\tesw-\u003edev = dev;\n+\tdev_set_drvdata(dev, esw);\n+\n+\treturn dsa_register_switch(ds);\n+}\n+\n+static void mt7628_remove(struct platform_device *pdev)\n+{\n+\tstruct mt7628_esw *esw = platform_get_drvdata(pdev);\n+\n+\tif (!esw)\n+\t\treturn;\n+\n+\tdsa_unregister_switch(esw-\u003eds);\n+}\n+\n+static void mt7628_shutdown(struct platform_device *pdev)\n+{\n+\tstruct mt7628_esw *esw = platform_get_drvdata(pdev);\n+\n+\tif (!esw)\n+\t\treturn;\n+\n+\tdsa_switch_shutdown(esw-\u003eds);\n+\tdev_set_drvdata(\u0026pdev-\u003edev, NULL);\n+}\n+\n+static const struct of_device_id mt7628_of_match[] = {\n+\t{ .compatible = \"mediatek,mt7628-esw\" },\n+\t{}\n+};\n+\n+MODULE_DEVICE_TABLE(of, mt7628_of_match);\n+\n+static struct platform_driver mt7628_driver = {\n+\t.driver = {\n+\t\t .name = \"mt7628-esw\",\n+\t\t .of_match_table = mt7628_of_match,\n+\t\t },\n+\t.probe = mt7628_probe,\n+\t.remove = mt7628_remove,\n+\t.shutdown = mt7628_shutdown,\n+};\n+\n+module_platform_driver(mt7628_driver);\n+\n+MODULE_AUTHOR(\"Joris Vaisvila \u003cjoey@tinyisr.com\u003e\");\n+MODULE_DESCRIPTION(\"Driver for Mediatek MT7628 embedded switch\");\n+MODULE_LICENSE(\"GPL\");\ndiff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig\nindex bb7dc876271e83..b6a51f38c358ab 100644\n--- a/drivers/net/phy/mediatek/Kconfig\n+++ b/drivers/net/phy/mediatek/Kconfig\n@@ -21,8 +21,16 @@ config MEDIATEK_GE_PHY\n \t common operations with MediaTek SoC built-in Gigabit\n \t Ethernet PHYs.\n \n+config MEDIATEK_FE_SOC_PHY\n+\ttristate \"MediaTek SoC Fast Ethernet PHYs\"\n+\thelp\n+\t Support for MediaTek MT7628 built-in Fast Ethernet PHYs.\n+\t This driver only sets an initialization bit required for the PHY\n+\t to establish 100 Mbps links. All other PHY operations are handled\n+\t by the kernel's generic PHY code.\n+\n config MEDIATEK_GE_SOC_PHY\n-\ttristate \"MediaTek SoC Ethernet PHYs\"\n+\ttristate \"MediaTek SoC Gigabit Ethernet PHYs\"\n \tdepends on ARM64 || COMPILE_TEST\n \tdepends on ARCH_AIROHA || (ARCH_MEDIATEK \u0026\u0026 NVMEM_MTK_EFUSE) || \\\n \t\t COMPILE_TEST\ndiff --git a/drivers/net/phy/mediatek/Makefile b/drivers/net/phy/mediatek/Makefile\nindex ac57ecc799fc81..6f9cacf7f90657 100644\n--- a/drivers/net/phy/mediatek/Makefile\n+++ b/drivers/net/phy/mediatek/Makefile\n@@ -1,5 +1,6 @@\n # SPDX-License-Identifier: GPL-2.0\n obj-$(CONFIG_MEDIATEK_2P5GE_PHY)\t+= mtk-2p5ge.o\n+obj-$(CONFIG_MEDIATEK_FE_SOC_PHY)\t+= mtk-fe-soc.o\n obj-$(CONFIG_MEDIATEK_GE_PHY)\t\t+= mtk-ge.o\n obj-$(CONFIG_MEDIATEK_GE_SOC_PHY)\t+= mtk-ge-soc.o\n obj-$(CONFIG_MTK_NET_PHYLIB)\t\t+= mtk-phy-lib.o\ndiff --git a/drivers/net/phy/mediatek/mtk-fe-soc.c b/drivers/net/phy/mediatek/mtk-fe-soc.c\nnew file mode 100644\nindex 00000000000000..9eb4960bcaade3\n--- /dev/null\n+++ b/drivers/net/phy/mediatek/mtk-fe-soc.c\n@@ -0,0 +1,50 @@\n+// SPDX-License-Identifier: GPL-2.0-only\n+/*\n+ * Driver for MT7628 Embedded Switch internal Fast Ethernet PHYs\n+ */\n+#include \u003clinux/module.h\u003e\n+#include \u003clinux/phy.h\u003e\n+\n+#define MTK_FPHY_ID_MT7628\t0x03a29410\n+#define MTK_EXT_PAGE_ACCESS\t0x1f\n+\n+static int mt7628_phy_read_page(struct phy_device *phydev)\n+{\n+\treturn __phy_read(phydev, MTK_EXT_PAGE_ACCESS);\n+}\n+\n+static int mt7628_phy_write_page(struct phy_device *phydev, int page)\n+{\n+\treturn __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);\n+}\n+\n+static int mt7628_phy_config_init(struct phy_device *phydev)\n+{\n+\t/*\n+\t * This undocumented bit is required for the PHYs to be able to\n+\t * establish 100mbps links.\n+\t */\n+\treturn phy_modify_paged(phydev, 0x8000, 30, BIT(13), BIT(13));\n+}\n+\n+static struct phy_driver mtk_soc_fe_phy_driver[] = {\n+\t{\n+\t\tPHY_ID_MATCH_EXACT(MTK_FPHY_ID_MT7628),\n+\t\t.name = \"MediaTek MT7628 PHY\",\n+\t\t.config_init = mt7628_phy_config_init,\n+\t\t.read_page = mt7628_phy_read_page,\n+\t\t.write_page = mt7628_phy_write_page,\n+\t},\n+};\n+\n+module_phy_driver(mtk_soc_fe_phy_driver);\n+static const struct mdio_device_id __maybe_unused mtk_soc_fe_phy_tbl[] = {\n+\t{ PHY_ID_MATCH_EXACT(MTK_FPHY_ID_MT7628) },\n+\t{ }\n+};\n+\n+MODULE_DESCRIPTION(\"MediaTek SoC Fast Ethernet PHY driver\");\n+MODULE_AUTHOR(\"Joris Vaisvila \u003cjoey@tinyisr.com\u003e\");\n+MODULE_LICENSE(\"GPL\");\n+\n+MODULE_DEVICE_TABLE(mdio, mtk_soc_fe_phy_tbl);\ndiff --git a/include/net/dsa.h b/include/net/dsa.h\nindex 8c16ef23cc102a..913d1f71e3dbfe 100644\n--- a/include/net/dsa.h\n+++ b/include/net/dsa.h\n@@ -59,6 +59,7 @@ struct tc_action;\n #define DSA_TAG_PROTO_MXL_GSW1XX_VALUE\t\t31\n #define DSA_TAG_PROTO_MXL862_VALUE\t\t32\n #define DSA_TAG_PROTO_NETC_VALUE\t\t33\n+#define DSA_TAG_PROTO_MT7628_VALUE\t\t34\n \n enum dsa_tag_protocol {\n \tDSA_TAG_PROTO_NONE\t\t= DSA_TAG_PROTO_NONE_VALUE,\n@@ -95,6 +96,7 @@ enum dsa_tag_protocol {\n \tDSA_TAG_PROTO_MXL_GSW1XX\t= DSA_TAG_PROTO_MXL_GSW1XX_VALUE,\n \tDSA_TAG_PROTO_MXL862\t\t= DSA_TAG_PROTO_MXL862_VALUE,\n \tDSA_TAG_PROTO_NETC\t\t= DSA_TAG_PROTO_NETC_VALUE,\n+\tDSA_TAG_PROTO_MT7628\t\t= DSA_TAG_PROTO_MT7628_VALUE,\n };\n \n struct dsa_switch;\ndiff --git a/net/dsa/Kconfig b/net/dsa/Kconfig\nindex d5e725b90d7858..23b4b74004ed5e 100644\n--- a/net/dsa/Kconfig\n+++ b/net/dsa/Kconfig\n@@ -98,6 +98,12 @@ config NET_DSA_TAG_EDSA\n \t Say Y or M if you want to enable support for tagging frames for the\n \t Marvell switches which use EtherType DSA headers.\n \n+config NET_DSA_TAG_MT7628\n+\ttristate \"Tag driver for the MT7628 embedded switch\"\n+\thelp\n+\t Say Y or M if you want to enable support for tagging frames for the\n+\t switch embedded in the MT7628 SoC.\n+\n config NET_DSA_TAG_MTK\n \ttristate \"Tag driver for Mediatek switches\"\n \thelp\ndiff --git a/net/dsa/Makefile b/net/dsa/Makefile\nindex b8c2667cd14aad..d15bcf5c68f02a 100644\n--- a/net/dsa/Makefile\n+++ b/net/dsa/Makefile\n@@ -27,6 +27,7 @@ obj-$(CONFIG_NET_DSA_TAG_GSWIP) += tag_gswip.o\n obj-$(CONFIG_NET_DSA_TAG_HELLCREEK) += tag_hellcreek.o\n obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o\n obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o\n+obj-$(CONFIG_NET_DSA_TAG_MT7628) += tag_mt7628.o\n obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o\n obj-$(CONFIG_NET_DSA_TAG_MXL_862XX) += tag_mxl862xx.o\n obj-$(CONFIG_NET_DSA_TAG_MXL_GSW1XX) += tag_mxl-gsw1xx.o\ndiff --git a/net/dsa/tag_mt7628.c b/net/dsa/tag_mt7628.c\nnew file mode 100644\nindex 00000000000000..80b50ff08e53f5\n--- /dev/null\n+++ b/net/dsa/tag_mt7628.c\n@@ -0,0 +1,93 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/*\n+ * Copyright (c) 2026, Joris Vaisvila \u003cjoey@tinyisr.com\u003e\n+ * MT7628 switch tag support\n+ */\n+\n+#include \u003clinux/etherdevice.h\u003e\n+#include \u003clinux/dsa/8021q.h\u003e\n+#include \u003cnet/dsa.h\u003e\n+\n+#include \"tag.h\"\n+\n+/*\n+ * The MT7628 tag is encoded in the VLAN TPID field.\n+ * On TX the lower 6 bits encode the destination port bitmask.\n+ * On RX the lower 3 bits encode the source port number.\n+ *\n+ * The switch hardware will not modify the TPID of an incoming packet if it is\n+ * already VLAN tagged. To work around this the switch is configured to always\n+ * append a tag_8021q standalone VLAN tag for each port. That means we can\n+ * safely strip the outer VLAN tag after parsing it.\n+ *\n+ * A VLAN tag is constructed on egress to target the standalone VLAN and\n+ * destination port.\n+ */\n+\n+#define MT7628_TAG_NAME \"mt7628\"\n+\n+#define MT7628_TAG_TX_PORT GENMASK(5, 0)\n+#define MT7628_TAG_RX_PORT GENMASK(2, 0)\n+#define MT7628_TAG_LEN 4\n+\n+static struct sk_buff *mt7628_tag_xmit(struct sk_buff *skb,\n+\t\t\t\t struct net_device *dev)\n+{\n+\tstruct dsa_port *dp;\n+\tu16 xmit_vlan;\n+\t__be16 *tag;\n+\n+\tdp = dsa_user_to_port(dev);\n+\txmit_vlan = dsa_tag_8021q_standalone_vid(dp);\n+\n+\tskb_push(skb, MT7628_TAG_LEN);\n+\tdsa_alloc_etype_header(skb, MT7628_TAG_LEN);\n+\n+\ttag = dsa_etype_header_pos_tx(skb);\n+\n+\ttag[0] = htons(ETH_P_8021Q |\n+\t\t FIELD_PREP(MT7628_TAG_TX_PORT,\n+\t\t\t\t dsa_xmit_port_mask(skb, dev)));\n+\ttag[1] = htons(xmit_vlan);\n+\n+\treturn skb;\n+}\n+\n+static struct sk_buff *mt7628_tag_rcv(struct sk_buff *skb,\n+\t\t\t\t struct net_device *dev)\n+{\n+\t__be16 *phdr;\n+\n+\tif (unlikely(!pskb_may_pull(skb, MT7628_TAG_LEN))) {\n+\t\tkfree_skb(skb);\n+\t\treturn NULL;\n+\t}\n+\n+\tphdr = dsa_etype_header_pos_rx(skb);\n+\tskb-\u003edev =\n+\t dsa_conduit_find_user(dev, 0,\n+\t\t\t\t FIELD_GET(MT7628_TAG_RX_PORT, ntohs(*phdr)));\n+\tif (!skb-\u003edev) {\n+\t\tkfree_skb(skb);\n+\t\treturn NULL;\n+\t}\n+\n+\tskb_pull_rcsum(skb, MT7628_TAG_LEN);\n+\tdsa_strip_etype_header(skb, MT7628_TAG_LEN);\n+\tdsa_default_offload_fwd_mark(skb);\n+\treturn skb;\n+}\n+\n+static const struct dsa_device_ops mt7628_tag_ops = {\n+\t.name = MT7628_TAG_NAME,\n+\t.proto = DSA_TAG_PROTO_MT7628,\n+\t.xmit = mt7628_tag_xmit,\n+\t.rcv = mt7628_tag_rcv,\n+\t.needed_headroom = MT7628_TAG_LEN,\n+};\n+\n+module_dsa_tag_driver(mt7628_tag_ops);\n+\n+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_MT7628, MT7628_TAG_NAME);\n+MODULE_DESCRIPTION(\"DSA tag driver for MT7628 switch\");\n+MODULE_LICENSE(\"GPL\");\n"
} |
| 2/1 | 2026/07/04 11:39 | agent | patch-evaluator |
1mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch adds support for the MediaTek MT7628 Embedded Ethernet Switch, including a platform driver, a PHY driver, and a DSA tag driver. The platform driver requires specific MMIO resources and reset controllers that are not present in virtualized environments (QEMU/GCE). The PHY driver requires an MDIO bus with a specific hardware PHY ID. The DSA tag driver can only be reached if a DSA switch is configured to use the MT7628 tag protocol. The only mock DSA switch available in virtualized environments (dsa_loop) does not support changing its tag protocol at runtime. Therefore, the modified code paths are impossible to reach in a virtualized environment.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 2959f8ac93ddc43dc10b0b2333c877b861015334
Author: syz-cluster <triage@syzkaller.com>
Date: Sat Jul 4 11:39:25 2026 +0000
syz-cluster: applied patch under review
diff --git a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7628-esw.yaml b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7628-esw.yaml
new file mode 100644
index 00000000000000..e0e7ffef66482c
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7628-esw.yaml
@@ -0,0 +1,96 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/dsa/mediatek,mt7628-esw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek MT7628 Embedded Ethernet Switch
+
+maintainers:
+ - Joris Vaisvila <joey@tinyisr.com>
+
+description:
+ The MT7628 SoC's built-in Ethernet Switch has five user ports and one
+ internally connected CPU port. The user ports are all connected to the SoC's
+ integrated Fast Ethernet PHYs. The switch registers are directly mapped in
+ the SoC's memory.
+
+allOf:
+ - $ref: dsa.yaml#/$defs/ethernet-ports
+
+properties:
+ compatible:
+ const: mediatek,mt7628-esw
+
+ reg:
+ maxItems: 1
+
+ resets:
+ items:
+ - description: internal switch block reset
+ - description: internal phy package reset
+
+ reset-names:
+ items:
+ - const: esw
+ - const: ephy
+
+required:
+ - compatible
+ - reg
+ - resets
+ - reset-names
+ - ethernet-ports
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ switch@10110000 {
+ compatible = "mediatek,mt7628-esw";
+ reg = <0x10110000 0x8000>;
+
+ resets = <&sysc 23>, <&sysc 24>;
+ reset-names = "esw", "ephy";
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet-port@0 {
+ reg = <0>;
+ phy-mode = "internal";
+ };
+
+ ethernet-port@1 {
+ reg = <1>;
+ phy-mode = "internal";
+ };
+
+ ethernet-port@2 {
+ reg = <2>;
+ phy-mode = "internal";
+ };
+
+ ethernet-port@3 {
+ reg = <3>;
+ phy-mode = "internal";
+ };
+
+ ethernet-port@4 {
+ reg = <4>;
+ phy-mode = "internal";
+ };
+
+ ethernet-port@6 {
+ reg = <6>;
+ phy-mode = "internal";
+ ethernet = <ðernet>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+ };
+ };
+ };
diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 4ab567c5bbafc6..daa1d3d4ba609e 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -63,6 +63,14 @@ config NET_DSA_MT7530_MMIO
are directly mapped into the SoCs register space rather than being
accessible via MDIO.
+config NET_DSA_MT7628
+ tristate "MediaTek MT7628 Embedded Ethernet switch support"
+ select NET_DSA_TAG_MT7628
+ select MEDIATEK_FE_SOC_PHY
+ help
+ This enables support for the built-in Ethernet switch found
+ in the MT7628 SoC.
+
config NET_DSA_MV88E6060
tristate "Marvell 88E6060 ethernet switch chip support"
select NET_DSA_TAG_TRAILER
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index d2975badffc093..6ceb78a755d777 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_NET_DSA_KS8995) += ks8995.o
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o
+obj-$(CONFIG_NET_DSA_MT7628) += mt7628.o
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o
obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
diff --git a/drivers/net/dsa/mt7628.c b/drivers/net/dsa/mt7628.c
new file mode 100644
index 00000000000000..eccdb05fce9b71
--- /dev/null
+++ b/drivers/net/dsa/mt7628.c
@@ -0,0 +1,649 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek MT7628 Embedded Switch (ESW) DSA driver
+ * Copyright (C) 2026 Joris Vaisvila <joey@tinyisr.com>
+ *
+ * Portions derived from OpenWRT esw_rt3050 driver:
+ * Copyright (C) 2009-2015 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2009-2015 Felix Fietkau <nbd@nbd.name>
+ * Copyright (C) 2013-2015 Michael Lee <igvtee@gmail.com>
+ * Copyright (C) 2016 Vittorio Gambaletta <openwrt@vittgam.net>
+ */
+
+#include <linux/platform_device.h>
+#include <linux/etherdevice.h>
+#include <linux/netdevice.h>
+#include <linux/dsa/8021q.h>
+#include <linux/if_bridge.h>
+#include <linux/module.h>
+#include <linux/mdio.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
+#include <linux/of_net.h>
+#include <linux/kernel.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <net/dsa.h>
+
+#define MT7628_ESW_REG_IMR 0x04
+#define MT7628_ESW_REG_FCT0 0x08
+#define MT7628_ESW_REG_PFC1 0x14
+#define MT7628_ESW_REG_PVIDC(port) (0x40 + 4 * ((port) / 2))
+#define MT7628_ESW_REG_VLANI(vlan) (0x50 + 4 * ((vlan) / 2))
+#define MT7628_ESW_REG_VMSC(vlan) (0x70 + 4 * ((vlan) / 4))
+#define MT7628_ESW_REG_VUB(vlan) (0x100 + 4 * ((vlan) / 4))
+#define MT7628_ESW_REG_SOCPC 0x8c
+#define MT7628_ESW_REG_POC0 0x90
+#define MT7628_ESW_REG_POC2 0x98
+#define MT7628_ESW_REG_SGC 0x9c
+#define MT7628_ESW_REG_PCR0 0xc0
+#define MT7628_ESW_REG_PCR1 0xc4
+#define MT7628_ESW_REG_FPA2 0xc8
+#define MT7628_ESW_REG_FCT2 0xcc
+#define MT7628_ESW_REG_SGC2 0xe4
+
+#define MT7628_ESW_FCT0_DROP_SET_TH GENMASK(7, 0)
+#define MT7628_ESW_FCT0_DROP_RLS_TH GENMASK(15, 8)
+#define MT7628_ESW_FCT0_FC_SET_TH GENMASK(23, 16)
+#define MT7628_ESW_FCT0_FC_RLS_TH GENMASK(31, 24)
+
+#define MT7628_ESW_PFC1_EN_VLAN GENMASK(22, 16)
+
+#define MT7628_ESW_PVID_S 12
+#define MT7628_ESW_PVID_M GENMASK(11, 0)
+#define MT7628_ESW_PVID_SHIFT(port) \
+ (MT7628_ESW_PVID_S * ((port) % 2))
+#define MT7628_ESW_PVID_MASK(port) \
+ (MT7628_ESW_PVID_M << MT7628_ESW_PVID_SHIFT(port))
+#define MT7628_ESW_PVID_PREP(port, pvid) \
+ (((pvid) & MT7628_ESW_PVID_M) << MT7628_ESW_PVID_SHIFT(port))
+
+#define MT7628_ESW_VID_S 12
+#define MT7628_ESW_VID_M GENMASK(11, 0)
+#define MT7628_ESW_VID_SHIFT(vlan) \
+ (MT7628_ESW_VID_S * ((vlan) % 2))
+#define MT7628_ESW_VID_MASK(vlan) \
+ (MT7628_ESW_VID_M << MT7628_ESW_VID_SHIFT(vlan))
+#define MT7628_ESW_VID_PREP(vlan, vid) \
+ (((vid) & MT7628_ESW_VID_M) << MT7628_ESW_VID_SHIFT(vlan))
+
+#define MT7628_ESW_VMSC_S 8
+#define MT7628_ESW_VMSC_M GENMASK(7, 0)
+#define MT7628_ESW_VMSC_SHIFT(vlan) \
+ (MT7628_ESW_VMSC_S * ((vlan) % 4))
+#define MT7628_ESW_VMSC_MASK(vlan) \
+ (MT7628_ESW_VMSC_M << MT7628_ESW_VMSC_SHIFT(vlan))
+#define MT7628_ESW_VMSC_PREP(vlan, vmsc) \
+ (((vmsc) & MT7628_ESW_VMSC_M) << MT7628_ESW_VMSC_SHIFT(vlan))
+
+#define MT7628_ESW_VUB_S 7
+#define MT7628_ESW_VUB_M GENMASK(6, 0)
+#define MT7628_ESW_VUB_SHIFT(vlan) \
+ (MT7628_ESW_VUB_S * ((vlan) % 4))
+#define MT7628_ESW_VUB_MASK(vlan) \
+ (MT7628_ESW_VUB_M << MT7628_ESW_VUB_SHIFT(vlan))
+#define MT7628_ESW_VUB_PREP(vlan, vub) \
+ (((vub) & MT7628_ESW_VUB_M) << MT7628_ESW_VUB_SHIFT(vlan))
+
+#define MT7628_ESW_SOCPC_CRC_PADDING BIT(25)
+#define MT7628_ESW_SOCPC_DISBC2CPU GENMASK(22, 16)
+#define MT7628_ESW_SOCPC_DISMC2CPU GENMASK(14, 8)
+#define MT7628_ESW_SOCPC_DISUN2CPU GENMASK(6, 0)
+
+#define MT7628_ESW_POC0_PORT_DISABLE GENMASK(29, 23)
+
+#define MT7628_ESW_POC2_PER_VLAN_UNTAG_EN BIT(15)
+
+#define MT7628_ESW_SGC_AGING_INTERVAL GENMASK(3, 0)
+#define MT7628_ESW_BC_STORM_PROT GENMASK(5, 4)
+#define MT7628_ESW_PKT_MAX_LEN GENMASK(7, 6)
+#define MT7628_ESW_DIS_PKT_ABORT BIT(8)
+#define MT7628_ESW_ADDRESS_HASH_ALG GENMASK(10, 9)
+#define MT7628_ESW_DISABLE_TX_BACKOFF BIT(11)
+#define MT7628_ESW_BP_JAM_CNT GENMASK(15, 12)
+#define MT7628_ESW_DISMIIPORT_WASTX GENMASK(17, 16)
+#define MT7628_ESW_BP_MODE GENMASK(19, 18)
+#define MT7628_ESW_BISH_DIS BIT(20)
+#define MT7628_ESW_BISH_TH GENMASK(22, 21)
+#define MT7628_ESW_LED_FLASH_TIME GENMASK(24, 23)
+#define MT7628_ESW_RMC_RULE GENMASK(26, 25)
+#define MT7628_ESW_IP_MULT_RULE GENMASK(28, 27)
+#define MT7628_ESW_LEN_ERR_CHK BIT(29)
+#define MT7628_ESW_BKOFF_ALG BIT(30)
+
+#define MT7628_ESW_PCR0_WT_NWAY_DATA GENMASK(31, 16)
+#define MT7628_ESW_PCR0_RD_PHY_CMD BIT(14)
+#define MT7628_ESW_PCR0_WT_PHY_CMD BIT(13)
+#define MT7628_ESW_PCR0_CPU_PHY_REG GENMASK(12, 8)
+#define MT7628_ESW_PCR0_CPU_PHY_ADDR GENMASK(4, 0)
+
+#define MT7628_ESW_PCR1_RD_DATA GENMASK(31, 16)
+#define MT7628_ESW_PCR1_RD_DONE BIT(1)
+#define MT7628_ESW_PCR1_WT_DONE BIT(0)
+
+#define MT7628_ESW_FPA2_AP_EN BIT(29)
+#define MT7628_ESW_FPA2_EXT_PHY_ADDR_BASE GENMASK(28, 24)
+#define MT7628_ESW_FPA2_FORCE_RGMII_LINK1 BIT(13)
+#define MT7628_ESW_FPA2_FORCE_RGMII_EN1 BIT(11)
+
+#define MT7628_ESW_FCT2_MUST_DROP_RLS_TH GENMASK(17, 13)
+#define MT7628_ESW_FCT2_MUST_DROP_SET_TH GENMASK(12, 8)
+#define MT7628_ESW_FCT2_MC_PER_PORT_TH GENMASK(5, 0)
+
+#define MT7628_ESW_SGC2_SPECIAL_TAG_EN BIT(23)
+#define MT7628_ESW_SGC2_TX_CPU_TPID_BIT_MAP GENMASK(22, 16)
+#define MT7628_ESW_SGC2_DOUBLE_TAG_EN GENMASK(6, 0)
+
+#define MT7628_ESW_PORTS_NOCPU GENMASK(5, 0)
+#define MT7628_ESW_PORTS_CPU BIT(6)
+#define MT7628_ESW_PORTS_ALL GENMASK(6, 0)
+
+#define MT7628_ESW_NUM_PORTS 7
+#define MT7628_NUM_VLANS 16
+
+static const struct regmap_config mt7628_esw_regmap_cfg = {
+ .name = "mt7628-esw",
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .fast_io = true,
+ .reg_format_endian = REGMAP_ENDIAN_LITTLE,
+ .val_format_endian = REGMAP_ENDIAN_LITTLE,
+};
+
+struct mt7628_vlan {
+ bool active;
+ u8 members;
+ u8 untag;
+ u16 vid;
+};
+
+struct mt7628_esw {
+ struct reset_control *rst_ephy;
+ struct reset_control *rst_esw;
+ struct regmap *regmap;
+ struct dsa_switch *ds;
+ u16 tag_8021q_pvid[MT7628_ESW_NUM_PORTS];
+ struct mt7628_vlan vlans[MT7628_NUM_VLANS];
+ struct device *dev;
+};
+
+static int mt7628_mii_read(struct mii_bus *bus, int port, int regnum)
+{
+ struct mt7628_esw *esw = bus->priv;
+ int ret;
+ u32 val;
+
+ /*
+ * RD_DONE bit is read to clear. Read PCR1 once to acknowledge any
+ * stale completion indicator before starting a new transaction.
+ */
+ ret = regmap_read(esw->regmap, MT7628_ESW_REG_PCR1, &val);
+ if (ret)
+ goto out;
+
+ ret = regmap_write(esw->regmap, MT7628_ESW_REG_PCR0,
+ FIELD_PREP(MT7628_ESW_PCR0_CPU_PHY_REG,
+ regnum) |
+ FIELD_PREP(MT7628_ESW_PCR0_CPU_PHY_ADDR,
+ port) | MT7628_ESW_PCR0_RD_PHY_CMD);
+ if (ret)
+ goto out;
+
+ ret = regmap_read_poll_timeout(esw->regmap, MT7628_ESW_REG_PCR1, val,
+ (val & MT7628_ESW_PCR1_RD_DONE), 10,
+ 5000);
+ if (ret)
+ goto out;
+
+ return FIELD_GET(MT7628_ESW_PCR1_RD_DATA, val);
+
+out:
+ dev_err(&bus->dev, "read failed. MDIO timeout?\n");
+ return ret;
+}
+
+static int mt7628_mii_write(struct mii_bus *bus, int port, int regnum, u16 dat)
+{
+ struct mt7628_esw *esw = bus->priv;
+ u32 val;
+ int ret;
+
+ /*
+ * WT_DONE bit is read to clear. Read PCR1 once to acknowledge any
+ * stale completion indicator before starting a new transaction.
+ */
+ ret = regmap_read(esw->regmap, MT7628_ESW_REG_PCR1, &val);
+ if (ret)
+ goto out;
+
+ ret = regmap_write(esw->regmap, MT7628_ESW_REG_PCR0,
+ FIELD_PREP(MT7628_ESW_PCR0_WT_NWAY_DATA, dat) |
+ FIELD_PREP(MT7628_ESW_PCR0_CPU_PHY_REG,
+ regnum) |
+ FIELD_PREP(MT7628_ESW_PCR0_CPU_PHY_ADDR,
+ port) | MT7628_ESW_PCR0_WT_PHY_CMD);
+ if (ret)
+ goto out;
+
+ ret = regmap_read_poll_timeout(esw->regmap, MT7628_ESW_REG_PCR1, val,
+ (val & MT7628_ESW_PCR1_WT_DONE), 10,
+ 5000);
+ if (ret)
+ goto out;
+
+ return 0;
+
+out:
+ dev_err(&bus->dev, "write failed. MDIO timeout?\n");
+ return ret;
+}
+
+static int mt7628_setup_internal_mdio(struct dsa_switch *ds)
+{
+ struct mt7628_esw *esw = ds->priv;
+ struct device *dev = ds->dev;
+ struct mii_bus *bus;
+
+ bus = devm_mdiobus_alloc(dev);
+ if (!bus)
+ return -ENOMEM;
+
+ bus->name = "MT7628 internal MDIO bus";
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(dev));
+ bus->priv = esw;
+ bus->read = mt7628_mii_read;
+ bus->write = mt7628_mii_write;
+ bus->parent = dev;
+
+ ds->user_mii_bus = bus;
+ bus->phy_mask = ~ds->phys_mii_mask;
+
+ return devm_mdiobus_register(dev, bus);
+}
+
+static void mt7628_switch_init(struct dsa_switch *ds)
+{
+ struct mt7628_esw *esw = ds->priv;
+
+ regmap_write(esw->regmap, MT7628_ESW_REG_FCT0,
+ FIELD_PREP(MT7628_ESW_FCT0_DROP_SET_TH, 0x50) |
+ FIELD_PREP(MT7628_ESW_FCT0_DROP_RLS_TH, 0x78) |
+ FIELD_PREP(MT7628_ESW_FCT0_FC_SET_TH, 0xa0) |
+ FIELD_PREP(MT7628_ESW_FCT0_FC_RLS_TH, 0xc8));
+
+ regmap_write(esw->regmap, MT7628_ESW_REG_FCT2,
+ FIELD_PREP(MT7628_ESW_FCT2_MC_PER_PORT_TH, 0xc) |
+ FIELD_PREP(MT7628_ESW_FCT2_MUST_DROP_SET_TH, 0x10) |
+ FIELD_PREP(MT7628_ESW_FCT2_MUST_DROP_RLS_TH, 0x12));
+
+ /*
+ * general switch configuration:
+ * 300s aging interval
+ * broadcast storm prevention disabled
+ * max packet length 1536 bytes
+ * disable collision 16 packet abort and late collision abort
+ * use xor48 for address hashing
+ * disable tx backoff
+ * 10 packet back pressure jam
+ * disable was_transmit
+ * jam until BP condition released
+ * 30ms LED flash
+ * rmc tb fault to all ports
+ * unmatched IGMP as broadcast
+ */
+ regmap_write(esw->regmap, MT7628_ESW_REG_SGC,
+ FIELD_PREP(MT7628_ESW_SGC_AGING_INTERVAL, 1) |
+ FIELD_PREP(MT7628_ESW_BC_STORM_PROT, 0) |
+ FIELD_PREP(MT7628_ESW_PKT_MAX_LEN, 0) |
+ MT7628_ESW_DIS_PKT_ABORT |
+ FIELD_PREP(MT7628_ESW_ADDRESS_HASH_ALG, 1) |
+ MT7628_ESW_DISABLE_TX_BACKOFF |
+ FIELD_PREP(MT7628_ESW_BP_JAM_CNT, 10) |
+ FIELD_PREP(MT7628_ESW_DISMIIPORT_WASTX, 0) |
+ FIELD_PREP(MT7628_ESW_BP_MODE, 0b10) |
+ FIELD_PREP(MT7628_ESW_LED_FLASH_TIME, 0) |
+ FIELD_PREP(MT7628_ESW_RMC_RULE, 0) |
+ FIELD_PREP(MT7628_ESW_IP_MULT_RULE, 0));
+
+ regmap_write(esw->regmap, MT7628_ESW_REG_SOCPC,
+ MT7628_ESW_SOCPC_CRC_PADDING |
+ FIELD_PREP(MT7628_ESW_SOCPC_DISUN2CPU,
+ MT7628_ESW_PORTS_CPU) |
+ FIELD_PREP(MT7628_ESW_SOCPC_DISMC2CPU,
+ MT7628_ESW_PORTS_CPU) |
+ FIELD_PREP(MT7628_ESW_SOCPC_DISBC2CPU,
+ MT7628_ESW_PORTS_CPU));
+
+ regmap_set_bits(esw->regmap, MT7628_ESW_REG_FPA2,
+ MT7628_ESW_FPA2_FORCE_RGMII_EN1 |
+ MT7628_ESW_FPA2_FORCE_RGMII_LINK1 |
+ MT7628_ESW_FPA2_AP_EN);
+
+ regmap_update_bits(esw->regmap, MT7628_ESW_REG_FPA2,
+ MT7628_ESW_FPA2_EXT_PHY_ADDR_BASE,
+ FIELD_PREP(MT7628_ESW_FPA2_EXT_PHY_ADDR_BASE, 31));
+
+ /* disable all interrupts */
+ regmap_write(esw->regmap, MT7628_ESW_REG_IMR, 0);
+
+ /* enable MT7628 DSA tag on CPU port */
+ regmap_write(esw->regmap, MT7628_ESW_REG_SGC2,
+ MT7628_ESW_SGC2_SPECIAL_TAG_EN |
+ FIELD_PREP(MT7628_ESW_SGC2_TX_CPU_TPID_BIT_MAP,
+ MT7628_ESW_PORTS_CPU));
+
+ /*
+ * Double tag feature allows switch to always append the port PVID VLAN tag
+ * regardless of if the incoming packet already has a VLAN tag.
+ * This is enabled to simulate VLAN unawareness.
+ */
+ regmap_set_bits(esw->regmap, MT7628_ESW_REG_SGC2,
+ FIELD_PREP(MT7628_ESW_SGC2_DOUBLE_TAG_EN,
+ MT7628_ESW_PORTS_NOCPU));
+
+ regmap_set_bits(esw->regmap, MT7628_ESW_REG_POC2,
+ MT7628_ESW_POC2_PER_VLAN_UNTAG_EN);
+
+ regmap_update_bits(esw->regmap, MT7628_ESW_REG_PFC1,
+ MT7628_ESW_PFC1_EN_VLAN,
+ FIELD_PREP(MT7628_ESW_PFC1_EN_VLAN,
+ MT7628_ESW_PORTS_ALL));
+}
+
+static void mt7628_esw_set_pvid(struct mt7628_esw *esw, unsigned int port,
+ unsigned int pvid)
+{
+ regmap_update_bits(esw->regmap, MT7628_ESW_REG_PVIDC(port),
+ MT7628_ESW_PVID_MASK(port),
+ MT7628_ESW_PVID_PREP(port, pvid));
+}
+
+static void mt7628_esw_set_vlan_id(struct mt7628_esw *esw, unsigned int vlan,
+ unsigned int vid)
+{
+ regmap_update_bits(esw->regmap, MT7628_ESW_REG_VLANI(vlan),
+ MT7628_ESW_VID_MASK(vlan),
+ MT7628_ESW_VID_PREP(vlan, vid));
+}
+
+static void mt7628_esw_set_vmsc(struct mt7628_esw *esw, unsigned int vlan,
+ unsigned int msc)
+{
+ regmap_update_bits(esw->regmap, MT7628_ESW_REG_VMSC(vlan),
+ MT7628_ESW_VMSC_MASK(vlan),
+ MT7628_ESW_VMSC_PREP(vlan, msc));
+}
+
+static void mt7628_esw_set_vub(struct mt7628_esw *esw, unsigned int vlan,
+ unsigned int vub)
+{
+ regmap_update_bits(esw->regmap, MT7628_ESW_REG_VUB(vlan),
+ MT7628_ESW_VUB_MASK(vlan),
+ MT7628_ESW_VUB_PREP(vlan, vub));
+}
+
+static void mt7628_vlan_sync(struct dsa_switch *ds)
+{
+ struct mt7628_esw *esw = ds->priv;
+ int i;
+
+ for (i = 0; i < MT7628_NUM_VLANS; i++) {
+ struct mt7628_vlan *vlan = &esw->vlans[i];
+
+ mt7628_esw_set_vmsc(esw, i, vlan->members);
+ mt7628_esw_set_vlan_id(esw, i, vlan->vid);
+ mt7628_esw_set_vub(esw, i, vlan->untag);
+ }
+
+ for (i = 0; i < ds->num_ports; i++)
+ mt7628_esw_set_pvid(esw, i, esw->tag_8021q_pvid[i]);
+}
+
+static int mt7628_setup(struct dsa_switch *ds)
+{
+ struct mt7628_esw *esw = ds->priv;
+ int ret;
+
+ ret = reset_control_reset(esw->rst_esw);
+ if (ret)
+ return ret;
+ usleep_range(1000, 2000);
+
+ ret = reset_control_reset(esw->rst_ephy);
+ if (ret)
+ return ret;
+ usleep_range(1000, 2000);
+ /*
+ * all MMIO reads hang if esw is not out of reset
+ * ephy needs extra time to get out of reset or it ends up misconfigured
+ */
+
+ mt7628_switch_init(ds);
+
+ ret = mt7628_setup_internal_mdio(ds);
+ if (ret)
+ return ret;
+
+ rtnl_lock();
+ ret = dsa_tag_8021q_register(ds, htons(ETH_P_8021Q));
+ rtnl_unlock();
+
+ return ret;
+}
+
+static int mt7628_port_enable(struct dsa_switch *ds, int port,
+ struct phy_device *phy)
+{
+ struct mt7628_esw *esw = ds->priv;
+
+ regmap_clear_bits(esw->regmap, MT7628_ESW_REG_POC0,
+ FIELD_PREP(MT7628_ESW_POC0_PORT_DISABLE, BIT(port)));
+ return 0;
+}
+
+static void mt7628_port_disable(struct dsa_switch *ds, int port)
+{
+ struct mt7628_esw *esw = ds->priv;
+
+ regmap_set_bits(esw->regmap, MT7628_ESW_REG_POC0,
+ FIELD_PREP(MT7628_ESW_POC0_PORT_DISABLE, BIT(port)));
+}
+
+static enum dsa_tag_protocol
+mt7628_get_tag_proto(struct dsa_switch *ds, int port, enum dsa_tag_protocol mp)
+{
+ return DSA_TAG_PROTO_MT7628;
+}
+
+static void mt7628_phylink_get_caps(struct dsa_switch *ds, int port,
+ struct phylink_config *config)
+{
+ switch (port) {
+ case 6:
+ config->mac_capabilities |= MAC_1000;
+ fallthrough;
+ case 0 ... 4:
+ config->mac_capabilities |= MAC_100 | MAC_10;
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ config->supported_interfaces);
+ break;
+ default:
+ break; /* port 5 does not exist on MT7628 */
+ }
+}
+
+static int mt7628_dsa_8021q_vlan_add(struct dsa_switch *ds, int port,
+ u16 vid, u16 flags)
+{
+ struct mt7628_esw *esw = ds->priv;
+ struct mt7628_vlan *vlan = NULL;
+ int i;
+
+ for (i = 0; i < MT7628_NUM_VLANS; i++) {
+ struct mt7628_vlan *check_vlan = &esw->vlans[i];
+
+ if (!check_vlan->active && !vlan)
+ vlan = check_vlan;
+
+ if (check_vlan->active && check_vlan->vid == vid) {
+ vlan = check_vlan;
+ break;
+ }
+ }
+
+ if (!vlan)
+ return -ENOSPC;
+
+ vlan->vid = vid;
+ vlan->active = true;
+ vlan->members |= BIT(port);
+
+ if (flags & BRIDGE_VLAN_INFO_PVID)
+ esw->tag_8021q_pvid[port] = vid;
+
+ if (flags & BRIDGE_VLAN_INFO_UNTAGGED)
+ vlan->untag |= BIT(port);
+
+ mt7628_vlan_sync(ds);
+ return 0;
+}
+
+static int mt7628_dsa_8021q_vlan_del(struct dsa_switch *ds, int port, u16 vid)
+{
+ struct mt7628_esw *esw = ds->priv;
+ struct mt7628_vlan *vlan = NULL;
+ int i;
+
+ for (i = 0; i < MT7628_NUM_VLANS; i++) {
+ struct mt7628_vlan *check_vlan = &esw->vlans[i];
+
+ if (!check_vlan->active || check_vlan->vid != vid)
+ continue;
+ vlan = check_vlan;
+ break;
+ }
+ if (!vlan)
+ return -ENOENT;
+
+ if (esw->tag_8021q_pvid[port] == vid)
+ esw->tag_8021q_pvid[port] = 0;
+
+ vlan->members &= ~BIT(port);
+ vlan->untag &= ~BIT(port);
+
+ if (!vlan->members) {
+ vlan->active = false;
+ vlan->vid = 0;
+ }
+
+ mt7628_vlan_sync(ds);
+ return 0;
+}
+
+static void mt7628_teardown(struct dsa_switch *ds)
+{
+ rtnl_lock();
+ dsa_tag_8021q_unregister(ds);
+ rtnl_unlock();
+}
+
+static const struct dsa_switch_ops mt7628_switch_ops = {
+ .get_tag_protocol = mt7628_get_tag_proto,
+ .setup = mt7628_setup,
+ .teardown = mt7628_teardown,
+ .port_enable = mt7628_port_enable,
+ .port_disable = mt7628_port_disable,
+ .phylink_get_caps = mt7628_phylink_get_caps,
+ .tag_8021q_vlan_add = mt7628_dsa_8021q_vlan_add,
+ .tag_8021q_vlan_del = mt7628_dsa_8021q_vlan_del,
+};
+
+static int mt7628_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct mt7628_esw *esw;
+ struct dsa_switch *ds;
+ void __iomem *base;
+
+ ds = devm_kzalloc(&pdev->dev, sizeof(*ds), GFP_KERNEL);
+ if (!ds)
+ return -ENOMEM;
+
+ esw = devm_kzalloc(&pdev->dev, sizeof(*esw), GFP_KERNEL);
+ if (!esw)
+ return -ENOMEM;
+
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ esw->regmap = devm_regmap_init_mmio(&pdev->dev, base,
+ &mt7628_esw_regmap_cfg);
+ if (IS_ERR(esw->regmap))
+ return PTR_ERR(esw->regmap);
+
+ esw->rst_ephy = devm_reset_control_get_exclusive(&pdev->dev, "ephy");
+ if (IS_ERR(esw->rst_ephy))
+ return dev_err_probe(dev, PTR_ERR(esw->rst_ephy),
+ "failed to get EPHY reset\n");
+
+ esw->rst_esw = devm_reset_control_get_exclusive(&pdev->dev, "esw");
+ if (IS_ERR(esw->rst_esw))
+ return dev_err_probe(dev, PTR_ERR(esw->rst_esw),
+ "failed to get ESW reset\n");
+
+ ds->dev = dev;
+ ds->num_ports = MT7628_ESW_NUM_PORTS;
+ ds->ops = &mt7628_switch_ops;
+ ds->priv = esw;
+ esw->ds = ds;
+ esw->dev = dev;
+ dev_set_drvdata(dev, esw);
+
+ return dsa_register_switch(ds);
+}
+
+static void mt7628_remove(struct platform_device *pdev)
+{
+ struct mt7628_esw *esw = platform_get_drvdata(pdev);
+
+ if (!esw)
+ return;
+
+ dsa_unregister_switch(esw->ds);
+}
+
+static void mt7628_shutdown(struct platform_device *pdev)
+{
+ struct mt7628_esw *esw = platform_get_drvdata(pdev);
+
+ if (!esw)
+ return;
+
+ dsa_switch_shutdown(esw->ds);
+ dev_set_drvdata(&pdev->dev, NULL);
+}
+
+static const struct of_device_id mt7628_of_match[] = {
+ { .compatible = "mediatek,mt7628-esw" },
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, mt7628_of_match);
+
+static struct platform_driver mt7628_driver = {
+ .driver = {
+ .name = "mt7628-esw",
+ .of_match_table = mt7628_of_match,
+ },
+ .probe = mt7628_probe,
+ .remove = mt7628_remove,
+ .shutdown = mt7628_shutdown,
+};
+
+module_platform_driver(mt7628_driver);
+
+MODULE_AUTHOR("Joris Vaisvila <joey@tinyisr.com>");
+MODULE_DESCRIPTION("Driver for Mediatek MT7628 embedded switch");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/phy/mediatek/Kconfig b/drivers/net/phy/mediatek/Kconfig
index bb7dc876271e83..b6a51f38c358ab 100644
--- a/drivers/net/phy/mediatek/Kconfig
+++ b/drivers/net/phy/mediatek/Kconfig
@@ -21,8 +21,16 @@ config MEDIATEK_GE_PHY
common operations with MediaTek SoC built-in Gigabit
Ethernet PHYs.
+config MEDIATEK_FE_SOC_PHY
+ tristate "MediaTek SoC Fast Ethernet PHYs"
+ help
+ Support for MediaTek MT7628 built-in Fast Ethernet PHYs.
+ This driver only sets an initialization bit required for the PHY
+ to establish 100 Mbps links. All other PHY operations are handled
+ by the kernel's generic PHY code.
+
config MEDIATEK_GE_SOC_PHY
- tristate "MediaTek SoC Ethernet PHYs"
+ tristate "MediaTek SoC Gigabit Ethernet PHYs"
depends on ARM64 || COMPILE_TEST
depends on ARCH_AIROHA || (ARCH_MEDIATEK && NVMEM_MTK_EFUSE) || \
COMPILE_TEST
diff --git a/drivers/net/phy/mediatek/Makefile b/drivers/net/phy/mediatek/Makefile
index ac57ecc799fc81..6f9cacf7f90657 100644
--- a/drivers/net/phy/mediatek/Makefile
+++ b/drivers/net/phy/mediatek/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_MEDIATEK_2P5GE_PHY) += mtk-2p5ge.o
+obj-$(CONFIG_MEDIATEK_FE_SOC_PHY) += mtk-fe-soc.o
obj-$(CONFIG_MEDIATEK_GE_PHY) += mtk-ge.o
obj-$(CONFIG_MEDIATEK_GE_SOC_PHY) += mtk-ge-soc.o
obj-$(CONFIG_MTK_NET_PHYLIB) += mtk-phy-lib.o
diff --git a/drivers/net/phy/mediatek/mtk-fe-soc.c b/drivers/net/phy/mediatek/mtk-fe-soc.c
new file mode 100644
index 00000000000000..9eb4960bcaade3
--- /dev/null
+++ b/drivers/net/phy/mediatek/mtk-fe-soc.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Driver for MT7628 Embedded Switch internal Fast Ethernet PHYs
+ */
+#include <linux/module.h>
+#include <linux/phy.h>
+
+#define MTK_FPHY_ID_MT7628 0x03a29410
+#define MTK_EXT_PAGE_ACCESS 0x1f
+
+static int mt7628_phy_read_page(struct phy_device *phydev)
+{
+ return __phy_read(phydev, MTK_EXT_PAGE_ACCESS);
+}
+
+static int mt7628_phy_write_page(struct phy_device *phydev, int page)
+{
+ return __phy_write(phydev, MTK_EXT_PAGE_ACCESS, page);
+}
+
+static int mt7628_phy_config_init(struct phy_device *phydev)
+{
+ /*
+ * This undocumented bit is required for the PHYs to be able to
+ * establish 100mbps links.
+ */
+ return phy_modify_paged(phydev, 0x8000, 30, BIT(13), BIT(13));
+}
+
+static struct phy_driver mtk_soc_fe_phy_driver[] = {
+ {
+ PHY_ID_MATCH_EXACT(MTK_FPHY_ID_MT7628),
+ .name = "MediaTek MT7628 PHY",
+ .config_init = mt7628_phy_config_init,
+ .read_page = mt7628_phy_read_page,
+ .write_page = mt7628_phy_write_page,
+ },
+};
+
+module_phy_driver(mtk_soc_fe_phy_driver);
+static const struct mdio_device_id __maybe_unused mtk_soc_fe_phy_tbl[] = {
+ { PHY_ID_MATCH_EXACT(MTK_FPHY_ID_MT7628) },
+ { }
+};
+
+MODULE_DESCRIPTION("MediaTek SoC Fast Ethernet PHY driver");
+MODULE_AUTHOR("Joris Vaisvila <joey@tinyisr.com>");
+MODULE_LICENSE("GPL");
+
+MODULE_DEVICE_TABLE(mdio, mtk_soc_fe_phy_tbl);
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 8c16ef23cc102a..913d1f71e3dbfe 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -59,6 +59,7 @@ struct tc_action;
#define DSA_TAG_PROTO_MXL_GSW1XX_VALUE 31
#define DSA_TAG_PROTO_MXL862_VALUE 32
#define DSA_TAG_PROTO_NETC_VALUE 33
+#define DSA_TAG_PROTO_MT7628_VALUE 34
enum dsa_tag_protocol {
DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
@@ -95,6 +96,7 @@ enum dsa_tag_protocol {
DSA_TAG_PROTO_MXL_GSW1XX = DSA_TAG_PROTO_MXL_GSW1XX_VALUE,
DSA_TAG_PROTO_MXL862 = DSA_TAG_PROTO_MXL862_VALUE,
DSA_TAG_PROTO_NETC = DSA_TAG_PROTO_NETC_VALUE,
+ DSA_TAG_PROTO_MT7628 = DSA_TAG_PROTO_MT7628_VALUE,
};
struct dsa_switch;
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index d5e725b90d7858..23b4b74004ed5e 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -98,6 +98,12 @@ config NET_DSA_TAG_EDSA
Say Y or M if you want to enable support for tagging frames for the
Marvell switches which use EtherType DSA headers.
+config NET_DSA_TAG_MT7628
+ tristate "Tag driver for the MT7628 embedded switch"
+ help
+ Say Y or M if you want to enable support for tagging frames for the
+ switch embedded in the MT7628 SoC.
+
config NET_DSA_TAG_MTK
tristate "Tag driver for Mediatek switches"
help
diff --git a/net/dsa/Makefile b/net/dsa/Makefile
index b8c2667cd14aad..d15bcf5c68f02a 100644
--- a/net/dsa/Makefile
+++ b/net/dsa/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_NET_DSA_TAG_GSWIP) += tag_gswip.o
obj-$(CONFIG_NET_DSA_TAG_HELLCREEK) += tag_hellcreek.o
obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o
obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o
+obj-$(CONFIG_NET_DSA_TAG_MT7628) += tag_mt7628.o
obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o
obj-$(CONFIG_NET_DSA_TAG_MXL_862XX) += tag_mxl862xx.o
obj-$(CONFIG_NET_DSA_TAG_MXL_GSW1XX) += tag_mxl-gsw1xx.o
diff --git a/net/dsa/tag_mt7628.c b/net/dsa/tag_mt7628.c
new file mode 100644
index 00000000000000..80b50ff08e53f5
--- /dev/null
+++ b/net/dsa/tag_mt7628.c
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2026, Joris Vaisvila <joey@tinyisr.com>
+ * MT7628 switch tag support
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/dsa/8021q.h>
+#include <net/dsa.h>
+
+#include "tag.h"
+
+/*
+ * The MT7628 tag is encoded in the VLAN TPID field.
+ * On TX the lower 6 bits encode the destination port bitmask.
+ * On RX the lower 3 bits encode the source port number.
+ *
+ * The switch hardware will not modify the TPID of an incoming packet if it is
+ * already VLAN tagged. To work around this the switch is configured to always
+ * append a tag_8021q standalone VLAN tag for each port. That means we can
+ * safely strip the outer VLAN tag after parsing it.
+ *
+ * A VLAN tag is constructed on egress to target the standalone VLAN and
+ * destination port.
+ */
+
+#define MT7628_TAG_NAME "mt7628"
+
+#define MT7628_TAG_TX_PORT GENMASK(5, 0)
+#define MT7628_TAG_RX_PORT GENMASK(2, 0)
+#define MT7628_TAG_LEN 4
+
+static struct sk_buff *mt7628_tag_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct dsa_port *dp;
+ u16 xmit_vlan;
+ __be16 *tag;
+
+ dp = dsa_user_to_port(dev);
+ xmit_vlan = dsa_tag_8021q_standalone_vid(dp);
+
+ skb_push(skb, MT7628_TAG_LEN);
+ dsa_alloc_etype_header(skb, MT7628_TAG_LEN);
+
+ tag = dsa_etype_header_pos_tx(skb);
+
+ tag[0] = htons(ETH_P_8021Q |
+ FIELD_PREP(MT7628_TAG_TX_PORT,
+ dsa_xmit_port_mask(skb, dev)));
+ tag[1] = htons(xmit_vlan);
+
+ return skb;
+}
+
+static struct sk_buff *mt7628_tag_rcv(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ __be16 *phdr;
+
+ if (unlikely(!pskb_may_pull(skb, MT7628_TAG_LEN))) {
+ kfree_skb(skb);
+ return NULL;
+ }
+
+ phdr = dsa_etype_header_pos_rx(skb);
+ skb->dev =
+ dsa_conduit_find_user(dev, 0,
+ FIELD_GET(MT7628_TAG_RX_PORT, ntohs(*phdr)));
+ if (!skb->dev) {
+ kfree_skb(skb);
+ return NULL;
+ }
+
+ skb_pull_rcsum(skb, MT7628_TAG_LEN);
+ dsa_strip_etype_header(skb, MT7628_TAG_LEN);
+ dsa_default_offload_fwd_mark(skb);
+ return skb;
+}
+
+static const struct dsa_device_ops mt7628_tag_ops = {
+ .name = MT7628_TAG_NAME,
+ .proto = DSA_TAG_PROTO_MT7628,
+ .xmit = mt7628_tag_xmit,
+ .rcv = mt7628_tag_rcv,
+ .needed_headroom = MT7628_TAG_LEN,
+};
+
+module_dsa_tag_driver(mt7628_tag_ops);
+
+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_MT7628, MT7628_TAG_NAME);
+MODULE_DESCRIPTION("DSA tag driver for MT7628 switch");
+MODULE_LICENSE("GPL");
|
| 3/2 | 2026/07/04 11:39 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 16370 output: 25 thoughts: 766 Thoughts: **Analyzing the Reachability of the MediaTek MT7628 Embedded Ethernet Switch Patch** Okay, so we have this new patch adding support for the MT7628 embedded Ethernet switch, and my initial thought is: how can we *actually* test this in a virtualized environment? The patch introduces a DSA driver (`mt7628.c`), a PHY driver (`mtk-fe-soc.c`), and a tag driver (`tag_mt7628.c`), along with some modifications to relevant Kconfig and Makefiles. First, let's think about the DSA driver itself. It's a platform driver, matching `mediatek,mt7628-esw`. Can we instantiate that? Syzkaller could *potentially* do it through its pseudo-device instantiation or device tree overlays. However, syzkaller generally doesn't do overlays on random drivers unless specifically told to. Wait, syzkaller *can* instantiate platform devices if they're part of `syz_mount_image` or similar mechanisms, and also I know syzkaller has a way to fuzz platform drivers if we can match them by name or create them via netlink or some other means. Does it have something like `syz_genetlink`? No, Syzkaller does device tree nodes. Hmm, it doesn't have a *generic* way to instantiate completely arbitrary platform devices unless they're explicitly defined. Now, that tag driver (`tag_mt7628.c`) is interesting. It's a DSA *tag* driver. I know DSA tag drivers get triggered if we can create a DSA switch or inject packets that use the tag protocol. But typically, the DSA switch driver sets that tag protocol, right? Can we configure it directly via netlink or sysfs? Okay, let's zoom in on `tag_mt7628.c`. It's registering with `module_dsa_tag_driver(mt7628_tag_ops)`. Can we get this tag driver to do something without the actual hardware? DSA has a way to set the tag protocol through `dsa_switch_ops`, or *maybe* netlink. The functions are `mt7628_tag_xmit` and `mt7628_tag_rcv`. They're invoked when packets are sent or received on a DSA port. Can syzkaller *create* a dummy DSA switch? Maybe there's something like `syz_dsa_setup`? I'll check if syzkaller has any DSA fuzzing descriptions. No? Okay, it looks like syzkaller does its DSA fuzzing by potentially creating a dummy DSA switch, maybe? Wait a second… syzkaller does fuzz network packets. If we can get a DSA interface created, we might be able to fuzz those `mt7628_tag_xmit` and `mt7628_tag_rcv` functions. That's the key. Let's see if `dsa_tag_8021q_standalone_vid` is used anywhere to understand how this tag driver works. I'm also going to search for `NET_DSA_TAG_MT7628` and `NET_DSA_MT7628` to see where the driver registers and sets itself up within the DSA framework. We need to leverage syzkaller's existing network fuzzing capabilities. That seems like the most promising path. |
| 4/2 | 2026/07/04 11:39 | tool | grepper |
0mArgs:{
"Expression": "NET_DSA_TAG_MT7628"
}Results: {
"Output": "drivers/net/dsa/Kconfig=66=config NET_DSA_MT7628\ndrivers/net/dsa/Kconfig-67-\ttristate \"MediaTek MT7628 Embedded Ethernet switch support\"\ndrivers/net/dsa/Kconfig:68:\tselect NET_DSA_TAG_MT7628\ndrivers/net/dsa/Kconfig-69-\tselect MEDIATEK_FE_SOC_PHY\n--\nnet/dsa/Kconfig=94=config NET_DSA_TAG_EDSA\n--\nnet/dsa/Kconfig-100-\nnet/dsa/Kconfig:101:config NET_DSA_TAG_MT7628\nnet/dsa/Kconfig-102-\ttristate \"Tag driver for the MT7628 embedded switch\"\n--\nnet/dsa/Makefile=29=obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o\nnet/dsa/Makefile:30:obj-$(CONFIG_NET_DSA_TAG_MT7628) += tag_mt7628.o\nnet/dsa/Makefile-31-obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o\n"
} |
| 5/2 | 2026/07/04 11:39 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 18230 output: 20 thoughts: 1246 Thoughts: **Analyzing Reachability of MT7628 Network Components in a Virtualized Environment**
Okay, let's break this down. My immediate concern is whether we can even hit `mt7628_tag_rcv` or `mt7628_tag_xmit` in a scenario that isn't running on actual MT7628 hardware. Remember, the DSA tag drivers are registered, and they're triggered based on the packet's protocol or via the master device's `tag_ops` pointer.
The obvious question: can we even get the `mt7628` platform device instantiated? Looking at the driver's structure, `mt7628_driver`, it's a platform driver. It relies on `devm_platform_ioremap_resource` for MMIO, which *demands* specific hardware resources. It also needs reset controls ("ephy" and "esw").
Now, thinking about a virtualized environment like QEMU or GCE (and we know syzkaller primarily uses x86_64 or arm64 `virt` machines). Unless we're running a QEMU machine meticulously emulating MT7628 – and we're not – the device tree will *not* contain the necessary node. Even if we somehow injected a device tree node, the MMIO reads/writes would be doomed to failure. They'd either crash (because of invalid memory access) or time out.
I see a problem even if we *could* force a DT node. Let's say we point the MMIO region to RAM. The driver is still going to expect specific *hardware* behavior. For example, `regmap_read_poll_timeout` is waiting for a *bit* to be set in a register. If it's just RAM, that bit won't magically change, and we'll hit a timeout. So, even if the mapping succeeds, `mt7628_probe` will ultimately fail.
In fact, `mt7628_probe` explicitly fails if the resets aren't found. We're looking at `devm_reset_control_get_exclusive(&pdev->dev, "ephy")` here. These reset controllers *require* a reset controller defined in the device tree. If the device tree doesn't have it, or we try to register it using `platform_device_register` without a DT, there are no reset controls. This means `mt7628_probe` will *always* fail very early in a virtualized environment. It's practically unreachable.
Okay, let's shift focus. What about the PHY driver, `mtk-fe-soc.c`? I see a `mtk_soc_fe_phy_driver` that includes an exact ID match for `MTK_FPHY_ID_MT7628`. Can we get this loaded? Syzkaller's common entry points - like `syz_mac80211_hwsim`, `syz_usb_connect`, or `tun` - don't instantiate random MDIO PHYs with the ID `0x03a29410`. Do we have a `syz_mdio_setup` equivalent? No. The only real way to get to `mt7628_phy_config_init` is if an MDIO bus is created and *finds* that PHY during a scan, or it’s explicitly instantiated. Since we're not on the hardware, the MDIO bus isn't going to magically find that PHY.
What about the DSA tag driver, `tag_mt7628.c`? Is there *any* general method to attach a DSA tag driver to a simulated network interface? I will now turn my attention to investigate whether a netlink interface can be utilized to modify the DSA tag protocol.
|
| 6/2 | 2026/07/04 11:39 | tool | grepper |
0mArgs:{
"Expression": "dsa_switch_ops"
}Results: {
"Output": "Documentation/networking/dsa/dsa.rst=378=DSA data structures are defined in ``include/net/dsa.h`` as well as\n--\nDocumentation/networking/dsa/dsa.rst-394- a ``dsa_switch_tree`` as a backpointer, user network devices, conduit network\nDocumentation/networking/dsa/dsa.rst:395: device, and a reference to the backing``dsa_switch_ops``\nDocumentation/networking/dsa/dsa.rst-396-\nDocumentation/networking/dsa/dsa.rst:397:- ``dsa_switch_ops``: structure referencing function pointers, see below for a\nDocumentation/networking/dsa/dsa.rst-398- full description.\n--\nDocumentation/networking/dsa/dsa.rst=516=Driver development\n--\nDocumentation/networking/dsa/dsa.rst-518-\nDocumentation/networking/dsa/dsa.rst:519:DSA switch drivers need to implement a ``dsa_switch_ops`` structure which will\nDocumentation/networking/dsa/dsa.rst-520-contain the various members described below.\n--\nDocumentation/networking/dsa/dsa.rst=532=provided structure:\n--\nDocumentation/networking/dsa/dsa.rst-538-\nDocumentation/networking/dsa/dsa.rst:539:- ``ds-\u003eops``: a pointer to the ``dsa_switch_ops`` structure holding the DSA\nDocumentation/networking/dsa/dsa.rst-540- method implementations.\n--\nDocumentation/networking/dsa/dsa.rst=602=After ``dsa_switch_shutdown()`` or ``dsa_unregister_switch()`` was called, no\nDocumentation/networking/dsa/dsa.rst:603:further callbacks via the provided ``dsa_switch_ops`` may take place, and the\nDocumentation/networking/dsa/dsa.rst-604-driver may free the data structures associated with the ``dsa_switch``.\n--\nDocumentation/networking/dsa/dsa.rst=606=Switch configuration\n--\nDocumentation/networking/dsa/dsa.rst-622-- ``setup``: setup function for the switch, this function is responsible for setting\nDocumentation/networking/dsa/dsa.rst:623: up the ``dsa_switch_ops`` private structure with all it needs: register maps,\nDocumentation/networking/dsa/dsa.rst-624- interrupts, mutexes, locks, etc. This function is also expected to properly\n--\nDocumentation/networking/dsa/dsa.rst=1051=Drivers that benefit from having an ID associated with each offloaded LAG\nDocumentation/networking/dsa/dsa.rst:1052:can optionally populate ``ds-\u003enum_lag_ids`` from the ``dsa_switch_ops::setup``\nDocumentation/networking/dsa/dsa.rst-1053-method. The LAG ID associated with a bonding/team interface can then be\n--\ndrivers/net/dsa/b53/b53_common.c=2694=static const struct phylink_mac_ops b53_phylink_mac_ops = {\n--\ndrivers/net/dsa/b53/b53_common.c-2700-\ndrivers/net/dsa/b53/b53_common.c:2701:static const struct dsa_switch_ops b53_switch_ops = {\ndrivers/net/dsa/b53/b53_common.c-2702-\t.get_tag_protocol\t= b53_get_tag_protocol,\n--\ndrivers/net/dsa/bcm_sf2.c=1216=static const struct phylink_mac_ops bcm_sf2_phylink_mac_ops = {\n--\ndrivers/net/dsa/bcm_sf2.c-1221-\ndrivers/net/dsa/bcm_sf2.c:1222:static const struct dsa_switch_ops bcm_sf2_ops = {\ndrivers/net/dsa/bcm_sf2.c-1223-\t.get_tag_protocol\t= b53_get_tag_protocol,\n--\ndrivers/net/dsa/bcm_sf2.c=1365=static int bcm_sf2_sw_probe(struct platform_device *pdev)\n--\ndrivers/net/dsa/bcm_sf2.c-1371-\tstruct b53_platform_data *pdata;\ndrivers/net/dsa/bcm_sf2.c:1372:\tstruct dsa_switch_ops *ops;\ndrivers/net/dsa/bcm_sf2.c-1373-\tstruct device_node *ports;\n--\ndrivers/net/dsa/dsa_loop.c=326=static void dsa_loop_phylink_get_caps(struct dsa_switch *dsa, int port,\n--\ndrivers/net/dsa/dsa_loop.c-333-\ndrivers/net/dsa/dsa_loop.c:334:static const struct dsa_switch_ops dsa_loop_driver = {\ndrivers/net/dsa/dsa_loop.c-335-\t.get_tag_protocol\t= dsa_loop_get_protocol,\n--\ndrivers/net/dsa/hirschmann/hellcreek.c=1872=static int hellcreek_port_setup_tc(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/hirschmann/hellcreek.c-1899-\ndrivers/net/dsa/hirschmann/hellcreek.c:1900:static const struct dsa_switch_ops hellcreek_ds_ops = {\ndrivers/net/dsa/hirschmann/hellcreek.c-1901-\t.devlink_info_get = hellcreek_devlink_info_get,\n--\ndrivers/net/dsa/ks8995.c=727=static int ks8995_get_max_mtu(struct dsa_switch *ds, int port)\n--\ndrivers/net/dsa/ks8995.c-731-\ndrivers/net/dsa/ks8995.c:732:static const struct dsa_switch_ops ks8995_ds_ops = {\ndrivers/net/dsa/ks8995.c-733-\t.get_tag_protocol = ks8995_get_tag_protocol,\n--\ndrivers/net/dsa/lan9303-core.c=1376=static const struct phylink_mac_ops lan9303_phylink_mac_ops = {\n--\ndrivers/net/dsa/lan9303-core.c-1381-\ndrivers/net/dsa/lan9303-core.c:1382:static const struct dsa_switch_ops lan9303_switch_ops = {\ndrivers/net/dsa/lan9303-core.c-1383-\t.get_tag_protocol\t= lan9303_get_tag_protocol,\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c=1614=static const struct phylink_mac_ops gswip_phylink_mac_ops = {\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1622-\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:1623:static const struct dsa_switch_ops gswip_switch_ops = {\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-1624-\t.get_tag_protocol\t= gswip_get_tag_protocol,\n--\ndrivers/net/dsa/microchip/ksz8.c=2512=const struct ksz_dev_ops ksz88xx_dev_ops = {\n--\ndrivers/net/dsa/microchip/ksz8.c-2525-\ndrivers/net/dsa/microchip/ksz8.c:2526:const struct dsa_switch_ops ksz8463_switch_ops = {\ndrivers/net/dsa/microchip/ksz8.c-2527-\t.get_tag_protocol\t= ksz8463_get_tag_protocol,\n--\ndrivers/net/dsa/microchip/ksz8.c-2572-\ndrivers/net/dsa/microchip/ksz8.c:2573:const struct dsa_switch_ops ksz87xx_switch_ops = {\ndrivers/net/dsa/microchip/ksz8.c-2574-\t.get_tag_protocol\t= ksz87xx_get_tag_protocol,\n--\ndrivers/net/dsa/microchip/ksz8.c-2622-\ndrivers/net/dsa/microchip/ksz8.c:2623:const struct dsa_switch_ops ksz88xx_switch_ops = {\ndrivers/net/dsa/microchip/ksz8.c-2624-\t.get_tag_protocol\t= ksz88xx_get_tag_protocol,\n--\ndrivers/net/dsa/microchip/ksz8.h=19=extern const struct phylink_mac_ops ksz8_phylink_mac_ops;\ndrivers/net/dsa/microchip/ksz8.h:20:extern const struct dsa_switch_ops ksz8463_switch_ops;\ndrivers/net/dsa/microchip/ksz8.h:21:extern const struct dsa_switch_ops ksz87xx_switch_ops;\ndrivers/net/dsa/microchip/ksz8.h:22:extern const struct dsa_switch_ops ksz88xx_switch_ops;\ndrivers/net/dsa/microchip/ksz8.h-23-\n--\ndrivers/net/dsa/microchip/ksz9477.c=2050=const struct ksz_dev_ops ksz9477_dev_ops = {\n--\ndrivers/net/dsa/microchip/ksz9477.c-2064-\ndrivers/net/dsa/microchip/ksz9477.c:2065:const struct dsa_switch_ops ksz9477_switch_ops = {\ndrivers/net/dsa/microchip/ksz9477.c-2066-\t.get_tag_protocol\t= ksz9477_get_tag_protocol,\n--\ndrivers/net/dsa/microchip/ksz9477.h=93=extern const struct phylink_mac_ops ksz9477_phylink_mac_ops;\ndrivers/net/dsa/microchip/ksz9477.h:94:extern const struct dsa_switch_ops ksz9477_switch_ops;\ndrivers/net/dsa/microchip/ksz9477.h-95-\n--\ndrivers/net/dsa/microchip/ksz_common.h=57=struct ksz_chip_data {\n--\ndrivers/net/dsa/microchip/ksz_common.h-75-\tconst struct ksz_dev_ops *ops;\ndrivers/net/dsa/microchip/ksz_common.h:76:\tconst struct dsa_switch_ops *switch_ops;\ndrivers/net/dsa/microchip/ksz_common.h-77-\tconst struct phylink_mac_ops *phylink_mac_ops;\n--\ndrivers/net/dsa/microchip/lan937x.h=10=extern const struct phylink_mac_ops lan937x_phylink_mac_ops;\ndrivers/net/dsa/microchip/lan937x.h:11:extern const struct dsa_switch_ops lan937x_switch_ops;\ndrivers/net/dsa/microchip/lan937x.h-12-\n--\ndrivers/net/dsa/microchip/lan937x_main.c=941=const struct ksz_dev_ops lan937x_dev_ops = {\n--\ndrivers/net/dsa/microchip/lan937x_main.c-952-\ndrivers/net/dsa/microchip/lan937x_main.c:953:const struct dsa_switch_ops lan937x_switch_ops = {\ndrivers/net/dsa/microchip/lan937x_main.c-954-\t.get_tag_protocol\t= lan937x_get_tag_protocol,\n--\ndrivers/net/dsa/mt7530.c=3322=static int mt7988_setup(struct dsa_switch *ds)\n--\ndrivers/net/dsa/mt7530.c-3347-\ndrivers/net/dsa/mt7530.c:3348:static const struct dsa_switch_ops mt7530_switch_ops = {\ndrivers/net/dsa/mt7530.c-3349-\t.get_tag_protocol\t= mtk_get_tag_protocol,\n--\ndrivers/net/dsa/mt7628.c=544=static void mt7628_teardown(struct dsa_switch *ds)\n--\ndrivers/net/dsa/mt7628.c-550-\ndrivers/net/dsa/mt7628.c:551:static const struct dsa_switch_ops mt7628_switch_ops = {\ndrivers/net/dsa/mt7628.c-552-\t.get_tag_protocol = mt7628_get_tag_proto,\n--\ndrivers/net/dsa/mv88e6060.c=250=static void mv88e6060_phylink_get_caps(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/mv88e6060.c-293-\ndrivers/net/dsa/mv88e6060.c:294:static const struct dsa_switch_ops mv88e6060_switch_ops = {\ndrivers/net/dsa/mv88e6060.c-295-\t.get_tag_protocol = mv88e6060_get_tag_protocol,\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=7178=static const struct phylink_mac_ops mv88e6xxx_phylink_mac_ops = {\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-7186-\ndrivers/net/dsa/mv88e6xxx/chip.c:7187:static const struct dsa_switch_ops mv88e6xxx_switch_ops = {\ndrivers/net/dsa/mv88e6xxx/chip.c-7188-\t.get_tag_protocol\t= mv88e6xxx_get_tag_protocol,\n--\ndrivers/net/dsa/mxl862xx/mxl862xx.c=2026=static void mxl862xx_get_stats64(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/mxl862xx/mxl862xx.c-2056-\ndrivers/net/dsa/mxl862xx/mxl862xx.c:2057:static const struct dsa_switch_ops mxl862xx_switch_ops = {\ndrivers/net/dsa/mxl862xx/mxl862xx.c-2058-\t.get_tag_protocol = mxl862xx_get_tag_protocol,\n--\ndrivers/net/dsa/netc/netc_main.c=2397=static const struct phylink_mac_ops netc_phylink_mac_ops = {\n--\ndrivers/net/dsa/netc/netc_main.c-2402-\ndrivers/net/dsa/netc/netc_main.c:2403:static const struct dsa_switch_ops netc_switch_ops = {\ndrivers/net/dsa/netc/netc_main.c-2404-\t.get_tag_protocol\t\t= netc_get_tag_protocol,\n--\ndrivers/net/dsa/ocelot/felix.c=2299=static const struct phylink_mac_ops felix_phylink_mac_ops = {\n--\ndrivers/net/dsa/ocelot/felix.c-2305-\ndrivers/net/dsa/ocelot/felix.c:2306:static const struct dsa_switch_ops felix_switch_ops = {\ndrivers/net/dsa/ocelot/felix.c-2307-\t.get_tag_protocol\t\t= felix_get_tag_protocol,\n--\ndrivers/net/dsa/qca/ar9331.c=238=struct ar9331_sw_priv {\n--\ndrivers/net/dsa/qca/ar9331.c-240-\tstruct dsa_switch ds;\ndrivers/net/dsa/qca/ar9331.c:241:\tstruct dsa_switch_ops ops;\ndrivers/net/dsa/qca/ar9331.c-242-\tstruct irq_domain *irqdomain;\n--\ndrivers/net/dsa/qca/ar9331.c=690=static const struct phylink_mac_ops ar9331_phylink_mac_ops = {\n--\ndrivers/net/dsa/qca/ar9331.c-695-\ndrivers/net/dsa/qca/ar9331.c:696:static const struct dsa_switch_ops ar9331_sw_ops = {\ndrivers/net/dsa/qca/ar9331.c-697-\t.get_tag_protocol\t= ar9331_sw_get_tag_protocol,\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=2014=static const struct phylink_mac_ops qca8k_phylink_mac_ops = {\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-2020-\ndrivers/net/dsa/qca/qca8k-8xxx.c:2021:static const struct dsa_switch_ops qca8k_switch_ops = {\ndrivers/net/dsa/qca/qca8k-8xxx.c-2022-\t.get_tag_protocol\t= qca8k_get_tag_protocol,\n--\ndrivers/net/dsa/realtek/realtek.h=161=struct realtek_variant {\ndrivers/net/dsa/realtek/realtek.h:162:\tconst struct dsa_switch_ops *ds_ops;\ndrivers/net/dsa/realtek/realtek.h-163-\tconst struct realtek_ops *ops;\n--\ndrivers/net/dsa/realtek/rtl8365mb_main.c=2660=static const struct phylink_mac_ops rtl8365mb_phylink_mac_ops = {\n--\ndrivers/net/dsa/realtek/rtl8365mb_main.c-2665-\ndrivers/net/dsa/realtek/rtl8365mb_main.c:2666:static const struct dsa_switch_ops rtl8365mb_switch_ops = {\ndrivers/net/dsa/realtek/rtl8365mb_main.c-2667-\t.get_tag_protocol = rtl8365mb_get_tag_protocol,\n--\ndrivers/net/dsa/realtek/rtl8366rb.c=1782=static const struct phylink_mac_ops rtl8366rb_phylink_mac_ops = {\n--\ndrivers/net/dsa/realtek/rtl8366rb.c-1787-\ndrivers/net/dsa/realtek/rtl8366rb.c:1788:static const struct dsa_switch_ops rtl8366rb_switch_ops = {\ndrivers/net/dsa/realtek/rtl8366rb.c-1789-\t.get_tag_protocol = rtl8366_get_tag_protocol,\n--\ndrivers/net/dsa/rzn1_a5psw.c=1004=static const struct phylink_mac_ops a5psw_phylink_mac_ops = {\n--\ndrivers/net/dsa/rzn1_a5psw.c-1010-\ndrivers/net/dsa/rzn1_a5psw.c:1011:static const struct dsa_switch_ops a5psw_switch_ops = {\ndrivers/net/dsa/rzn1_a5psw.c-1012-\t.get_tag_protocol = a5psw_get_tag_protocol,\n--\ndrivers/net/dsa/sja1105/sja1105_main.c=3136=static const struct phylink_mac_ops sja1105_phylink_mac_ops = {\n--\ndrivers/net/dsa/sja1105/sja1105_main.c-3142-\ndrivers/net/dsa/sja1105/sja1105_main.c:3143:static const struct dsa_switch_ops sja1105_switch_ops = {\ndrivers/net/dsa/sja1105/sja1105_main.c-3144-\t.get_tag_protocol\t= sja1105_get_tag_protocol,\n--\ndrivers/net/dsa/vitesse-vsc73xx-core.c=2212=static const struct phylink_mac_ops vsc73xx_phylink_mac_ops = {\n--\ndrivers/net/dsa/vitesse-vsc73xx-core.c-2217-\ndrivers/net/dsa/vitesse-vsc73xx-core.c:2218:static const struct dsa_switch_ops vsc73xx_ds_ops = {\ndrivers/net/dsa/vitesse-vsc73xx-core.c-2219-\t.get_tag_protocol = vsc73xx_get_tag_protocol,\n--\ndrivers/net/dsa/xrs700x/xrs700x.c=723=static const struct phylink_mac_ops xrs700x_phylink_mac_ops = {\n--\ndrivers/net/dsa/xrs700x/xrs700x.c-728-\ndrivers/net/dsa/xrs700x/xrs700x.c:729:static const struct dsa_switch_ops xrs700x_ops = {\ndrivers/net/dsa/xrs700x/xrs700x.c-730-\t.get_tag_protocol\t= xrs700x_get_tag_protocol,\n--\ndrivers/net/dsa/yt921x.c=4792=static const struct phylink_mac_ops yt921x_phylink_mac_ops = {\n--\ndrivers/net/dsa/yt921x.c-4797-\ndrivers/net/dsa/yt921x.c:4798:static const struct dsa_switch_ops yt921x_dsa_switch_ops = {\ndrivers/net/dsa/yt921x.c-4799-\t/* mib */\n--\ndrivers/net/dsa/yt921x.c=4914=static int yt921x_mdio_probe(struct mdio_device *mdiodev)\n--\ndrivers/net/dsa/yt921x.c-4949-\tds-\u003epriv = priv;\ndrivers/net/dsa/yt921x.c:4950:\tds-\u003eops = \u0026yt921x_dsa_switch_ops;\ndrivers/net/dsa/yt921x.c-4951-\tds-\u003eageing_time_min = 1 * 5000;\n--\ninclude/net/dsa.h=383=struct dsa_switch {\n--\ninclude/net/dsa.h-472-\t */\ninclude/net/dsa.h:473:\tconst struct dsa_switch_ops\t*ops;\ninclude/net/dsa.h-474-\n--\ninclude/net/dsa.h=860=typedef int dsa_fdb_dump_cb_t(const unsigned char *addr, u16 vid,\ninclude/net/dsa.h-861-\t\t\t bool is_static, void *data);\ninclude/net/dsa.h:862:struct dsa_switch_ops {\ninclude/net/dsa.h-863-\t/*\n"
} |
| 7/2 | 2026/07/04 11:39 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 26738 output: 20 thoughts: 217 Thoughts: **Analyzing the Tag Protocol Implementation**
Okay, so I'm digging into how the tag protocol works within this DSA switch framework. My understanding is that the `get_tag_protocol` function within `dsa_switch_ops` is the key to determining the appropriate tagging method. Specifically, for the `tag_mt7628.c` driver to be engaged, the switch needs to advertise `DSA_TAG_PROTO_MT7628` through that function. It seems the `mt7628_switch_ops` in `drivers/net/dsa/mt7628.c` is the only one I've encountered so far that actually does this:
```c
static enum dsa_tag_protocol
mt7628_get_tag_proto(struct dsa_switch *ds, int port, enum dsa_tag_protocol mp)
{
return DSA_TAG_PROTO_MT7628;
}
```
... which, makes sense. But, I wonder, is there *any* other mechanism for setting this tag protocol? I'm aware of the expected behavior, but I'm trying to be exhaustive here. Ah, right, I remember now, there's the sysfs attribute for DSA ports to modify the tag protocol! That opens up some interesting possibilities. I'll need to double-check whether we can modify the tag protocol through sysfs or potentially even netlink. That might give me some more control over this.
|
| 8/2 | 2026/07/04 11:40 | tool | grepper |
0mArgs:{
"Expression": "dsa_tag_protocol"
}Results: {
"Output": "Documentation/networking/dsa/dsa.rst=606=Switch configuration\n--\nDocumentation/networking/dsa/dsa.rst-609-- ``get_tag_protocol``: this is to indicate what kind of tagging protocol is\nDocumentation/networking/dsa/dsa.rst:610: supported, should be a valid value from the ``dsa_tag_protocol`` enum.\nDocumentation/networking/dsa/dsa.rst-611- The returned information does not have to be static; the driver is passed the\n--\ndrivers/net/dsa/b53/b53_common.c=2478=static bool b53_can_enable_brcm_tags(struct dsa_switch *ds, int port,\ndrivers/net/dsa/b53/b53_common.c:2479:\t\t\t\t enum dsa_tag_protocol tag_protocol)\ndrivers/net/dsa/b53/b53_common.c-2480-{\n--\ndrivers/net/dsa/b53/b53_common.c-2503-\ndrivers/net/dsa/b53/b53_common.c:2504:enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port,\ndrivers/net/dsa/b53/b53_common.c:2505:\t\t\t\t\t enum dsa_tag_protocol mprot)\ndrivers/net/dsa/b53/b53_common.c-2506-{\n--\ndrivers/net/dsa/b53/b53_priv.h=133=struct b53_device {\n--\ndrivers/net/dsa/b53/b53_priv.h-154-\tu16 num_arl_buckets;\ndrivers/net/dsa/b53/b53_priv.h:155:\tenum dsa_tag_protocol tag_protocol;\ndrivers/net/dsa/b53/b53_priv.h-156-\n--\ndrivers/net/dsa/b53/b53_priv.h=547=int b53_mirror_add(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/b53/b53_priv.h-549-\t\t struct netlink_ext_ack *extack);\ndrivers/net/dsa/b53/b53_priv.h:550:enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds, int port,\ndrivers/net/dsa/b53/b53_priv.h:551:\t\t\t\t\t enum dsa_tag_protocol mprot);\ndrivers/net/dsa/b53/b53_priv.h-552-void b53_mirror_del(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/dsa_loop.c=97=static int dsa_loop_setup_devlink_resources(struct dsa_switch *ds)\n--\ndrivers/net/dsa/dsa_loop.c-124-\ndrivers/net/dsa/dsa_loop.c:125:static enum dsa_tag_protocol dsa_loop_get_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/dsa_loop.c-126-\t\t\t\t\t\t int port,\ndrivers/net/dsa/dsa_loop.c:127:\t\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/dsa_loop.c-128-{\n--\ndrivers/net/dsa/hirschmann/hellcreek.c=227=static void hellcreek_feature_detect(struct hellcreek *hellcreek)\n--\ndrivers/net/dsa/hirschmann/hellcreek.c-239-\ndrivers/net/dsa/hirschmann/hellcreek.c:240:static enum dsa_tag_protocol hellcreek_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/hirschmann/hellcreek.c-241-\t\t\t\t\t\t\tint port,\ndrivers/net/dsa/hirschmann/hellcreek.c:242:\t\t\t\t\t\t\tenum dsa_tag_protocol mp)\ndrivers/net/dsa/hirschmann/hellcreek.c-243-{\n--\ndrivers/net/dsa/ks8995.c=530=static enum\ndrivers/net/dsa/ks8995.c:531:dsa_tag_protocol ks8995_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/ks8995.c-532-\t\t\t\t\t int port,\ndrivers/net/dsa/ks8995.c:533:\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/ks8995.c-534-{\n--\ndrivers/net/dsa/lan9303-core.c=867=static int lan9303_check_device(struct lan9303 *chip)\n--\ndrivers/net/dsa/lan9303-core.c-936-\ndrivers/net/dsa/lan9303-core.c:937:static enum dsa_tag_protocol lan9303_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/lan9303-core.c-938-\t\t\t\t\t\t int port,\ndrivers/net/dsa/lan9303-core.c:939:\t\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/lan9303-core.c-940-{\n--\ndrivers/net/dsa/lantiq/lantiq_gswip.h=255=struct gswip_hw_info {\n--\ndrivers/net/dsa/lantiq/lantiq_gswip.h-262-\tsize_t pce_microcode_size;\ndrivers/net/dsa/lantiq/lantiq_gswip.h:263:\tenum dsa_tag_protocol tag_protocol;\ndrivers/net/dsa/lantiq/lantiq_gswip.h-264-\tvoid (*phylink_get_caps)(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c=742=static void gswip_teardown(struct dsa_switch *ds)\n--\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-748-\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:749:static enum dsa_tag_protocol gswip_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-750-\t\t\t\t\t\t int port,\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c:751:\t\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/lantiq/lantiq_gswip_common.c-752-{\n--\ndrivers/net/dsa/microchip/ksz8.c=2382=static int ksz8_switch_init(struct ksz_device *dev)\n--\ndrivers/net/dsa/microchip/ksz8.c-2390-\ndrivers/net/dsa/microchip/ksz8.c:2391:static enum dsa_tag_protocol ksz8463_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/microchip/ksz8.c-2392-\t\t\t\t\t\t int port,\ndrivers/net/dsa/microchip/ksz8.c:2393:\t\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/microchip/ksz8.c-2394-{\n--\ndrivers/net/dsa/microchip/ksz8.c=2398=static int ksz8463_connect_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/microchip/ksz8.c:2399:\t\t\t\t\tenum dsa_tag_protocol proto)\ndrivers/net/dsa/microchip/ksz8.c-2400-{\n--\ndrivers/net/dsa/microchip/ksz8.c-2411-\ndrivers/net/dsa/microchip/ksz8.c:2412:static enum dsa_tag_protocol ksz87xx_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/microchip/ksz8.c-2413-\t\t\t\t\t\t int port,\ndrivers/net/dsa/microchip/ksz8.c:2414:\t\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/microchip/ksz8.c-2415-{\n--\ndrivers/net/dsa/microchip/ksz8.c=2419=static int ksz87xx_connect_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/microchip/ksz8.c:2420:\t\t\t\t\tenum dsa_tag_protocol proto)\ndrivers/net/dsa/microchip/ksz8.c-2421-{\n--\ndrivers/net/dsa/microchip/ksz8.c-2427-\ndrivers/net/dsa/microchip/ksz8.c:2428:static enum dsa_tag_protocol ksz88xx_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/microchip/ksz8.c-2429-\t\t\t\t\t\t int port,\ndrivers/net/dsa/microchip/ksz8.c:2430:\t\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/microchip/ksz8.c-2431-{\n--\ndrivers/net/dsa/microchip/ksz8.c=2440=static int ksz88xx_connect_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/microchip/ksz8.c:2441:\t\t\t\t\tenum dsa_tag_protocol proto)\ndrivers/net/dsa/microchip/ksz8.c-2442-{\n--\ndrivers/net/dsa/microchip/ksz9477.c=1820=static int ksz9477_switch_init(struct ksz_device *dev)\n--\ndrivers/net/dsa/microchip/ksz9477.c-1839-\ndrivers/net/dsa/microchip/ksz9477.c:1840:static enum dsa_tag_protocol ksz9477_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/microchip/ksz9477.c-1841-\t\t\t\t\t\t int port,\ndrivers/net/dsa/microchip/ksz9477.c:1842:\t\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/microchip/ksz9477.c-1843-{\n--\ndrivers/net/dsa/microchip/ksz9477.c=1854=static int ksz9477_connect_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/microchip/ksz9477.c:1855:\t\t\t\t\tenum dsa_tag_protocol proto)\ndrivers/net/dsa/microchip/ksz9477.c-1856-{\n--\ndrivers/net/dsa/microchip/lan937x_main.c=768=static int lan937x_setup(struct dsa_switch *ds)\n--\ndrivers/net/dsa/microchip/lan937x_main.c-911-\ndrivers/net/dsa/microchip/lan937x_main.c:912:static enum dsa_tag_protocol lan937x_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/microchip/lan937x_main.c-913-\t\t\t\t\t\t int port,\ndrivers/net/dsa/microchip/lan937x_main.c:914:\t\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/microchip/lan937x_main.c-915-{\n--\ndrivers/net/dsa/microchip/lan937x_main.c=919=static int lan937x_connect_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/microchip/lan937x_main.c:920:\t\t\t\t\tenum dsa_tag_protocol proto)\ndrivers/net/dsa/microchip/lan937x_main.c-921-{\n--\ndrivers/net/dsa/mt7530.c=2132=static void mt753x_port_mirror_del(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/mt7530.c-2154-\ndrivers/net/dsa/mt7530.c:2155:static enum dsa_tag_protocol\ndrivers/net/dsa/mt7530.c-2156-mtk_get_tag_protocol(struct dsa_switch *ds, int port,\ndrivers/net/dsa/mt7530.c:2157:\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/mt7530.c-2158-{\n--\ndrivers/net/dsa/mt7628.c=445=static void mt7628_port_disable(struct dsa_switch *ds, int port)\n--\ndrivers/net/dsa/mt7628.c-452-\ndrivers/net/dsa/mt7628.c:453:static enum dsa_tag_protocol\ndrivers/net/dsa/mt7628.c:454:mt7628_get_tag_proto(struct dsa_switch *ds, int port, enum dsa_tag_protocol mp)\ndrivers/net/dsa/mt7628.c-455-{\n--\ndrivers/net/dsa/mv88e6060.c=27=static const char *mv88e6060_get_name(struct mii_bus *bus, int sw_addr)\n--\ndrivers/net/dsa/mv88e6060.c-44-\ndrivers/net/dsa/mv88e6060.c:45:static enum dsa_tag_protocol mv88e6060_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/mv88e6060.c-46-\t\t\t\t\t\t\tint port,\ndrivers/net/dsa/mv88e6060.c:47:\t\t\t\t\t\t\tenum dsa_tag_protocol m)\ndrivers/net/dsa/mv88e6060.c-48-{\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=6627=static struct mv88e6xxx_chip *mv88e6xxx_alloc_chip(struct device *dev)\n--\ndrivers/net/dsa/mv88e6xxx/chip.c-6645-\ndrivers/net/dsa/mv88e6xxx/chip.c:6646:static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/mv88e6xxx/chip.c-6647-\t\t\t\t\t\t\tint port,\ndrivers/net/dsa/mv88e6xxx/chip.c:6648:\t\t\t\t\t\t\tenum dsa_tag_protocol m)\ndrivers/net/dsa/mv88e6xxx/chip.c-6649-{\n--\ndrivers/net/dsa/mv88e6xxx/chip.c=6655=static int mv88e6xxx_change_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/mv88e6xxx/chip.c:6656:\t\t\t\t\t enum dsa_tag_protocol proto)\ndrivers/net/dsa/mv88e6xxx/chip.c-6657-{\ndrivers/net/dsa/mv88e6xxx/chip.c-6658-\tstruct mv88e6xxx_chip *chip = ds-\u003epriv;\ndrivers/net/dsa/mv88e6xxx/chip.c:6659:\tenum dsa_tag_protocol old_protocol;\ndrivers/net/dsa/mv88e6xxx/chip.c-6660-\tstruct dsa_port *cpu_dp;\n--\ndrivers/net/dsa/mv88e6xxx/chip.h=349=struct mv88e6xxx_chip {\n--\ndrivers/net/dsa/mv88e6xxx/chip.h-352-\t/* Currently configured tagging protocol */\ndrivers/net/dsa/mv88e6xxx/chip.h:353:\tenum dsa_tag_protocol tag_protocol;\ndrivers/net/dsa/mv88e6xxx/chip.h-354-\n--\ndrivers/net/dsa/mxl862xx/mxl862xx.c=159=static const struct mxl862xx_evlan_rule_desc vid_accept_egress_unaware[] = {\n--\ndrivers/net/dsa/mxl862xx/mxl862xx.c-163-\ndrivers/net/dsa/mxl862xx/mxl862xx.c:164:static enum dsa_tag_protocol mxl862xx_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/mxl862xx/mxl862xx.c-165-\t\t\t\t\t\t int port,\ndrivers/net/dsa/mxl862xx/mxl862xx.c:166:\t\t\t\t\t\t enum dsa_tag_protocol m)\ndrivers/net/dsa/mxl862xx/mxl862xx.c-167-{\n--\ndrivers/net/dsa/netc/netc_main.c=52=static void netc_destroy_vlan_list(struct netc_switch *priv)\n--\ndrivers/net/dsa/netc/netc_main.c-60-\ndrivers/net/dsa/netc/netc_main.c:61:static enum dsa_tag_protocol\ndrivers/net/dsa/netc/netc_main.c-62-netc_get_tag_protocol(struct dsa_switch *ds, int port,\ndrivers/net/dsa/netc/netc_main.c:63:\t\t enum dsa_tag_protocol mprot)\ndrivers/net/dsa/netc/netc_main.c-64-{\n--\ndrivers/net/dsa/ocelot/felix.c=754=static int felix_change_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/ocelot/felix.c:755:\t\t\t\t enum dsa_tag_protocol proto)\ndrivers/net/dsa/ocelot/felix.c-756-{\n--\ndrivers/net/dsa/ocelot/felix.c-800-\ndrivers/net/dsa/ocelot/felix.c:801:static enum dsa_tag_protocol felix_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/ocelot/felix.c-802-\t\t\t\t\t\t int port,\ndrivers/net/dsa/ocelot/felix.c:803:\t\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/ocelot/felix.c-804-{\n--\ndrivers/net/dsa/ocelot/felix.c=1678=static int felix_connect_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/ocelot/felix.c:1679:\t\t\t\t enum dsa_tag_protocol proto)\ndrivers/net/dsa/ocelot/felix.c-1680-{\n--\ndrivers/net/dsa/ocelot/felix.c=2390=int felix_register_switch(struct device *dev, resource_size_t switch_base,\n--\ndrivers/net/dsa/ocelot/felix.c-2392-\t\t\t bool mm_supported,\ndrivers/net/dsa/ocelot/felix.c:2393:\t\t\t enum dsa_tag_protocol init_tag_proto,\ndrivers/net/dsa/ocelot/felix.c-2394-\t\t\t const struct felix_info *info)\n--\ndrivers/net/dsa/ocelot/felix.h=87=struct felix {\n--\ndrivers/net/dsa/ocelot/felix.h-93-\tresource_size_t\t\t\tswitch_base;\ndrivers/net/dsa/ocelot/felix.h:94:\tenum dsa_tag_protocol\t\ttag_proto;\ndrivers/net/dsa/ocelot/felix.h-95-\tconst struct felix_tag_proto_ops *tag_proto_ops;\n--\ndrivers/net/dsa/ocelot/felix.h=101=int felix_register_switch(struct device *dev, resource_size_t switch_base,\n--\ndrivers/net/dsa/ocelot/felix.h-103-\t\t\t bool mm_supported,\ndrivers/net/dsa/ocelot/felix.h:104:\t\t\t enum dsa_tag_protocol init_tag_proto,\ndrivers/net/dsa/ocelot/felix.h-105-\t\t\t const struct felix_info *info);\n--\ndrivers/net/dsa/qca/ar9331.c=485=static void ar9331_sw_port_disable(struct dsa_switch *ds, int port)\n--\ndrivers/net/dsa/qca/ar9331.c-495-\ndrivers/net/dsa/qca/ar9331.c:496:static enum dsa_tag_protocol ar9331_sw_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/qca/ar9331.c-497-\t\t\t\t\t\t\tint port,\ndrivers/net/dsa/qca/ar9331.c:498:\t\t\t\t\t\t\tenum dsa_tag_protocol m)\ndrivers/net/dsa/qca/ar9331.c-499-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=1739=static u32 qca8k_get_phy_flags(struct dsa_switch *ds, int port)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1754-\ndrivers/net/dsa/qca/qca8k-8xxx.c:1755:static enum dsa_tag_protocol\ndrivers/net/dsa/qca/qca8k-8xxx.c-1756-qca8k_get_tag_protocol(struct dsa_switch *ds, int port,\ndrivers/net/dsa/qca/qca8k-8xxx.c:1757:\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/qca/qca8k-8xxx.c-1758-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=1782=static int qca8k_connect_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/qca/qca8k-8xxx.c:1783:\t\t\t\t enum dsa_tag_protocol proto)\ndrivers/net/dsa/qca/qca8k-8xxx.c-1784-{\n--\ndrivers/net/dsa/realtek/rtl8365mb_main.c=927=rtl8365mb_get_port_extint(struct realtek_priv *priv, int port)\n--\ndrivers/net/dsa/realtek/rtl8365mb_main.c-945-\ndrivers/net/dsa/realtek/rtl8365mb_main.c:946:static enum dsa_tag_protocol\ndrivers/net/dsa/realtek/rtl8365mb_main.c-947-rtl8365mb_get_tag_protocol(struct dsa_switch *ds, int port,\ndrivers/net/dsa/realtek/rtl8365mb_main.c:948:\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/realtek/rtl8365mb_main.c-949-{\n--\ndrivers/net/dsa/realtek/rtl8365mb_main.c=2332=static int rtl8365mb_change_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/realtek/rtl8365mb_main.c:2333:\t\t\t\t\t enum dsa_tag_protocol proto)\ndrivers/net/dsa/realtek/rtl8365mb_main.c-2334-{\n--\ndrivers/net/dsa/realtek/rtl8366rb.c=867=static int rtl8366rb_setup(struct dsa_switch *ds)\n--\ndrivers/net/dsa/realtek/rtl8366rb.c-1130-\ndrivers/net/dsa/realtek/rtl8366rb.c:1131:static enum dsa_tag_protocol rtl8366_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/realtek/rtl8366rb.c-1132-\t\t\t\t\t\t int port,\ndrivers/net/dsa/realtek/rtl8366rb.c:1133:\t\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/realtek/rtl8366rb.c-1134-{\n--\ndrivers/net/dsa/rzn1_a5psw.c=81=static void a5psw_reg_rmw(struct a5psw *a5psw, int offset, u32 mask, u32 val)\n--\ndrivers/net/dsa/rzn1_a5psw.c-94-\ndrivers/net/dsa/rzn1_a5psw.c:95:static enum dsa_tag_protocol a5psw_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/rzn1_a5psw.c-96-\t\t\t\t\t\t int port,\ndrivers/net/dsa/rzn1_a5psw.c:97:\t\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/rzn1_a5psw.c-98-{\n--\ndrivers/net/dsa/sja1105/sja1105.h=115=struct sja1105_info {\n--\ndrivers/net/dsa/sja1105/sja1105.h-136-\tbool fixed_cbs_mapping;\ndrivers/net/dsa/sja1105/sja1105.h:137:\tenum dsa_tag_protocol tag_proto;\ndrivers/net/dsa/sja1105/sja1105.h-138-\tconst struct sja1105_dynamic_table_ops *dyn_ops;\n--\ndrivers/net/dsa/sja1105/sja1105_main.c=2258=int sja1105_static_config_reload(struct sja1105_private *priv,\n--\ndrivers/net/dsa/sja1105/sja1105_main.c-2354-\ndrivers/net/dsa/sja1105/sja1105_main.c:2355:static enum dsa_tag_protocol\ndrivers/net/dsa/sja1105/sja1105_main.c-2356-sja1105_get_tag_protocol(struct dsa_switch *ds, int port,\ndrivers/net/dsa/sja1105/sja1105_main.c:2357:\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/sja1105/sja1105_main.c-2358-{\n--\ndrivers/net/dsa/sja1105/sja1105_main.c=2691=static int sja1105_connect_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/sja1105/sja1105_main.c:2692:\t\t\t\t\tenum dsa_tag_protocol proto)\ndrivers/net/dsa/sja1105/sja1105_main.c-2693-{\n--\ndrivers/net/dsa/vitesse-vsc73xx-core.c=662=static int vsc73xx_phy_write(struct dsa_switch *ds, int phy, int regnum,\n--\ndrivers/net/dsa/vitesse-vsc73xx-core.c-685-\ndrivers/net/dsa/vitesse-vsc73xx-core.c:686:static enum dsa_tag_protocol vsc73xx_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/vitesse-vsc73xx-core.c-687-\t\t\t\t\t\t int port,\ndrivers/net/dsa/vitesse-vsc73xx-core.c:688:\t\t\t\t\t\t enum dsa_tag_protocol mp)\ndrivers/net/dsa/vitesse-vsc73xx-core.c-689-{\n--\ndrivers/net/dsa/xrs700x/xrs700x.c=185=static int xrs700x_setup_regmap_range(struct xrs700x *priv)\n--\ndrivers/net/dsa/xrs700x/xrs700x.c-225-\ndrivers/net/dsa/xrs700x/xrs700x.c:226:static enum dsa_tag_protocol xrs700x_get_tag_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/xrs700x/xrs700x.c-227-\t\t\t\t\t\t int port,\ndrivers/net/dsa/xrs700x/xrs700x.c:228:\t\t\t\t\t\t enum dsa_tag_protocol m)\ndrivers/net/dsa/xrs700x/xrs700x.c-229-{\n--\ndrivers/net/dsa/yt921x.c=4269=static int yt921x_port_setup(struct yt921x_priv *priv, int port)\n--\ndrivers/net/dsa/yt921x.c-4309-\ndrivers/net/dsa/yt921x.c:4310:static enum dsa_tag_protocol\ndrivers/net/dsa/yt921x.c-4311-yt921x_dsa_get_tag_protocol(struct dsa_switch *ds, int port,\ndrivers/net/dsa/yt921x.c:4312:\t\t\t enum dsa_tag_protocol m)\ndrivers/net/dsa/yt921x.c-4313-{\n--\ninclude/net/dsa.h=26=struct tc_action;\n--\ninclude/net/dsa.h-63-\ninclude/net/dsa.h:64:enum dsa_tag_protocol {\ninclude/net/dsa.h-65-\tDSA_TAG_PROTO_NONE\t\t= DSA_TAG_PROTO_NONE_VALUE,\n--\ninclude/net/dsa.h=104=struct dsa_device_ops {\n--\ninclude/net/dsa.h-113-\tconst char *name;\ninclude/net/dsa.h:114:\tenum dsa_tag_protocol proto;\ninclude/net/dsa.h-115-\t/* Some tagging protocols either mangle or shift the destination MAC\n--\ninclude/net/dsa.h=131=struct dsa_switch_tree {\n--\ninclude/net/dsa.h-156-\t */\ninclude/net/dsa.h:157:\tenum dsa_tag_protocol default_proto;\ninclude/net/dsa.h-158-\n--\ninclude/net/dsa.h=862=struct dsa_switch_ops {\n--\ninclude/net/dsa.h-869-\t */\ninclude/net/dsa.h:870:\tenum dsa_tag_protocol (*get_tag_protocol)(struct dsa_switch *ds,\ninclude/net/dsa.h-871-\t\t\t\t\t\t int port,\ninclude/net/dsa.h:872:\t\t\t\t\t\t enum dsa_tag_protocol mprot);\ninclude/net/dsa.h-873-\tint\t(*change_tag_protocol)(struct dsa_switch *ds,\ninclude/net/dsa.h:874:\t\t\t\t enum dsa_tag_protocol proto);\ninclude/net/dsa.h-875-\t/*\n--\ninclude/net/dsa.h-880-\tint\t(*connect_tag_protocol)(struct dsa_switch *ds,\ninclude/net/dsa.h:881:\t\t\t\t\tenum dsa_tag_protocol proto);\ninclude/net/dsa.h-882-\n--\nnet/dsa/conduit.c=340=static ssize_t tagging_show(struct device *d, struct device_attribute *attr,\n--\nnet/dsa/conduit.c-346-\treturn sysfs_emit(buf, \"%s\\n\",\nnet/dsa/conduit.c:347:\t\t dsa_tag_protocol_to_str(cpu_dp-\u003etag_ops));\nnet/dsa/conduit.c-348-}\n--\nnet/dsa/conduit.c=419=int dsa_conduit_setup(struct net_device *dev, struct dsa_port *cpu_dp)\n--\nnet/dsa/conduit.c-425-\nnet/dsa/conduit.c:426:\tmtu = ETH_DATA_LEN + dsa_tag_protocol_overhead(tag_ops);\nnet/dsa/conduit.c-427-\n--\nnet/dsa/dsa.c=1121=static int dsa_port_parse_dsa(struct dsa_port *dp)\n--\nnet/dsa/dsa.c-1127-\nnet/dsa/dsa.c:1128:static enum dsa_tag_protocol dsa_get_tag_protocol(struct dsa_port *dp,\nnet/dsa/dsa.c-1129-\t\t\t\t\t\t struct net_device *conduit)\nnet/dsa/dsa.c-1130-{\nnet/dsa/dsa.c:1131:\tenum dsa_tag_protocol tag_protocol = DSA_TAG_PROTO_NONE;\nnet/dsa/dsa.c-1132-\tstruct dsa_switch *mds, *ds = dp-\u003eds;\n--\nnet/dsa/dsa.c=1154=static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *conduit,\n--\nnet/dsa/dsa.c-1159-\tstruct dsa_switch_tree *dst = ds-\u003edst;\nnet/dsa/dsa.c:1160:\tenum dsa_tag_protocol default_proto;\nnet/dsa/dsa.c-1161-\n--\nnet/dsa/tag.c=168=EXPORT_SYMBOL_GPL(dsa_tag_drivers_unregister);\nnet/dsa/tag.c-169-\nnet/dsa/tag.c:170:const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops)\nnet/dsa/tag.c-171-{\n--\nnet/dsa/tag.h=24=void dsa_tag_driver_put(const struct dsa_device_ops *ops);\nnet/dsa/tag.h:25:const char *dsa_tag_protocol_to_str(const struct dsa_device_ops *ops);\nnet/dsa/tag.h-26-\nnet/dsa/tag.h:27:static inline int dsa_tag_protocol_overhead(const struct dsa_device_ops *ops)\nnet/dsa/tag.h-28-{\n--\nnet/dsa/user.c=2101=int dsa_user_change_mtu(struct net_device *dev, int new_mtu)\n--\nnet/dsa/user.c-2140-\nnet/dsa/user.c:2141:\toverhead = dsa_tag_protocol_overhead(cpu_dp-\u003etag_ops);\nnet/dsa/user.c-2142-\tmtu_limit = min_t(int, conduit-\u003emax_mtu, dev-\u003emax_mtu + overhead);\n"
} |
| 9/2 | 2026/07/04 11:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 36933 output: 18 thoughts: 71 Thoughts: **Investigating Tag Protocol Configuration** Okay, let's see how we can configure the tagging protocol, specifically whether we can do this through sysfs or netlink. That would be ideal. I'm going to dig into the kernel code and see if there are any obvious entry points. Let's see... I'm looking at `net/dsa/conduit.c`. Hmm, I see a `static ssize_t tagging_show` function defined there. Okay, so we have a show function for device attributes. That's a good starting point. Now, the crucial thing is... is there a corresponding store function? A `tagging_store`? That's what I really need to find to understand if this configuration is actually writable, or just read-only. |
| 10/2 | 2026/07/04 11:40 | tool | grepper |
0mArgs:{
"Expression": "tagging_store"
}Results: {
"Output": "net/dsa/conduit.c=340=static ssize_t tagging_show(struct device *d, struct device_attribute *attr,\n--\nnet/dsa/conduit.c-349-\nnet/dsa/conduit.c:350:static ssize_t tagging_store(struct device *d, struct device_attribute *attr,\nnet/dsa/conduit.c-351-\t\t\t const char *buf, size_t count)\n"
} |
| 11/2 | 2026/07/04 11:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 37314 output: 37 thoughts: 19 Thoughts: Okay, here's my attempt at summarizing those thoughts from a first-person, expert perspective, aiming for a fulsome rendering: **Initial Assessment of `tagging_store`** Ah, *`tagging_store`*! Excellent! It's actually present, which is good news. Now, my first instinct, of course, is to delve into its functionality. I'm immediately curious about what purpose it serves. My mind's already racing, considering the potential implementations and scenarios where a `tagging_store` would be useful. Is this a system for managing metadata, keywords, or perhaps a more complex hierarchical tagging structure? Is it relational, NoSQL, or maybe even graph-based? I'll need to understand its design to place it into the broader architecture. I'm keen to determine how well it supports querying, indexing, and the overall performance implications. What level of abstraction does it provide? I need to analyze its methods and data structures, the level of control it offers, and what assumptions its design might be making. My goal is to quickly and precisely understand its role and impact on the overall system. Time to dissect! |
| 12/2 | 2026/07/04 11:40 | tool | read-file |
0mArgs:{
"File": "net/dsa/conduit.c",
"FirstLine": 350,
"LineCount": 50
}Results: {
"Contents": " 350:\tstatic ssize_t tagging_store(struct device *d, struct device_attribute *attr,\n 351:\t\t\t\t const char *buf, size_t count)\n 352:\t{\n 353:\t\tconst struct dsa_device_ops *new_tag_ops, *old_tag_ops;\n 354:\t\tconst char *end = strchrnul(buf, '\\n'), *name;\n 355:\t\tstruct net_device *dev = to_net_dev(d);\n 356:\t\tstruct dsa_port *cpu_dp = dev-\u003edsa_ptr;\n 357:\t\tsize_t len = end - buf;\n 358:\t\tint err;\n 359:\t\n 360:\t\t/* Empty string passed */\n 361:\t\tif (!len)\n 362:\t\t\treturn -ENOPROTOOPT;\n 363:\t\n 364:\t\tname = kstrndup(buf, len, GFP_KERNEL);\n 365:\t\tif (!name)\n 366:\t\t\treturn -ENOMEM;\n 367:\t\n 368:\t\told_tag_ops = cpu_dp-\u003etag_ops;\n 369:\t\tnew_tag_ops = dsa_tag_driver_get_by_name(name);\n 370:\t\tkfree(name);\n 371:\t\t/* Bad tagger name? */\n 372:\t\tif (IS_ERR(new_tag_ops))\n 373:\t\t\treturn PTR_ERR(new_tag_ops);\n 374:\t\n 375:\t\tif (new_tag_ops == old_tag_ops)\n 376:\t\t\t/* Drop the temporarily held duplicate reference, since\n 377:\t\t\t * the DSA switch tree uses this tagger.\n 378:\t\t\t */\n 379:\t\t\tgoto out;\n 380:\t\n 381:\t\terr = dsa_tree_change_tag_proto(cpu_dp-\u003eds-\u003edst, new_tag_ops,\n 382:\t\t\t\t\t\told_tag_ops);\n 383:\t\tif (err) {\n 384:\t\t\t/* On failure the old tagger is restored, so we don't need the\n 385:\t\t\t * driver for the new one.\n 386:\t\t\t */\n 387:\t\t\tdsa_tag_driver_put(new_tag_ops);\n 388:\t\t\treturn err;\n 389:\t\t}\n 390:\t\n 391:\t\t/* On success we no longer need the module for the old tagging protocol\n 392:\t\t */\n 393:\tout:\n 394:\t\tdsa_tag_driver_put(old_tag_ops);\n 395:\t\treturn count;\n 396:\t}\n 397:\tstatic DEVICE_ATTR_RW(tagging);\n 398:\t\n 399:\tstatic struct attribute *dsa_user_attrs[] = {\n"
} |
| 13/2 | 2026/07/04 11:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 38379 output: 24 thoughts: 65 Thoughts: **Analyzing the Tag Protocol Modification** Okay, so I'm looking at how we can modify the tagging protocol used within a DSA switch tree, and it looks like `tagging_store` is the key. But hold on, the critical function seems to be `dsa_tree_change_tag_proto`. I'm starting to piece it together... it appears this function will call `change_tag_protocol` on the switch operations. I'm going to dig into `dsa_tree_change_tag_proto` next to confirm my understanding and make sure there are no surprises. This looks like a promising avenue. |
| 14/2 | 2026/07/04 11:40 | tool | grepper |
0mArgs:{
"Expression": "dsa_tree_change_tag_proto"
}Results: {
"Output": "net/dsa/conduit.c=350=static ssize_t tagging_store(struct device *d, struct device_attribute *attr,\n--\nnet/dsa/conduit.c-380-\nnet/dsa/conduit.c:381:\terr = dsa_tree_change_tag_proto(cpu_dp-\u003eds-\u003edst, new_tag_ops,\nnet/dsa/conduit.c-382-\t\t\t\t\told_tag_ops);\n--\nnet/dsa/dsa.c=947=static int dsa_tree_bind_tag_proto(struct dsa_switch_tree *dst,\n--\nnet/dsa/dsa.c-981- */\nnet/dsa/dsa.c:982:int dsa_tree_change_tag_proto(struct dsa_switch_tree *dst,\nnet/dsa/dsa.c-983-\t\t\t const struct dsa_device_ops *tag_ops,\n--\nnet/dsa/dsa.h=24=struct net_device *dsa_tree_find_first_conduit(struct dsa_switch_tree *dst);\nnet/dsa/dsa.h:25:int dsa_tree_change_tag_proto(struct dsa_switch_tree *dst,\nnet/dsa/dsa.h-26-\t\t\t const struct dsa_device_ops *tag_ops,\n--\nnet/dsa/switch.c=873=static int dsa_switch_change_tag_proto(struct dsa_switch *ds,\n--\nnet/dsa/switch.c-900-\nnet/dsa/switch.c:901:\t\t/* rtnl_mutex is held in dsa_tree_change_tag_proto */\nnet/dsa/switch.c-902-\t\tdsa_user_change_mtu(user, user-\u003emtu);\n"
} |
| 15/2 | 2026/07/04 11:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 39082 output: 37 thoughts: 16 Thoughts: Okay, let's dive into this. Here's my take on those thoughts, as if they're my own: **Analyzing `dsa_tree_change_tag_proto`** Alright, time to crack open `dsa_tree_change_tag_proto`. I'm already anticipating what's in here. Given the name, I'm expecting something related to modifying the tags associated with elements within a DSA (Distributed Shared Array) tree structure. It's likely a protobuf definition, which means it'll define the message format used to represent these tag change operations. I'm mentally preparing to look for fields that specify the target node or nodes within the tree that are going to be affected. The level of granularity for targeting will be interesting - is it individual nodes, subtrees, or something else entirely? Then, I'll be looking for the tag-related information itself: what tags are being added, removed, or modified. Are these simple key-value pairs? Perhaps they're more complex structures with versioning or metadata? It’s critical to understand the format for interoperability in the system. I'll be paying close attention to any fields that might indicate the scope of the change. Is this a local operation, or is it intended to propagate across the distributed system? Any flags or enums related to consistency, atomicity, or conflict resolution will be crucial to understanding the intended behavior. Also, I'll be on the lookout for anything related to error handling or status reporting – how does the protocol handle failures during tag updates? Finally, my expert eye will be scanning for anything that might reveal performance considerations. Are there any hints about the expected frequency or scale of these tag changes? Any optimization strategies implied in the structure of the message itself? Analyzing the efficiency of this data structure is something I must do as a matter of routine. This is what's running through my head as I get ready to read it. |
| 16/2 | 2026/07/04 11:40 | tool | read-file |
0mArgs:{
"File": "net/dsa/dsa.c",
"FirstLine": 982,
"LineCount": 50
}Results: {
"Contents": " 982:\tint dsa_tree_change_tag_proto(struct dsa_switch_tree *dst,\n 983:\t\t\t\t const struct dsa_device_ops *tag_ops,\n 984:\t\t\t\t const struct dsa_device_ops *old_tag_ops)\n 985:\t{\n 986:\t\tstruct dsa_notifier_tag_proto_info info;\n 987:\t\tstruct dsa_port *dp;\n 988:\t\tint err = -EBUSY;\n 989:\t\n 990:\t\tif (!rtnl_trylock())\n 991:\t\t\treturn restart_syscall();\n 992:\t\n 993:\t\t/* At the moment we don't allow changing the tag protocol under\n 994:\t\t * traffic. The rtnl_mutex also happens to serialize concurrent\n 995:\t\t * attempts to change the tagging protocol. If we ever lift the IFF_UP\n 996:\t\t * restriction, there needs to be another mutex which serializes this.\n 997:\t\t */\n 998:\t\tdsa_tree_for_each_user_port(dp, dst) {\n 999:\t\t\tif (dsa_port_to_conduit(dp)-\u003eflags \u0026 IFF_UP)\n1000:\t\t\t\tgoto out_unlock;\n1001:\t\n1002:\t\t\tif (dp-\u003euser-\u003eflags \u0026 IFF_UP)\n1003:\t\t\t\tgoto out_unlock;\n1004:\t\t}\n1005:\t\n1006:\t\t/* Notify the tag protocol change */\n1007:\t\tinfo.tag_ops = tag_ops;\n1008:\t\terr = dsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO, \u0026info);\n1009:\t\tif (err)\n1010:\t\t\tgoto out_unwind_tagger;\n1011:\t\n1012:\t\terr = dsa_tree_bind_tag_proto(dst, tag_ops);\n1013:\t\tif (err)\n1014:\t\t\tgoto out_unwind_tagger;\n1015:\t\n1016:\t\trtnl_unlock();\n1017:\t\n1018:\t\treturn 0;\n1019:\t\n1020:\tout_unwind_tagger:\n1021:\t\tinfo.tag_ops = old_tag_ops;\n1022:\t\tdsa_tree_notify(dst, DSA_NOTIFIER_TAG_PROTO, \u0026info);\n1023:\tout_unlock:\n1024:\t\trtnl_unlock();\n1025:\t\treturn err;\n1026:\t}\n1027:\t\n1028:\tstatic void dsa_tree_conduit_state_change(struct dsa_switch_tree *dst,\n1029:\t\t\t\t\t\t struct net_device *conduit)\n1030:\t{\n1031:\t\tstruct dsa_notifier_conduit_state_info info;\n"
} |
| 17/2 | 2026/07/04 11:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 40318 output: 36 thoughts: 62 Thoughts: Here's my summary, as the expert: **Deep Dive into `dsa_tree_notify` and Tag Protocol Updates** Okay, so I'm thinking about this `dsa_tree_notify` function. It seems that when I call it with `DSA_NOTIFIER_TAG_PROTO` and `&info`, it's going to iterate through the entire switch tree and execute `dsa_switch_change_tag_proto` for *every* switch present. My immediate concern is the potential overhead this represents, depending on the size and complexity of the DSA (Distributed Switch Architecture) network. My next thought is, let's go check the implementation of `dsa_switch_change_tag_proto` to understand what exactly happens within each switch's context and what impact changing the tag protocol might have. I need to understand its behavior thoroughly to get the true picture. What sort of checks happen? What resources are touched? This level of granular examination will reveal any possible inefficiencies, contention, or unexpected side effects that I need to be aware of. |
| 18/2 | 2026/07/04 11:40 | tool | read-file |
0mArgs:{
"File": "net/dsa/switch.c",
"FirstLine": 873,
"LineCount": 50
}Results: {
"Contents": " 873:\tstatic int dsa_switch_change_tag_proto(struct dsa_switch *ds,\n 874:\t\t\t\t\t struct dsa_notifier_tag_proto_info *info)\n 875:\t{\n 876:\t\tconst struct dsa_device_ops *tag_ops = info-\u003etag_ops;\n 877:\t\tstruct dsa_port *dp, *cpu_dp;\n 878:\t\tint err;\n 879:\t\n 880:\t\tif (!ds-\u003eops-\u003echange_tag_protocol)\n 881:\t\t\treturn -EOPNOTSUPP;\n 882:\t\n 883:\t\tASSERT_RTNL();\n 884:\t\n 885:\t\terr = ds-\u003eops-\u003echange_tag_protocol(ds, tag_ops-\u003eproto);\n 886:\t\tif (err)\n 887:\t\t\treturn err;\n 888:\t\n 889:\t\tdsa_switch_for_each_cpu_port(cpu_dp, ds)\n 890:\t\t\tdsa_port_set_tag_protocol(cpu_dp, tag_ops);\n 891:\t\n 892:\t\t/* Now that changing the tag protocol can no longer fail, let's update\n 893:\t\t * the remaining bits which are \"duplicated for faster access\", and the\n 894:\t\t * bits that depend on the tagger, such as the MTU.\n 895:\t\t */\n 896:\t\tdsa_switch_for_each_user_port(dp, ds) {\n 897:\t\t\tstruct net_device *user = dp-\u003euser;\n 898:\t\n 899:\t\t\tdsa_user_setup_tagger(user);\n 900:\t\n 901:\t\t\t/* rtnl_mutex is held in dsa_tree_change_tag_proto */\n 902:\t\t\tdsa_user_change_mtu(user, user-\u003emtu);\n 903:\t\t}\n 904:\t\n 905:\t\treturn 0;\n 906:\t}\n 907:\t\n 908:\t/* We use the same cross-chip notifiers to inform both the tagger side, as well\n 909:\t * as the switch side, of connection and disconnection events.\n 910:\t * Since ds-\u003etagger_data is owned by the tagger, it isn't a hard error if the\n 911:\t * switch side doesn't support connecting to this tagger, and therefore, the\n 912:\t * fact that we don't disconnect the tagger side doesn't constitute a memory\n 913:\t * leak: the tagger will still operate with persistent per-switch memory, just\n 914:\t * with the switch side unconnected to it. What does constitute a hard error is\n 915:\t * when the switch side supports connecting but fails.\n 916:\t */\n 917:\tstatic int\n 918:\tdsa_switch_connect_tag_proto(struct dsa_switch *ds,\n 919:\t\t\t\t struct dsa_notifier_tag_proto_info *info)\n 920:\t{\n 921:\t\tconst struct dsa_device_ops *tag_ops = info-\u003etag_ops;\n 922:\t\tint err;\n"
} |
| 19/2 | 2026/07/04 11:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 41491 output: 20 thoughts: 62 Thoughts: **Analyzing the `dsa_switch_change_tag_proto` Function** Okay, so it looks like `dsa_switch_change_tag_proto` is returning `-EOPNOTSUPP` when the `ds->ops->change_tag_protocol` function pointer is NULL. That makes perfect sense. Now, my next thought is, I need to understand which DSA switches might *not* support this. I want to confirm whether `dsa_loop` or any other "dummy" switches are going to trigger this `-EOPNOTSUPP` error. It's important to know which devices will fall into this category. This'll help me understand the implications for any code that's calling this `dsa_switch_change_tag_proto` function. I need to make sure I've got a comprehensive picture of the driver support here. |
| 20/2 | 2026/07/04 11:40 | tool | grepper |
0mArgs:{
"Expression": "\\.change_tag_protocol"
}Results: {
"Output": "drivers/net/dsa/mv88e6xxx/chip.c=7187=static const struct dsa_switch_ops mv88e6xxx_switch_ops = {\ndrivers/net/dsa/mv88e6xxx/chip.c-7188-\t.get_tag_protocol\t= mv88e6xxx_get_tag_protocol,\ndrivers/net/dsa/mv88e6xxx/chip.c:7189:\t.change_tag_protocol\t= mv88e6xxx_change_tag_protocol,\ndrivers/net/dsa/mv88e6xxx/chip.c-7190-\t.setup\t\t\t= mv88e6xxx_setup,\n--\ndrivers/net/dsa/ocelot/felix.c=2306=static const struct dsa_switch_ops felix_switch_ops = {\ndrivers/net/dsa/ocelot/felix.c-2307-\t.get_tag_protocol\t\t= felix_get_tag_protocol,\ndrivers/net/dsa/ocelot/felix.c:2308:\t.change_tag_protocol\t\t= felix_change_tag_protocol,\ndrivers/net/dsa/ocelot/felix.c-2309-\t.connect_tag_protocol\t\t= felix_connect_tag_protocol,\n--\ndrivers/net/dsa/realtek/rtl8365mb_main.c=2666=static const struct dsa_switch_ops rtl8365mb_switch_ops = {\ndrivers/net/dsa/realtek/rtl8365mb_main.c-2667-\t.get_tag_protocol = rtl8365mb_get_tag_protocol,\ndrivers/net/dsa/realtek/rtl8365mb_main.c:2668:\t.change_tag_protocol = rtl8365mb_change_tag_protocol,\ndrivers/net/dsa/realtek/rtl8365mb_main.c-2669-\t.setup = rtl8365mb_setup,\n--\nnet/dsa/dsa.c=1154=static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *conduit,\n--\nnet/dsa/dsa.c-1229-\t * dsa_switch_setup_tag_protocol once .setup has run and the\nnet/dsa/dsa.c:1230:\t * driver is ready to accept calls to .change_tag_protocol. If\nnet/dsa/dsa.c-1231-\t * the driver does not support the custom protocol at that\n"
} |
| 21/2 | 2026/07/04 11:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 42434 output: 22 thoughts: 209 Thoughts: **Analyzing `change_tag_protocol` Support for Virtualization** Okay, so I'm focusing on `change_tag_protocol` support, and it looks like only `mv88e6xxx`, `felix`, and `rtl8365mb` are listed as supporting it. Hold on, `dsa_loop` isn't supported, which is important to keep in mind. My next thought is, can I instantiate any of these, specifically `mv88e6xxx`, `felix`, or `rtl8365mb`, within a virtualized environment for testing? Considering fuzzing, I'm thinking about Syzkaller. Now, `mv88e6xxx` is an MDIO device. The problem is Syzkaller struggles with MDIO devices unless they are either probed via the device tree or the I2C/MDIO bus. Wait a moment, I am second guessing myself. Does Syzkaller have the functionality? No, that's right, Syzkaller doesn't have a generic fuzzer for MDIO devices. Alright, let's switch gears and focus on `felix`. This is different. This is a PCI device! Let me refresh my memory. Yes, I remember, `drivers/net/dsa/ocelot/felix_vsc9959.c` is its PCI driver. I need to confirm that `felix` is a PCI driver. |
| 22/2 | 2026/07/04 11:40 | tool | grepper |
0mArgs:{
"Expression": "MODULE_DEVICE_TABLE\\(pci"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 4932 lines.\nUse more precise expression if possible.\n\nDocumentation/sound/kernel-api/writing-an-alsa-driver.rst=698=destructor and PCI entries. Example code is shown first, below::\n--\nDocumentation/sound/kernel-api/writing-an-alsa-driver.rst-797- };\nDocumentation/sound/kernel-api/writing-an-alsa-driver.rst:798: MODULE_DEVICE_TABLE(pci, snd_mychip_ids);\nDocumentation/sound/kernel-api/writing-an-alsa-driver.rst-799-\n--\nDocumentation/sound/kernel-api/writing-an-alsa-driver.rst=1041=For example::\n--\nDocumentation/sound/kernel-api/writing-an-alsa-driver.rst-1048- };\nDocumentation/sound/kernel-api/writing-an-alsa-driver.rst:1049: MODULE_DEVICE_TABLE(pci, snd_mychip_ids);\nDocumentation/sound/kernel-api/writing-an-alsa-driver.rst-1050-\n--\narch/x86/platform/intel/iosf_mbi.c=518=static const struct pci_device_id iosf_mbi_pci_ids[] = {\n--\narch/x86/platform/intel/iosf_mbi.c-524-};\narch/x86/platform/intel/iosf_mbi.c:525:MODULE_DEVICE_TABLE(pci, iosf_mbi_pci_ids);\narch/x86/platform/intel/iosf_mbi.c-526-\n--\narch/x86/platform/scx200/scx200_32.c=30=static struct pci_device_id scx200_tbl[] = {\n--\narch/x86/platform/scx200/scx200_32.c-36-};\narch/x86/platform/scx200/scx200_32.c:37:MODULE_DEVICE_TABLE(pci,scx200_tbl);\narch/x86/platform/scx200/scx200_32.c-38-\n--\ndrivers/accel/amdxdna/amdxdna_pci_drv.c=53=static const struct pci_device_id pci_ids[] = {\n--\ndrivers/accel/amdxdna/amdxdna_pci_drv.c-62-\ndrivers/accel/amdxdna/amdxdna_pci_drv.c:63:MODULE_DEVICE_TABLE(pci, pci_ids);\ndrivers/accel/amdxdna/amdxdna_pci_drv.c-64-\n--\ndrivers/accel/habanalabs/common/habanalabs_drv.c=68=static const struct pci_device_id ids[] = {\n--\ndrivers/accel/habanalabs/common/habanalabs_drv.c-74-};\ndrivers/accel/habanalabs/common/habanalabs_drv.c:75:MODULE_DEVICE_TABLE(pci, ids);\ndrivers/accel/habanalabs/common/habanalabs_drv.c-76-\n--\ndrivers/accel/ivpu/ivpu_drv.c=821=static struct pci_device_id ivpu_pci_ids[] = {\n--\ndrivers/accel/ivpu/ivpu_drv.c-829-};\ndrivers/accel/ivpu/ivpu_drv.c:830:MODULE_DEVICE_TABLE(pci, ivpu_pci_ids);\ndrivers/accel/ivpu/ivpu_drv.c-831-\n--\ndrivers/accel/qaic/qaic_drv.c=664=static const struct pci_device_id qaic_ids[] = {\n--\ndrivers/accel/qaic/qaic_drv.c-669-};\ndrivers/accel/qaic/qaic_drv.c:670:MODULE_DEVICE_TABLE(pci, qaic_ids);\ndrivers/accel/qaic/qaic_drv.c-671-\n--\ndrivers/ata/acard-ahci.c=463=MODULE_LICENSE(\"GPL\");\ndrivers/ata/acard-ahci.c:464:MODULE_DEVICE_TABLE(pci, acard_ahci_pci_tbl);\ndrivers/ata/acard-ahci.c-465-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/ahci.c=3121=MODULE_LICENSE(\"GPL\");\ndrivers/ata/ahci.c:3122:MODULE_DEVICE_TABLE(pci, ahci_pci_tbl);\ndrivers/ata/ahci.c-3123-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/ata_generic.c=254=MODULE_LICENSE(\"GPL\");\ndrivers/ata/ata_generic.c:255:MODULE_DEVICE_TABLE(pci, ata_generic);\ndrivers/ata/ata_generic.c-256-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/ata_piix.c=632=MODULE_LICENSE(\"GPL\");\ndrivers/ata/ata_piix.c:633:MODULE_DEVICE_TABLE(pci, piix_pci_tbl);\ndrivers/ata/ata_piix.c-634-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_acpi.c=282=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_acpi.c:283:MODULE_DEVICE_TABLE(pci, pacpi_pci_tbl);\ndrivers/ata/pata_acpi.c-284-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_ali.c=647=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_ali.c:648:MODULE_DEVICE_TABLE(pci, ali);\ndrivers/ata/pata_ali.c-649-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_amd.c=682=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_amd.c:683:MODULE_DEVICE_TABLE(pci, amd);\ndrivers/ata/pata_amd.c-684-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_artop.c=464=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_artop.c:465:MODULE_DEVICE_TABLE(pci, artop_pci_tbl);\ndrivers/ata/pata_artop.c-466-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_atiixp.c=318=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_atiixp.c:319:MODULE_DEVICE_TABLE(pci, atiixp);\ndrivers/ata/pata_atiixp.c-320-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_atp867x.c=549=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_atp867x.c:550:MODULE_DEVICE_TABLE(pci, atp867x_pci_tbl);\ndrivers/ata/pata_atp867x.c-551-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_cmd640.c=270=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_cmd640.c:271:MODULE_DEVICE_TABLE(pci, cmd640);\ndrivers/ata/pata_cmd640.c-272-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_cmd64x.c=531=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_cmd64x.c:532:MODULE_DEVICE_TABLE(pci, cmd64x);\ndrivers/ata/pata_cmd64x.c-533-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_cs5520.c=289=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_cs5520.c:290:MODULE_DEVICE_TABLE(pci, pata_cs5520);\ndrivers/ata/pata_cs5520.c-291-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_cs5530.c=356=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_cs5530.c:357:MODULE_DEVICE_TABLE(pci, cs5530);\ndrivers/ata/pata_cs5530.c-358-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_cs5535.c=201=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_cs5535.c:202:MODULE_DEVICE_TABLE(pci, cs5535);\ndrivers/ata/pata_cs5535.c-203-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_cs5536.c=299=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_cs5536.c:300:MODULE_DEVICE_TABLE(pci, cs5536);\ndrivers/ata/pata_cs5536.c-301-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_cypress.c=171=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_cypress.c:172:MODULE_DEVICE_TABLE(pci, cy82c693);\ndrivers/ata/pata_cypress.c-173-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_efar.c=302=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_efar.c:303:MODULE_DEVICE_TABLE(pci, efar_pci_tbl);\ndrivers/ata/pata_efar.c-304-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_hpt366.c=459=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_hpt366.c:460:MODULE_DEVICE_TABLE(pci, hpt36x);\ndrivers/ata/pata_hpt366.c-461-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_hpt37x.c=1030=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_hpt37x.c:1031:MODULE_DEVICE_TABLE(pci, hpt37x);\ndrivers/ata/pata_hpt37x.c-1032-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_hpt3x2n.c=627=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_hpt3x2n.c:628:MODULE_DEVICE_TABLE(pci, hpt3x2n);\ndrivers/ata/pata_hpt3x2n.c-629-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_hpt3x3.c=287=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_hpt3x3.c:288:MODULE_DEVICE_TABLE(pci, hpt3x3);\ndrivers/ata/pata_hpt3x3.c-289-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_it8213.c=297=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_it8213.c:298:MODULE_DEVICE_TABLE(pci, it8213_pci_tbl);\ndrivers/ata/pata_it8213.c-299-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_it821x.c=983=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_it821x.c:984:MODULE_DEVICE_TABLE(pci, it821x);\ndrivers/ata/pata_it821x.c-985-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_jmicron.c=174=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_jmicron.c:175:MODULE_DEVICE_TABLE(pci, jmicron_pci_tbl);\ndrivers/ata/pata_jmicron.c-176-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_macio.c=1379=static struct pci_driver pata_macio_pci_driver = {\n--\ndrivers/ata/pata_macio.c-1388-};\ndrivers/ata/pata_macio.c:1389:MODULE_DEVICE_TABLE(pci, pata_macio_pci_match);\ndrivers/ata/pata_macio.c-1390-\n--\ndrivers/ata/pata_marvell.c=182=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_marvell.c:183:MODULE_DEVICE_TABLE(pci, marvell_pci_tbl);\ndrivers/ata/pata_marvell.c-184-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_mpiix.c=237=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_mpiix.c:238:MODULE_DEVICE_TABLE(pci, mpiix);\ndrivers/ata/pata_mpiix.c-239-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_netcell.c=107=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_netcell.c:108:MODULE_DEVICE_TABLE(pci, netcell_pci_tbl);\ndrivers/ata/pata_netcell.c-109-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_ninja32.c=193=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_ninja32.c:194:MODULE_DEVICE_TABLE(pci, ninja32);\ndrivers/ata/pata_ninja32.c-195-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_ns87410.c=161=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_ns87410.c:162:MODULE_DEVICE_TABLE(pci, ns87410);\ndrivers/ata/pata_ns87410.c-163-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_ns87415.c=420=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_ns87415.c:421:MODULE_DEVICE_TABLE(pci, ns87415_pci_tbl);\ndrivers/ata/pata_ns87415.c-422-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_oldpiix.c=272=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_oldpiix.c:273:MODULE_DEVICE_TABLE(pci, oldpiix_pci_tbl);\ndrivers/ata/pata_oldpiix.c-274-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_opti.c=197=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_opti.c:198:MODULE_DEVICE_TABLE(pci, opti);\ndrivers/ata/pata_opti.c-199-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_optidma.c=457=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_optidma.c:458:MODULE_DEVICE_TABLE(pci, optidma);\ndrivers/ata/pata_optidma.c-459-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_pdc2027x.c=180=MODULE_VERSION(DRV_VERSION);\ndrivers/ata/pata_pdc2027x.c:181:MODULE_DEVICE_TABLE(pci, pdc2027x_pci_tbl);\ndrivers/ata/pata_pdc2027x.c-182-\n--\ndrivers/ata/pata_pdc202xx_old.c=388=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_pdc202xx_old.c:389:MODULE_DEVICE_TABLE(pci, pdc202xx);\ndrivers/ata/pata_pdc202xx_old.c-390-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_piccolo.c=123=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_piccolo.c:124:MODULE_DEVICE_TABLE(pci, ata_tosh);\ndrivers/ata/pata_piccolo.c-125-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_radisys.c=251=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_radisys.c:252:MODULE_DEVICE_TABLE(pci, radisys_pci_tbl);\ndrivers/ata/pata_radisys.c-253-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_rdc.c=383=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_rdc.c:384:MODULE_DEVICE_TABLE(pci, rdc_pci_tbl);\ndrivers/ata/pata_rdc.c-385-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_rz1000.c=147=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_rz1000.c:148:MODULE_DEVICE_TABLE(pci, pata_rz1000);\ndrivers/ata/pata_rz1000.c-149-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_sc1200.c=255=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_sc1200.c:256:MODULE_DEVICE_TABLE(pci, sc1200);\ndrivers/ata/pata_sc1200.c-257-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_sch.c=81=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_sch.c:82:MODULE_DEVICE_TABLE(pci, sch_pci_tbl);\ndrivers/ata/pata_sch.c-83-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_serverworks.c=504=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_serverworks.c:505:MODULE_DEVICE_TABLE(pci, serverworks);\ndrivers/ata/pata_serverworks.c-506-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_sil680.c=436=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_sil680.c:437:MODULE_DEVICE_TABLE(pci, sil680);\ndrivers/ata/pata_sil680.c-438-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_sis.c=912=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_sis.c:913:MODULE_DEVICE_TABLE(pci, sis_pci_tbl);\ndrivers/ata/pata_sis.c-914-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_sl82c105.c=378=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_sl82c105.c:379:MODULE_DEVICE_TABLE(pci, sl82c105);\ndrivers/ata/pata_sl82c105.c-380-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_triflex.c=230=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_triflex.c:231:MODULE_DEVICE_TABLE(pci, triflex);\ndrivers/ata/pata_triflex.c-232-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pata_via.c=704=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pata_via.c:705:MODULE_DEVICE_TABLE(pci, via);\ndrivers/ata/pata_via.c-706-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/pdc_adma.c=605=MODULE_LICENSE(\"GPL\");\ndrivers/ata/pdc_adma.c:606:MODULE_DEVICE_TABLE(pci, adma_ata_pci_tbl);\ndrivers/ata/pdc_adma.c-607-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/sata_inic162x.c=901=MODULE_LICENSE(\"GPL v2\");\ndrivers/ata/sata_inic162x.c:902:MODULE_DEVICE_TABLE(pci, inic_pci_tbl);\ndrivers/ata/sata_inic162x.c-903-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/sata_mv.c=4307=static struct pci_driver mv_pci_driver = {\n--\ndrivers/ata/sata_mv.c-4317-};\ndrivers/ata/sata_mv.c:4318:MODULE_DEVICE_TABLE(pci, mv_pci_tbl);\ndrivers/ata/sata_mv.c-4319-\n--\ndrivers/ata/sata_nv.c=618=MODULE_LICENSE(\"GPL\");\ndrivers/ata/sata_nv.c:619:MODULE_DEVICE_TABLE(pci, nv_pci_tbl);\ndrivers/ata/sata_nv.c-620-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/sata_promise.c=1229=MODULE_LICENSE(\"GPL\");\ndrivers/ata/sata_promise.c:1230:MODULE_DEVICE_TABLE(pci, pdc_ata_pci_tbl);\ndrivers/ata/sata_promise.c-1231-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/sata_qstor.c=595=MODULE_LICENSE(\"GPL\");\ndrivers/ata/sata_qstor.c:596:MODULE_DEVICE_TABLE(pci, qs_ata_pci_tbl);\ndrivers/ata/sata_qstor.c-597-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/sata_sil.c=241=MODULE_LICENSE(\"GPL\");\ndrivers/ata/sata_sil.c:242:MODULE_DEVICE_TABLE(pci, sil_pci_tbl);\ndrivers/ata/sata_sil.c-243-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/sata_sil24.c=1365=MODULE_LICENSE(\"GPL\");\ndrivers/ata/sata_sil24.c:1366:MODULE_DEVICE_TABLE(pci, sil24_pci_tbl);\n--\ndrivers/ata/sata_sis.c=113=MODULE_LICENSE(\"GPL\");\ndrivers/ata/sata_sis.c:114:MODULE_DEVICE_TABLE(pci, sis_pci_tbl);\ndrivers/ata/sata_sis.c-115-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/sata_svw.c=524=MODULE_LICENSE(\"GPL\");\ndrivers/ata/sata_svw.c:525:MODULE_DEVICE_TABLE(pci, k2_sata_pci_tbl);\ndrivers/ata/sata_svw.c-526-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/sata_sx4.c=1454=MODULE_LICENSE(\"GPL\");\ndrivers/ata/sata_sx4.c:1455:MODULE_DEVICE_TABLE(pci, pdc_sata_pci_tbl);\ndrivers/ata/sata_sx4.c-1456-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/sata_uli.c=82=MODULE_LICENSE(\"GPL\");\ndrivers/ata/sata_uli.c:83:MODULE_DEVICE_TABLE(pci, uli_pci_tbl);\ndrivers/ata/sata_uli.c-84-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/sata_via.c=202=MODULE_LICENSE(\"GPL\");\ndrivers/ata/sata_via.c:203:MODULE_DEVICE_TABLE(pci, svia_pci_tbl);\ndrivers/ata/sata_via.c-204-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/ata/sata_vsc.c=426=MODULE_LICENSE(\"GPL\");\ndrivers/ata/sata_vsc.c:427:MODULE_DEVICE_TABLE(pci, vsc_sata_pci_tbl);\ndrivers/ata/sata_vsc.c-428-MODULE_VERSION(DRV_VERSION);\n--\ndrivers/atm/solos-pci.c=1462=static const struct pci_device_id fpga_pci_tbl[] = {\n--\ndrivers/atm/solos-pci.c-1466-\ndrivers/atm/solos-pci.c:1467:MODULE_DEVICE_TABLE(pci,fpga_pci_tbl);\ndrivers/atm/solos-pci.c-1468-\n--\ndrivers/bcma/host_pci.c=283=static const struct pci_device_id bcma_pci_bridge_tbl[] = {\n--\ndrivers/bcma/host_pci.c-305-};\ndrivers/bcma/host_pci.c:306:MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);\ndrivers/bcma/host_pci.c-307-\n--\ndrivers/block/mtip32xx/mtip32xx.c=4008=static struct pci_driver mtip_pci_driver = {\n--\ndrivers/block/mtip32xx/mtip32xx.c-4016-\ndrivers/block/mtip32xx/mtip32xx.c:4017:MODULE_DEVICE_TABLE(pci, mtip_pci_tbl);\ndrivers/block/mtip32xx/mtip32xx.c-4018-\n--\ndrivers/bluetooth/btintel_pcie.c=44=static const struct pci_device_id btintel_pcie_table[] = {\n--\ndrivers/bluetooth/btintel_pcie.c-58-};\ndrivers/bluetooth/btintel_pcie.c:59:MODULE_DEVICE_TABLE(pci, btintel_pcie_table);\ndrivers/bluetooth/btintel_pcie.c-60-\n--\ndrivers/bluetooth/hci_bcm4377.c=2535=static const struct pci_device_id bcm4377_devid_table[] = {\n--\ndrivers/bluetooth/hci_bcm4377.c-2541-};\ndrivers/bluetooth/hci_bcm4377.c:2542:MODULE_DEVICE_TABLE(pci, bcm4377_devid_table);\ndrivers/bluetooth/hci_bcm4377.c-2543-\n--\ndrivers/bus/mhi/host/pci_generic.c=948=static const struct pci_device_id mhi_pci_id_table[] = {\n--\ndrivers/bus/mhi/host/pci_generic.c-1082-};\ndrivers/bus/mhi/host/pci_generic.c:1083:MODULE_DEVICE_TABLE(pci, mhi_pci_id_table);\ndrivers/bus/mhi/host/pci_generic.c-1084-\n--\ndrivers/char/agp/ali-agp.c=384=static const struct pci_device_id agp_ali_pci_table[] = {\n--\ndrivers/char/agp/ali-agp.c-395-\ndrivers/char/agp/ali-agp.c:396:MODULE_DEVICE_TABLE(pci, agp_ali_pci_table);\ndrivers/char/agp/ali-agp.c-397-\n--\ndrivers/char/agp/amd-k7-agp.c=496=static const struct pci_device_id agp_amdk7_pci_table[] = {\n--\ndrivers/char/agp/amd-k7-agp.c-523-\ndrivers/char/agp/amd-k7-agp.c:524:MODULE_DEVICE_TABLE(pci, agp_amdk7_pci_table);\ndrivers/char/agp/amd-k7-agp.c-525-\n--\ndrivers/char/agp/amd64-agp.c=601=static const struct pci_device_id agp_amd64_pci_table[] = {\n--\ndrivers/char/agp/amd64-agp.c-720-\ndrivers/char/agp/amd64-agp.c:721:MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);\ndrivers/char/agp/amd64-agp.c-722-\n--\ndrivers/char/agp/ati-agp.c=534=static const struct pci_device_id agp_ati_pci_table[] = {\n--\ndrivers/char/agp/ati-agp.c-545-\ndrivers/char/agp/ati-agp.c:546:MODULE_DEVICE_TABLE(pci, agp_ati_pci_table);\ndrivers/char/agp/ati-agp.c-547-\n--\ndrivers/char/agp/efficeon-agp.c=434=static DEFINE_SIMPLE_DEV_PM_OPS(agp_efficeon_pm_ops, NULL, agp_efficeon_resume);\ndrivers/char/agp/efficeon-agp.c-435-\ndrivers/char/agp/efficeon-agp.c:436:MODULE_DEVICE_TABLE(pci, agp_efficeon_pci_table);\ndrivers/char/agp/efficeon-agp.c-437-\n--\ndrivers/char/agp/intel-agp.c=830=static const struct pci_device_id agp_intel_pci_table[] = {\n--\ndrivers/char/agp/intel-agp.c-894-\ndrivers/char/agp/intel-agp.c:895:MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);\ndrivers/char/agp/intel-agp.c-896-\n--\ndrivers/char/agp/nvidia-agp.c=416=static const struct pci_device_id agp_nvidia_pci_table[] = {\n--\ndrivers/char/agp/nvidia-agp.c-435-\ndrivers/char/agp/nvidia-agp.c:436:MODULE_DEVICE_TABLE(pci, agp_nvidia_pci_table);\ndrivers/char/agp/nvidia-agp.c-437-\n--\ndrivers/char/agp/sis-agp.c=225=static const struct pci_device_id agp_sis_pci_table[] = {\n--\ndrivers/char/agp/sis-agp.c-404-\ndrivers/char/agp/sis-agp.c:405:MODULE_DEVICE_TABLE(pci, agp_sis_pci_table);\ndrivers/char/agp/sis-agp.c-406-\n--\ndrivers/char/agp/sworks-agp.c=530=static struct pci_device_id agp_serverworks_pci_table[] = {\n--\ndrivers/char/agp/sworks-agp.c-541-\ndrivers/char/agp/sworks-agp.c:542:MODULE_DEVICE_TABLE(pci, agp_serverworks_pci_table);\ndrivers/char/agp/sworks-agp.c-543-\n--\ndrivers/char/agp/uninorth-agp.c=684=static const struct pci_device_id agp_uninorth_pci_table[] = {\n--\ndrivers/char/agp/uninorth-agp.c-695-\ndrivers/char/agp/uninorth-agp.c:696:MODULE_DEVICE_TABLE(pci, agp_uninorth_pci_table);\ndrivers/char/agp/uninorth-agp.c-697-\n--\ndrivers/char/agp/via-agp.c=505=static const struct pci_device_id agp_via_pci_table[] = {\n--\ndrivers/char/agp/via-agp.c-549-\ndrivers/char/agp/via-agp.c:550:MODULE_DEVICE_TABLE(pci, agp_via_pci_table);\ndrivers/char/agp/via-agp.c-551-\n--\ndrivers/char/hw_random/amd-rng.c=49=static const struct pci_device_id pci_tbl[] = {\n--\ndrivers/char/hw_random/amd-rng.c-53-};\ndrivers/char/hw_random/amd-rng.c:54:MODULE_DEVICE_TABLE(pci, pci_tbl);\ndrivers/char/hw_random/amd-rng.c-55-\n--\ndrivers/char/hw_random/cavium-rng-vf.c=254=static const struct pci_device_id cavium_rng_vf_id_table[] = {\n--\ndrivers/char/hw_random/cavium-rng-vf.c-257-};\ndrivers/char/hw_random/cavium-rng-vf.c:258:MODULE_DEVICE_TABLE(pci, cavium_rng_vf_id_table);\ndrivers/char/hw_random/cavium-rng-vf.c-259-\n--\ndrivers/char/hw_random/cavium-rng.c=75=static const struct pci_device_id cavium_rng_pf_id_table[] = {\n--\ndrivers/char/hw_random/cavium-rng.c-79-\ndrivers/char/hw_random/cavium-rng.c:80:MODULE_DEVICE_TABLE(pci, cavium_rng_pf_id_table);\ndrivers/char/hw_random/cavium-rng.c-81-\n--\ndrivers/char/hw_random/cn10k-rng.c=212=static const struct pci_device_id cn10k_rng_id_table[] = {\n--\ndrivers/char/hw_random/cn10k-rng.c-216-\ndrivers/char/hw_random/cn10k-rng.c:217:MODULE_DEVICE_TABLE(pci, cn10k_rng_id_table);\ndrivers/char/hw_random/cn10k-rng.c-218-\n--\ndrivers/char/hw_random/geode-rng.c=48=static const struct pci_device_id pci_tbl[] = {\n--\ndrivers/char/hw_random/geode-rng.c-51-};\ndrivers/char/hw_random/geode-rng.c:52:MODULE_DEVICE_TABLE(pci, pci_tbl);\ndrivers/char/hw_random/geode-rng.c-53-\n--\ndrivers/char/hw_random/intel-rng.c=100=static const struct pci_device_id pci_tbl[] = {\n--\ndrivers/char/hw_random/intel-rng.c-146-};\ndrivers/char/hw_random/intel-rng.c:147:MODULE_DEVICE_TABLE(pci, pci_tbl);\ndrivers/char/hw_random/intel-rng.c-148-\n--\ndrivers/char/ipmi/ipmi_si_pci.c=134=static const struct pci_device_id ipmi_pci_devices[] = {\n--\ndrivers/char/ipmi/ipmi_si_pci.c-140-};\ndrivers/char/ipmi/ipmi_si_pci.c:141:MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);\ndrivers/char/ipmi/ipmi_si_pci.c-142-\n--\ndrivers/char/xillybus/xillybus_pcie.c=111=static void xilly_remove(struct pci_dev *pdev)\n--\ndrivers/char/xillybus/xillybus_pcie.c-117-\ndrivers/char/xillybus/xillybus_pcie.c:118:MODULE_DEVICE_TABLE(pci, xillyids);\ndrivers/char/xillybus/xillybus_pcie.c-119-\n--\ndrivers/comedi/drivers/8255_pci.c=268=static const struct pci_device_id pci_8255_pci_table[] = {\n--\ndrivers/comedi/drivers/8255_pci.c-289-};\ndrivers/comedi/drivers/8255_pci.c:290:MODULE_DEVICE_TABLE(pci, pci_8255_pci_table);\ndrivers/comedi/drivers/8255_pci.c-291-\n--\ndrivers/comedi/drivers/addi_apci_1032.c=380=static const struct pci_device_id apci1032_pci_table[] = {\n--\ndrivers/comedi/drivers/addi_apci_1032.c-383-};\ndrivers/comedi/drivers/addi_apci_1032.c:384:MODULE_DEVICE_TABLE(pci, apci1032_pci_table);\ndrivers/comedi/drivers/addi_apci_1032.c-385-\n--\ndrivers/comedi/drivers/addi_apci_1500.c=871=static const struct pci_device_id apci1500_pci_table[] = {\n--\ndrivers/comedi/drivers/addi_apci_1500.c-874-};\ndrivers/comedi/drivers/addi_apci_1500.c:875:MODULE_DEVICE_TABLE(pci, apci1500_pci_table);\ndrivers/comedi/drivers/addi_apci_1500.c-876-\n--\ndrivers/comedi/drivers/addi_apci_1516.c=198=static const struct pci_device_id apci1516_pci_table[] = {\n--\ndrivers/comedi/drivers/addi_apci_1516.c-203-};\ndrivers/comedi/drivers/addi_apci_1516.c:204:MODULE_DEVICE_TABLE(pci, apci1516_pci_table);\ndrivers/comedi/drivers/addi_apci_1516.c-205-\n--\ndrivers/comedi/drivers/addi_apci_1564.c=804=static const struct pci_device_id apci1564_pci_table[] = {\n--\ndrivers/comedi/drivers/addi_apci_1564.c-807-};\ndrivers/comedi/drivers/addi_apci_1564.c:808:MODULE_DEVICE_TABLE(pci, apci1564_pci_table);\ndrivers/comedi/drivers/addi_apci_1564.c-809-\n--\ndrivers/comedi/drivers/addi_apci_16xx.c=160=static const struct pci_device_id apci16xx_pci_table[] = {\n--\ndrivers/comedi/drivers/addi_apci_16xx.c-164-};\ndrivers/comedi/drivers/addi_apci_16xx.c:165:MODULE_DEVICE_TABLE(pci, apci16xx_pci_table);\ndrivers/comedi/drivers/addi_apci_16xx.c-166-\n--\ndrivers/comedi/drivers/addi_apci_2032.c=314=static const struct pci_device_id apci2032_pci_table[] = {\n--\ndrivers/comedi/drivers/addi_apci_2032.c-317-};\ndrivers/comedi/drivers/addi_apci_2032.c:318:MODULE_DEVICE_TABLE(pci, apci2032_pci_table);\ndrivers/comedi/drivers/addi_apci_2032.c-319-\n--\ndrivers/comedi/drivers/addi_apci_2200.c=127=static const struct pci_device_id apci2200_pci_table[] = {\n--\ndrivers/comedi/drivers/addi_apci_2200.c-130-};\ndrivers/comedi/drivers/addi_apci_2200.c:131:MODULE_DEVICE_TABLE(pci, apci2200_pci_table);\ndrivers/comedi/drivers/addi_apci_2200.c-132-\n--\n\n"
} |
| 23/2 | 2026/07/04 11:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 53844 output: 36 thoughts: 792 Thoughts: **Analyzing the Path to `mt7628_tag_rcv`** Okay, so we're looking at a patch related to `mt7628`, which is a platform device. First thing I'm checking is how to actually get to that `mt7628_tag_rcv` function. I know `felix` is a PCI device, but it's an Ocelot switch, so that's a dead end since this is about a platform device. I remember Syzkaller works by injecting PCI devices via the descriptions, but this isn't PCI. The goal seems to be creating a DSA switch tree and set the tag protocol to `mt7628` which should cause packets on the conduit interface to be passed to that function. But `dsa_tree_change_tag_proto` is what we need and that calls `dsa_switch_change_tag_proto`. That in turn requires the switch to support `change_tag_protocol`. If I instantiate a dummy DSA switch, like `dsa_loop`, it doesn't support that! Right, `dsa_loop` doesn't implement it. `dsa_switch_change_tag_proto` will then return `-EOPNOTSUPP` for `dsa_loop`, meaning that won't work. Could I somehow use `felix`? No, Syzkaller doesn't have descriptions for it, and it needs specific IDs and BARs, so that won't work. Okay, let's back up. I see in `net/dsa/dsa.c` that `dsa_port_parse_cpu` calls `dsa_switch_setup_tag_protocol`, which determines the default protocol based on the switch driver's `get_tag_protocol`. So if I can't change the protocol of `dsa_loop` to `mt7628`, I can't get there using that approach. And `dsa_loop` is hardcoded to return `DSA_TAG_PROTO_NONE`, so that's definitely a no-go. It's a mock driver, after all. Is there *any* other way to inject packets into the tag driver? Tag drivers are only called by `dsa_switch_rcv`, and that function is the packet handler for `ETH_P_XDSA` or `ETH_P_8021Q` or `ETH_P_ALL`, depending on the tag protocol. But wait, `mt7628_tag_rcv` is called from `dsa_switch_rcv` *if* the conduit device has `cpu_dp->tag_ops == &mt7628_tag_ops`. Can I set `cpu_dp->tag_ops` somehow, via netlink or sysfs? Aha! `tagging_store` in `net/dsa/conduit.c` allows me to change it! But... checking the code, it calls `dsa_tree_change_tag_proto`, which calls `dsa_switch_change_tag_proto`, which *again* returns `-EOPNOTSUPP` if `ds->ops->change_tag_protocol` is NULL! So, the `tagging_store` will fail if the switch doesn't support `change_tag_protocol`. I need to verify this is the behavior. |
| 24/2 | 2026/07/04 11:40 | tool | read-file |
0mArgs:{
"File": "net/dsa/switch.c",
"FirstLine": 873,
"LineCount": 20
}Results: {
"Contents": " 873:\tstatic int dsa_switch_change_tag_proto(struct dsa_switch *ds,\n 874:\t\t\t\t\t struct dsa_notifier_tag_proto_info *info)\n 875:\t{\n 876:\t\tconst struct dsa_device_ops *tag_ops = info-\u003etag_ops;\n 877:\t\tstruct dsa_port *dp, *cpu_dp;\n 878:\t\tint err;\n 879:\t\n 880:\t\tif (!ds-\u003eops-\u003echange_tag_protocol)\n 881:\t\t\treturn -EOPNOTSUPP;\n 882:\t\n 883:\t\tASSERT_RTNL();\n 884:\t\n 885:\t\terr = ds-\u003eops-\u003echange_tag_protocol(ds, tag_ops-\u003eproto);\n 886:\t\tif (err)\n 887:\t\t\treturn err;\n 888:\t\n 889:\t\tdsa_switch_for_each_cpu_port(cpu_dp, ds)\n 890:\t\t\tdsa_port_set_tag_protocol(cpu_dp, tag_ops);\n 891:\t\n 892:\t\t/* Now that changing the tag protocol can no longer fail, let's update\n"
} |
| 25/2 | 2026/07/04 11:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 55744 output: 18 thoughts: 706 Thoughts: **Unreachable Code in Syzkaller: A Deep Dive** Okay, so the `change_tag_protocol` operation in the DSA framework is giving me a headache. I've been thinking about how to exercise this code path, and it looks like I'm hitting a wall with syzkaller. Let's break this down. First, it's clear that the code I'm looking at returns `-EOPNOTSUPP` if the `ds->ops->change_tag_protocol` function pointer is NULL. This means I need to find a DSA switch that *does* support changing the tag protocol to make any headway. My initial thought was to look at switches I know, like `mv88e6xxx`, `felix`, and `rtl8365mb`. However, they are a problem. `mv88e6xxx` and `rtl8365mb` are MDIO devices, and unfortunately, I don't think syzkaller has a good way to instantiate those. I thought maybe `syz_mdio_setup` could do it, but no luck. `felix` is a PCI device, and I also couldn't get it working with syzkaller, which relies on QEMU, and QEMU doesn't have the `felix` switch. `vhci` or `dummy` devices can't help either. Using `syz_dev_create` looks like a non-starter. So, I started thinking about specific drivers. `tag_mt7628.c` is practically unreachable in the current syzkaller setup. I briefly checked other related drivers, like `mt7628.c` and `mtk-fe-soc.c`, but they're either platform or MDIO drivers, which syzkaller struggles with as well. I even entertained the idea of using device tree overlays or dynamically registering platform devices using `platform_device_register`. No luck on that front either. I checked for a `syz_platform_device_register`, but syzkaller doesn't have such a primitive. Even `syz_dev_create` is only for `/dev/` nodes. This patch is looking increasingly unreachable in a virtualized environment like syzkaller. Okay, let's see if there is any other way to reach `mt7628_tag_rcv`. It's a static function registered through `module_dsa_tag_driver`, so calling it directly is impossible. Could it be used by some other switch that I'm overlooking? No, it looks like no other switch returns `DSA_TAG_PROTO_MT7628` by default. Can I change the tag protocol of *another* switch to `mt7628`? That would only work if it supports `change_tag_protocol`. And the switches that support `change_tag_protocol` are the ones I mentioned earlier: `mv88e6xxx`, `felix`, and `rtl8365mb`. But wait... What if syzkaller *could* instantiate `mv88e6xxx`? There's a `dsa_loop` driver, which is a mock driver, that is instantiated by `dsa_loop_bdinfo.c`, which registers an MDIO device! Now that sounds like something I should check! I'll look into `dsa_loop_bdinfo.c`. This could be the breakthrough I'm looking for! |
| 26/2 | 2026/07/04 11:41 | tool | grepper |
0mArgs:{
"Expression": "dsa_loop"
}Results: {
"Output": "Documentation/networking/dsa/dsa.rst=159=all attached switch ports must be down while doing this).\nDocumentation/networking/dsa/dsa.rst-160-\nDocumentation/networking/dsa/dsa.rst:161:It is desirable that all tagging protocols are testable with the ``dsa_loop``\nDocumentation/networking/dsa/dsa.rst-162-mockup driver, which can be attached to any network interface. The goal is that\n--\ndrivers/net/dsa/Makefile=3=bcm-sf2-objs\t\t\t:= bcm_sf2.o bcm_sf2_cfp.o\ndrivers/net/dsa/Makefile:4:obj-$(CONFIG_NET_DSA_LOOP)\t+= dsa_loop.o\ndrivers/net/dsa/Makefile-5-obj-$(CONFIG_NET_DSA_KS8995) \t+= ks8995.o\n--\ndrivers/net/dsa/dsa_loop.c-24-\ndrivers/net/dsa/dsa_loop.c:25:struct dsa_loop_vlan {\ndrivers/net/dsa/dsa_loop.c-26-\tu16 members;\n--\ndrivers/net/dsa/dsa_loop.c-29-\ndrivers/net/dsa/dsa_loop.c:30:struct dsa_loop_mib_entry {\ndrivers/net/dsa/dsa_loop.c-31-\tchar name[ETH_GSTRING_LEN];\n--\ndrivers/net/dsa/dsa_loop.c-34-\ndrivers/net/dsa/dsa_loop.c:35:enum dsa_loop_mib_counters {\ndrivers/net/dsa/dsa_loop.c-36-\tDSA_LOOP_PHY_READ_OK,\n--\ndrivers/net/dsa/dsa_loop.c-42-\ndrivers/net/dsa/dsa_loop.c:43:struct dsa_loop_port {\ndrivers/net/dsa/dsa_loop.c:44:\tstruct dsa_loop_mib_entry mib[__DSA_LOOP_CNT_MAX];\ndrivers/net/dsa/dsa_loop.c-45-\tu16 pvid;\n--\ndrivers/net/dsa/dsa_loop.c-48-\ndrivers/net/dsa/dsa_loop.c:49:struct dsa_loop_priv {\ndrivers/net/dsa/dsa_loop.c-50-\tstruct mii_bus\t*bus;\ndrivers/net/dsa/dsa_loop.c-51-\tunsigned int\tport_base;\ndrivers/net/dsa/dsa_loop.c:52:\tstruct dsa_loop_vlan vlans[VLAN_N_VID];\ndrivers/net/dsa/dsa_loop.c-53-\tstruct net_device *netdev;\ndrivers/net/dsa/dsa_loop.c:54:\tstruct dsa_loop_port ports[DSA_MAX_PORTS];\ndrivers/net/dsa/dsa_loop.c-55-};\ndrivers/net/dsa/dsa_loop.c-56-\ndrivers/net/dsa/dsa_loop.c:57:struct dsa_loop_pdata {\ndrivers/net/dsa/dsa_loop.c-58-\t/* Must be first, such that dsa_register_switch() can access this\n--\ndrivers/net/dsa/dsa_loop.c-66-\ndrivers/net/dsa/dsa_loop.c:67:static struct dsa_loop_mib_entry dsa_loop_mibs[] = {\ndrivers/net/dsa/dsa_loop.c-68-\t[DSA_LOOP_PHY_READ_OK]\t= { \"phy_read_ok\", },\n--\ndrivers/net/dsa/dsa_loop.c=75=static struct mdio_device *switch_mdiodev;\ndrivers/net/dsa/dsa_loop.c-76-\ndrivers/net/dsa/dsa_loop.c:77:enum dsa_loop_devlink_resource_id {\ndrivers/net/dsa/dsa_loop.c-78-\tDSA_LOOP_DEVLINK_PARAM_ID_NONE, /* DEVLINK_RESOURCE_ID_PARENT_TOP */\n--\ndrivers/net/dsa/dsa_loop.c-81-\ndrivers/net/dsa/dsa_loop.c:82:static u64 dsa_loop_devlink_vtu_get(void *priv)\ndrivers/net/dsa/dsa_loop.c-83-{\ndrivers/net/dsa/dsa_loop.c:84:\tstruct dsa_loop_priv *ps = priv;\ndrivers/net/dsa/dsa_loop.c-85-\tunsigned int i, count = 0;\ndrivers/net/dsa/dsa_loop.c:86:\tstruct dsa_loop_vlan *vl;\ndrivers/net/dsa/dsa_loop.c-87-\n--\ndrivers/net/dsa/dsa_loop.c-96-\ndrivers/net/dsa/dsa_loop.c:97:static int dsa_loop_setup_devlink_resources(struct dsa_switch *ds)\ndrivers/net/dsa/dsa_loop.c-98-{\ndrivers/net/dsa/dsa_loop.c-99-\tstruct devlink_resource_size_params size_params;\ndrivers/net/dsa/dsa_loop.c:100:\tstruct dsa_loop_priv *ps = ds-\u003epriv;\ndrivers/net/dsa/dsa_loop.c-101-\tint err;\n--\ndrivers/net/dsa/dsa_loop.c-115-\t\t\t\t\t DSA_LOOP_DEVLINK_PARAM_ID_VTU,\ndrivers/net/dsa/dsa_loop.c:116:\t\t\t\t\t dsa_loop_devlink_vtu_get, ps);\ndrivers/net/dsa/dsa_loop.c-117-\n--\ndrivers/net/dsa/dsa_loop.c-124-\ndrivers/net/dsa/dsa_loop.c:125:static enum dsa_tag_protocol dsa_loop_get_protocol(struct dsa_switch *ds,\ndrivers/net/dsa/dsa_loop.c-126-\t\t\t\t\t\t int port,\n--\ndrivers/net/dsa/dsa_loop.c-133-\ndrivers/net/dsa/dsa_loop.c:134:static int dsa_loop_setup(struct dsa_switch *ds)\ndrivers/net/dsa/dsa_loop.c-135-{\ndrivers/net/dsa/dsa_loop.c:136:\tstruct dsa_loop_priv *ps = ds-\u003epriv;\ndrivers/net/dsa/dsa_loop.c-137-\tunsigned int i;\n--\ndrivers/net/dsa/dsa_loop.c-139-\tfor (i = 0; i \u003c ds-\u003enum_ports; i++)\ndrivers/net/dsa/dsa_loop.c:140:\t\tmemcpy(ps-\u003eports[i].mib, dsa_loop_mibs,\ndrivers/net/dsa/dsa_loop.c:141:\t\t sizeof(dsa_loop_mibs));\ndrivers/net/dsa/dsa_loop.c-142-\n--\ndrivers/net/dsa/dsa_loop.c-144-\ndrivers/net/dsa/dsa_loop.c:145:\treturn dsa_loop_setup_devlink_resources(ds);\ndrivers/net/dsa/dsa_loop.c-146-}\ndrivers/net/dsa/dsa_loop.c-147-\ndrivers/net/dsa/dsa_loop.c:148:static void dsa_loop_teardown(struct dsa_switch *ds)\ndrivers/net/dsa/dsa_loop.c-149-{\n--\ndrivers/net/dsa/dsa_loop.c-152-\ndrivers/net/dsa/dsa_loop.c:153:static int dsa_loop_get_sset_count(struct dsa_switch *ds, int port, int sset)\ndrivers/net/dsa/dsa_loop.c-154-{\n--\ndrivers/net/dsa/dsa_loop.c-160-\ndrivers/net/dsa/dsa_loop.c:161:static void dsa_loop_get_strings(struct dsa_switch *ds, int port,\ndrivers/net/dsa/dsa_loop.c-162-\t\t\t\t u32 stringset, uint8_t *data)\ndrivers/net/dsa/dsa_loop.c-163-{\ndrivers/net/dsa/dsa_loop.c:164:\tstruct dsa_loop_priv *ps = ds-\u003epriv;\ndrivers/net/dsa/dsa_loop.c-165-\tunsigned int i;\n--\ndrivers/net/dsa/dsa_loop.c-173-\ndrivers/net/dsa/dsa_loop.c:174:static void dsa_loop_get_ethtool_stats(struct dsa_switch *ds, int port,\ndrivers/net/dsa/dsa_loop.c-175-\t\t\t\t uint64_t *data)\ndrivers/net/dsa/dsa_loop.c-176-{\ndrivers/net/dsa/dsa_loop.c:177:\tstruct dsa_loop_priv *ps = ds-\u003epriv;\ndrivers/net/dsa/dsa_loop.c-178-\tunsigned int i;\n--\ndrivers/net/dsa/dsa_loop.c-183-\ndrivers/net/dsa/dsa_loop.c:184:static int dsa_loop_phy_read(struct dsa_switch *ds, int port, int regnum)\ndrivers/net/dsa/dsa_loop.c-185-{\ndrivers/net/dsa/dsa_loop.c:186:\tstruct dsa_loop_priv *ps = ds-\u003epriv;\ndrivers/net/dsa/dsa_loop.c-187-\tstruct mii_bus *bus = ps-\u003ebus;\n--\ndrivers/net/dsa/dsa_loop.c-198-\ndrivers/net/dsa/dsa_loop.c:199:static int dsa_loop_phy_write(struct dsa_switch *ds, int port,\ndrivers/net/dsa/dsa_loop.c-200-\t\t\t int regnum, u16 value)\ndrivers/net/dsa/dsa_loop.c-201-{\ndrivers/net/dsa/dsa_loop.c:202:\tstruct dsa_loop_priv *ps = ds-\u003epriv;\ndrivers/net/dsa/dsa_loop.c-203-\tstruct mii_bus *bus = ps-\u003ebus;\n--\ndrivers/net/dsa/dsa_loop.c-214-\ndrivers/net/dsa/dsa_loop.c:215:static int dsa_loop_port_bridge_join(struct dsa_switch *ds, int port,\ndrivers/net/dsa/dsa_loop.c-216-\t\t\t\t struct dsa_bridge bridge,\n--\ndrivers/net/dsa/dsa_loop.c-225-\ndrivers/net/dsa/dsa_loop.c:226:static void dsa_loop_port_bridge_leave(struct dsa_switch *ds, int port,\ndrivers/net/dsa/dsa_loop.c-227-\t\t\t\t struct dsa_bridge bridge)\n--\ndrivers/net/dsa/dsa_loop.c-232-\ndrivers/net/dsa/dsa_loop.c:233:static void dsa_loop_port_stp_state_set(struct dsa_switch *ds, int port,\ndrivers/net/dsa/dsa_loop.c-234-\t\t\t\t\tu8 state)\n--\ndrivers/net/dsa/dsa_loop.c-239-\ndrivers/net/dsa/dsa_loop.c:240:static int dsa_loop_port_vlan_filtering(struct dsa_switch *ds, int port,\ndrivers/net/dsa/dsa_loop.c-241-\t\t\t\t\tbool vlan_filtering,\n--\ndrivers/net/dsa/dsa_loop.c-249-\ndrivers/net/dsa/dsa_loop.c:250:static int dsa_loop_port_vlan_add(struct dsa_switch *ds, int port,\ndrivers/net/dsa/dsa_loop.c-251-\t\t\t\t const struct switchdev_obj_port_vlan *vlan,\n--\ndrivers/net/dsa/dsa_loop.c-255-\tbool pvid = vlan-\u003eflags \u0026 BRIDGE_VLAN_INFO_PVID;\ndrivers/net/dsa/dsa_loop.c:256:\tstruct dsa_loop_priv *ps = ds-\u003epriv;\ndrivers/net/dsa/dsa_loop.c-257-\tstruct mii_bus *bus = ps-\u003ebus;\ndrivers/net/dsa/dsa_loop.c:258:\tstruct dsa_loop_vlan *vl;\ndrivers/net/dsa/dsa_loop.c-259-\n--\ndrivers/net/dsa/dsa_loop.c-282-\ndrivers/net/dsa/dsa_loop.c:283:static int dsa_loop_port_vlan_del(struct dsa_switch *ds, int port,\ndrivers/net/dsa/dsa_loop.c-284-\t\t\t\t const struct switchdev_obj_port_vlan *vlan)\n--\ndrivers/net/dsa/dsa_loop.c-286-\tbool untagged = vlan-\u003eflags \u0026 BRIDGE_VLAN_INFO_UNTAGGED;\ndrivers/net/dsa/dsa_loop.c:287:\tstruct dsa_loop_priv *ps = ds-\u003epriv;\ndrivers/net/dsa/dsa_loop.c-288-\tu16 pvid = ps-\u003eports[port].pvid;\ndrivers/net/dsa/dsa_loop.c-289-\tstruct mii_bus *bus = ps-\u003ebus;\ndrivers/net/dsa/dsa_loop.c:290:\tstruct dsa_loop_vlan *vl;\ndrivers/net/dsa/dsa_loop.c-291-\n--\ndrivers/net/dsa/dsa_loop.c-310-\ndrivers/net/dsa/dsa_loop.c:311:static int dsa_loop_port_change_mtu(struct dsa_switch *ds, int port,\ndrivers/net/dsa/dsa_loop.c-312-\t\t\t\t int new_mtu)\ndrivers/net/dsa/dsa_loop.c-313-{\ndrivers/net/dsa/dsa_loop.c:314:\tstruct dsa_loop_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/dsa_loop.c-315-\n--\ndrivers/net/dsa/dsa_loop.c-320-\ndrivers/net/dsa/dsa_loop.c:321:static int dsa_loop_port_max_mtu(struct dsa_switch *ds, int port)\ndrivers/net/dsa/dsa_loop.c-322-{\n--\ndrivers/net/dsa/dsa_loop.c-325-\ndrivers/net/dsa/dsa_loop.c:326:static void dsa_loop_phylink_get_caps(struct dsa_switch *dsa, int port,\ndrivers/net/dsa/dsa_loop.c-327-\t\t\t\t struct phylink_config *config)\n--\ndrivers/net/dsa/dsa_loop.c-333-\ndrivers/net/dsa/dsa_loop.c:334:static const struct dsa_switch_ops dsa_loop_driver = {\ndrivers/net/dsa/dsa_loop.c:335:\t.get_tag_protocol\t= dsa_loop_get_protocol,\ndrivers/net/dsa/dsa_loop.c:336:\t.setup\t\t\t= dsa_loop_setup,\ndrivers/net/dsa/dsa_loop.c:337:\t.teardown\t\t= dsa_loop_teardown,\ndrivers/net/dsa/dsa_loop.c:338:\t.get_strings\t\t= dsa_loop_get_strings,\ndrivers/net/dsa/dsa_loop.c:339:\t.get_ethtool_stats\t= dsa_loop_get_ethtool_stats,\ndrivers/net/dsa/dsa_loop.c:340:\t.get_sset_count\t\t= dsa_loop_get_sset_count,\ndrivers/net/dsa/dsa_loop.c:341:\t.get_ethtool_phy_stats\t= dsa_loop_get_ethtool_stats,\ndrivers/net/dsa/dsa_loop.c:342:\t.phy_read\t\t= dsa_loop_phy_read,\ndrivers/net/dsa/dsa_loop.c:343:\t.phy_write\t\t= dsa_loop_phy_write,\ndrivers/net/dsa/dsa_loop.c:344:\t.port_bridge_join\t= dsa_loop_port_bridge_join,\ndrivers/net/dsa/dsa_loop.c:345:\t.port_bridge_leave\t= dsa_loop_port_bridge_leave,\ndrivers/net/dsa/dsa_loop.c:346:\t.port_stp_state_set\t= dsa_loop_port_stp_state_set,\ndrivers/net/dsa/dsa_loop.c:347:\t.port_vlan_filtering\t= dsa_loop_port_vlan_filtering,\ndrivers/net/dsa/dsa_loop.c:348:\t.port_vlan_add\t\t= dsa_loop_port_vlan_add,\ndrivers/net/dsa/dsa_loop.c:349:\t.port_vlan_del\t\t= dsa_loop_port_vlan_del,\ndrivers/net/dsa/dsa_loop.c:350:\t.port_change_mtu\t= dsa_loop_port_change_mtu,\ndrivers/net/dsa/dsa_loop.c:351:\t.port_max_mtu\t\t= dsa_loop_port_max_mtu,\ndrivers/net/dsa/dsa_loop.c:352:\t.phylink_get_caps\t= dsa_loop_phylink_get_caps,\ndrivers/net/dsa/dsa_loop.c-353-};\ndrivers/net/dsa/dsa_loop.c-354-\ndrivers/net/dsa/dsa_loop.c:355:static int dsa_loop_drv_probe(struct mdio_device *mdiodev)\ndrivers/net/dsa/dsa_loop.c-356-{\ndrivers/net/dsa/dsa_loop.c:357:\tstruct dsa_loop_pdata *pdata = mdiodev-\u003edev.platform_data;\ndrivers/net/dsa/dsa_loop.c:358:\tstruct dsa_loop_priv *ps;\ndrivers/net/dsa/dsa_loop.c-359-\tstruct dsa_switch *ds;\n--\ndrivers/net/dsa/dsa_loop.c-382-\tds-\u003edev = \u0026mdiodev-\u003edev;\ndrivers/net/dsa/dsa_loop.c:383:\tds-\u003eops = \u0026dsa_loop_driver;\ndrivers/net/dsa/dsa_loop.c-384-\tds-\u003epriv = ps;\n--\ndrivers/net/dsa/dsa_loop.c-396-\ndrivers/net/dsa/dsa_loop.c:397:static void dsa_loop_drv_remove(struct mdio_device *mdiodev)\ndrivers/net/dsa/dsa_loop.c-398-{\ndrivers/net/dsa/dsa_loop.c-399-\tstruct dsa_switch *ds = dev_get_drvdata(\u0026mdiodev-\u003edev);\ndrivers/net/dsa/dsa_loop.c:400:\tstruct dsa_loop_priv *ps;\ndrivers/net/dsa/dsa_loop.c-401-\n--\ndrivers/net/dsa/dsa_loop.c-410-\ndrivers/net/dsa/dsa_loop.c:411:static void dsa_loop_drv_shutdown(struct mdio_device *mdiodev)\ndrivers/net/dsa/dsa_loop.c-412-{\n--\ndrivers/net/dsa/dsa_loop.c-422-\ndrivers/net/dsa/dsa_loop.c:423:static struct mdio_driver dsa_loop_drv = {\ndrivers/net/dsa/dsa_loop.c-424-\t.mdiodrv.driver\t= {\n--\ndrivers/net/dsa/dsa_loop.c-426-\t},\ndrivers/net/dsa/dsa_loop.c:427:\t.probe\t= dsa_loop_drv_probe,\ndrivers/net/dsa/dsa_loop.c:428:\t.remove\t= dsa_loop_drv_remove,\ndrivers/net/dsa/dsa_loop.c:429:\t.shutdown = dsa_loop_drv_shutdown,\ndrivers/net/dsa/dsa_loop.c-430-};\ndrivers/net/dsa/dsa_loop.c-431-\ndrivers/net/dsa/dsa_loop.c:432:static int dsa_loop_bus_match(struct device *dev,\ndrivers/net/dsa/dsa_loop.c-433-\t\t\t const struct device_driver *drv)\ndrivers/net/dsa/dsa_loop.c-434-{\ndrivers/net/dsa/dsa_loop.c:435:\treturn drv == \u0026dsa_loop_drv.mdiodrv.driver;\ndrivers/net/dsa/dsa_loop.c-436-}\ndrivers/net/dsa/dsa_loop.c-437-\ndrivers/net/dsa/dsa_loop.c:438:static void dsa_loop_phydevs_unregister(void)\ndrivers/net/dsa/dsa_loop.c-439-{\n--\ndrivers/net/dsa/dsa_loop.c-445-\ndrivers/net/dsa/dsa_loop.c:446:static int __init dsa_loop_create_switch_mdiodev(void)\ndrivers/net/dsa/dsa_loop.c-447-{\ndrivers/net/dsa/dsa_loop.c:448:\tstatic struct dsa_loop_pdata dsa_loop_pdata = {\ndrivers/net/dsa/dsa_loop.c-449-\t\t.cd = {\n--\ndrivers/net/dsa/dsa_loop.c-470-\ndrivers/net/dsa/dsa_loop.c:471:\tswitch_mdiodev-\u003ebus_match = dsa_loop_bus_match;\ndrivers/net/dsa/dsa_loop.c:472:\tswitch_mdiodev-\u003edev.platform_data = \u0026dsa_loop_pdata;\ndrivers/net/dsa/dsa_loop.c-473-\n--\ndrivers/net/dsa/dsa_loop.c-481-\ndrivers/net/dsa/dsa_loop.c:482:static int __init dsa_loop_init(void)\ndrivers/net/dsa/dsa_loop.c-483-{\n--\ndrivers/net/dsa/dsa_loop.c-486-\ndrivers/net/dsa/dsa_loop.c:487:\tret = dsa_loop_create_switch_mdiodev();\ndrivers/net/dsa/dsa_loop.c-488-\tif (ret)\n--\ndrivers/net/dsa/dsa_loop.c-493-\ndrivers/net/dsa/dsa_loop.c:494:\tret = mdio_driver_register(\u0026dsa_loop_drv);\ndrivers/net/dsa/dsa_loop.c-495-\tif (ret) {\ndrivers/net/dsa/dsa_loop.c:496:\t\tdsa_loop_phydevs_unregister();\ndrivers/net/dsa/dsa_loop.c-497-\t\tmdio_device_remove(switch_mdiodev);\n--\ndrivers/net/dsa/dsa_loop.c-502-}\ndrivers/net/dsa/dsa_loop.c:503:module_init(dsa_loop_init);\ndrivers/net/dsa/dsa_loop.c-504-\ndrivers/net/dsa/dsa_loop.c:505:static void __exit dsa_loop_exit(void)\ndrivers/net/dsa/dsa_loop.c-506-{\ndrivers/net/dsa/dsa_loop.c:507:\tmdio_driver_unregister(\u0026dsa_loop_drv);\ndrivers/net/dsa/dsa_loop.c:508:\tdsa_loop_phydevs_unregister();\ndrivers/net/dsa/dsa_loop.c-509-\tmdio_device_remove(switch_mdiodev);\n--\ndrivers/net/dsa/dsa_loop.c-511-}\ndrivers/net/dsa/dsa_loop.c:512:module_exit(dsa_loop_exit);\ndrivers/net/dsa/dsa_loop.c-513-\n"
} |
| 27/2 | 2026/07/04 11:41 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 63876 output: 172 thoughts: 870 Thoughts: **Unreachable Code in a Virtualized Environment** Okay, so I've been digging into this code and I've come to a pretty firm conclusion: this patch, as it stands, is unreachable in a virtualized environment. Let me break down my thinking. First, the core issue is the dependency on specific hardware features. The `mt7628` platform driver, the one that’s key to all this, requires MMIO resources and reset controllers. Those are simply not present in a virtualized setup like QEMU or Google Compute Engine. I'm not seeing any way around that. Then there's the PHY driver, `mtk-fe-soc.c`. It's looking for an MDIO bus and a specific PHY ID. Again, in a virtual environment, we're not going to have that specific hardware configuration available. It's expecting a physical connection, which just isn't there. The crucial link is the DSA tag driver, `net/dsa/tag_mt7628.c`. It depends on a DSA switch being configured to use the `DSA_TAG_PROTO_MT7628` protocol. I know the default here is to go to the `mt7628` switch itself. But the problem is, the only mock switch we *do* have that's available in a virtual environment, `dsa_loop`, *doesn't* support dynamically changing its tag protocol. And other switches which implement this are hardware-specific, so there's no way to reach them virtually. The only way to change the tag protocol would be to use the `change_tag_protocol` function, but `dsa_loop` does not implement this. I even tried to consider whether we could manipulate things with Syzkaller, but no dice. Syzkaller can't patch the kernel at runtime to make `dsa_loop` behave differently, or magically create a dummy DSA switch with the correct capabilities. Injecting packets directly to trigger `mt7628_tag_rcv` wouldn't work either because it requires a DSA switch tree and a conduit device which requires a master switch. I also checked for any netlink interfaces to create a DSA switch, and there aren't any, which seems to imply that switches are always created by hardware drivers. Syzkaller can only fuzz DSA if `dsa_loop` is loaded, but it uses a default protocol and can't be changed. So, bottom line: the code paths introduced by this patch are, for all practical purposes, unreachable in a virtualized environment. The dependencies on hardware features, and the limitations of our virtualization tools, make it impossible to trigger the relevant logic. I'm going to return `WorthFuzzing=false` here. There's no point in trying to fuzz code we can't get to. |
| 28/2 | 2026/07/04 11:41 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch adds support for the MediaTek MT7628 Embedded Ethernet Switch, including a platform driver, a PHY driver, and a DSA tag driver. The platform driver requires specific MMIO resources and reset controllers that are not present in virtualized environments (QEMU/GCE). The PHY driver requires an MDIO bus with a specific hardware PHY ID. The DSA tag driver can only be reached if a DSA switch is configured to use the MT7628 tag protocol. The only mock DSA switch available in virtualized environments (dsa_loop) does not support changing its tag protocol at runtime. Therefore, the modified code paths are impossible to reach in a virtualized environment.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch adds support for the MediaTek MT7628 Embedded Ethernet Switch, including a platform driver, a PHY driver, and a DSA tag driver. The platform driver requires specific MMIO resources and reset controllers that are not present in virtualized environments (QEMU/GCE). The PHY driver requires an MDIO bus with a specific hardware PHY ID. The DSA tag driver can only be reached if a DSA switch is configured to use the MT7628 tag protocol. The only mock DSA switch available in virtualized environments (dsa_loop) does not support changing its tag protocol at runtime. Therefore, the modified code paths are impossible to reach in a virtualized environment.",
"WorthFuzzing": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|