| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/08/02 16:22 | flow | patch-triage |
1mArgs:null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch exclusively modifies the Qualcomm Atheros QCA8K DSA switch driver (qca8k). This driver requires specific physical hardware (QCA8337/QCA8327/QCA8328 switch chips connected via MDIO) to probe successfully. Since this hardware is not emulated in standard QEMU or virtualized environments, the modified code paths are unreachable and cannot be fuzzed.",
"WorthFuzzing": false
} |
| 1/1 | 2026/08/02 16:22 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit c0865ef49267aca2a6a9ffb3dfb21086c06a81d5\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Sun Aug 2 16:22:50 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c\nindex 4c928983b8623..4af92d51f0464 100644\n--- a/drivers/net/dsa/qca/qca8k-8xxx.c\n+++ b/drivers/net/dsa/qca/qca8k-8xxx.c\n@@ -1087,22 +1087,6 @@ qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)\n \treturn ret;\n }\n \n-static int qca8k_find_cpu_port(struct dsa_switch *ds)\n-{\n-\tstruct qca8k_priv *priv = ds-\u003epriv;\n-\n-\t/* Find the connected cpu port. Valid port are 0 or 6 */\n-\tif (dsa_is_cpu_port(ds, 0))\n-\t\treturn 0;\n-\n-\tdev_dbg(priv-\u003edev, \"port 0 is not the CPU port. Checking port 6\");\n-\n-\tif (dsa_is_cpu_port(ds, 6))\n-\t\treturn 6;\n-\n-\treturn -EINVAL;\n-}\n-\n static int\n qca8k_setup_of_pws_reg(struct qca8k_priv *priv)\n {\n@@ -1759,6 +1743,139 @@ qca8k_get_tag_protocol(struct dsa_switch *ds, int port,\n \treturn DSA_TAG_PROTO_QCA;\n }\n \n+static int qca8k_port_get_conduit_membership(struct dsa_switch *ds, int port,\n+\t\t\t\t\t u32 *user_members,\n+\t\t\t\t\t u32 *cpu_members)\n+{\n+\tstruct qca8k_priv *priv = ds-\u003epriv;\n+\tstruct dsa_port *cpu_dp;\n+\tu32 val;\n+\tint ret;\n+\n+\tret = regmap_read(priv-\u003eregmap, QCA8K_PORT_LOOKUP_CTRL(port), \u0026val);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t*user_members = val \u0026 dsa_cpu_ports(ds);\n+\t*cpu_members = 0;\n+\n+\tdsa_switch_for_each_cpu_port(cpu_dp, ds) {\n+\t\tret = regmap_read(priv-\u003eregmap,\n+\t\t\t\t QCA8K_PORT_LOOKUP_CTRL(cpu_dp-\u003eindex), \u0026val);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\n+\t\tif (val \u0026 BIT(port))\n+\t\t\t*cpu_members |= BIT(cpu_dp-\u003eindex);\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int qca8k_port_set_conduit_membership(struct dsa_switch *ds, int port,\n+\t\t\t\t\t u32 user_members,\n+\t\t\t\t\t u32 cpu_members)\n+{\n+\tstruct qca8k_priv *priv = ds-\u003epriv;\n+\tstruct dsa_port *cpu_dp;\n+\tint ret;\n+\n+\tret = regmap_update_bits(priv-\u003eregmap,\n+\t\t\t\t QCA8K_PORT_LOOKUP_CTRL(port),\n+\t\t\t\t dsa_cpu_ports(ds), user_members);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tdsa_switch_for_each_cpu_port(cpu_dp, ds) {\n+\t\tu32 member = cpu_members \u0026 BIT(cpu_dp-\u003eindex) ? BIT(port) : 0;\n+\n+\t\tret = regmap_update_bits(priv-\u003eregmap,\n+\t\t\t\t\t QCA8K_PORT_LOOKUP_CTRL(cpu_dp-\u003eindex),\n+\t\t\t\t\t BIT(port), member);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int qca8k_port_change_conduit(struct dsa_switch *ds, int port,\n+\t\t\t\t struct net_device *conduit,\n+\t\t\t\t struct netlink_ext_ack *extack)\n+{\n+\tstruct qca8k_priv *priv = ds-\u003epriv;\n+\tu32 cpu_port_mask, old_cpu_members, old_user_members;\n+\tint restore_ret, ret;\n+\n+\tret = qca8k_conduit_port_mask(ds, conduit, \u0026cpu_port_mask, extack);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = qca8k_port_get_conduit_membership(ds, port, \u0026old_user_members,\n+\t\t\t\t\t\t\u0026old_cpu_members);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tret = qca8k_port_set_conduit_membership(ds, port, cpu_port_mask,\n+\t\t\t\t\t\tcpu_port_mask);\n+\tif (!ret)\n+\t\treturn 0;\n+\n+\trestore_ret = qca8k_port_set_conduit_membership(ds, port,\n+\t\t\t\t\t\t\told_user_members,\n+\t\t\t\t\t\t\told_cpu_members);\n+\tif (restore_ret)\n+\t\tdev_err(priv-\u003edev,\n+\t\t\t\"failed to restore conduit membership for port %d: %pe\\n\",\n+\t\t\tport, ERR_PTR(restore_ret));\n+\n+\treturn ret;\n+}\n+\n+static int qca8k_lag_refresh_conduit_ports(struct dsa_switch *ds,\n+\t\t\t\t\t struct dsa_lag lag)\n+{\n+\tstruct dsa_port *dp;\n+\tint ret;\n+\n+\tdsa_switch_for_each_user_port(dp, ds) {\n+\t\tif (dsa_port_to_conduit(dp) != lag.dev)\n+\t\t\tcontinue;\n+\n+\t\tret = qca8k_port_change_conduit(ds, dp-\u003eindex, lag.dev, NULL);\n+\t\tif (ret)\n+\t\t\treturn ret;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int qca8k_port_lag_join_with_conduits(struct dsa_switch *ds, int port,\n+\t\t\t\t\t struct dsa_lag lag,\n+\t\t\t\t\t struct netdev_lag_upper_info *info,\n+\t\t\t\t\t struct netlink_ext_ack *extack)\n+{\n+\tint ret;\n+\n+\tret = qca8k_port_lag_join(ds, port, lag, info, extack);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn qca8k_lag_refresh_conduit_ports(ds, lag);\n+}\n+\n+static int qca8k_port_lag_leave_with_conduits(struct dsa_switch *ds, int port,\n+\t\t\t\t\t struct dsa_lag lag)\n+{\n+\tint ret;\n+\n+\tret = qca8k_port_lag_leave(ds, port, lag);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn qca8k_lag_refresh_conduit_ports(ds, lag);\n+}\n+\n static void\n qca8k_conduit_change(struct dsa_switch *ds, const struct net_device *conduit,\n \t\t bool operational)\n@@ -1844,13 +1961,13 @@ qca8k_setup(struct dsa_switch *ds)\n {\n \tstruct qca8k_priv *priv = ds-\u003epriv;\n \tstruct dsa_port *dp;\n-\tint cpu_port, ret;\n-\tu32 mask;\n+\tu32 cpu_ports, mask;\n+\tint ret;\n \n-\tcpu_port = qca8k_find_cpu_port(ds);\n-\tif (cpu_port \u003c 0) {\n-\t\tdev_err(priv-\u003edev, \"No cpu port configured in both cpu port0 and port6\");\n-\t\treturn cpu_port;\n+\tcpu_ports = dsa_cpu_ports(ds);\n+\tif (!cpu_ports || cpu_ports \u0026 ~(BIT(0) | BIT(6))) {\n+\t\tdev_err(priv-\u003edev, \"CPU ports must be port 0 or 6\");\n+\t\treturn -EINVAL;\n \t}\n \n \t/* Parse CPU port config to be later used in phy_link mac_config */\n@@ -1900,9 +2017,10 @@ qca8k_setup(struct dsa_switch *ds)\n \n \t/* Initial setup of all ports */\n \tdsa_switch_for_each_port(dp, ds) {\n-\t\t/* Disable forwarding by default on all ports */\n+\t\t/* Disable forwarding and learning by default on all ports */\n \t\tret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(dp-\u003eindex),\n-\t\t\t\tQCA8K_PORT_LOOKUP_MEMBER, 0);\n+\t\t\t\tQCA8K_PORT_LOOKUP_MEMBER |\n+\t\t\t\tQCA8K_PORT_LOOKUP_LEARN, 0);\n \t\tif (ret)\n \t\t\treturn ret;\n \t}\n@@ -1922,28 +2040,20 @@ qca8k_setup(struct dsa_switch *ds)\n \t\t}\n \t}\n \n-\t/* Forward all unknown frames to CPU port for Linux processing\n-\t * Notice that in multi-cpu config only one port should be set\n-\t * for igmp, unknown, multicast and broadcast packet\n+\t/* Forward unknown frames to every CPU port. The ingress port lookup\n+\t * membership restricts each frame to its assigned CPU port.\n \t */\n \tret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,\n-\t\t\t FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) |\n-\t\t\t FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) |\n-\t\t\t FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) |\n-\t\t\t FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port)));\n+\t\t\t FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, cpu_ports) |\n+\t\t\t FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, cpu_ports) |\n+\t\t\t FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, cpu_ports) |\n+\t\t\t FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, cpu_ports));\n \tif (ret)\n \t\treturn ret;\n \n-\t/* CPU port gets connected to all user ports of the switch */\n-\tret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),\n-\t\t\tQCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));\n-\tif (ret)\n-\t\treturn ret;\n-\n-\t/* Setup connection between CPU port \u0026 user ports\n-\t * Individual user ports get connected to CPU port only\n-\t */\n+\t/* Connect each user port bidirectionally to its assigned CPU port. */\n \tdsa_switch_for_each_user_port(dp, ds) {\n+\t\tu8 cpu_port = dp-\u003ecpu_dp-\u003eindex;\n \t\tu8 port = dp-\u003eindex;\n \n \t\tret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),\n@@ -1952,8 +2062,8 @@ qca8k_setup(struct dsa_switch *ds)\n \t\tif (ret)\n \t\t\treturn ret;\n \n-\t\tret = regmap_clear_bits(priv-\u003eregmap, QCA8K_PORT_LOOKUP_CTRL(port),\n-\t\t\t\t\tQCA8K_PORT_LOOKUP_LEARN);\n+\t\tret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),\n+\t\t\t\tBIT(port), BIT(port));\n \t\tif (ret)\n \t\t\treturn ret;\n \n@@ -2008,6 +2118,8 @@ qca8k_setup(struct dsa_switch *ds)\n \t/* Set max number of LAGs supported */\n \tds-\u003enum_lag_ids = QCA8K_NUM_LAGS;\n \n+\tds-\u003eassisted_learning_on_cpu_port = true;\n+\n \treturn 0;\n }\n \n@@ -2040,6 +2152,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = {\n \t.port_fdb_add\t\t= qca8k_port_fdb_add,\n \t.port_fdb_del\t\t= qca8k_port_fdb_del,\n \t.port_fdb_dump\t\t= qca8k_port_fdb_dump,\n+\t.lag_fdb_add\t\t= qca8k_lag_fdb_add,\n+\t.lag_fdb_del\t\t= qca8k_lag_fdb_del,\n \t.port_mdb_add\t\t= qca8k_port_mdb_add,\n \t.port_mdb_del\t\t= qca8k_port_mdb_del,\n \t.port_mirror_add\t= qca8k_port_mirror_add,\n@@ -2049,8 +2163,9 @@ static const struct dsa_switch_ops qca8k_switch_ops = {\n \t.port_vlan_del\t\t= qca8k_port_vlan_del,\n \t.phylink_get_caps\t= qca8k_phylink_get_caps,\n \t.get_phy_flags\t\t= qca8k_get_phy_flags,\n-\t.port_lag_join\t\t= qca8k_port_lag_join,\n-\t.port_lag_leave\t\t= qca8k_port_lag_leave,\n+\t.port_lag_join\t\t= qca8k_port_lag_join_with_conduits,\n+\t.port_lag_leave\t\t= qca8k_port_lag_leave_with_conduits,\n+\t.port_change_conduit\t= qca8k_port_change_conduit,\n \t.conduit_state_change\t= qca8k_conduit_change,\n \t.connect_tag_protocol\t= qca8k_connect_tag_protocol,\n };\ndiff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c\nindex 13005f10edb7d..73e36f5fb3585 100644\n--- a/drivers/net/dsa/qca/qca8k-common.c\n+++ b/drivers/net/dsa/qca/qca8k-common.c\n@@ -322,6 +322,36 @@ static int qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,\n \treturn ret;\n }\n \n+static int qca8k_fdb_purge_dynamic(struct qca8k_priv *priv, const u8 *mac,\n+\t\t\t\t u16 vid)\n+{\n+\tstruct qca8k_fdb fdb = { 0 };\n+\tint ret;\n+\n+\tmutex_lock(\u0026priv-\u003ereg_mutex);\n+\n+\tqca8k_fdb_write(priv, vid, 0, mac, 0);\n+\tret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);\n+\tif (ret \u003c 0)\n+\t\tgoto out;\n+\n+\tret = qca8k_fdb_read(priv, \u0026fdb);\n+\tif (ret \u003c 0)\n+\t\tgoto out;\n+\n+\t/* Keep deliberately configured static entries. */\n+\tif (!fdb.aging || fdb.aging == QCA8K_ATU_STATUS_STATIC) {\n+\t\tret = 0;\n+\t\tgoto out;\n+\t}\n+\n+\tret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);\n+\n+out:\n+\tmutex_unlock(\u0026priv-\u003ereg_mutex);\n+\treturn ret;\n+}\n+\n static int qca8k_vlan_access(struct qca8k_priv *priv,\n \t\t\t enum qca8k_vlan_cmd cmd, u16 vid)\n {\n@@ -607,15 +637,60 @@ void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)\n \tqca8k_port_configure_learning(ds, port, learning);\n }\n \n+int qca8k_conduit_port_mask(struct dsa_switch *ds,\n+\t\t\t struct net_device *conduit,\n+\t\t\t u32 *port_mask,\n+\t\t\t struct netlink_ext_ack *extack)\n+{\n+\tstruct dsa_switch_tree *dst = ds-\u003edst;\n+\tstruct dsa_port *dp;\n+\tint id;\n+\n+\t*port_mask = 0;\n+\n+\tif (!netif_is_lag_master(conduit)) {\n+\t\tdp = conduit-\u003edsa_ptr;\n+\t\tif (!dp || dp-\u003eds != ds || !dsa_port_is_cpu(dp)) {\n+\t\t\tNL_SET_ERR_MSG_MOD(extack,\n+\t\t\t\t\t \"Conduit is not a local CPU port\");\n+\t\t\treturn -EOPNOTSUPP;\n+\t\t}\n+\n+\t\t*port_mask = BIT(dp-\u003eindex);\n+\t\treturn 0;\n+\t}\n+\n+\tid = dsa_lag_id(dst, conduit);\n+\tif (id \u003c 0)\n+\t\treturn id;\n+\n+\tdsa_lag_foreach_port(dp, dst, dsa_lag_by_id(dst, id))\n+\t\tif (dp-\u003eds == ds \u0026\u0026 dsa_port_is_cpu(dp))\n+\t\t\t*port_mask |= BIT(dp-\u003eindex);\n+\n+\tif (!*port_mask) {\n+\t\tNL_SET_ERR_MSG_MOD(extack,\n+\t\t\t\t \"Conduit LAG has no local CPU port\");\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int qca8k_update_port_member(struct qca8k_priv *priv, int port,\n \t\t\t\t const struct net_device *bridge_dev,\n \t\t\t\t bool join)\n {\n \tbool isolated = !!(priv-\u003eport_isolated_map \u0026 BIT(port)), other_isolated;\n \tstruct dsa_port *dp = dsa_to_port(priv-\u003eds, port), *other_dp;\n-\tu32 port_mask = BIT(dp-\u003ecpu_dp-\u003eindex);\n+\tu32 port_mask;\n \tint i, ret;\n \n+\tret = qca8k_conduit_port_mask(priv-\u003eds, dsa_port_to_conduit(dp),\n+\t\t\t\t \u0026port_mask, NULL);\n+\tif (ret)\n+\t\treturn ret;\n+\n \tfor (i = 0; i \u003c QCA8K_NUM_PORTS; i++) {\n \t\tif (i == port)\n \t\t\tcontinue;\n@@ -829,6 +904,14 @@ int qca8k_port_fdb_add(struct dsa_switch *ds, int port,\n \tstruct qca8k_priv *priv = ds-\u003epriv;\n \tu16 port_mask = BIT(port);\n \n+\t/* Unknown unicast flooding delivers host traffic to the conduit. */\n+\tif (dsa_is_cpu_port(ds, port)) {\n+\t\tif (!vid)\n+\t\t\tvid = QCA8K_PORT_VID_DEF;\n+\n+\t\treturn qca8k_fdb_purge_dynamic(priv, addr, vid);\n+\t}\n+\n \treturn qca8k_port_fdb_insert(priv, addr, port_mask, vid);\n }\n \n@@ -839,6 +922,9 @@ int qca8k_port_fdb_del(struct dsa_switch *ds, int port,\n \tstruct qca8k_priv *priv = ds-\u003epriv;\n \tu16 port_mask = BIT(port);\n \n+\tif (dsa_is_cpu_port(ds, port))\n+\t\treturn 0;\n+\n \tif (!vid)\n \t\tvid = QCA8K_PORT_VID_DEF;\n \n@@ -868,6 +954,75 @@ int qca8k_port_fdb_dump(struct dsa_switch *ds, int port,\n \treturn 0;\n }\n \n+static u8 qca8k_lag_port_mask(struct dsa_switch *ds,\n+\t\t\t const struct dsa_lag *lag)\n+{\n+\tstruct dsa_port *dp;\n+\tu8 port_mask = 0;\n+\n+\tdsa_lag_foreach_port(dp, ds-\u003edst, lag)\n+\t\tif (dp-\u003eds == ds)\n+\t\t\tport_mask |= BIT(dp-\u003eindex);\n+\n+\treturn port_mask;\n+}\n+\n+static bool qca8k_lag_is_cpu(struct dsa_switch *ds,\n+\t\t\t const struct dsa_lag *lag)\n+{\n+\tstruct dsa_port *dp;\n+\tbool has_cpu = false;\n+\n+\tdsa_lag_foreach_port(dp, ds-\u003edst, lag) {\n+\t\tif (dp-\u003eds != ds)\n+\t\t\tcontinue;\n+\n+\t\tif (!dsa_port_is_cpu(dp))\n+\t\t\treturn false;\n+\n+\t\thas_cpu = true;\n+\t}\n+\n+\treturn has_cpu;\n+}\n+\n+int qca8k_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag,\n+\t\t const unsigned char *addr, u16 vid,\n+\t\t struct dsa_db db)\n+{\n+\tstruct qca8k_priv *priv = ds-\u003epriv;\n+\tu8 port_mask;\n+\n+\tport_mask = qca8k_lag_port_mask(ds, \u0026lag);\n+\n+\tif (qca8k_lag_is_cpu(ds, \u0026lag)) {\n+\t\tif (!vid)\n+\t\t\tvid = QCA8K_PORT_VID_DEF;\n+\n+\t\treturn qca8k_fdb_purge_dynamic(priv, addr, vid);\n+\t}\n+\n+\treturn qca8k_port_fdb_insert(priv, addr, port_mask, vid);\n+}\n+\n+int qca8k_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag,\n+\t\t const unsigned char *addr, u16 vid,\n+\t\t struct dsa_db db)\n+{\n+\tstruct qca8k_priv *priv = ds-\u003epriv;\n+\tu8 port_mask;\n+\n+\tif (qca8k_lag_is_cpu(ds, \u0026lag))\n+\t\treturn 0;\n+\n+\tif (!vid)\n+\t\tvid = QCA8K_PORT_VID_DEF;\n+\n+\tport_mask = qca8k_lag_port_mask(ds, \u0026lag);\n+\n+\treturn qca8k_fdb_del(priv, addr, port_mask, vid);\n+}\n+\n int qca8k_port_mdb_add(struct dsa_switch *ds, int port,\n \t\t const struct switchdev_obj_port_mdb *mdb,\n \t\t struct dsa_db db)\ndiff --git a/drivers/net/dsa/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h\nindex 9563388930325..333b343886def 100644\n--- a/drivers/net/dsa/qca/qca8k.h\n+++ b/drivers/net/dsa/qca/qca8k.h\n@@ -523,6 +523,10 @@ int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset);\n int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *eee);\n \n /* Common bridge function */\n+int qca8k_conduit_port_mask(struct dsa_switch *ds,\n+\t\t\t struct net_device *conduit,\n+\t\t\t u32 *port_mask,\n+\t\t\t struct netlink_ext_ack *extack);\n void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);\n int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,\n \t\t\t\tstruct switchdev_brport_flags flags,\n@@ -561,6 +565,12 @@ int qca8k_port_fdb_del(struct dsa_switch *ds, int port,\n \t\t struct dsa_db db);\n int qca8k_port_fdb_dump(struct dsa_switch *ds, int port,\n \t\t\tdsa_fdb_dump_cb_t *cb, void *data);\n+int qca8k_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag,\n+\t\t const unsigned char *addr, u16 vid,\n+\t\t struct dsa_db db);\n+int qca8k_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag,\n+\t\t const unsigned char *addr, u16 vid,\n+\t\t struct dsa_db db);\n \n /* Common MDB function */\n int qca8k_port_mdb_add(struct dsa_switch *ds, int port,\n"
} |
| 2/1 | 2026/08/02 16:22 | agent | patch-evaluator |
1mModel:best-expensive Args: null Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch exclusively modifies the Qualcomm Atheros QCA8K DSA switch driver (qca8k). This driver requires specific physical hardware (QCA8337/QCA8327/QCA8328 switch chips connected via MDIO) to probe successfully. Since this hardware is not emulated in standard QEMU or virtualized environments, the modified code paths are unreachable and cannot be fuzzed.",
"WorthFuzzing": false
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). - Code in vendor-specific PCIe switch, SmartNIC, or GPU drivers (e.g., mlxsw, pds_core, qed, ionic, amdgpu) that require physical PCIe hardware cards not emulated in standard QEMU. - Driver .remove, .shutdown, or pci_unregister_driver teardown callbacks (e.g., igb_remove) that are executed only during PCI hot-unplug or sysfs driver unbind operations. If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. Prefer non-static, non-inlined API entrypoint functions over internal static helper functions (which are inlined by the compiler and do not have distinct symbol addresses). 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Also check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed for Kbuild to compile the code statically into vmlinux. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit c0865ef49267aca2a6a9ffb3dfb21086c06a81d5
Author: syz-cluster <triage@syzkaller.com>
Date: Sun Aug 2 16:22:50 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
index 4c928983b8623..4af92d51f0464 100644
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
@@ -1087,22 +1087,6 @@ qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)
return ret;
}
-static int qca8k_find_cpu_port(struct dsa_switch *ds)
-{
- struct qca8k_priv *priv = ds->priv;
-
- /* Find the connected cpu port. Valid port are 0 or 6 */
- if (dsa_is_cpu_port(ds, 0))
- return 0;
-
- dev_dbg(priv->dev, "port 0 is not the CPU port. Checking port 6");
-
- if (dsa_is_cpu_port(ds, 6))
- return 6;
-
- return -EINVAL;
-}
-
static int
qca8k_setup_of_pws_reg(struct qca8k_priv *priv)
{
@@ -1759,6 +1743,139 @@ qca8k_get_tag_protocol(struct dsa_switch *ds, int port,
return DSA_TAG_PROTO_QCA;
}
+static int qca8k_port_get_conduit_membership(struct dsa_switch *ds, int port,
+ u32 *user_members,
+ u32 *cpu_members)
+{
+ struct qca8k_priv *priv = ds->priv;
+ struct dsa_port *cpu_dp;
+ u32 val;
+ int ret;
+
+ ret = regmap_read(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port), &val);
+ if (ret)
+ return ret;
+
+ *user_members = val & dsa_cpu_ports(ds);
+ *cpu_members = 0;
+
+ dsa_switch_for_each_cpu_port(cpu_dp, ds) {
+ ret = regmap_read(priv->regmap,
+ QCA8K_PORT_LOOKUP_CTRL(cpu_dp->index), &val);
+ if (ret)
+ return ret;
+
+ if (val & BIT(port))
+ *cpu_members |= BIT(cpu_dp->index);
+ }
+
+ return 0;
+}
+
+static int qca8k_port_set_conduit_membership(struct dsa_switch *ds, int port,
+ u32 user_members,
+ u32 cpu_members)
+{
+ struct qca8k_priv *priv = ds->priv;
+ struct dsa_port *cpu_dp;
+ int ret;
+
+ ret = regmap_update_bits(priv->regmap,
+ QCA8K_PORT_LOOKUP_CTRL(port),
+ dsa_cpu_ports(ds), user_members);
+ if (ret)
+ return ret;
+
+ dsa_switch_for_each_cpu_port(cpu_dp, ds) {
+ u32 member = cpu_members & BIT(cpu_dp->index) ? BIT(port) : 0;
+
+ ret = regmap_update_bits(priv->regmap,
+ QCA8K_PORT_LOOKUP_CTRL(cpu_dp->index),
+ BIT(port), member);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int qca8k_port_change_conduit(struct dsa_switch *ds, int port,
+ struct net_device *conduit,
+ struct netlink_ext_ack *extack)
+{
+ struct qca8k_priv *priv = ds->priv;
+ u32 cpu_port_mask, old_cpu_members, old_user_members;
+ int restore_ret, ret;
+
+ ret = qca8k_conduit_port_mask(ds, conduit, &cpu_port_mask, extack);
+ if (ret)
+ return ret;
+
+ ret = qca8k_port_get_conduit_membership(ds, port, &old_user_members,
+ &old_cpu_members);
+ if (ret)
+ return ret;
+
+ ret = qca8k_port_set_conduit_membership(ds, port, cpu_port_mask,
+ cpu_port_mask);
+ if (!ret)
+ return 0;
+
+ restore_ret = qca8k_port_set_conduit_membership(ds, port,
+ old_user_members,
+ old_cpu_members);
+ if (restore_ret)
+ dev_err(priv->dev,
+ "failed to restore conduit membership for port %d: %pe\n",
+ port, ERR_PTR(restore_ret));
+
+ return ret;
+}
+
+static int qca8k_lag_refresh_conduit_ports(struct dsa_switch *ds,
+ struct dsa_lag lag)
+{
+ struct dsa_port *dp;
+ int ret;
+
+ dsa_switch_for_each_user_port(dp, ds) {
+ if (dsa_port_to_conduit(dp) != lag.dev)
+ continue;
+
+ ret = qca8k_port_change_conduit(ds, dp->index, lag.dev, NULL);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int qca8k_port_lag_join_with_conduits(struct dsa_switch *ds, int port,
+ struct dsa_lag lag,
+ struct netdev_lag_upper_info *info,
+ struct netlink_ext_ack *extack)
+{
+ int ret;
+
+ ret = qca8k_port_lag_join(ds, port, lag, info, extack);
+ if (ret)
+ return ret;
+
+ return qca8k_lag_refresh_conduit_ports(ds, lag);
+}
+
+static int qca8k_port_lag_leave_with_conduits(struct dsa_switch *ds, int port,
+ struct dsa_lag lag)
+{
+ int ret;
+
+ ret = qca8k_port_lag_leave(ds, port, lag);
+ if (ret)
+ return ret;
+
+ return qca8k_lag_refresh_conduit_ports(ds, lag);
+}
+
static void
qca8k_conduit_change(struct dsa_switch *ds, const struct net_device *conduit,
bool operational)
@@ -1844,13 +1961,13 @@ qca8k_setup(struct dsa_switch *ds)
{
struct qca8k_priv *priv = ds->priv;
struct dsa_port *dp;
- int cpu_port, ret;
- u32 mask;
+ u32 cpu_ports, mask;
+ int ret;
- cpu_port = qca8k_find_cpu_port(ds);
- if (cpu_port < 0) {
- dev_err(priv->dev, "No cpu port configured in both cpu port0 and port6");
- return cpu_port;
+ cpu_ports = dsa_cpu_ports(ds);
+ if (!cpu_ports || cpu_ports & ~(BIT(0) | BIT(6))) {
+ dev_err(priv->dev, "CPU ports must be port 0 or 6");
+ return -EINVAL;
}
/* Parse CPU port config to be later used in phy_link mac_config */
@@ -1900,9 +2017,10 @@ qca8k_setup(struct dsa_switch *ds)
/* Initial setup of all ports */
dsa_switch_for_each_port(dp, ds) {
- /* Disable forwarding by default on all ports */
+ /* Disable forwarding and learning by default on all ports */
ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(dp->index),
- QCA8K_PORT_LOOKUP_MEMBER, 0);
+ QCA8K_PORT_LOOKUP_MEMBER |
+ QCA8K_PORT_LOOKUP_LEARN, 0);
if (ret)
return ret;
}
@@ -1922,28 +2040,20 @@ qca8k_setup(struct dsa_switch *ds)
}
}
- /* Forward all unknown frames to CPU port for Linux processing
- * Notice that in multi-cpu config only one port should be set
- * for igmp, unknown, multicast and broadcast packet
+ /* Forward unknown frames to every CPU port. The ingress port lookup
+ * membership restricts each frame to its assigned CPU port.
*/
ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, BIT(cpu_port)) |
- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, BIT(cpu_port)) |
- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, BIT(cpu_port)) |
- FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, BIT(cpu_port)));
+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_MASK, cpu_ports) |
+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_BC_DP_MASK, cpu_ports) |
+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_MC_DP_MASK, cpu_ports) |
+ FIELD_PREP(QCA8K_GLOBAL_FW_CTRL1_UC_DP_MASK, cpu_ports));
if (ret)
return ret;
- /* CPU port gets connected to all user ports of the switch */
- ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
- QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds));
- if (ret)
- return ret;
-
- /* Setup connection between CPU port & user ports
- * Individual user ports get connected to CPU port only
- */
+ /* Connect each user port bidirectionally to its assigned CPU port. */
dsa_switch_for_each_user_port(dp, ds) {
+ u8 cpu_port = dp->cpu_dp->index;
u8 port = dp->index;
ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
@@ -1952,8 +2062,8 @@ qca8k_setup(struct dsa_switch *ds)
if (ret)
return ret;
- ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(port),
- QCA8K_PORT_LOOKUP_LEARN);
+ ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(cpu_port),
+ BIT(port), BIT(port));
if (ret)
return ret;
@@ -2008,6 +2118,8 @@ qca8k_setup(struct dsa_switch *ds)
/* Set max number of LAGs supported */
ds->num_lag_ids = QCA8K_NUM_LAGS;
+ ds->assisted_learning_on_cpu_port = true;
+
return 0;
}
@@ -2040,6 +2152,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
.port_fdb_add = qca8k_port_fdb_add,
.port_fdb_del = qca8k_port_fdb_del,
.port_fdb_dump = qca8k_port_fdb_dump,
+ .lag_fdb_add = qca8k_lag_fdb_add,
+ .lag_fdb_del = qca8k_lag_fdb_del,
.port_mdb_add = qca8k_port_mdb_add,
.port_mdb_del = qca8k_port_mdb_del,
.port_mirror_add = qca8k_port_mirror_add,
@@ -2049,8 +2163,9 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
.port_vlan_del = qca8k_port_vlan_del,
.phylink_get_caps = qca8k_phylink_get_caps,
.get_phy_flags = qca8k_get_phy_flags,
- .port_lag_join = qca8k_port_lag_join,
- .port_lag_leave = qca8k_port_lag_leave,
+ .port_lag_join = qca8k_port_lag_join_with_conduits,
+ .port_lag_leave = qca8k_port_lag_leave_with_conduits,
+ .port_change_conduit = qca8k_port_change_conduit,
.conduit_state_change = qca8k_conduit_change,
.connect_tag_protocol = qca8k_connect_tag_protocol,
};
diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c
index 13005f10edb7d..73e36f5fb3585 100644
--- a/drivers/net/dsa/qca/qca8k-common.c
+++ b/drivers/net/dsa/qca/qca8k-common.c
@@ -322,6 +322,36 @@ static int qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,
return ret;
}
+static int qca8k_fdb_purge_dynamic(struct qca8k_priv *priv, const u8 *mac,
+ u16 vid)
+{
+ struct qca8k_fdb fdb = { 0 };
+ int ret;
+
+ mutex_lock(&priv->reg_mutex);
+
+ qca8k_fdb_write(priv, vid, 0, mac, 0);
+ ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
+ if (ret < 0)
+ goto out;
+
+ ret = qca8k_fdb_read(priv, &fdb);
+ if (ret < 0)
+ goto out;
+
+ /* Keep deliberately configured static entries. */
+ if (!fdb.aging || fdb.aging == QCA8K_ATU_STATUS_STATIC) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
+
+out:
+ mutex_unlock(&priv->reg_mutex);
+ return ret;
+}
+
static int qca8k_vlan_access(struct qca8k_priv *priv,
enum qca8k_vlan_cmd cmd, u16 vid)
{
@@ -607,15 +637,60 @@ void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
qca8k_port_configure_learning(ds, port, learning);
}
+int qca8k_conduit_port_mask(struct dsa_switch *ds,
+ struct net_device *conduit,
+ u32 *port_mask,
+ struct netlink_ext_ack *extack)
+{
+ struct dsa_switch_tree *dst = ds->dst;
+ struct dsa_port *dp;
+ int id;
+
+ *port_mask = 0;
+
+ if (!netif_is_lag_master(conduit)) {
+ dp = conduit->dsa_ptr;
+ if (!dp || dp->ds != ds || !dsa_port_is_cpu(dp)) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Conduit is not a local CPU port");
+ return -EOPNOTSUPP;
+ }
+
+ *port_mask = BIT(dp->index);
+ return 0;
+ }
+
+ id = dsa_lag_id(dst, conduit);
+ if (id < 0)
+ return id;
+
+ dsa_lag_foreach_port(dp, dst, dsa_lag_by_id(dst, id))
+ if (dp->ds == ds && dsa_port_is_cpu(dp))
+ *port_mask |= BIT(dp->index);
+
+ if (!*port_mask) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Conduit LAG has no local CPU port");
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
static int qca8k_update_port_member(struct qca8k_priv *priv, int port,
const struct net_device *bridge_dev,
bool join)
{
bool isolated = !!(priv->port_isolated_map & BIT(port)), other_isolated;
struct dsa_port *dp = dsa_to_port(priv->ds, port), *other_dp;
- u32 port_mask = BIT(dp->cpu_dp->index);
+ u32 port_mask;
int i, ret;
+ ret = qca8k_conduit_port_mask(priv->ds, dsa_port_to_conduit(dp),
+ &port_mask, NULL);
+ if (ret)
+ return ret;
+
for (i = 0; i < QCA8K_NUM_PORTS; i++) {
if (i == port)
continue;
@@ -829,6 +904,14 @@ int qca8k_port_fdb_add(struct dsa_switch *ds, int port,
struct qca8k_priv *priv = ds->priv;
u16 port_mask = BIT(port);
+ /* Unknown unicast flooding delivers host traffic to the conduit. */
+ if (dsa_is_cpu_port(ds, port)) {
+ if (!vid)
+ vid = QCA8K_PORT_VID_DEF;
+
+ return qca8k_fdb_purge_dynamic(priv, addr, vid);
+ }
+
return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
}
@@ -839,6 +922,9 @@ int qca8k_port_fdb_del(struct dsa_switch *ds, int port,
struct qca8k_priv *priv = ds->priv;
u16 port_mask = BIT(port);
+ if (dsa_is_cpu_port(ds, port))
+ return 0;
+
if (!vid)
vid = QCA8K_PORT_VID_DEF;
@@ -868,6 +954,75 @@ int qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
return 0;
}
+static u8 qca8k_lag_port_mask(struct dsa_switch *ds,
+ const struct dsa_lag *lag)
+{
+ struct dsa_port *dp;
+ u8 port_mask = 0;
+
+ dsa_lag_foreach_port(dp, ds->dst, lag)
+ if (dp->ds == ds)
+ port_mask |= BIT(dp->index);
+
+ return port_mask;
+}
+
+static bool qca8k_lag_is_cpu(struct dsa_switch *ds,
+ const struct dsa_lag *lag)
+{
+ struct dsa_port *dp;
+ bool has_cpu = false;
+
+ dsa_lag_foreach_port(dp, ds->dst, lag) {
+ if (dp->ds != ds)
+ continue;
+
+ if (!dsa_port_is_cpu(dp))
+ return false;
+
+ has_cpu = true;
+ }
+
+ return has_cpu;
+}
+
+int qca8k_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag,
+ const unsigned char *addr, u16 vid,
+ struct dsa_db db)
+{
+ struct qca8k_priv *priv = ds->priv;
+ u8 port_mask;
+
+ port_mask = qca8k_lag_port_mask(ds, &lag);
+
+ if (qca8k_lag_is_cpu(ds, &lag)) {
+ if (!vid)
+ vid = QCA8K_PORT_VID_DEF;
+
+ return qca8k_fdb_purge_dynamic(priv, addr, vid);
+ }
+
+ return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
+}
+
+int qca8k_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag,
+ const unsigned char *addr, u16 vid,
+ struct dsa_db db)
+{
+ struct qca8k_priv *priv = ds->priv;
+ u8 port_mask;
+
+ if (qca8k_lag_is_cpu(ds, &lag))
+ return 0;
+
+ if (!vid)
+ vid = QCA8K_PORT_VID_DEF;
+
+ port_mask = qca8k_lag_port_mask(ds, &lag);
+
+ return qca8k_fdb_del(priv, addr, port_mask, vid);
+}
+
int qca8k_port_mdb_add(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb,
struct dsa_db db)
diff --git a/drivers/net/dsa/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h
index 9563388930325..333b343886def 100644
--- a/drivers/net/dsa/qca/qca8k.h
+++ b/drivers/net/dsa/qca/qca8k.h
@@ -523,6 +523,10 @@ int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset);
int qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *eee);
/* Common bridge function */
+int qca8k_conduit_port_mask(struct dsa_switch *ds,
+ struct net_device *conduit,
+ u32 *port_mask,
+ struct netlink_ext_ack *extack);
void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
struct switchdev_brport_flags flags,
@@ -561,6 +565,12 @@ int qca8k_port_fdb_del(struct dsa_switch *ds, int port,
struct dsa_db db);
int qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
dsa_fdb_dump_cb_t *cb, void *data);
+int qca8k_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag lag,
+ const unsigned char *addr, u16 vid,
+ struct dsa_db db);
+int qca8k_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag lag,
+ const unsigned char *addr, u16 vid,
+ struct dsa_db db);
/* Common MDB function */
int qca8k_port_mdb_add(struct dsa_switch *ds, int port,
|
| 3/2 | 2026/08/02 16:22 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8488 output: 34 thoughts: 371 Thoughts: **Analyzing the Reachability of a qca8k DSA Driver Patch** Okay, so I've got this patch for the `qca8k` DSA driver. It's a significant one, adding multi-CPU port support and LAG FDB operations, among other things. It touches `qca8k-8xxx.c`, `qca8k-common.c`, and the header. My immediate thought is, can this even be triggered in a virtualized environment? DSA drivers are notoriously hardware-dependent. They typically rely on a physical Ethernet switch chip connected via MDIO or SPI, that sort of thing. Hmm, can I instantiate a DSA driver like `qca8k` through device tree overlays in QEMU, or even with some sort of dummy device? This is usually how they come up - I mean, `qca8k` is *specifically* for Qualcomm Atheros QCA8337/QCA8327/QCA8328 switches. I need to figure out if there's any QCA8K emulation in QEMU, or at least a fuzzing target. Wait, syzkaller doesn't typically emulate *specific* DSA switch chips unless there's a more generic way to instantiate them, or if it's a software switch. I've been through this before, but does syzkaller have *any* built-in support for injecting device tree nodes or using netlink to configure a DSA setup? No, that's not right. DSA switches are usually defined through device tree or platform data. Okay, I'm getting back to syzkaller's limits. I know it can use `syz_genetlink` and other network fuzzing techniques, but these hardware-specific drivers, without proper QEMU emulation, are generally unreachable. My question remains: can I probe `qca8k` inside QEMU? Let's go search the kernel tree for `qca8k` and see what comes up. That's the first step here. |
| 4/2 | 2026/08/02 16:22 | tool | grepper |
0mArgs:{
"Expression": "qca8k",
"PathPrefix": "drivers/net/dsa/qca/"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 1951 lines.\nUse more precise expression if possible.\n\ndrivers/net/dsa/qca/Makefile=2=obj-$(CONFIG_NET_DSA_AR9331)\t+= ar9331.o\ndrivers/net/dsa/qca/Makefile:3:obj-$(CONFIG_NET_DSA_QCA8K)\t+= qca8k.o\ndrivers/net/dsa/qca/Makefile:4:qca8k-y \t\t\t+= qca8k-common.o qca8k-8xxx.o\ndrivers/net/dsa/qca/Makefile-5-ifdef CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT\ndrivers/net/dsa/qca/Makefile:6:qca8k-y\t\t\t\t+= qca8k-leds.o\ndrivers/net/dsa/qca/Makefile-7-endif\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-23-\ndrivers/net/dsa/qca/qca8k-8xxx.c:24:#include \"qca8k.h\"\ndrivers/net/dsa/qca/qca8k-8xxx.c:25:#include \"qca8k_leds.h\"\ndrivers/net/dsa/qca/qca8k-8xxx.c-26-\ndrivers/net/dsa/qca/qca8k-8xxx.c=27=static void\ndrivers/net/dsa/qca/qca8k-8xxx.c:28:qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)\ndrivers/net/dsa/qca/qca8k-8xxx.c-29-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=40=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:41:qca8k_mii_write_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)\ndrivers/net/dsa/qca/qca8k-8xxx.c-42-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-49-\t\tdev_err_ratelimited(\u0026bus-\u003edev,\ndrivers/net/dsa/qca/qca8k-8xxx.c:50:\t\t\t\t \"failed to write qca8k 32bit lo register\\n\");\ndrivers/net/dsa/qca/qca8k-8xxx.c-51-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=55=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:56:qca8k_mii_write_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)\ndrivers/net/dsa/qca/qca8k-8xxx.c-57-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-64-\t\tdev_err_ratelimited(\u0026bus-\u003edev,\ndrivers/net/dsa/qca/qca8k-8xxx.c:65:\t\t\t\t \"failed to write qca8k 32bit hi register\\n\");\ndrivers/net/dsa/qca/qca8k-8xxx.c-66-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=70=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:71:qca8k_mii_read_lo(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)\ndrivers/net/dsa/qca/qca8k-8xxx.c-72-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-83-\tdev_err_ratelimited(\u0026bus-\u003edev,\ndrivers/net/dsa/qca/qca8k-8xxx.c:84:\t\t\t \"failed to read qca8k 32bit lo register\\n\");\ndrivers/net/dsa/qca/qca8k-8xxx.c-85-\t*val = 0;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=90=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:91:qca8k_mii_read_hi(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)\ndrivers/net/dsa/qca/qca8k-8xxx.c-92-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-103-\tdev_err_ratelimited(\u0026bus-\u003edev,\ndrivers/net/dsa/qca/qca8k-8xxx.c:104:\t\t\t \"failed to read qca8k 32bit hi register\\n\");\ndrivers/net/dsa/qca/qca8k-8xxx.c-105-\t*val = 0;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=110=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:111:qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)\ndrivers/net/dsa/qca/qca8k-8xxx.c-112-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-117-\ndrivers/net/dsa/qca/qca8k-8xxx.c:118:\tret = qca8k_mii_read_lo(bus, phy_id, regnum, \u0026lo);\ndrivers/net/dsa/qca/qca8k-8xxx.c-119-\tif (ret \u003c 0)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-121-\ndrivers/net/dsa/qca/qca8k-8xxx.c:122:\tret = qca8k_mii_read_hi(bus, phy_id, regnum + 1, \u0026hi);\ndrivers/net/dsa/qca/qca8k-8xxx.c-123-\tif (ret \u003c 0)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=132=static void\ndrivers/net/dsa/qca/qca8k-8xxx.c:133:qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)\ndrivers/net/dsa/qca/qca8k-8xxx.c-134-{\ndrivers/net/dsa/qca/qca8k-8xxx.c:135:\tif (qca8k_mii_write_lo(bus, phy_id, regnum, val) \u003c 0)\ndrivers/net/dsa/qca/qca8k-8xxx.c-136-\t\treturn;\ndrivers/net/dsa/qca/qca8k-8xxx.c-137-\ndrivers/net/dsa/qca/qca8k-8xxx.c:138:\tqca8k_mii_write_hi(bus, phy_id, regnum + 1, val);\ndrivers/net/dsa/qca/qca8k-8xxx.c-139-}\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=141=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:142:qca8k_set_page(struct qca8k_priv *priv, u16 page)\ndrivers/net/dsa/qca/qca8k-8xxx.c-143-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-153-\t\tdev_err_ratelimited(\u0026bus-\u003edev,\ndrivers/net/dsa/qca/qca8k-8xxx.c:154:\t\t\t\t \"failed to set qca8k page\\n\");\ndrivers/net/dsa/qca/qca8k-8xxx.c-155-\t\treturn ret;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-162-\ndrivers/net/dsa/qca/qca8k-8xxx.c:163:static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)\ndrivers/net/dsa/qca/qca8k-8xxx.c-164-{\ndrivers/net/dsa/qca/qca8k-8xxx.c:165:\tstruct qca8k_mgmt_eth_data *mgmt_eth_data;\ndrivers/net/dsa/qca/qca8k-8xxx.c:166:\tstruct qca8k_priv *priv = ds-\u003epriv;\ndrivers/net/dsa/qca/qca8k-8xxx.c-167-\tstruct qca_mgmt_ethhdr *mgmt_ethhdr;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-217-\ndrivers/net/dsa/qca/qca8k-8xxx.c:218:static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *val,\ndrivers/net/dsa/qca/qca8k-8xxx.c-219-\t\t\t\t\t int priority, unsigned int len)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-301-\ndrivers/net/dsa/qca/qca8k-8xxx.c:302:static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num)\ndrivers/net/dsa/qca/qca8k-8xxx.c-303-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-311-\ndrivers/net/dsa/qca/qca8k-8xxx.c:312:static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)\ndrivers/net/dsa/qca/qca8k-8xxx.c-313-{\ndrivers/net/dsa/qca/qca8k-8xxx.c:314:\tstruct qca8k_mgmt_eth_data *mgmt_eth_data = \u0026priv-\u003emgmt_eth_data;\ndrivers/net/dsa/qca/qca8k-8xxx.c-315-\tstruct sk_buff *skb;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-318-\ndrivers/net/dsa/qca/qca8k-8xxx.c:319:\tskb = qca8k_alloc_mdio_header(MDIO_READ, reg, NULL,\ndrivers/net/dsa/qca/qca8k-8xxx.c-320-\t\t\t\t QCA8K_ETHERNET_MDIO_PRIORITY, len);\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-338-\tmgmt_eth_data-\u003eseq++;\ndrivers/net/dsa/qca/qca8k-8xxx.c:339:\tqca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data-\u003eseq);\ndrivers/net/dsa/qca/qca8k-8xxx.c-340-\tmgmt_eth_data-\u003eack = false;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-363-\ndrivers/net/dsa/qca/qca8k-8xxx.c:364:static int qca8k_write_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)\ndrivers/net/dsa/qca/qca8k-8xxx.c-365-{\ndrivers/net/dsa/qca/qca8k-8xxx.c:366:\tstruct qca8k_mgmt_eth_data *mgmt_eth_data = \u0026priv-\u003emgmt_eth_data;\ndrivers/net/dsa/qca/qca8k-8xxx.c-367-\tstruct sk_buff *skb;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-370-\ndrivers/net/dsa/qca/qca8k-8xxx.c:371:\tskb = qca8k_alloc_mdio_header(MDIO_WRITE, reg, val,\ndrivers/net/dsa/qca/qca8k-8xxx.c-372-\t\t\t\t QCA8K_ETHERNET_MDIO_PRIORITY, len);\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-390-\tmgmt_eth_data-\u003eseq++;\ndrivers/net/dsa/qca/qca8k-8xxx.c:391:\tqca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data-\u003eseq);\ndrivers/net/dsa/qca/qca8k-8xxx.c-392-\tmgmt_eth_data-\u003eack = false;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=412=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:413:qca8k_regmap_update_bits_eth(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)\ndrivers/net/dsa/qca/qca8k-8xxx.c-414-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-417-\ndrivers/net/dsa/qca/qca8k-8xxx.c:418:\tret = qca8k_read_eth(priv, reg, \u0026val, sizeof(val));\ndrivers/net/dsa/qca/qca8k-8xxx.c-419-\tif (ret)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-424-\ndrivers/net/dsa/qca/qca8k-8xxx.c:425:\treturn qca8k_write_eth(priv, reg, \u0026val, sizeof(val));\ndrivers/net/dsa/qca/qca8k-8xxx.c-426-}\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=428=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:429:qca8k_read_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t *val)\ndrivers/net/dsa/qca/qca8k-8xxx.c-430-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-434-\ndrivers/net/dsa/qca/qca8k-8xxx.c:435:\tqca8k_split_addr(reg, \u0026r1, \u0026r2, \u0026page);\ndrivers/net/dsa/qca/qca8k-8xxx.c-436-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-438-\ndrivers/net/dsa/qca/qca8k-8xxx.c:439:\tret = qca8k_set_page(priv, page);\ndrivers/net/dsa/qca/qca8k-8xxx.c-440-\tif (ret \u003c 0)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-442-\ndrivers/net/dsa/qca/qca8k-8xxx.c:443:\tret = qca8k_mii_read32(bus, 0x10 | r2, r1, val);\ndrivers/net/dsa/qca/qca8k-8xxx.c-444-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=450=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:451:qca8k_write_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t val)\ndrivers/net/dsa/qca/qca8k-8xxx.c-452-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-456-\ndrivers/net/dsa/qca/qca8k-8xxx.c:457:\tqca8k_split_addr(reg, \u0026r1, \u0026r2, \u0026page);\ndrivers/net/dsa/qca/qca8k-8xxx.c-458-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-460-\ndrivers/net/dsa/qca/qca8k-8xxx.c:461:\tret = qca8k_set_page(priv, page);\ndrivers/net/dsa/qca/qca8k-8xxx.c-462-\tif (ret \u003c 0)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-464-\ndrivers/net/dsa/qca/qca8k-8xxx.c:465:\tqca8k_mii_write32(bus, 0x10 | r2, r1, val);\ndrivers/net/dsa/qca/qca8k-8xxx.c-466-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=472=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:473:qca8k_regmap_update_bits_mii(struct qca8k_priv *priv, uint32_t reg,\ndrivers/net/dsa/qca/qca8k-8xxx.c-474-\t\t\t uint32_t mask, uint32_t write_val)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-480-\ndrivers/net/dsa/qca/qca8k-8xxx.c:481:\tqca8k_split_addr(reg, \u0026r1, \u0026r2, \u0026page);\ndrivers/net/dsa/qca/qca8k-8xxx.c-482-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-484-\ndrivers/net/dsa/qca/qca8k-8xxx.c:485:\tret = qca8k_set_page(priv, page);\ndrivers/net/dsa/qca/qca8k-8xxx.c-486-\tif (ret \u003c 0)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-488-\ndrivers/net/dsa/qca/qca8k-8xxx.c:489:\tret = qca8k_mii_read32(bus, 0x10 | r2, r1, \u0026val);\ndrivers/net/dsa/qca/qca8k-8xxx.c-490-\tif (ret \u003c 0)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-494-\tval |= write_val;\ndrivers/net/dsa/qca/qca8k-8xxx.c:495:\tqca8k_mii_write32(bus, 0x10 | r2, r1, val);\ndrivers/net/dsa/qca/qca8k-8xxx.c-496-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=503=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:504:qca8k_bulk_read(void *ctx, const void *reg_buf, size_t reg_len,\ndrivers/net/dsa/qca/qca8k-8xxx.c-505-\t\tvoid *val_buf, size_t val_len)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-507-\tint i, count = val_len / sizeof(u32), ret;\ndrivers/net/dsa/qca/qca8k-8xxx.c:508:\tstruct qca8k_priv *priv = ctx;\ndrivers/net/dsa/qca/qca8k-8xxx.c-509-\tu32 reg = *(u16 *)reg_buf;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-511-\tif (priv-\u003emgmt_conduit \u0026\u0026\ndrivers/net/dsa/qca/qca8k-8xxx.c:512:\t !qca8k_read_eth(priv, reg, val_buf, val_len))\ndrivers/net/dsa/qca/qca8k-8xxx.c-513-\t\treturn 0;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-516-\tfor (i = 0; i \u003c count; i++, reg += sizeof(u32)) {\ndrivers/net/dsa/qca/qca8k-8xxx.c:517:\t\tret = qca8k_read_mii(priv, reg, val_buf + i);\ndrivers/net/dsa/qca/qca8k-8xxx.c-518-\t\tif (ret \u003c 0)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=525=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:526:qca8k_bulk_gather_write(void *ctx, const void *reg_buf, size_t reg_len,\ndrivers/net/dsa/qca/qca8k-8xxx.c-527-\t\t\tconst void *val_buf, size_t val_len)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-529-\tint i, count = val_len / sizeof(u32), ret;\ndrivers/net/dsa/qca/qca8k-8xxx.c:530:\tstruct qca8k_priv *priv = ctx;\ndrivers/net/dsa/qca/qca8k-8xxx.c-531-\tu32 reg = *(u16 *)reg_buf;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-534-\tif (priv-\u003emgmt_conduit \u0026\u0026\ndrivers/net/dsa/qca/qca8k-8xxx.c:535:\t !qca8k_write_eth(priv, reg, val, val_len))\ndrivers/net/dsa/qca/qca8k-8xxx.c-536-\t\treturn 0;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-541-\tfor (i = 0; i \u003c count; i++, reg += sizeof(u32), val++) {\ndrivers/net/dsa/qca/qca8k-8xxx.c:542:\t\tret = qca8k_write_mii(priv, reg, *val);\ndrivers/net/dsa/qca/qca8k-8xxx.c-543-\t\tif (ret \u003c 0)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=550=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:551:qca8k_bulk_write(void *ctx, const void *data, size_t bytes)\ndrivers/net/dsa/qca/qca8k-8xxx.c-552-{\ndrivers/net/dsa/qca/qca8k-8xxx.c:553:\treturn qca8k_bulk_gather_write(ctx, data, sizeof(u16), data + sizeof(u16),\ndrivers/net/dsa/qca/qca8k-8xxx.c-554-\t\t\t\t bytes - sizeof(u16));\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=557=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:558:qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)\ndrivers/net/dsa/qca/qca8k-8xxx.c-559-{\ndrivers/net/dsa/qca/qca8k-8xxx.c:560:\tstruct qca8k_priv *priv = ctx;\ndrivers/net/dsa/qca/qca8k-8xxx.c-561-\ndrivers/net/dsa/qca/qca8k-8xxx.c:562:\tif (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))\ndrivers/net/dsa/qca/qca8k-8xxx.c-563-\t\treturn 0;\ndrivers/net/dsa/qca/qca8k-8xxx.c-564-\ndrivers/net/dsa/qca/qca8k-8xxx.c:565:\treturn qca8k_regmap_update_bits_mii(priv, reg, mask, write_val);\ndrivers/net/dsa/qca/qca8k-8xxx.c-566-}\ndrivers/net/dsa/qca/qca8k-8xxx.c-567-\ndrivers/net/dsa/qca/qca8k-8xxx.c:568:static const struct regmap_config qca8k_regmap_config = {\ndrivers/net/dsa/qca/qca8k-8xxx.c-569-\t.reg_bits = 16,\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-572-\t.max_register = 0x16ac, /* end MIB - Port6 range */\ndrivers/net/dsa/qca/qca8k-8xxx.c:573:\t.read = qca8k_bulk_read,\ndrivers/net/dsa/qca/qca8k-8xxx.c:574:\t.write = qca8k_bulk_write,\ndrivers/net/dsa/qca/qca8k-8xxx.c:575:\t.reg_update_bits = qca8k_regmap_update_bits,\ndrivers/net/dsa/qca/qca8k-8xxx.c:576:\t.rd_table = \u0026qca8k_readable_table,\ndrivers/net/dsa/qca/qca8k-8xxx.c:577:\t.disable_locking = true, /* Locking is handled by qca8k read/write */\ndrivers/net/dsa/qca/qca8k-8xxx.c-578-\t.cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=586=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:587:qca8k_phy_eth_busy_wait(struct qca8k_mgmt_eth_data *mgmt_eth_data,\ndrivers/net/dsa/qca/qca8k-8xxx.c-588-\t\t\tstruct sk_buff *read_skb, u32 *val)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-600-\tmgmt_eth_data-\u003eseq++;\ndrivers/net/dsa/qca/qca8k-8xxx.c:601:\tqca8k_mdio_header_fill_seq_num(skb, mgmt_eth_data-\u003eseq);\ndrivers/net/dsa/qca/qca8k-8xxx.c-602-\tmgmt_eth_data-\u003eack = false;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=622=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:623:qca8k_phy_eth_command(struct qca8k_priv *priv, bool read, int phy,\ndrivers/net/dsa/qca/qca8k-8xxx.c-624-\t\t int regnum, u16 data)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-626-\tstruct sk_buff *write_skb, *clear_skb, *read_skb;\ndrivers/net/dsa/qca/qca8k-8xxx.c:627:\tstruct qca8k_mgmt_eth_data *mgmt_eth_data;\ndrivers/net/dsa/qca/qca8k-8xxx.c-628-\tu32 write_val, clear_val = 0, val;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-649-\t/* Prealloc all the needed skb before the lock */\ndrivers/net/dsa/qca/qca8k-8xxx.c:650:\twrite_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, \u0026write_val,\ndrivers/net/dsa/qca/qca8k-8xxx.c-651-\t\t\t\t\t QCA8K_ETHERNET_PHY_PRIORITY, sizeof(write_val));\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-654-\ndrivers/net/dsa/qca/qca8k-8xxx.c:655:\tclear_skb = qca8k_alloc_mdio_header(MDIO_WRITE, QCA8K_MDIO_MASTER_CTRL, \u0026clear_val,\ndrivers/net/dsa/qca/qca8k-8xxx.c-656-\t\t\t\t\t QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-661-\ndrivers/net/dsa/qca/qca8k-8xxx.c:662:\tread_skb = qca8k_alloc_mdio_header(MDIO_READ, QCA8K_MDIO_MASTER_CTRL, \u0026clear_val,\ndrivers/net/dsa/qca/qca8k-8xxx.c-663-\t\t\t\t\t QCA8K_ETHERNET_PHY_PRIORITY, sizeof(clear_val));\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-702-\tmgmt_eth_data-\u003eseq++;\ndrivers/net/dsa/qca/qca8k-8xxx.c:703:\tqca8k_mdio_header_fill_seq_num(write_skb, mgmt_eth_data-\u003eseq);\ndrivers/net/dsa/qca/qca8k-8xxx.c-704-\tmgmt_eth_data-\u003eack = false;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-724-\ndrivers/net/dsa/qca/qca8k-8xxx.c:725:\tret = read_poll_timeout(qca8k_phy_eth_busy_wait, ret1,\ndrivers/net/dsa/qca/qca8k-8xxx.c-726-\t\t\t\t!(val \u0026 QCA8K_MDIO_MASTER_BUSY), 0,\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-739-\t\tmgmt_eth_data-\u003eseq++;\ndrivers/net/dsa/qca/qca8k-8xxx.c:740:\t\tqca8k_mdio_header_fill_seq_num(read_skb, mgmt_eth_data-\u003eseq);\ndrivers/net/dsa/qca/qca8k-8xxx.c-741-\t\tmgmt_eth_data-\u003eack = false;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-768-\tmgmt_eth_data-\u003eseq++;\ndrivers/net/dsa/qca/qca8k-8xxx.c:769:\tqca8k_mdio_header_fill_seq_num(clear_skb, mgmt_eth_data-\u003eseq);\ndrivers/net/dsa/qca/qca8k-8xxx.c-770-\tmgmt_eth_data-\u003eack = false;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=793=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:794:qca8k_mdio_busy_wait(struct mii_bus *bus, u32 reg, u32 mask)\ndrivers/net/dsa/qca/qca8k-8xxx.c-795-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-799-\ndrivers/net/dsa/qca/qca8k-8xxx.c:800:\tqca8k_split_addr(reg, \u0026r1, \u0026r2, \u0026page);\ndrivers/net/dsa/qca/qca8k-8xxx.c-801-\ndrivers/net/dsa/qca/qca8k-8xxx.c:802:\tret = read_poll_timeout(qca8k_mii_read_hi, ret1, !(val \u0026 mask), 0,\ndrivers/net/dsa/qca/qca8k-8xxx.c-803-\t\t\t\tQCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC, false,\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-805-\ndrivers/net/dsa/qca/qca8k-8xxx.c:806:\t/* Check if qca8k_read has failed for a different reason\ndrivers/net/dsa/qca/qca8k-8xxx.c-807-\t * before returnting -ETIMEDOUT\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=815=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:816:qca8k_mdio_write(struct qca8k_priv *priv, int phy, int regnum, u16 data)\ndrivers/net/dsa/qca/qca8k-8xxx.c-817-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-830-\ndrivers/net/dsa/qca/qca8k-8xxx.c:831:\tqca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, \u0026r1, \u0026r2, \u0026page);\ndrivers/net/dsa/qca/qca8k-8xxx.c-832-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-834-\ndrivers/net/dsa/qca/qca8k-8xxx.c:835:\tret = qca8k_set_page(priv, page);\ndrivers/net/dsa/qca/qca8k-8xxx.c-836-\tif (ret)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-838-\ndrivers/net/dsa/qca/qca8k-8xxx.c:839:\tqca8k_mii_write32(bus, 0x10 | r2, r1, val);\ndrivers/net/dsa/qca/qca8k-8xxx.c-840-\ndrivers/net/dsa/qca/qca8k-8xxx.c:841:\tret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,\ndrivers/net/dsa/qca/qca8k-8xxx.c-842-\t\t\t\t QCA8K_MDIO_MASTER_BUSY);\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-845-\t/* even if the busy_wait timeouts try to clear the MASTER_EN */\ndrivers/net/dsa/qca/qca8k-8xxx.c:846:\tqca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0);\ndrivers/net/dsa/qca/qca8k-8xxx.c-847-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=853=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:854:qca8k_mdio_read(struct qca8k_priv *priv, int phy, int regnum)\ndrivers/net/dsa/qca/qca8k-8xxx.c-855-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-867-\ndrivers/net/dsa/qca/qca8k-8xxx.c:868:\tqca8k_split_addr(QCA8K_MDIO_MASTER_CTRL, \u0026r1, \u0026r2, \u0026page);\ndrivers/net/dsa/qca/qca8k-8xxx.c-869-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-871-\ndrivers/net/dsa/qca/qca8k-8xxx.c:872:\tret = qca8k_set_page(priv, page);\ndrivers/net/dsa/qca/qca8k-8xxx.c-873-\tif (ret)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-875-\ndrivers/net/dsa/qca/qca8k-8xxx.c:876:\tqca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, val);\ndrivers/net/dsa/qca/qca8k-8xxx.c-877-\ndrivers/net/dsa/qca/qca8k-8xxx.c:878:\tret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,\ndrivers/net/dsa/qca/qca8k-8xxx.c-879-\t\t\t\t QCA8K_MDIO_MASTER_BUSY);\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-882-\ndrivers/net/dsa/qca/qca8k-8xxx.c:883:\tret = qca8k_mii_read_lo(bus, 0x10 | r2, r1, \u0026val);\ndrivers/net/dsa/qca/qca8k-8xxx.c-884-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-886-\t/* even if the busy_wait timeouts try to clear the MASTER_EN */\ndrivers/net/dsa/qca/qca8k-8xxx.c:887:\tqca8k_mii_write_hi(bus, 0x10 | r2, r1 + 1, 0);\ndrivers/net/dsa/qca/qca8k-8xxx.c-888-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=897=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:898:qca8k_internal_mdio_write(struct mii_bus *slave_bus, int phy, int regnum, u16 data)\ndrivers/net/dsa/qca/qca8k-8xxx.c-899-{\ndrivers/net/dsa/qca/qca8k-8xxx.c:900:\tstruct qca8k_priv *priv = slave_bus-\u003epriv;\ndrivers/net/dsa/qca/qca8k-8xxx.c-901-\tint ret;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-903-\t/* Use mdio Ethernet when available, fallback to legacy one on error */\ndrivers/net/dsa/qca/qca8k-8xxx.c:904:\tret = qca8k_phy_eth_command(priv, false, phy, regnum, data);\ndrivers/net/dsa/qca/qca8k-8xxx.c-905-\tif (!ret)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-907-\ndrivers/net/dsa/qca/qca8k-8xxx.c:908:\treturn qca8k_mdio_write(priv, phy, regnum, data);\ndrivers/net/dsa/qca/qca8k-8xxx.c-909-}\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=911=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:912:qca8k_internal_mdio_read(struct mii_bus *slave_bus, int phy, int regnum)\ndrivers/net/dsa/qca/qca8k-8xxx.c-913-{\ndrivers/net/dsa/qca/qca8k-8xxx.c:914:\tstruct qca8k_priv *priv = slave_bus-\u003epriv;\ndrivers/net/dsa/qca/qca8k-8xxx.c-915-\tint ret;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-917-\t/* Use mdio Ethernet when available, fallback to legacy one on error */\ndrivers/net/dsa/qca/qca8k-8xxx.c:918:\tret = qca8k_phy_eth_command(priv, true, phy, regnum, 0);\ndrivers/net/dsa/qca/qca8k-8xxx.c-919-\tif (ret \u003e= 0)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-921-\ndrivers/net/dsa/qca/qca8k-8xxx.c:922:\tret = qca8k_mdio_read(priv, phy, regnum);\ndrivers/net/dsa/qca/qca8k-8xxx.c-923-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=930=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:931:qca8k_legacy_mdio_write(struct mii_bus *slave_bus, int port, int regnum, u16 data)\ndrivers/net/dsa/qca/qca8k-8xxx.c-932-{\ndrivers/net/dsa/qca/qca8k-8xxx.c:933:\tport = qca8k_port_to_phy(port) % PHY_MAX_ADDR;\ndrivers/net/dsa/qca/qca8k-8xxx.c-934-\ndrivers/net/dsa/qca/qca8k-8xxx.c:935:\treturn qca8k_internal_mdio_write(slave_bus, port, regnum, data);\ndrivers/net/dsa/qca/qca8k-8xxx.c-936-}\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=938=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:939:qca8k_legacy_mdio_read(struct mii_bus *slave_bus, int port, int regnum)\ndrivers/net/dsa/qca/qca8k-8xxx.c-940-{\ndrivers/net/dsa/qca/qca8k-8xxx.c:941:\tport = qca8k_port_to_phy(port) % PHY_MAX_ADDR;\ndrivers/net/dsa/qca/qca8k-8xxx.c-942-\ndrivers/net/dsa/qca/qca8k-8xxx.c:943:\treturn qca8k_internal_mdio_read(slave_bus, port, regnum);\ndrivers/net/dsa/qca/qca8k-8xxx.c-944-}\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=946=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:947:qca8k_mdio_register(struct qca8k_priv *priv)\ndrivers/net/dsa/qca/qca8k-8xxx.c-948-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-966-\tbus-\u003epriv = (void *)priv;\ndrivers/net/dsa/qca/qca8k-8xxx.c:967:\tsnprintf(bus-\u003eid, MII_BUS_ID_SIZE, \"qca8k-%d.%d\",\ndrivers/net/dsa/qca/qca8k-8xxx.c-968-\t\t ds-\u003edst-\u003eindex, ds-\u003eindex);\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-972-\t\t/* Check if the device tree declares the port:phy mapping */\ndrivers/net/dsa/qca/qca8k-8xxx.c:973:\t\tbus-\u003ename = \"qca8k user mii\";\ndrivers/net/dsa/qca/qca8k-8xxx.c:974:\t\tbus-\u003eread = qca8k_internal_mdio_read;\ndrivers/net/dsa/qca/qca8k-8xxx.c:975:\t\tbus-\u003ewrite = qca8k_internal_mdio_write;\ndrivers/net/dsa/qca/qca8k-8xxx.c-976-\t} else {\ndrivers/net/dsa/qca/qca8k-8xxx.c-977-\t\t/* If a mapping can't be found, the legacy mapping is used,\ndrivers/net/dsa/qca/qca8k-8xxx.c:978:\t\t * using qca8k_port_to_phy()\ndrivers/net/dsa/qca/qca8k-8xxx.c-979-\t\t */\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-981-\t\tbus-\u003ephy_mask = ~ds-\u003ephys_mii_mask;\ndrivers/net/dsa/qca/qca8k-8xxx.c:982:\t\tbus-\u003ename = \"qca8k-legacy user mii\";\ndrivers/net/dsa/qca/qca8k-8xxx.c:983:\t\tbus-\u003eread = qca8k_legacy_mdio_read;\ndrivers/net/dsa/qca/qca8k-8xxx.c:984:\t\tbus-\u003ewrite = qca8k_legacy_mdio_write;\ndrivers/net/dsa/qca/qca8k-8xxx.c-985-\t}\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=994=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:995:qca8k_setup_mdio_bus(struct qca8k_priv *priv)\ndrivers/net/dsa/qca/qca8k-8xxx.c-996-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1041-\t * If the external mdio-bus driver is capable magically disabling\ndrivers/net/dsa/qca/qca8k-8xxx.c:1042:\t * the QCA8K_MDIO_MASTER_EN and mutex/spin-locking out the qca8k's\ndrivers/net/dsa/qca/qca8k-8xxx.c-1043-\t * accessors for the time being, it would be possible to pull this\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1059-\ndrivers/net/dsa/qca/qca8k-8xxx.c:1060:\treturn qca8k_mdio_register(priv);\ndrivers/net/dsa/qca/qca8k-8xxx.c-1061-}\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=1063=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:1064:qca8k_setup_mac_pwr_sel(struct qca8k_priv *priv)\ndrivers/net/dsa/qca/qca8k-8xxx.c-1065-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1080-\tif (mask) {\ndrivers/net/dsa/qca/qca8k-8xxx.c:1081:\t\tret = qca8k_rmw(priv, QCA8K_REG_MAC_PWR_SEL,\ndrivers/net/dsa/qca/qca8k-8xxx.c-1082-\t\t\t\tQCA8K_MAC_PWR_RGMII0_1_8V |\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=1090=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:1091:qca8k_setup_of_pws_reg(struct qca8k_priv *priv)\ndrivers/net/dsa/qca/qca8k-8xxx.c-1092-{\ndrivers/net/dsa/qca/qca8k-8xxx.c:1093:\tconst struct qca8k_match_data *data = priv-\u003einfo;\ndrivers/net/dsa/qca/qca8k-8xxx.c-1094-\tstruct device_node *node = priv-\u003edev-\u003eof_node;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1106-\ndrivers/net/dsa/qca/qca8k-8xxx.c:1107:\t\tret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8327_PWS_PACKAGE148_EN,\ndrivers/net/dsa/qca/qca8k-8xxx.c-1108-\t\t\t\tval);\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1124-\ndrivers/net/dsa/qca/qca8k-8xxx.c:1125:\treturn qca8k_rmw(priv, QCA8K_REG_PWS,\ndrivers/net/dsa/qca/qca8k-8xxx.c-1126-\t\t\tQCA8K_PWS_LED_OPEN_EN_CSR | QCA8K_PWS_POWER_ON_SEL,\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=1130=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:1131:qca8k_parse_port_config(struct qca8k_priv *priv)\ndrivers/net/dsa/qca/qca8k-8xxx.c-1132-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=1228=static void\ndrivers/net/dsa/qca/qca8k-8xxx.c:1229:qca8k_mac_config_setup_internal_delay(struct qca8k_priv *priv, int cpu_port_index,\ndrivers/net/dsa/qca/qca8k-8xxx.c-1230-\t\t\t\t u32 reg)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1257-\t/* Set RGMII delay based on the selected values */\ndrivers/net/dsa/qca/qca8k-8xxx.c:1258:\tret = qca8k_rmw(priv, reg,\ndrivers/net/dsa/qca/qca8k-8xxx.c-1259-\t\t\tQCA8K_PORT_PAD_RGMII_TX_DELAY_MASK |\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=1269=static struct phylink_pcs *\ndrivers/net/dsa/qca/qca8k-8xxx.c:1270:qca8k_phylink_mac_select_pcs(struct phylink_config *config,\ndrivers/net/dsa/qca/qca8k-8xxx.c-1271-\t\t\t phy_interface_t interface)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1273-\tstruct dsa_port *dp = dsa_phylink_to_port(config);\ndrivers/net/dsa/qca/qca8k-8xxx.c:1274:\tstruct qca8k_priv *priv = dp-\u003eds-\u003epriv;\ndrivers/net/dsa/qca/qca8k-8xxx.c-1275-\tstruct phylink_pcs *pcs = NULL;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=1299=static void\ndrivers/net/dsa/qca/qca8k-8xxx.c:1300:qca8k_phylink_mac_config(struct phylink_config *config, unsigned int mode,\ndrivers/net/dsa/qca/qca8k-8xxx.c-1301-\t\t\t const struct phylink_link_state *state)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1304-\tstruct dsa_switch *ds = dp-\u003eds;\ndrivers/net/dsa/qca/qca8k-8xxx.c:1305:\tstruct qca8k_priv *priv;\ndrivers/net/dsa/qca/qca8k-8xxx.c-1306-\tint port = dp-\u003eindex;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1358-\tcase PHY_INTERFACE_MODE_RGMII_RXID:\ndrivers/net/dsa/qca/qca8k-8xxx.c:1359:\t\tqca8k_write(priv, reg, QCA8K_PORT_PAD_RGMII_EN);\ndrivers/net/dsa/qca/qca8k-8xxx.c-1360-\ndrivers/net/dsa/qca/qca8k-8xxx.c-1361-\t\t/* Configure rgmii delay */\ndrivers/net/dsa/qca/qca8k-8xxx.c:1362:\t\tqca8k_mac_config_setup_internal_delay(priv, cpu_port_index, reg);\ndrivers/net/dsa/qca/qca8k-8xxx.c-1363-\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1368-\t\tif (priv-\u003eswitch_id == QCA8K_ID_QCA8337)\ndrivers/net/dsa/qca/qca8k-8xxx.c:1369:\t\t\tqca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL,\ndrivers/net/dsa/qca/qca8k-8xxx.c-1370-\t\t\t\t QCA8K_PORT_PAD_RGMII_RX_DELAY_EN);\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1374-\t\t/* Enable SGMII on the port */\ndrivers/net/dsa/qca/qca8k-8xxx.c:1375:\t\tqca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);\ndrivers/net/dsa/qca/qca8k-8xxx.c-1376-\t\tbreak;\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-1383-\ndrivers/net/dsa/qca/qca8k-8xxx.c:1384:static void qca8k_phylink_get_caps(struct dsa_switch *ds, int port,\ndrivers/net/dsa/qca/qca8k-8xxx.c-1385-\t\t\t\t struct phylink_config *config)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=1419=static void\ndrivers/net/dsa/qca/qca8k-8xxx.c:1420:qca8k_phylink_mac_link_down(struct phylink_config *config, unsigned int mode,\ndrivers/net/dsa/qca/qca8k-8xxx.c-1421-\t\t\t phy_interface_t interface)\n\n"
} |
| 5/2 | 2026/08/02 16:22 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 24417 output: 40 thoughts: 635 Thoughts: **Analyzing the Fuzzing Potential of a QCA8K Driver Patch** Okay, so I'm looking at this patch and my initial thought is that it touches the `qca8k` driver, which from what I understand, registers a DSA switch. My immediate goal is to figure out if this is something we can even fuzz effectively, and that means determining if we can instantiate it without relying on actual hardware. DSA drivers typically use the device tree, so my brain is immediately going down that path. Can we inject a device tree overlay to bring the driver up? Syzkaller, of course, comes to mind. It has ways to inject things (though I'm still trying to remember exactly what it can do). I know it has `syz_mount_image` and `syz_read_part_sector` – but for DT injection specifically, it's not clear. Does it use `syz_genetlink`? No, wait, doesn't syzkaller have `syz_dev_dt_overlay` or something? Hold on, no, Syzkaller doesn't have a *generic* DT overlay injector in upstream Linux unless it's via configfs. A related question is: does Syzkaller *even* test DSA drivers? Let me see if `CONFIG_NET_DSA_QCA8K` is enabled in syzbot. I should also check if there are any syzbot reports related to `qca8k`. Oh, interesting - the commit author is `syz-cluster <triage@syzkaller.com>`. So, this likely means the patch was submitted to syz-cluster for testing, or it's a patch under review that syz-cluster is testing. The instructions say to return `WorthFuzzing=false` if the patch concerns code paths unreachable in virtualized environments like QEMU. That's key: can we reach `qca8k` code in QEMU? Now, thinking about it, `qca8k` is an MDIO device. Are there ways to emulate MDIO buses in QEMU, maybe through `mdio-bcm-unimac` or similar? No, QEMU doesn't seem to emulate a `qca8k` specifically. But wait, can syzkaller somehow instantiate MDIO devices using a netlink API or sysfs? Like it has `syz_genetlink` and `syz_80211_...`. Unfortunately, there isn't a generic software emulator in the kernel for MDIO devices, like there is `mac80211_hwsim` or `vhci` for USB. Wait, there's `dsa_loop`, a software-emulated DSA switch, but `qca8k` is a driver for *specific* hardware. This brings me back to the core question: Is it possible to reach the `qca8k` code in QEMU? I should check if there’s any QEMU emulation for it. Okay, I'll search for `qca8k` within `drivers/net/dsa/qca/qca8k-8xxx.c` to see how it's probed and try to get a better handle on the potential for emulation. |
| 6/2 | 2026/08/02 16:23 | tool | grepper |
0mArgs:{
"Expression": "probe",
"PathPrefix": "drivers/net/dsa/qca/qca8k-8xxx.c"
}Results: {
"Output": "drivers/net/dsa/qca/qca8k-8xxx.c=2173=static int\ndrivers/net/dsa/qca/qca8k-8xxx.c:2174:qca8k_sw_probe(struct mdio_device *mdiodev)\ndrivers/net/dsa/qca/qca8k-8xxx.c-2175-{\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-2178-\ndrivers/net/dsa/qca/qca8k-8xxx.c:2179:\t/* allocate the private data struct so that we can probe the switches\ndrivers/net/dsa/qca/qca8k-8xxx.c-2180-\t * ID register\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c=2336=static struct mdio_driver qca8kmdio_driver = {\ndrivers/net/dsa/qca/qca8k-8xxx.c:2337:\t.probe = qca8k_sw_probe,\ndrivers/net/dsa/qca/qca8k-8xxx.c-2338-\t.remove = qca8k_sw_remove,\n"
} |
| 7/2 | 2026/08/02 16:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 26132 output: 23 thoughts: 231 Thoughts: **MDIO Device Instantiation: A Deep Dive** Okay, so I'm looking at this `mdio_driver` and immediately I'm wondering about the mechanics of device creation. Can I conjure an `mdio_device` from userspace, or does the kernel offer some clever software emulation pathway? I recall there being something like `mdio-mockup`, but that's not quite it. Aha! `mdio-gpio` requires actual hardware interaction, so that's a dead end. Wait a minute, wasn't there `dsa_loop`? Yes! It *is* an MDIO device. And it cleverly utilizes `fixed-link` and a mock MDIO bus. Interesting... But the real question is, can I actually instantiate a `qca8k` device on a *mock* MDIO bus using a userspace approach? Typically, MDIO devices are born through the Device Tree, right? If the kernel doesn't offer a backdoor to inject DT nodes - and syzkaller, my go-to fuzzing tool, typically can't do that unless we're dealing with `CONFIG_OF_OVERLAY` and a userspace interface (which is not standard for fuzzing)– then it's a non-starter. This is usually what happens. Hold on... didn't I read something about syzkaller actually *being* able to inject DT overlays? It hit me! Syzkaller *does* have a `syz_dev_dt_overlay` pseudo-syscall. That's the key! Now I need to verify that and see if this solves my problem. This could be a game-changer for my fuzzing strategy! |
| 8/2 | 2026/08/02 16:23 | tool | grepper |
0mArgs:{
"Expression": "syz_",
"PathPrefix": ""
}Results: {
"Output": "drivers/iommu/iommufd/ioas.c=283=int iommufd_ioas_copy(struct iommufd_ucmd *ucmd)\n--\ndrivers/iommu/iommufd/ioas.c-292-\ndrivers/iommu/iommufd/ioas.c:293:\tiommufd_test_syz_conv_iova_id(ucmd, cmd-\u003esrc_ioas_id, \u0026cmd-\u003esrc_iova,\ndrivers/iommu/iommufd/ioas.c-294-\t\t\t\t \u0026cmd-\u003eflags);\n--\ndrivers/iommu/iommufd/iommufd_private.h=712=extern size_t iommufd_test_memory_limit;\ndrivers/iommu/iommufd/iommufd_private.h:713:void iommufd_test_syz_conv_iova_id(struct iommufd_ucmd *ucmd,\ndrivers/iommu/iommufd/iommufd_private.h-714-\t\t\t\t unsigned int ioas_id, u64 *iova, u32 *flags);\n--\ndrivers/iommu/iommufd/iommufd_private.h=719=int iommufd_test_dma_buf_iommufd_map(struct dma_buf_attachment *attachment,\n--\ndrivers/iommu/iommufd/iommufd_private.h-721-#else\ndrivers/iommu/iommufd/iommufd_private.h:722:static inline void iommufd_test_syz_conv_iova_id(struct iommufd_ucmd *ucmd,\ndrivers/iommu/iommufd/iommufd_private.h-723-\t\t\t\t\t\t unsigned int ioas_id,\n--\ndrivers/iommu/iommufd/selftest.c=51=static void mock_dev_disable_iopf(struct device *dev, struct iommu_domain *domain);\n--\ndrivers/iommu/iommufd/selftest.c-58- */\ndrivers/iommu/iommufd/selftest.c:59:static unsigned long __iommufd_test_syz_conv_iova(struct io_pagetable *iopt,\ndrivers/iommu/iommufd/selftest.c-60-\t\t\t\t\t\t u64 *iova)\ndrivers/iommu/iommufd/selftest.c-61-{\ndrivers/iommu/iommufd/selftest.c:62:\tstruct syz_layout {\ndrivers/iommu/iommufd/selftest.c-63-\t\t__u32 nth_area;\n--\ndrivers/iommu/iommufd/selftest.c-65-\t};\ndrivers/iommu/iommufd/selftest.c:66:\tstruct syz_layout *syz = (void *)iova;\ndrivers/iommu/iommufd/selftest.c-67-\tunsigned int nth = syz-\u003enth_area;\n--\ndrivers/iommu/iommufd/selftest.c-83-\ndrivers/iommu/iommufd/selftest.c:84:static unsigned long iommufd_test_syz_conv_iova(struct iommufd_access *access,\ndrivers/iommu/iommufd/selftest.c-85-\t\t\t\t\t\tu64 *iova)\n--\ndrivers/iommu/iommufd/selftest.c-93-\t}\ndrivers/iommu/iommufd/selftest.c:94:\tret = __iommufd_test_syz_conv_iova(\u0026access-\u003eioas-\u003eiopt, iova);\ndrivers/iommu/iommufd/selftest.c-95-\tmutex_unlock(\u0026access-\u003eioas_lock);\n--\ndrivers/iommu/iommufd/selftest.c-98-\ndrivers/iommu/iommufd/selftest.c:99:void iommufd_test_syz_conv_iova_id(struct iommufd_ucmd *ucmd,\ndrivers/iommu/iommufd/selftest.c-100-\t\t\t\t unsigned int ioas_id, u64 *iova, u32 *flags)\n--\ndrivers/iommu/iommufd/selftest.c-110-\t\treturn;\ndrivers/iommu/iommufd/selftest.c:111:\t*iova = __iommufd_test_syz_conv_iova(\u0026ioas-\u003eiopt, iova);\ndrivers/iommu/iommufd/selftest.c-112-\tiommufd_put_object(ucmd-\u003eictx, \u0026ioas-\u003eobj);\n--\ndrivers/iommu/iommufd/selftest.c=1529=static int iommufd_test_access_pages(struct iommufd_ucmd *ucmd,\n--\ndrivers/iommu/iommufd/selftest.c-1557-\tif (flags \u0026 MOCK_FLAGS_ACCESS_SYZ)\ndrivers/iommu/iommufd/selftest.c:1558:\t\tiova = iommufd_test_syz_conv_iova(staccess-\u003eaccess,\ndrivers/iommu/iommufd/selftest.c-1559-\t\t\t\t\t\t \u0026cmd-\u003eaccess_pages.iova);\n--\ndrivers/iommu/iommufd/selftest.c=1624=static int iommufd_test_access_rw(struct iommufd_ucmd *ucmd,\n--\ndrivers/iommu/iommufd/selftest.c-1659-\tif (flags \u0026 MOCK_FLAGS_ACCESS_SYZ)\ndrivers/iommu/iommufd/selftest.c:1660:\t\tiova = iommufd_test_syz_conv_iova(staccess-\u003eaccess,\ndrivers/iommu/iommufd/selftest.c-1661-\t\t\t\t\t\t \u0026cmd-\u003eaccess_rw.iova);\n"
} |
| 9/2 | 2026/08/02 16:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 28320 output: 49 thoughts: 604 Thoughts: **Analyzing the Fuzzing Applicability of the `qca8k` Driver** Okay, first things first, I need to remind myself that I *cannot* search for any `syz_` prefixes directly in the kernel tree. The prompt specifically told me that. I should be using `read-syz-spec` or `syz-grepper` for that, but I don't see those in my available tools according to the `declaration` list: `default_api:grepper`, `default_api:codesearch-dir-index`, `default_api:read-file`, `default_api:set-results`. So, scratch that. Now, my primary question is whether this `qca8k` driver is even reachable in a typical virtualized environment. The prompt is very clear that if something relies on hardware not emulated in GCE or QEMU, even with software emulation, then it's a no-go for fuzzing purposes. It flags PCIe switch drivers and SmartNIC drivers as immediate red flags if they need a physical PCIe card. Let's break down `qca8k`. It's a Qualcomm Atheros DSA switch driver, so it's vendor-specific, and it connects via MDIO. Hmm, I don't recall seeing any QEMU emulation for QCA8K. And can it be instantiated via software emulated hardware? The prompt is pretty stringent: no, since I don't see any software-emulated MDIO bus that allows instantiation of arbitrary MDIO devices from userspace in standard QEMU/syzkaller setups. Wait, syzkaller does have `syz_genetlink` but that's for netlink, and I don't think that's the same thing as DSA. I can't easily check for syzbot reports, but let's see if there are any obvious fuzzing entry points in the kernel for DSA in general. Aha, the `dsa_loop` is a mock DSA driver. Okay, but that's not `qca8k`; it's a specific hardware driver. If `qca8k` requires a physical MDIO bus and a specific PHY ID to probe successfully, it's just not going to work in QEMU. Looks like I should take a look at `qca8k_sw_probe`. This looks like a dead end for fuzzing unless there are some serious kernel emulations available that I haven't heard about. |
| 10/2 | 2026/08/02 16:23 | tool | read-file |
0mArgs:{
"File": "drivers/net/dsa/qca/qca8k-8xxx.c",
"FirstLine": 2170,
"LineCount": 100
}Results: {
"Contents": "2170:\t\t.connect_tag_protocol\t= qca8k_connect_tag_protocol,\n2171:\t};\n2172:\t\n2173:\tstatic int\n2174:\tqca8k_sw_probe(struct mdio_device *mdiodev)\n2175:\t{\n2176:\t\tstruct qca8k_priv *priv;\n2177:\t\tint ret;\n2178:\t\n2179:\t\t/* allocate the private data struct so that we can probe the switches\n2180:\t\t * ID register\n2181:\t\t */\n2182:\t\tpriv = devm_kzalloc(\u0026mdiodev-\u003edev, sizeof(*priv), GFP_KERNEL);\n2183:\t\tif (!priv)\n2184:\t\t\treturn -ENOMEM;\n2185:\t\n2186:\t\tpriv-\u003ebus = mdiodev-\u003ebus;\n2187:\t\tpriv-\u003edev = \u0026mdiodev-\u003edev;\n2188:\t\tpriv-\u003einfo = of_device_get_match_data(priv-\u003edev);\n2189:\t\n2190:\t\tpriv-\u003ereset_gpio = devm_gpiod_get_optional(priv-\u003edev, \"reset\",\n2191:\t\t\t\t\t\t\t GPIOD_OUT_HIGH);\n2192:\t\tif (IS_ERR(priv-\u003ereset_gpio))\n2193:\t\t\treturn PTR_ERR(priv-\u003ereset_gpio);\n2194:\t\n2195:\t\tif (priv-\u003ereset_gpio) {\n2196:\t\t\t/* The active low duration must be greater than 10 ms\n2197:\t\t\t * and checkpatch.pl wants 20 ms.\n2198:\t\t\t */\n2199:\t\t\tmsleep(20);\n2200:\t\t\tgpiod_set_value_cansleep(priv-\u003ereset_gpio, 0);\n2201:\t\t}\n2202:\t\n2203:\t\t/* Start by setting up the register mapping */\n2204:\t\tpriv-\u003eregmap = devm_regmap_init(\u0026mdiodev-\u003edev, NULL, priv,\n2205:\t\t\t\t\t\t\u0026qca8k_regmap_config);\n2206:\t\tif (IS_ERR(priv-\u003eregmap)) {\n2207:\t\t\tdev_err(priv-\u003edev, \"regmap initialization failed\");\n2208:\t\t\treturn PTR_ERR(priv-\u003eregmap);\n2209:\t\t}\n2210:\t\n2211:\t\tpriv-\u003emdio_cache.page = 0xffff;\n2212:\t\n2213:\t\t/* Check the detected switch id */\n2214:\t\tret = qca8k_read_switch_id(priv);\n2215:\t\tif (ret)\n2216:\t\t\treturn ret;\n2217:\t\n2218:\t\tpriv-\u003eds = devm_kzalloc(\u0026mdiodev-\u003edev, sizeof(*priv-\u003eds), GFP_KERNEL);\n2219:\t\tif (!priv-\u003eds)\n2220:\t\t\treturn -ENOMEM;\n2221:\t\n2222:\t\tmutex_init(\u0026priv-\u003emgmt_eth_data.mutex);\n2223:\t\tinit_completion(\u0026priv-\u003emgmt_eth_data.rw_done);\n2224:\t\n2225:\t\tmutex_init(\u0026priv-\u003emib_eth_data.mutex);\n2226:\t\tinit_completion(\u0026priv-\u003emib_eth_data.rw_done);\n2227:\t\n2228:\t\tpriv-\u003eds-\u003edev = \u0026mdiodev-\u003edev;\n2229:\t\tpriv-\u003eds-\u003enum_ports = QCA8K_NUM_PORTS;\n2230:\t\tpriv-\u003eds-\u003epriv = priv;\n2231:\t\tpriv-\u003eds-\u003eops = \u0026qca8k_switch_ops;\n2232:\t\tpriv-\u003eds-\u003ephylink_mac_ops = \u0026qca8k_phylink_mac_ops;\n2233:\t\tmutex_init(\u0026priv-\u003ereg_mutex);\n2234:\t\tdev_set_drvdata(\u0026mdiodev-\u003edev, priv);\n2235:\t\n2236:\t\treturn dsa_register_switch(priv-\u003eds);\n2237:\t}\n2238:\t\n2239:\tstatic void\n2240:\tqca8k_sw_remove(struct mdio_device *mdiodev)\n2241:\t{\n2242:\t\tstruct qca8k_priv *priv = dev_get_drvdata(\u0026mdiodev-\u003edev);\n2243:\t\tint i;\n2244:\t\n2245:\t\tif (!priv)\n2246:\t\t\treturn;\n2247:\t\n2248:\t\tfor (i = 0; i \u003c QCA8K_NUM_PORTS; i++)\n2249:\t\t\tqca8k_port_set_status(priv, i, 0);\n2250:\t\n2251:\t\tdsa_unregister_switch(priv-\u003eds);\n2252:\t}\n2253:\t\n2254:\tstatic void qca8k_sw_shutdown(struct mdio_device *mdiodev)\n2255:\t{\n2256:\t\tstruct qca8k_priv *priv = dev_get_drvdata(\u0026mdiodev-\u003edev);\n2257:\t\n2258:\t\tif (!priv)\n2259:\t\t\treturn;\n2260:\t\n2261:\t\tdsa_switch_shutdown(priv-\u003eds);\n2262:\t\n2263:\t\tdev_set_drvdata(\u0026mdiodev-\u003edev, NULL);\n2264:\t}\n2265:\t\n2266:\t#ifdef CONFIG_PM_SLEEP\n2267:\tstatic void\n2268:\tqca8k_set_pm(struct qca8k_priv *priv, int enable)\n2269:\t{\n"
} |
| 11/2 | 2026/08/02 16:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 31029 output: 49 thoughts: 34 Thoughts: Okay, here's my take on those thoughts, framed from my perspective as a networking expert: **Digging into the QCA8K Switch Probe Function** Alright, so `qca8k_sw_probe` has been called. Naturally, the first thing I want to understand is what it's doing under the hood, so I immediately look at the subsequent function call, `qca8k_read_switch_id(priv)`. That makes perfect sense; before you can configure or manage a switch, you *need* to identify it. It's the absolute foundational step in the initialization process. Knowing the specific chip revision, vendor ID, and model helps determine the exact hardware in play and, by extension, which configuration options and register mappings are applicable. My next question would be how the `priv` argument is structured and which data members I need to understand. I'll need to figure out if it's reading the ID from a register, a flash device, or somewhere else entirely and how this ID is actually used by the driver later on. Knowing this, I can start to develop a mental map of the probing stage and how the QCA8K driver handles basic device identification. |
| 12/2 | 2026/08/02 16:23 | tool | grepper |
0mArgs:{
"Expression": "qca8k_read_switch_id",
"PathPrefix": "drivers/net/dsa/qca/qca8k-8xxx.c"
}Results: {
"Output": "drivers/net/dsa/qca/qca8k-8xxx.c=2174=qca8k_sw_probe(struct mdio_device *mdiodev)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-2213-\t/* Check the detected switch id */\ndrivers/net/dsa/qca/qca8k-8xxx.c:2214:\tret = qca8k_read_switch_id(priv);\ndrivers/net/dsa/qca/qca8k-8xxx.c-2215-\tif (ret)\n"
} |
| 13/2 | 2026/08/02 16:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 31530 output: 40 thoughts: 35 Thoughts: Here's my attempt at summarizing the thought process, tailored for an expert audience: **Investigating the Location of `qca8k_read_switch_id`** Okay, so I'm dealing with the `qca8k_read_switch_id` function. The name itself suggests it's likely related to reading the identifier from a QCA8K switch. But where is that defined, specifically? I seem to recall it being in `qca8k-common.c` or a similar common file within that QCA8K driver suite. Time to verify. I need to quickly confirm its source before I proceed any further with this current task. Just need to quickly confirm where it's actually defined within the relevant source files. |
| 14/2 | 2026/08/02 16:23 | tool | grepper |
0mArgs:{
"Expression": "qca8k_read_switch_id",
"PathPrefix": "drivers/net/dsa/qca/"
}Results: {
"Output": "drivers/net/dsa/qca/qca8k-8xxx.c=2174=qca8k_sw_probe(struct mdio_device *mdiodev)\n--\ndrivers/net/dsa/qca/qca8k-8xxx.c-2213-\t/* Check the detected switch id */\ndrivers/net/dsa/qca/qca8k-8xxx.c:2214:\tret = qca8k_read_switch_id(priv);\ndrivers/net/dsa/qca/qca8k-8xxx.c-2215-\tif (ret)\n--\ndrivers/net/dsa/qca/qca8k-common.c=1379=int qca8k_port_lag_leave(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/qca/qca8k-common.c-1384-\ndrivers/net/dsa/qca/qca8k-common.c:1385:int qca8k_read_switch_id(struct qca8k_priv *priv)\ndrivers/net/dsa/qca/qca8k-common.c-1386-{\n--\ndrivers/net/dsa/qca/qca8k.h=505=void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable);\ndrivers/net/dsa/qca/qca8k.h:506:int qca8k_read_switch_id(struct qca8k_priv *priv);\ndrivers/net/dsa/qca/qca8k.h-507-\n"
} |
| 15/2 | 2026/08/02 16:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 32198 output: 47 thoughts: 16 Thoughts: Okay, let's dive into this `qca8k_read_switch_id` function. Here's how I'm approaching it: **Dissecting `qca8k_read_switch_id`** My initial thought is to understand its purpose. Based on the name, it's pretty clear: it's designed to read the switch ID, likely from a QCA8K-based switch. Now, I need to figure out the context. Where does this function live? Is it part of a larger driver or SDK? What are the calling conventions? What platform am I working with? Knowing the broader environment is crucial for effective analysis. I'll start by looking at the function signature. What are the input parameters? Are there pointers, integers, or structures involved? The return value is key, as it'll likely indicate success or failure, and perhaps the actual switch ID itself. I'll need to pay close attention to the data types to understand the underlying hardware representation. Then, I'll examine the function's internal logic. How does it actually *read* this ID? Does it involve register access, perhaps using I2C or MDIO? Are there any specific sequences of operations? Are there any error checks in place? I will likely be looking for bit manipulation and address decoding. I'll be looking for common patterns related to QCA8K communication. I'll have to consider interrupt handling if that is part of the implementation. Furthermore, I'll think about potential failure modes. What can go wrong during the ID reading process? Are there timeouts? What error codes are defined, and what do they signify? I'll probably be checking for common pitfalls such as invalid register addresses, communication errors, and incorrect data interpretation. Finally, I'll consider how this function fits into the overall system. Is it part of a larger initialization sequence? Does the switch ID influence any other configuration or behavior? How does it handle potential revisions and variations of the QCA8K silicon? Understanding the larger architecture is absolutely crucial for fully understanding the role and impact of this function. |
| 16/2 | 2026/08/02 16:23 | tool | read-file |
0mArgs:{
"File": "drivers/net/dsa/qca/qca8k-common.c",
"FirstLine": 1385,
"LineCount": 40
}Results: {
"Contents": "1385:\tint qca8k_read_switch_id(struct qca8k_priv *priv)\n1386:\t{\n1387:\t\tu32 val;\n1388:\t\tu8 id;\n1389:\t\tint ret;\n1390:\t\n1391:\t\tif (!priv-\u003einfo)\n1392:\t\t\treturn -ENODEV;\n1393:\t\n1394:\t\tret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, \u0026val);\n1395:\t\tif (ret \u003c 0)\n1396:\t\t\treturn -ENODEV;\n1397:\t\n1398:\t\tid = QCA8K_MASK_CTRL_DEVICE_ID(val);\n1399:\t\tif (id != priv-\u003einfo-\u003eid) {\n1400:\t\t\tdev_err(priv-\u003edev,\n1401:\t\t\t\t\"Switch id detected %x but expected %x\",\n1402:\t\t\t\tid, priv-\u003einfo-\u003eid);\n1403:\t\t\treturn -ENODEV;\n1404:\t\t}\n1405:\t\n1406:\t\tpriv-\u003eswitch_id = id;\n1407:\t\n1408:\t\t/* Save revision to communicate to the internal PHY driver */\n1409:\t\tpriv-\u003eswitch_revision = QCA8K_MASK_CTRL_REV_ID(val);\n1410:\t\n1411:\t\treturn 0;\n1412:\t}\n"
} |
| 17/2 | 2026/08/02 16:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 33105 output: 28 thoughts: 548 Thoughts: **My Assessment of the QCA8K Driver's Fuzzability** Okay, let me break this down. My initial thought is that the `qca8k` driver, which is a Qualcomm Atheros switch driver, is likely *not* fuzzable in standard virtualized environments. The code performs a register read using `qca8k_read`, and if that fails or the device ID doesn't match, it returns `-ENODEV`. Since it's an MDIO device, `qca8k_read` relies on MDIO reads, and those will fail or return 0xffff in the absence of the actual hardware, leading to a failed probe. I considered whether syzkaller might have a way around this, perhaps through `syz_genetlink` or something similar, but that wouldn't mock MDIO devices. I also wondered if it was related to the prompt about vendor-specific PCIe switch drivers, but `qca8k` is MDIO, not PCIe. It appears QEMU *doesn't* emulate the QCA8K switch chip, so it seems it's unreachable in virtualized setups. Could syzkaller potentially use a `dummy` or `dsa_loop` mock? `dsa_loop` is a mock DSA driver, but it has its own driver code (`dsa_loop.c`) and doesn't utilize `qca8k`. Therefore, that `qca8k` code seems unreachable without the actual hardware or some kind of specific emulation. I checked, and there's no `qca8k` emulation in QEMU. The commit message mentioning a "patch under review" in syzkaller is interesting, but if the code is genuinely unreachable, then syzkaller won't be able to fuzz it effectively, and we will get no coverage. That would mean it's unlikely the patch is fuzzing this. Therefore, I need to conclude that the `qca8k` code paths in `qca8k-8xxx.c` and `qca8k-common.c` are impossible to reach in virtualized environments like GCE or QEMU. My conclusion is that `WorthFuzzing=false`. I need to ensure this is truly un-fuzzable and verify no mocking exists. Is there a `qca8k` mock in the kernel, and if so, how does that work? |
| 18/2 | 2026/08/02 16:23 | tool | grepper |
0mError:no matches Args: {
"Expression": "qca8k",
"PathPrefix": "tools/testing/"
}Results: {
"error": "no matches"
} |
| 19/2 | 2026/08/02 16:23 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 34210 output: 120 thoughts: 535 Thoughts: **WorthFuzzing Assessment: qca8k Driver Patch** Okay, let's break this down. First, I checked `tools/testing/` – nothing relevant there. Then, I looked at `drivers/net/dsa/qca/qca8k-8xxx.c`. A hardware driver, specifically. The question is: is there *any* chance this is used in an emulation context? The prompt is clear: any unreachable code in virtualized environments means `WorthFuzzing=false`. `qca8k` is a Qualcomm Atheros DSA driver targeting the QCA8337/QCA8327/QCA8328 chips. It relies on an MDIO bus connected to *that* specific hardware. Impossible to probe in QEMU. Therefore, it's unreachable in a virtualized fuzzing environment. Alright, let's review the patch itself, just to be absolutely certain it's *only* touching `qca8k`. The diff lists: * `drivers/net/dsa/qca/qca8k-8xxx.c` * `drivers/net/dsa/qca/qca8k-common.c` * `drivers/net/dsa/qca/qca8k.h` Perfect. Strictly within the `qca8k` driver suite. Since this driver needs a physical chip, not available in any QEMU emulation, it's not worth the effort for fuzzing. Just to be thorough, I wanted to double-check if `qca8k` is emulated by something like `dsa_loop`. Nope. `dsa_loop` is a completely separate driver, located in `drivers/net/dsa/dsa_loop.c`. Is there any other emulation to consider? Nope. So, I'm setting `WorthFuzzing=false`. Here's the reasoning I'll provide: "The patch modifies the Qualcomm Atheros QCA8K DSA switch driver (`qca8k`). This driver requires specific physical hardware (QCA8337/QCA8327/QCA8328 switch chips connected via MDIO) not emulated in QEMU or other standard virtualized environments. Therefore, the modified code paths are impossible to reach and test during fuzzing." I'll just double-check one last time for any `qca8k` references in `arch/um` or anything similar...Nope. I am confident in this assessment. |
| 20/2 | 2026/08/02 16:24 | tool | set-results |
0mArgs:{
"EnableConfigs": [],
"FocusSymbols": [],
"Reasoning": "The patch exclusively modifies the Qualcomm Atheros QCA8K DSA switch driver (qca8k). This driver requires specific physical hardware (QCA8337/QCA8327/QCA8328 switch chips connected via MDIO) to probe successfully. Since this hardware is not emulated in standard QEMU or virtualized environments, the modified code paths are unreachable and cannot be fuzzed.",
"WorthFuzzing": false
}Results: {
"EnableConfigs": null,
"FocusSymbols": [],
"Reasoning": "The patch exclusively modifies the Qualcomm Atheros QCA8K DSA switch driver (qca8k). This driver requires specific physical hardware (QCA8337/QCA8327/QCA8328 switch chips connected via MDIO) to probe successfully. Since this hardware is not emulated in standard QEMU or virtualized environments, the modified code paths are unreachable and cannot be fuzzed.",
"WorthFuzzing": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|