| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/09/09 16:04 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"KMSANReasoning": "",
"NeedsKMSAN": false,
"Reasoning": "The patch series updates Device Tree bindings documentation and adds support for EcoNet EN751221 SoCs and passthrough mode to the MediaTek MT7530 DSA Ethernet switch driver (drivers/net/dsa/mt7530*). This driver controls specific physical MediaTek/EcoNet SoC ethernet switches and MDIO/MMIO devices that cannot be instantiated or emulated in standard QEMU/GCE virtualized environments on the target architecture (amd64). Because the modified hardware-specific code paths are structurally unreachable, fuzzing is not warranted.",
"WorthFuzzing": false
} |
| 1/1 | 2026/09/09 16:04 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 38a726e966add9c303f38ccfb191675e814026e6\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Wed Sep 9 16:04:42 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml\nindex 90b3582b76190..106c4087528d7 100644\n--- a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml\n+++ b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml\n@@ -29,6 +29,12 @@ description: |\n and the switch registers are directly mapped into SoC's memory map rather than\n using MDIO. The DSA driver currently doesn't support MT7620 variants.\n \n+ EcoNet EN751221 SoCs have a memory mapped MT7530 with 3x 10/100 PHYs and 1x\n+ gigabit PHY. Some EN751221 chips such as EN7513G and EN7526G have a multi-chip\n+ module implementation of the MT7530 as well as the on-die switch. In these\n+ packages, the multi-chip module is connected to port 5 of the on-die switch\n+ via a TRGMII link.\n+\n There is only the standalone version of MT7531.\n \n Port 5 on MT7530 supports various configurations:\n@@ -73,6 +79,13 @@ description: |\n \n Check out example 7.\n \n+ The MT7530 and MT7531 switches are capable of being operated in \"passthrough\"\n+ mode. In this mode, traffic is unconditionally passed between the CPU port\n+ and the DSA port which links to a second switch. To use passthrough mode, the\n+ upstream switch is configured with a DSA link to the downstream switch. In\n+ passthrough mode the upstream switch is restricted, with no other ports or\n+ switch configuration allowed.\n+\n properties:\n compatible:\n oneOf:\n@@ -104,6 +117,14 @@ properties:\n Built-in switch of the EcoNet EN7528 SoC\n const: econet,en7528-switch\n \n+ - description:\n+ Built-in switch of EcoNet EN751221 SoC\n+ const: econet,en751221-switch\n+\n+ - description:\n+ Multi-chip module MT7530 in EN751221 SoC\n+ const: econet,en751221\n+\n reg:\n maxItems: 1\n \n@@ -153,8 +174,8 @@ properties:\n mediatek,mcm:\n type: boolean\n description:\n- Used for MT7621AT, MT7621DAT, MT7621ST and MT7623AI SoCs which the MT7530\n- switch is a part of the multi-chip module.\n+ Used for MT7621AT, MT7621DAT, MT7621ST, MT7623AI and EN751221 SoCs which\n+ the MT7530 switch is a part of the multi-chip module.\n \n reset-gpios:\n description: |\n@@ -216,6 +237,20 @@ $defs:\n phy-mode:\n const: internal\n \n+ mt7530-passthrough-dsa-port:\n+ patternProperties:\n+ \"^(ethernet-)?ports$\":\n+ patternProperties:\n+ \"^(ethernet-)?port@[0-6]$\":\n+ if:\n+ required: [ link ]\n+ then:\n+ properties:\n+ reg:\n+ const: 6\n+ phy-mode:\n+ const: trgmii\n+\n mt7530-dsa-port:\n patternProperties:\n \"^(ethernet-)?ports$\":\n@@ -323,6 +358,7 @@ allOf:\n - airoha,en7581-switch\n - airoha,an7583-switch\n - econet,en7528-switch\n+ - econet,en751221-switch\n then:\n $ref: \"#/$defs/builtin-dsa-port\"\n properties:\n@@ -330,6 +366,16 @@ allOf:\n mediatek,mcm: false\n reset-names: false\n \n+ - if:\n+ properties:\n+ compatible:\n+ enum:\n+ - econet,en751221\n+ then:\n+ $ref: \"#/$defs/mt7530-passthrough-dsa-port\"\n+ required:\n+ - mediatek,mcm\n+\n unevaluatedProperties: false\n \n examples:\ndiff --git a/drivers/net/dsa/mt7530-mdio.c b/drivers/net/dsa/mt7530-mdio.c\nindex 24ef54f3db2a6..2fd987ff85107 100644\n--- a/drivers/net/dsa/mt7530-mdio.c\n+++ b/drivers/net/dsa/mt7530-mdio.c\n@@ -139,6 +139,7 @@ mt7531_create_sgmii(struct mt7530_priv *priv)\n }\n \n static const struct of_device_id mt7530_of_match[] = {\n+\t{ .compatible = \"econet,en751221\", .data = \u0026mt753x_table[ID_EN751221_EXT], },\n \t{ .compatible = \"mediatek,mt7621\", .data = \u0026mt753x_table[ID_MT7621], },\n \t{ .compatible = \"mediatek,mt7530\", .data = \u0026mt753x_table[ID_MT7530], },\n \t{ .compatible = \"mediatek,mt7531\", .data = \u0026mt753x_table[ID_MT7531], },\ndiff --git a/drivers/net/dsa/mt7530-mmio.c b/drivers/net/dsa/mt7530-mmio.c\nindex cf3bdb23a2d54..1a29b1eefb2c0 100644\n--- a/drivers/net/dsa/mt7530-mmio.c\n+++ b/drivers/net/dsa/mt7530-mmio.c\n@@ -12,6 +12,7 @@\n static const struct of_device_id mt7988_of_match[] = {\n \t{ .compatible = \"airoha,an7583-switch\", .data = \u0026mt753x_table[ID_AN7583], },\n \t{ .compatible = \"airoha,en7581-switch\", .data = \u0026mt753x_table[ID_EN7581], },\n+\t{ .compatible = \"econet,en751221-switch\", .data = \u0026mt753x_table[ID_EN751221], },\n \t{ .compatible = \"econet,en7528-switch\", .data = \u0026mt753x_table[ID_EN7528], },\n \t{ .compatible = \"mediatek,mt7988-switch\", .data = \u0026mt753x_table[ID_MT7988], },\n \t{ /* sentinel */ }\n@@ -61,7 +62,12 @@ mt7988_probe(struct platform_device *pdev)\n \tif (IS_ERR(priv-\u003eregmap))\n \t\treturn PTR_ERR(priv-\u003eregmap);\n \n-\treturn dsa_register_switch(priv-\u003eds);\n+\tret = dsa_register_switch(priv-\u003eds);\n+\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn mt7530_setup_mdio(priv);\n }\n \n static void mt7988_remove(struct platform_device *pdev)\ndiff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c\nindex 28f94cd25b955..6fd4719aab89b 100644\n--- a/drivers/net/dsa/mt7530.c\n+++ b/drivers/net/dsa/mt7530.c\n@@ -46,6 +46,19 @@ static const struct mt7530_mib_desc mt7530_mib[] = {\n \tMIB_DESC(1, MT7530_PORT_MIB_RX_ARL_DROP, \"RxArlDrop\"),\n };\n \n+static int\n+mt753x_ctrl_phy_addr(struct mt7530_priv *priv)\n+{\n+\tif (priv-\u003eid == ID_EN751221)\n+\t\treturn 12;\n+\n+\tif (WARN_ON_ONCE(!priv-\u003emdiodev))\n+\t\treturn 0;\n+\n+\t/* Default is 1st PHY */\n+\treturn (priv-\u003emdiodev-\u003eaddr + 1) \u0026 (PHY_MAX_ADDR - 1);\n+}\n+\n static void\n mt7530_mutex_lock(struct mt7530_priv *priv)\n {\n@@ -63,32 +76,36 @@ mt7530_mutex_unlock(struct mt7530_priv *priv)\n static void\n core_write(struct mt7530_priv *priv, u32 reg, u32 val)\n {\n+\tint ctl_phy = mt753x_ctrl_phy_addr(priv);\n \tstruct mii_bus *bus = priv-\u003ebus;\n \tint ret;\n \n+\tif (!bus)\n+\t\tbus = priv-\u003echild_bus;\n+\n+\tif (WARN_ON_ONCE(!bus))\n+\t\treturn;\n+\n \tmt7530_mutex_lock(priv);\n \n \t/* Write the desired MMD Devad */\n-\tret = bus-\u003ewrite(bus, MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr),\n-\t\t\t MII_MMD_CTRL, MDIO_MMD_VEND2);\n+\tret = bus-\u003ewrite(bus, ctl_phy, MII_MMD_CTRL, MDIO_MMD_VEND2);\n \tif (ret \u003c 0)\n \t\tgoto err;\n \n \t/* Write the desired MMD register address */\n-\tret = bus-\u003ewrite(bus, MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr),\n-\t\t\t MII_MMD_DATA, reg);\n+\tret = bus-\u003ewrite(bus, ctl_phy, MII_MMD_DATA, reg);\n \tif (ret \u003c 0)\n \t\tgoto err;\n \n \t/* Select the Function : DATA with no post increment */\n-\tret = bus-\u003ewrite(bus, MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr),\n+\tret = bus-\u003ewrite(bus, ctl_phy,\n \t\t\t MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);\n \tif (ret \u003c 0)\n \t\tgoto err;\n \n \t/* Write the data into MMD's selected register */\n-\tret = bus-\u003ewrite(bus, MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr),\n-\t\t\t MII_MMD_DATA, val);\n+\tret = bus-\u003ewrite(bus, ctl_phy, MII_MMD_DATA, val);\n err:\n \tif (ret \u003c 0)\n \t\tdev_err(\u0026bus-\u003edev, \"failed to write mmd register\\n\");\n@@ -99,33 +116,37 @@ core_write(struct mt7530_priv *priv, u32 reg, u32 val)\n static void\n core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)\n {\n+\tint ctl_phy = mt753x_ctrl_phy_addr(priv);\n \tstruct mii_bus *bus = priv-\u003ebus;\n \tu32 val;\n \tint ret;\n \n+\tif (!bus)\n+\t\tbus = priv-\u003echild_bus;\n+\n+\tif (WARN_ON_ONCE(!bus))\n+\t\treturn;\n+\n \tmt7530_mutex_lock(priv);\n \n \t/* Write the desired MMD Devad */\n-\tret = bus-\u003ewrite(bus, MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr),\n-\t\t\t MII_MMD_CTRL, MDIO_MMD_VEND2);\n+\tret = bus-\u003ewrite(bus, ctl_phy, MII_MMD_CTRL, MDIO_MMD_VEND2);\n \tif (ret \u003c 0)\n \t\tgoto err;\n \n \t/* Write the desired MMD register address */\n-\tret = bus-\u003ewrite(bus, MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr),\n-\t\t\t MII_MMD_DATA, reg);\n+\tret = bus-\u003ewrite(bus, ctl_phy, MII_MMD_DATA, reg);\n \tif (ret \u003c 0)\n \t\tgoto err;\n \n \t/* Select the Function : DATA with no post increment */\n-\tret = bus-\u003ewrite(bus, MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr),\n+\tret = bus-\u003ewrite(bus, ctl_phy,\n \t\t\t MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);\n \tif (ret \u003c 0)\n \t\tgoto err;\n \n \t/* Read the content of the MMD's selected register */\n-\tret = bus-\u003eread(bus, MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr),\n-\t\t\tMII_MMD_DATA);\n+\tret = bus-\u003eread(bus, ctl_phy, MII_MMD_DATA);\n \tif (ret \u003c 0)\n \t\tgoto err;\n \tval = ret;\n@@ -133,8 +154,7 @@ core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)\n \tval \u0026= ~mask;\n \tval |= set;\n \t/* Write the data into MMD's selected register */\n-\tret = bus-\u003ewrite(bus, MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr),\n-\t\t\t MII_MMD_DATA, val);\n+\tret = bus-\u003ewrite(bus, ctl_phy, MII_MMD_DATA, val);\n err:\n \tif (ret \u003c 0)\n \t\tdev_err(\u0026bus-\u003edev, \"failed to write mmd register\\n\");\n@@ -327,12 +347,19 @@ mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)\n \tregmap_read(priv-\u003eregmap, MT753X_MTRAP, \u0026xtal);\n \txtal \u0026= MT7530_XTAL_MASK;\n \n+\t/* EN751221 on-die does not report clock speed in MTRAP */\n+\tif (priv-\u003eid == ID_EN751221)\n+\t\txtal = MT7530_XTAL_25MHZ;\n+\n \tif (xtal == MT7530_XTAL_25MHZ)\n \t\tssc_delta = 0x57;\n \telse\n \t\tssc_delta = 0x87;\n \n-\tif (priv-\u003eid == ID_MT7621) {\n+\tif (priv-\u003eid == ID_EN751221_EXT || priv-\u003eid == ID_EN751221) {\n+\t\t/* PLL frequency: 362.5Mhz */\n+\t\tncpo1 = 0x1d00;\n+\t} else if (priv-\u003eid == ID_MT7621) {\n \t\t/* PLL frequency: 125MHz: 1.0GBit */\n \t\tif (xtal == MT7530_XTAL_40MHZ)\n \t\t\tncpo1 = 0x0640;\n@@ -449,6 +476,251 @@ mt7531_pll_setup(struct mt7530_priv *priv)\n \tusleep_range(25, 35);\n }\n \n+static bool\n+en751221_trgmii_cal_ok(struct mt7530_priv *rx, u32 reg, int chan, int i)\n+{\n+\tu32 val = 0;\n+\n+\tregmap_read(rx-\u003eregmap, reg, \u0026val);\n+\tregmap_write(rx-\u003eregmap, reg, val | EDGE_CHK);\n+\tregmap_write(rx-\u003eregmap, reg, val \u0026 ~EDGE_CHK);\n+\tregmap_read(rx-\u003eregmap, reg, \u0026val);\n+\n+\treturn FIELD_GET(RD_VALUE_MASK, val) == TGMII_TD_PAT \u0026\u0026\n+\t !FIELD_GET(RD_ERR_MASK, val);\n+}\n+\n+static void\n+en751221_trgmii_calibrate_direction(struct mt7530_priv *tx,\n+\t\t\t\t struct mt7530_priv *rx,\n+\t\t\t\t u8 *default_taps)\n+{\n+\tint channel;\n+\n+\tregmap_set_bits(tx-\u003eregmap, MT7530_TRGMII_TXCTRL, TRAIN_TXEN);\n+\n+\t/* Put fail pattern on every channel */\n+\tfor (channel = 0; channel \u003c NUM_TRGMII_CTRL; channel++)\n+\t\tregmap_update_bits(tx-\u003eregmap, EN7530_TRGMII_TD_CTRL(channel),\n+\t\t\t\t TGMII_TD_PAT_MASK,\n+\t\t\t\t FIELD_PREP(TGMII_TD_PAT_MASK,\n+\t\t\t\t\t TGMII_TD_FAIL_PAT));\n+\n+\tfor (channel = 0; channel \u003c NUM_TRGMII_CTRL; channel++) {\n+\t\tu32 rx_reg = MT7530_TRGMII_RD(channel);\n+\t\tint best_tap = -1, best_range = -1;\n+\t\tint first = -1;\n+\t\tu8 dac;\n+\t\tchar log[TD_TAP_MAX + 1];\n+\n+\t\t/* Put test pattern on correct channel */\n+\t\tregmap_update_bits(tx-\u003eregmap, EN7530_TRGMII_TD_CTRL(channel),\n+\t\t\t\t TGMII_TD_PAT_MASK,\n+\t\t\t\t FIELD_PREP(TGMII_TD_PAT_MASK, TGMII_TD_PAT));\n+\n+\t\tfor (dac = 0; dac \u003c TD_TAP_MAX; dac++) {\n+\t\t\t/* Set TAP */\n+\t\t\tregmap_update_bits(rx-\u003eregmap, rx_reg, RD_TAP_MASK,\n+\t\t\t\t\t RD_TAP(dac));\n+\n+\t\t\t/* Check if we can get a good read */\n+\t\t\tif (en751221_trgmii_cal_ok(rx, rx_reg, channel, dac)) {\n+\t\t\t\tlog[dac] = '+';\n+\n+\t\t\t\tif (first \u003c 0)\n+\t\t\t\t\tfirst = dac;\n+\n+\t\t\t\tif ((dac - first) \u003e best_range) {\n+\t\t\t\t\tbest_tap = (first + dac) / 2;\n+\t\t\t\t\tbest_range = dac - first;\n+\t\t\t\t}\n+\t\t\t} else {\n+\t\t\t\tlog[dac] = '.';\n+\t\t\t\tfirst = -1;\n+\t\t\t}\n+\t\t}\n+\n+\t\tlog[TD_TAP_MAX] = '\\0';\n+\n+\t\tif (best_tap \u003e -1) {\n+\t\t\tregmap_update_bits(rx-\u003eregmap, rx_reg, RD_TAP_MASK,\n+\t\t\t\t\t RD_TAP(best_tap));\n+\n+\t\t\tlog[best_tap] = 'X';\n+\n+\t\t\tdev_info(rx-\u003edev,\n+\t\t\t\t \"TRGMII lane %d: %s tap %d old %d\\n\",\n+\t\t\t\t channel, log, best_tap, default_taps[channel]);\n+\t\t} else {\n+\t\t\tregmap_update_bits(rx-\u003eregmap, rx_reg, RD_TAP_MASK,\n+\t\t\t\t\t RD_TAP(default_taps[channel]));\n+\n+\t\t\tdev_warn(rx-\u003edev,\n+\t\t\t\t \"TRGMII lane %d: %s calibration failed, preserving tap %u\\n\",\n+\t\t\t\t channel, log, default_taps[channel]);\n+\t\t}\n+\n+\t\t/* Return channel to failure pattern */\n+\t\tregmap_update_bits(tx-\u003eregmap, EN7530_TRGMII_TD_CTRL(channel),\n+\t\t\t\t TGMII_TD_PAT_MASK,\n+\t\t\t\t FIELD_PREP(TGMII_TD_PAT_MASK,\n+\t\t\t\t\t TGMII_TD_FAIL_PAT));\n+\t}\n+\n+\tregmap_clear_bits(tx-\u003eregmap, MT7530_TRGMII_TXCTRL, TRAIN_TXEN);\n+}\n+\n+static void\n+en751221_set_tx_drive(struct mt7530_priv *priv, u8 drvp, u8 drvn, u8 clk_drvp,\n+\t\t u8 clk_drvn)\n+{\n+\tint channel;\n+\n+\t/* Tx driving for TRGMII path on SoC */\n+\tfor (channel = 0; channel \u003c NUM_TRGMII_CTRL; channel++)\n+\t\tregmap_write(priv-\u003eregmap, MT7530_TRGMII_TD_ODT(channel),\n+\t\t\t TD_DM_DRVP(drvp) | TD_DM_DRVN(drvn));\n+\n+\t/* Undocumented 6th channel, probably drive strength for clock line. */\n+\tregmap_write(priv-\u003eregmap, MT7530_TRGMII_TD_ODT(5), TD_DM_DRVP(drvp) |\n+\t\t TD_DM_DRVN(drvn));\n+}\n+\n+static void\n+en751221_trgmii_pair_setup(struct mt7530_priv *ext, int ext_port,\n+\t\t\t struct mt7530_priv *ondie, int ondie_port)\n+{\n+\tu8 default_taps_ondie[NUM_TRGMII_CTRL];\n+\tu8 default_taps_ext[NUM_TRGMII_CTRL];\n+\tu32 mcr_down, mcr_up;\n+\tint channel;\n+\tint reg_val;\n+\n+\t/* BOTH: Put interfaces in a downed state */\n+\tmcr_down = PMCR_IFG_XMIT(PMCR_IFG_XMIT_64) | PMCR_MAC_MODE |\n+\t\t MT7530_FORCE_MODE | PMCR_MAC_RX_EN | PMCR_BACKOFF_EN |\n+\t\t PMCR_BACKPR_EN | PMCR_FORCE_SPEED_1000 | PMCR_FORCE_FDX;\n+\tregmap_write(ondie-\u003eregmap, MT753X_PMCR_P(ondie_port), mcr_down);\n+\tregmap_write(ext-\u003eregmap, MT753X_PMCR_P(ext_port), mcr_down);\n+\tusleep_range(5000, 6000);\n+\n+\t/* BOTH: Reset TX */\n+\tregmap_set_bits(ext-\u003eregmap, MT7530_TRGMII_TXCTRL, TX_RST);\n+\tregmap_set_bits(ondie-\u003eregmap, MT7530_TRGMII_TXCTRL, TX_RST);\n+\tusleep_range(5000, 6000);\n+\tregmap_clear_bits(ext-\u003eregmap, MT7530_TRGMII_TXCTRL, TX_RST);\n+\tregmap_clear_bits(ondie-\u003eregmap, MT7530_TRGMII_TXCTRL, TX_RST);\n+\n+\t/* BOTH: Reset RX controllers down */\n+\tregmap_set_bits(ext-\u003eregmap, MT7530_TRGMII_RCK_CTRL, RX_RST);\n+\tregmap_set_bits(ondie-\u003eregmap, MT7530_TRGMII_RCK_CTRL, RX_RST);\n+\n+\t/* BOTH: Set TX drive strength, MCM uses more */\n+\ten751221_set_tx_drive(ondie, 8, 8, 7, 7);\n+\ten751221_set_tx_drive(ext, 11, 11, 16, 16);\n+\n+\t/* BOTH: Reset RX controllers up */\n+\tregmap_clear_bits(ext-\u003eregmap, MT7530_TRGMII_RCK_CTRL, RX_RST);\n+\tregmap_clear_bits(ondie-\u003eregmap, MT7530_TRGMII_RCK_CTRL, RX_RST);\n+\n+\t/* BOTH: Ports up */\n+\tmcr_up = mcr_down | PMCR_MAC_TX_EN | PMCR_FORCE_LNK;\n+\tregmap_write(ondie-\u003eregmap, MT753X_PMCR_P(ondie_port), mcr_up);\n+\tregmap_write(ext-\u003eregmap, MT753X_PMCR_P(ext_port), mcr_up);\n+\n+\t/* MCM: Set Ext-\u003eSoC TX delay to 0 */\n+\tfor (channel = 0; channel \u003c NUM_TRGMII_CTRL; channel++)\n+\t\tregmap_clear_bits(ext-\u003eregmap, EN7530_TRGMII_TD_CTRL(channel),\n+\t\t\t\t TGMII_TD_TAP_MASK);\n+\n+\t/* SOC: ODT */\n+\tregmap_set_bits(ondie-\u003eregmap, MT7530_TRGMII_RCK_RTT,\n+\t\t\tDQS1_GATE | DQS0_GATE | EN751221_B17);\n+\n+\t/* SOC: Undocumented */\n+\tfor (channel = 0; channel \u003c NUM_TRGMII_CTRL; channel++)\n+\t\tregmap_write(ondie-\u003eregmap, (0x7a14 + channel * 8),\n+\t\t\t 0x3227700);\n+\n+\t/* MCM: Spread spectrum clock*/\n+\tcore_clear(ext, CORE_PLL_GROUP8, RG_LCDDS_SSC_EN);\n+\n+\t/* BOTH: Zero clock delay */\n+\tregmap_clear_bits(ext-\u003eregmap, MT7530_TRGMII_RCK_CTRL,\n+\t\t\t DQSI0_TAP_MASK);\n+\tregmap_clear_bits(ondie-\u003eregmap, MT7530_TRGMII_RCK_CTRL,\n+\t\t\t DQSI0_TAP_MASK);\n+\n+\t/* BOTH: Collect and then zero every RX TAP */\n+\tfor (channel = 0; channel \u003c NUM_TRGMII_CTRL; channel++) {\n+\t\treg_val = 0;\n+\t\tregmap_read(ext-\u003eregmap, MT7530_TRGMII_RD(channel), \u0026reg_val);\n+\t\tdefault_taps_ext[channel] = FIELD_GET(RD_TAP_MASK, reg_val);\n+\t\tregmap_clear_bits(ext-\u003eregmap, MT7530_TRGMII_RD(channel),\n+\t\t\t\t RD_TAP_MASK);\n+\n+\t\treg_val = 0;\n+\t\tregmap_read(ondie-\u003eregmap, MT7530_TRGMII_RD(channel), \u0026reg_val);\n+\t\tdefault_taps_ondie[channel] = FIELD_GET(RD_TAP_MASK, reg_val);\n+\t\tregmap_clear_bits(ondie-\u003eregmap, MT7530_TRGMII_RD(channel),\n+\t\t\t\t RD_TAP_MASK);\n+\t}\n+\n+\ten751221_trgmii_calibrate_direction(ondie, ext, default_taps_ext);\n+\ten751221_trgmii_calibrate_direction(ext, ondie, default_taps_ext);\n+\n+\tdev_info(ondie-\u003edev, \"TRGMII inter-switch link initialized\\n\");\n+}\n+\n+static void\n+mt7530_cal_interswitch_trgmii(struct dsa_port *dp)\n+{\n+\tstruct dsa_switch *ds = dp-\u003eds;\n+\tstruct dsa_switch *peer_ds;\n+\tstruct dsa_port *peer_dp;\n+\tstruct mt7530_priv *peer;\n+\tstruct mt7530_priv *priv;\n+\tstruct dsa_link *dl;\n+\tu32 pmsr = 0;\n+\n+\tpriv = ds-\u003epriv;\n+\n+\tif (priv-\u003eid != ID_EN751221_EXT)\n+\t\treturn;\n+\n+\tif (dp-\u003etype != DSA_PORT_TYPE_DSA)\n+\t\treturn;\n+\n+\tregmap_read(priv-\u003eregmap, MT7530_PMSR_P(dp-\u003eindex), \u0026pmsr);\n+\n+\tif (!(pmsr \u0026 PMSR_LINK))\n+\t\treturn;\n+\n+\tlist_for_each_entry(dl, \u0026ds-\u003edst-\u003ertable, list) {\n+\t\tif (dl-\u003edp != dp)\n+\t\t\tcontinue;\n+\n+\t\tpeer_dp = dl-\u003elink_dp;\n+\n+\t\tif (peer_dp-\u003etype != DSA_PORT_TYPE_DSA)\n+\t\t\tcontinue;\n+\n+\t\tpeer_ds = dl-\u003elink_dp-\u003eds;\n+\n+\t\tif (!of_device_is_compatible(peer_ds-\u003edev-\u003eof_node,\n+\t\t\t\t\t \"econet,en751221-switch\"))\n+\t\t\tcontinue;\n+\n+\t\tpeer = peer_ds-\u003epriv;\n+\n+\t\tif (peer-\u003eid != ID_EN751221)\n+\t\t\tcontinue;\n+\n+\t\ten751221_trgmii_pair_setup(priv, dp-\u003eindex, peer,\n+\t\t\t\t\t peer_dp-\u003eindex);\n+\t}\n+}\n+\n static void\n mt7530_mib_reset(struct dsa_switch *ds)\n {\n@@ -1281,13 +1553,41 @@ mt753x_trap_frames(struct mt7530_priv *priv)\n \t\t\t\t TO_CPU_FW_CPU_ONLY);\n }\n \n+static int\n+mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu);\n+\n+/* If this switch is downstream of another switch that is in passthrough mode,\n+ * the \"CPU\" port is actually a DSA port.\n+ */\n static void\n mt753x_cpu_port_enable(struct dsa_switch *ds, int port)\n {\n \tstruct mt7530_priv *priv = ds-\u003epriv;\n \n-\t/* Enable Mediatek header mode on the cpu port */\n-\tregmap_write(priv-\u003eregmap, MT7530_PVC_P(port), PORT_SPEC_TAG);\n+\tif (priv-\u003eis_passthrough) {\n+\t\t/* Disable parsing of the DSA tag, it will be forwarded blindly\n+\t\t * to the downstream switch.\n+\t\t */\n+\t\tregmap_write(priv-\u003eregmap, MT7530_PVC_P(port),\n+\t\t\t VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |\n+\t\t\t PVC_EG_TAG(MT7530_VLAN_EG_DISABLED));\n+\n+\t\t/* The port is not configured to parse DSA tags, so they are\n+\t\t * liable to be confused for length fields, so length check is\n+\t\t * disabled.\n+\t\t */\n+\t\tregmap_clear_bits(priv-\u003eregmap, MT753X_AGC, AGC_L2LEN_CHK);\n+\n+\t\t/* In passthrough mode, MTU is only enforced downstream */\n+\t\tmt7530_port_change_mtu(ds, port, MT7530_MAX_MTU);\n+\n+\t\t/* Loop detection has no value in passthrough mode */\n+\t\tregmap_set_bits(priv-\u003eregmap, MT753X_MTRAP,\n+\t\t\t\tMT7530_LOOP_DET_DISABLE);\n+\t} else {\n+\t\t/* Not passthrough, enable DSA tag handling on CPU port. */\n+\t\tregmap_write(priv-\u003eregmap, MT7530_PVC_P(port), PORT_SPEC_TAG);\n+\t}\n \n \t/* Enable flooding on the CPU port */\n \tregmap_set_bits(priv-\u003eregmap, MT753X_MFC,\n@@ -1317,6 +1617,7 @@ static int\n mt7530_port_enable(struct dsa_switch *ds, int port,\n \t\t struct phy_device *phy)\n {\n+\tint upstream_pt = dsa_switch_upstream_port(ds);\n \tstruct dsa_port *dp = dsa_to_port(ds, port);\n \tstruct mt7530_priv *priv = ds-\u003epriv;\n \n@@ -1327,17 +1628,43 @@ mt7530_port_enable(struct dsa_switch *ds, int port,\n \t * bridge.\n \t */\n \tif (dsa_port_is_user(dp)) {\n-\t\tstruct dsa_port *cpu_dp = dp-\u003ecpu_dp;\n+\t\tpriv-\u003eports[port].pm |= PCR_MATRIX(BIT(upstream_pt));\n+\n+\t} else if (dsa_port_is_dsa(dp) \u0026\u0026 dp-\u003eindex != upstream_pt) {\n+\t\tpriv-\u003eports[port].pm |= PCR_MATRIX(BIT(upstream_pt));\n+\n+\t\t/* Should not happen */\n+\t\tWARN_ON_ONCE(!priv-\u003eis_passthrough);\n+\n+\t\t/* We are passing through to a downstream switch so we set both\n+\t\t * CPU and downstream link to pass traffic untouched so that\n+\t\t * the STAG from the downstream switch will pass to the upstream.\n+\t\t */\n+\t\tregmap_write(priv-\u003eregmap, MT7530_PVC_P(port),\n+\t\t\t VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |\n+\t\t\t PVC_EG_TAG(MT7530_VLAN_EG_DISABLED));\n+\n+\t\t/* We let the downstream switch flood */\n+\t\tregmap_set_bits(priv-\u003eregmap, MT753X_MFC, BC_FFP(BIT(port)) |\n+\t\t\t\tUNM_FFP(BIT(port)) | UNU_FFP(BIT(port)));\n \n-\t\tpriv-\u003eports[port].pm |= PCR_MATRIX(BIT(cpu_dp-\u003eindex));\n+\t\t/* Make the upstream port able to connect to the DSA port.\n+\t\t * This must be explicit because PORT_SPEC_TAG is unset.\n+\t\t */\n+\t\tregmap_write(priv-\u003eregmap, MT7530_PCR_P(upstream_pt),\n+\t\t\t PCR_MATRIX(BIT(port)));\n \t}\n \tpriv-\u003eports[port].enable = true;\n-\tregmap_update_bits(priv-\u003eregmap, MT7530_PCR_P(port), PCR_MATRIX_MASK,\n-\t\t\t priv-\u003eports[port].pm);\n+\n+\t/* In passthrough mode, CPU port mask is set above. */\n+\tif (!(priv-\u003eis_passthrough \u0026\u0026 dp-\u003eindex == upstream_pt))\n+\t\tregmap_update_bits(priv-\u003eregmap, MT7530_PCR_P(port),\n+\t\t\t\t PCR_MATRIX_MASK, priv-\u003eports[port].pm);\n \n \tmutex_unlock(\u0026priv-\u003ereg_mutex);\n \n-\tif (priv-\u003eid != ID_MT7530 \u0026\u0026 priv-\u003eid != ID_MT7621)\n+\tif (priv-\u003eid != ID_MT7530 \u0026\u0026 priv-\u003eid != ID_MT7621 \u0026\u0026\n+\t priv-\u003eid != ID_EN751221 \u0026\u0026 priv-\u003eid != ID_EN751221_EXT)\n \t\treturn 0;\n \n \tif (port == 5)\n@@ -1364,7 +1691,8 @@ mt7530_port_disable(struct dsa_switch *ds, int port)\n \n \tmutex_unlock(\u0026priv-\u003ereg_mutex);\n \n-\tif (priv-\u003eid != ID_MT7530 \u0026\u0026 priv-\u003eid != ID_MT7621)\n+\tif (priv-\u003eid != ID_MT7530 \u0026\u0026 priv-\u003eid != ID_MT7621 \u0026\u0026\n+\t priv-\u003eid != ID_EN751221 \u0026\u0026 priv-\u003eid != ID_EN751221_EXT)\n \t\treturn;\n \n \t/* Do not set MT7530_P5_DIS when port 5 is being used for PHY muxing. */\n@@ -1385,7 +1713,7 @@ mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)\n \t * largest MTU of the user ports. Because the switch only has a global\n \t * RX length register, only allowing CPU port here is enough.\n \t */\n-\tif (!dsa_is_cpu_port(ds, port))\n+\tif (!dsa_is_upstream_port(ds, port))\n \t\treturn 0;\n \n \tregmap_read(priv-\u003eregmap, MT7530_GMACCR, \u0026val);\n@@ -2333,7 +2661,7 @@ mt7530_free_mdio_irq(struct mt7530_priv *priv)\n \t}\n }\n \n-static int\n+int\n mt7530_setup_mdio(struct mt7530_priv *priv)\n {\n \tstruct device_node *mnp, *np = priv-\u003edev-\u003eof_node;\n@@ -2343,6 +2671,10 @@ mt7530_setup_mdio(struct mt7530_priv *priv)\n \tstatic int idx;\n \tint ret = 0;\n \n+\t/* Already done */\n+\tif (priv-\u003echild_bus)\n+\t\treturn 0;\n+\n \tmnp = of_get_child_by_name(np, \"mdio\");\n \n \tif (mnp \u0026\u0026 !of_device_is_available(mnp))\n@@ -2370,8 +2702,11 @@ mt7530_setup_mdio(struct mt7530_priv *priv)\n \tif (priv-\u003eirq_domain \u0026\u0026 !mnp)\n \t\tmt7530_setup_mdio_irq(priv);\n \n+\tpriv-\u003echild_bus = bus;\n+\n \tret = devm_of_mdiobus_register(dev, bus, mnp);\n \tif (ret) {\n+\t\tpriv-\u003echild_bus = NULL;\n \t\tdev_err(dev, \"failed to register MDIO bus: %d\\n\", ret);\n \t\tif (priv-\u003eirq_domain \u0026\u0026 !mnp)\n \t\t\tmt7530_free_mdio_irq(priv);\n@@ -2381,6 +2716,7 @@ mt7530_setup_mdio(struct mt7530_priv *priv)\n \tof_node_put(mnp);\n \treturn ret;\n }\n+EXPORT_SYMBOL_GPL(mt7530_setup_mdio);\n \n static int\n mt7530_setup(struct dsa_switch *ds)\n@@ -2406,11 +2742,6 @@ mt7530_setup(struct dsa_switch *ds)\n \t\tbreak;\n \t}\n \n-\tif (!dn) {\n-\t\tdev_err(ds-\u003edev, \"parent OF node of DSA conduit not found\");\n-\t\treturn -EINVAL;\n-\t}\n-\n \tds-\u003eassisted_learning_on_cpu_port = true;\n \tds-\u003euntag_vlan_aware_bridge_pvid = true;\n \tds-\u003emtu_enforcement_ingress = true;\n@@ -2489,6 +2820,12 @@ mt7530_setup(struct dsa_switch *ds)\n \t\t\t MT7530_CHG_TRAP | MT7530_PHY_INDIRECT_ACCESS,\n \t\t\t MT7530_CHG_TRAP);\n \n+\t/* EN751221 MCM starts on the wrong frequency */\n+\tif (priv-\u003eid == ID_EN751221_EXT)\n+\t\tregmap_update_bits(priv-\u003eregmap, MT753X_MTRAP,\n+\t\t\t\t MT7530_CHG_TRAP | MT7530_CK_SEL,\n+\t\t\t\t MT7530_CHG_TRAP);\n+\n \tif ((val \u0026 MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ)\n \t\tmt7530_pll_setup(priv);\n \n@@ -2512,7 +2849,7 @@ mt7530_setup(struct dsa_switch *ds)\n \t\t/* Disable learning by default on all ports */\n \t\tregmap_set_bits(priv-\u003eregmap, MT7530_PSC_P(i), SA_DIS);\n \n-\t\tif (dsa_is_cpu_port(ds, i)) {\n+\t\tif (dsa_is_upstream_port(ds, i)) {\n \t\t\tmt753x_cpu_port_enable(ds, i);\n \t\t} else {\n \t\t\tmt7530_port_disable(ds, i);\n@@ -2536,7 +2873,7 @@ mt7530_setup(struct dsa_switch *ds)\n \t\treturn ret;\n \n \t/* Check for PHY muxing on port 5 */\n-\tif (dsa_is_unused_port(ds, 5)) {\n+\tif (dn \u0026\u0026 dsa_is_unused_port(ds, 5)) {\n \t\t/* Scan the ethernet nodes. Look for GMAC1, lookup the used PHY.\n \t\t * Set priv-\u003ep5_mode to the appropriate value if PHY muxing is\n \t\t * detected.\n@@ -2636,7 +2973,7 @@ mt7531_setup_common(struct dsa_switch *ds)\n \t\tregmap_set_bits(priv-\u003eregmap, MT7531_DBG_CNT(i),\n \t\t\t\tMT7531_DIS_CLR);\n \n-\t\tif (dsa_is_cpu_port(ds, i)) {\n+\t\tif (dsa_is_upstream_port(ds, i)) {\n \t\t\tmt753x_cpu_port_enable(ds, i);\n \t\t} else {\n \t\t\tmt7530_port_disable(ds, i);\n@@ -2674,8 +3011,11 @@ mt7531_setup(struct dsa_switch *ds)\n {\n \tstruct mt7530_priv *priv = ds-\u003epriv;\n \tu32 val, id;\n+\tint ctl_phy;\n \tint ret, i;\n \n+\tctl_phy = mt753x_ctrl_phy_addr(priv);\n+\n \t/* Reset whole chip through gpio pin or memory-mapped registers for\n \t * different type of hardware\n \t */\n@@ -2743,25 +3083,21 @@ mt7531_setup(struct dsa_switch *ds)\n \t * phy_[read,write]_mmd_indirect is called, we provide our own\n \t * mt7531_ind_mmd_phy_[read,write] to complete this function.\n \t */\n-\tret = mt7531_ind_c45_phy_read(priv,\n-\t\t\t\t MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr),\n-\t\t\t\t MDIO_MMD_VEND2, CORE_PLL_GROUP4);\n+\tret = mt7531_ind_c45_phy_read(priv, ctl_phy, MDIO_MMD_VEND2,\n+\t\t\t\t CORE_PLL_GROUP4);\n \tif (ret \u003c 0)\n \t\treturn ret;\n \n \tval = ret;\n \tval |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;\n \tval \u0026= ~MT7531_PHY_PLL_OFF;\n-\tret = mt7531_ind_c45_phy_write(priv,\n-\t\t\t\t MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr),\n-\t\t\t\t MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);\n+\tret = mt7531_ind_c45_phy_write(priv, ctl_phy, MDIO_MMD_VEND2,\n+\t\t\t\t CORE_PLL_GROUP4, val);\n \tif (ret \u003c 0)\n \t\treturn ret;\n \n \t/* Disable EEE advertisement on the switch PHYs. */\n-\tfor (i = MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr);\n-\t i \u003c MT753X_CTRL_PHY_ADDR(priv-\u003emdiodev-\u003eaddr) + MT7530_NUM_PHYS;\n-\t i++) {\n+\tfor (i = ctl_phy; i \u003c ctl_phy + MT7530_NUM_PHYS; i++) {\n \t\tmt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV,\n \t\t\t\t\t 0);\n \t}\n@@ -2910,6 +3246,44 @@ static void en7528_mac_port_get_caps(struct dsa_switch *ds, int port,\n \t}\n }\n \n+static void en751221_mac_port_get_caps(struct dsa_switch *ds, int port,\n+\t\t\t\t struct phylink_config *config)\n+{\n+\tswitch (port) {\n+\t/* EN751221 ports 0..3 are connected to the integrated FE PHYs. */\n+\tcase 0 ... 3:\n+\t\t__set_bit(PHY_INTERFACE_MODE_INTERNAL,\n+\t\t\t config-\u003esupported_interfaces);\n+\n+\t\tconfig-\u003emac_capabilities |= MAC_10 | MAC_100;\n+\t\tbreak;\n+\n+\t/* Port 4 is connected to the standalone EN7512/EN7521 GPHY. */\n+\tcase 4:\n+\t\t__set_bit(PHY_INTERFACE_MODE_INTERNAL,\n+\t\t\t config-\u003esupported_interfaces);\n+\n+\t\tconfig-\u003emac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD;\n+\t\tbreak;\n+\n+\t/* Port 5 is the 1 Gbit/s TRGMII cascade to the external MT7530. */\n+\tcase 5:\n+\t\t__set_bit(PHY_INTERFACE_MODE_TRGMII,\n+\t\t\t config-\u003esupported_interfaces);\n+\n+\t\tconfig-\u003emac_capabilities |= MAC_1000FD;\n+\t\tbreak;\n+\n+\t/* Port 6 is the 1 Gbit/s CPU link to GDM1. */\n+\tcase 6:\n+\t\t__set_bit(PHY_INTERFACE_MODE_INTERNAL,\n+\t\t\t config-\u003esupported_interfaces);\n+\n+\t\tconfig-\u003emac_capabilities |= MAC_1000FD;\n+\t\tbreak;\n+\t}\n+}\n+\n static void\n mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,\n \t\t phy_interface_t interface)\n@@ -3059,6 +3433,9 @@ static void mt753x_phylink_mac_link_up(struct phylink_config *config,\n \t}\n \n \tregmap_set_bits(priv-\u003eregmap, MT753X_PMCR_P(dp-\u003eindex), mcr);\n+\n+\tif (interface == PHY_INTERFACE_MODE_TRGMII)\n+\t\tmt7530_cal_interswitch_trgmii(dp);\n }\n \n static void mt753x_phylink_mac_disable_tx_lpi(struct phylink_config *config)\n@@ -3298,10 +3675,11 @@ mt753x_conduit_state_change(struct dsa_switch *ds,\n \n \t/* Set the CPU port to trap frames to for MT7530. Trapped frames will be\n \t * forwarded to the numerically smallest CPU port whose conduit\n-\t * interface is up.\n+\t * interface is up. NOTE: \"CPU port\" can also mean an upstream DSA link.\n \t */\n \tif (priv-\u003eid != ID_MT7530 \u0026\u0026 priv-\u003eid != ID_MT7621 \u0026\u0026\n-\t priv-\u003eid != ID_EN7528)\n+\t priv-\u003eid != ID_EN7528 \u0026\u0026 priv-\u003eid != ID_EN751221 \u0026\u0026\n+\t priv-\u003eid != ID_EN751221_EXT)\n \t\treturn;\n \n \tmask = BIT(cpu_dp-\u003eindex);\n@@ -3393,6 +3771,76 @@ static int mt7988_setup(struct dsa_switch *ds)\n \treturn mt7531_setup_common(ds);\n }\n \n+/* 1 if passthrough, negative if error. */\n+static int mt753x_check_passthrough(struct device *dev)\n+{\n+\tstruct device_node *ports, *port;\n+\tint passthrough_ports = 0;\n+\tint enabled_ports = 0;\n+\n+\tports = of_get_child_by_name(dev-\u003eof_node, \"ports\");\n+\tif (!ports)\n+\t\tports = of_get_child_by_name(dev-\u003eof_node, \"ethernet-ports\");\n+\n+\tif (!ports) {\n+\t\tdev_err(dev, \"no ports child node found\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tfor_each_available_child_of_node(ports, port) {\n+\t\tstruct device_node *link;\n+\n+\t\tenabled_ports++;\n+\n+\t\tlink = of_parse_phandle(port, \"ethernet\", 0);\n+\t\tif (!link)\n+\t\t\tlink = of_parse_phandle(port, \"link\", 0);\n+\n+\t\tif (!link)\n+\t\t\tcontinue;\n+\n+\t\tof_node_put(link);\n+\n+\t\tpassthrough_ports++;\n+\t}\n+\n+\tof_node_put(ports);\n+\n+\t/*\n+\t * A switch is considered passthrough if exactly two available\n+\t * ports have an \"ethernet\" or \"link\" phandle.\n+\t */\n+\tif (passthrough_ports \u003e 2 ||\n+\t (passthrough_ports == 2 \u0026\u0026 enabled_ports != 2)\n+\t) {\n+\t\tdev_err(dev, \"Only two ports allowed in passthrough mode\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn passthrough_ports == 2;\n+}\n+\n+/* No manipulation of forwarding rules allowed in passthrough mode */\n+static const struct dsa_switch_ops mt7530_passthrough_switch_ops = {\n+\t.get_tag_protocol\t= mtk_get_tag_protocol,\n+\t.setup\t\t\t= mt753x_setup,\n+\t.teardown\t\t= mt753x_teardown,\n+\t.preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port,\n+\t.get_strings\t\t= mt7530_get_strings,\n+\t.get_ethtool_stats\t= mt7530_get_ethtool_stats,\n+\t.get_sset_count\t\t= mt7530_get_sset_count,\n+\t.get_eth_mac_stats\t= mt7530_get_eth_mac_stats,\n+\t.get_rmon_stats\t\t= mt7530_get_rmon_stats,\n+\t.get_eth_ctrl_stats\t= mt7530_get_eth_ctrl_stats,\n+\t.get_stats64\t\t= mt7530_get_stats64,\n+\t.port_enable\t\t= mt7530_port_enable,\n+\t.port_disable\t\t= mt7530_port_disable,\n+\t.phylink_get_caps\t= mt753x_phylink_get_caps,\n+\t.support_eee\t\t= dsa_supports_eee,\n+\t.set_mac_eee\t\t= mt753x_set_mac_eee,\n+\t.conduit_state_change\t= mt753x_conduit_state_change,\n+};\n+\n static const struct dsa_switch_ops mt7530_switch_ops = {\n \t.get_tag_protocol\t= mtk_get_tag_protocol,\n \t.setup\t\t\t= mt753x_setup,\n@@ -3519,14 +3967,40 @@ const struct mt753x_info mt753x_table[] = {\n \t\t.phy_write_c45 = mt7531_ind_c45_phy_write,\n \t\t.mac_port_get_caps = en7528_mac_port_get_caps,\n \t},\n+\t[ID_EN751221] = {\n+\t\t.id = ID_EN751221,\n+\t\t.pcs_ops = \u0026mt7530_pcs_ops,\n+\t\t.sw_setup = mt7988_setup,\n+\t\t.phy_read_c22 = mt7531_ind_c22_phy_read,\n+\t\t.phy_write_c22 = mt7531_ind_c22_phy_write,\n+\t\t.phy_read_c45 = mt7531_ind_c45_phy_read,\n+\t\t.phy_write_c45 = mt7531_ind_c45_phy_write,\n+\t\t.mac_port_get_caps = en751221_mac_port_get_caps,\n+\t\t.mac_port_config = mt7530_mac_config,\n+\t},\n+\t[ID_EN751221_EXT] = {\n+\t\t.id = ID_EN751221_EXT,\n+\t\t.pcs_ops = \u0026mt7530_pcs_ops,\n+\t\t.sw_setup = mt7530_setup,\n+\t\t.phy_read_c22 = mt7530_phy_read_c22,\n+\t\t.phy_write_c22 = mt7530_phy_write_c22,\n+\t\t.phy_read_c45 = mt7530_phy_read_c45,\n+\t\t.phy_write_c45 = mt7530_phy_write_c45,\n+\t\t.mac_port_get_caps = mt7530_mac_port_get_caps,\n+\t\t.mac_port_config = mt7530_mac_config,\n+\t},\n };\n EXPORT_SYMBOL_GPL(mt753x_table);\n \n int\n mt7530_probe_common(struct mt7530_priv *priv)\n {\n+\tint passthrough = mt753x_check_passthrough(priv-\u003edev);\n \tstruct device *dev = priv-\u003edev;\n \n+\tif (passthrough \u003c 0)\n+\t\treturn passthrough;\n+\n \tpriv-\u003eds = devm_kzalloc(dev, sizeof(*priv-\u003eds), GFP_KERNEL);\n \tif (!priv-\u003eds)\n \t\treturn -ENOMEM;\n@@ -3544,7 +4018,14 @@ mt7530_probe_common(struct mt7530_priv *priv)\n \tpriv-\u003eid = priv-\u003einfo-\u003eid;\n \tpriv-\u003edev = dev;\n \tpriv-\u003eds-\u003epriv = priv;\n-\tpriv-\u003eds-\u003eops = \u0026mt7530_switch_ops;\n+\n+\tif (passthrough) {\n+\t\tpriv-\u003eds-\u003eops = \u0026mt7530_passthrough_switch_ops;\n+\t\tpriv-\u003eis_passthrough = true;\n+\t} else {\n+\t\tpriv-\u003eds-\u003eops = \u0026mt7530_switch_ops;\n+\t}\n+\n \tpriv-\u003eds-\u003ephylink_mac_ops = \u0026mt753x_phylink_mac_ops;\n \tmutex_init(\u0026priv-\u003ereg_mutex);\n \tspin_lock_init(\u0026priv-\u003estats_lock);\ndiff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h\nindex 2bbbe617b52ee..1a4329749c0f1 100644\n--- a/drivers/net/dsa/mt7530.h\n+++ b/drivers/net/dsa/mt7530.h\n@@ -24,6 +24,8 @@ enum mt753x_id {\n \tID_EN7581 = 4,\n \tID_AN7583 = 5,\n \tID_EN7528 = 6,\n+\tID_EN751221 = 7,\n+\tID_EN751221_EXT = 8,\n };\n \n #define\tNUM_TRGMII_CTRL\t\t\t5\n@@ -40,6 +42,7 @@ enum mt753x_id {\n /* Register for ARL global control */\n #define MT753X_AGC\t\t\t0xc\n #define LOCAL_EN\t\t\tBIT(7)\n+#define AGC_L2LEN_CHK\t\t\tBIT(4)\n \n /* Register for MAC forward control */\n #define MT753X_MFC\t\t\t0x10\n@@ -355,6 +358,9 @@ enum mt7530_vlan_port_acc_frm {\n #define MT753X_PMCR_P(x)\t\t(0x3000 + ((x) * 0x100))\n #define PMCR_IFG_XMIT_MASK\t\tGENMASK(19, 18)\n #define PMCR_IFG_XMIT(x)\t\tFIELD_PREP(PMCR_IFG_XMIT_MASK, x)\n+#define PMCR_IFG_XMIT_96\t\t0\n+#define PMCR_IFG_XMIT_RAND\t\t1\n+#define PMCR_IFG_XMIT_64\t\t2\n #define PMCR_EXT_PHY\t\t\tBIT(17)\n #define PMCR_MAC_MODE\t\t\tBIT(16)\n #define MT7530_FORCE_MODE\t\tBIT(15)\n@@ -583,6 +589,8 @@ enum mt7531_clk_skew {\n #define MT753X_MTRAP\t\t\t0x7804\n #define MT7530_P5_PHY0_SEL\t\tBIT(20)\n #define MT7530_CHG_TRAP\t\tBIT(16)\n+#define MT7530_CK_SEL\t\t\tBIT(15)\n+#define MT7530_LOOP_DET_DISABLE\tBIT(14)\n #define MT7530_P5_MAC_SEL\t\tBIT(13)\n #define MT7530_P6_DIS\t\t\tBIT(8)\n #define MT7530_P5_RGMII_MODE\t\tBIT(7)\n@@ -599,6 +607,8 @@ enum mt7531_xtal_fsel {\n /* Register for TOP signal control */\n #define MT7530_TOP_SIG_CTRL\t\t0x7808\n #define TOP_SIG_CTRL_NORMAL\t\t(BIT(17) | BIT(16))\n+/* Undocumented */\n+#define TOP_SIG_CTRL_B0\t\tBIT(0)\n \n #define MT7531_TOP_SIG_SR\t\t0x780c\n #define PAD_DUAL_SGMII_EN\t\tBIT(1)\n@@ -645,18 +655,31 @@ enum mt7531_xtal_fsel {\n #define MT7530_TRGMII_RCK_RTT\t\t0x7a04\n #define DQS1_GATE\t\t\tBIT(31)\n #define DQS0_GATE\t\t\tBIT(30)\n+/* Undocumented */\n+#define EN751221_B17\t\t\tBIT(17)\n \n #define MT7530_TRGMII_RD(x)\t\t(0x7a10 + (x) * 8)\n #define BSLIP_EN\t\t\tBIT(31)\n #define EDGE_CHK\t\t\tBIT(30)\n+#define RD_VALUE_MASK\t\t\tGENMASK(23, 16)\n+#define RD_ERR_MASK\t\t\tGENMASK(11, 8)\n #define RD_TAP_MASK\t\t\tGENMASK(6, 0)\n #define RD_TAP(x)\t\t\tFIELD_PREP(RD_TAP_MASK, x)\n+/* Training does not try anything beyond this */\n+#define TD_TAP_MAX\t\t\t64\n \n #define MT7530_TRGMII_TXCTRL\t\t0x7a40\n #define TRAIN_TXEN\t\t\tBIT(31)\n #define TXC_INV\t\t\tBIT(30)\n #define TX_RST\t\t\t\tBIT(28)\n \n+#define EN7530_TRGMII_TD_CTRL(x)\t(0x7a50 + (x) * 8)\n+#define TGMII_TD_TAP_MASK\t\tGENMASK(11, 8)\n+#define TGMII_TD_PAT_MASK\t\tGENMASK(7, 0)\n+/* Use a 01010101 bit pattern */\n+#define TGMII_TD_PAT\t\t\t0x55\n+#define TGMII_TD_FAIL_PAT\t\t0xaa\n+\n #define MT7530_TRGMII_TD_ODT(i)\t\t(0x7a54 + 8 * (i))\n #define TD_DM_DRVP_MASK\t\tGENMASK(3, 0)\n #define TD_DM_DRVP(x)\t\t\tFIELD_PREP(TD_DM_DRVP_MASK, x)\n@@ -747,8 +770,6 @@ enum mt7531_xtal_fsel {\n #define MT7531_PHY_PLL_OFF\t\tBIT(5)\n #define MT7531_PHY_PLL_BYPASS_MODE\tBIT(4)\n \n-#define MT753X_CTRL_PHY_ADDR(addr)\t(((addr) + 1) \u0026 (PHY_MAX_ADDR - 1))\n-\n #define CORE_PLL_GROUP5\t\t\t0x404\n #define RG_LCDDS_PCW_NCPO1_MASK\tGENMASK(15, 0)\n #define RG_LCDDS_PCW_NCPO1(x)\t\tFIELD_PREP(RG_LCDDS_PCW_NCPO1_MASK, x)\n@@ -764,6 +785,9 @@ enum mt7531_xtal_fsel {\n #define RG_LCCDS_C(x)\t\t\tFIELD_PREP(RG_LCCDS_C_MASK, x)\n #define RG_LCDDS_PCW_NCPO_CHG\t\tBIT(3)\n \n+#define CORE_PLL_GROUP8\t\t\t0x407\n+#define RG_LCDDS_SSC_EN\t\tBIT(10)\n+\n #define CORE_PLL_GROUP10\t\t0x409\n #define RG_LCDDS_SSC_DELTA_MASK\tGENMASK(11, 0)\n #define RG_LCDDS_SSC_DELTA(x)\t\tFIELD_PREP(RG_LCDDS_SSC_DELTA_MASK, x)\n@@ -886,6 +910,9 @@ struct mt753x_info {\n * @dev:\t\tThe device pointer\n * @ds:\t\t\tThe pointer to the dsa core structure\n * @bus:\t\tThe bus used for the device and built-in PHY\n+ * @child_bus:\t\tThe bus created by the device, on MDIO implementations\n+ *\t\t\tthis is bus indirectly accesses `bus`, on MMIO\n+ *\t\t\timplementations this bus is part of the switch.\n * @regmap:\t\tThe regmap instance representing all switch registers\n * @rstc:\t\tThe pointer to reset control used by MCM\n * @core_pwr:\t\tThe power supplied into the core\n@@ -899,6 +926,9 @@ struct mt753x_info {\n * @p5_mode:\t\tHolding the current mode of port 5 of the MT7530 switch\n * @p5_sgmii:\t\tFlag for distinguishing if port 5 of the MT7531 switch\n *\t\t\thas got SGMII\n+ * @is_passthrough:\tIf this switch is to pass traffic between the upstream\n+ *\t\t\t(CPU) port and a second downstream switch, without\n+ *\t\t\taltering the DSA tag.\n * @irq_domain:\t\tIRQ domain of the switch irq_chip\n * @create_sgmii:\tPointer to function creating SGMII PCS instance(s)\n * @active_cpu_ports:\tHolding the active CPU ports\n@@ -911,6 +941,7 @@ struct mt7530_priv {\n \tstruct device\t\t*dev;\n \tstruct dsa_switch\t*ds;\n \tstruct mii_bus\t\t*bus;\n+\tstruct mii_bus\t\t*child_bus;\n \tstruct regmap\t\t*regmap;\n \tstruct reset_control\t*rstc;\n \tstruct regulator\t*core_pwr;\n@@ -923,6 +954,7 @@ struct mt7530_priv {\n \tbool\t\t\tp5_sgmii;\n \tu8\t\t\tmirror_rx;\n \tu8\t\t\tmirror_tx;\n+\tbool\t\t\tis_passthrough;\n \tstruct mt7530_port\tports[MT7530_NUM_PORTS];\n \tstruct mt753x_pcs\tpcs[MT7530_NUM_PORTS];\n \t/* protect among processes for registers access*/\n@@ -961,6 +993,16 @@ struct mt7530_hw_stats {\n int mt7530_probe_common(struct mt7530_priv *priv);\n void mt7530_remove_common(struct mt7530_priv *priv);\n \n+/*\n+ * When an MMIO based switch has an MDIO bus which contains a downstream MDIO\n+ * switch, the MDIO bus is not normally setup until mt753x_setup() has been\n+ * called. But mt753x_setup() is not called until DSA sees that every switch in\n+ * the tree has been probed. Calling mt7530_setup_mdio() after at the end of\n+ * the MMIO probe function allows the downstream switch to register, completing\n+ * the tree.\n+ */\n+int mt7530_setup_mdio(struct mt7530_priv *priv);\n+\n extern const struct mt753x_info mt753x_table[];\n \n #endif /* __MT7530_H */\n"
} |
| 2/1 | 2026/09/09 16:04 | agent | patch-evaluator |
0mModel:core Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch series updates Device Tree bindings documentation and adds support for EcoNet EN751221 SoCs and passthrough mode to the MediaTek MT7530 DSA Ethernet switch driver (drivers/net/dsa/mt7530*). This driver controls specific physical MediaTek/EcoNet SoC ethernet switches and MDIO/MMIO devices that cannot be instantiated or emulated in standard QEMU/GCE virtualized environments on the target architecture (amd64). Because the modified hardware-specific code paths are structurally unreachable, fuzzing is not warranted.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.
IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.
================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.
- REACHABILITY IS THE PRIMARY GATE:
Fuzzing can only discover bugs in code that can actually execute in standard virtualized
environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
regardless of whether it adds assertions or complex logic.
- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
Patch authors routinely label changes as "cleanups", "refactorings", or state
"No functional change intended". Do NOT take these claims at face value.
Code refactorings that rearrange logic, introduce helper functions, or alter state management
in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
If reachable executable code is modified or refactored, it MUST be fuzzed.
- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
Even if the author believes the invariant always holds, fuzzing is essential to verify whether
an unusual sequence of operations can violate it.
================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:
- Non-kernel and non-executable changes:
* Modifications to Documentation/, comments, or spelling fixes.
* User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
that do not affect the compiled kernel image (vmlinux) or kernel modules.
* Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
that do not alter control flow or data structures.
* Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
* Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
* Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
physical PCI hot-unplug or manual sysfs driver unbinding.
* Code paths exclusive to architectures other than the target architecture.
================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
* Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
* Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
* Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
* Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).
================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:
- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
Do NOT list generic, ubiquitous functions called by almost every program in the corpus
(including, but not limited to: general memory allocators and deallocators, page fault
and trap handlers, or core synchronization primitives; this is not an exhaustive list).
Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
which severely dilutes fuzzing effort away from the actual changes.
- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
List functions that specifically implement the logic being added or altered, or direct API entrypoints
for the subsystem feature under review.
- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).
================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any '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: Target architecture: amd64
For your convenience, here is the diff of the changes:
commit 38a726e966add9c303f38ccfb191675e814026e6
Author: syz-cluster <triage@syzkaller.com>
Date: Wed Sep 9 16:04:42 2026 +0000
syz-cluster: applied patch under review
diff --git a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml
index 90b3582b76190..106c4087528d7 100644
--- a/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml
+++ b/Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml
@@ -29,6 +29,12 @@ description: |
and the switch registers are directly mapped into SoC's memory map rather than
using MDIO. The DSA driver currently doesn't support MT7620 variants.
+ EcoNet EN751221 SoCs have a memory mapped MT7530 with 3x 10/100 PHYs and 1x
+ gigabit PHY. Some EN751221 chips such as EN7513G and EN7526G have a multi-chip
+ module implementation of the MT7530 as well as the on-die switch. In these
+ packages, the multi-chip module is connected to port 5 of the on-die switch
+ via a TRGMII link.
+
There is only the standalone version of MT7531.
Port 5 on MT7530 supports various configurations:
@@ -73,6 +79,13 @@ description: |
Check out example 7.
+ The MT7530 and MT7531 switches are capable of being operated in "passthrough"
+ mode. In this mode, traffic is unconditionally passed between the CPU port
+ and the DSA port which links to a second switch. To use passthrough mode, the
+ upstream switch is configured with a DSA link to the downstream switch. In
+ passthrough mode the upstream switch is restricted, with no other ports or
+ switch configuration allowed.
+
properties:
compatible:
oneOf:
@@ -104,6 +117,14 @@ properties:
Built-in switch of the EcoNet EN7528 SoC
const: econet,en7528-switch
+ - description:
+ Built-in switch of EcoNet EN751221 SoC
+ const: econet,en751221-switch
+
+ - description:
+ Multi-chip module MT7530 in EN751221 SoC
+ const: econet,en751221
+
reg:
maxItems: 1
@@ -153,8 +174,8 @@ properties:
mediatek,mcm:
type: boolean
description:
- Used for MT7621AT, MT7621DAT, MT7621ST and MT7623AI SoCs which the MT7530
- switch is a part of the multi-chip module.
+ Used for MT7621AT, MT7621DAT, MT7621ST, MT7623AI and EN751221 SoCs which
+ the MT7530 switch is a part of the multi-chip module.
reset-gpios:
description: |
@@ -216,6 +237,20 @@ $defs:
phy-mode:
const: internal
+ mt7530-passthrough-dsa-port:
+ patternProperties:
+ "^(ethernet-)?ports$":
+ patternProperties:
+ "^(ethernet-)?port@[0-6]$":
+ if:
+ required: [ link ]
+ then:
+ properties:
+ reg:
+ const: 6
+ phy-mode:
+ const: trgmii
+
mt7530-dsa-port:
patternProperties:
"^(ethernet-)?ports$":
@@ -323,6 +358,7 @@ allOf:
- airoha,en7581-switch
- airoha,an7583-switch
- econet,en7528-switch
+ - econet,en751221-switch
then:
$ref: "#/$defs/builtin-dsa-port"
properties:
@@ -330,6 +366,16 @@ allOf:
mediatek,mcm: false
reset-names: false
+ - if:
+ properties:
+ compatible:
+ enum:
+ - econet,en751221
+ then:
+ $ref: "#/$defs/mt7530-passthrough-dsa-port"
+ required:
+ - mediatek,mcm
+
unevaluatedProperties: false
examples:
diff --git a/drivers/net/dsa/mt7530-mdio.c b/drivers/net/dsa/mt7530-mdio.c
index 24ef54f3db2a6..2fd987ff85107 100644
--- a/drivers/net/dsa/mt7530-mdio.c
+++ b/drivers/net/dsa/mt7530-mdio.c
@@ -139,6 +139,7 @@ mt7531_create_sgmii(struct mt7530_priv *priv)
}
static const struct of_device_id mt7530_of_match[] = {
+ { .compatible = "econet,en751221", .data = &mt753x_table[ID_EN751221_EXT], },
{ .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
{ .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
{ .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
diff --git a/drivers/net/dsa/mt7530-mmio.c b/drivers/net/dsa/mt7530-mmio.c
index cf3bdb23a2d54..1a29b1eefb2c0 100644
--- a/drivers/net/dsa/mt7530-mmio.c
+++ b/drivers/net/dsa/mt7530-mmio.c
@@ -12,6 +12,7 @@
static const struct of_device_id mt7988_of_match[] = {
{ .compatible = "airoha,an7583-switch", .data = &mt753x_table[ID_AN7583], },
{ .compatible = "airoha,en7581-switch", .data = &mt753x_table[ID_EN7581], },
+ { .compatible = "econet,en751221-switch", .data = &mt753x_table[ID_EN751221], },
{ .compatible = "econet,en7528-switch", .data = &mt753x_table[ID_EN7528], },
{ .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], },
{ /* sentinel */ }
@@ -61,7 +62,12 @@ mt7988_probe(struct platform_device *pdev)
if (IS_ERR(priv->regmap))
return PTR_ERR(priv->regmap);
- return dsa_register_switch(priv->ds);
+ ret = dsa_register_switch(priv->ds);
+
+ if (ret)
+ return ret;
+
+ return mt7530_setup_mdio(priv);
}
static void mt7988_remove(struct platform_device *pdev)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 28f94cd25b955..6fd4719aab89b 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -46,6 +46,19 @@ static const struct mt7530_mib_desc mt7530_mib[] = {
MIB_DESC(1, MT7530_PORT_MIB_RX_ARL_DROP, "RxArlDrop"),
};
+static int
+mt753x_ctrl_phy_addr(struct mt7530_priv *priv)
+{
+ if (priv->id == ID_EN751221)
+ return 12;
+
+ if (WARN_ON_ONCE(!priv->mdiodev))
+ return 0;
+
+ /* Default is 1st PHY */
+ return (priv->mdiodev->addr + 1) & (PHY_MAX_ADDR - 1);
+}
+
static void
mt7530_mutex_lock(struct mt7530_priv *priv)
{
@@ -63,32 +76,36 @@ mt7530_mutex_unlock(struct mt7530_priv *priv)
static void
core_write(struct mt7530_priv *priv, u32 reg, u32 val)
{
+ int ctl_phy = mt753x_ctrl_phy_addr(priv);
struct mii_bus *bus = priv->bus;
int ret;
+ if (!bus)
+ bus = priv->child_bus;
+
+ if (WARN_ON_ONCE(!bus))
+ return;
+
mt7530_mutex_lock(priv);
/* Write the desired MMD Devad */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
- MII_MMD_CTRL, MDIO_MMD_VEND2);
+ ret = bus->write(bus, ctl_phy, MII_MMD_CTRL, MDIO_MMD_VEND2);
if (ret < 0)
goto err;
/* Write the desired MMD register address */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
- MII_MMD_DATA, reg);
+ ret = bus->write(bus, ctl_phy, MII_MMD_DATA, reg);
if (ret < 0)
goto err;
/* Select the Function : DATA with no post increment */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+ ret = bus->write(bus, ctl_phy,
MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
if (ret < 0)
goto err;
/* Write the data into MMD's selected register */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
- MII_MMD_DATA, val);
+ ret = bus->write(bus, ctl_phy, MII_MMD_DATA, val);
err:
if (ret < 0)
dev_err(&bus->dev, "failed to write mmd register\n");
@@ -99,33 +116,37 @@ core_write(struct mt7530_priv *priv, u32 reg, u32 val)
static void
core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
{
+ int ctl_phy = mt753x_ctrl_phy_addr(priv);
struct mii_bus *bus = priv->bus;
u32 val;
int ret;
+ if (!bus)
+ bus = priv->child_bus;
+
+ if (WARN_ON_ONCE(!bus))
+ return;
+
mt7530_mutex_lock(priv);
/* Write the desired MMD Devad */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
- MII_MMD_CTRL, MDIO_MMD_VEND2);
+ ret = bus->write(bus, ctl_phy, MII_MMD_CTRL, MDIO_MMD_VEND2);
if (ret < 0)
goto err;
/* Write the desired MMD register address */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
- MII_MMD_DATA, reg);
+ ret = bus->write(bus, ctl_phy, MII_MMD_DATA, reg);
if (ret < 0)
goto err;
/* Select the Function : DATA with no post increment */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+ ret = bus->write(bus, ctl_phy,
MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
if (ret < 0)
goto err;
/* Read the content of the MMD's selected register */
- ret = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
- MII_MMD_DATA);
+ ret = bus->read(bus, ctl_phy, MII_MMD_DATA);
if (ret < 0)
goto err;
val = ret;
@@ -133,8 +154,7 @@ core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
val &= ~mask;
val |= set;
/* Write the data into MMD's selected register */
- ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
- MII_MMD_DATA, val);
+ ret = bus->write(bus, ctl_phy, MII_MMD_DATA, val);
err:
if (ret < 0)
dev_err(&bus->dev, "failed to write mmd register\n");
@@ -327,12 +347,19 @@ mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)
regmap_read(priv->regmap, MT753X_MTRAP, &xtal);
xtal &= MT7530_XTAL_MASK;
+ /* EN751221 on-die does not report clock speed in MTRAP */
+ if (priv->id == ID_EN751221)
+ xtal = MT7530_XTAL_25MHZ;
+
if (xtal == MT7530_XTAL_25MHZ)
ssc_delta = 0x57;
else
ssc_delta = 0x87;
- if (priv->id == ID_MT7621) {
+ if (priv->id == ID_EN751221_EXT || priv->id == ID_EN751221) {
+ /* PLL frequency: 362.5Mhz */
+ ncpo1 = 0x1d00;
+ } else if (priv->id == ID_MT7621) {
/* PLL frequency: 125MHz: 1.0GBit */
if (xtal == MT7530_XTAL_40MHZ)
ncpo1 = 0x0640;
@@ -449,6 +476,251 @@ mt7531_pll_setup(struct mt7530_priv *priv)
usleep_range(25, 35);
}
+static bool
+en751221_trgmii_cal_ok(struct mt7530_priv *rx, u32 reg, int chan, int i)
+{
+ u32 val = 0;
+
+ regmap_read(rx->regmap, reg, &val);
+ regmap_write(rx->regmap, reg, val | EDGE_CHK);
+ regmap_write(rx->regmap, reg, val & ~EDGE_CHK);
+ regmap_read(rx->regmap, reg, &val);
+
+ return FIELD_GET(RD_VALUE_MASK, val) == TGMII_TD_PAT &&
+ !FIELD_GET(RD_ERR_MASK, val);
+}
+
+static void
+en751221_trgmii_calibrate_direction(struct mt7530_priv *tx,
+ struct mt7530_priv *rx,
+ u8 *default_taps)
+{
+ int channel;
+
+ regmap_set_bits(tx->regmap, MT7530_TRGMII_TXCTRL, TRAIN_TXEN);
+
+ /* Put fail pattern on every channel */
+ for (channel = 0; channel < NUM_TRGMII_CTRL; channel++)
+ regmap_update_bits(tx->regmap, EN7530_TRGMII_TD_CTRL(channel),
+ TGMII_TD_PAT_MASK,
+ FIELD_PREP(TGMII_TD_PAT_MASK,
+ TGMII_TD_FAIL_PAT));
+
+ for (channel = 0; channel < NUM_TRGMII_CTRL; channel++) {
+ u32 rx_reg = MT7530_TRGMII_RD(channel);
+ int best_tap = -1, best_range = -1;
+ int first = -1;
+ u8 dac;
+ char log[TD_TAP_MAX + 1];
+
+ /* Put test pattern on correct channel */
+ regmap_update_bits(tx->regmap, EN7530_TRGMII_TD_CTRL(channel),
+ TGMII_TD_PAT_MASK,
+ FIELD_PREP(TGMII_TD_PAT_MASK, TGMII_TD_PAT));
+
+ for (dac = 0; dac < TD_TAP_MAX; dac++) {
+ /* Set TAP */
+ regmap_update_bits(rx->regmap, rx_reg, RD_TAP_MASK,
+ RD_TAP(dac));
+
+ /* Check if we can get a good read */
+ if (en751221_trgmii_cal_ok(rx, rx_reg, channel, dac)) {
+ log[dac] = '+';
+
+ if (first < 0)
+ first = dac;
+
+ if ((dac - first) > best_range) {
+ best_tap = (first + dac) / 2;
+ best_range = dac - first;
+ }
+ } else {
+ log[dac] = '.';
+ first = -1;
+ }
+ }
+
+ log[TD_TAP_MAX] = '\0';
+
+ if (best_tap > -1) {
+ regmap_update_bits(rx->regmap, rx_reg, RD_TAP_MASK,
+ RD_TAP(best_tap));
+
+ log[best_tap] = 'X';
+
+ dev_info(rx->dev,
+ "TRGMII lane %d: %s tap %d old %d\n",
+ channel, log, best_tap, default_taps[channel]);
+ } else {
+ regmap_update_bits(rx->regmap, rx_reg, RD_TAP_MASK,
+ RD_TAP(default_taps[channel]));
+
+ dev_warn(rx->dev,
+ "TRGMII lane %d: %s calibration failed, preserving tap %u\n",
+ channel, log, default_taps[channel]);
+ }
+
+ /* Return channel to failure pattern */
+ regmap_update_bits(tx->regmap, EN7530_TRGMII_TD_CTRL(channel),
+ TGMII_TD_PAT_MASK,
+ FIELD_PREP(TGMII_TD_PAT_MASK,
+ TGMII_TD_FAIL_PAT));
+ }
+
+ regmap_clear_bits(tx->regmap, MT7530_TRGMII_TXCTRL, TRAIN_TXEN);
+}
+
+static void
+en751221_set_tx_drive(struct mt7530_priv *priv, u8 drvp, u8 drvn, u8 clk_drvp,
+ u8 clk_drvn)
+{
+ int channel;
+
+ /* Tx driving for TRGMII path on SoC */
+ for (channel = 0; channel < NUM_TRGMII_CTRL; channel++)
+ regmap_write(priv->regmap, MT7530_TRGMII_TD_ODT(channel),
+ TD_DM_DRVP(drvp) | TD_DM_DRVN(drvn));
+
+ /* Undocumented 6th channel, probably drive strength for clock line. */
+ regmap_write(priv->regmap, MT7530_TRGMII_TD_ODT(5), TD_DM_DRVP(drvp) |
+ TD_DM_DRVN(drvn));
+}
+
+static void
+en751221_trgmii_pair_setup(struct mt7530_priv *ext, int ext_port,
+ struct mt7530_priv *ondie, int ondie_port)
+{
+ u8 default_taps_ondie[NUM_TRGMII_CTRL];
+ u8 default_taps_ext[NUM_TRGMII_CTRL];
+ u32 mcr_down, mcr_up;
+ int channel;
+ int reg_val;
+
+ /* BOTH: Put interfaces in a downed state */
+ mcr_down = PMCR_IFG_XMIT(PMCR_IFG_XMIT_64) | PMCR_MAC_MODE |
+ MT7530_FORCE_MODE | PMCR_MAC_RX_EN | PMCR_BACKOFF_EN |
+ PMCR_BACKPR_EN | PMCR_FORCE_SPEED_1000 | PMCR_FORCE_FDX;
+ regmap_write(ondie->regmap, MT753X_PMCR_P(ondie_port), mcr_down);
+ regmap_write(ext->regmap, MT753X_PMCR_P(ext_port), mcr_down);
+ usleep_range(5000, 6000);
+
+ /* BOTH: Reset TX */
+ regmap_set_bits(ext->regmap, MT7530_TRGMII_TXCTRL, TX_RST);
+ regmap_set_bits(ondie->regmap, MT7530_TRGMII_TXCTRL, TX_RST);
+ usleep_range(5000, 6000);
+ regmap_clear_bits(ext->regmap, MT7530_TRGMII_TXCTRL, TX_RST);
+ regmap_clear_bits(ondie->regmap, MT7530_TRGMII_TXCTRL, TX_RST);
+
+ /* BOTH: Reset RX controllers down */
+ regmap_set_bits(ext->regmap, MT7530_TRGMII_RCK_CTRL, RX_RST);
+ regmap_set_bits(ondie->regmap, MT7530_TRGMII_RCK_CTRL, RX_RST);
+
+ /* BOTH: Set TX drive strength, MCM uses more */
+ en751221_set_tx_drive(ondie, 8, 8, 7, 7);
+ en751221_set_tx_drive(ext, 11, 11, 16, 16);
+
+ /* BOTH: Reset RX controllers up */
+ regmap_clear_bits(ext->regmap, MT7530_TRGMII_RCK_CTRL, RX_RST);
+ regmap_clear_bits(ondie->regmap, MT7530_TRGMII_RCK_CTRL, RX_RST);
+
+ /* BOTH: Ports up */
+ mcr_up = mcr_down | PMCR_MAC_TX_EN | PMCR_FORCE_LNK;
+ regmap_write(ondie->regmap, MT753X_PMCR_P(ondie_port), mcr_up);
+ regmap_write(ext->regmap, MT753X_PMCR_P(ext_port), mcr_up);
+
+ /* MCM: Set Ext->SoC TX delay to 0 */
+ for (channel = 0; channel < NUM_TRGMII_CTRL; channel++)
+ regmap_clear_bits(ext->regmap, EN7530_TRGMII_TD_CTRL(channel),
+ TGMII_TD_TAP_MASK);
+
+ /* SOC: ODT */
+ regmap_set_bits(ondie->regmap, MT7530_TRGMII_RCK_RTT,
+ DQS1_GATE | DQS0_GATE | EN751221_B17);
+
+ /* SOC: Undocumented */
+ for (channel = 0; channel < NUM_TRGMII_CTRL; channel++)
+ regmap_write(ondie->regmap, (0x7a14 + channel * 8),
+ 0x3227700);
+
+ /* MCM: Spread spectrum clock*/
+ core_clear(ext, CORE_PLL_GROUP8, RG_LCDDS_SSC_EN);
+
+ /* BOTH: Zero clock delay */
+ regmap_clear_bits(ext->regmap, MT7530_TRGMII_RCK_CTRL,
+ DQSI0_TAP_MASK);
+ regmap_clear_bits(ondie->regmap, MT7530_TRGMII_RCK_CTRL,
+ DQSI0_TAP_MASK);
+
+ /* BOTH: Collect and then zero every RX TAP */
+ for (channel = 0; channel < NUM_TRGMII_CTRL; channel++) {
+ reg_val = 0;
+ regmap_read(ext->regmap, MT7530_TRGMII_RD(channel), ®_val);
+ default_taps_ext[channel] = FIELD_GET(RD_TAP_MASK, reg_val);
+ regmap_clear_bits(ext->regmap, MT7530_TRGMII_RD(channel),
+ RD_TAP_MASK);
+
+ reg_val = 0;
+ regmap_read(ondie->regmap, MT7530_TRGMII_RD(channel), ®_val);
+ default_taps_ondie[channel] = FIELD_GET(RD_TAP_MASK, reg_val);
+ regmap_clear_bits(ondie->regmap, MT7530_TRGMII_RD(channel),
+ RD_TAP_MASK);
+ }
+
+ en751221_trgmii_calibrate_direction(ondie, ext, default_taps_ext);
+ en751221_trgmii_calibrate_direction(ext, ondie, default_taps_ext);
+
+ dev_info(ondie->dev, "TRGMII inter-switch link initialized\n");
+}
+
+static void
+mt7530_cal_interswitch_trgmii(struct dsa_port *dp)
+{
+ struct dsa_switch *ds = dp->ds;
+ struct dsa_switch *peer_ds;
+ struct dsa_port *peer_dp;
+ struct mt7530_priv *peer;
+ struct mt7530_priv *priv;
+ struct dsa_link *dl;
+ u32 pmsr = 0;
+
+ priv = ds->priv;
+
+ if (priv->id != ID_EN751221_EXT)
+ return;
+
+ if (dp->type != DSA_PORT_TYPE_DSA)
+ return;
+
+ regmap_read(priv->regmap, MT7530_PMSR_P(dp->index), &pmsr);
+
+ if (!(pmsr & PMSR_LINK))
+ return;
+
+ list_for_each_entry(dl, &ds->dst->rtable, list) {
+ if (dl->dp != dp)
+ continue;
+
+ peer_dp = dl->link_dp;
+
+ if (peer_dp->type != DSA_PORT_TYPE_DSA)
+ continue;
+
+ peer_ds = dl->link_dp->ds;
+
+ if (!of_device_is_compatible(peer_ds->dev->of_node,
+ "econet,en751221-switch"))
+ continue;
+
+ peer = peer_ds->priv;
+
+ if (peer->id != ID_EN751221)
+ continue;
+
+ en751221_trgmii_pair_setup(priv, dp->index, peer,
+ peer_dp->index);
+ }
+}
+
static void
mt7530_mib_reset(struct dsa_switch *ds)
{
@@ -1281,13 +1553,41 @@ mt753x_trap_frames(struct mt7530_priv *priv)
TO_CPU_FW_CPU_ONLY);
}
+static int
+mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu);
+
+/* If this switch is downstream of another switch that is in passthrough mode,
+ * the "CPU" port is actually a DSA port.
+ */
static void
mt753x_cpu_port_enable(struct dsa_switch *ds, int port)
{
struct mt7530_priv *priv = ds->priv;
- /* Enable Mediatek header mode on the cpu port */
- regmap_write(priv->regmap, MT7530_PVC_P(port), PORT_SPEC_TAG);
+ if (priv->is_passthrough) {
+ /* Disable parsing of the DSA tag, it will be forwarded blindly
+ * to the downstream switch.
+ */
+ regmap_write(priv->regmap, MT7530_PVC_P(port),
+ VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
+ PVC_EG_TAG(MT7530_VLAN_EG_DISABLED));
+
+ /* The port is not configured to parse DSA tags, so they are
+ * liable to be confused for length fields, so length check is
+ * disabled.
+ */
+ regmap_clear_bits(priv->regmap, MT753X_AGC, AGC_L2LEN_CHK);
+
+ /* In passthrough mode, MTU is only enforced downstream */
+ mt7530_port_change_mtu(ds, port, MT7530_MAX_MTU);
+
+ /* Loop detection has no value in passthrough mode */
+ regmap_set_bits(priv->regmap, MT753X_MTRAP,
+ MT7530_LOOP_DET_DISABLE);
+ } else {
+ /* Not passthrough, enable DSA tag handling on CPU port. */
+ regmap_write(priv->regmap, MT7530_PVC_P(port), PORT_SPEC_TAG);
+ }
/* Enable flooding on the CPU port */
regmap_set_bits(priv->regmap, MT753X_MFC,
@@ -1317,6 +1617,7 @@ static int
mt7530_port_enable(struct dsa_switch *ds, int port,
struct phy_device *phy)
{
+ int upstream_pt = dsa_switch_upstream_port(ds);
struct dsa_port *dp = dsa_to_port(ds, port);
struct mt7530_priv *priv = ds->priv;
@@ -1327,17 +1628,43 @@ mt7530_port_enable(struct dsa_switch *ds, int port,
* bridge.
*/
if (dsa_port_is_user(dp)) {
- struct dsa_port *cpu_dp = dp->cpu_dp;
+ priv->ports[port].pm |= PCR_MATRIX(BIT(upstream_pt));
+
+ } else if (dsa_port_is_dsa(dp) && dp->index != upstream_pt) {
+ priv->ports[port].pm |= PCR_MATRIX(BIT(upstream_pt));
+
+ /* Should not happen */
+ WARN_ON_ONCE(!priv->is_passthrough);
+
+ /* We are passing through to a downstream switch so we set both
+ * CPU and downstream link to pass traffic untouched so that
+ * the STAG from the downstream switch will pass to the upstream.
+ */
+ regmap_write(priv->regmap, MT7530_PVC_P(port),
+ VLAN_ATTR(MT7530_VLAN_TRANSPARENT) |
+ PVC_EG_TAG(MT7530_VLAN_EG_DISABLED));
+
+ /* We let the downstream switch flood */
+ regmap_set_bits(priv->regmap, MT753X_MFC, BC_FFP(BIT(port)) |
+ UNM_FFP(BIT(port)) | UNU_FFP(BIT(port)));
- priv->ports[port].pm |= PCR_MATRIX(BIT(cpu_dp->index));
+ /* Make the upstream port able to connect to the DSA port.
+ * This must be explicit because PORT_SPEC_TAG is unset.
+ */
+ regmap_write(priv->regmap, MT7530_PCR_P(upstream_pt),
+ PCR_MATRIX(BIT(port)));
}
priv->ports[port].enable = true;
- regmap_update_bits(priv->regmap, MT7530_PCR_P(port), PCR_MATRIX_MASK,
- priv->ports[port].pm);
+
+ /* In passthrough mode, CPU port mask is set above. */
+ if (!(priv->is_passthrough && dp->index == upstream_pt))
+ regmap_update_bits(priv->regmap, MT7530_PCR_P(port),
+ PCR_MATRIX_MASK, priv->ports[port].pm);
mutex_unlock(&priv->reg_mutex);
- if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621 &&
+ priv->id != ID_EN751221 && priv->id != ID_EN751221_EXT)
return 0;
if (port == 5)
@@ -1364,7 +1691,8 @@ mt7530_port_disable(struct dsa_switch *ds, int port)
mutex_unlock(&priv->reg_mutex);
- if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621 &&
+ priv->id != ID_EN751221 && priv->id != ID_EN751221_EXT)
return;
/* Do not set MT7530_P5_DIS when port 5 is being used for PHY muxing. */
@@ -1385,7 +1713,7 @@ mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
* largest MTU of the user ports. Because the switch only has a global
* RX length register, only allowing CPU port here is enough.
*/
- if (!dsa_is_cpu_port(ds, port))
+ if (!dsa_is_upstream_port(ds, port))
return 0;
regmap_read(priv->regmap, MT7530_GMACCR, &val);
@@ -2333,7 +2661,7 @@ mt7530_free_mdio_irq(struct mt7530_priv *priv)
}
}
-static int
+int
mt7530_setup_mdio(struct mt7530_priv *priv)
{
struct device_node *mnp, *np = priv->dev->of_node;
@@ -2343,6 +2671,10 @@ mt7530_setup_mdio(struct mt7530_priv *priv)
static int idx;
int ret = 0;
+ /* Already done */
+ if (priv->child_bus)
+ return 0;
+
mnp = of_get_child_by_name(np, "mdio");
if (mnp && !of_device_is_available(mnp))
@@ -2370,8 +2702,11 @@ mt7530_setup_mdio(struct mt7530_priv *priv)
if (priv->irq_domain && !mnp)
mt7530_setup_mdio_irq(priv);
+ priv->child_bus = bus;
+
ret = devm_of_mdiobus_register(dev, bus, mnp);
if (ret) {
+ priv->child_bus = NULL;
dev_err(dev, "failed to register MDIO bus: %d\n", ret);
if (priv->irq_domain && !mnp)
mt7530_free_mdio_irq(priv);
@@ -2381,6 +2716,7 @@ mt7530_setup_mdio(struct mt7530_priv *priv)
of_node_put(mnp);
return ret;
}
+EXPORT_SYMBOL_GPL(mt7530_setup_mdio);
static int
mt7530_setup(struct dsa_switch *ds)
@@ -2406,11 +2742,6 @@ mt7530_setup(struct dsa_switch *ds)
break;
}
- if (!dn) {
- dev_err(ds->dev, "parent OF node of DSA conduit not found");
- return -EINVAL;
- }
-
ds->assisted_learning_on_cpu_port = true;
ds->untag_vlan_aware_bridge_pvid = true;
ds->mtu_enforcement_ingress = true;
@@ -2489,6 +2820,12 @@ mt7530_setup(struct dsa_switch *ds)
MT7530_CHG_TRAP | MT7530_PHY_INDIRECT_ACCESS,
MT7530_CHG_TRAP);
+ /* EN751221 MCM starts on the wrong frequency */
+ if (priv->id == ID_EN751221_EXT)
+ regmap_update_bits(priv->regmap, MT753X_MTRAP,
+ MT7530_CHG_TRAP | MT7530_CK_SEL,
+ MT7530_CHG_TRAP);
+
if ((val & MT7530_XTAL_MASK) == MT7530_XTAL_40MHZ)
mt7530_pll_setup(priv);
@@ -2512,7 +2849,7 @@ mt7530_setup(struct dsa_switch *ds)
/* Disable learning by default on all ports */
regmap_set_bits(priv->regmap, MT7530_PSC_P(i), SA_DIS);
- if (dsa_is_cpu_port(ds, i)) {
+ if (dsa_is_upstream_port(ds, i)) {
mt753x_cpu_port_enable(ds, i);
} else {
mt7530_port_disable(ds, i);
@@ -2536,7 +2873,7 @@ mt7530_setup(struct dsa_switch *ds)
return ret;
/* Check for PHY muxing on port 5 */
- if (dsa_is_unused_port(ds, 5)) {
+ if (dn && dsa_is_unused_port(ds, 5)) {
/* Scan the ethernet nodes. Look for GMAC1, lookup the used PHY.
* Set priv->p5_mode to the appropriate value if PHY muxing is
* detected.
@@ -2636,7 +2973,7 @@ mt7531_setup_common(struct dsa_switch *ds)
regmap_set_bits(priv->regmap, MT7531_DBG_CNT(i),
MT7531_DIS_CLR);
- if (dsa_is_cpu_port(ds, i)) {
+ if (dsa_is_upstream_port(ds, i)) {
mt753x_cpu_port_enable(ds, i);
} else {
mt7530_port_disable(ds, i);
@@ -2674,8 +3011,11 @@ mt7531_setup(struct dsa_switch *ds)
{
struct mt7530_priv *priv = ds->priv;
u32 val, id;
+ int ctl_phy;
int ret, i;
+ ctl_phy = mt753x_ctrl_phy_addr(priv);
+
/* Reset whole chip through gpio pin or memory-mapped registers for
* different type of hardware
*/
@@ -2743,25 +3083,21 @@ mt7531_setup(struct dsa_switch *ds)
* phy_[read,write]_mmd_indirect is called, we provide our own
* mt7531_ind_mmd_phy_[read,write] to complete this function.
*/
- ret = mt7531_ind_c45_phy_read(priv,
- MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
- MDIO_MMD_VEND2, CORE_PLL_GROUP4);
+ ret = mt7531_ind_c45_phy_read(priv, ctl_phy, MDIO_MMD_VEND2,
+ CORE_PLL_GROUP4);
if (ret < 0)
return ret;
val = ret;
val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;
val &= ~MT7531_PHY_PLL_OFF;
- ret = mt7531_ind_c45_phy_write(priv,
- MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
- MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
+ ret = mt7531_ind_c45_phy_write(priv, ctl_phy, MDIO_MMD_VEND2,
+ CORE_PLL_GROUP4, val);
if (ret < 0)
return ret;
/* Disable EEE advertisement on the switch PHYs. */
- for (i = MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr);
- i < MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr) + MT7530_NUM_PHYS;
- i++) {
+ for (i = ctl_phy; i < ctl_phy + MT7530_NUM_PHYS; i++) {
mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
0);
}
@@ -2910,6 +3246,44 @@ static void en7528_mac_port_get_caps(struct dsa_switch *ds, int port,
}
}
+static void en751221_mac_port_get_caps(struct dsa_switch *ds, int port,
+ struct phylink_config *config)
+{
+ switch (port) {
+ /* EN751221 ports 0..3 are connected to the integrated FE PHYs. */
+ case 0 ... 3:
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ config->supported_interfaces);
+
+ config->mac_capabilities |= MAC_10 | MAC_100;
+ break;
+
+ /* Port 4 is connected to the standalone EN7512/EN7521 GPHY. */
+ case 4:
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ config->supported_interfaces);
+
+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD;
+ break;
+
+ /* Port 5 is the 1 Gbit/s TRGMII cascade to the external MT7530. */
+ case 5:
+ __set_bit(PHY_INTERFACE_MODE_TRGMII,
+ config->supported_interfaces);
+
+ config->mac_capabilities |= MAC_1000FD;
+ break;
+
+ /* Port 6 is the 1 Gbit/s CPU link to GDM1. */
+ case 6:
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ config->supported_interfaces);
+
+ config->mac_capabilities |= MAC_1000FD;
+ break;
+ }
+}
+
static void
mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
@@ -3059,6 +3433,9 @@ static void mt753x_phylink_mac_link_up(struct phylink_config *config,
}
regmap_set_bits(priv->regmap, MT753X_PMCR_P(dp->index), mcr);
+
+ if (interface == PHY_INTERFACE_MODE_TRGMII)
+ mt7530_cal_interswitch_trgmii(dp);
}
static void mt753x_phylink_mac_disable_tx_lpi(struct phylink_config *config)
@@ -3298,10 +3675,11 @@ mt753x_conduit_state_change(struct dsa_switch *ds,
/* Set the CPU port to trap frames to for MT7530. Trapped frames will be
* forwarded to the numerically smallest CPU port whose conduit
- * interface is up.
+ * interface is up. NOTE: "CPU port" can also mean an upstream DSA link.
*/
if (priv->id != ID_MT7530 && priv->id != ID_MT7621 &&
- priv->id != ID_EN7528)
+ priv->id != ID_EN7528 && priv->id != ID_EN751221 &&
+ priv->id != ID_EN751221_EXT)
return;
mask = BIT(cpu_dp->index);
@@ -3393,6 +3771,76 @@ static int mt7988_setup(struct dsa_switch *ds)
return mt7531_setup_common(ds);
}
+/* 1 if passthrough, negative if error. */
+static int mt753x_check_passthrough(struct device *dev)
+{
+ struct device_node *ports, *port;
+ int passthrough_ports = 0;
+ int enabled_ports = 0;
+
+ ports = of_get_child_by_name(dev->of_node, "ports");
+ if (!ports)
+ ports = of_get_child_by_name(dev->of_node, "ethernet-ports");
+
+ if (!ports) {
+ dev_err(dev, "no ports child node found\n");
+ return -EINVAL;
+ }
+
+ for_each_available_child_of_node(ports, port) {
+ struct device_node *link;
+
+ enabled_ports++;
+
+ link = of_parse_phandle(port, "ethernet", 0);
+ if (!link)
+ link = of_parse_phandle(port, "link", 0);
+
+ if (!link)
+ continue;
+
+ of_node_put(link);
+
+ passthrough_ports++;
+ }
+
+ of_node_put(ports);
+
+ /*
+ * A switch is considered passthrough if exactly two available
+ * ports have an "ethernet" or "link" phandle.
+ */
+ if (passthrough_ports > 2 ||
+ (passthrough_ports == 2 && enabled_ports != 2)
+ ) {
+ dev_err(dev, "Only two ports allowed in passthrough mode\n");
+ return -EINVAL;
+ }
+
+ return passthrough_ports == 2;
+}
+
+/* No manipulation of forwarding rules allowed in passthrough mode */
+static const struct dsa_switch_ops mt7530_passthrough_switch_ops = {
+ .get_tag_protocol = mtk_get_tag_protocol,
+ .setup = mt753x_setup,
+ .teardown = mt753x_teardown,
+ .preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port,
+ .get_strings = mt7530_get_strings,
+ .get_ethtool_stats = mt7530_get_ethtool_stats,
+ .get_sset_count = mt7530_get_sset_count,
+ .get_eth_mac_stats = mt7530_get_eth_mac_stats,
+ .get_rmon_stats = mt7530_get_rmon_stats,
+ .get_eth_ctrl_stats = mt7530_get_eth_ctrl_stats,
+ .get_stats64 = mt7530_get_stats64,
+ .port_enable = mt7530_port_enable,
+ .port_disable = mt7530_port_disable,
+ .phylink_get_caps = mt753x_phylink_get_caps,
+ .support_eee = dsa_supports_eee,
+ .set_mac_eee = mt753x_set_mac_eee,
+ .conduit_state_change = mt753x_conduit_state_change,
+};
+
static const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt753x_setup,
@@ -3519,14 +3967,40 @@ const struct mt753x_info mt753x_table[] = {
.phy_write_c45 = mt7531_ind_c45_phy_write,
.mac_port_get_caps = en7528_mac_port_get_caps,
},
+ [ID_EN751221] = {
+ .id = ID_EN751221,
+ .pcs_ops = &mt7530_pcs_ops,
+ .sw_setup = mt7988_setup,
+ .phy_read_c22 = mt7531_ind_c22_phy_read,
+ .phy_write_c22 = mt7531_ind_c22_phy_write,
+ .phy_read_c45 = mt7531_ind_c45_phy_read,
+ .phy_write_c45 = mt7531_ind_c45_phy_write,
+ .mac_port_get_caps = en751221_mac_port_get_caps,
+ .mac_port_config = mt7530_mac_config,
+ },
+ [ID_EN751221_EXT] = {
+ .id = ID_EN751221_EXT,
+ .pcs_ops = &mt7530_pcs_ops,
+ .sw_setup = mt7530_setup,
+ .phy_read_c22 = mt7530_phy_read_c22,
+ .phy_write_c22 = mt7530_phy_write_c22,
+ .phy_read_c45 = mt7530_phy_read_c45,
+ .phy_write_c45 = mt7530_phy_write_c45,
+ .mac_port_get_caps = mt7530_mac_port_get_caps,
+ .mac_port_config = mt7530_mac_config,
+ },
};
EXPORT_SYMBOL_GPL(mt753x_table);
int
mt7530_probe_common(struct mt7530_priv *priv)
{
+ int passthrough = mt753x_check_passthrough(priv->dev);
struct device *dev = priv->dev;
+ if (passthrough < 0)
+ return passthrough;
+
priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
if (!priv->ds)
return -ENOMEM;
@@ -3544,7 +4018,14 @@ mt7530_probe_common(struct mt7530_priv *priv)
priv->id = priv->info->id;
priv->dev = dev;
priv->ds->priv = priv;
- priv->ds->ops = &mt7530_switch_ops;
+
+ if (passthrough) {
+ priv->ds->ops = &mt7530_passthrough_switch_ops;
+ priv->is_passthrough = true;
+ } else {
+ priv->ds->ops = &mt7530_switch_ops;
+ }
+
priv->ds->phylink_mac_ops = &mt753x_phylink_mac_ops;
mutex_init(&priv->reg_mutex);
spin_lock_init(&priv->stats_lock);
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index 2bbbe617b52ee..1a4329749c0f1 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -24,6 +24,8 @@ enum mt753x_id {
ID_EN7581 = 4,
ID_AN7583 = 5,
ID_EN7528 = 6,
+ ID_EN751221 = 7,
+ ID_EN751221_EXT = 8,
};
#define NUM_TRGMII_CTRL 5
@@ -40,6 +42,7 @@ enum mt753x_id {
/* Register for ARL global control */
#define MT753X_AGC 0xc
#define LOCAL_EN BIT(7)
+#define AGC_L2LEN_CHK BIT(4)
/* Register for MAC forward control */
#define MT753X_MFC 0x10
@@ -355,6 +358,9 @@ enum mt7530_vlan_port_acc_frm {
#define MT753X_PMCR_P(x) (0x3000 + ((x) * 0x100))
#define PMCR_IFG_XMIT_MASK GENMASK(19, 18)
#define PMCR_IFG_XMIT(x) FIELD_PREP(PMCR_IFG_XMIT_MASK, x)
+#define PMCR_IFG_XMIT_96 0
+#define PMCR_IFG_XMIT_RAND 1
+#define PMCR_IFG_XMIT_64 2
#define PMCR_EXT_PHY BIT(17)
#define PMCR_MAC_MODE BIT(16)
#define MT7530_FORCE_MODE BIT(15)
@@ -583,6 +589,8 @@ enum mt7531_clk_skew {
#define MT753X_MTRAP 0x7804
#define MT7530_P5_PHY0_SEL BIT(20)
#define MT7530_CHG_TRAP BIT(16)
+#define MT7530_CK_SEL BIT(15)
+#define MT7530_LOOP_DET_DISABLE BIT(14)
#define MT7530_P5_MAC_SEL BIT(13)
#define MT7530_P6_DIS BIT(8)
#define MT7530_P5_RGMII_MODE BIT(7)
@@ -599,6 +607,8 @@ enum mt7531_xtal_fsel {
/* Register for TOP signal control */
#define MT7530_TOP_SIG_CTRL 0x7808
#define TOP_SIG_CTRL_NORMAL (BIT(17) | BIT(16))
+/* Undocumented */
+#define TOP_SIG_CTRL_B0 BIT(0)
#define MT7531_TOP_SIG_SR 0x780c
#define PAD_DUAL_SGMII_EN BIT(1)
@@ -645,18 +655,31 @@ enum mt7531_xtal_fsel {
#define MT7530_TRGMII_RCK_RTT 0x7a04
#define DQS1_GATE BIT(31)
#define DQS0_GATE BIT(30)
+/* Undocumented */
+#define EN751221_B17 BIT(17)
#define MT7530_TRGMII_RD(x) (0x7a10 + (x) * 8)
#define BSLIP_EN BIT(31)
#define EDGE_CHK BIT(30)
+#define RD_VALUE_MASK GENMASK(23, 16)
+#define RD_ERR_MASK GENMASK(11, 8)
#define RD_TAP_MASK GENMASK(6, 0)
#define RD_TAP(x) FIELD_PREP(RD_TAP_MASK, x)
+/* Training does not try anything beyond this */
+#define TD_TAP_MAX 64
#define MT7530_TRGMII_TXCTRL 0x7a40
#define TRAIN_TXEN BIT(31)
#define TXC_INV BIT(30)
#define TX_RST BIT(28)
+#define EN7530_TRGMII_TD_CTRL(x) (0x7a50 + (x) * 8)
+#define TGMII_TD_TAP_MASK GENMASK(11, 8)
+#define TGMII_TD_PAT_MASK GENMASK(7, 0)
+/* Use a 01010101 bit pattern */
+#define TGMII_TD_PAT 0x55
+#define TGMII_TD_FAIL_PAT 0xaa
+
#define MT7530_TRGMII_TD_ODT(i) (0x7a54 + 8 * (i))
#define TD_DM_DRVP_MASK GENMASK(3, 0)
#define TD_DM_DRVP(x) FIELD_PREP(TD_DM_DRVP_MASK, x)
@@ -747,8 +770,6 @@ enum mt7531_xtal_fsel {
#define MT7531_PHY_PLL_OFF BIT(5)
#define MT7531_PHY_PLL_BYPASS_MODE BIT(4)
-#define MT753X_CTRL_PHY_ADDR(addr) (((addr) + 1) & (PHY_MAX_ADDR - 1))
-
#define CORE_PLL_GROUP5 0x404
#define RG_LCDDS_PCW_NCPO1_MASK GENMASK(15, 0)
#define RG_LCDDS_PCW_NCPO1(x) FIELD_PREP(RG_LCDDS_PCW_NCPO1_MASK, x)
@@ -764,6 +785,9 @@ enum mt7531_xtal_fsel {
#define RG_LCCDS_C(x) FIELD_PREP(RG_LCCDS_C_MASK, x)
#define RG_LCDDS_PCW_NCPO_CHG BIT(3)
+#define CORE_PLL_GROUP8 0x407
+#define RG_LCDDS_SSC_EN BIT(10)
+
#define CORE_PLL_GROUP10 0x409
#define RG_LCDDS_SSC_DELTA_MASK GENMASK(11, 0)
#define RG_LCDDS_SSC_DELTA(x) FIELD_PREP(RG_LCDDS_SSC_DELTA_MASK, x)
@@ -886,6 +910,9 @@ struct mt753x_info {
* @dev: The device pointer
* @ds: The pointer to the dsa core structure
* @bus: The bus used for the device and built-in PHY
+ * @child_bus: The bus created by the device, on MDIO implementations
+ * this is bus indirectly accesses `bus`, on MMIO
+ * implementations this bus is part of the switch.
* @regmap: The regmap instance representing all switch registers
* @rstc: The pointer to reset control used by MCM
* @core_pwr: The power supplied into the core
@@ -899,6 +926,9 @@ struct mt753x_info {
* @p5_mode: Holding the current mode of port 5 of the MT7530 switch
* @p5_sgmii: Flag for distinguishing if port 5 of the MT7531 switch
* has got SGMII
+ * @is_passthrough: If this switch is to pass traffic between the upstream
+ * (CPU) port and a second downstream switch, without
+ * altering the DSA tag.
* @irq_domain: IRQ domain of the switch irq_chip
* @create_sgmii: Pointer to function creating SGMII PCS instance(s)
* @active_cpu_ports: Holding the active CPU ports
@@ -911,6 +941,7 @@ struct mt7530_priv {
struct device *dev;
struct dsa_switch *ds;
struct mii_bus *bus;
+ struct mii_bus *child_bus;
struct regmap *regmap;
struct reset_control *rstc;
struct regulator *core_pwr;
@@ -923,6 +954,7 @@ struct mt7530_priv {
bool p5_sgmii;
u8 mirror_rx;
u8 mirror_tx;
+ bool is_passthrough;
struct mt7530_port ports[MT7530_NUM_PORTS];
struct mt753x_pcs pcs[MT7530_NUM_PORTS];
/* protect among processes for registers access*/
@@ -961,6 +993,16 @@ struct mt7530_hw_stats {
int mt7530_probe_common(struct mt7530_priv *priv);
void mt7530_remove_common(struct mt7530_priv *priv);
+/*
+ * When an MMIO based switch has an MDIO bus which contains a downstream MDIO
+ * switch, the MDIO bus is not normally setup until mt753x_setup() has been
+ * called. But mt753x_setup() is not called until DSA sees that every switch in
+ * the tree has been probed. Calling mt7530_setup_mdio() after at the end of
+ * the MMIO probe function allows the downstream switch to register, completing
+ * the tree.
+ */
+int mt7530_setup_mdio(struct mt7530_priv *priv);
+
extern const struct mt753x_info mt753x_table[];
#endif /* __MT7530_H */
|
| 3/2 | 2026/09/09 16:04 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 19825 output: 35 thoughts: 272 Thoughts: **Evaluating the Fuzzing Potential of a Linux Kernel Patch** Okay, so the user wants me to decide if this patch series is worth fuzzing with syzkaller. Alright, let's get down to it. First, I need to see what's actually being changed. Looks like it's touching these files: `Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml`, `drivers/net/dsa/mt7530-mdio.c`, `drivers/net/dsa/mt7530-mmio.c`, `drivers/net/dsa/mt7530.c`, and `drivers/net/dsa/mt7530.h`. Right, MT7530... that rings a bell. Let's confirm: it's the MediaTek / EcoNet MT7530 DSA ethernet switch driver. Now comes the critical part: can we *actually* get at this thing in a fuzzing environment? I need to know the target hardware. Is it something that's likely to be supported by QEMU on amd64, which is the standard syzkaller setup? This is where I start thinking about the probing methods. I'm going to dig into the git repo, probably using `git grep` and the Kconfig files. I need to figure out *how* the MT7530 is hooked up. Is it MDIO, MMIO, Platform, SPI, I2C, or something else? Understanding the bus it relies on is essential. Then, I need to assess whether we can simulate it, emulate it, or otherwise reach it within the fuzzing framework. If it requires some obscure hardware I can't easily emulate, then we'll have a tough time. Time to run grepper or read the Kconfig files. Let's see what we can find. |
| 4/2 | 2026/09/09 16:04 | tool | grepper |
0mArgs:{
"Expression": "NET_DSA_MT7530",
"PathPrefix": "drivers/net/dsa"
}Results: {
"Output": "drivers/net/dsa/Kconfig=29=source \"drivers/net/dsa/lantiq/Kconfig\"\ndrivers/net/dsa/Kconfig-30-\ndrivers/net/dsa/Kconfig:31:config NET_DSA_MT7530\ndrivers/net/dsa/Kconfig-32-\ttristate \"MediaTek MT7530 and MT7531 Ethernet switch support\"\n--\ndrivers/net/dsa/Kconfig-34-\tselect REGMAP_IRQ\ndrivers/net/dsa/Kconfig:35:\timply NET_DSA_MT7530_MDIO\ndrivers/net/dsa/Kconfig:36:\timply NET_DSA_MT7530_MMIO\ndrivers/net/dsa/Kconfig-37-\thelp\n--\ndrivers/net/dsa/Kconfig-42-\ndrivers/net/dsa/Kconfig:43:config NET_DSA_MT7530_MDIO\ndrivers/net/dsa/Kconfig-44-\ttristate \"MediaTek MT7530 MDIO interface driver\"\ndrivers/net/dsa/Kconfig:45:\tdepends on NET_DSA_MT7530\ndrivers/net/dsa/Kconfig-46-\tselect MEDIATEK_GE_PHY\n--\ndrivers/net/dsa/Kconfig-53-\ndrivers/net/dsa/Kconfig:54:config NET_DSA_MT7530_MMIO\ndrivers/net/dsa/Kconfig-55-\ttristate \"MediaTek MT7530 MMIO interface driver\"\ndrivers/net/dsa/Kconfig:56:\tdepends on NET_DSA_MT7530\ndrivers/net/dsa/Kconfig-57-\tdepends on HAS_IOMEM\n--\ndrivers/net/dsa/Makefile=5=obj-$(CONFIG_NET_DSA_KS8995) \t+= ks8995.o\ndrivers/net/dsa/Makefile:6:obj-$(CONFIG_NET_DSA_MT7530)\t+= mt7530.o\ndrivers/net/dsa/Makefile:7:obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o\ndrivers/net/dsa/Makefile:8:obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o\ndrivers/net/dsa/Makefile-9-obj-$(CONFIG_NET_DSA_MT7628) += mt7628.o\n"
} |
| 5/2 | 2026/09/09 16:04 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 21194 output: 45 thoughts: 58 Thoughts: Here's my thinking process: **Diving into the MT7530 Driver Implementation** Okay, so I need to understand how the MT7530 switch is being probed and initialized in the kernel. My first step is to zero in on the relevant driver code. Let's see... the architecture suggests that the MDIO and MMIO variants are likely the key drivers. So, I'll go straight to `drivers/net/dsa/mt7530-mdio.c` and `mt7530-mmio.c`. I want to see exactly how these drivers are structured. I'll be looking for the typical patterns here. I need to understand whether we're dealing with an MDIO driver (`mdio_driver`) for the MDIO-connected variant, a platform driver (`platform_driver`) for the MMIO variant, or something else entirely. Are there device tree (OF) match tables involved? That's almost a given these days, but it's important to confirm. I need to see how the kernel identifies these devices during the boot process and how the relevant driver is attached to them. This will give me a solid foundation for understanding the initialization sequence and any potential quirks. |
| 6/2 | 2026/09/09 16:04 | tool | read-file |
0mArgs:{
"File": "drivers/net/dsa/mt7530-mdio.c",
"FirstLine": 130,
"LineCount": 40
}Results: {
"Contents": " 130:\t\t\t\tbreak;\n 131:\t\t\t}\n 132:\t\t\tpriv-\u003eports[5 + i].sgmii_pcs = pcs;\n 133:\t\t}\n 134:\t\n 135:\t\tif (ret \u0026\u0026 i)\n 136:\t\t\tmtk_pcs_lynxi_destroy(priv-\u003eports[5].sgmii_pcs);\n 137:\t\n 138:\t\treturn ret;\n 139:\t}\n 140:\t\n 141:\tstatic const struct of_device_id mt7530_of_match[] = {\n 142:\t\t{ .compatible = \"econet,en751221\", .data = \u0026mt753x_table[ID_EN751221_EXT], },\n 143:\t\t{ .compatible = \"mediatek,mt7621\", .data = \u0026mt753x_table[ID_MT7621], },\n 144:\t\t{ .compatible = \"mediatek,mt7530\", .data = \u0026mt753x_table[ID_MT7530], },\n 145:\t\t{ .compatible = \"mediatek,mt7531\", .data = \u0026mt753x_table[ID_MT7531], },\n 146:\t\t{ /* sentinel */ }\n 147:\t};\n 148:\tMODULE_DEVICE_TABLE(of, mt7530_of_match);\n 149:\t\n 150:\tstatic const struct regmap_config regmap_config = {\n 151:\t\t.reg_bits = 16,\n 152:\t\t.val_bits = 32,\n 153:\t\t.reg_stride = 4,\n 154:\t\t.max_register = MT7530_CREV,\n 155:\t\t.lock = mt7530_mdio_regmap_lock,\n 156:\t\t.unlock = mt7530_mdio_regmap_unlock,\n 157:\t};\n 158:\t\n 159:\tstatic int\n 160:\tmt7530_probe(struct mdio_device *mdiodev)\n 161:\t{\n 162:\t\tstruct regmap_config rc = regmap_config;\n 163:\t\tstruct mt7530_priv *priv;\n 164:\t\tstruct device_node *dn;\n 165:\t\tint ret;\n 166:\t\n 167:\t\tdn = mdiodev-\u003edev.of_node;\n 168:\t\n 169:\t\tpriv = devm_kzalloc(\u0026mdiodev-\u003edev, sizeof(*priv), GFP_KERNEL);\n"
} |
| 7/2 | 2026/09/09 16:04 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 22268 output: 43 thoughts: 19 Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue: **Checking the Hardware Abstraction** Alright, so we're seeing something peculiar, and I need to methodically track down the source. Given the likely area of the problem, I know I should be looking closely at the hardware abstraction layer. I've already scrutinized the more obvious suspects, but it's time to dig a bit deeper. Specifically, I'm going to turn my attention to `mt7530-mmio.c`. This file almost certainly contains the low-level memory-mapped I/O definitions and functions for the MT7530 hardware. This is where the rubber meets the road, where the register reads and writes are defined, and the critical interaction with the hardware itself is handled. This is likely the best place to start. |
| 8/2 | 2026/09/09 16:04 | tool | read-file |
0mArgs:{
"File": "drivers/net/dsa/mt7530-mmio.c",
"FirstLine": 1,
"LineCount": 80
}Results: {
"Contents": " 1:\t// SPDX-License-Identifier: GPL-2.0-only\n 2:\t\n 3:\t#include \u003clinux/module.h\u003e\n 4:\t#include \u003clinux/platform_device.h\u003e\n 5:\t#include \u003clinux/regmap.h\u003e\n 6:\t#include \u003clinux/regulator/consumer.h\u003e\n 7:\t#include \u003clinux/reset.h\u003e\n 8:\t#include \u003cnet/dsa.h\u003e\n 9:\t\n 10:\t#include \"mt7530.h\"\n 11:\t\n 12:\tstatic const struct of_device_id mt7988_of_match[] = {\n 13:\t\t{ .compatible = \"airoha,an7583-switch\", .data = \u0026mt753x_table[ID_AN7583], },\n 14:\t\t{ .compatible = \"airoha,en7581-switch\", .data = \u0026mt753x_table[ID_EN7581], },\n 15:\t\t{ .compatible = \"econet,en751221-switch\", .data = \u0026mt753x_table[ID_EN751221], },\n 16:\t\t{ .compatible = \"econet,en7528-switch\", .data = \u0026mt753x_table[ID_EN7528], },\n 17:\t\t{ .compatible = \"mediatek,mt7988-switch\", .data = \u0026mt753x_table[ID_MT7988], },\n 18:\t\t{ /* sentinel */ }\n 19:\t};\n 20:\tMODULE_DEVICE_TABLE(of, mt7988_of_match);\n 21:\t\n 22:\tstatic const struct regmap_config sw_regmap_config = {\n 23:\t\t.name = \"switch\",\n 24:\t\t.reg_bits = 16,\n 25:\t\t.val_bits = 32,\n 26:\t\t.reg_stride = 4,\n 27:\t\t.max_register = MT7530_CREV,\n 28:\t};\n 29:\t\n 30:\tstatic int\n 31:\tmt7988_probe(struct platform_device *pdev)\n 32:\t{\n 33:\t\tstruct mt7530_priv *priv;\n 34:\t\tvoid __iomem *base_addr;\n 35:\t\tint ret;\n 36:\t\n 37:\t\tpriv = devm_kzalloc(\u0026pdev-\u003edev, sizeof(*priv), GFP_KERNEL);\n 38:\t\tif (!priv)\n 39:\t\t\treturn -ENOMEM;\n 40:\t\n 41:\t\tpriv-\u003ebus = NULL;\n 42:\t\tpriv-\u003edev = \u0026pdev-\u003edev;\n 43:\t\n 44:\t\tret = mt7530_probe_common(priv);\n 45:\t\tif (ret)\n 46:\t\t\treturn ret;\n 47:\t\n 48:\t\tpriv-\u003erstc = devm_reset_control_get(\u0026pdev-\u003edev, NULL);\n 49:\t\tif (IS_ERR(priv-\u003erstc)) {\n 50:\t\t\tdev_err(\u0026pdev-\u003edev, \"Couldn't get our reset line\\n\");\n 51:\t\t\treturn PTR_ERR(priv-\u003erstc);\n 52:\t\t}\n 53:\t\n 54:\t\tbase_addr = devm_platform_ioremap_resource(pdev, 0);\n 55:\t\tif (IS_ERR(base_addr)) {\n 56:\t\t\tdev_err(\u0026pdev-\u003edev, \"cannot request I/O memory space\\n\");\n 57:\t\t\treturn -ENXIO;\n 58:\t\t}\n 59:\t\n 60:\t\tpriv-\u003eregmap = devm_regmap_init_mmio(\u0026pdev-\u003edev, base_addr,\n 61:\t\t\t\t\t\t \u0026sw_regmap_config);\n 62:\t\tif (IS_ERR(priv-\u003eregmap))\n 63:\t\t\treturn PTR_ERR(priv-\u003eregmap);\n 64:\t\n 65:\t\tret = dsa_register_switch(priv-\u003eds);\n 66:\t\n 67:\t\tif (ret)\n 68:\t\t\treturn ret;\n 69:\t\n 70:\t\treturn mt7530_setup_mdio(priv);\n 71:\t}\n 72:\t\n 73:\tstatic void mt7988_remove(struct platform_device *pdev)\n 74:\t{\n 75:\t\tstruct mt7530_priv *priv = platform_get_drvdata(pdev);\n 76:\t\n 77:\t\tif (priv)\n 78:\t\t\tmt7530_remove_common(priv);\n 79:\t}\n 80:\t\n"
} |
| 9/2 | 2026/09/09 16:04 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 23756 output: 30 thoughts: 721 Thoughts: **My Assessment of MT7530 Driver Reachability for Fuzzing** Okay, let's break this down. `mt7530`... right, that's a DSA driver for MediaTek/EcoNet ethernet switches. And it's not just the MT7530; it covers a family of them, including MT7531, MT7621, and so on. These are specifically SoC-internal Ethernet switches, or MDIO/OF-probed external switches, found on specific ARM/MIPS MediaTek/EcoNet/Airoha SoCs. Now, the crucial question: can we even *reach* this code in a standard x86/amd64 QEMU environment? Can we probe or emulate these DSA switches without real hardware or a properly constructed device tree? Let me review the reachability criteria. The primary gate is reachability. The prompt emphasizes that fuzzing should only target code that *can* actually run in a virtualized environment – meaning software-emulated devices like USB gadgets, netdev, or tun/tap. If the code is structurally unreachable, it's a no-go for fuzzing, no matter how complex the logic. The examples of *unreachable* hardware are illuminating: vendor-specific PCIe switches, SmartNICs, GPU drivers that rely on physical ASICs/PCIe cards that QEMU doesn't emulate. Also, code paths specific to non-target architectures. So, how are these MDIO and MMIO DSA drivers probed? Can syzkaller probe them? The key is whether or not syzkaller or userspace can probe OF platform devices or MDIO devices on amd64, our target architecture. And here's where it gets interesting. On amd64, is there even a DT/OF or virtual MDIO bus or ACPI table instantiating an `econet,en751221` or `mediatek,mt7530`? I need to check the device matching. `mt7530-mdio` and `mt7530-mmio` seem to match only through `of_device_id` entries, specifically `mt7530_of_match[]` and `mt7988_of_match[]`. That's Device Tree territory. No platform device IDs, no ACPI device IDs, no PCI device IDs – strictly OF devices. And these devices are for specific MediaTek/EcoNet SoCs, the likes of EN751221 and MT7621, which are MIPS/ARM. The conclusion is clear: In our x86_64/amd64 QEMU/GCE setup, there's no Device Tree nodes for these MediaTek/Econet switches, and there's no physical hardware either. They're just not present. Now, a final, hopeful thought: Could these DSA switches be *mockable*? Could we reach them via some virtual interface like netdevsim or dsa_loop? I need to know if `dsa_loop` or mock drivers use `mt7530`. Let's see: `dsa_loop` is a fixed, dummy driver for testing DSA, using its own switch driver (`drivers/net/dsa/dsa_loop.c`). It does *not* utilize `mt7530.c`. So that's out. I'll verify this with grepper. |
| 10/2 | 2026/09/09 16:05 | tool | grepper |
0mArgs:{
"Expression": "mt753",
"PathPrefix": "drivers/net/dsa"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 1653 lines.\nUse more precise expression if possible.\n\ndrivers/net/dsa/Makefile=5=obj-$(CONFIG_NET_DSA_KS8995) \t+= ks8995.o\ndrivers/net/dsa/Makefile:6:obj-$(CONFIG_NET_DSA_MT7530)\t+= mt7530.o\ndrivers/net/dsa/Makefile:7:obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o\ndrivers/net/dsa/Makefile:8:obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o\ndrivers/net/dsa/Makefile-9-obj-$(CONFIG_NET_DSA_MT7628) += mt7628.o\n--\ndrivers/net/dsa/mt7530-mdio.c-15-\ndrivers/net/dsa/mt7530-mdio.c:16:#include \"mt7530.h\"\ndrivers/net/dsa/mt7530-mdio.c-17-\ndrivers/net/dsa/mt7530-mdio.c=18=static int\ndrivers/net/dsa/mt7530-mdio.c:19:mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)\ndrivers/net/dsa/mt7530-mdio.c-20-{\ndrivers/net/dsa/mt7530-mdio.c:21:\tstruct mt7530_priv *priv = context;\ndrivers/net/dsa/mt7530-mdio.c-22-\tstruct mii_bus *bus = priv-\u003ebus;\n--\ndrivers/net/dsa/mt7530-mdio.c=43=static int\ndrivers/net/dsa/mt7530-mdio.c:44:mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)\ndrivers/net/dsa/mt7530-mdio.c-45-{\ndrivers/net/dsa/mt7530-mdio.c:46:\tstruct mt7530_priv *priv = context;\ndrivers/net/dsa/mt7530-mdio.c-47-\tstruct mii_bus *bus = priv-\u003ebus;\n--\ndrivers/net/dsa/mt7530-mdio.c=76=static void\ndrivers/net/dsa/mt7530-mdio.c:77:mt7530_mdio_regmap_lock(void *mdio_lock)\ndrivers/net/dsa/mt7530-mdio.c-78-{\n--\ndrivers/net/dsa/mt7530-mdio.c=82=static void\ndrivers/net/dsa/mt7530-mdio.c:83:mt7530_mdio_regmap_unlock(void *mdio_lock)\ndrivers/net/dsa/mt7530-mdio.c-84-{\n--\ndrivers/net/dsa/mt7530-mdio.c-87-\ndrivers/net/dsa/mt7530-mdio.c:88:static const struct regmap_bus mt7530_regmap_bus = {\ndrivers/net/dsa/mt7530-mdio.c:89:\t.reg_write = mt7530_regmap_write,\ndrivers/net/dsa/mt7530-mdio.c:90:\t.reg_read = mt7530_regmap_read,\ndrivers/net/dsa/mt7530-mdio.c-91-};\n--\ndrivers/net/dsa/mt7530-mdio.c=93=static int\ndrivers/net/dsa/mt7530-mdio.c:94:mt7531_create_sgmii(struct mt7530_priv *priv)\ndrivers/net/dsa/mt7530-mdio.c-95-{\ndrivers/net/dsa/mt7530-mdio.c:96:\tstruct regmap_config *mt7531_pcs_config[2] = {};\ndrivers/net/dsa/mt7530-mdio.c-97-\tstruct phylink_pcs *pcs;\n--\ndrivers/net/dsa/mt7530-mdio.c-101-\tfor (i = priv-\u003ep5_sgmii ? 0 : 1; i \u003c 2; i++) {\ndrivers/net/dsa/mt7530-mdio.c:102:\t\tmt7531_pcs_config[i] = devm_kzalloc(priv-\u003edev,\ndrivers/net/dsa/mt7530-mdio.c-103-\t\t\t\t\t\t sizeof(struct regmap_config),\ndrivers/net/dsa/mt7530-mdio.c-104-\t\t\t\t\t\t GFP_KERNEL);\ndrivers/net/dsa/mt7530-mdio.c:105:\t\tif (!mt7531_pcs_config[i]) {\ndrivers/net/dsa/mt7530-mdio.c-106-\t\t\tret = -ENOMEM;\n--\ndrivers/net/dsa/mt7530-mdio.c-109-\ndrivers/net/dsa/mt7530-mdio.c:110:\t\tmt7531_pcs_config[i]-\u003ename = i ? \"port6\" : \"port5\";\ndrivers/net/dsa/mt7530-mdio.c:111:\t\tmt7531_pcs_config[i]-\u003ereg_bits = 16;\ndrivers/net/dsa/mt7530-mdio.c:112:\t\tmt7531_pcs_config[i]-\u003eval_bits = 32;\ndrivers/net/dsa/mt7530-mdio.c:113:\t\tmt7531_pcs_config[i]-\u003ereg_stride = 4;\ndrivers/net/dsa/mt7530-mdio.c:114:\t\tmt7531_pcs_config[i]-\u003ereg_base = MT7531_SGMII_REG_BASE(5 + i);\ndrivers/net/dsa/mt7530-mdio.c:115:\t\tmt7531_pcs_config[i]-\u003emax_register = 0x17c;\ndrivers/net/dsa/mt7530-mdio.c:116:\t\tmt7531_pcs_config[i]-\u003elock = mt7530_mdio_regmap_lock;\ndrivers/net/dsa/mt7530-mdio.c:117:\t\tmt7531_pcs_config[i]-\u003eunlock = mt7530_mdio_regmap_unlock;\ndrivers/net/dsa/mt7530-mdio.c:118:\t\tmt7531_pcs_config[i]-\u003elock_arg = \u0026priv-\u003ebus-\u003emdio_lock;\ndrivers/net/dsa/mt7530-mdio.c-119-\ndrivers/net/dsa/mt7530-mdio.c:120:\t\tregmap = devm_regmap_init(priv-\u003edev, \u0026mt7530_regmap_bus, priv,\ndrivers/net/dsa/mt7530-mdio.c:121:\t\t\t\t\t mt7531_pcs_config[i]);\ndrivers/net/dsa/mt7530-mdio.c-122-\t\tif (IS_ERR(regmap)) {\n--\ndrivers/net/dsa/mt7530-mdio.c-140-\ndrivers/net/dsa/mt7530-mdio.c:141:static const struct of_device_id mt7530_of_match[] = {\ndrivers/net/dsa/mt7530-mdio.c:142:\t{ .compatible = \"econet,en751221\", .data = \u0026mt753x_table[ID_EN751221_EXT], },\ndrivers/net/dsa/mt7530-mdio.c:143:\t{ .compatible = \"mediatek,mt7621\", .data = \u0026mt753x_table[ID_MT7621], },\ndrivers/net/dsa/mt7530-mdio.c:144:\t{ .compatible = \"mediatek,mt7530\", .data = \u0026mt753x_table[ID_MT7530], },\ndrivers/net/dsa/mt7530-mdio.c:145:\t{ .compatible = \"mediatek,mt7531\", .data = \u0026mt753x_table[ID_MT7531], },\ndrivers/net/dsa/mt7530-mdio.c-146-\t{ /* sentinel */ }\ndrivers/net/dsa/mt7530-mdio.c-147-};\ndrivers/net/dsa/mt7530-mdio.c:148:MODULE_DEVICE_TABLE(of, mt7530_of_match);\ndrivers/net/dsa/mt7530-mdio.c-149-\ndrivers/net/dsa/mt7530-mdio.c=150=static const struct regmap_config regmap_config = {\n--\ndrivers/net/dsa/mt7530-mdio.c-154-\t.max_register = MT7530_CREV,\ndrivers/net/dsa/mt7530-mdio.c:155:\t.lock = mt7530_mdio_regmap_lock,\ndrivers/net/dsa/mt7530-mdio.c:156:\t.unlock = mt7530_mdio_regmap_unlock,\ndrivers/net/dsa/mt7530-mdio.c-157-};\n--\ndrivers/net/dsa/mt7530-mdio.c=159=static int\ndrivers/net/dsa/mt7530-mdio.c:160:mt7530_probe(struct mdio_device *mdiodev)\ndrivers/net/dsa/mt7530-mdio.c-161-{\ndrivers/net/dsa/mt7530-mdio.c-162-\tstruct regmap_config rc = regmap_config;\ndrivers/net/dsa/mt7530-mdio.c:163:\tstruct mt7530_priv *priv;\ndrivers/net/dsa/mt7530-mdio.c-164-\tstruct device_node *dn;\n--\ndrivers/net/dsa/mt7530-mdio.c-176-\ndrivers/net/dsa/mt7530-mdio.c:177:\tret = mt7530_probe_common(priv);\ndrivers/net/dsa/mt7530-mdio.c-178-\tif (ret)\n--\ndrivers/net/dsa/mt7530-mdio.c-216-\trc.lock_arg = \u0026priv-\u003ebus-\u003emdio_lock;\ndrivers/net/dsa/mt7530-mdio.c:217:\tpriv-\u003eregmap = devm_regmap_init(priv-\u003edev, \u0026mt7530_regmap_bus,\ndrivers/net/dsa/mt7530-mdio.c-218-\t\t\t\t\tpriv, \u0026rc);\n--\ndrivers/net/dsa/mt7530-mdio.c-222-\tif (priv-\u003eid == ID_MT7531)\ndrivers/net/dsa/mt7530-mdio.c:223:\t\tpriv-\u003ecreate_sgmii = mt7531_create_sgmii;\ndrivers/net/dsa/mt7530-mdio.c-224-\n--\ndrivers/net/dsa/mt7530-mdio.c=228=static void\ndrivers/net/dsa/mt7530-mdio.c:229:mt7530_remove(struct mdio_device *mdiodev)\ndrivers/net/dsa/mt7530-mdio.c-230-{\ndrivers/net/dsa/mt7530-mdio.c:231:\tstruct mt7530_priv *priv = dev_get_drvdata(\u0026mdiodev-\u003edev);\ndrivers/net/dsa/mt7530-mdio.c-232-\tint ret = 0, i;\n--\ndrivers/net/dsa/mt7530-mdio.c-246-\ndrivers/net/dsa/mt7530-mdio.c:247:\tmt7530_remove_common(priv);\ndrivers/net/dsa/mt7530-mdio.c-248-\n--\ndrivers/net/dsa/mt7530-mdio.c-252-\ndrivers/net/dsa/mt7530-mdio.c:253:static void mt7530_shutdown(struct mdio_device *mdiodev)\ndrivers/net/dsa/mt7530-mdio.c-254-{\ndrivers/net/dsa/mt7530-mdio.c:255:\tstruct mt7530_priv *priv = dev_get_drvdata(\u0026mdiodev-\u003edev);\ndrivers/net/dsa/mt7530-mdio.c-256-\n--\ndrivers/net/dsa/mt7530-mdio.c-264-\ndrivers/net/dsa/mt7530-mdio.c:265:static struct mdio_driver mt7530_mdio_driver = {\ndrivers/net/dsa/mt7530-mdio.c:266:\t.probe = mt7530_probe,\ndrivers/net/dsa/mt7530-mdio.c:267:\t.remove = mt7530_remove,\ndrivers/net/dsa/mt7530-mdio.c:268:\t.shutdown = mt7530_shutdown,\ndrivers/net/dsa/mt7530-mdio.c-269-\t.mdiodrv.driver = {\ndrivers/net/dsa/mt7530-mdio.c:270:\t\t.name = \"mt7530-mdio\",\ndrivers/net/dsa/mt7530-mdio.c:271:\t\t.of_match_table = mt7530_of_match,\ndrivers/net/dsa/mt7530-mdio.c-272-\t},\n--\ndrivers/net/dsa/mt7530-mdio.c-274-\ndrivers/net/dsa/mt7530-mdio.c:275:mdio_module_driver(mt7530_mdio_driver);\ndrivers/net/dsa/mt7530-mdio.c-276-\n--\ndrivers/net/dsa/mt7530-mmio.c-9-\ndrivers/net/dsa/mt7530-mmio.c:10:#include \"mt7530.h\"\ndrivers/net/dsa/mt7530-mmio.c-11-\ndrivers/net/dsa/mt7530-mmio.c=12=static const struct of_device_id mt7988_of_match[] = {\ndrivers/net/dsa/mt7530-mmio.c:13:\t{ .compatible = \"airoha,an7583-switch\", .data = \u0026mt753x_table[ID_AN7583], },\ndrivers/net/dsa/mt7530-mmio.c:14:\t{ .compatible = \"airoha,en7581-switch\", .data = \u0026mt753x_table[ID_EN7581], },\ndrivers/net/dsa/mt7530-mmio.c:15:\t{ .compatible = \"econet,en751221-switch\", .data = \u0026mt753x_table[ID_EN751221], },\ndrivers/net/dsa/mt7530-mmio.c:16:\t{ .compatible = \"econet,en7528-switch\", .data = \u0026mt753x_table[ID_EN7528], },\ndrivers/net/dsa/mt7530-mmio.c:17:\t{ .compatible = \"mediatek,mt7988-switch\", .data = \u0026mt753x_table[ID_MT7988], },\ndrivers/net/dsa/mt7530-mmio.c-18-\t{ /* sentinel */ }\n--\ndrivers/net/dsa/mt7530-mmio.c=31=mt7988_probe(struct platform_device *pdev)\ndrivers/net/dsa/mt7530-mmio.c-32-{\ndrivers/net/dsa/mt7530-mmio.c:33:\tstruct mt7530_priv *priv;\ndrivers/net/dsa/mt7530-mmio.c-34-\tvoid __iomem *base_addr;\n--\ndrivers/net/dsa/mt7530-mmio.c-43-\ndrivers/net/dsa/mt7530-mmio.c:44:\tret = mt7530_probe_common(priv);\ndrivers/net/dsa/mt7530-mmio.c-45-\tif (ret)\n--\ndrivers/net/dsa/mt7530-mmio.c-69-\ndrivers/net/dsa/mt7530-mmio.c:70:\treturn mt7530_setup_mdio(priv);\ndrivers/net/dsa/mt7530-mmio.c-71-}\n--\ndrivers/net/dsa/mt7530-mmio.c=73=static void mt7988_remove(struct platform_device *pdev)\ndrivers/net/dsa/mt7530-mmio.c-74-{\ndrivers/net/dsa/mt7530-mmio.c:75:\tstruct mt7530_priv *priv = platform_get_drvdata(pdev);\ndrivers/net/dsa/mt7530-mmio.c-76-\ndrivers/net/dsa/mt7530-mmio.c-77-\tif (priv)\ndrivers/net/dsa/mt7530-mmio.c:78:\t\tmt7530_remove_common(priv);\ndrivers/net/dsa/mt7530-mmio.c-79-}\n--\ndrivers/net/dsa/mt7530-mmio.c=81=static void mt7988_shutdown(struct platform_device *pdev)\ndrivers/net/dsa/mt7530-mmio.c-82-{\ndrivers/net/dsa/mt7530-mmio.c:83:\tstruct mt7530_priv *priv = platform_get_drvdata(pdev);\ndrivers/net/dsa/mt7530-mmio.c-84-\n--\ndrivers/net/dsa/mt7530-mmio.c=93=static struct platform_driver mt7988_platform_driver = {\n--\ndrivers/net/dsa/mt7530-mmio.c-97-\t.driver = {\ndrivers/net/dsa/mt7530-mmio.c:98:\t\t.name = \"mt7530-mmio\",\ndrivers/net/dsa/mt7530-mmio.c-99-\t\t.of_match_table = mt7988_of_match,\n--\ndrivers/net/dsa/mt7530.c-25-\ndrivers/net/dsa/mt7530.c:26:#include \"mt7530.h\"\ndrivers/net/dsa/mt7530.c-27-\n--\ndrivers/net/dsa/mt7530.c-30-\ndrivers/net/dsa/mt7530.c:31:static struct mt753x_pcs *pcs_to_mt753x_pcs(struct phylink_pcs *pcs)\ndrivers/net/dsa/mt7530.c-32-{\ndrivers/net/dsa/mt7530.c:33:\treturn container_of(pcs, struct mt753x_pcs, pcs);\ndrivers/net/dsa/mt7530.c-34-}\n--\ndrivers/net/dsa/mt7530.c-36-/* String, offset, and register size in bytes if different from 4 bytes */\ndrivers/net/dsa/mt7530.c:37:static const struct mt7530_mib_desc mt7530_mib[] = {\ndrivers/net/dsa/mt7530.c-38-\tMIB_DESC(1, MT7530_PORT_MIB_TX_DROP, \"TxDrop\"),\n--\ndrivers/net/dsa/mt7530.c=49=static int\ndrivers/net/dsa/mt7530.c:50:mt753x_ctrl_phy_addr(struct mt7530_priv *priv)\ndrivers/net/dsa/mt7530.c-51-{\n--\ndrivers/net/dsa/mt7530.c=62=static void\ndrivers/net/dsa/mt7530.c:63:mt7530_mutex_lock(struct mt7530_priv *priv)\ndrivers/net/dsa/mt7530.c-64-{\n--\ndrivers/net/dsa/mt7530.c=69=static void\ndrivers/net/dsa/mt7530.c:70:mt7530_mutex_unlock(struct mt7530_priv *priv)\ndrivers/net/dsa/mt7530.c-71-{\n--\ndrivers/net/dsa/mt7530.c=76=static void\ndrivers/net/dsa/mt7530.c:77:core_write(struct mt7530_priv *priv, u32 reg, u32 val)\ndrivers/net/dsa/mt7530.c-78-{\ndrivers/net/dsa/mt7530.c:79:\tint ctl_phy = mt753x_ctrl_phy_addr(priv);\ndrivers/net/dsa/mt7530.c-80-\tstruct mii_bus *bus = priv-\u003ebus;\n--\ndrivers/net/dsa/mt7530.c-88-\ndrivers/net/dsa/mt7530.c:89:\tmt7530_mutex_lock(priv);\ndrivers/net/dsa/mt7530.c-90-\n--\ndrivers/net/dsa/mt7530.c-112-\ndrivers/net/dsa/mt7530.c:113:\tmt7530_mutex_unlock(priv);\ndrivers/net/dsa/mt7530.c-114-}\n--\ndrivers/net/dsa/mt7530.c=116=static void\ndrivers/net/dsa/mt7530.c:117:core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)\ndrivers/net/dsa/mt7530.c-118-{\ndrivers/net/dsa/mt7530.c:119:\tint ctl_phy = mt753x_ctrl_phy_addr(priv);\ndrivers/net/dsa/mt7530.c-120-\tstruct mii_bus *bus = priv-\u003ebus;\n--\ndrivers/net/dsa/mt7530.c-129-\ndrivers/net/dsa/mt7530.c:130:\tmt7530_mutex_lock(priv);\ndrivers/net/dsa/mt7530.c-131-\n--\ndrivers/net/dsa/mt7530.c-161-\ndrivers/net/dsa/mt7530.c:162:\tmt7530_mutex_unlock(priv);\ndrivers/net/dsa/mt7530.c-163-}\n--\ndrivers/net/dsa/mt7530.c=165=static void\ndrivers/net/dsa/mt7530.c:166:core_set(struct mt7530_priv *priv, u32 reg, u32 val)\ndrivers/net/dsa/mt7530.c-167-{\n--\ndrivers/net/dsa/mt7530.c=171=static void\ndrivers/net/dsa/mt7530.c:172:core_clear(struct mt7530_priv *priv, u32 reg, u32 val)\ndrivers/net/dsa/mt7530.c-173-{\n--\ndrivers/net/dsa/mt7530.c=177=static int\ndrivers/net/dsa/mt7530.c:178:mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)\ndrivers/net/dsa/mt7530.c-179-{\n--\ndrivers/net/dsa/mt7530.c-210-\ndrivers/net/dsa/mt7530.c:211:static void mt7530_port_fast_age(struct dsa_switch *ds, int port)\ndrivers/net/dsa/mt7530.c-212-{\ndrivers/net/dsa/mt7530.c:213:\tstruct mt7530_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/mt7530.c-214-\tu32 val;\n--\ndrivers/net/dsa/mt7530.c=231=static void\ndrivers/net/dsa/mt7530.c:232:mt7530_fdb_read(struct mt7530_priv *priv, struct mt7530_fdb *fdb)\ndrivers/net/dsa/mt7530.c-233-{\n--\ndrivers/net/dsa/mt7530.c=258=static void\ndrivers/net/dsa/mt7530.c:259:mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,\ndrivers/net/dsa/mt7530.c-260-\t\t u8 port_mask, const u8 *mac,\n--\ndrivers/net/dsa/mt7530.c-288-/* Set up switch core clock for MT7530 */\ndrivers/net/dsa/mt7530.c:289:static void mt7530_pll_setup(struct mt7530_priv *priv)\ndrivers/net/dsa/mt7530.c-290-{\n--\ndrivers/net/dsa/mt7530.c=317=static struct dsa_port *\ndrivers/net/dsa/mt7530.c:318:mt753x_preferred_default_local_cpu_port(struct dsa_switch *ds)\ndrivers/net/dsa/mt7530.c-319-{\n--\ndrivers/net/dsa/mt7530.c=329=static void\ndrivers/net/dsa/mt7530.c:330:mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)\ndrivers/net/dsa/mt7530.c-331-{\ndrivers/net/dsa/mt7530.c:332:\tstruct mt7530_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/mt7530.c-333-\tu32 ncpo1, ssc_delta, xtal;\n--\ndrivers/net/dsa/mt7530.c=391=static void\ndrivers/net/dsa/mt7530.c:392:mt7531_pll_setup(struct mt7530_priv *priv)\ndrivers/net/dsa/mt7530.c-393-{\ndrivers/net/dsa/mt7530.c:394:\tenum mt7531_xtal_fsel xtal;\ndrivers/net/dsa/mt7530.c-395-\tu32 top_sig;\n--\ndrivers/net/dsa/mt7530.c=479=static bool\ndrivers/net/dsa/mt7530.c:480:en751221_trgmii_cal_ok(struct mt7530_priv *rx, u32 reg, int chan, int i)\ndrivers/net/dsa/mt7530.c-481-{\n--\ndrivers/net/dsa/mt7530.c=493=static void\ndrivers/net/dsa/mt7530.c:494:en751221_trgmii_calibrate_direction(struct mt7530_priv *tx,\ndrivers/net/dsa/mt7530.c:495:\t\t\t\t struct mt7530_priv *rx,\ndrivers/net/dsa/mt7530.c-496-\t\t\t\t u8 *default_taps)\n--\ndrivers/net/dsa/mt7530.c=573=static void\ndrivers/net/dsa/mt7530.c:574:en751221_set_tx_drive(struct mt7530_priv *priv, u8 drvp, u8 drvn, u8 clk_drvp,\ndrivers/net/dsa/mt7530.c-575-\t\t u8 clk_drvn)\n--\ndrivers/net/dsa/mt7530.c=589=static void\ndrivers/net/dsa/mt7530.c:590:en751221_trgmii_pair_setup(struct mt7530_priv *ext, int ext_port,\ndrivers/net/dsa/mt7530.c:591:\t\t\t struct mt7530_priv *ondie, int ondie_port)\ndrivers/net/dsa/mt7530.c-592-{\n--\ndrivers/net/dsa/mt7530.c=675=static void\ndrivers/net/dsa/mt7530.c:676:mt7530_cal_interswitch_trgmii(struct dsa_port *dp)\ndrivers/net/dsa/mt7530.c-677-{\n--\ndrivers/net/dsa/mt7530.c-680-\tstruct dsa_port *peer_dp;\ndrivers/net/dsa/mt7530.c:681:\tstruct mt7530_priv *peer;\ndrivers/net/dsa/mt7530.c:682:\tstruct mt7530_priv *priv;\ndrivers/net/dsa/mt7530.c-683-\tstruct dsa_link *dl;\n--\ndrivers/net/dsa/mt7530.c=724=static void\ndrivers/net/dsa/mt7530.c:725:mt7530_mib_reset(struct dsa_switch *ds)\ndrivers/net/dsa/mt7530.c-726-{\ndrivers/net/dsa/mt7530.c:727:\tstruct mt7530_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/mt7530.c-728-\n--\ndrivers/net/dsa/mt7530.c-732-\ndrivers/net/dsa/mt7530.c:733:static int mt7530_phy_read_c22(struct mt7530_priv *priv, int port, int regnum)\ndrivers/net/dsa/mt7530.c-734-{\n--\ndrivers/net/dsa/mt7530.c-737-\ndrivers/net/dsa/mt7530.c:738:static int mt7530_phy_write_c22(struct mt7530_priv *priv, int port, int regnum,\ndrivers/net/dsa/mt7530.c-739-\t\t\t\tu16 val)\n--\ndrivers/net/dsa/mt7530.c-743-\ndrivers/net/dsa/mt7530.c:744:static int mt7530_phy_read_c45(struct mt7530_priv *priv, int port,\ndrivers/net/dsa/mt7530.c-745-\t\t\t int devad, int regnum)\n--\ndrivers/net/dsa/mt7530.c-749-\ndrivers/net/dsa/mt7530.c:750:static int mt7530_phy_write_c45(struct mt7530_priv *priv, int port, int devad,\ndrivers/net/dsa/mt7530.c-751-\t\t\t\tint regnum, u16 val)\n--\ndrivers/net/dsa/mt7530.c=756=static int\ndrivers/net/dsa/mt7530.c:757:mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,\ndrivers/net/dsa/mt7530.c-758-\t\t\tint regnum)\n--\ndrivers/net/dsa/mt7530.c=807=static int\ndrivers/net/dsa/mt7530.c:808:mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,\ndrivers/net/dsa/mt7530.c-809-\t\t\t int regnum, u16 data)\n--\ndrivers/net/dsa/mt7530.c=857=static int\ndrivers/net/dsa/mt7530.c:858:mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)\ndrivers/net/dsa/mt7530.c-859-{\n--\ndrivers/net/dsa/mt7530.c=894=static int\ndrivers/net/dsa/mt7530.c:895:mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,\ndrivers/net/dsa/mt7530.c-896-\t\t\t u16 data)\n--\ndrivers/net/dsa/mt7530.c=931=static int\ndrivers/net/dsa/mt7530.c:932:mt753x_phy_read_c22(struct mii_bus *bus, int port, int regnum)\ndrivers/net/dsa/mt7530.c-933-{\ndrivers/net/dsa/mt7530.c:934:\tstruct mt7530_priv *priv = bus-\u003epriv;\ndrivers/net/dsa/mt7530.c-935-\n--\ndrivers/net/dsa/mt7530.c=939=static int\ndrivers/net/dsa/mt7530.c:940:mt753x_phy_read_c45(struct mii_bus *bus, int port, int devad, int regnum)\ndrivers/net/dsa/mt7530.c-941-{\ndrivers/net/dsa/mt7530.c:942:\tstruct mt7530_priv *priv = bus-\u003epriv;\ndrivers/net/dsa/mt7530.c-943-\n--\ndrivers/net/dsa/mt7530.c=947=static int\ndrivers/net/dsa/mt7530.c:948:mt753x_phy_write_c22(struct mii_bus *bus, int port, int regnum, u16 val)\ndrivers/net/dsa/mt7530.c-949-{\ndrivers/net/dsa/mt7530.c:950:\tstruct mt7530_priv *priv = bus-\u003epriv;\ndrivers/net/dsa/mt7530.c-951-\n--\ndrivers/net/dsa/mt7530.c=955=static int\ndrivers/net/dsa/mt7530.c:956:mt753x_phy_write_c45(struct mii_bus *bus, int port, int devad, int regnum,\ndrivers/net/dsa/mt7530.c-957-\t\t u16 val)\ndrivers/net/dsa/mt7530.c-958-{\ndrivers/net/dsa/mt7530.c:959:\tstruct mt7530_priv *priv = bus-\u003epriv;\ndrivers/net/dsa/mt7530.c-960-\n--\ndrivers/net/dsa/mt7530.c=964=static void\ndrivers/net/dsa/mt7530.c:965:mt7530_get_strings(struct dsa_switch *ds, int port, u32 stringset,\ndrivers/net/dsa/mt7530.c-966-\t\t uint8_t *data)\n--\ndrivers/net/dsa/mt7530.c-972-\ndrivers/net/dsa/mt7530.c:973:\tfor (i = 0; i \u003c ARRAY_SIZE(mt7530_mib); i++)\ndrivers/net/dsa/mt7530.c:974:\t\tethtool_puts(\u0026data, mt7530_mib[i].name);\ndrivers/net/dsa/mt7530.c-975-}\n--\ndrivers/net/dsa/mt7530.c=977=static void\ndrivers/net/dsa/mt7530.c:978:mt7530_read_port_stats(struct mt7530_priv *priv, int port,\ndrivers/net/dsa/mt7530.c-979-\t\t u32 offset, u8 size, uint64_t *data)\n--\ndrivers/net/dsa/mt7530.c=992=static void\ndrivers/net/dsa/mt7530.c:993:mt7530_get_ethtool_stats(struct dsa_switch *ds, int port,\ndrivers/net/dsa/mt7530.c-994-\t\t\t uint64_t *data)\ndrivers/net/dsa/mt7530.c-995-{\ndrivers/net/dsa/mt7530.c:996:\tstruct mt7530_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/mt7530.c:997:\tconst struct mt7530_mib_desc *mib;\ndrivers/net/dsa/mt7530.c-998-\tint i;\ndrivers/net/dsa/mt7530.c-999-\ndrivers/net/dsa/mt7530.c:1000:\tfor (i = 0; i \u003c ARRAY_SIZE(mt7530_mib); i++) {\ndrivers/net/dsa/mt7530.c:1001:\t\tmib = \u0026mt7530_mib[i];\ndrivers/net/dsa/mt7530.c-1002-\ndrivers/net/dsa/mt7530.c:1003:\t\tmt7530_read_port_stats(priv, port, mib-\u003eoffset, mib-\u003esize,\ndrivers/net/dsa/mt7530.c-1004-\t\t\t\t data + i);\n--\ndrivers/net/dsa/mt7530.c=1008=static int\ndrivers/net/dsa/mt7530.c:1009:mt7530_get_sset_count(struct dsa_switch *ds, int port, int sset)\ndrivers/net/dsa/mt7530.c-1010-{\n--\ndrivers/net/dsa/mt7530.c-1013-\ndrivers/net/dsa/mt7530.c:1014:\treturn ARRAY_SIZE(mt7530_mib);\ndrivers/net/dsa/mt7530.c-1015-}\ndrivers/net/dsa/mt7530.c-1016-\ndrivers/net/dsa/mt7530.c:1017:static void mt7530_get_eth_mac_stats(struct dsa_switch *ds, int port,\ndrivers/net/dsa/mt7530.c-1018-\t\t\t\t struct ethtool_eth_mac_stats *mac_stats)\ndrivers/net/dsa/mt7530.c-1019-{\ndrivers/net/dsa/mt7530.c:1020:\tstruct mt7530_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/mt7530.c-1021-\n--\ndrivers/net/dsa/mt7530.c-1026-\t */\ndrivers/net/dsa/mt7530.c:1027:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_UNICAST, 1,\ndrivers/net/dsa/mt7530.c-1028-\t\t\t \u0026mac_stats-\u003eFramesTransmittedOK);\ndrivers/net/dsa/mt7530.c-1029-\ndrivers/net/dsa/mt7530.c:1030:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_SINGLE_COLLISION, 1,\ndrivers/net/dsa/mt7530.c-1031-\t\t\t \u0026mac_stats-\u003eSingleCollisionFrames);\ndrivers/net/dsa/mt7530.c-1032-\ndrivers/net/dsa/mt7530.c:1033:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_MULTIPLE_COLLISION, 1,\ndrivers/net/dsa/mt7530.c-1034-\t\t\t \u0026mac_stats-\u003eMultipleCollisionFrames);\ndrivers/net/dsa/mt7530.c-1035-\ndrivers/net/dsa/mt7530.c:1036:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_UNICAST, 1,\ndrivers/net/dsa/mt7530.c-1037-\t\t\t \u0026mac_stats-\u003eFramesReceivedOK);\ndrivers/net/dsa/mt7530.c-1038-\ndrivers/net/dsa/mt7530.c:1039:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_BYTES, 2,\ndrivers/net/dsa/mt7530.c-1040-\t\t\t \u0026mac_stats-\u003eOctetsTransmittedOK);\ndrivers/net/dsa/mt7530.c-1041-\ndrivers/net/dsa/mt7530.c:1042:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_ALIGN_ERR, 1,\ndrivers/net/dsa/mt7530.c-1043-\t\t\t \u0026mac_stats-\u003eAlignmentErrors);\ndrivers/net/dsa/mt7530.c-1044-\ndrivers/net/dsa/mt7530.c:1045:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_DEFERRED, 1,\ndrivers/net/dsa/mt7530.c-1046-\t\t\t \u0026mac_stats-\u003eFramesWithDeferredXmissions);\ndrivers/net/dsa/mt7530.c-1047-\ndrivers/net/dsa/mt7530.c:1048:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_LATE_COLLISION, 1,\ndrivers/net/dsa/mt7530.c-1049-\t\t\t \u0026mac_stats-\u003eLateCollisions);\ndrivers/net/dsa/mt7530.c-1050-\ndrivers/net/dsa/mt7530.c:1051:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_EXCESSIVE_COLLISION, 1,\ndrivers/net/dsa/mt7530.c-1052-\t\t\t \u0026mac_stats-\u003eFramesAbortedDueToXSColls);\ndrivers/net/dsa/mt7530.c-1053-\ndrivers/net/dsa/mt7530.c:1054:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_BYTES, 2,\ndrivers/net/dsa/mt7530.c-1055-\t\t\t \u0026mac_stats-\u003eOctetsReceivedOK);\ndrivers/net/dsa/mt7530.c-1056-\ndrivers/net/dsa/mt7530.c:1057:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_MULTICAST, 1,\ndrivers/net/dsa/mt7530.c-1058-\t\t\t \u0026mac_stats-\u003eMulticastFramesXmittedOK);\ndrivers/net/dsa/mt7530.c-1059-\tmac_stats-\u003eFramesTransmittedOK += mac_stats-\u003eMulticastFramesXmittedOK;\ndrivers/net/dsa/mt7530.c:1060:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_BROADCAST, 1,\ndrivers/net/dsa/mt7530.c-1061-\t\t\t \u0026mac_stats-\u003eBroadcastFramesXmittedOK);\n--\ndrivers/net/dsa/mt7530.c-1063-\ndrivers/net/dsa/mt7530.c:1064:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_MULTICAST, 1,\ndrivers/net/dsa/mt7530.c-1065-\t\t\t \u0026mac_stats-\u003eMulticastFramesReceivedOK);\ndrivers/net/dsa/mt7530.c-1066-\tmac_stats-\u003eFramesReceivedOK += mac_stats-\u003eMulticastFramesReceivedOK;\ndrivers/net/dsa/mt7530.c:1067:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_BROADCAST, 1,\ndrivers/net/dsa/mt7530.c-1068-\t\t\t \u0026mac_stats-\u003eBroadcastFramesReceivedOK);\n--\ndrivers/net/dsa/mt7530.c-1071-\ndrivers/net/dsa/mt7530.c:1072:static const struct ethtool_rmon_hist_range mt7530_rmon_ranges[] = {\ndrivers/net/dsa/mt7530.c-1073-\t{ 0, 64 },\n--\ndrivers/net/dsa/mt7530.c-1081-\ndrivers/net/dsa/mt7530.c:1082:static void mt7530_get_rmon_stats(struct dsa_switch *ds, int port,\ndrivers/net/dsa/mt7530.c-1083-\t\t\t\t struct ethtool_rmon_stats *rmon_stats,\n--\ndrivers/net/dsa/mt7530.c-1085-{\ndrivers/net/dsa/mt7530.c:1086:\tstruct mt7530_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/mt7530.c-1087-\ndrivers/net/dsa/mt7530.c:1088:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_UNDER_SIZE_ERR, 1,\ndrivers/net/dsa/mt7530.c-1089-\t\t\t \u0026rmon_stats-\u003eundersize_pkts);\ndrivers/net/dsa/mt7530.c:1090:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_OVER_SZ_ERR, 1,\ndrivers/net/dsa/mt7530.c-1091-\t\t\t \u0026rmon_stats-\u003eoversize_pkts);\ndrivers/net/dsa/mt7530.c:1092:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_FRAG_ERR, 1,\ndrivers/net/dsa/mt7530.c-1093-\t\t\t \u0026rmon_stats-\u003efragments);\ndrivers/net/dsa/mt7530.c:1094:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_JABBER_ERR, 1,\ndrivers/net/dsa/mt7530.c-1095-\t\t\t \u0026rmon_stats-\u003ejabbers);\ndrivers/net/dsa/mt7530.c-1096-\ndrivers/net/dsa/mt7530.c:1097:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PKT_SZ_64, 1,\ndrivers/net/dsa/mt7530.c-1098-\t\t\t \u0026rmon_stats-\u003ehist[0]);\ndrivers/net/dsa/mt7530.c:1099:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PKT_SZ_65_TO_127, 1,\ndrivers/net/dsa/mt7530.c-1100-\t\t\t \u0026rmon_stats-\u003ehist[1]);\ndrivers/net/dsa/mt7530.c:1101:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PKT_SZ_128_TO_255, 1,\ndrivers/net/dsa/mt7530.c-1102-\t\t\t \u0026rmon_stats-\u003ehist[2]);\ndrivers/net/dsa/mt7530.c:1103:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PKT_SZ_256_TO_511, 1,\ndrivers/net/dsa/mt7530.c-1104-\t\t\t \u0026rmon_stats-\u003ehist[3]);\ndrivers/net/dsa/mt7530.c:1105:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PKT_SZ_512_TO_1023, 1,\ndrivers/net/dsa/mt7530.c-1106-\t\t\t \u0026rmon_stats-\u003ehist[4]);\ndrivers/net/dsa/mt7530.c:1107:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_PKT_SZ_1024_TO_MAX, 1,\ndrivers/net/dsa/mt7530.c-1108-\t\t\t \u0026rmon_stats-\u003ehist[5]);\ndrivers/net/dsa/mt7530.c-1109-\ndrivers/net/dsa/mt7530.c:1110:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PKT_SZ_64, 1,\ndrivers/net/dsa/mt7530.c-1111-\t\t\t \u0026rmon_stats-\u003ehist_tx[0]);\ndrivers/net/dsa/mt7530.c:1112:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PKT_SZ_65_TO_127, 1,\ndrivers/net/dsa/mt7530.c-1113-\t\t\t \u0026rmon_stats-\u003ehist_tx[1]);\ndrivers/net/dsa/mt7530.c:1114:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PKT_SZ_128_TO_255, 1,\ndrivers/net/dsa/mt7530.c-1115-\t\t\t \u0026rmon_stats-\u003ehist_tx[2]);\ndrivers/net/dsa/mt7530.c:1116:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PKT_SZ_256_TO_511, 1,\ndrivers/net/dsa/mt7530.c-1117-\t\t\t \u0026rmon_stats-\u003ehist_tx[3]);\ndrivers/net/dsa/mt7530.c:1118:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PKT_SZ_512_TO_1023, 1,\ndrivers/net/dsa/mt7530.c-1119-\t\t\t \u0026rmon_stats-\u003ehist_tx[4]);\ndrivers/net/dsa/mt7530.c:1120:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_PKT_SZ_1024_TO_MAX, 1,\ndrivers/net/dsa/mt7530.c-1121-\t\t\t \u0026rmon_stats-\u003ehist_tx[5]);\ndrivers/net/dsa/mt7530.c-1122-\ndrivers/net/dsa/mt7530.c:1123:\t*ranges = mt7530_rmon_ranges;\ndrivers/net/dsa/mt7530.c-1124-}\ndrivers/net/dsa/mt7530.c-1125-\ndrivers/net/dsa/mt7530.c:1126:static void mt7530_read_port_stats64(struct mt7530_priv *priv, int port,\ndrivers/net/dsa/mt7530.c-1127-\t\t\t\t struct rtnl_link_stats64 *storage)\n--\ndrivers/net/dsa/mt7530.c-1135-\t */\n\n"
} |
| 11/2 | 2026/09/09 16:05 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 39893 output: 25 thoughts: 95 Thoughts: Okay, here's my thought process on this. **Investigating the `mt7530` Driver** Alright, so `mt7530`... right, that's a DSA (Distributed Switch Architecture) driver. Specifically for that MediaTek or EcoNet switch hardware. The question is, can I trigger or probe that thing without the actual hardware in the system? You know, the kind of situation where you might get a false positive or an unexpected loading. Therefore, the next logical step is to do a thorough investigation. A deep dive is needed to see if the driver is somehow being referenced or called without the expected hardware conditions being met. I need to comb through the entire kernel source tree, looking for any instances of either `mt7530` or `mt753x` being mentioned or used. Any clues will be useful. |
| 12/2 | 2026/09/09 16:05 | tool | grepper |
0mArgs:{
"Expression": "mt7530|mt753x"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 1632 lines.\nUse more precise expression if possible.\n\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-3----\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml:4:$id: http://devicetree.org/schemas/net/dsa/mediatek,mt7530.yaml#\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-5-$schema: http://devicetree.org/meta-schemas/core.yaml#\n--\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml=89=properties:\n--\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-93- Standalone MT7530 and multi-chip module MT7530 in MT7623AI SoC\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml:94: const: mediatek,mt7530\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-95-\n--\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml=227=$defs:\n--\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-239-\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml:240: mt7530-passthrough-dsa-port:\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-241- patternProperties:\n--\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-253-\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml:254: mt7530-dsa-port:\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-255- patternProperties:\n--\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml=308=allOf:\n--\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-326- compatible:\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml:327: const: mediatek,mt7530\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-328- then:\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml:329: $ref: \"#/$defs/mt7530-dsa-port\"\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-330- required:\n--\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-348- then:\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml:349: $ref: \"#/$defs/mt7530-dsa-port\"\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-350- required:\n--\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-374- then:\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml:375: $ref: \"#/$defs/mt7530-passthrough-dsa-port\"\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-376- required:\n--\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml=381=examples:\n--\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-390- switch@1f {\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml:391: compatible = \"mediatek,mt7530\";\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-392- reg = \u003c0x1f\u003e;\n--\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-451- switch@1f {\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml:452: compatible = \"mediatek,mt7530\";\nDocumentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml-453- reg = \u003c0x1f\u003e;\n--\nMAINTAINERS=16821=S:\tMaintained\nMAINTAINERS:16822:F:\tdrivers/net/dsa/mt7530-mdio.c\nMAINTAINERS:16823:F:\tdrivers/net/dsa/mt7530-mmio.c\nMAINTAINERS:16824:F:\tdrivers/net/dsa/mt7530.*\nMAINTAINERS-16825-F:\tnet/dsa/tag_mtk.c\n--\narch/arm/boot/dts/mediatek/mt7623a.dtsi=50=\t\tswitch0: switch@1f {\narch/arm/boot/dts/mediatek/mt7623a.dtsi:51:\t\t\tcompatible = \"mediatek,mt7530\";\narch/arm/boot/dts/mediatek/mt7623a.dtsi-52-\t\t\treg = \u003c0x1f\u003e;\n--\narch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts=203=\t\tswitch@1f {\narch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts:204:\t\t\tcompatible = \"mediatek,mt7530\";\narch/arm/boot/dts/mediatek/mt7623n-bananapi-bpi-r2.dts-205-\t\t\treg = \u003c0x1f\u003e;\n--\narch/arm/boot/dts/mediatek/mt7623n-rfb-emmc.dts=188=\t\tswitch@1f {\narch/arm/boot/dts/mediatek/mt7623n-rfb-emmc.dts:189:\t\t\tcompatible = \"mediatek,mt7530\";\narch/arm/boot/dts/mediatek/mt7623n-rfb-emmc.dts-190-\t\t\treg = \u003c0x1f\u003e;\n--\ndrivers/net/dsa/Makefile=5=obj-$(CONFIG_NET_DSA_KS8995) \t+= ks8995.o\ndrivers/net/dsa/Makefile:6:obj-$(CONFIG_NET_DSA_MT7530)\t+= mt7530.o\ndrivers/net/dsa/Makefile:7:obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o\ndrivers/net/dsa/Makefile:8:obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o\ndrivers/net/dsa/Makefile-9-obj-$(CONFIG_NET_DSA_MT7628) += mt7628.o\n--\ndrivers/net/dsa/mt7530-mdio.c-15-\ndrivers/net/dsa/mt7530-mdio.c:16:#include \"mt7530.h\"\ndrivers/net/dsa/mt7530-mdio.c-17-\ndrivers/net/dsa/mt7530-mdio.c=18=static int\ndrivers/net/dsa/mt7530-mdio.c:19:mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)\ndrivers/net/dsa/mt7530-mdio.c-20-{\ndrivers/net/dsa/mt7530-mdio.c:21:\tstruct mt7530_priv *priv = context;\ndrivers/net/dsa/mt7530-mdio.c-22-\tstruct mii_bus *bus = priv-\u003ebus;\n--\ndrivers/net/dsa/mt7530-mdio.c=43=static int\ndrivers/net/dsa/mt7530-mdio.c:44:mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)\ndrivers/net/dsa/mt7530-mdio.c-45-{\ndrivers/net/dsa/mt7530-mdio.c:46:\tstruct mt7530_priv *priv = context;\ndrivers/net/dsa/mt7530-mdio.c-47-\tstruct mii_bus *bus = priv-\u003ebus;\n--\ndrivers/net/dsa/mt7530-mdio.c=76=static void\ndrivers/net/dsa/mt7530-mdio.c:77:mt7530_mdio_regmap_lock(void *mdio_lock)\ndrivers/net/dsa/mt7530-mdio.c-78-{\n--\ndrivers/net/dsa/mt7530-mdio.c=82=static void\ndrivers/net/dsa/mt7530-mdio.c:83:mt7530_mdio_regmap_unlock(void *mdio_lock)\ndrivers/net/dsa/mt7530-mdio.c-84-{\n--\ndrivers/net/dsa/mt7530-mdio.c-87-\ndrivers/net/dsa/mt7530-mdio.c:88:static const struct regmap_bus mt7530_regmap_bus = {\ndrivers/net/dsa/mt7530-mdio.c:89:\t.reg_write = mt7530_regmap_write,\ndrivers/net/dsa/mt7530-mdio.c:90:\t.reg_read = mt7530_regmap_read,\ndrivers/net/dsa/mt7530-mdio.c-91-};\n--\ndrivers/net/dsa/mt7530-mdio.c=93=static int\ndrivers/net/dsa/mt7530-mdio.c:94:mt7531_create_sgmii(struct mt7530_priv *priv)\ndrivers/net/dsa/mt7530-mdio.c-95-{\n--\ndrivers/net/dsa/mt7530-mdio.c-115-\t\tmt7531_pcs_config[i]-\u003emax_register = 0x17c;\ndrivers/net/dsa/mt7530-mdio.c:116:\t\tmt7531_pcs_config[i]-\u003elock = mt7530_mdio_regmap_lock;\ndrivers/net/dsa/mt7530-mdio.c:117:\t\tmt7531_pcs_config[i]-\u003eunlock = mt7530_mdio_regmap_unlock;\ndrivers/net/dsa/mt7530-mdio.c-118-\t\tmt7531_pcs_config[i]-\u003elock_arg = \u0026priv-\u003ebus-\u003emdio_lock;\ndrivers/net/dsa/mt7530-mdio.c-119-\ndrivers/net/dsa/mt7530-mdio.c:120:\t\tregmap = devm_regmap_init(priv-\u003edev, \u0026mt7530_regmap_bus, priv,\ndrivers/net/dsa/mt7530-mdio.c-121-\t\t\t\t\t mt7531_pcs_config[i]);\n--\ndrivers/net/dsa/mt7530-mdio.c-140-\ndrivers/net/dsa/mt7530-mdio.c:141:static const struct of_device_id mt7530_of_match[] = {\ndrivers/net/dsa/mt7530-mdio.c:142:\t{ .compatible = \"econet,en751221\", .data = \u0026mt753x_table[ID_EN751221_EXT], },\ndrivers/net/dsa/mt7530-mdio.c:143:\t{ .compatible = \"mediatek,mt7621\", .data = \u0026mt753x_table[ID_MT7621], },\ndrivers/net/dsa/mt7530-mdio.c:144:\t{ .compatible = \"mediatek,mt7530\", .data = \u0026mt753x_table[ID_MT7530], },\ndrivers/net/dsa/mt7530-mdio.c:145:\t{ .compatible = \"mediatek,mt7531\", .data = \u0026mt753x_table[ID_MT7531], },\ndrivers/net/dsa/mt7530-mdio.c-146-\t{ /* sentinel */ }\ndrivers/net/dsa/mt7530-mdio.c-147-};\ndrivers/net/dsa/mt7530-mdio.c:148:MODULE_DEVICE_TABLE(of, mt7530_of_match);\ndrivers/net/dsa/mt7530-mdio.c-149-\ndrivers/net/dsa/mt7530-mdio.c=150=static const struct regmap_config regmap_config = {\n--\ndrivers/net/dsa/mt7530-mdio.c-154-\t.max_register = MT7530_CREV,\ndrivers/net/dsa/mt7530-mdio.c:155:\t.lock = mt7530_mdio_regmap_lock,\ndrivers/net/dsa/mt7530-mdio.c:156:\t.unlock = mt7530_mdio_regmap_unlock,\ndrivers/net/dsa/mt7530-mdio.c-157-};\n--\ndrivers/net/dsa/mt7530-mdio.c=159=static int\ndrivers/net/dsa/mt7530-mdio.c:160:mt7530_probe(struct mdio_device *mdiodev)\ndrivers/net/dsa/mt7530-mdio.c-161-{\ndrivers/net/dsa/mt7530-mdio.c-162-\tstruct regmap_config rc = regmap_config;\ndrivers/net/dsa/mt7530-mdio.c:163:\tstruct mt7530_priv *priv;\ndrivers/net/dsa/mt7530-mdio.c-164-\tstruct device_node *dn;\n--\ndrivers/net/dsa/mt7530-mdio.c-176-\ndrivers/net/dsa/mt7530-mdio.c:177:\tret = mt7530_probe_common(priv);\ndrivers/net/dsa/mt7530-mdio.c-178-\tif (ret)\n--\ndrivers/net/dsa/mt7530-mdio.c-216-\trc.lock_arg = \u0026priv-\u003ebus-\u003emdio_lock;\ndrivers/net/dsa/mt7530-mdio.c:217:\tpriv-\u003eregmap = devm_regmap_init(priv-\u003edev, \u0026mt7530_regmap_bus,\ndrivers/net/dsa/mt7530-mdio.c-218-\t\t\t\t\tpriv, \u0026rc);\n--\ndrivers/net/dsa/mt7530-mdio.c=228=static void\ndrivers/net/dsa/mt7530-mdio.c:229:mt7530_remove(struct mdio_device *mdiodev)\ndrivers/net/dsa/mt7530-mdio.c-230-{\ndrivers/net/dsa/mt7530-mdio.c:231:\tstruct mt7530_priv *priv = dev_get_drvdata(\u0026mdiodev-\u003edev);\ndrivers/net/dsa/mt7530-mdio.c-232-\tint ret = 0, i;\n--\ndrivers/net/dsa/mt7530-mdio.c-246-\ndrivers/net/dsa/mt7530-mdio.c:247:\tmt7530_remove_common(priv);\ndrivers/net/dsa/mt7530-mdio.c-248-\n--\ndrivers/net/dsa/mt7530-mdio.c-252-\ndrivers/net/dsa/mt7530-mdio.c:253:static void mt7530_shutdown(struct mdio_device *mdiodev)\ndrivers/net/dsa/mt7530-mdio.c-254-{\ndrivers/net/dsa/mt7530-mdio.c:255:\tstruct mt7530_priv *priv = dev_get_drvdata(\u0026mdiodev-\u003edev);\ndrivers/net/dsa/mt7530-mdio.c-256-\n--\ndrivers/net/dsa/mt7530-mdio.c-264-\ndrivers/net/dsa/mt7530-mdio.c:265:static struct mdio_driver mt7530_mdio_driver = {\ndrivers/net/dsa/mt7530-mdio.c:266:\t.probe = mt7530_probe,\ndrivers/net/dsa/mt7530-mdio.c:267:\t.remove = mt7530_remove,\ndrivers/net/dsa/mt7530-mdio.c:268:\t.shutdown = mt7530_shutdown,\ndrivers/net/dsa/mt7530-mdio.c-269-\t.mdiodrv.driver = {\ndrivers/net/dsa/mt7530-mdio.c:270:\t\t.name = \"mt7530-mdio\",\ndrivers/net/dsa/mt7530-mdio.c:271:\t\t.of_match_table = mt7530_of_match,\ndrivers/net/dsa/mt7530-mdio.c-272-\t},\n--\ndrivers/net/dsa/mt7530-mdio.c-274-\ndrivers/net/dsa/mt7530-mdio.c:275:mdio_module_driver(mt7530_mdio_driver);\ndrivers/net/dsa/mt7530-mdio.c-276-\n--\ndrivers/net/dsa/mt7530-mmio.c-9-\ndrivers/net/dsa/mt7530-mmio.c:10:#include \"mt7530.h\"\ndrivers/net/dsa/mt7530-mmio.c-11-\ndrivers/net/dsa/mt7530-mmio.c=12=static const struct of_device_id mt7988_of_match[] = {\ndrivers/net/dsa/mt7530-mmio.c:13:\t{ .compatible = \"airoha,an7583-switch\", .data = \u0026mt753x_table[ID_AN7583], },\ndrivers/net/dsa/mt7530-mmio.c:14:\t{ .compatible = \"airoha,en7581-switch\", .data = \u0026mt753x_table[ID_EN7581], },\ndrivers/net/dsa/mt7530-mmio.c:15:\t{ .compatible = \"econet,en751221-switch\", .data = \u0026mt753x_table[ID_EN751221], },\ndrivers/net/dsa/mt7530-mmio.c:16:\t{ .compatible = \"econet,en7528-switch\", .data = \u0026mt753x_table[ID_EN7528], },\ndrivers/net/dsa/mt7530-mmio.c:17:\t{ .compatible = \"mediatek,mt7988-switch\", .data = \u0026mt753x_table[ID_MT7988], },\ndrivers/net/dsa/mt7530-mmio.c-18-\t{ /* sentinel */ }\n--\ndrivers/net/dsa/mt7530-mmio.c=31=mt7988_probe(struct platform_device *pdev)\ndrivers/net/dsa/mt7530-mmio.c-32-{\ndrivers/net/dsa/mt7530-mmio.c:33:\tstruct mt7530_priv *priv;\ndrivers/net/dsa/mt7530-mmio.c-34-\tvoid __iomem *base_addr;\n--\ndrivers/net/dsa/mt7530-mmio.c-43-\ndrivers/net/dsa/mt7530-mmio.c:44:\tret = mt7530_probe_common(priv);\ndrivers/net/dsa/mt7530-mmio.c-45-\tif (ret)\n--\ndrivers/net/dsa/mt7530-mmio.c-69-\ndrivers/net/dsa/mt7530-mmio.c:70:\treturn mt7530_setup_mdio(priv);\ndrivers/net/dsa/mt7530-mmio.c-71-}\n--\ndrivers/net/dsa/mt7530-mmio.c=73=static void mt7988_remove(struct platform_device *pdev)\ndrivers/net/dsa/mt7530-mmio.c-74-{\ndrivers/net/dsa/mt7530-mmio.c:75:\tstruct mt7530_priv *priv = platform_get_drvdata(pdev);\ndrivers/net/dsa/mt7530-mmio.c-76-\ndrivers/net/dsa/mt7530-mmio.c-77-\tif (priv)\ndrivers/net/dsa/mt7530-mmio.c:78:\t\tmt7530_remove_common(priv);\ndrivers/net/dsa/mt7530-mmio.c-79-}\n--\ndrivers/net/dsa/mt7530-mmio.c=81=static void mt7988_shutdown(struct platform_device *pdev)\ndrivers/net/dsa/mt7530-mmio.c-82-{\ndrivers/net/dsa/mt7530-mmio.c:83:\tstruct mt7530_priv *priv = platform_get_drvdata(pdev);\ndrivers/net/dsa/mt7530-mmio.c-84-\n--\ndrivers/net/dsa/mt7530-mmio.c=93=static struct platform_driver mt7988_platform_driver = {\n--\ndrivers/net/dsa/mt7530-mmio.c-97-\t.driver = {\ndrivers/net/dsa/mt7530-mmio.c:98:\t\t.name = \"mt7530-mmio\",\ndrivers/net/dsa/mt7530-mmio.c-99-\t\t.of_match_table = mt7988_of_match,\n--\ndrivers/net/dsa/mt7530.c-25-\ndrivers/net/dsa/mt7530.c:26:#include \"mt7530.h\"\ndrivers/net/dsa/mt7530.c-27-\n--\ndrivers/net/dsa/mt7530.c-30-\ndrivers/net/dsa/mt7530.c:31:static struct mt753x_pcs *pcs_to_mt753x_pcs(struct phylink_pcs *pcs)\ndrivers/net/dsa/mt7530.c-32-{\ndrivers/net/dsa/mt7530.c:33:\treturn container_of(pcs, struct mt753x_pcs, pcs);\ndrivers/net/dsa/mt7530.c-34-}\n--\ndrivers/net/dsa/mt7530.c-36-/* String, offset, and register size in bytes if different from 4 bytes */\ndrivers/net/dsa/mt7530.c:37:static const struct mt7530_mib_desc mt7530_mib[] = {\ndrivers/net/dsa/mt7530.c-38-\tMIB_DESC(1, MT7530_PORT_MIB_TX_DROP, \"TxDrop\"),\n--\ndrivers/net/dsa/mt7530.c=49=static int\ndrivers/net/dsa/mt7530.c:50:mt753x_ctrl_phy_addr(struct mt7530_priv *priv)\ndrivers/net/dsa/mt7530.c-51-{\n--\ndrivers/net/dsa/mt7530.c=62=static void\ndrivers/net/dsa/mt7530.c:63:mt7530_mutex_lock(struct mt7530_priv *priv)\ndrivers/net/dsa/mt7530.c-64-{\n--\ndrivers/net/dsa/mt7530.c=69=static void\ndrivers/net/dsa/mt7530.c:70:mt7530_mutex_unlock(struct mt7530_priv *priv)\ndrivers/net/dsa/mt7530.c-71-{\n--\ndrivers/net/dsa/mt7530.c=76=static void\ndrivers/net/dsa/mt7530.c:77:core_write(struct mt7530_priv *priv, u32 reg, u32 val)\ndrivers/net/dsa/mt7530.c-78-{\ndrivers/net/dsa/mt7530.c:79:\tint ctl_phy = mt753x_ctrl_phy_addr(priv);\ndrivers/net/dsa/mt7530.c-80-\tstruct mii_bus *bus = priv-\u003ebus;\n--\ndrivers/net/dsa/mt7530.c-88-\ndrivers/net/dsa/mt7530.c:89:\tmt7530_mutex_lock(priv);\ndrivers/net/dsa/mt7530.c-90-\n--\ndrivers/net/dsa/mt7530.c-112-\ndrivers/net/dsa/mt7530.c:113:\tmt7530_mutex_unlock(priv);\ndrivers/net/dsa/mt7530.c-114-}\n--\ndrivers/net/dsa/mt7530.c=116=static void\ndrivers/net/dsa/mt7530.c:117:core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)\ndrivers/net/dsa/mt7530.c-118-{\ndrivers/net/dsa/mt7530.c:119:\tint ctl_phy = mt753x_ctrl_phy_addr(priv);\ndrivers/net/dsa/mt7530.c-120-\tstruct mii_bus *bus = priv-\u003ebus;\n--\ndrivers/net/dsa/mt7530.c-129-\ndrivers/net/dsa/mt7530.c:130:\tmt7530_mutex_lock(priv);\ndrivers/net/dsa/mt7530.c-131-\n--\ndrivers/net/dsa/mt7530.c-161-\ndrivers/net/dsa/mt7530.c:162:\tmt7530_mutex_unlock(priv);\ndrivers/net/dsa/mt7530.c-163-}\n--\ndrivers/net/dsa/mt7530.c=165=static void\ndrivers/net/dsa/mt7530.c:166:core_set(struct mt7530_priv *priv, u32 reg, u32 val)\ndrivers/net/dsa/mt7530.c-167-{\n--\ndrivers/net/dsa/mt7530.c=171=static void\ndrivers/net/dsa/mt7530.c:172:core_clear(struct mt7530_priv *priv, u32 reg, u32 val)\ndrivers/net/dsa/mt7530.c-173-{\n--\ndrivers/net/dsa/mt7530.c=177=static int\ndrivers/net/dsa/mt7530.c:178:mt7530_fdb_cmd(struct mt7530_priv *priv, enum mt7530_fdb_cmd cmd, u32 *rsp)\ndrivers/net/dsa/mt7530.c-179-{\n--\ndrivers/net/dsa/mt7530.c-210-\ndrivers/net/dsa/mt7530.c:211:static void mt7530_port_fast_age(struct dsa_switch *ds, int port)\ndrivers/net/dsa/mt7530.c-212-{\ndrivers/net/dsa/mt7530.c:213:\tstruct mt7530_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/mt7530.c-214-\tu32 val;\n--\ndrivers/net/dsa/mt7530.c=231=static void\ndrivers/net/dsa/mt7530.c:232:mt7530_fdb_read(struct mt7530_priv *priv, struct mt7530_fdb *fdb)\ndrivers/net/dsa/mt7530.c-233-{\n--\ndrivers/net/dsa/mt7530.c=258=static void\ndrivers/net/dsa/mt7530.c:259:mt7530_fdb_write(struct mt7530_priv *priv, u16 vid,\ndrivers/net/dsa/mt7530.c-260-\t\t u8 port_mask, const u8 *mac,\n--\ndrivers/net/dsa/mt7530.c-288-/* Set up switch core clock for MT7530 */\ndrivers/net/dsa/mt7530.c:289:static void mt7530_pll_setup(struct mt7530_priv *priv)\ndrivers/net/dsa/mt7530.c-290-{\n--\ndrivers/net/dsa/mt7530.c=317=static struct dsa_port *\ndrivers/net/dsa/mt7530.c:318:mt753x_preferred_default_local_cpu_port(struct dsa_switch *ds)\ndrivers/net/dsa/mt7530.c-319-{\n--\ndrivers/net/dsa/mt7530.c=329=static void\ndrivers/net/dsa/mt7530.c:330:mt7530_setup_port6(struct dsa_switch *ds, phy_interface_t interface)\ndrivers/net/dsa/mt7530.c-331-{\ndrivers/net/dsa/mt7530.c:332:\tstruct mt7530_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/mt7530.c-333-\tu32 ncpo1, ssc_delta, xtal;\n--\ndrivers/net/dsa/mt7530.c=391=static void\ndrivers/net/dsa/mt7530.c:392:mt7531_pll_setup(struct mt7530_priv *priv)\ndrivers/net/dsa/mt7530.c-393-{\n--\ndrivers/net/dsa/mt7530.c=479=static bool\ndrivers/net/dsa/mt7530.c:480:en751221_trgmii_cal_ok(struct mt7530_priv *rx, u32 reg, int chan, int i)\ndrivers/net/dsa/mt7530.c-481-{\n--\ndrivers/net/dsa/mt7530.c=493=static void\ndrivers/net/dsa/mt7530.c:494:en751221_trgmii_calibrate_direction(struct mt7530_priv *tx,\ndrivers/net/dsa/mt7530.c:495:\t\t\t\t struct mt7530_priv *rx,\ndrivers/net/dsa/mt7530.c-496-\t\t\t\t u8 *default_taps)\n--\ndrivers/net/dsa/mt7530.c=573=static void\ndrivers/net/dsa/mt7530.c:574:en751221_set_tx_drive(struct mt7530_priv *priv, u8 drvp, u8 drvn, u8 clk_drvp,\ndrivers/net/dsa/mt7530.c-575-\t\t u8 clk_drvn)\n--\ndrivers/net/dsa/mt7530.c=589=static void\ndrivers/net/dsa/mt7530.c:590:en751221_trgmii_pair_setup(struct mt7530_priv *ext, int ext_port,\ndrivers/net/dsa/mt7530.c:591:\t\t\t struct mt7530_priv *ondie, int ondie_port)\ndrivers/net/dsa/mt7530.c-592-{\n--\ndrivers/net/dsa/mt7530.c=675=static void\ndrivers/net/dsa/mt7530.c:676:mt7530_cal_interswitch_trgmii(struct dsa_port *dp)\ndrivers/net/dsa/mt7530.c-677-{\n--\ndrivers/net/dsa/mt7530.c-680-\tstruct dsa_port *peer_dp;\ndrivers/net/dsa/mt7530.c:681:\tstruct mt7530_priv *peer;\ndrivers/net/dsa/mt7530.c:682:\tstruct mt7530_priv *priv;\ndrivers/net/dsa/mt7530.c-683-\tstruct dsa_link *dl;\n--\ndrivers/net/dsa/mt7530.c=724=static void\ndrivers/net/dsa/mt7530.c:725:mt7530_mib_reset(struct dsa_switch *ds)\ndrivers/net/dsa/mt7530.c-726-{\ndrivers/net/dsa/mt7530.c:727:\tstruct mt7530_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/mt7530.c-728-\n--\ndrivers/net/dsa/mt7530.c-732-\ndrivers/net/dsa/mt7530.c:733:static int mt7530_phy_read_c22(struct mt7530_priv *priv, int port, int regnum)\ndrivers/net/dsa/mt7530.c-734-{\n--\ndrivers/net/dsa/mt7530.c-737-\ndrivers/net/dsa/mt7530.c:738:static int mt7530_phy_write_c22(struct mt7530_priv *priv, int port, int regnum,\ndrivers/net/dsa/mt7530.c-739-\t\t\t\tu16 val)\n--\ndrivers/net/dsa/mt7530.c-743-\ndrivers/net/dsa/mt7530.c:744:static int mt7530_phy_read_c45(struct mt7530_priv *priv, int port,\ndrivers/net/dsa/mt7530.c-745-\t\t\t int devad, int regnum)\n--\ndrivers/net/dsa/mt7530.c-749-\ndrivers/net/dsa/mt7530.c:750:static int mt7530_phy_write_c45(struct mt7530_priv *priv, int port, int devad,\ndrivers/net/dsa/mt7530.c-751-\t\t\t\tint regnum, u16 val)\n--\ndrivers/net/dsa/mt7530.c=756=static int\ndrivers/net/dsa/mt7530.c:757:mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,\ndrivers/net/dsa/mt7530.c-758-\t\t\tint regnum)\n--\ndrivers/net/dsa/mt7530.c=807=static int\ndrivers/net/dsa/mt7530.c:808:mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,\ndrivers/net/dsa/mt7530.c-809-\t\t\t int regnum, u16 data)\n--\ndrivers/net/dsa/mt7530.c=857=static int\ndrivers/net/dsa/mt7530.c:858:mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)\ndrivers/net/dsa/mt7530.c-859-{\n--\ndrivers/net/dsa/mt7530.c=894=static int\ndrivers/net/dsa/mt7530.c:895:mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,\ndrivers/net/dsa/mt7530.c-896-\t\t\t u16 data)\n--\ndrivers/net/dsa/mt7530.c=931=static int\ndrivers/net/dsa/mt7530.c:932:mt753x_phy_read_c22(struct mii_bus *bus, int port, int regnum)\ndrivers/net/dsa/mt7530.c-933-{\ndrivers/net/dsa/mt7530.c:934:\tstruct mt7530_priv *priv = bus-\u003epriv;\ndrivers/net/dsa/mt7530.c-935-\n--\ndrivers/net/dsa/mt7530.c=939=static int\ndrivers/net/dsa/mt7530.c:940:mt753x_phy_read_c45(struct mii_bus *bus, int port, int devad, int regnum)\ndrivers/net/dsa/mt7530.c-941-{\ndrivers/net/dsa/mt7530.c:942:\tstruct mt7530_priv *priv = bus-\u003epriv;\ndrivers/net/dsa/mt7530.c-943-\n--\ndrivers/net/dsa/mt7530.c=947=static int\ndrivers/net/dsa/mt7530.c:948:mt753x_phy_write_c22(struct mii_bus *bus, int port, int regnum, u16 val)\ndrivers/net/dsa/mt7530.c-949-{\ndrivers/net/dsa/mt7530.c:950:\tstruct mt7530_priv *priv = bus-\u003epriv;\ndrivers/net/dsa/mt7530.c-951-\n--\ndrivers/net/dsa/mt7530.c=955=static int\ndrivers/net/dsa/mt7530.c:956:mt753x_phy_write_c45(struct mii_bus *bus, int port, int devad, int regnum,\ndrivers/net/dsa/mt7530.c-957-\t\t u16 val)\ndrivers/net/dsa/mt7530.c-958-{\ndrivers/net/dsa/mt7530.c:959:\tstruct mt7530_priv *priv = bus-\u003epriv;\ndrivers/net/dsa/mt7530.c-960-\n--\ndrivers/net/dsa/mt7530.c=964=static void\ndrivers/net/dsa/mt7530.c:965:mt7530_get_strings(struct dsa_switch *ds, int port, u32 stringset,\ndrivers/net/dsa/mt7530.c-966-\t\t uint8_t *data)\n--\ndrivers/net/dsa/mt7530.c-972-\ndrivers/net/dsa/mt7530.c:973:\tfor (i = 0; i \u003c ARRAY_SIZE(mt7530_mib); i++)\ndrivers/net/dsa/mt7530.c:974:\t\tethtool_puts(\u0026data, mt7530_mib[i].name);\ndrivers/net/dsa/mt7530.c-975-}\n--\ndrivers/net/dsa/mt7530.c=977=static void\ndrivers/net/dsa/mt7530.c:978:mt7530_read_port_stats(struct mt7530_priv *priv, int port,\ndrivers/net/dsa/mt7530.c-979-\t\t u32 offset, u8 size, uint64_t *data)\n--\ndrivers/net/dsa/mt7530.c=992=static void\ndrivers/net/dsa/mt7530.c:993:mt7530_get_ethtool_stats(struct dsa_switch *ds, int port,\ndrivers/net/dsa/mt7530.c-994-\t\t\t uint64_t *data)\ndrivers/net/dsa/mt7530.c-995-{\ndrivers/net/dsa/mt7530.c:996:\tstruct mt7530_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/mt7530.c:997:\tconst struct mt7530_mib_desc *mib;\ndrivers/net/dsa/mt7530.c-998-\tint i;\ndrivers/net/dsa/mt7530.c-999-\ndrivers/net/dsa/mt7530.c:1000:\tfor (i = 0; i \u003c ARRAY_SIZE(mt7530_mib); i++) {\ndrivers/net/dsa/mt7530.c:1001:\t\tmib = \u0026mt7530_mib[i];\ndrivers/net/dsa/mt7530.c-1002-\ndrivers/net/dsa/mt7530.c:1003:\t\tmt7530_read_port_stats(priv, port, mib-\u003eoffset, mib-\u003esize,\ndrivers/net/dsa/mt7530.c-1004-\t\t\t\t data + i);\n--\ndrivers/net/dsa/mt7530.c=1008=static int\ndrivers/net/dsa/mt7530.c:1009:mt7530_get_sset_count(struct dsa_switch *ds, int port, int sset)\ndrivers/net/dsa/mt7530.c-1010-{\n--\ndrivers/net/dsa/mt7530.c-1013-\ndrivers/net/dsa/mt7530.c:1014:\treturn ARRAY_SIZE(mt7530_mib);\ndrivers/net/dsa/mt7530.c-1015-}\ndrivers/net/dsa/mt7530.c-1016-\ndrivers/net/dsa/mt7530.c:1017:static void mt7530_get_eth_mac_stats(struct dsa_switch *ds, int port,\ndrivers/net/dsa/mt7530.c-1018-\t\t\t\t struct ethtool_eth_mac_stats *mac_stats)\ndrivers/net/dsa/mt7530.c-1019-{\ndrivers/net/dsa/mt7530.c:1020:\tstruct mt7530_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/mt7530.c-1021-\n--\ndrivers/net/dsa/mt7530.c-1026-\t */\ndrivers/net/dsa/mt7530.c:1027:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_UNICAST, 1,\ndrivers/net/dsa/mt7530.c-1028-\t\t\t \u0026mac_stats-\u003eFramesTransmittedOK);\ndrivers/net/dsa/mt7530.c-1029-\ndrivers/net/dsa/mt7530.c:1030:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_SINGLE_COLLISION, 1,\ndrivers/net/dsa/mt7530.c-1031-\t\t\t \u0026mac_stats-\u003eSingleCollisionFrames);\ndrivers/net/dsa/mt7530.c-1032-\ndrivers/net/dsa/mt7530.c:1033:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_MULTIPLE_COLLISION, 1,\ndrivers/net/dsa/mt7530.c-1034-\t\t\t \u0026mac_stats-\u003eMultipleCollisionFrames);\ndrivers/net/dsa/mt7530.c-1035-\ndrivers/net/dsa/mt7530.c:1036:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_UNICAST, 1,\ndrivers/net/dsa/mt7530.c-1037-\t\t\t \u0026mac_stats-\u003eFramesReceivedOK);\ndrivers/net/dsa/mt7530.c-1038-\ndrivers/net/dsa/mt7530.c:1039:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_BYTES, 2,\ndrivers/net/dsa/mt7530.c-1040-\t\t\t \u0026mac_stats-\u003eOctetsTransmittedOK);\ndrivers/net/dsa/mt7530.c-1041-\ndrivers/net/dsa/mt7530.c:1042:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_ALIGN_ERR, 1,\ndrivers/net/dsa/mt7530.c-1043-\t\t\t \u0026mac_stats-\u003eAlignmentErrors);\ndrivers/net/dsa/mt7530.c-1044-\ndrivers/net/dsa/mt7530.c:1045:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_DEFERRED, 1,\ndrivers/net/dsa/mt7530.c-1046-\t\t\t \u0026mac_stats-\u003eFramesWithDeferredXmissions);\ndrivers/net/dsa/mt7530.c-1047-\ndrivers/net/dsa/mt7530.c:1048:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_LATE_COLLISION, 1,\ndrivers/net/dsa/mt7530.c-1049-\t\t\t \u0026mac_stats-\u003eLateCollisions);\ndrivers/net/dsa/mt7530.c-1050-\ndrivers/net/dsa/mt7530.c:1051:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_EXCESSIVE_COLLISION, 1,\ndrivers/net/dsa/mt7530.c-1052-\t\t\t \u0026mac_stats-\u003eFramesAbortedDueToXSColls);\ndrivers/net/dsa/mt7530.c-1053-\ndrivers/net/dsa/mt7530.c:1054:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_BYTES, 2,\ndrivers/net/dsa/mt7530.c-1055-\t\t\t \u0026mac_stats-\u003eOctetsReceivedOK);\ndrivers/net/dsa/mt7530.c-1056-\ndrivers/net/dsa/mt7530.c:1057:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_MULTICAST, 1,\ndrivers/net/dsa/mt7530.c-1058-\t\t\t \u0026mac_stats-\u003eMulticastFramesXmittedOK);\ndrivers/net/dsa/mt7530.c-1059-\tmac_stats-\u003eFramesTransmittedOK += mac_stats-\u003eMulticastFramesXmittedOK;\ndrivers/net/dsa/mt7530.c:1060:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_TX_BROADCAST, 1,\ndrivers/net/dsa/mt7530.c-1061-\t\t\t \u0026mac_stats-\u003eBroadcastFramesXmittedOK);\n--\ndrivers/net/dsa/mt7530.c-1063-\ndrivers/net/dsa/mt7530.c:1064:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_MULTICAST, 1,\ndrivers/net/dsa/mt7530.c-1065-\t\t\t \u0026mac_stats-\u003eMulticastFramesReceivedOK);\ndrivers/net/dsa/mt7530.c-1066-\tmac_stats-\u003eFramesReceivedOK += mac_stats-\u003eMulticastFramesReceivedOK;\ndrivers/net/dsa/mt7530.c:1067:\tmt7530_read_port_stats(priv, port, MT7530_PORT_MIB_RX_BROADCAST, 1,\ndrivers/net/dsa/mt7530.c-1068-\t\t\t \u0026mac_stats-\u003eBroadcastFramesReceivedOK);\n--\ndrivers/net/dsa/mt7530.c-1071-\ndrivers/net/dsa/mt7530.c:1072:static const struct ethtool_rmon_hist_range mt7530_rmon_ranges[] = {\ndrivers/net/dsa/mt7530.c-1073-\t{ 0, 64 },\n--\ndrivers/net/dsa/mt7530.c-1081-\ndrivers/net/dsa/mt7530.c:1082:static void mt7530_get_rmon_stats(struct dsa_switch *ds, int port,\ndrivers/net/dsa/mt7530.c-1083-\t\t\t\t struct ethtool_rmon_stats *rmon_stats,\n--\ndrivers/net/dsa/mt7530.c-1085-{\ndrivers/net/dsa/mt7530.c:1086:\tstruct mt7530_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/mt7530.c-1087-\n\n"
} |
| 13/2 | 2026/09/09 16:05 | llm | patch-evaluator |
0mModel:gemini-3.7-flash Args: null Results: null Tokens: input: 54031 output: 151 thoughts: 522 Thoughts: **Fuzzing Feasibility Assessment: MT7530 Ethernet Switch Driver** Okay, let's break this down. The changes are focused on `Documentation/devicetree/bindings/net/dsa/mediatek,mt7530.yaml` and the `drivers/net/dsa/mt7530*` driver. This is the MediaTek/EcoNet/Airoha ethernet switch driver for their embedded SoCs, specifically the MT7530/MT7531/MT7621/MT7988/EN751221 and similar devices. My target architecture here is amd64. The problem, as I see it, is that standard virtualized fuzzing environments, like QEMU and GCE on amd64, simply *don't* have this specific MediaTek SoC switch hardware present. There aren't any readily available mock devices or virtual buses to instantiate and bind this driver on amd64. Now, let's consider the negative criteria. My review of section 2 clearly shows a structural problem: the MT7530 is a hardware-specific ASIC/SoC-integrated switch, and the changes involve device tree bindings and the driver for this device. This hardware is not emulated in standard QEMU/GCE environments, and I have no reason to think that it is available for this architecture. Therefore, given the structural unreachability of the hardware, I'm confident that `WorthFuzzing` should be `false`. Now, let's make sure I'm setting this up correctly. I need to make the `set-results` call. I'll need to clearly state that the modifications touch device tree bindings and the MT7530/MT7531/EN751221 DSA Ethernet switch driver, and that this hardware isn't present in standard QEMU/GCE virtualized environments on the target architecture. My `FocusSymbols` and `EnableConfigs` are empty. Okay, let's call `set-results`. |
| 14/2 | 2026/09/09 16:05 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch series updates Device Tree bindings documentation and adds support for EcoNet EN751221 SoCs and passthrough mode to the MediaTek MT7530 DSA Ethernet switch driver (drivers/net/dsa/mt7530*). This driver controls specific physical MediaTek/EcoNet SoC ethernet switches and MDIO/MMIO devices that cannot be instantiated or emulated in standard QEMU/GCE virtualized environments on the target architecture (amd64). Because the modified hardware-specific code paths are structurally unreachable, fuzzing is not warranted.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch series updates Device Tree bindings documentation and adds support for EcoNet EN751221 SoCs and passthrough mode to the MediaTek MT7530 DSA Ethernet switch driver (drivers/net/dsa/mt7530*). This driver controls specific physical MediaTek/EcoNet SoC ethernet switches and MDIO/MMIO devices that cannot be instantiated or emulated in standard QEMU/GCE virtualized environments on the target architecture (amd64). Because the modified hardware-specific code paths are structurally unreachable, fuzzing is not warranted.",
"WorthFuzzing": false
} |
| 15/1 | 2026/09/09 16:05 | action | If |
0mArgs:{
"WorthFuzzing": false
}Results: null |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|