| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/08/08 14:56 | flow | patch-triage |
44mArgs:null Results: {
"EnableConfigs": [
"STMMAC_ETH",
"STMMAC_PCI",
"NET_SCH_ETS",
"NET_SCH_MQPRIO"
],
"FocusSymbols": [
"stmmac_setup_tc",
"tc_setup_ets",
"tc_setup_dwmac510_mqprio",
"stmmac_set_tx_queue_weight",
"stmmac_mac_config_tx_queues_prio",
"dwmac5_fpe_map_preemption_class"
],
"KMSANReasoning": "The patch adds hardware offload support for ETS (Enhanced Transmission Selection) and MQPRIO in the stmmac driver. It introduces a new `qdisc` structure within the driver's private data (`struct stmmac_priv`) to store the configuration and modifies the queue setup functions to apply these settings to the hardware. The private data structure is zero-initialized upon allocation by the networking core (`alloc_netdev_mqs` uses `kvzalloc`). The offload parameters (`struct tc_ets_qopt_offload`, `struct tc_mqprio_qopt_offload`) are provided by the kernel's qdisc subsystem and are only read by the driver to configure the hardware; no data is copied back to userspace. There are no new allocations of complex data structures or uninitialized buffers that could lead to information leaks or uninitialized memory use. Any potential bugs introduced by this patch, such as out-of-bounds array accesses or use-after-free, would be effectively caught by standard KASAN and other default debugging tools. Therefore, a dedicated KMSAN fuzzing session is not required.",
"NeedsKMSAN": false,
"Reasoning": "The patch adds support for ETS (Enhanced Transmission Selection) and MQPRIO qdisc offloads to the stmmac driver. This involves modifying the tc setup callbacks and queue configuration logic. The driver can be probed via the stmmac_pci wrapper using syzkaller's PCI fuzzer, and the new offload paths can be reached by sending tc netlink commands to the registered netdev.",
"WorthFuzzing": true
} |
| 1/1 | 2026/08/08 14:56 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 222c434c8acd601577a64983289d41de3bcbe278\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Sat Aug 8 14:56:44 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h\nindex 04dafec021b4f..b70883a53b09a 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h\n+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h\n@@ -580,6 +580,8 @@ struct stmmac_tc_ops {\n \t\t\t struct tc_taprio_qopt_offload *qopt);\n \tint (*setup_etf)(struct stmmac_priv *priv,\n \t\t\t struct tc_etf_qopt_offload *qopt);\n+\tint (*setup_ets)(struct stmmac_priv *priv,\n+\t\t\t struct tc_ets_qopt_offload *qopt);\n \tint (*query_caps)(struct stmmac_priv *priv,\n \t\t\t struct tc_query_caps_base *base);\n \tint (*setup_mqprio)(struct stmmac_priv *priv,\n@@ -598,6 +600,8 @@ struct stmmac_tc_ops {\n \tstmmac_do_callback(__priv, tc, setup_taprio, __args)\n #define stmmac_tc_setup_etf(__priv, __args...) \\\n \tstmmac_do_callback(__priv, tc, setup_etf, __args)\n+#define stmmac_tc_setup_ets(__priv, __args...) \\\n+\tstmmac_do_callback(__priv, tc, setup_ets, __args)\n #define stmmac_tc_query_caps(__priv, __args...) \\\n \tstmmac_do_callback(__priv, tc, query_caps, __args)\n #define stmmac_tc_setup_mqprio(__priv, __args...) \\\ndiff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h\nindex 8ba8f03e1ce03..1967279a4cccc 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h\n+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h\n@@ -301,6 +301,14 @@ struct stmmac_priv {\n \t/* Protect est parameters */\n \tstruct mutex est_lock;\n \tstruct stmmac_est *est;\n+\tstruct {\n+\t\tbool enable;\n+\t\tu8 algo;\n+\t\tu8 bands;\n+\t\tu32 handle;\n+\t\tu32 quanta[MTL_MAX_TX_QUEUES];\n+\t\tu32 prio[MTL_MAX_TX_QUEUES];\n+\t} qdisc;\n \tstruct dma_features dma_cap;\n \tstruct stmmac_counters mmc;\n \tint hw_cap_support;\n@@ -394,6 +402,8 @@ enum stmmac_state {\n \n extern const struct dev_pm_ops stmmac_simple_pm_ops;\n \n+void stmmac_set_tx_queue_weight(struct stmmac_priv *priv);\n+void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv);\n int stmmac_mdio_unregister(struct net_device *ndev);\n int stmmac_mdio_register(struct net_device *ndev);\n int stmmac_mdio_reset(struct mii_bus *mii);\ndiff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c\nindex c54c702243517..d84b6fdc01b3a 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c\n+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c\n@@ -205,7 +205,10 @@ int dwmac5_fpe_map_preemption_class(struct net_device *ndev,\n {\n \tu32 val, offset, count, queue_weight, preemptible_txqs = 0;\n \tstruct stmmac_priv *priv = netdev_priv(ndev);\n+\tstruct plat_stmmacenet_data *pdata = priv-\u003eplat;\n \tint num_tc = netdev_get_num_tc(ndev);\n+\tu32 sched_algo;\n+\tbool ets;\n \n \tif (!pclass)\n \t\tgoto update_mapping;\n@@ -216,6 +219,11 @@ int dwmac5_fpe_map_preemption_class(struct net_device *ndev,\n \t * \"The number of Tx DMA channels is equal to the number of Tx queues,\n \t * and is direct one-to-one mapping.\"\n \t */\n+\n+\tsched_algo = priv-\u003eqdisc.enable ? priv-\u003eqdisc.algo\n+\t\t\t\t\t: pdata-\u003etx_sched_algorithm;\n+\tets = priv-\u003eqdisc.enable \u0026\u0026 sched_algo == MTL_TX_ALGORITHM_DWRR;\n+\n \tfor (u32 tc = 0; tc \u003c num_tc; tc++) {\n \t\tcount = ndev-\u003etc_to_txq[tc].count;\n \t\toffset = ndev-\u003etc_to_txq[tc].offset;\n@@ -227,16 +235,20 @@ int dwmac5_fpe_map_preemption_class(struct net_device *ndev,\n \t\tif (count == 1)\n \t\t\tcontinue;\n \n-\t\tif (priv-\u003eplat-\u003etx_sched_algorithm == MTL_TX_ALGORITHM_SP) {\n+\t\tif (sched_algo == MTL_TX_ALGORITHM_SP) {\n \t\t\tNL_SET_ERR_MSG_MOD(extack, ALG_ERR_MSG);\n \t\t\treturn -EINVAL;\n \t\t}\n \n-\t\tqueue_weight = priv-\u003eplat-\u003etx_queues_cfg[offset].weight;\n+\t\tqueue_weight = ets ? priv-\u003eqdisc.quanta[offset]\n+\t\t\t\t : pdata-\u003etx_queues_cfg[offset].weight;\n \n \t\tfor (u32 i = 1; i \u003c count; i++) {\n-\t\t\tif (priv-\u003eplat-\u003etx_queues_cfg[offset + i].weight !=\n-\t\t\t queue_weight) {\n+\t\t\tu32 weight;\n+\n+\t\t\tweight = ets ? priv-\u003eqdisc.quanta[offset + i]\n+\t\t\t\t : pdata-\u003etx_queues_cfg[offset + i].weight;\n+\t\t\tif (weight != queue_weight) {\n \t\t\t\tNL_SET_ERR_MSG_FMT_MOD(extack, WEIGHT_ERR_MSG,\n \t\t\t\t\t\t queue_weight, tc);\n \t\t\t\treturn -EINVAL;\ndiff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c\nindex b2b7d0242dd3c..5aee03ebe1312 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c\n+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c\n@@ -3419,14 +3419,22 @@ static void stmmac_set_rings_length(struct stmmac_priv *priv)\n * @priv: driver private structure\n * Description: It is used for setting TX queues weight\n */\n-static void stmmac_set_tx_queue_weight(struct stmmac_priv *priv)\n+void stmmac_set_tx_queue_weight(struct stmmac_priv *priv)\n {\n-\tu8 tx_queues_count = priv-\u003eplat-\u003etx_queues_to_use;\n+\tstruct plat_stmmacenet_data *pdata = priv-\u003eplat;\n+\tu8 tx_queues_count = pdata-\u003etx_queues_to_use;\n \tu32 weight;\n \tu8 queue;\n \n \tfor (queue = 0; queue \u003c tx_queues_count; queue++) {\n-\t\tweight = priv-\u003eplat-\u003etx_queues_cfg[queue].weight;\n+\t\tif (pdata-\u003etx_queues_cfg[queue].mode_to_use == MTL_QUEUE_AVB)\n+\t\t\tcontinue;\n+\n+\t\tif (priv-\u003eqdisc.enable \u0026\u0026\n+\t\t priv-\u003eqdisc.algo == MTL_TX_ALGORITHM_DWRR)\n+\t\t\tweight = priv-\u003eqdisc.quanta[queue];\n+\t\telse\n+\t\t\tweight = pdata-\u003etx_queues_cfg[queue].weight;\n \t\tstmmac_set_mtl_tx_queue_weight(priv, priv-\u003ehw, weight, queue);\n \t}\n }\n@@ -3499,18 +3507,23 @@ static void stmmac_mac_config_rx_queues_prio(struct stmmac_priv *priv)\n * @priv: driver private structure\n * Description: It is used for configuring the TX Queue Priority\n */\n-static void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv)\n+void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv)\n {\n \tu8 tx_queues_count = priv-\u003eplat-\u003etx_queues_to_use;\n \tu8 queue;\n-\tu32 prio;\n \n \tfor (queue = 0; queue \u003c tx_queues_count; queue++) {\n-\t\tif (!priv-\u003eplat-\u003etx_queues_cfg[queue].use_prio)\n+\t\tif (priv-\u003eqdisc.enable \u0026\u0026\n+\t\t priv-\u003eqdisc.algo == MTL_TX_ALGORITHM_SP) {\n+\t\t\tstmmac_tx_queue_prio(priv, priv-\u003ehw,\n+\t\t\t\t\t priv-\u003eqdisc.prio[queue], queue);\n \t\t\tcontinue;\n+\t\t}\n \n-\t\tprio = priv-\u003eplat-\u003etx_queues_cfg[queue].prio;\n-\t\tstmmac_tx_queue_prio(priv, priv-\u003ehw, prio, queue);\n+\t\tif (priv-\u003eplat-\u003etx_queues_cfg[queue].use_prio)\n+\t\t\tstmmac_tx_queue_prio(priv, priv-\u003ehw,\n+\t\t\t\t\t priv-\u003eplat-\u003etx_queues_cfg[queue].prio,\n+\t\t\t\t\t queue);\n \t}\n }\n \n@@ -3570,9 +3583,15 @@ static void stmmac_mtl_configuration(struct stmmac_priv *priv)\n \t\t\t\tpriv-\u003eplat-\u003erx_sched_algorithm);\n \n \t/* Configure MTL TX algorithms */\n-\tif (tx_queues_count \u003e 1)\n-\t\tstmmac_prog_mtl_tx_algorithms(priv, priv-\u003ehw,\n-\t\t\t\tpriv-\u003eplat-\u003etx_sched_algorithm);\n+\tif (tx_queues_count \u003e 1) {\n+\t\tu8 tx_sched_algo;\n+\n+\t\tif (priv-\u003eqdisc.enable)\n+\t\t\ttx_sched_algo = priv-\u003eqdisc.algo;\n+\t\telse\n+\t\t\ttx_sched_algo = priv-\u003eplat-\u003etx_sched_algorithm;\n+\t\tstmmac_prog_mtl_tx_algorithms(priv, priv-\u003ehw, tx_sched_algo);\n+\t}\n \n \t/* Configure CBS in AVB TX queues */\n \tif (tx_queues_count \u003e 1)\n@@ -3738,7 +3757,11 @@ static int stmmac_hw_setup(struct net_device *dev)\n \n \t/* Configure real RX and TX queues */\n \tnetif_set_real_num_rx_queues(dev, priv-\u003eplat-\u003erx_queues_to_use);\n-\tnetif_set_real_num_tx_queues(dev, priv-\u003eplat-\u003etx_queues_to_use);\n+\tif (priv-\u003eqdisc.enable \u0026\u0026 priv-\u003eqdisc.algo == MTL_TX_ALGORITHM_DWRR)\n+\t\tnetif_set_real_num_tx_queues(dev, priv-\u003eqdisc.bands);\n+\telse\n+\t\tnetif_set_real_num_tx_queues(dev,\n+\t\t\t\t\t priv-\u003eplat-\u003etx_queues_to_use);\n \n \t/* Start the ball rolling... */\n \tstmmac_start_all_dma(priv);\n@@ -6420,26 +6443,45 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,\n \t\t\t void *type_data)\n {\n \tstruct stmmac_priv *priv = netdev_priv(ndev);\n+\tint ret;\n+\n+\tret = pm_runtime_resume_and_get(priv-\u003edevice);\n+\tif (ret \u003c 0)\n+\t\treturn ret;\n \n \tswitch (type) {\n \tcase TC_QUERY_CAPS:\n-\t\treturn stmmac_tc_query_caps(priv, priv, type_data);\n+\t\tret = stmmac_tc_query_caps(priv, priv, type_data);\n+\t\tbreak;\n \tcase TC_SETUP_QDISC_MQPRIO:\n-\t\treturn stmmac_tc_setup_mqprio(priv, priv, type_data);\n+\t\tret = stmmac_tc_setup_mqprio(priv, priv, type_data);\n+\t\tbreak;\n \tcase TC_SETUP_BLOCK:\n-\t\treturn flow_block_cb_setup_simple(type_data,\n-\t\t\t\t\t\t \u0026stmmac_block_cb_list,\n-\t\t\t\t\t\t stmmac_setup_tc_block_cb,\n-\t\t\t\t\t\t priv, priv, true);\n+\t\tret = flow_block_cb_setup_simple(type_data,\n+\t\t\t\t\t\t \u0026stmmac_block_cb_list,\n+\t\t\t\t\t\t stmmac_setup_tc_block_cb,\n+\t\t\t\t\t\t priv, priv, true);\n+\t\tbreak;\n \tcase TC_SETUP_QDISC_CBS:\n-\t\treturn stmmac_tc_setup_cbs(priv, priv, type_data);\n+\t\tret = stmmac_tc_setup_cbs(priv, priv, type_data);\n+\t\tbreak;\n \tcase TC_SETUP_QDISC_TAPRIO:\n-\t\treturn stmmac_tc_setup_taprio(priv, priv, type_data);\n+\t\tret = stmmac_tc_setup_taprio(priv, priv, type_data);\n+\t\tbreak;\n \tcase TC_SETUP_QDISC_ETF:\n-\t\treturn stmmac_tc_setup_etf(priv, priv, type_data);\n+\t\tret = stmmac_tc_setup_etf(priv, priv, type_data);\n+\t\tbreak;\n+\tcase TC_SETUP_QDISC_ETS:\n+\t\tret = stmmac_tc_setup_ets(priv, priv, type_data);\n+\t\tbreak;\n \tdefault:\n-\t\treturn -EOPNOTSUPP;\n+\t\tret = -EOPNOTSUPP;\n+\t\tbreak;\n \t}\n+\n+\tpm_runtime_put(priv-\u003edevice);\n+\n+\treturn ret;\n }\n \n static u16 stmmac_select_queue(struct net_device *dev, struct sk_buff *skb,\ndiff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c\nindex 14cabe76e53ec..336350d6786b3 100644\n--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c\n+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c\n@@ -1210,6 +1210,109 @@ static int tc_setup_etf(struct stmmac_priv *priv,\n \treturn 0;\n }\n \n+/* Max quantum value supported by the MTL DWRR scheduler */\n+#define MTL_TXQ_WEIGHT_QUANTUM_MAX\t0x1312d0\n+\n+static void stmmac_qdisc_restore_dt_config(struct stmmac_priv *priv)\n+{\n+\t/* reset to the dt configured algorithm. */\n+\tpriv-\u003eqdisc.enable = false;\n+\tnetif_set_real_num_tx_queues(priv-\u003edev, priv-\u003eplat-\u003etx_queues_to_use);\n+\tstmmac_set_tx_queue_weight(priv);\n+\tstmmac_mac_config_tx_queues_prio(priv);\n+\tstmmac_prog_mtl_tx_algorithms(priv, priv-\u003ehw,\n+\t\t\t\t priv-\u003eplat-\u003etx_sched_algorithm);\n+}\n+\n+static int tc_setup_ets_sched(struct stmmac_priv *priv,\n+\t\t\t struct tc_ets_qopt_offload *qopt)\n+{\n+\tstruct tc_ets_qopt_offload_replace_params *p = \u0026qopt-\u003ereplace_params;\n+\tstruct plat_stmmacenet_data *pdata = priv-\u003eplat;\n+\tint err, i;\n+\n+\tif (!priv-\u003edma_cap.dcben)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tif (qopt-\u003eparent != TC_H_ROOT)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tif (p-\u003ebands \u003e pdata-\u003etx_queues_to_use)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tfor (i = 0; i \u003c pdata-\u003etx_queues_to_use; i++) {\n+\t\tif (pdata-\u003etx_queues_cfg[i].mode_to_use == MTL_QUEUE_AVB)\n+\t\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\tfor (i = 0; i \u003c p-\u003ebands; i++) {\n+\t\tif (!p-\u003equanta[i])\n+\t\t\treturn -EOPNOTSUPP;\n+\n+\t\tif (p-\u003equanta[i] \u003e MTL_TXQ_WEIGHT_QUANTUM_MAX)\n+\t\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\terr = netif_set_real_num_tx_queues(priv-\u003edev, p-\u003ebands);\n+\tif (err)\n+\t\treturn err;\n+\n+\tfor (i = 0; i \u003c pdata-\u003etx_queues_to_use; i++) {\n+\t\tu32 quantum = i \u003c p-\u003ebands ? p-\u003equanta[i] : 0;\n+\n+\t\tpriv-\u003eqdisc.quanta[i] = quantum;\n+\t\tstmmac_set_mtl_tx_queue_weight(priv, priv-\u003ehw, quantum, i);\n+\t}\n+\n+\tstmmac_prog_mtl_tx_algorithms(priv, priv-\u003ehw, MTL_TX_ALGORITHM_DWRR);\n+\tpriv-\u003eqdisc.algo = MTL_TX_ALGORITHM_DWRR;\n+\tpriv-\u003eqdisc.handle = qopt-\u003ehandle;\n+\tpriv-\u003eqdisc.bands = p-\u003ebands;\n+\tpriv-\u003eqdisc.enable = true;\n+\n+\treturn 0;\n+}\n+\n+static int tc_setup_ets_destroy(struct stmmac_priv *priv,\n+\t\t\t\tstruct tc_ets_qopt_offload *qopt)\n+{\n+\tif (qopt-\u003eparent != TC_H_ROOT ||\n+\t qopt-\u003ehandle != priv-\u003eqdisc.handle)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tif (!priv-\u003eqdisc.enable ||\n+\t priv-\u003eqdisc.algo != MTL_TX_ALGORITHM_DWRR)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tstmmac_qdisc_restore_dt_config(priv);\n+\n+\treturn 0;\n+}\n+\n+static int tc_setup_ets(struct stmmac_priv *priv,\n+\t\t\tstruct tc_ets_qopt_offload *qopt)\n+{\n+\tswitch (qopt-\u003ecommand) {\n+\tcase TC_ETS_REPLACE:\n+\t\treturn tc_setup_ets_sched(priv, qopt);\n+\tcase TC_ETS_DESTROY:\n+\t\treturn tc_setup_ets_destroy(priv, qopt);\n+\tcase TC_ETS_GRAFT:\n+\t\tbreak;\n+\tcase TC_ETS_STATS:\n+\t\tif (qopt-\u003eparent == TC_H_ROOT \u0026\u0026\n+\t\t qopt-\u003ehandle == priv-\u003eqdisc.handle \u0026\u0026\n+\t\t priv-\u003eqdisc.enable \u0026\u0026\n+\t\t priv-\u003eqdisc.algo == MTL_TX_ALGORITHM_DWRR)\n+\t\t\tbreak;\n+\t\tfallthrough;\n+\tdefault:\n+\t\treturn -EOPNOTSUPP;\n+\t}\n+\n+\treturn 0;\n+}\n+\n static int tc_query_caps(struct stmmac_priv *priv,\n \t\t\t struct tc_query_caps_base *base)\n {\n@@ -1243,8 +1346,16 @@ static void stmmac_reset_tc_mqprio(struct net_device *ndev,\n \tstruct stmmac_priv *priv = netdev_priv(ndev);\n \n \tnetdev_reset_tc(ndev);\n-\tnetif_set_real_num_tx_queues(ndev, priv-\u003eplat-\u003etx_queues_to_use);\n \tstmmac_fpe_map_preemption_class(priv, ndev, extack, 0);\n+\n+\tif (priv-\u003eqdisc.enable \u0026\u0026 priv-\u003eqdisc.algo == MTL_TX_ALGORITHM_SP) {\n+\t\tstmmac_qdisc_restore_dt_config(priv);\n+\t} else {\n+\t\tu8 bands = priv-\u003eqdisc.enable ? priv-\u003eqdisc.bands\n+\t\t\t\t\t : priv-\u003eplat-\u003etx_queues_to_use;\n+\n+\t\tnetif_set_real_num_tx_queues(ndev, bands);\n+\t}\n }\n \n static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,\n@@ -1255,13 +1366,24 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,\n \tu32 offset, count, num_stack_tx_queues = 0;\n \tstruct net_device *ndev = priv-\u003edev;\n \tu32 num_tc = qopt-\u003enum_tc;\n-\tint err;\n+\tint i, tc, err;\n \n \tif (!num_tc) {\n \t\tstmmac_reset_tc_mqprio(ndev, extack);\n \t\treturn 0;\n \t}\n \n+\tif (!priv-\u003edma_cap.dcben)\n+\t\treturn -EOPNOTSUPP;\n+\n+\t/* Forcing strict priority conflicts with the CBS algorithm of AVB\n+\t * queues, so reject the offload when any queue is configured as AVB.\n+\t */\n+\tfor (i = 0; i \u003c priv-\u003eplat-\u003etx_queues_to_use; i++) {\n+\t\tif (priv-\u003eplat-\u003etx_queues_cfg[i].mode_to_use == MTL_QUEUE_AVB)\n+\t\t\treturn -EOPNOTSUPP;\n+\t}\n+\n \terr = netdev_set_num_tc(ndev, num_tc);\n \tif (err)\n \t\treturn err;\n@@ -1271,6 +1393,15 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,\n \t\tcount = qopt-\u003ecount[tc];\n \t\tnum_stack_tx_queues += count;\n \n+\t\tif (offset + count \u003e priv-\u003eplat-\u003etx_queues_to_use)\n+\t\t\tgoto err_reset_tc;\n+\n+\t\t/* The offload switches the MTL scheduler to strict priority,\n+\t\t * which only supports a 1:1 TC to TX queue mapping.\n+\t\t */\n+\t\tif (count \u003e 1)\n+\t\t\tgoto err_reset_tc;\n+\n \t\terr = netdev_set_tc_queue(ndev, tc, count, offset);\n \t\tif (err)\n \t\t\tgoto err_reset_tc;\n@@ -1285,6 +1416,28 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,\n \tif (err)\n \t\tgoto err_reset_tc;\n \n+\tfor (i = 0; i \u003c priv-\u003eplat-\u003etx_queues_to_use; i++) {\n+\t\tu32 prio = 0;\n+\n+\t\tfor (tc = 0; tc \u003c num_tc; tc++) {\n+\t\t\tint p;\n+\n+\t\t\tif (qopt-\u003eoffset[tc] != i)\n+\t\t\t\tcontinue;\n+\n+\t\t\tfor (p = 0; p \u003c ARRAY_SIZE(qopt-\u003eprio_tc_map); p++)\n+\t\t\t\tif (qopt-\u003eprio_tc_map[p] == tc)\n+\t\t\t\t\tprio |= BIT(p);\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tpriv-\u003eqdisc.prio[i] = prio;\n+\t\tstmmac_tx_queue_prio(priv, priv-\u003ehw, prio, i);\n+\t}\n+\tstmmac_prog_mtl_tx_algorithms(priv, priv-\u003ehw, MTL_TX_ALGORITHM_SP);\n+\tpriv-\u003eqdisc.algo = MTL_TX_ALGORITHM_SP;\n+\tpriv-\u003eqdisc.enable = true;\n+\n \treturn 0;\n \n err_reset_tc:\n@@ -1308,6 +1461,7 @@ const struct stmmac_tc_ops dwmac4_tc_ops = {\n \t.setup_cls = tc_setup_cls,\n \t.setup_taprio = tc_setup_taprio_without_fpe,\n \t.setup_etf = tc_setup_etf,\n+\t.setup_ets = tc_setup_ets,\n \t.query_caps = tc_query_caps,\n \t.setup_mqprio = tc_setup_mqprio_unimplemented,\n };\n@@ -1319,6 +1473,7 @@ const struct stmmac_tc_ops dwmac510_tc_ops = {\n \t.setup_cls = tc_setup_cls,\n \t.setup_taprio = tc_setup_taprio,\n \t.setup_etf = tc_setup_etf,\n+\t.setup_ets = tc_setup_ets,\n \t.query_caps = tc_query_caps,\n \t.setup_mqprio = tc_setup_dwmac510_mqprio,\n };\n"
} |
| 2/1 | 2026/08/08 14:56 | agent | patch-evaluator |
44mModel:best-expensive Args: null Results: {
"EnableConfigs": [
"STMMAC_ETH",
"STMMAC_PCI",
"NET_SCH_ETS",
"NET_SCH_MQPRIO"
],
"FocusSymbols": [
"stmmac_setup_tc",
"tc_setup_ets",
"tc_setup_dwmac510_mqprio",
"stmmac_set_tx_queue_weight",
"stmmac_mac_config_tx_queues_prio",
"dwmac5_fpe_map_preemption_class"
],
"Reasoning": "The patch adds support for ETS (Enhanced Transmission Selection) and MQPRIO qdisc offloads to the stmmac driver. This involves modifying the tc setup callbacks and queue configuration logic. The driver can be probed via the stmmac_pci wrapper using syzkaller's PCI fuzzer, and the new offload paths can be reached by sending tc netlink commands to the registered netdev.",
"WorthFuzzing": true
}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 222c434c8acd601577a64983289d41de3bcbe278
Author: syz-cluster <triage@syzkaller.com>
Date: Sat Aug 8 14:56:44 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index 04dafec021b4f..b70883a53b09a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -580,6 +580,8 @@ struct stmmac_tc_ops {
struct tc_taprio_qopt_offload *qopt);
int (*setup_etf)(struct stmmac_priv *priv,
struct tc_etf_qopt_offload *qopt);
+ int (*setup_ets)(struct stmmac_priv *priv,
+ struct tc_ets_qopt_offload *qopt);
int (*query_caps)(struct stmmac_priv *priv,
struct tc_query_caps_base *base);
int (*setup_mqprio)(struct stmmac_priv *priv,
@@ -598,6 +600,8 @@ struct stmmac_tc_ops {
stmmac_do_callback(__priv, tc, setup_taprio, __args)
#define stmmac_tc_setup_etf(__priv, __args...) \
stmmac_do_callback(__priv, tc, setup_etf, __args)
+#define stmmac_tc_setup_ets(__priv, __args...) \
+ stmmac_do_callback(__priv, tc, setup_ets, __args)
#define stmmac_tc_query_caps(__priv, __args...) \
stmmac_do_callback(__priv, tc, query_caps, __args)
#define stmmac_tc_setup_mqprio(__priv, __args...) \
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 8ba8f03e1ce03..1967279a4cccc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -301,6 +301,14 @@ struct stmmac_priv {
/* Protect est parameters */
struct mutex est_lock;
struct stmmac_est *est;
+ struct {
+ bool enable;
+ u8 algo;
+ u8 bands;
+ u32 handle;
+ u32 quanta[MTL_MAX_TX_QUEUES];
+ u32 prio[MTL_MAX_TX_QUEUES];
+ } qdisc;
struct dma_features dma_cap;
struct stmmac_counters mmc;
int hw_cap_support;
@@ -394,6 +402,8 @@ enum stmmac_state {
extern const struct dev_pm_ops stmmac_simple_pm_ops;
+void stmmac_set_tx_queue_weight(struct stmmac_priv *priv);
+void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv);
int stmmac_mdio_unregister(struct net_device *ndev);
int stmmac_mdio_register(struct net_device *ndev);
int stmmac_mdio_reset(struct mii_bus *mii);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
index c54c702243517..d84b6fdc01b3a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
@@ -205,7 +205,10 @@ int dwmac5_fpe_map_preemption_class(struct net_device *ndev,
{
u32 val, offset, count, queue_weight, preemptible_txqs = 0;
struct stmmac_priv *priv = netdev_priv(ndev);
+ struct plat_stmmacenet_data *pdata = priv->plat;
int num_tc = netdev_get_num_tc(ndev);
+ u32 sched_algo;
+ bool ets;
if (!pclass)
goto update_mapping;
@@ -216,6 +219,11 @@ int dwmac5_fpe_map_preemption_class(struct net_device *ndev,
* "The number of Tx DMA channels is equal to the number of Tx queues,
* and is direct one-to-one mapping."
*/
+
+ sched_algo = priv->qdisc.enable ? priv->qdisc.algo
+ : pdata->tx_sched_algorithm;
+ ets = priv->qdisc.enable && sched_algo == MTL_TX_ALGORITHM_DWRR;
+
for (u32 tc = 0; tc < num_tc; tc++) {
count = ndev->tc_to_txq[tc].count;
offset = ndev->tc_to_txq[tc].offset;
@@ -227,16 +235,20 @@ int dwmac5_fpe_map_preemption_class(struct net_device *ndev,
if (count == 1)
continue;
- if (priv->plat->tx_sched_algorithm == MTL_TX_ALGORITHM_SP) {
+ if (sched_algo == MTL_TX_ALGORITHM_SP) {
NL_SET_ERR_MSG_MOD(extack, ALG_ERR_MSG);
return -EINVAL;
}
- queue_weight = priv->plat->tx_queues_cfg[offset].weight;
+ queue_weight = ets ? priv->qdisc.quanta[offset]
+ : pdata->tx_queues_cfg[offset].weight;
for (u32 i = 1; i < count; i++) {
- if (priv->plat->tx_queues_cfg[offset + i].weight !=
- queue_weight) {
+ u32 weight;
+
+ weight = ets ? priv->qdisc.quanta[offset + i]
+ : pdata->tx_queues_cfg[offset + i].weight;
+ if (weight != queue_weight) {
NL_SET_ERR_MSG_FMT_MOD(extack, WEIGHT_ERR_MSG,
queue_weight, tc);
return -EINVAL;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index b2b7d0242dd3c..5aee03ebe1312 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3419,14 +3419,22 @@ static void stmmac_set_rings_length(struct stmmac_priv *priv)
* @priv: driver private structure
* Description: It is used for setting TX queues weight
*/
-static void stmmac_set_tx_queue_weight(struct stmmac_priv *priv)
+void stmmac_set_tx_queue_weight(struct stmmac_priv *priv)
{
- u8 tx_queues_count = priv->plat->tx_queues_to_use;
+ struct plat_stmmacenet_data *pdata = priv->plat;
+ u8 tx_queues_count = pdata->tx_queues_to_use;
u32 weight;
u8 queue;
for (queue = 0; queue < tx_queues_count; queue++) {
- weight = priv->plat->tx_queues_cfg[queue].weight;
+ if (pdata->tx_queues_cfg[queue].mode_to_use == MTL_QUEUE_AVB)
+ continue;
+
+ if (priv->qdisc.enable &&
+ priv->qdisc.algo == MTL_TX_ALGORITHM_DWRR)
+ weight = priv->qdisc.quanta[queue];
+ else
+ weight = pdata->tx_queues_cfg[queue].weight;
stmmac_set_mtl_tx_queue_weight(priv, priv->hw, weight, queue);
}
}
@@ -3499,18 +3507,23 @@ static void stmmac_mac_config_rx_queues_prio(struct stmmac_priv *priv)
* @priv: driver private structure
* Description: It is used for configuring the TX Queue Priority
*/
-static void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv)
+void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv)
{
u8 tx_queues_count = priv->plat->tx_queues_to_use;
u8 queue;
- u32 prio;
for (queue = 0; queue < tx_queues_count; queue++) {
- if (!priv->plat->tx_queues_cfg[queue].use_prio)
+ if (priv->qdisc.enable &&
+ priv->qdisc.algo == MTL_TX_ALGORITHM_SP) {
+ stmmac_tx_queue_prio(priv, priv->hw,
+ priv->qdisc.prio[queue], queue);
continue;
+ }
- prio = priv->plat->tx_queues_cfg[queue].prio;
- stmmac_tx_queue_prio(priv, priv->hw, prio, queue);
+ if (priv->plat->tx_queues_cfg[queue].use_prio)
+ stmmac_tx_queue_prio(priv, priv->hw,
+ priv->plat->tx_queues_cfg[queue].prio,
+ queue);
}
}
@@ -3570,9 +3583,15 @@ static void stmmac_mtl_configuration(struct stmmac_priv *priv)
priv->plat->rx_sched_algorithm);
/* Configure MTL TX algorithms */
- if (tx_queues_count > 1)
- stmmac_prog_mtl_tx_algorithms(priv, priv->hw,
- priv->plat->tx_sched_algorithm);
+ if (tx_queues_count > 1) {
+ u8 tx_sched_algo;
+
+ if (priv->qdisc.enable)
+ tx_sched_algo = priv->qdisc.algo;
+ else
+ tx_sched_algo = priv->plat->tx_sched_algorithm;
+ stmmac_prog_mtl_tx_algorithms(priv, priv->hw, tx_sched_algo);
+ }
/* Configure CBS in AVB TX queues */
if (tx_queues_count > 1)
@@ -3738,7 +3757,11 @@ static int stmmac_hw_setup(struct net_device *dev)
/* Configure real RX and TX queues */
netif_set_real_num_rx_queues(dev, priv->plat->rx_queues_to_use);
- netif_set_real_num_tx_queues(dev, priv->plat->tx_queues_to_use);
+ if (priv->qdisc.enable && priv->qdisc.algo == MTL_TX_ALGORITHM_DWRR)
+ netif_set_real_num_tx_queues(dev, priv->qdisc.bands);
+ else
+ netif_set_real_num_tx_queues(dev,
+ priv->plat->tx_queues_to_use);
/* Start the ball rolling... */
stmmac_start_all_dma(priv);
@@ -6420,26 +6443,45 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,
void *type_data)
{
struct stmmac_priv *priv = netdev_priv(ndev);
+ int ret;
+
+ ret = pm_runtime_resume_and_get(priv->device);
+ if (ret < 0)
+ return ret;
switch (type) {
case TC_QUERY_CAPS:
- return stmmac_tc_query_caps(priv, priv, type_data);
+ ret = stmmac_tc_query_caps(priv, priv, type_data);
+ break;
case TC_SETUP_QDISC_MQPRIO:
- return stmmac_tc_setup_mqprio(priv, priv, type_data);
+ ret = stmmac_tc_setup_mqprio(priv, priv, type_data);
+ break;
case TC_SETUP_BLOCK:
- return flow_block_cb_setup_simple(type_data,
- &stmmac_block_cb_list,
- stmmac_setup_tc_block_cb,
- priv, priv, true);
+ ret = flow_block_cb_setup_simple(type_data,
+ &stmmac_block_cb_list,
+ stmmac_setup_tc_block_cb,
+ priv, priv, true);
+ break;
case TC_SETUP_QDISC_CBS:
- return stmmac_tc_setup_cbs(priv, priv, type_data);
+ ret = stmmac_tc_setup_cbs(priv, priv, type_data);
+ break;
case TC_SETUP_QDISC_TAPRIO:
- return stmmac_tc_setup_taprio(priv, priv, type_data);
+ ret = stmmac_tc_setup_taprio(priv, priv, type_data);
+ break;
case TC_SETUP_QDISC_ETF:
- return stmmac_tc_setup_etf(priv, priv, type_data);
+ ret = stmmac_tc_setup_etf(priv, priv, type_data);
+ break;
+ case TC_SETUP_QDISC_ETS:
+ ret = stmmac_tc_setup_ets(priv, priv, type_data);
+ break;
default:
- return -EOPNOTSUPP;
+ ret = -EOPNOTSUPP;
+ break;
}
+
+ pm_runtime_put(priv->device);
+
+ return ret;
}
static u16 stmmac_select_queue(struct net_device *dev, struct sk_buff *skb,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
index 14cabe76e53ec..336350d6786b3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
@@ -1210,6 +1210,109 @@ static int tc_setup_etf(struct stmmac_priv *priv,
return 0;
}
+/* Max quantum value supported by the MTL DWRR scheduler */
+#define MTL_TXQ_WEIGHT_QUANTUM_MAX 0x1312d0
+
+static void stmmac_qdisc_restore_dt_config(struct stmmac_priv *priv)
+{
+ /* reset to the dt configured algorithm. */
+ priv->qdisc.enable = false;
+ netif_set_real_num_tx_queues(priv->dev, priv->plat->tx_queues_to_use);
+ stmmac_set_tx_queue_weight(priv);
+ stmmac_mac_config_tx_queues_prio(priv);
+ stmmac_prog_mtl_tx_algorithms(priv, priv->hw,
+ priv->plat->tx_sched_algorithm);
+}
+
+static int tc_setup_ets_sched(struct stmmac_priv *priv,
+ struct tc_ets_qopt_offload *qopt)
+{
+ struct tc_ets_qopt_offload_replace_params *p = &qopt->replace_params;
+ struct plat_stmmacenet_data *pdata = priv->plat;
+ int err, i;
+
+ if (!priv->dma_cap.dcben)
+ return -EOPNOTSUPP;
+
+ if (qopt->parent != TC_H_ROOT)
+ return -EOPNOTSUPP;
+
+ if (p->bands > pdata->tx_queues_to_use)
+ return -EOPNOTSUPP;
+
+ for (i = 0; i < pdata->tx_queues_to_use; i++) {
+ if (pdata->tx_queues_cfg[i].mode_to_use == MTL_QUEUE_AVB)
+ return -EOPNOTSUPP;
+ }
+
+ for (i = 0; i < p->bands; i++) {
+ if (!p->quanta[i])
+ return -EOPNOTSUPP;
+
+ if (p->quanta[i] > MTL_TXQ_WEIGHT_QUANTUM_MAX)
+ return -EOPNOTSUPP;
+ }
+
+ err = netif_set_real_num_tx_queues(priv->dev, p->bands);
+ if (err)
+ return err;
+
+ for (i = 0; i < pdata->tx_queues_to_use; i++) {
+ u32 quantum = i < p->bands ? p->quanta[i] : 0;
+
+ priv->qdisc.quanta[i] = quantum;
+ stmmac_set_mtl_tx_queue_weight(priv, priv->hw, quantum, i);
+ }
+
+ stmmac_prog_mtl_tx_algorithms(priv, priv->hw, MTL_TX_ALGORITHM_DWRR);
+ priv->qdisc.algo = MTL_TX_ALGORITHM_DWRR;
+ priv->qdisc.handle = qopt->handle;
+ priv->qdisc.bands = p->bands;
+ priv->qdisc.enable = true;
+
+ return 0;
+}
+
+static int tc_setup_ets_destroy(struct stmmac_priv *priv,
+ struct tc_ets_qopt_offload *qopt)
+{
+ if (qopt->parent != TC_H_ROOT ||
+ qopt->handle != priv->qdisc.handle)
+ return -EOPNOTSUPP;
+
+ if (!priv->qdisc.enable ||
+ priv->qdisc.algo != MTL_TX_ALGORITHM_DWRR)
+ return -EOPNOTSUPP;
+
+ stmmac_qdisc_restore_dt_config(priv);
+
+ return 0;
+}
+
+static int tc_setup_ets(struct stmmac_priv *priv,
+ struct tc_ets_qopt_offload *qopt)
+{
+ switch (qopt->command) {
+ case TC_ETS_REPLACE:
+ return tc_setup_ets_sched(priv, qopt);
+ case TC_ETS_DESTROY:
+ return tc_setup_ets_destroy(priv, qopt);
+ case TC_ETS_GRAFT:
+ break;
+ case TC_ETS_STATS:
+ if (qopt->parent == TC_H_ROOT &&
+ qopt->handle == priv->qdisc.handle &&
+ priv->qdisc.enable &&
+ priv->qdisc.algo == MTL_TX_ALGORITHM_DWRR)
+ break;
+ fallthrough;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
static int tc_query_caps(struct stmmac_priv *priv,
struct tc_query_caps_base *base)
{
@@ -1243,8 +1346,16 @@ static void stmmac_reset_tc_mqprio(struct net_device *ndev,
struct stmmac_priv *priv = netdev_priv(ndev);
netdev_reset_tc(ndev);
- netif_set_real_num_tx_queues(ndev, priv->plat->tx_queues_to_use);
stmmac_fpe_map_preemption_class(priv, ndev, extack, 0);
+
+ if (priv->qdisc.enable && priv->qdisc.algo == MTL_TX_ALGORITHM_SP) {
+ stmmac_qdisc_restore_dt_config(priv);
+ } else {
+ u8 bands = priv->qdisc.enable ? priv->qdisc.bands
+ : priv->plat->tx_queues_to_use;
+
+ netif_set_real_num_tx_queues(ndev, bands);
+ }
}
static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
@@ -1255,13 +1366,24 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
u32 offset, count, num_stack_tx_queues = 0;
struct net_device *ndev = priv->dev;
u32 num_tc = qopt->num_tc;
- int err;
+ int i, tc, err;
if (!num_tc) {
stmmac_reset_tc_mqprio(ndev, extack);
return 0;
}
+ if (!priv->dma_cap.dcben)
+ return -EOPNOTSUPP;
+
+ /* Forcing strict priority conflicts with the CBS algorithm of AVB
+ * queues, so reject the offload when any queue is configured as AVB.
+ */
+ for (i = 0; i < priv->plat->tx_queues_to_use; i++) {
+ if (priv->plat->tx_queues_cfg[i].mode_to_use == MTL_QUEUE_AVB)
+ return -EOPNOTSUPP;
+ }
+
err = netdev_set_num_tc(ndev, num_tc);
if (err)
return err;
@@ -1271,6 +1393,15 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
count = qopt->count[tc];
num_stack_tx_queues += count;
+ if (offset + count > priv->plat->tx_queues_to_use)
+ goto err_reset_tc;
+
+ /* The offload switches the MTL scheduler to strict priority,
+ * which only supports a 1:1 TC to TX queue mapping.
+ */
+ if (count > 1)
+ goto err_reset_tc;
+
err = netdev_set_tc_queue(ndev, tc, count, offset);
if (err)
goto err_reset_tc;
@@ -1285,6 +1416,28 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
if (err)
goto err_reset_tc;
+ for (i = 0; i < priv->plat->tx_queues_to_use; i++) {
+ u32 prio = 0;
+
+ for (tc = 0; tc < num_tc; tc++) {
+ int p;
+
+ if (qopt->offset[tc] != i)
+ continue;
+
+ for (p = 0; p < ARRAY_SIZE(qopt->prio_tc_map); p++)
+ if (qopt->prio_tc_map[p] == tc)
+ prio |= BIT(p);
+ break;
+ }
+
+ priv->qdisc.prio[i] = prio;
+ stmmac_tx_queue_prio(priv, priv->hw, prio, i);
+ }
+ stmmac_prog_mtl_tx_algorithms(priv, priv->hw, MTL_TX_ALGORITHM_SP);
+ priv->qdisc.algo = MTL_TX_ALGORITHM_SP;
+ priv->qdisc.enable = true;
+
return 0;
err_reset_tc:
@@ -1308,6 +1461,7 @@ const struct stmmac_tc_ops dwmac4_tc_ops = {
.setup_cls = tc_setup_cls,
.setup_taprio = tc_setup_taprio_without_fpe,
.setup_etf = tc_setup_etf,
+ .setup_ets = tc_setup_ets,
.query_caps = tc_query_caps,
.setup_mqprio = tc_setup_mqprio_unimplemented,
};
@@ -1319,6 +1473,7 @@ const struct stmmac_tc_ops dwmac510_tc_ops = {
.setup_cls = tc_setup_cls,
.setup_taprio = tc_setup_taprio,
.setup_etf = tc_setup_etf,
+ .setup_ets = tc_setup_ets,
.query_caps = tc_query_caps,
.setup_mqprio = tc_setup_dwmac510_mqprio,
};
|
| 3/2 | 2026/08/08 14:56 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8598 output: 20 thoughts: 431 Thoughts: **Analyzing the ETS and MQPRIO Offload Patch for stmmac in a QEMU Context** Okay, so I've got this patch adding ETS and MQPRIO offload support to the `stmmac` driver. It touches `stmmac_tc.c`, `stmmac_main.c`, `stmmac_fpe.c`, `stmmac.h`, and `hwif.h`, and, based on the changes, it looks like it's adding `setup_ets` to `stmmac_tc_ops`, and handling `TC_SETUP_QDISC_ETS` and `TC_SETUP_QDISC_MQPRIO` in `stmmac_setup_tc`, with modifications to `stmmac_set_tx_queue_weight` and `stmmac_mac_config_tx_queues_prio`. Good, seems like a fairly standard approach to integrating these features. The key question is, can I reach this in QEMU, since that's my primary fuzzing environment? `stmmac` is, of course, the STMicroelectronics Ethernet driver, for various speeds. It *could* be on some ARM boards in QEMU, but syzkaller usually focuses on x86_64 and arm64, unless specifically told to fuzz an ARM board. And, while I'm thinking about it, stmmac is a PCI device as well (stmmac_pci). That opens up a whole different possibility. Syzkaller might not be directly using `stmmac` for networking, typically it uses `vhci` or `netdevsim`, but, it *can* fuzz PCI drivers if they're present. Aha! `stmmac_pci.c` – a PCI wrapper for `stmmac`. Now, that's interesting. I need to check if `stmmac_pci` is enabled in my syzkaller configuration. If it is, or if it's generally considered a PCI driver within syzkaller's purview, then this ETS/MQPRIO offload support becomes potentially fuzzable. I need to dig into the config and see what's what. |
| 4/2 | 2026/08/08 14:56 | tool | grepper |
0mArgs:{
"Expression": "stmmac_pci"
}Results: {
"Output": "Documentation/networking/device_drivers/ethernet/stmicro/stmmac.rst=107=syntax (e.g. for PCI module)::\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-108-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:109: modprobe stmmac_pci [\u003coption\u003e=\u003cVAL1\u003e,\u003cVAL2\u003e,...]\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-110-\n--\ndrivers/net/ethernet/stmicro/stmmac/Makefile=53=obj-$(CONFIG_DWMAC_MOTORCOMM)\t+= dwmac-motorcomm.o\ndrivers/net/ethernet/stmicro/stmmac/Makefile:54:stmmac-pci-objs:= stmmac_pci.o\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=25=struct intel_priv_data {\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-39- */\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:40:struct stmmac_pci_func_data {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-41-\tunsigned int func;\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-44-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:45:struct stmmac_pci_dmi_data {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:46:\tconst struct stmmac_pci_func_data *func;\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-47-\tsize_t nfuncs;\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-49-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:50:struct stmmac_pci_info {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-51-\tint (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=91=static const int adln_tsn_lane_regs[] = {6};\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-92-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:93:static int stmmac_pci_find_phy_addr(struct pci_dev *pdev,\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-94-\t\t\t\t const struct dmi_system_id *dmi_list)\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-95-{\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:96:\tconst struct stmmac_pci_func_data *func_data;\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:97:\tconst struct stmmac_pci_dmi_data *dmi_data;\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-98-\tconst struct dmi_system_id *dmi_id;\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=786=static int ehl_sgmii_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-805-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:806:static struct stmmac_pci_info ehl_sgmii1g_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-807-\t.setup = ehl_sgmii_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=810=static int ehl_rgmii_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-820-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:821:static struct stmmac_pci_info ehl_rgmii1g_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-822-\t.setup = ehl_rgmii_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=841=static int ehl_pse0_rgmii1g_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-847-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:848:static struct stmmac_pci_info ehl_pse0_rgmii1g_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-849-\t.setup = ehl_pse0_rgmii1g_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=852=static int ehl_pse0_sgmii1g_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-869-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:870:static struct stmmac_pci_info ehl_pse0_sgmii1g_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-871-\t.setup = ehl_pse0_sgmii1g_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=890=static int ehl_pse1_rgmii1g_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-896-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:897:static struct stmmac_pci_info ehl_pse1_rgmii1g_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-898-\t.setup = ehl_pse1_rgmii1g_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=901=static int ehl_pse1_sgmii1g_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-918-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:919:static struct stmmac_pci_info ehl_pse1_sgmii1g_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-920-\t.setup = ehl_pse1_sgmii1g_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=944=static int tgl_sgmii_phy0_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-952-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:953:static struct stmmac_pci_info tgl_sgmii1g_phy0_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-954-\t.setup = tgl_sgmii_phy0_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=957=static int tgl_sgmii_phy1_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-965-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:966:static struct stmmac_pci_info tgl_sgmii1g_phy1_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-967-\t.setup = tgl_sgmii_phy1_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=970=static int adls_sgmii_phy0_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-979-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:980:static struct stmmac_pci_info adls_sgmii1g_phy0_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-981-\t.setup = adls_sgmii_phy0_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=984=static int adls_sgmii_phy1_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-993-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:994:static struct stmmac_pci_info adls_sgmii1g_phy1_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-995-\t.setup = adls_sgmii_phy1_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=1023=static int adln_sgmii_phy0_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1041-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:1042:static struct stmmac_pci_info adln_sgmii1g_phy0_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1043-\t.setup = adln_sgmii_phy0_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1045-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:1046:static const struct stmmac_pci_func_data galileo_stmmac_func_data[] = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1047-\t{\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1052-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:1053:static const struct stmmac_pci_dmi_data galileo_stmmac_dmi_data = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1054-\t.func = galileo_stmmac_func_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1057-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:1058:static const struct stmmac_pci_func_data iot2040_stmmac_func_data[] = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1059-\t{\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1068-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:1069:static const struct stmmac_pci_dmi_data iot2040_stmmac_dmi_data = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1070-\t.func = iot2040_stmmac_func_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=1109=static int quark_default_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1119-\t */\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:1120:\tret = stmmac_pci_find_phy_addr(pdev, quark_pci_dmi);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1121-\tif (ret \u003c 0) {\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1144-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:1145:static const struct stmmac_pci_info quark_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1146-\t.setup = quark_default_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=1263=static int intel_eth_pci_probe(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1265-{\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:1266:\tstruct stmmac_pci_info *info = (struct stmmac_pci_info *)id-\u003edriver_data;\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1267-\tstruct intel_priv_data *intel_priv;\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c=76=struct loongson_data {\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-81-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c:82:struct stmmac_pci_info {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-83-\tint (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c=132=static int loongson_gmac_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-141-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c:142:static struct stmmac_pci_info loongson_gmac_pci_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-143-\t.setup = loongson_gmac_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c=165=static int loongson_gnet_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-176-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c:177:static struct stmmac_pci_info loongson_gnet_pci_info = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-178-\t.setup = loongson_gnet_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c=498=static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id *id)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-501-\tstruct stmmac_resources res = {};\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c:502:\tstruct stmmac_pci_info *info;\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-503-\tstruct loongson_data *ld;\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-537-\tplat-\u003efix_soc_reset = loongson_dwmac_fix_reset;\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c:538:\tplat-\u003esuspend = stmmac_pci_plat_suspend;\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c:539:\tplat-\u003eresume = stmmac_pci_plat_resume;\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-540-\tld-\u003edev = \u0026pdev-\u003edev;\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-542-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c:543:\tinfo = (struct stmmac_pci_info *)id-\u003edriver_data;\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-544-\tret = info-\u003esetup(pdev, plat);\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c=188=static int motorcomm_resume(struct device *dev, void *bsp_priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c-192-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c:193:\tret = stmmac_pci_plat_resume(dev, bsp_priv);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c-194-\tif (ret)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c=208=motorcomm_default_plat_data(struct pci_dev *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c-248-\tplat-\u003ecore_type\t\t= DWMAC_CORE_GMAC4;\ndrivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c:249:\tplat-\u003esuspend\t\t= stmmac_pci_plat_suspend;\ndrivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c-250-\tplat-\u003eresume\t\t= motorcomm_resume;\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.c-11-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.c:12:int stmmac_pci_plat_suspend(struct device *dev, void *bsp_priv)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.c-13-{\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.c-25-}\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.c:26:EXPORT_SYMBOL_GPL(stmmac_pci_plat_suspend);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.c-27-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.c:28:int stmmac_pci_plat_resume(struct device *dev, void *bsp_priv)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.c-29-{\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.c-43-}\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.c:44:EXPORT_SYMBOL_GPL(stmmac_pci_plat_resume);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.c-45-\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.h-8-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.h:9:int stmmac_pci_plat_suspend(struct device *dev, void *bsp_priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.h:10:int stmmac_pci_plat_resume(struct device *dev, void *bsp_priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_libpci.h-11-\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-18-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:19:struct stmmac_pci_info {\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-20-\tint (*setup)(struct pci_dev *pdev, struct plat_stmmacenet_data *plat);\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c=33=static int stmmac_default_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-49-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:50:static const struct stmmac_pci_info stmmac_pci_info = {\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-51-\t.setup = stmmac_default_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c=54=static int snps_gmac5_default_data(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-101-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:102:static const struct stmmac_pci_info snps_gmac5_pci_info = {\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-103-\t.setup = snps_gmac5_default_data,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-106-/**\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:107: * stmmac_pci_probe\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-108- *\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-117- */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:118:static int stmmac_pci_probe(struct pci_dev *pdev,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-119-\t\t\t const struct pci_device_id *id)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-120-{\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:121:\tstruct stmmac_pci_info *info = (struct stmmac_pci_info *)id-\u003edriver_data;\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-122-\tstruct plat_stmmacenet_data *plat;\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-179-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:180:\tplat-\u003esuspend = stmmac_pci_plat_suspend;\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:181:\tplat-\u003eresume = stmmac_pci_plat_resume;\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-182-\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-186-/**\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:187: * stmmac_pci_remove\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-188- *\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-191- */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:192:static void stmmac_pci_remove(struct pci_dev *pdev)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-193-{\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c=203=static const struct pci_device_id stmmac_id_table[] = {\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:204:\t{ PCI_DEVICE_DATA(STMMAC, STMMAC, \u0026stmmac_pci_info) },\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:205:\t{ PCI_DEVICE_DATA(STMICRO, MAC, \u0026stmmac_pci_info) },\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-206-\t{ PCI_DEVICE_DATA(SYNOPSYS, GMAC5_ID, \u0026snps_gmac5_pci_info) },\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c=210=MODULE_DEVICE_TABLE(pci, stmmac_id_table);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-211-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:212:static struct pci_driver stmmac_pci_driver = {\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-213-\t.name = STMMAC_RESOURCE_NAME,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-214-\t.id_table = stmmac_id_table,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:215:\t.probe = stmmac_pci_probe,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:216:\t.remove = stmmac_pci_remove,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-217-\t.driver = {\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-221-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:222:module_pci_driver(stmmac_pci_driver);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-223-\n"
} |
| 5/2 | 2026/08/08 14:56 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 16883 output: 21 thoughts: 291 Thoughts: **Analyzing the `stmmac_pci` Driver and Syzkaller Fuzzing Capabilities** Okay, so `stmmac_pci`, from its name, is a PCI driver, which means I should consider how syzkaller can approach fuzzing it. I recall syzkaller has some PCI fuzzing mechanisms. Initially, I thought about emulation via `vhci` or `netdevsim`, but that's not quite right. Syzkaller leverages `syz_pci_vpci` or direct device injection for PCI fuzzing, not a generic emulator for all PCI devices. The crucial point is that syzkaller doesn't have an emulator that can specifically and accurately replicate the registers of `stmmac`. Wait, isn't `stmmac` actually a network driver? If so, could it be targeted via `netlink` commands like `tc`, assuming the device is present and functional within the system? Definitely, that's a key possibility if the device is operational. The question is, is this device instantiated and accessible within the QEMU environment syzkaller uses? Syzkaller *can* probe PCI devices, as I remember, if they're supported by QEMU, or if the syzkaller PCI fuzzer is utilized. But the PCI fuzzer, as I recall, primarily targets the PCI configuration space and BARs. It’s highly unlikely that it can provide a fully functional network device that properly integrates with the network device subsystem, especially for a complex controller like an ethernet device, unless the driver can somehow initialize with the fuzzed BARs – which is rare. However, thinking back, I remember `stmmac` is used in some virtual environments or maybe syzkaller has a specific path to access it. Given its network nature, I need to check whether `stmmac` is even enabled in syzkaller's config. That's the next step. |
| 6/2 | 2026/08/08 14:57 | tool | grepper |
0mArgs:{
"Expression": "CONFIG_STMMAC_ETH"
}Results: {
"Output": "Documentation/networking/device_drivers/ethernet/stmicro/stmmac.rst=95=Kernel Configuration\n--\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-97-\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst:98:The kernel configuration option is ``CONFIG_STMMAC_ETH``:\nDocumentation/networking/device_drivers/ethernet/stmicro/stmmac.rst-99- - ``CONFIG_STMMAC_PLATFORM``: is to enable the platform driver.\n--\narch/arc/configs/axs101_defconfig=44=CONFIG_NETDEVICES=y\n--\narch/arc/configs/axs101_defconfig-51-# CONFIG_NET_VENDOR_SEEQ is not set\narch/arc/configs/axs101_defconfig:52:CONFIG_STMMAC_ETH=y\narch/arc/configs/axs101_defconfig-53-# CONFIG_NET_VENDOR_VIA is not set\n--\narch/arc/configs/axs103_defconfig=44=CONFIG_NETDEVICES=y\n--\narch/arc/configs/axs103_defconfig-51-# CONFIG_NET_VENDOR_SEEQ is not set\narch/arc/configs/axs103_defconfig:52:CONFIG_STMMAC_ETH=y\narch/arc/configs/axs103_defconfig-53-# CONFIG_NET_VENDOR_VIA is not set\n--\narch/arc/configs/axs103_smp_defconfig=44=CONFIG_NETDEVICES=y\n--\narch/arc/configs/axs103_smp_defconfig-51-# CONFIG_NET_VENDOR_SEEQ is not set\narch/arc/configs/axs103_smp_defconfig:52:CONFIG_STMMAC_ETH=y\narch/arc/configs/axs103_smp_defconfig-53-# CONFIG_NET_VENDOR_VIA is not set\n--\narch/arc/configs/hsdk_defconfig=37=CONFIG_NETDEVICES=y\narch/arc/configs/hsdk_defconfig:38:CONFIG_STMMAC_ETH=y\narch/arc/configs/hsdk_defconfig-39-CONFIG_MICREL_PHY=y\n--\narch/arc/configs/tb10x_defconfig=41=CONFIG_NETDEVICES=y\n--\narch/arc/configs/tb10x_defconfig-47-# CONFIG_NET_VENDOR_SEEQ is not set\narch/arc/configs/tb10x_defconfig:48:CONFIG_STMMAC_ETH=y\narch/arc/configs/tb10x_defconfig-49-# CONFIG_NET_VENDOR_WIZNET is not set\n--\narch/arc/configs/vdk_hs38_defconfig=39=CONFIG_NETDEVICES=y\n--\narch/arc/configs/vdk_hs38_defconfig-46-# CONFIG_NET_VENDOR_SEEQ is not set\narch/arc/configs/vdk_hs38_defconfig:47:CONFIG_STMMAC_ETH=y\narch/arc/configs/vdk_hs38_defconfig-48-# CONFIG_NET_VENDOR_VIA is not set\n--\narch/arc/configs/vdk_hs38_smp_defconfig=41=CONFIG_NETDEVICES=y\n--\narch/arc/configs/vdk_hs38_smp_defconfig-48-# CONFIG_NET_VENDOR_SEEQ is not set\narch/arc/configs/vdk_hs38_smp_defconfig:49:CONFIG_STMMAC_ETH=y\narch/arc/configs/vdk_hs38_smp_defconfig-50-# CONFIG_NET_VENDOR_VIA is not set\n--\narch/arm/configs/lpc18xx_defconfig=61=CONFIG_NETDEVICES=y\n--\narch/arm/configs/lpc18xx_defconfig-76-# CONFIG_NET_VENDOR_SMSC is not set\narch/arm/configs/lpc18xx_defconfig:77:CONFIG_STMMAC_ETH=y\narch/arm/configs/lpc18xx_defconfig-78-# CONFIG_NET_VENDOR_VIA is not set\n--\narch/arm/configs/multi_v7_defconfig=275=CONFIG_SNI_AVE=y\narch/arm/configs/multi_v7_defconfig:276:CONFIG_STMMAC_ETH=y\narch/arm/configs/multi_v7_defconfig-277-CONFIG_DWMAC_DWC_QOS_ETH=y\n--\narch/arm/configs/pxa_defconfig=182=CONFIG_SMSC911X=m\narch/arm/configs/pxa_defconfig:183:CONFIG_STMMAC_ETH=m\narch/arm/configs/pxa_defconfig-184-CONFIG_PHYLIB=y\n--\narch/arm/configs/shmobile_defconfig=59=CONFIG_SMSC911X=y\narch/arm/configs/shmobile_defconfig:60:CONFIG_STMMAC_ETH=y\narch/arm/configs/shmobile_defconfig-61-# CONFIG_DWMAC_RENESAS_GBETH is not set\n--\narch/arm/configs/socfpga_defconfig=66=CONFIG_IXGBE=m\narch/arm/configs/socfpga_defconfig:67:CONFIG_STMMAC_ETH=y\narch/arm/configs/socfpga_defconfig-68-CONFIG_MARVELL_PHY=y\n--\narch/arm/configs/spear13xx_defconfig=43=CONFIG_NETDEVICES=y\n--\narch/arm/configs/spear13xx_defconfig-51-# CONFIG_NET_VENDOR_SMSC is not set\narch/arm/configs/spear13xx_defconfig:52:CONFIG_STMMAC_ETH=y\narch/arm/configs/spear13xx_defconfig-53-# CONFIG_WLAN is not set\n--\narch/arm/configs/spear3xx_defconfig=23=CONFIG_NETDEVICES=y\n--\narch/arm/configs/spear3xx_defconfig-31-# CONFIG_NET_VENDOR_SMSC is not set\narch/arm/configs/spear3xx_defconfig:32:CONFIG_STMMAC_ETH=y\narch/arm/configs/spear3xx_defconfig-33-# CONFIG_WLAN is not set\n--\narch/arm/configs/spear6xx_defconfig=19=CONFIG_NETDEVICES=y\n--\narch/arm/configs/spear6xx_defconfig-27-# CONFIG_NET_VENDOR_SMSC is not set\narch/arm/configs/spear6xx_defconfig:28:CONFIG_STMMAC_ETH=y\narch/arm/configs/spear6xx_defconfig-29-# CONFIG_WLAN is not set\n--\narch/arm/configs/sunxi_defconfig=36=CONFIG_SUN4I_EMAC=y\n--\narch/arm/configs/sunxi_defconfig-48-# CONFIG_NET_VENDOR_SMSC is not set\narch/arm/configs/sunxi_defconfig:49:CONFIG_STMMAC_ETH=y\narch/arm/configs/sunxi_defconfig-50-# CONFIG_NET_VENDOR_VIA is not set\n--\narch/arm64/configs/defconfig=445=CONFIG_SNI_NETSEC=m\narch/arm64/configs/defconfig:446:CONFIG_STMMAC_ETH=m\narch/arm64/configs/defconfig-447-CONFIG_DWMAC_MEDIATEK=m\n--\narch/loongarch/configs/loongson32_defconfig=611=CONFIG_R8169=y\n--\narch/loongarch/configs/loongson32_defconfig-619-# CONFIG_NET_VENDOR_SMSC is not set\narch/loongarch/configs/loongson32_defconfig:620:CONFIG_STMMAC_ETH=y\narch/loongarch/configs/loongson32_defconfig-621-# CONFIG_NET_VENDOR_SUN is not set\n--\narch/loongarch/configs/loongson64_defconfig=627=CONFIG_R8169=y\n--\narch/loongarch/configs/loongson64_defconfig-635-# CONFIG_NET_VENDOR_SMSC is not set\narch/loongarch/configs/loongson64_defconfig:636:CONFIG_STMMAC_ETH=y\narch/loongarch/configs/loongson64_defconfig-637-# CONFIG_NET_VENDOR_SUN is not set\n--\narch/mips/configs/cu1000-neo_defconfig=42=CONFIG_NETDEVICES=y\narch/mips/configs/cu1000-neo_defconfig:43:CONFIG_STMMAC_ETH=y\narch/mips/configs/cu1000-neo_defconfig-44-CONFIG_SMSC_PHY=y\n--\narch/mips/configs/cu1830-neo_defconfig=45=CONFIG_NETDEVICES=y\narch/mips/configs/cu1830-neo_defconfig:46:CONFIG_STMMAC_ETH=y\narch/mips/configs/cu1830-neo_defconfig-47-CONFIG_ICPLUS_PHY=y\n--\narch/mips/configs/generic/board-marduk.config=25=CONFIG_NETDEVICES=y\narch/mips/configs/generic/board-marduk.config:26:CONFIG_STMMAC_ETH=y\narch/mips/configs/generic/board-marduk.config-27-CONFIG_STMMAC_PLATFORM=y\n--\narch/mips/configs/generic/board-ni169445.config=26=CONFIG_NETDEVICES=y\narch/mips/configs/generic/board-ni169445.config:27:CONFIG_STMMAC_ETH=y\narch/mips/configs/generic/board-ni169445.config-28-CONFIG_STMMAC_PLATFORM=y\n--\narch/mips/configs/loongson1_defconfig=51=CONFIG_NETDEVICES=y\n--\narch/mips/configs/loongson1_defconfig-88-# CONFIG_NET_VENDOR_SOCIONEXT is not set\narch/mips/configs/loongson1_defconfig:89:CONFIG_STMMAC_ETH=y\narch/mips/configs/loongson1_defconfig-90-# CONFIG_DWMAC_GENERIC is not set\n--\narch/mips/configs/loongson2k_defconfig=175=CONFIG_R8169=y\n--\narch/mips/configs/loongson2k_defconfig-183-# CONFIG_NET_VENDOR_SMSC is not set\narch/mips/configs/loongson2k_defconfig:184:CONFIG_STMMAC_ETH=y\narch/mips/configs/loongson2k_defconfig-185-# CONFIG_NET_VENDOR_SUN is not set\n--\narch/riscv/configs/defconfig=140=CONFIG_R8169=y\narch/riscv/configs/defconfig:141:CONFIG_STMMAC_ETH=m\narch/riscv/configs/defconfig-142-CONFIG_DWMAC_THEAD=m\n--\ndrivers/gpio/gpiolib-of.c=343=static void of_gpio_flags_quirks(const struct device_node *np,\n--\ndrivers/gpio/gpiolib-of.c-398-\t/* Legacy handling of stmmac's active-low PHY reset line */\ndrivers/gpio/gpiolib-of.c:399:\tif (IS_ENABLED(CONFIG_STMMAC_ETH) \u0026\u0026\ndrivers/gpio/gpiolib-of.c-400-\t !strcmp(propname, \"snps,reset-gpio\") \u0026\u0026\n--\ndrivers/gpu/drm/ci/arm64.config=36=CONFIG_DWMAC_ROCKCHIP=y\ndrivers/gpu/drm/ci/arm64.config:37:CONFIG_STMMAC_ETH=y\ndrivers/gpu/drm/ci/arm64.config-38-CONFIG_TYPEC_FUSB302=y\n--\ndrivers/net/ethernet/stmicro/Makefile-5-\ndrivers/net/ethernet/stmicro/Makefile:6:obj-$(CONFIG_STMMAC_ETH) += stmmac/\n--\ndrivers/net/ethernet/stmicro/stmmac/Makefile-1-# SPDX-License-Identifier: GPL-2.0\ndrivers/net/ethernet/stmicro/stmmac/Makefile:2:obj-$(CONFIG_STMMAC_ETH) += stmmac.o\ndrivers/net/ethernet/stmicro/stmmac/Makefile-3-stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o\t\\\n"
} |
| 7/2 | 2026/08/08 14:57 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 20872 output: 22 thoughts: 531 Thoughts: **Analyzing the Syzkaller Coverage of CONFIG_STMMAC_ETH** Okay, so `CONFIG_STMMAC_ETH` seems pretty widespread; I see it enabled in `arch/arm64/configs/defconfig` and `arch/riscv/configs/defconfig`, among others. The immediate question is whether syzkaller's x86_64 config *also* enables it, or if it's covered by any of the existing test configurations. My hunch is it probably *isn't* directly in syzkaller's config, since it's a network driver, not a core system component, but it's important to find out. I don't have direct access to syzkaller's config file, but since this is a PCI driver, there are a couple of indirect avenues for coverage. Now, this is an `stmmac` driver; specifically, I see the patch modifies `stmmac_tc.c`, which is all about traffic control (`tc`) offloads. Can syzkaller effectively fuzz `tc` offloads? Yes, it does fuzz `tc` netlink commands. If the driver loads and a net device is created, syzkaller has a pretty good chance of exercising it through these commands. The crucial point is: Will the device *be* created? The PCI fuzzer in syzkaller could potentially probe the `stmmac_pci` driver. That is the most promising route. But `stmmac_pci` requires specific PCI IDs: `STMMAC`, `STMICRO`, and `SYNOPSYS`. The PCI fuzzer can emulate those IDs. That's a good starting point. However, here's the rub: `stmmac` is a network driver, and those drivers *really* depend on specific hardware resources (BARs, IRQs, memory regions, and so on) to initialize successfully. PCI fuzzers can be pretty simplistic in this respect. Complex network drivers often fail initialization because the fuzzer doesn't emulate the device's specific registers, the MAC registers, or the DMA engines. These kinds of devices can be a pain to bring up. Wait, does `stmmac` have a fallback for dummy memory? No, looking at `stmmac` it seems like it will fail if it's reading all 0s or 1s, since it tries to read the MAC registers. The question is, does `stmmac_hw_setup` or `stmmac_pci_probe` have any graceful handling of missing or incorrect hardware resources. I'll need to check the code in there to see if the probe can succeed with emulated memory, or if the initialization is too brittle for this to be a useful avenue for syzkaller coverage. |
| 8/2 | 2026/08/08 14:57 | tool | grepper |
0mArgs:{
"Expression": "stmmac_pci_probe"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c=102=static const struct stmmac_pci_info snps_gmac5_pci_info = {\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-106-/**\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:107: * stmmac_pci_probe\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-108- *\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-117- */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:118:static int stmmac_pci_probe(struct pci_dev *pdev,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-119-\t\t\t const struct pci_device_id *id)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c=212=static struct pci_driver stmmac_pci_driver = {\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-214-\t.id_table = stmmac_id_table,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:215:\t.probe = stmmac_pci_probe,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-216-\t.remove = stmmac_pci_remove,\n"
} |
| 9/2 | 2026/08/08 14:57 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 22474 output: 51 thoughts: 15 Thoughts: Okay, let's dive into this `stmmac_pci_probe` function. I need to understand what's happening here. My initial thought process would be something like this: **Analyzing the `stmmac_pci_probe` Function** Alright, I see we're dealing with the PCI probe function for the STMicroelectronics MAC driver. This is where the driver gets initialized and bound to a specific PCI device, right? The key here is likely the sequence of steps involved in identifying the hardware, allocating resources, configuring the device, and ultimately, making it available to the network stack. First, I'd expect to see checks for the PCI device ID to ensure it's compatible with this particular driver. Then, resource allocation should follow. That'll be critical, figuring out which memory regions and interrupt lines are needed. I'll need to pay close attention to how these are handled; any misconfiguration at this point can lead to significant issues. Next, the driver will probably initialize the MAC hardware itself, writing configuration values to the registers, setting up the DMA, and enabling the various network interfaces. Error handling will be super important here - what are the checks for DMA errors, memory mapping failures, and interrupt initialization problems? The driver needs to gracefully handle potential failures during setup. Finally, the function will likely register the device with the kernel's network subsystem, making the new network interface accessible. I need to understand how the net_device structure is set up, which functions are registered for transmit and receive, and how the driver handles link state changes. I'll probably also see some power management considerations within the probe. This is an area I need to pay close attention to. |
| 10/2 | 2026/08/08 14:57 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c",
"FirstLine": 118,
"LineCount": 100
}Results: {
"Contents": " 118:\tstatic int stmmac_pci_probe(struct pci_dev *pdev,\n 119:\t\t\t\t const struct pci_device_id *id)\n 120:\t{\n 121:\t\tstruct stmmac_pci_info *info = (struct stmmac_pci_info *)id-\u003edriver_data;\n 122:\t\tstruct plat_stmmacenet_data *plat;\n 123:\t\tstruct stmmac_resources res = {};\n 124:\t\tint ret;\n 125:\t\tint i;\n 126:\t\n 127:\t\tplat = stmmac_plat_dat_alloc(\u0026pdev-\u003edev);\n 128:\t\tif (!plat)\n 129:\t\t\treturn -ENOMEM;\n 130:\t\n 131:\t\tplat-\u003emdio_bus_data = devm_kzalloc(\u0026pdev-\u003edev,\n 132:\t\t\t\t\t\t sizeof(*plat-\u003emdio_bus_data),\n 133:\t\t\t\t\t\t GFP_KERNEL);\n 134:\t\tif (!plat-\u003emdio_bus_data)\n 135:\t\t\treturn -ENOMEM;\n 136:\t\n 137:\t\tplat-\u003esafety_feat_cfg = devm_kzalloc(\u0026pdev-\u003edev,\n 138:\t\t\t\t\t\t sizeof(*plat-\u003esafety_feat_cfg),\n 139:\t\t\t\t\t\t GFP_KERNEL);\n 140:\t\tif (!plat-\u003esafety_feat_cfg)\n 141:\t\t\treturn -ENOMEM;\n 142:\t\n 143:\t\t/* Enable pci device */\n 144:\t\tret = pcim_enable_device(pdev);\n 145:\t\tif (ret) {\n 146:\t\t\tdev_err(\u0026pdev-\u003edev, \"%s: ERROR: failed to enable device\\n\",\n 147:\t\t\t\t__func__);\n 148:\t\t\treturn ret;\n 149:\t\t}\n 150:\t\n 151:\t\t/* Get the base address of device */\n 152:\t\tfor (i = 0; i \u003c PCI_STD_NUM_BARS; i++) {\n 153:\t\t\tif (pci_resource_len(pdev, i) == 0)\n 154:\t\t\t\tcontinue;\n 155:\t\t\tres.addr = pcim_iomap_region(pdev, i, STMMAC_RESOURCE_NAME);\n 156:\t\t\tif (IS_ERR(res.addr))\n 157:\t\t\t\treturn PTR_ERR(res.addr);\n 158:\t\t\tbreak;\n 159:\t\t}\n 160:\t\n 161:\t\tpci_set_master(pdev);\n 162:\t\n 163:\t\tret = info-\u003esetup(pdev, plat);\n 164:\t\tif (ret)\n 165:\t\t\treturn ret;\n 166:\t\n 167:\t\tres.wol_irq = pdev-\u003eirq;\n 168:\t\tres.irq = pdev-\u003eirq;\n 169:\t\n 170:\t\tplat-\u003esafety_feat_cfg-\u003etsoee = 1;\n 171:\t\tplat-\u003esafety_feat_cfg-\u003emrxpee = 1;\n 172:\t\tplat-\u003esafety_feat_cfg-\u003emestee = 1;\n 173:\t\tplat-\u003esafety_feat_cfg-\u003emrxee = 1;\n 174:\t\tplat-\u003esafety_feat_cfg-\u003emtxee = 1;\n 175:\t\tplat-\u003esafety_feat_cfg-\u003eepsi = 1;\n 176:\t\tplat-\u003esafety_feat_cfg-\u003eedpp = 1;\n 177:\t\tplat-\u003esafety_feat_cfg-\u003eprtyen = 1;\n 178:\t\tplat-\u003esafety_feat_cfg-\u003etmouten = 1;\n 179:\t\n 180:\t\tplat-\u003esuspend = stmmac_pci_plat_suspend;\n 181:\t\tplat-\u003eresume = stmmac_pci_plat_resume;\n 182:\t\n 183:\t\treturn stmmac_dvr_probe(\u0026pdev-\u003edev, plat, \u0026res);\n 184:\t}\n 185:\t\n 186:\t/**\n 187:\t * stmmac_pci_remove\n 188:\t *\n 189:\t * @pdev: platform device pointer\n 190:\t * Description: this function calls the main to free the net resources.\n 191:\t */\n 192:\tstatic void stmmac_pci_remove(struct pci_dev *pdev)\n 193:\t{\n 194:\t\tstmmac_dvr_remove(\u0026pdev-\u003edev);\n 195:\t}\n 196:\t\n 197:\t/* synthetic ID, no official vendor */\n 198:\t#define PCI_VENDOR_ID_STMMAC\t\t0x0700\n 199:\t\n 200:\t#define PCI_DEVICE_ID_STMMAC_STMMAC\t\t0x1108\n 201:\t#define PCI_DEVICE_ID_SYNOPSYS_GMAC5_ID\t\t0x7102\n 202:\t\n 203:\tstatic const struct pci_device_id stmmac_id_table[] = {\n 204:\t\t{ PCI_DEVICE_DATA(STMMAC, STMMAC, \u0026stmmac_pci_info) },\n 205:\t\t{ PCI_DEVICE_DATA(STMICRO, MAC, \u0026stmmac_pci_info) },\n 206:\t\t{ PCI_DEVICE_DATA(SYNOPSYS, GMAC5_ID, \u0026snps_gmac5_pci_info) },\n 207:\t\t{}\n 208:\t};\n 209:\t\n 210:\tMODULE_DEVICE_TABLE(pci, stmmac_id_table);\n 211:\t\n 212:\tstatic struct pci_driver stmmac_pci_driver = {\n 213:\t\t.name = STMMAC_RESOURCE_NAME,\n 214:\t\t.id_table = stmmac_id_table,\n 215:\t\t.probe = stmmac_pci_probe,\n 216:\t\t.remove = stmmac_pci_remove,\n 217:\t\t.driver = {\n"
} |
| 11/2 | 2026/08/08 14:57 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 24545 output: 22 thoughts: 44 Thoughts: Okay, here's my interpretation of that thought process, from an expert's perspective: **Probing the STMMAC Driver with Dummy Memory** Alright, so the `stmmac_pci_probe` function is the entry point for probing the STMMAC Ethernet driver when it's dealing with a PCI device, which makes sense. Now, `stmmac_pci_probe` then calls `stmmac_dvr_probe`. That's where the core driver initialization happens. My immediate thought is to consider the robustness of the driver's memory handling. Can I successfully execute this `stmmac_dvr_probe` with a "dummy" memory configuration? By that, I mean, can I test its fundamental operations without relying on the actual, correct memory map initially? This is a really useful debugging technique. If `stmmac_dvr_probe` *can* handle a situation where it's fed some placeholder memory addresses or sizes initially, it implies a certain degree of resilience and isolation in its memory management. This would make testing the driver easier in isolation from hardware constraints and perhaps aid in a simulated environment. We can see if we can get this to succeed with a dummy memory before continuing. |
| 12/2 | 2026/08/08 14:57 | tool | grepper |
0mArgs:{
"Expression": "stmmac_dvr_probe"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c=283=static int dwc_eth_dwmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c-329-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c:330:\tret = stmmac_dvr_probe(\u0026pdev-\u003edev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c-331-\tif (ret)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c=42=static int intel_eth_plat_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c-117-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c:118:\tret = stmmac_dvr_probe(\u0026pdev-\u003edev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel-plat.c-119-\tif (ret)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c=1263=static int intel_eth_pci_probe(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1340-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:1341:\tret = stmmac_dvr_probe(\u0026pdev-\u003edev, plat, \u0026res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-intel.c-1342-\tif (ret) {\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c=374=static int ipq806x_gmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c-482-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c:483:\treturn stmmac_dvr_probe(\u0026pdev-\u003edev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c-484-\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c=498=static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id *id)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-561-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c:562:\tret = stmmac_dvr_probe(\u0026pdev-\u003edev, plat, \u0026res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c-563-\tif (ret)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c=42=static int lpc18xx_dwmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c-67-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c:68:\treturn stmmac_dvr_probe(\u0026pdev-\u003edev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c-69-}\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c=599=static int mediatek_dwmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c-641-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c:642:\tret = stmmac_dvr_probe(\u0026pdev-\u003edev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c-643-\tif (ret)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-meson.c=47=static int meson6_dwmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-meson.c-72-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-meson.c:73:\treturn stmmac_dvr_probe(\u0026pdev-\u003edev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-meson.c-74-}\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c=382=static int meson8b_dwmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c-463-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c:464:\treturn stmmac_dvr_probe(\u0026pdev-\u003edev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c-465-}\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c=293=static int motorcomm_probe(struct pci_dev *pdev, const struct pci_device_id *id)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c-358-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c:359:\treturn stmmac_dvr_probe(\u0026pdev-\u003edev, plat, \u0026res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c-360-}\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c=48=static int rzn1_dwmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c-67-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c:68:\tret = stmmac_dvr_probe(dev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-rzn1.c-69-\tif (ret)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c=35=static int sophgo_dwmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c-64-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c:65:\treturn stmmac_dvr_probe(dev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c-66-}\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c=147=static int spacemit_dwmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c-206-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c:207:\treturn stmmac_dvr_probe(dev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-spacemit.c-208-}\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c=90=static int starfive_dwmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c-152-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c:153:\treturn stmmac_dvr_probe(\u0026pdev-\u003edev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-starfive.c-154-}\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c=525=static int stm32_dwmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c-578-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c:579:\tret = stmmac_dvr_probe(\u0026pdev-\u003edev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c-580-\tif (ret)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c=1105=static int sun8i_dwmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c-1201-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c:1202:\t/* the MAC is runtime suspended after stmmac_dvr_probe(), so we\ndrivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c-1203-\t * need to ensure the MAC resume back before other operations such\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c-1208-\t/* The mux must be registered after parent MDIO\ndrivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c:1209:\t * so after stmmac_dvr_probe()\ndrivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c-1210-\t */\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c=214=static int tegra_mgbe_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c-375-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c:376:\terr = stmmac_dvr_probe(\u0026pdev-\u003edev, plat, \u0026res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-tegra.c-377-\tif (err \u003c 0)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c=205=static int visconti_eth_dwmac_probe(struct platform_device *pdev)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c-236-\ndrivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c:237:\tret = stmmac_dvr_probe(\u0026pdev-\u003edev, plat_dat, \u0026stmmac_res);\ndrivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c-238-\tif (ret)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac.h=423=void stmmac_dvr_remove(struct device *dev);\ndrivers/net/ethernet/stmicro/stmmac/stmmac.h:424:int stmmac_dvr_probe(struct device *device,\ndrivers/net/ethernet/stmicro/stmmac/stmmac.h-425-\t\t struct plat_stmmacenet_data *plat_dat,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7830=EXPORT_SYMBOL_GPL(stmmac_plat_dat_alloc);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7831-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7832:static int __stmmac_dvr_probe(struct device *device,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7833-\t\t\t struct plat_stmmacenet_data *plat_dat,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8134-/**\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8135: * stmmac_dvr_probe\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8136- * @dev: device pointer\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8143- */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8144:int stmmac_dvr_probe(struct device *dev, struct plat_stmmacenet_data *plat_dat,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8145-\t\t struct stmmac_resources *res)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8154-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8155:\tret = __stmmac_dvr_probe(dev, plat_dat, res);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8156-\tif (ret \u0026\u0026 plat_dat-\u003eexit)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8160-}\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8161:EXPORT_SYMBOL_GPL(stmmac_dvr_probe);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8162-\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c=118=static int stmmac_pci_probe(struct pci_dev *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-182-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:183:\treturn stmmac_dvr_probe(\u0026pdev-\u003edev, plat, \u0026res);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-184-}\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_platform.c=848=int stmmac_pltfr_probe(struct platform_device *pdev,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_platform.c-856-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_platform.c:857:\treturn stmmac_dvr_probe(\u0026pdev-\u003edev, plat, res);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_platform.c-858-}\n"
} |
| 13/2 | 2026/08/08 14:57 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 28985 output: 51 thoughts: 15 Thoughts: Okay, here's my attempt at summarizing that thought process, keeping in mind I'm speaking to a fellow expert: **Diving into `__stmmac_dvr_probe`** Alright, time to dig in. The kernel is pointing me toward `__stmmac_dvr_probe`. Let's assume this is the starting point for the STMMAC driver's probe function. This is where the magic happens, at least initially. This is where I would expect to see the resource allocation, device initialization, and platform-specific setup happening. Likely, this is where the hardware is being identified and associated with the driver. I’ll need to understand the control flow here: what's it checking, what's it calling, and what's it setting up? This is the core of getting the device ready to run. Let’s see what goodies await inside! |
| 14/2 | 2026/08/08 14:57 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/stmmac_main.c",
"FirstLine": 7832,
"LineCount": 100
}Results: {
"Contents": "7832:\tstatic int __stmmac_dvr_probe(struct device *device,\n7833:\t\t\t\t struct plat_stmmacenet_data *plat_dat,\n7834:\t\t\t\t struct stmmac_resources *res)\n7835:\t{\n7836:\t\tstruct net_device *ndev = NULL;\n7837:\t\tstruct stmmac_priv *priv;\n7838:\t\tint i, ret = 0;\n7839:\t\tu8 rxq;\n7840:\t\n7841:\t\tif (!plat_dat-\u003edma_cfg || !plat_dat-\u003edma_cfg-\u003epbl) {\n7842:\t\t\tdev_err(device, \"invalid DMA configuration\\n\");\n7843:\t\t\treturn -EINVAL;\n7844:\t\t}\n7845:\t\n7846:\t\tndev = devm_alloc_etherdev_mqs(device, sizeof(struct stmmac_priv),\n7847:\t\t\t\t\t MTL_MAX_TX_QUEUES, MTL_MAX_RX_QUEUES);\n7848:\t\tif (!ndev)\n7849:\t\t\treturn -ENOMEM;\n7850:\t\n7851:\t\tSET_NETDEV_DEV(ndev, device);\n7852:\t\n7853:\t\tpriv = netdev_priv(ndev);\n7854:\t\tpriv-\u003edevice = device;\n7855:\t\tpriv-\u003edev = ndev;\n7856:\t\n7857:\t\tfor (i = 0; i \u003c MTL_MAX_RX_QUEUES; i++)\n7858:\t\t\tu64_stats_init(\u0026priv-\u003exstats.rxq_stats[i].napi_syncp);\n7859:\t\tfor (i = 0; i \u003c MTL_MAX_TX_QUEUES; i++) {\n7860:\t\t\tu64_stats_init(\u0026priv-\u003exstats.txq_stats[i].q_syncp);\n7861:\t\t\tu64_stats_init(\u0026priv-\u003exstats.txq_stats[i].napi_syncp);\n7862:\t\t}\n7863:\t\n7864:\t\tpriv-\u003exstats.pcpu_stats =\n7865:\t\t\tdevm_netdev_alloc_pcpu_stats(device, struct stmmac_pcpu_stats);\n7866:\t\tif (!priv-\u003exstats.pcpu_stats)\n7867:\t\t\treturn -ENOMEM;\n7868:\t\n7869:\t\tstmmac_set_ethtool_ops(ndev);\n7870:\t\tpriv-\u003epause_time = pause;\n7871:\t\tpriv-\u003eplat = plat_dat;\n7872:\t\tpriv-\u003eioaddr = res-\u003eaddr;\n7873:\t\tpriv-\u003edev-\u003ebase_addr = (unsigned long)res-\u003eaddr;\n7874:\t\tpriv-\u003eplat-\u003edma_cfg-\u003emulti_msi_en =\n7875:\t\t\t(priv-\u003eplat-\u003eflags \u0026 STMMAC_FLAG_MULTI_MSI_EN);\n7876:\t\n7877:\t\tpriv-\u003edev-\u003eirq = res-\u003eirq;\n7878:\t\tpriv-\u003ewol_irq = res-\u003ewol_irq;\n7879:\t\tpriv-\u003esfty_irq = res-\u003esfty_irq;\n7880:\t\n7881:\t\tif (priv-\u003eplat-\u003eflags \u0026 STMMAC_FLAG_MULTI_MSI_EN) {\n7882:\t\t\tret = stmmac_msi_init(priv, res);\n7883:\t\t\tif (ret)\n7884:\t\t\t\treturn ret;\n7885:\t\t}\n7886:\t\n7887:\t\tif (!is_zero_ether_addr(res-\u003emac))\n7888:\t\t\teth_hw_addr_set(priv-\u003edev, res-\u003emac);\n7889:\t\n7890:\t\tdev_set_drvdata(device, priv-\u003edev);\n7891:\t\n7892:\t\t/* Verify driver arguments */\n7893:\t\tstmmac_verify_args();\n7894:\t\n7895:\t\tpriv-\u003eaf_xdp_zc_qps = bitmap_zalloc(MTL_MAX_TX_QUEUES, GFP_KERNEL);\n7896:\t\tif (!priv-\u003eaf_xdp_zc_qps)\n7897:\t\t\treturn -ENOMEM;\n7898:\t\n7899:\t\t/* Allocate workqueue */\n7900:\t\tpriv-\u003ewq = create_singlethread_workqueue(\"stmmac_wq\");\n7901:\t\tif (!priv-\u003ewq) {\n7902:\t\t\tdev_err(priv-\u003edevice, \"failed to create workqueue\\n\");\n7903:\t\t\tret = -ENOMEM;\n7904:\t\t\tgoto error_wq_init;\n7905:\t\t}\n7906:\t\n7907:\t\tINIT_WORK(\u0026priv-\u003eservice_task, stmmac_service_task);\n7908:\t\n7909:\t\ttimer_setup(\u0026priv-\u003eeee_ctrl_timer, stmmac_eee_ctrl_timer, 0);\n7910:\t\n7911:\t\t/* Override with kernel parameters if supplied XXX CRS XXX\n7912:\t\t * this needs to have multiple instances\n7913:\t\t */\n7914:\t\tif ((phyaddr \u003e= 0) \u0026\u0026 (phyaddr \u003c= 31))\n7915:\t\t\tpriv-\u003eplat-\u003ephy_addr = phyaddr;\n7916:\t\n7917:\t\tif (priv-\u003eplat-\u003estmmac_rst) {\n7918:\t\t\tret = reset_control_assert(priv-\u003eplat-\u003estmmac_rst);\n7919:\t\t\treset_control_deassert(priv-\u003eplat-\u003estmmac_rst);\n7920:\t\t\t/* Some reset controllers have only reset callback instead of\n7921:\t\t\t * assert + deassert callbacks pair.\n7922:\t\t\t */\n7923:\t\t\tif (ret == -ENOTSUPP)\n7924:\t\t\t\treset_control_reset(priv-\u003eplat-\u003estmmac_rst);\n7925:\t\t}\n7926:\t\n7927:\t\tret = reset_control_deassert(priv-\u003eplat-\u003estmmac_ahb_rst);\n7928:\t\tif (ret == -ENOTSUPP)\n7929:\t\t\tdev_err(priv-\u003edevice, \"unable to bring out of ahb reset: %pe\\n\",\n7930:\t\t\t\tERR_PTR(ret));\n7931:\t\n"
} |
| 15/2 | 2026/08/08 14:57 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 30927 output: 51 thoughts: 17 Thoughts: Okay, here's my attempt at summarizing the thought process, as requested, geared toward an expert audience, and written in the first person: **Diving into `__stmmac_dvr_probe`** Alright, let's get down to brass tacks. I need to take a closer look at this `__stmmac_dvr_probe` function. I know this is the driver probe function for the STMMAC Ethernet driver. My goal is to quickly grasp the key aspects of its operation. I'm looking for the essential steps to understand how it binds to a new device. First, I need to understand if this is related to the DT or platform data parsing. I'm mentally running through the typical probe sequence: device initialization, resource allocation (IRQ, memory regions), clock configuration, and then the hardware setup. Specifically, I'm expecting to see something like resource requests via the platform or device tree, followed by the mapping of memory-mapped registers, perhaps some clock enable/disable logic, and then the critical step: DMA engine initialization. Then, initialization of the DMA descriptors. I'll be paying close attention to how it handles potential errors. Any robust driver needs to have graceful error handling and resource cleanup. I'm expecting some kind of check for the STMMAC's capabilities to align with my expectations. This is critical for compatibility. Furthermore, I'll examine the interrupt setup. How are interrupts enabled and handled? What interrupt handlers are registered? What masking and unmasking methods are used? How is the driver prepared to handle link changes and packet reception/transmission? Given my prior knowledge, I'm expecting to see calls to register DMA channels or maybe even to configure the STMMAC to enable and initialize itself. Ultimately, I want to assess whether this probe function is clean, efficient, and adheres to best practices. I also need to identify which data structures and callbacks are critical to the device's ongoing operation. Okay, let's start digging into the code and see what we find! |
| 16/2 | 2026/08/08 14:57 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/stmmac_main.c",
"FirstLine": 7932,
"LineCount": 100
}Results: {
"Contents": "7932:\t\t/* Wait a bit for the reset to take effect */\n7933:\t\tudelay(10);\n7934:\t\n7935:\t\t/* Init MAC and get the capabilities */\n7936:\t\tret = stmmac_hw_init(priv);\n7937:\t\tif (ret)\n7938:\t\t\tgoto error_hw_init;\n7939:\t\n7940:\t\t/* Only DWMAC core version 5.20 onwards supports HW descriptor prefetch.\n7941:\t\t */\n7942:\t\tif (priv-\u003esynopsys_id \u003c DWMAC_CORE_5_20)\n7943:\t\t\tpriv-\u003eplat-\u003edma_cfg-\u003edche = false;\n7944:\t\n7945:\t\tstmmac_check_ether_addr(priv);\n7946:\t\n7947:\t\tndev-\u003enetdev_ops = \u0026stmmac_netdev_ops;\n7948:\t\n7949:\t\tndev-\u003exdp_metadata_ops = \u0026stmmac_xdp_metadata_ops;\n7950:\t\tndev-\u003exsk_tx_metadata_ops = \u0026stmmac_xsk_tx_metadata_ops;\n7951:\t\n7952:\t\tndev-\u003ehw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |\n7953:\t\t\t\t NETIF_F_RXCSUM;\n7954:\t\tndev-\u003exdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_REDIRECT |\n7955:\t\t\t\t NETDEV_XDP_ACT_XSK_ZEROCOPY;\n7956:\t\n7957:\t\tret = stmmac_tc_init(priv, priv);\n7958:\t\tif (!ret) {\n7959:\t\t\tndev-\u003ehw_features |= NETIF_F_HW_TC;\n7960:\t\t}\n7961:\t\n7962:\t\tstmmac_set_gso_features(ndev);\n7963:\t\n7964:\t\tif (priv-\u003edma_cap.sphen \u0026\u0026\n7965:\t\t !(priv-\u003eplat-\u003eflags \u0026 STMMAC_FLAG_SPH_DISABLE)) {\n7966:\t\t\tndev-\u003ehw_features |= NETIF_F_GRO;\n7967:\t\t\tpriv-\u003esph_capable = true;\n7968:\t\t\tpriv-\u003esph_active = priv-\u003esph_capable;\n7969:\t\t\tdev_info(priv-\u003edevice, \"SPH feature enabled\\n\");\n7970:\t\t}\n7971:\t\n7972:\t\t/* Ideally our host DMA address width is the same as for the\n7973:\t\t * device. However, it may differ and then we have to use our\n7974:\t\t * host DMA width for allocation and the device DMA width for\n7975:\t\t * register handling.\n7976:\t\t */\n7977:\t\tif (priv-\u003eplat-\u003ehost_dma_width)\n7978:\t\t\tpriv-\u003edma_cap.host_dma_width = priv-\u003eplat-\u003ehost_dma_width;\n7979:\t\telse\n7980:\t\t\tpriv-\u003edma_cap.host_dma_width = priv-\u003edma_cap.addr64;\n7981:\t\n7982:\t\tif (priv-\u003edma_cap.host_dma_width) {\n7983:\t\t\tret = dma_set_mask_and_coherent(device,\n7984:\t\t\t\t\tDMA_BIT_MASK(priv-\u003edma_cap.host_dma_width));\n7985:\t\t\tif (!ret) {\n7986:\t\t\t\tdev_info(priv-\u003edevice, \"Using %d/%d bits DMA host/device width\\n\",\n7987:\t\t\t\t\t priv-\u003edma_cap.host_dma_width, priv-\u003edma_cap.addr64);\n7988:\t\n7989:\t\t\t\t/*\n7990:\t\t\t\t * If more than 32 bits can be addressed, make sure to\n7991:\t\t\t\t * enable enhanced addressing mode.\n7992:\t\t\t\t */\n7993:\t\t\t\tif (IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT))\n7994:\t\t\t\t\tpriv-\u003eplat-\u003edma_cfg-\u003eeame = true;\n7995:\t\t\t} else {\n7996:\t\t\t\tret = dma_set_mask_and_coherent(device, DMA_BIT_MASK(32));\n7997:\t\t\t\tif (ret) {\n7998:\t\t\t\t\tdev_err(priv-\u003edevice, \"Failed to set DMA Mask\\n\");\n7999:\t\t\t\t\tgoto error_hw_init;\n8000:\t\t\t\t}\n8001:\t\n8002:\t\t\t\tpriv-\u003edma_cap.host_dma_width = 32;\n8003:\t\t\t}\n8004:\t\t}\n8005:\t\n8006:\t\tndev-\u003efeatures |= ndev-\u003ehw_features | NETIF_F_HIGHDMA;\n8007:\t\tndev-\u003ewatchdog_timeo = msecs_to_jiffies(watchdog);\n8008:\t#ifdef STMMAC_VLAN_TAG_USED\n8009:\t\t/* Both mac100 and gmac support receive VLAN tag detection */\n8010:\t\tndev-\u003efeatures |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX;\n8011:\t\tif (dwmac_is_xmac(priv-\u003eplat-\u003ecore_type)) {\n8012:\t\t\tndev-\u003ehw_features |= NETIF_F_HW_VLAN_CTAG_RX;\n8013:\t\t\tpriv-\u003ehw-\u003ehw_vlan_en = true;\n8014:\t\t}\n8015:\t\tif (priv-\u003edma_cap.vlhash) {\n8016:\t\t\tndev-\u003efeatures |= NETIF_F_HW_VLAN_CTAG_FILTER;\n8017:\t\t\tndev-\u003efeatures |= NETIF_F_HW_VLAN_STAG_FILTER;\n8018:\t\t}\n8019:\t\tif (priv-\u003edma_cap.vlins)\n8020:\t\t\tndev-\u003efeatures |= NETIF_F_HW_VLAN_CTAG_TX;\n8021:\t#endif\n8022:\t\tpriv-\u003emsg_enable = netif_msg_init(debug, default_msg_level);\n8023:\t\n8024:\t\tpriv-\u003exstats.threshold = tc;\n8025:\t\n8026:\t\t/* Initialize RSS */\n8027:\t\trxq = priv-\u003eplat-\u003erx_queues_to_use;\n8028:\t\tnetdev_rss_key_fill(priv-\u003erss.key, sizeof(priv-\u003erss.key));\n8029:\t\tfor (i = 0; i \u003c ARRAY_SIZE(priv-\u003erss.table); i++)\n8030:\t\t\tpriv-\u003erss.table[i] = ethtool_rxfh_indir_default(i, rxq);\n8031:\t\n"
} |
| 17/2 | 2026/08/08 14:57 | llm | patch-evaluator |
4mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 33255 output: 21 thoughts: 20 Thoughts: Here's a summary of my thought process: **Diving into the STMMAC Initialization** Okay, so we're starting up, and the code has hit `stmmac_hw_init`. Right away, I'm thinking, "Let's see what's actually going on in there." I need to understand the hardware initialization sequence of the STMMAC driver. I want to know exactly how it sets up the registers, configures the MAC itself, and gets things ready to receive and transmit packets. I'm looking for the nitty-gritty details of the hardware configuration. I want to see how the registers are programmed. The DMA settings, flow control, interrupt enablement – that's all what I will be going to check in that initialization function. |
| 18/2 | 2026/08/08 15:02 | tool | grepper |
0mArgs:{
"Expression": "stmmac_hw_init"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7401=static void stmmac_print_actphyif(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7435-/**\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7436: * stmmac_hw_init - Init the MAC device\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7437- * @priv: driver private structure\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7442- */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7443:static int stmmac_hw_init(struct stmmac_priv *priv)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7444-{\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7832=static int __stmmac_dvr_probe(struct device *device,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7935-\t/* Init MAC and get the capabilities */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7936:\tret = stmmac_hw_init(priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7937-\tif (ret)\n"
} |
| 19/2 | 2026/08/08 15:02 | llm | patch-evaluator |
4mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 33896 output: 51 thoughts: 13 Thoughts: Okay, here we go. Let's dive into this `stmmac_hw_init` function. I need to understand how the hardware is being brought up, the initial register configurations, and any crucial setup steps before the driver is fully operational. This is a critical piece, laying the groundwork for everything else. I'll be looking for potential areas of concern: Are there any hardware-specific quirks being addressed here? Any obvious assumptions made about the underlying hardware that could cause problems down the line? Are the clock configurations being handled correctly, and are interrupts being enabled at this point? I also want to identify any "magic numbers" or hardcoded values that might indicate a lack of proper abstraction or could introduce portability issues. The goal is a clear mental map of what this initialisation code is doing and the potential downstream effects of any choices made within it. Let's see if this function is as robust as it needs to be. |
| 20/2 | 2026/08/08 15:06 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/stmmac_main.c",
"FirstLine": 7443,
"LineCount": 100
}Results: {
"Contents": "7443:\tstatic int stmmac_hw_init(struct stmmac_priv *priv)\n7444:\t{\n7445:\t\tint ret;\n7446:\t\n7447:\t\t/* dwmac-sun8i only work in chain mode */\n7448:\t\tif (priv-\u003eplat-\u003eflags \u0026 STMMAC_FLAG_HAS_SUN8I)\n7449:\t\t\tchain_mode = 1;\n7450:\t\tpriv-\u003echain_mode = !!chain_mode;\n7451:\t\n7452:\t\t/* Initialize HW Interface */\n7453:\t\tret = stmmac_hwif_init(priv);\n7454:\t\tif (ret)\n7455:\t\t\treturn ret;\n7456:\t\n7457:\t\t/* Get the HW capability (new GMAC newer than 3.50a) */\n7458:\t\tpriv-\u003ehw_cap_support = stmmac_get_hw_features(priv);\n7459:\t\tif (priv-\u003ehw_cap_support) {\n7460:\t\t\tdev_info(priv-\u003edevice, \"DMA HW capability register supported\\n\");\n7461:\t\n7462:\t\t\t/* We can override some gmac/dma configuration fields: e.g.\n7463:\t\t\t * enh_desc, tx_coe (e.g. that are passed through the\n7464:\t\t\t * platform) with the values from the HW capability\n7465:\t\t\t * register (if supported).\n7466:\t\t\t */\n7467:\t\t\tpriv-\u003eplat-\u003eenh_desc = priv-\u003edma_cap.enh_desc;\n7468:\t\t\tpriv-\u003eplat-\u003epmt = priv-\u003edma_cap.pmt_remote_wake_up \u0026\u0026\n7469:\t\t\t\t\t!(priv-\u003eplat-\u003eflags \u0026 STMMAC_FLAG_USE_PHY_WOL);\n7470:\t\t\tif (priv-\u003edma_cap.hash_tb_sz) {\n7471:\t\t\t\tpriv-\u003ehw-\u003emulticast_filter_bins =\n7472:\t\t\t\t\t\t(BIT(priv-\u003edma_cap.hash_tb_sz) \u003c\u003c 5);\n7473:\t\t\t\tpriv-\u003ehw-\u003emcast_bits_log2 =\n7474:\t\t\t\t\t\tilog2(priv-\u003ehw-\u003emulticast_filter_bins);\n7475:\t\t\t}\n7476:\t\n7477:\t\t\t/* TXCOE doesn't work in thresh DMA mode */\n7478:\t\t\tif (priv-\u003eplat-\u003eforce_thresh_dma_mode)\n7479:\t\t\t\tpriv-\u003eplat-\u003etx_coe = false;\n7480:\t\t\telse\n7481:\t\t\t\tpriv-\u003eplat-\u003etx_coe = priv-\u003edma_cap.tx_coe;\n7482:\t\n7483:\t\t\t/* In case of GMAC4 rx_coe is from HW cap register. */\n7484:\t\t\tpriv-\u003eplat-\u003erx_coe = priv-\u003edma_cap.rx_coe;\n7485:\t\n7486:\t\t\tif (priv-\u003edma_cap.rx_coe_type2)\n7487:\t\t\t\tpriv-\u003eplat-\u003erx_coe = STMMAC_RX_COE_TYPE2;\n7488:\t\t\telse if (priv-\u003edma_cap.rx_coe_type1)\n7489:\t\t\t\tpriv-\u003eplat-\u003erx_coe = STMMAC_RX_COE_TYPE1;\n7490:\t\n7491:\t\t\tstmmac_print_actphyif(priv);\n7492:\t\t} else {\n7493:\t\t\tdev_info(priv-\u003edevice, \"No HW DMA feature register supported\\n\");\n7494:\t\t}\n7495:\t\n7496:\t\tif (priv-\u003eplat-\u003erx_coe) {\n7497:\t\t\tpriv-\u003ehw-\u003erx_csum = priv-\u003eplat-\u003erx_coe;\n7498:\t\t\tdev_info(priv-\u003edevice, \"RX Checksum Offload Engine supported\\n\");\n7499:\t\t\tif (priv-\u003esynopsys_id \u003c DWMAC_CORE_4_00)\n7500:\t\t\t\tdev_info(priv-\u003edevice, \"COE Type %d\\n\", priv-\u003ehw-\u003erx_csum);\n7501:\t\t}\n7502:\t\tif (priv-\u003eplat-\u003etx_coe)\n7503:\t\t\tdev_info(priv-\u003edevice, \"TX Checksum insertion supported\\n\");\n7504:\t\n7505:\t\tif (priv-\u003eplat-\u003epmt) {\n7506:\t\t\tdev_info(priv-\u003edevice, \"Wake-Up On Lan supported\\n\");\n7507:\t\t\tdevice_set_wakeup_capable(priv-\u003edevice, 1);\n7508:\t\t\tdevm_pm_set_wake_irq(priv-\u003edevice, priv-\u003ewol_irq);\n7509:\t\t}\n7510:\t\n7511:\t\tif (priv-\u003edma_cap.number_rx_queues \u0026\u0026\n7512:\t\t priv-\u003eplat-\u003erx_queues_to_use \u003e priv-\u003edma_cap.number_rx_queues) {\n7513:\t\t\tdev_warn(priv-\u003edevice,\n7514:\t\t\t\t \"Number of Rx queues (%u) exceeds dma capability\\n\",\n7515:\t\t\t\t priv-\u003eplat-\u003erx_queues_to_use);\n7516:\t\t\tpriv-\u003eplat-\u003erx_queues_to_use = priv-\u003edma_cap.number_rx_queues;\n7517:\t\t}\n7518:\t\tif (priv-\u003edma_cap.number_tx_queues \u0026\u0026\n7519:\t\t priv-\u003eplat-\u003etx_queues_to_use \u003e priv-\u003edma_cap.number_tx_queues) {\n7520:\t\t\tdev_warn(priv-\u003edevice,\n7521:\t\t\t\t \"Number of Tx queues (%u) exceeds dma capability\\n\",\n7522:\t\t\t\t priv-\u003eplat-\u003etx_queues_to_use);\n7523:\t\t\tpriv-\u003eplat-\u003etx_queues_to_use = priv-\u003edma_cap.number_tx_queues;\n7524:\t\t}\n7525:\t\n7526:\t\tif (priv-\u003edma_cap.rx_fifo_size \u0026\u0026\n7527:\t\t priv-\u003eplat-\u003erx_fifo_size \u003e priv-\u003edma_cap.rx_fifo_size) {\n7528:\t\t\tdev_warn(priv-\u003edevice,\n7529:\t\t\t\t \"Rx FIFO size (%u) exceeds dma capability\\n\",\n7530:\t\t\t\t priv-\u003eplat-\u003erx_fifo_size);\n7531:\t\t\tpriv-\u003eplat-\u003erx_fifo_size = priv-\u003edma_cap.rx_fifo_size;\n7532:\t\t}\n7533:\t\tif (priv-\u003edma_cap.tx_fifo_size \u0026\u0026\n7534:\t\t priv-\u003eplat-\u003etx_fifo_size \u003e priv-\u003edma_cap.tx_fifo_size) {\n7535:\t\t\tdev_warn(priv-\u003edevice,\n7536:\t\t\t\t \"Tx FIFO size (%u) exceeds dma capability\\n\",\n7537:\t\t\t\t priv-\u003eplat-\u003etx_fifo_size);\n7538:\t\t\tpriv-\u003eplat-\u003etx_fifo_size = priv-\u003edma_cap.tx_fifo_size;\n7539:\t\t}\n7540:\t\n7541:\t\tpriv-\u003ehw-\u003evlan_fail_q_en =\n7542:\t\t\t(priv-\u003eplat-\u003eflags \u0026 STMMAC_FLAG_VLAN_FAIL_Q_EN);\n"
} |
| 21/2 | 2026/08/08 15:06 | llm | patch-evaluator |
2mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 36054 output: 22 thoughts: 39 Thoughts: Okay, here's my interpretation of those thoughts, summarized from an expert's perspective: **Initial Hardware Interface Initialization** Alright, so the driver's jumping straight into the hardware interface initialization. It's calling `stmmac_hwif_init` first, which is the expected initial setup routine. Then, it's grabbing the hardware features with `stmmac_get_hw_features`. It makes sense; we need to understand the capabilities of this specific StMMAC variant before proceeding. I'm keen to see what's happening within that `stmmac_hwif_init` function. I'll take a closer look at that to see how the hardware interface is set up. |
| 22/2 | 2026/08/08 15:09 | tool | grepper |
0mArgs:{
"Expression": "stmmac_hwif_init"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/hwif.c=294=stmmac_hwif_find(enum dwmac_core_type core_type, u8 snpsver, u8 dev_id)\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.c-316-\ndrivers/net/ethernet/stmicro/stmmac/hwif.c:317:int stmmac_hwif_init(struct stmmac_priv *priv)\ndrivers/net/ethernet/stmicro/stmmac/hwif.c-318-{\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.h=701=int stmmac_reset(struct stmmac_priv *priv);\ndrivers/net/ethernet/stmicro/stmmac/hwif.h:702:int stmmac_hwif_init(struct stmmac_priv *priv);\ndrivers/net/ethernet/stmicro/stmmac/hwif.h-703-\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7443=static int stmmac_hw_init(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7452-\t/* Initialize HW Interface */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7453:\tret = stmmac_hwif_init(priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7454-\tif (ret)\n"
} |
| 23/2 | 2026/08/08 15:09 | llm | patch-evaluator |
2mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 36696 output: 46 thoughts: 14 Thoughts: Okay, let's dive into `stmmac_hwif_init`. I need to get a good understanding of how this initialization function works. I'm assuming, given the name, it's responsible for bringing up the hardware interface for the STMMAC Ethernet driver. I'll need to pay close attention to the data structures it uses, particularly any interaction with the device tree and any memory allocation it performs. I’m expecting to see configuration of the DMA engine, PHY interaction, and interrupt setup in here. Understanding the flow of these operations is crucial. I want to see how it handles potential errors and what steps are taken during the setup. It's also important to note the various hardware variations this code might need to support. Let’s see how elegantly it handles these different configurations. I need to keep in mind possible race conditions at different points during the process. |
| 24/2 | 2026/08/08 15:11 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/hwif.c",
"FirstLine": 317,
"LineCount": 50
}Results: {
"Contents": " 317:\tint stmmac_hwif_init(struct stmmac_priv *priv)\n 318:\t{\n 319:\t\tenum dwmac_core_type core_type = priv-\u003eplat-\u003ecore_type;\n 320:\t\tconst struct stmmac_hwif_entry *entry;\n 321:\t\tstruct stmmac_version version;\n 322:\t\tstruct mac_device_info *mac;\n 323:\t\tbool needs_setup = true;\n 324:\t\tint ret;\n 325:\t\n 326:\t\tstmmac_get_version(priv, \u0026version);\n 327:\t\n 328:\t\t/* Save ID for later use */\n 329:\t\tpriv-\u003esynopsys_id = version.snpsver;\n 330:\t\n 331:\t\tmac = devm_kzalloc(priv-\u003edevice, sizeof(*mac), GFP_KERNEL);\n 332:\t\tif (!mac)\n 333:\t\t\treturn -ENOMEM;\n 334:\t\n 335:\t\t/* Check for HW specific setup first */\n 336:\t\tif (priv-\u003eplat-\u003emac_setup) {\n 337:\t\t\tret = priv-\u003eplat-\u003emac_setup(priv, mac);\n 338:\t\t\tif (ret)\n 339:\t\t\t\treturn ret;\n 340:\t\n 341:\t\t\tneeds_setup = false;\n 342:\t\t}\n 343:\t\n 344:\t\tspin_lock_init(\u0026mac-\u003eirq_ctrl_lock);\n 345:\t\n 346:\t\t/* Fallback to generic HW */\n 347:\t\n 348:\t\t/* Use synopsys_id var because some setups can override this */\n 349:\t\tentry = stmmac_hwif_find(core_type, priv-\u003esynopsys_id, version.dev_id);\n 350:\t\tif (!entry) {\n 351:\t\t\tdev_err(priv-\u003edevice,\n 352:\t\t\t\t\"Failed to find HW IF (id=0x%x, gmac=%d/%d)\\n\",\n 353:\t\t\t\tversion.snpsver, core_type == DWMAC_CORE_GMAC,\n 354:\t\t\t\tcore_type == DWMAC_CORE_GMAC4);\n 355:\t\n 356:\t\t\treturn -EINVAL;\n 357:\t\t}\n 358:\t\n 359:\t\t/* Only use generic HW helpers if needed */\n 360:\t\tmac-\u003edesc = mac-\u003edesc ? : entry-\u003edesc;\n 361:\t\tmac-\u003edma = mac-\u003edma ? : entry-\u003edma;\n 362:\t\tmac-\u003emac = mac-\u003emac ? : entry-\u003emac;\n 363:\t\tmac-\u003eptp = mac-\u003eptp ? : entry-\u003ehwtimestamp;\n 364:\t\tmac-\u003emode = mac-\u003emode ? : entry-\u003emode;\n 365:\t\tmac-\u003etc = mac-\u003etc ? : entry-\u003etc;\n 366:\t\tmac-\u003emmc = mac-\u003emmc ? : entry-\u003emmc;\n"
} |
| 25/2 | 2026/08/08 15:11 | llm | patch-evaluator |
1mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 37741 output: 21 thoughts: 33 Thoughts: Here's my take on the thought process, as if it were my own: **Analyzing the `stmmac_get_version` Function** Okay, so I see `stmmac_get_version` is responsible for grabbing the version information directly from the hardware. That makes sense, a standard procedure for getting the current state of a device. Now, let's dive into the implementation itself. I want to understand *how* it's reading this version number. Is it a simple register read? Does it involve some bit-shifting or masking? I want to see if it utilizes any vendor-specific commands to retrieve the data. Knowing the method will give me clues about reliability and potential areas for optimization or potential conflicts in complex SoCs. I also have to consider what kind of error checking is implemented. |
| 26/2 | 2026/08/08 15:13 | tool | grepper |
0mArgs:{
"Expression": "stmmac_get_version"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/hwif.c=16=struct stmmac_version {\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.c-20-\ndrivers/net/ethernet/stmicro/stmmac/hwif.c:21:static void stmmac_get_version(struct stmmac_priv *priv,\ndrivers/net/ethernet/stmicro/stmmac/hwif.c-22-\t\t\t struct stmmac_version *ver)\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.c=317=int stmmac_hwif_init(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.c-325-\ndrivers/net/ethernet/stmicro/stmmac/hwif.c:326:\tstmmac_get_version(priv, \u0026version);\ndrivers/net/ethernet/stmicro/stmmac/hwif.c-327-\n"
} |
| 27/2 | 2026/08/08 15:13 | llm | patch-evaluator |
2mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 38242 output: 45 thoughts: 13 Thoughts: Okay, here's my interpretation of that thought process, assuming I'm well-versed in embedded systems and device drivers: **Analyzing the Call to `stmmac_get_version`** Alright, the directive is clear: dive into the `stmmac_get_version` function. That's a good starting point. Understanding the version information of the STMicroelectronics MAC driver is crucial, it's the foundation of almost everything. It usually involves reading registers, maybe some internal data structures within the driver, and formatting that data for the user. I'll need to look for where it's defined. Is it a direct register read, or does it involve some more complex logic to determine the driver's revision, feature set, or hardware compatibility? Hopefully, it is well documented; otherwise I will need to understand the register-level interpretation of it. This is definitely a critical component for debugging and ensuring compatibility, especially when dealing with different hardware revisions or kernel versions. I'm going to pay close attention to the data types it's working with and how the version information is structured. |
| 28/2 | 2026/08/08 15:16 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/hwif.c",
"FirstLine": 21,
"LineCount": 40
}Results: {
"Contents": " 21:\tstatic void stmmac_get_version(struct stmmac_priv *priv,\n 22:\t\t\t\t struct stmmac_version *ver)\n 23:\t{\n 24:\t\tenum dwmac_core_type core_type = priv-\u003eplat-\u003ecore_type;\n 25:\t\tunsigned int version_offset;\n 26:\t\tu32 version;\n 27:\t\n 28:\t\tver-\u003esnpsver = 0;\n 29:\t\tver-\u003edev_id = 0;\n 30:\t\n 31:\t\tif (core_type == DWMAC_CORE_MAC100)\n 32:\t\t\treturn;\n 33:\t\n 34:\t\tif (core_type == DWMAC_CORE_GMAC)\n 35:\t\t\tversion_offset = GMAC_VERSION;\n 36:\t\telse\n 37:\t\t\tversion_offset = GMAC4_VERSION;\n 38:\t\n 39:\t\tversion = readl(priv-\u003eioaddr + version_offset);\n 40:\t\tif (version == 0) {\n 41:\t\t\tdev_info(priv-\u003edevice, \"Version ID not available\\n\");\n 42:\t\t\treturn;\n 43:\t\t}\n 44:\t\n 45:\t\tdev_info(priv-\u003edevice, \"User ID: 0x%x, Synopsys ID: 0x%x\\n\",\n 46:\t\t\t FIELD_GET(DWMAC_USERVER, version),\n 47:\t\t\t FIELD_GET(DWMAC_SNPSVER, version));\n 48:\t\n 49:\t\tver-\u003esnpsver = FIELD_GET(DWMAC_SNPSVER, version);\n 50:\t\tif (core_type == DWMAC_CORE_XGMAC)\n 51:\t\t\tver-\u003edev_id = FIELD_GET(DWMAC_USERVER, version);\n 52:\t}\n 53:\t\n 54:\tstatic void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv)\n 55:\t{\n 56:\t\tstruct mac_device_info *mac = priv-\u003ehw;\n 57:\t\n 58:\t\tif (priv-\u003echain_mode) {\n 59:\t\t\tdev_info(priv-\u003edevice, \"Chain mode enabled\\n\");\n 60:\t\t\tpriv-\u003edescriptor_mode = STMMAC_CHAIN_MODE;\n"
} |
| 29/2 | 2026/08/08 15:16 | llm | patch-evaluator |
5mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 39145 output: 46 thoughts: 101 Thoughts: **Analyzing the STMMAC Driver Initialization** Okay, let me think this through. I see the code checks the `version` variable; if it's zero, then `stmmac_get_version` gets called, and subsequently, `ver->snpsver` ends up as zero. That's fine. The next critical step is `stmmac_hwif_init`, which calls `stmmac_hwif_find`. I understand the purpose of that function - it's looking for the right hardware interface structure based on the `core_type`, the Synopsys ID (`priv->synopsys_id`), and the device ID from the version information. Now, my question is about a specific scenario: What happens if `priv->synopsys_id` *is* zero? What does `stmmac_hwif_find` return in that case? Does it return a default interface, error out, or maybe try to auto-detect? Knowing that return value is key to understanding the subsequent behavior of the driver, and how it handles the hardware discovery or configuration. I need to figure out the logic within `stmmac_hwif_find` to determine how the driver reacts in this particular situation. |
| 30/2 | 2026/08/08 15:21 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/hwif.c",
"FirstLine": 294,
"LineCount": 25
}Results: {
"Contents": " 294:\tstmmac_hwif_find(enum dwmac_core_type core_type, u8 snpsver, u8 dev_id)\n 295:\t{\n 296:\t\tconst struct stmmac_hwif_entry *entry;\n 297:\t\tint i;\n 298:\t\n 299:\t\tfor (i = ARRAY_SIZE(stmmac_hw) - 1; i \u003e= 0; i--) {\n 300:\t\t\tentry = \u0026stmmac_hw[i];\n 301:\t\n 302:\t\t\tif (core_type != entry-\u003ecore_type)\n 303:\t\t\t\tcontinue;\n 304:\t\t\t/* Use synopsys_id var because some setups can override this */\n 305:\t\t\tif (snpsver \u003c entry-\u003emin_id)\n 306:\t\t\t\tcontinue;\n 307:\t\t\tif (core_type == DWMAC_CORE_XGMAC \u0026\u0026\n 308:\t\t\t dev_id != entry-\u003edev_id)\n 309:\t\t\t\tcontinue;\n 310:\t\n 311:\t\t\treturn entry;\n 312:\t\t}\n 313:\t\n 314:\t\treturn NULL;\n 315:\t}\n 316:\t\n 317:\tint stmmac_hwif_init(struct stmmac_priv *priv)\n 318:\t{\n"
} |
| 31/2 | 2026/08/08 15:21 | llm | patch-evaluator |
5mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 39928 output: 21 thoughts: 38 Thoughts: Okay, here's my interpretation of those thoughts, presented as my own mental process, given my expertise: **Examining the Impact of `snpsver` and the `stmmac_hw` Array** Alright, I'm digging into this code, specifically how the system handles identifiers. It looks like the value of `snpsver` is crucial. If it's set to zero, then the matching logic is heavily restricted. I'm inferring that a `0` value for `snpsver` means that the system *only* considers entries with `min_id` also at zero. This is probably a very specific configuration, perhaps related to a legacy system, minimal hardware setup, or a certain test scenario. I need to understand what this configuration implies about the expected behavior of the system under these conditions, it's very likely impacting the filtering and selection of hardware configurations or drivers. I immediately recognize the implications for backwards compatibility and potential edge-case performance characteristics. Now, let's turn our attention to the `stmmac_hw` array. I'm going to quickly reference my mental model of the system architecture to understand what roles and relationships are defined by that array, this may be defining hardware or software functionality for STMMAC Ethernet controllers. I'm going to look for what this array represents and how it interacts with the condition I've just identified. I need to understand what hardware variations are associated with each index. I need to be ready to recognize any subtle interactions. |
| 32/2 | 2026/08/08 15:26 | tool | grepper |
0mArgs:{
"Expression": "stmmac_hw\\[\\]"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/hwif.c=111=static const struct stmmac_hwif_entry {\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.c-127-\tint (*quirks)(struct stmmac_priv *priv);\ndrivers/net/ethernet/stmicro/stmmac/hwif.c:128:} stmmac_hw[] = {\ndrivers/net/ethernet/stmicro/stmmac/hwif.c-129-\t/* NOTE: New HW versions shall go to the end of this table */\n"
} |
| 33/2 | 2026/08/08 15:26 | llm | patch-evaluator |
2mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 40463 output: 47 thoughts: 13 Thoughts: Okay, let's dive into this. Here's my thought process as I approach reading the `stmmac_hw` array: **Analyzing the `stmmac_hw` Array** Alright, the first step is clear: I need to understand this `stmmac_hw` array. Based on the name and general context, my expectation is this contains hardware-specific configuration or register definitions related to an STMicroelectronics MAC controller. Given the "hw" suffix, I'm anticipating this is more than likely going to be related to the registers themselves, possibly including their addresses, bitfield definitions, and default values. I'll need to see if it's an array of structs, a simple array of register addresses, or something more complex. The structure here is key. I'll need to determine the format. Does it use bitfields or offsets? Once I understand the array's organization, I can delve into specific registers. What's the context? Is this used during driver initialization, packet transmission, or reception? Knowing the function of the array is key. Where is this array used in the wider code base? Understanding where it's called and the context in which it's accessed will be crucial to fully understand its meaning. I'll need to know which values are set, and when. I'll be looking for comments within the code, ideally describing what each entry or element represents. If there aren't any, I'll need to piece it together by looking at the register names, and any related documentation available for this particular MAC controller. I'll be scrutinizing any accompanying documentation or header files to see if there is any more relevant info. |
| 34/2 | 2026/08/08 15:29 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/hwif.c",
"FirstLine": 128,
"LineCount": 100
}Results: {
"Contents": " 128:\t} stmmac_hw[] = {\n 129:\t\t/* NOTE: New HW versions shall go to the end of this table */\n 130:\t\t{\n 131:\t\t\t.core_type = DWMAC_CORE_MAC100,\n 132:\t\t\t.min_id = 0,\n 133:\t\t\t.regs = {\n 134:\t\t\t\t.ptp_off = PTP_GMAC3_X_OFFSET,\n 135:\t\t\t\t.mmc_off = MMC_GMAC3_X_OFFSET,\n 136:\t\t\t},\n 137:\t\t\t.desc = NULL,\n 138:\t\t\t.dma = \u0026dwmac100_dma_ops,\n 139:\t\t\t.mac = \u0026dwmac100_ops,\n 140:\t\t\t.hwtimestamp = \u0026dwmac1000_ptp,\n 141:\t\t\t.ptp = \u0026dwmac1000_ptp_clock_ops,\n 142:\t\t\t.mode = NULL,\n 143:\t\t\t.tc = NULL,\n 144:\t\t\t.mmc = \u0026dwmac_mmc_ops,\n 145:\t\t\t.setup = dwmac100_setup,\n 146:\t\t\t.quirks = stmmac_dwmac1_quirks,\n 147:\t\t}, {\n 148:\t\t\t.core_type = DWMAC_CORE_GMAC,\n 149:\t\t\t.min_id = 0,\n 150:\t\t\t.regs = {\n 151:\t\t\t\t.ptp_off = PTP_GMAC3_X_OFFSET,\n 152:\t\t\t\t.mmc_off = MMC_GMAC3_X_OFFSET,\n 153:\t\t\t},\n 154:\t\t\t.desc = NULL,\n 155:\t\t\t.dma = \u0026dwmac1000_dma_ops,\n 156:\t\t\t.mac = \u0026dwmac1000_ops,\n 157:\t\t\t.hwtimestamp = \u0026dwmac1000_ptp,\n 158:\t\t\t.ptp = \u0026dwmac1000_ptp_clock_ops,\n 159:\t\t\t.mode = NULL,\n 160:\t\t\t.tc = NULL,\n 161:\t\t\t.mmc = \u0026dwmac_mmc_ops,\n 162:\t\t\t.setup = dwmac1000_setup,\n 163:\t\t\t.quirks = stmmac_dwmac1_quirks,\n 164:\t\t}, {\n 165:\t\t\t.core_type = DWMAC_CORE_GMAC4,\n 166:\t\t\t.min_id = 0,\n 167:\t\t\t.regs = {\n 168:\t\t\t\t.ptp_off = PTP_GMAC4_OFFSET,\n 169:\t\t\t\t.mmc_off = MMC_GMAC4_OFFSET,\n 170:\t\t\t\t.est_off = EST_GMAC4_OFFSET,\n 171:\t\t\t},\n 172:\t\t\t.desc = \u0026dwmac4_desc_ops,\n 173:\t\t\t.dma = \u0026dwmac4_dma_ops,\n 174:\t\t\t.mac = \u0026dwmac4_ops,\n 175:\t\t\t.vlan = \u0026dwmac_vlan_ops,\n 176:\t\t\t.hwtimestamp = \u0026stmmac_ptp,\n 177:\t\t\t.ptp = \u0026stmmac_ptp_clock_ops,\n 178:\t\t\t.mode = NULL,\n 179:\t\t\t.tc = \u0026dwmac4_tc_ops,\n 180:\t\t\t.mmc = \u0026dwmac_mmc_ops,\n 181:\t\t\t.est = \u0026dwmac510_est_ops,\n 182:\t\t\t.setup = dwmac4_setup,\n 183:\t\t\t.quirks = stmmac_dwmac4_quirks,\n 184:\t\t}, {\n 185:\t\t\t.core_type = DWMAC_CORE_GMAC4,\n 186:\t\t\t.min_id = DWMAC_CORE_4_00,\n 187:\t\t\t.regs = {\n 188:\t\t\t\t.ptp_off = PTP_GMAC4_OFFSET,\n 189:\t\t\t\t.mmc_off = MMC_GMAC4_OFFSET,\n 190:\t\t\t\t.est_off = EST_GMAC4_OFFSET,\n 191:\t\t\t\t.fpe_reg = \u0026dwmac5_fpe_reg,\n 192:\t\t\t},\n 193:\t\t\t.desc = \u0026dwmac4_desc_ops,\n 194:\t\t\t.dma = \u0026dwmac4_dma_ops,\n 195:\t\t\t.mac = \u0026dwmac410_ops,\n 196:\t\t\t.vlan = \u0026dwmac_vlan_ops,\n 197:\t\t\t.hwtimestamp = \u0026stmmac_ptp,\n 198:\t\t\t.ptp = \u0026stmmac_ptp_clock_ops,\n 199:\t\t\t.mode = \u0026dwmac4_ring_mode_ops,\n 200:\t\t\t.tc = \u0026dwmac510_tc_ops,\n 201:\t\t\t.mmc = \u0026dwmac_mmc_ops,\n 202:\t\t\t.est = \u0026dwmac510_est_ops,\n 203:\t\t\t.setup = dwmac4_setup,\n 204:\t\t\t.quirks = NULL,\n 205:\t\t}, {\n 206:\t\t\t.core_type = DWMAC_CORE_GMAC4,\n 207:\t\t\t.min_id = DWMAC_CORE_4_10,\n 208:\t\t\t.regs = {\n 209:\t\t\t\t.ptp_off = PTP_GMAC4_OFFSET,\n 210:\t\t\t\t.mmc_off = MMC_GMAC4_OFFSET,\n 211:\t\t\t\t.est_off = EST_GMAC4_OFFSET,\n 212:\t\t\t\t.fpe_reg = \u0026dwmac5_fpe_reg,\n 213:\t\t\t},\n 214:\t\t\t.desc = \u0026dwmac4_desc_ops,\n 215:\t\t\t.dma = \u0026dwmac410_dma_ops,\n 216:\t\t\t.mac = \u0026dwmac410_ops,\n 217:\t\t\t.vlan = \u0026dwmac_vlan_ops,\n 218:\t\t\t.hwtimestamp = \u0026stmmac_ptp,\n 219:\t\t\t.ptp = \u0026stmmac_ptp_clock_ops,\n 220:\t\t\t.mode = \u0026dwmac4_ring_mode_ops,\n 221:\t\t\t.tc = \u0026dwmac510_tc_ops,\n 222:\t\t\t.mmc = \u0026dwmac_mmc_ops,\n 223:\t\t\t.est = \u0026dwmac510_est_ops,\n 224:\t\t\t.setup = dwmac4_setup,\n 225:\t\t\t.quirks = NULL,\n 226:\t\t}, {\n 227:\t\t\t.core_type = DWMAC_CORE_GMAC4,\n"
} |
| 35/2 | 2026/08/08 15:29 | llm | patch-evaluator |
2mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 42698 output: 24 thoughts: 180 Thoughts: **Analyzing the DWMAC Core Initialization** Okay, let's break this down. If `min_id` is zero, that means we're going for the very first entry for a given `core_type`. Looking at `DWMAC_CORE_GMAC4`, the first entry points to `dwmac4_tc_ops`. Aha, the patch is modifying `dwmac4_tc_ops` and `dwmac510_tc_ops` by adding `.setup_ets = tc_setup_ets`. That's interesting; so even if the `version` is zero, `stmmac_hwif_init` should succeed because it will find that now-updated `dwmac4_tc_ops`, and the mac's `tc` will be correctly set. But wait, where is `plat->core_type` actually defined? I need to double-check where that comes from. Let's see... is it coming from `stmmac_pci_probe`? I need to verify how that core type is set. Okay, let's go back and check the values inside `stmmac_default_data` and also the values in `snps_gmac5_default_data` to ensure there are no surprises or assumptions I'm missing. |
| 36/2 | 2026/08/08 15:32 | tool | grepper |
0mArgs:{
"Expression": "snps_gmac5_default_data"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c=50=static const struct stmmac_pci_info stmmac_pci_info = {\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-53-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:54:static int snps_gmac5_default_data(struct pci_dev *pdev,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-55-\t\t\t\t struct plat_stmmacenet_data *plat)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c=102=static const struct stmmac_pci_info snps_gmac5_pci_info = {\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c:103:\t.setup = snps_gmac5_default_data,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_pci.c-104-};\n"
} |
| 37/2 | 2026/08/08 15:32 | llm | patch-evaluator |
2mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 43487 output: 49 thoughts: 16 Thoughts: Okay, here's my interpretation of that thought process, assuming I'm deeply familiar with relevant data science concepts and the file naming conventions within my field: **Initial Assessment: Navigating the Data Landscape** Alright, I see the instruction: "Let's read `snps_gmac5_default_data`." My immediate thought is, okay, *which* data are we about to delve into? The file name itself offers significant clues, triggering a cascade of mental associations. "snps" – that undoubtedly refers to Single Nucleotide Polymorphisms, probably genomic data. "gmac5" – Hmm, now that's interesting. Likely this hints at a specific genotyping platform, data processing pipeline, or perhaps a particular versioning schema linked to the data generation. The "default_data" suggests this is the standard or baseline dataset for this specific genetic study. I quickly begin evaluating: * **Data Type:** Is this raw genotype calls, processed allele frequencies, dosage data, or something else entirely? * **Format:** Is it in a standard format like VCF, PLINK, or something custom to this study? I'll probably need to consider the appropriate data reading and parsing libraries here, like `pysam` for VCF or `pandas` for potentially tab-delimited formats. * **Context:** What project or analysis is this related to? Are we running quality control, calculating genetic correlations, or building a predictive model? Knowing the ultimate objective dictates how I'll approach reading and interpreting the data. * **Size:** This may not be explicit, but I'm subconsciously estimating the file size based on my general knowledge of the dataset. Is it going to require careful memory management or parallel processing to avoid hitting bottlenecks? * **Expected Variables:** Based on the naming, I know I'm looking at genetic data. I'm now anticipating what variables are going to be in the file, like chromosome, position, reference allele, alternative allele, genotype data, and so on. My mind is already running through my toolkit – libraries for data loading, data wrangling, potentially even visualization – preparing to tackle the specifics once I begin reading the actual file. It is a rapid assessment, anticipating possible challenges and the potential insights that could be yielded. |
| 38/2 | 2026/08/08 15:34 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c",
"FirstLine": 54,
"LineCount": 50
}Results: {
"Contents": " 54:\tstatic int snps_gmac5_default_data(struct pci_dev *pdev,\n 55:\t\t\t\t\t struct plat_stmmacenet_data *plat)\n 56:\t{\n 57:\t\tint i;\n 58:\t\n 59:\t\tplat-\u003eclk_csr = STMMAC_CSR_250_300M;\n 60:\t\tplat-\u003ecore_type = DWMAC_CORE_GMAC4;\n 61:\t\tplat-\u003eforce_sf_dma_mode = true;\n 62:\t\tplat-\u003eflags |= STMMAC_FLAG_TSO_EN;\n 63:\t\tplat-\u003epmt = true;\n 64:\t\n 65:\t\t/* Set default number of RX and TX queues to use */\n 66:\t\tplat-\u003etx_queues_to_use = 4;\n 67:\t\tplat-\u003erx_queues_to_use = 4;\n 68:\t\n 69:\t\tplat-\u003etx_sched_algorithm = MTL_TX_ALGORITHM_WRR;\n 70:\t\tfor (i = 0; i \u003c plat-\u003etx_queues_to_use; i++) {\n 71:\t\t\tplat-\u003etx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB;\n 72:\t\t\tplat-\u003etx_queues_cfg[i].weight = 25;\n 73:\t\t\tif (i \u003e 0)\n 74:\t\t\t\tplat-\u003etx_queues_cfg[i].tbs_en = 1;\n 75:\t\t}\n 76:\t\n 77:\t\tplat-\u003erx_sched_algorithm = MTL_RX_ALGORITHM_SP;\n 78:\t\tfor (i = 0; i \u003c plat-\u003erx_queues_to_use; i++)\n 79:\t\t\tplat-\u003erx_queues_cfg[i].mode_to_use = MTL_QUEUE_DCB;\n 80:\t\n 81:\t\tplat-\u003ebus_id = 1;\n 82:\t\tplat-\u003ephy_interface = PHY_INTERFACE_MODE_GMII;\n 83:\t\n 84:\t\tplat-\u003edma_cfg-\u003epbl = 32;\n 85:\t\tplat-\u003edma_cfg-\u003epblx8 = true;\n 86:\t\n 87:\t\t/* Axi Configuration */\n 88:\t\tplat-\u003eaxi = devm_kzalloc(\u0026pdev-\u003edev, sizeof(*plat-\u003eaxi), GFP_KERNEL);\n 89:\t\tif (!plat-\u003eaxi)\n 90:\t\t\treturn -ENOMEM;\n 91:\t\n 92:\t\tplat-\u003eaxi-\u003eaxi_wr_osr_lmt = 31;\n 93:\t\tplat-\u003eaxi-\u003eaxi_rd_osr_lmt = 31;\n 94:\t\n 95:\t\tplat-\u003eaxi-\u003eaxi_fb = false;\n 96:\t\tplat-\u003eaxi-\u003eaxi_blen_regval = DMA_AXI_BLEN4 | DMA_AXI_BLEN8 |\n 97:\t\t\t\t\t DMA_AXI_BLEN16 | DMA_AXI_BLEN32;\n 98:\t\n 99:\t\treturn 0;\n 100:\t}\n 101:\t\n 102:\tstatic const struct stmmac_pci_info snps_gmac5_pci_info = {\n 103:\t\t.setup = snps_gmac5_default_data,\n"
} |
| 39/2 | 2026/08/08 15:34 | llm | patch-evaluator |
1mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 44903 output: 24 thoughts: 573 Thoughts: **Analyzing the STM32 Ethernet Driver Initialization** Okay, so I'm looking at this STM32 Ethernet driver initialization sequence. The code starts by setting `plat->core_type = DWMAC_CORE_GMAC4` and `plat->tx_queues_to_use = 4`. This means `stmmac_hwif_init` should succeed, and it will set the `mac->tc` pointer to either `&dwmac4_tc_ops` or `&dwmac510_tc_ops`, depending on the specific GMAC revision. My main concern right now is the call to `stmmac_hw_init` immediately after. It's initializing the hardware, and I want to make sure there are no obvious points of failure. The code calls `stmmac_hwif_init` again, which seems redundant but could potentially be needed. More importantly, it then calls `stmmac_get_hw_features`. If this function reads a zero value from the hardware, it returns 0. That's fine, the `priv->hw_cap_support` will simply be zero, and the driver prints a message, "No HW DMA feature register supported." This doesn't seem like a hard error, which is good. The probe function then continues with the crucial `stmmac_hw_init` call, followed by `stmmac_tc_init`, and finally, the registration of the network device with `register_netdev(ndev)`. This is the point where the driver becomes active. But before it gets to the point of registering, I have to ensure that we will not crash. Now I am going to check for other hardware accesses. I know there's a reset control assertion in `__stmmac_dvr_probe`, specifically: `reset_control_assert(priv->plat->stmmac_rst)`. In the PCI probe, `stmmac_rst` is likely `NULL`. But the code will skip this and proceed. So, in the overall sequence: we have `stmmac_hwif_init`, then `stmmac_get_hw_features`, `stmmac_hw_init`, and finally `stmmac_tc_init`, leading into `register_netdev`. I need to ensure there isn't some DMA engine initialization that hangs waiting for a hardware condition. I should be searching in `stmmac_dvr_probe` for an `stmmac_init_dma_engine` or some other function that might involve a loop or waiting. I will investigate this further to confirm this. |
| 40/2 | 2026/08/08 15:35 | tool | grepper |
0mArgs:{
"Expression": "stmmac_init_dma_engine"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/stmmac_main.c=3213=static int stmmac_prereset_configure(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3254-/**\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3255: * stmmac_init_dma_engine - DMA init.\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3256- * @priv: driver private structure\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3261- */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3262:static int stmmac_init_dma_engine(struct stmmac_priv *priv)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3263-{\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=3657=static int stmmac_hw_setup(struct net_device *dev)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3678-\t/* DMA initialization and SW reset */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3679:\tret = stmmac_init_dma_engine(priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3680-\tif (ret \u003c 0) {\n"
} |
| 41/2 | 2026/08/08 15:35 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 46510 output: 50 thoughts: 47 Thoughts: Okay, here's my interpretation of that thought process, as if I were thinking it myself, with a focus tailored for an expert audience: **Analyzing stmmac Driver Initialization** Right, so `stmmac_hw_setup` gets called during the interface bring-up, specifically from `stmmac_open`. I need to understand the sequencing here. My primary concern is the potential for bottlenecks or inefficiencies during this stage. I've seen issues in the past with DMA engine initialization routines taking too long or getting into unexpected loops, especially under certain hardware configurations or interrupt load. I want to check for potential looping behavior in `stmmac_init_dma_engine`. I need to ensure a quick and deterministic initialization that doesn't hold up the interface bring-up. The potential for the DMA engine initialization to loop is important for the performance of the driver. I need to review that code to make sure there are no obvious issues there. |
| 42/2 | 2026/08/08 15:36 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/stmmac_main.c",
"FirstLine": 3262,
"LineCount": 50
}Results: {
"Contents": "3262:\tstatic int stmmac_init_dma_engine(struct stmmac_priv *priv)\n3263:\t{\n3264:\t\tu8 rx_channels_count = priv-\u003eplat-\u003erx_queues_to_use;\n3265:\t\tu8 tx_channels_count = priv-\u003eplat-\u003etx_queues_to_use;\n3266:\t\tu8 dma_csr_ch = max(rx_channels_count, tx_channels_count);\n3267:\t\tstruct stmmac_rx_queue *rx_q;\n3268:\t\tstruct stmmac_tx_queue *tx_q;\n3269:\t\tint ret = 0;\n3270:\t\tu8 chan;\n3271:\t\n3272:\t\tret = stmmac_prereset_configure(priv);\n3273:\t\tif (ret)\n3274:\t\t\treturn ret;\n3275:\t\n3276:\t\tret = stmmac_reset(priv);\n3277:\t\tif (ret) {\n3278:\t\t\tnetdev_err(priv-\u003edev, \"Failed to reset the dma\\n\");\n3279:\t\t\treturn ret;\n3280:\t\t}\n3281:\t\n3282:\t\t/* DMA Configuration */\n3283:\t\tstmmac_dma_init(priv, priv-\u003eioaddr, priv-\u003eplat-\u003edma_cfg);\n3284:\t\n3285:\t\tif (priv-\u003eplat-\u003eaxi)\n3286:\t\t\tstmmac_axi(priv, priv-\u003eioaddr, priv-\u003eplat-\u003eaxi);\n3287:\t\n3288:\t\t/* DMA CSR Channel configuration */\n3289:\t\tfor (chan = 0; chan \u003c dma_csr_ch; chan++) {\n3290:\t\t\tstmmac_init_chan(priv, priv-\u003eioaddr, priv-\u003eplat-\u003edma_cfg, chan);\n3291:\t\t\tstmmac_disable_dma_irq(priv, priv-\u003eioaddr, chan, 1, 1);\n3292:\t\t}\n3293:\t\n3294:\t\t/* DMA RX Channel Configuration */\n3295:\t\tfor (chan = 0; chan \u003c rx_channels_count; chan++) {\n3296:\t\t\trx_q = \u0026priv-\u003edma_conf.rx_queue[chan];\n3297:\t\n3298:\t\t\tstmmac_init_rx_chan(priv, priv-\u003eioaddr, priv-\u003eplat-\u003edma_cfg,\n3299:\t\t\t\t\t rx_q-\u003edma_rx_phy, chan);\n3300:\t\n3301:\t\t\tstmmac_set_queue_rx_tail_ptr(priv, rx_q, chan,\n3302:\t\t\t\t\t\t rx_q-\u003ebuf_alloc_num);\n3303:\t\t}\n3304:\t\n3305:\t\t/* DMA TX Channel Configuration */\n3306:\t\tfor (chan = 0; chan \u003c tx_channels_count; chan++) {\n3307:\t\t\ttx_q = \u0026priv-\u003edma_conf.tx_queue[chan];\n3308:\t\n3309:\t\t\tstmmac_init_tx_chan(priv, priv-\u003eioaddr, priv-\u003eplat-\u003edma_cfg,\n3310:\t\t\t\t\t tx_q-\u003edma_tx_phy, chan);\n3311:\t\n"
} |
| 43/2 | 2026/08/08 15:36 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 47685 output: 19 thoughts: 21 Thoughts: Here's a summary of my thought process: **Diving into the `stmmac_reset` Function** Okay, so the program's calling `stmmac_reset`. I need to figure out what's going on within that function. My initial thought is to jump right in and examine the code. I'm going to carefully review the function's implementation, paying close attention to how it handles the hardware reset sequence, register configurations, and potential error conditions. I'll be looking for things like: how the PHY is reset, what registers are being manipulated, if there are any specific timing considerations, and whether any error handling is present. I'll need to understand the reset procedure fully to assess if this is where the current issue might be originating, or if this function is behaving as intended. The aim will be to verify it's operating correctly in the context of the larger driver. |
| 44/2 | 2026/08/08 15:36 | tool | grepper |
0mArgs:{
"Expression": "stmmac_reset"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/hwif.c=94=static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.c-99-\ndrivers/net/ethernet/stmicro/stmmac/hwif.c:100:int stmmac_reset(struct stmmac_priv *priv)\ndrivers/net/ethernet/stmicro/stmmac/hwif.c-101-{\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.h=696=extern const struct stmmac_tc_ops dwmac510_tc_ops;\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.h-700-\ndrivers/net/ethernet/stmicro/stmmac/hwif.h:701:int stmmac_reset(struct stmmac_priv *priv);\ndrivers/net/ethernet/stmicro/stmmac/hwif.h-702-int stmmac_hwif_init(struct stmmac_priv *priv);\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=152=static irqreturn_t stmmac_msi_intr_rx(int irq, void *data);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:153:static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:154:static void stmmac_reset_tx_queue(struct stmmac_priv *priv, u32 queue);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:155:static void stmmac_reset_queues_param(struct stmmac_priv *priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-156-static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue);\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=3006=static void stmmac_tx_err(struct stmmac_priv *priv, u32 chan)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3014-\tstmmac_clear_tx_descriptors(priv, \u0026priv-\u003edma_conf, chan);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3015:\tstmmac_reset_tx_queue(priv, chan);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3016-\tstmmac_init_tx_chan(priv, priv-\u003eioaddr, priv-\u003eplat-\u003edma_cfg,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=3262=static int stmmac_init_dma_engine(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3275-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3276:\tret = stmmac_reset(priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3277-\tif (ret) {\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=4152=static int __stmmac_open(struct net_device *dev,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-4172-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:4173:\tstmmac_reset_queues_param(priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-4174-\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7044=void stmmac_enable_rx_queue(struct stmmac_priv *priv, u32 queue)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7063-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7064:\tstmmac_reset_rx_queue(priv, queue);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7065-\tstmmac_clear_rx_descriptors(priv, \u0026priv-\u003edma_conf, queue);\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7094=void stmmac_enable_tx_queue(struct stmmac_priv *priv, u32 queue)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7113-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7114:\tstmmac_reset_tx_queue(priv, queue);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7115-\tstmmac_clear_tx_descriptors(priv, \u0026priv-\u003edma_conf, queue);\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7165=int stmmac_xdp_open(struct net_device *dev)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7190-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7191:\tstmmac_reset_queues_param(priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7192-\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7346=static const struct net_device_ops stmmac_netdev_ops = {\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7369-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7370:static void stmmac_reset_subtask(struct stmmac_priv *priv)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7371-{\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7392=static void stmmac_service_task(struct work_struct *work)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7396-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7397:\tstmmac_reset_subtask(priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7398-\tclear_bit(STMMAC_SERVICE_SCHED, \u0026priv-\u003estate);\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=8264=EXPORT_SYMBOL_GPL(stmmac_suspend);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8265-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8266:static void stmmac_reset_rx_queue(struct stmmac_priv *priv, u32 queue)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8267-{\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8273-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8274:static void stmmac_reset_tx_queue(struct stmmac_priv *priv, u32 queue)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8275-{\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8285-/**\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8286: * stmmac_reset_queues_param - reset queue parameters\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8287- * @priv: device pointer\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8288- */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8289:static void stmmac_reset_queues_param(struct stmmac_priv *priv)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8290-{\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8295-\tfor (queue = 0; queue \u003c rx_cnt; queue++)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8296:\t\tstmmac_reset_rx_queue(priv, queue);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8297-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8298-\tfor (queue = 0; queue \u003c tx_cnt; queue++)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8299:\t\tstmmac_reset_tx_queue(priv, queue);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8300-}\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=8308=int stmmac_resume(struct device *dev)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8355-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8356:\tstmmac_reset_queues_param(priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-8357-\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c=1316=static int tc_query_caps(struct stmmac_priv *priv,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1342-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:1343:static void stmmac_reset_tc_mqprio(struct net_device *ndev,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1344-\t\t\t\t struct netlink_ext_ack *extack)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c=1361=static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1371-\tif (!num_tc) {\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:1372:\t\tstmmac_reset_tc_mqprio(ndev, extack);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1373-\t\treturn 0;\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1443-err_reset_tc:\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:1444:\tstmmac_reset_tc_mqprio(ndev, extack);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1445-\n"
} |
| 45/2 | 2026/08/08 15:36 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 51114 output: 46 thoughts: 18 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Diving into the STMMAC Reset Mechanism** Alright, time to crack open `stmmac_reset` within `hwif.c`. I need to get a clear picture of how the STMMAC driver handles hardware resets. I'm assuming, given its location, this function is responsible for the low-level, register-level interactions required to bring the MAC back to a known good state after a reset event. I'll be looking specifically for things like: the reset sequence itself – are they using a dedicated reset register or a more indirect method? Are there any wait loops or timeout mechanisms involved, which could indicate the complexity of the hardware or a potential for issues? I'm also anticipating checking what registers are configured during and immediately after the reset. I want to see if they're zeroing out specific registers, restoring any critical configuration, or if there's any particular sequence. Understanding the register configuration will be crucial to understand the implications of a reset and how we can best recover from it. I'm especially keen to see how they handle different reset scenarios. Is it a full, cold reset, or a more targeted functional reset? Are there any distinctions made based on the type of reset (e.g., system reset versus a PHY reset)? I need to assess how robust this function is and whether it accounts for potential race conditions. Finally, I'll be keeping a mental note of any error handling or logging within the function, because that'll give me insight into how the driver deals with reset failures, and whether we have any instrumentation available in these critical paths. |
| 46/2 | 2026/08/08 15:36 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/hwif.c",
"FirstLine": 100,
"LineCount": 20
}Results: {
"Contents": " 100:\tint stmmac_reset(struct stmmac_priv *priv)\n 101:\t{\n 102:\t\tstruct plat_stmmacenet_data *plat = priv-\u003eplat;\n 103:\t\tvoid __iomem *ioaddr = priv-\u003eioaddr;\n 104:\t\n 105:\t\tif (plat \u0026\u0026 plat-\u003efix_soc_reset)\n 106:\t\t\treturn plat-\u003efix_soc_reset(priv);\n 107:\t\n 108:\t\treturn stmmac_do_callback(priv, dma, reset, ioaddr);\n 109:\t}\n 110:\t\n 111:\tstatic const struct stmmac_hwif_entry {\n 112:\t\tenum dwmac_core_type core_type;\n 113:\t\tu32 min_id;\n 114:\t\tu32 dev_id;\n 115:\t\tconst struct stmmac_regs_off regs;\n 116:\t\tconst void *desc;\n 117:\t\tconst void *dma;\n 118:\t\tconst void *mac;\n 119:\t\tconst void *hwtimestamp;\n"
} |
| 47/2 | 2026/08/08 15:36 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 51839 output: 22 thoughts: 56 Thoughts: Okay, here's my interpretation of this code snippet, expressed as if it's my own thought process: **Diving into the Driver's Reset Procedure** Right, so we're looking at a critical call here: `stmmac_do_callback(priv, dma, reset, ioaddr)`. This feels like the heart of some sort of reset or initialization sequence. Specifically, with the `dwmac4_dma_ops` structure in play, the `reset` function pointer is bound to `dwmac4_dma_reset`. Now, *that's* interesting. I need to be sure the `dwmac4_dma_reset` function isn't going to get stuck in some sort of infinite loop during its execution. Let me make sure I understand the control flow; I can't have this thing hanging my whole system. I'll need to double check any potential looping conditions. |
| 48/2 | 2026/08/08 15:36 | tool | grepper |
0mArgs:{
"Expression": "dwmac4_dma_reset"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c=569=const struct stmmac_dma_ops dwmac4_dma_ops = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c:570:\t.reset = dwmac4_dma_reset,\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c-571-\t.init = dwmac4_dma_init,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c=599=const struct stmmac_dma_ops dwmac410_dma_ops = {\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c:600:\t.reset = dwmac4_dma_reset,\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c-601-\t.init = dwmac4_dma_init,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h=54=static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h-175-\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h:176:int dwmac4_dma_reset(void __iomem *ioaddr);\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.h-177-void dwmac4_enable_dma_irq(struct stmmac_priv *priv, void __iomem *ioaddr,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c-15-\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c:16:int dwmac4_dma_reset(void __iomem *ioaddr)\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c-17-{\n"
} |
| 49/2 | 2026/08/08 15:36 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 52682 output: 48 thoughts: 14 Thoughts: Okay, let's dive into this `dwmac4_dma_reset` function. I need to understand this DMA reset procedure thoroughly. This likely involves some critical hardware manipulation, so I need to be precise. I'm going to start by going line by line and mentally mapping out each step, identifying the registers being accessed, the values being written, and, crucially, the intent behind each operation. My experience with other DMA controllers is going to be useful here, allowing me to draw parallels and anticipate potential issues. I'll pay close attention to any potential race conditions or timing dependencies that might be present. This is a common point for errors, so it deserves extra scrutiny. I also need to think about what the reset *doesn't* do – what state is preserved, and what needs to be re-initialized after this. Finally, I'll need to keep the overall architecture in mind; how does this DMA controller integrate with the rest of the system? Any interaction with other modules will be especially relevant. |
| 50/2 | 2026/08/08 15:36 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c",
"FirstLine": 16,
"LineCount": 20
}Results: {
"Contents": " 16:\tint dwmac4_dma_reset(void __iomem *ioaddr)\n 17:\t{\n 18:\t\tu32 value = readl(ioaddr + DMA_BUS_MODE);\n 19:\t\n 20:\t\t/* DMA SW reset */\n 21:\t\tvalue |= DMA_BUS_MODE_SFT_RESET;\n 22:\t\twritel(value, ioaddr + DMA_BUS_MODE);\n 23:\t\n 24:\t\treturn readl_poll_timeout(ioaddr + DMA_BUS_MODE, value,\n 25:\t\t\t\t\t !(value \u0026 DMA_BUS_MODE_SFT_RESET),\n 26:\t\t\t\t\t 10000, 1000000);\n 27:\t}\n 28:\t\n 29:\tvoid dwmac4_set_rx_tail_ptr(struct stmmac_priv *priv, void __iomem *ioaddr,\n 30:\t\t\t\t u32 tail_ptr, u32 chan)\n 31:\t{\n 32:\t\tconst struct dwmac4_addrs *dwmac4_addrs = priv-\u003eplat-\u003edwmac4_addrs;\n 33:\t\n 34:\t\twritel(tail_ptr, ioaddr + DMA_CHAN_RX_END_ADDR(dwmac4_addrs, chan));\n 35:\t}\n"
} |
| 51/2 | 2026/08/08 15:36 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 53308 output: 21 thoughts: 316 Thoughts: **Analyzing the Interface Initialization Path** Okay, so I'm tracing through this initialization sequence... If `readl_poll_timeout` fails after a second, meaning a bit isn't cleared as expected, that leads to an error return from `stmmac_reset`, which then bubbles up to an error from `stmmac_init_dma_engine`. Right, and `stmmac_init_dma_engine` is called from `stmmac_hw_setup`, which in turn is part of `stmmac_open`. So, if `stmmac_open` fails, the network interface can't be brought up, which makes sense. Now, a question is popping up: can `tc` commands even be applied to a down interface? I seem to recall that they can, specifically things like `tc qdisc add dev eth0 root ...` are valid even when the link is down. Interesting. Then I see that `stmmac_setup_tc` does a `pm_runtime_resume_and_get` call. If the device isn't opened, this call *might* just power it on. I need to be sure. But, if `stmmac_pci_probe` succeeds, the netdev gets registered. That's good. But here's a worry: can `stmmac_pci_probe` actually succeed even if the hardware is just... dummy? I need to look into that. Let me circle back. I know `stmmac_hw_init` doesn't have loops in it. What about `stmmac_tc_init`? Are there any potential infinite loops there? Gotta check that too. |
| 52/2 | 2026/08/08 15:37 | tool | grepper |
0mArgs:{
"Expression": "stmmac_tc_init"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/hwif.h=571=struct stmmac_tc_ops {\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.h-590-\ndrivers/net/ethernet/stmicro/stmmac/hwif.h:591:#define stmmac_tc_init(__priv, __args...) \\\ndrivers/net/ethernet/stmicro/stmmac/hwif.h-592-\tstmmac_do_callback(__priv, tc, init, __args)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7832=static int __stmmac_dvr_probe(struct device *device,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7956-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7957:\tret = stmmac_tc_init(priv, priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7958-\tif (!ret) {\n"
} |
| 53/2 | 2026/08/08 15:37 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 54319 output: 17 thoughts: 32 Thoughts: Okay, here's my interpretation of that thought process, from an expert's perspective: **Decoding the STMMAC Traffic Class Initialization** Alright, let's break this down. We're talking about the initialization routine for traffic classes within the STMMAC driver – specifically, how it's integrated. The crucial thing here is recognizing that `stmmac_tc_init` is acting as a callback. That's a key piece of information, signifying it's a function that gets invoked by some other part of the system at a specific time or in response to a particular event. Now, when we drill down and look at the specifics, and connect `dwmac4_tc_ops`, it's clear what's happening. `init` being mapped to `tc_init` in this context. It's a clean, efficient design, and I'd expect nothing less in a well-structured driver. They're probably using a table of function pointers or a similar mechanism, and `stmmac_tc_init` is registered to handle the initialization for the defined traffic classes. That `dwmac4_tc_ops` structure likely contains other function pointers for various TC operations, like configuration and packet classification. It's a standard pattern, and I see it all the time. |
| 54/2 | 2026/08/08 15:37 | tool | grepper |
0mArgs:{
"Expression": "tc_init"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 3017 lines.\nUse more precise expression if possible.\n\narch/alpha/kernel/rtc.c=203=static int __init\narch/alpha/kernel/rtc.c:204:alpha_rtc_init(void)\narch/alpha/kernel/rtc.c-205-{\n--\narch/alpha/kernel/rtc.c-225-}\narch/alpha/kernel/rtc.c:226:device_initcall(alpha_rtc_init);\n--\narch/arm/mach-dove/common.c=151=void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)\n--\narch/arm/mach-dove/common.c-160- ****************************************************************************/\narch/arm/mach-dove/common.c:161:static void __init dove_rtc_init(void)\narch/arm/mach-dove/common.c-162-{\narch/arm/mach-dove/common.c:163:\torion_rtc_init(DOVE_RTC_PHYS_BASE, IRQ_DOVE_RTC);\narch/arm/mach-dove/common.c-164-}\n--\narch/arm/mach-dove/common.c=415=void __init dove_init(void)\n--\narch/arm/mach-dove/common.c-429-\tdove_init_pmu_legacy(\u0026pmu_data);\narch/arm/mach-dove/common.c:430:\tdove_rtc_init();\narch/arm/mach-dove/common.c-431-\tdove_xor0_init();\n--\narch/arm/mach-footbridge/common.h=5=extern void isa_timer_init(void);\narch/arm/mach-footbridge/common.h-6-\narch/arm/mach-footbridge/common.h:7:extern void isa_rtc_init(void);\narch/arm/mach-footbridge/common.h-8-\n--\narch/arm/mach-footbridge/isa-rtc.c-26-\narch/arm/mach-footbridge/isa-rtc.c:27:void __init isa_rtc_init(void)\narch/arm/mach-footbridge/isa-rtc.c-28-{\n--\narch/arm/mach-footbridge/isa.c=78=static int __init footbridge_isa_init(void)\n--\narch/arm/mach-footbridge/isa.c-82-\t/* Personal server doesn't have RTC */\narch/arm/mach-footbridge/isa.c:83:\tisa_rtc_init();\narch/arm/mach-footbridge/isa.c-84-\terr = platform_device_register(\u0026rtc_device);\n--\narch/arm/plat-orion/common.c=221=static struct resource orion_rtc_resource[2];\narch/arm/plat-orion/common.c-222-\narch/arm/plat-orion/common.c:223:void __init orion_rtc_init(unsigned long mapbase,\narch/arm/plat-orion/common.c-224-\t\t\t unsigned long irq)\n--\narch/arm/plat-orion/include/plat/common.h=32=void __init orion_uart3_init(void __iomem *membase,\n--\narch/arm/plat-orion/include/plat/common.h-36-\narch/arm/plat-orion/include/plat/common.h:37:void __init orion_rtc_init(unsigned long mapbase,\narch/arm/plat-orion/include/plat/common.h-38-\t\t\t unsigned long irq);\n--\narch/arm64/kvm/arm.c=921=int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arm.c-997-\narch/arm64/kvm/arm.c:998:bool kvm_arch_intc_initialized(struct kvm *kvm)\narch/arm64/kvm/arm.c-999-{\n--\narch/loongarch/kvm/irqfd.c=70=int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,\n--\narch/loongarch/kvm/irqfd.c-86-\narch/loongarch/kvm/irqfd.c:87:bool kvm_arch_intc_initialized(struct kvm *kvm)\narch/loongarch/kvm/irqfd.c-88-{\n--\narch/m68k/kernel/time.c=131=static const struct rtc_class_ops generic_rtc_ops = {\n--\narch/m68k/kernel/time.c-136-\narch/m68k/kernel/time.c:137:static int __init rtc_init(void)\narch/m68k/kernel/time.c-138-{\n--\narch/m68k/kernel/time.c-149-\narch/m68k/kernel/time.c:150:module_init(rtc_init);\narch/m68k/kernel/time.c-151-#endif /* CONFIG_RTC_DRV_GENERIC */\n--\narch/mips/kernel/smp-mt.c=46=static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0,\n--\narch/mips/kernel/smp-mt.c-80-\narch/mips/kernel/smp-mt.c:81:static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0)\narch/mips/kernel/smp-mt.c-82-{\n--\narch/mips/kernel/smp-mt.c=184=static void __init vsmp_smp_setup(void)\n--\narch/mips/kernel/smp-mt.c-214-\narch/mips/kernel/smp-mt.c:215:\t\tsmvp_tc_init(tc, mvpconf0);\narch/mips/kernel/smp-mt.c-216-\t\tncpu = smvp_vpe_init(tc, mvpconf0, ncpu);\n--\narch/mips/sgi-ip27/ip27-common.h=9=extern void hub_rt_clock_event_init(void);\narch/mips/sgi-ip27/ip27-common.h:10:extern void hub_rtc_init(nasid_t nasid);\narch/mips/sgi-ip27/ip27-common.h-11-extern void install_cpu_nmi_handler(int slice);\n--\narch/mips/sgi-ip27/ip27-init.c=45=static void per_hub_init(nasid_t nasid)\n--\narch/mips/sgi-ip27/ip27-init.c-58-\narch/mips/sgi-ip27/ip27-init.c:59:\thub_rtc_init(nasid);\narch/mips/sgi-ip27/ip27-init.c-60-\n--\narch/mips/sgi-ip27/ip27-timer.c=130=void __init plat_time_init(void)\n--\narch/mips/sgi-ip27/ip27-timer.c-136-\narch/mips/sgi-ip27/ip27-timer.c:137:void hub_rtc_init(nasid_t nasid)\narch/mips/sgi-ip27/ip27-timer.c-138-{\n--\narch/mips/txx9/rbtx4927/setup.c=282=static void __init rbtx4927_time_init(void)\n--\narch/mips/txx9/rbtx4927/setup.c-286-\narch/mips/txx9/rbtx4927/setup.c:287:static void __init toshiba_rbtx4927_rtc_init(void)\narch/mips/txx9/rbtx4927/setup.c-288-{\n--\narch/mips/txx9/rbtx4927/setup.c=339=static void __init rbtx4927_device_init(void)\narch/mips/txx9/rbtx4927/setup.c-340-{\narch/mips/txx9/rbtx4927/setup.c:341:\ttoshiba_rbtx4927_rtc_init();\narch/mips/txx9/rbtx4927/setup.c-342-\trbtx4927_ne_init();\n--\narch/parisc/kernel/time.c=166=static const struct rtc_class_ops rtc_generic_ops = {\n--\narch/parisc/kernel/time.c-170-\narch/parisc/kernel/time.c:171:static int __init rtc_init(void)\narch/parisc/kernel/time.c-172-{\n--\narch/parisc/kernel/time.c-180-}\narch/parisc/kernel/time.c:181:device_initcall(rtc_init);\narch/parisc/kernel/time.c-182-#endif\n--\narch/powerpc/kernel/time.c=1087=static const struct rtc_class_ops rtc_generic_ops = {\n--\narch/powerpc/kernel/time.c-1091-\narch/powerpc/kernel/time.c:1092:static int __init rtc_init(void)\narch/powerpc/kernel/time.c-1093-{\n--\narch/powerpc/kernel/time.c-1105-\narch/powerpc/kernel/time.c:1106:device_initcall(rtc_init);\narch/powerpc/kernel/time.c-1107-#endif\n--\narch/powerpc/kvm/powerpc.c=1879=static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,\n--\narch/powerpc/kvm/powerpc.c-1999-\narch/powerpc/kvm/powerpc.c:2000:bool kvm_arch_intc_initialized(struct kvm *kvm)\narch/powerpc/kvm/powerpc.c-2001-{\n--\narch/powerpc/platforms/ps3/time.c=43=time64_t __init ps3_get_boot_time(void)\n--\narch/powerpc/platforms/ps3/time.c-47-\narch/powerpc/platforms/ps3/time.c:48:static int __init ps3_rtc_init(void)\narch/powerpc/platforms/ps3/time.c-49-{\n--\narch/powerpc/platforms/ps3/time.c-58-}\narch/powerpc/platforms/ps3/time.c:59:device_initcall(ps3_rtc_init);\n--\narch/um/drivers/rtc_kern.c=180=static struct platform_driver uml_rtc_driver = {\n--\narch/um/drivers/rtc_kern.c-187-\narch/um/drivers/rtc_kern.c:188:static int __init uml_rtc_init(void)\narch/um/drivers/rtc_kern.c-189-{\n--\narch/um/drivers/rtc_kern.c-212-}\narch/um/drivers/rtc_kern.c:213:device_initcall(uml_rtc_init);\n--\narch/x86/kernel/apic/x2apic_uv_x.c=1102=static __init void map_low_mmrs(void)\n--\narch/x86/kernel/apic/x2apic_uv_x.c-1110-\narch/x86/kernel/apic/x2apic_uv_x.c:1111:static __init void uv_rtc_init(void)\narch/x86/kernel/apic/x2apic_uv_x.c-1112-{\n--\narch/x86/kernel/apic/x2apic_uv_x.c=1647=static void __init uv_system_init_hub(void)\n--\narch/x86/kernel/apic/x2apic_uv_x.c-1690-\thub_info.coherency_domain_number = sn_coherency_id;\narch/x86/kernel/apic/x2apic_uv_x.c:1691:\tuv_rtc_init();\narch/x86/kernel/apic/x2apic_uv_x.c-1692-\n--\narch/x86/platform/olpc/olpc-xo1-rtc.c=48=static struct platform_device xo1_rtc_device = {\n--\narch/x86/platform/olpc/olpc-xo1-rtc.c-55-\narch/x86/platform/olpc/olpc-xo1-rtc.c:56:static int __init xo1_rtc_init(void)\narch/x86/platform/olpc/olpc-xo1-rtc.c-57-{\n--\narch/x86/platform/olpc/olpc-xo1-rtc.c-79-}\narch/x86/platform/olpc/olpc-xo1-rtc.c:80:arch_initcall(xo1_rtc_init);\n--\ndrivers/acpi/internal.h=50=static inline void acpi_dock_add(struct acpi_device *adev) {}\n--\ndrivers/acpi/internal.h-52-#ifdef CONFIG_X86\ndrivers/acpi/internal.h:53:void acpi_cmos_rtc_init(void);\ndrivers/acpi/internal.h-54-#else\ndrivers/acpi/internal.h:55:static inline void acpi_cmos_rtc_init(void) {}\ndrivers/acpi/internal.h-56-#endif\n--\ndrivers/acpi/scan.c=2821=void __init acpi_scan_init(void)\n--\ndrivers/acpi/scan.c-2831-\tacpi_apd_init();\ndrivers/acpi/scan.c:2832:\tacpi_cmos_rtc_init();\ndrivers/acpi/scan.c-2833-\tacpi_container_init();\n--\ndrivers/acpi/x86/cmos_rtc.c=98=static struct acpi_scan_handler cmos_rtc_handler = {\n--\ndrivers/acpi/x86/cmos_rtc.c-102-\ndrivers/acpi/x86/cmos_rtc.c:103:void __init acpi_cmos_rtc_init(void)\ndrivers/acpi/x86/cmos_rtc.c-104-{\n--\ndrivers/gpu/drm/adp/adp_drv.c=368=static int adp_setup_crtc(struct adp_drv_private *adp)\n--\ndrivers/gpu/drm/adp/adp_drv.c-377-\ndrivers/gpu/drm/adp/adp_drv.c:378:\tret = drm_crtc_init_with_planes(drm, \u0026adp-\u003ecrtc, primary,\ndrivers/gpu/drm/adp/adp_drv.c-379-\t\t\t\t\tNULL, \u0026adp_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c=56=static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = {\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c-59-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:60:static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c-61-\t\t\t struct drm_plane *primary, struct drm_plane *cursor)\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c-66-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:67:\tret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c-68-\t\t\t\t\t\u0026amdgpu_vkms_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c=319=static int amdgpu_vkms_output_init(struct drm_device *dev, struct\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c-331-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:332:\tret = amdgpu_vkms_crtc_init(dev, crtc, primary, cursor);\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c-333-\tif (ret)\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c=2692=static const struct drm_plane_helper_funcs dce_v10_0_drm_primary_plane_helper_funcs = {\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c-2696-\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c:2697:static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c-2698-{\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c-2705-\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c:2706:\tdrm_crtc_init(adev_to_drm(adev), \u0026amdgpu_crtc-\u003ebase, \u0026dce_v10_0_crtc_funcs);\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c-2707-\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c=2776=static int dce_v10_0_sw_init(struct amdgpu_ip_block *ip_block)\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c-2818-\tfor (i = 0; i \u003c adev-\u003emode_info.num_crtc; i++) {\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c:2819:\t\tr = dce_v10_0_crtc_init(adev, i);\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c-2820-\t\tif (r)\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c=2659=static const struct drm_plane_helper_funcs dce_v6_0_drm_primary_plane_helper_funcs = {\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c-2663-\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c:2664:static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c-2665-{\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c-2672-\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c:2673:\tdrm_crtc_init(adev_to_drm(adev), \u0026amdgpu_crtc-\u003ebase, \u0026dce_v6_0_crtc_funcs);\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c-2674-\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c=2727=static int dce_v6_0_sw_init(struct amdgpu_ip_block *ip_block)\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c-2767-\tfor (i = 0; i \u003c adev-\u003emode_info.num_crtc; i++) {\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c:2768:\t\tr = dce_v6_0_crtc_init(adev, i);\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c-2769-\t\tif (r)\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c=2617=static const struct drm_plane_helper_funcs dce_v8_0_drm_primary_plane_helper_funcs = {\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c-2621-\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c:2622:static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c-2623-{\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c-2630-\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c:2631:\tdrm_crtc_init(adev_to_drm(adev), \u0026amdgpu_crtc-\u003ebase, \u0026dce_v8_0_crtc_funcs);\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c-2632-\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c=2690=static int dce_v8_0_sw_init(struct amdgpu_ip_block *ip_block)\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c-2736-\tfor (i = 0; i \u003c adev-\u003emode_info.num_crtc; i++) {\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c:2737:\t\tr = dce_v8_0_crtc_init(adev, i);\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c-2738-\t\tif (r)\n--\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c=5699=static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)\n--\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c-5779-\tfor (i = 0; i \u003c dm-\u003edc-\u003ecaps.max_streams; i++)\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:5780:\t\tif (amdgpu_dm_crtc_init(dm, mode_info-\u003eplanes[i], i)) {\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c-5781-\t\t\tdrm_err(adev_to_drm(adev), \"KMS: Failed to initialize crtc\\n\");\n--\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c=718=static struct amdgpu_dm_ism_config default_ism_config = {\n--\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c-726-\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c:727:int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c-728-\t\t\t struct drm_plane *plane,\n--\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c-746-\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c:747:\tres = drm_crtc_init_with_planes(\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c-748-\t\t\tdm-\u003eddev,\n--\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h=49=void amdgpu_dm_crtc_disable_vblank(struct drm_crtc *crtc);\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h-50-\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h:51:int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h-52-\t\t\tstruct drm_plane *plane,\n--\ndrivers/gpu/drm/arm/display/komeda/komeda_crtc.c=638=static int komeda_crtc_add(struct komeda_kms_dev *kms,\n--\ndrivers/gpu/drm/arm/display/komeda/komeda_crtc.c-646-\ndrivers/gpu/drm/arm/display/komeda/komeda_crtc.c:647:\terr = drm_crtc_init_with_planes(base, crtc,\ndrivers/gpu/drm/arm/display/komeda/komeda_crtc.c-648-\t\t\t\t\tget_crtc_primary(kms, kcrtc), NULL,\n--\ndrivers/gpu/drm/arm/hdlcd_crtc.c=327=int hdlcd_setup_crtc(struct drm_device *drm)\n--\ndrivers/gpu/drm/arm/hdlcd_crtc.c-336-\ndrivers/gpu/drm/arm/hdlcd_crtc.c:337:\tret = drm_crtc_init_with_planes(drm, \u0026hdlcd-\u003ecrtc, primary, NULL,\ndrivers/gpu/drm/arm/hdlcd_crtc.c-338-\t\t\t\t\t\u0026hdlcd_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/arm/malidp_crtc.c=511=static const struct drm_crtc_funcs malidp_crtc_funcs = {\n--\ndrivers/gpu/drm/arm/malidp_crtc.c-520-\ndrivers/gpu/drm/arm/malidp_crtc.c:521:int malidp_crtc_init(struct drm_device *drm)\ndrivers/gpu/drm/arm/malidp_crtc.c-522-{\n--\ndrivers/gpu/drm/arm/malidp_crtc.c-544-\ndrivers/gpu/drm/arm/malidp_crtc.c:545:\tret = drmm_crtc_init_with_planes(drm, \u0026malidp-\u003ecrtc, primary, NULL,\ndrivers/gpu/drm/arm/malidp_crtc.c-546-\t\t\t\t\t \u0026malidp_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/arm/malidp_drv.c=396=static int malidp_init(struct drm_device *drm)\n--\ndrivers/gpu/drm/arm/malidp_drv.c-412-\ndrivers/gpu/drm/arm/malidp_drv.c:413:\tret = malidp_crtc_init(drm);\ndrivers/gpu/drm/arm/malidp_drv.c-414-\tif (ret)\n--\ndrivers/gpu/drm/arm/malidp_drv.h=89=int malidp_de_planes_init(struct drm_device *drm);\ndrivers/gpu/drm/arm/malidp_drv.h:90:int malidp_crtc_init(struct drm_device *drm);\ndrivers/gpu/drm/arm/malidp_drv.h-91-\n--\ndrivers/gpu/drm/armada/armada_510.c=15=struct armada510_variant_data {\n--\ndrivers/gpu/drm/armada/armada_510.c-19-\ndrivers/gpu/drm/armada/armada_510.c:20:static int armada510_crtc_init(struct armada_crtc *dcrtc, struct device *dev)\ndrivers/gpu/drm/armada/armada_510.c-21-{\n--\ndrivers/gpu/drm/armada/armada_510.c=153=const struct armada_variant armada510_ops = {\ndrivers/gpu/drm/armada/armada_510.c-154-\t.has_spu_adv_reg = true,\ndrivers/gpu/drm/armada/armada_510.c:155:\t.init = armada510_crtc_init,\ndrivers/gpu/drm/armada/armada_510.c-156-\t.compute_clock = armada510_crtc_compute_clock,\n--\ndrivers/gpu/drm/armada/armada_crtc.c=910=static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,\n--\ndrivers/gpu/drm/armada/armada_crtc.c-984-\ndrivers/gpu/drm/armada/armada_crtc.c:985:\tret = drm_crtc_init_with_planes(drm, \u0026dcrtc-\u003ecrtc, primary, NULL,\ndrivers/gpu/drm/armada/armada_crtc.c-986-\t\t\t\t\t\u0026armada_crtc_funcs, NULL);\ndrivers/gpu/drm/armada/armada_crtc.c-987-\tif (ret)\ndrivers/gpu/drm/armada/armada_crtc.c:988:\t\tgoto err_crtc_init;\ndrivers/gpu/drm/armada/armada_crtc.c-989-\n--\ndrivers/gpu/drm/armada/armada_crtc.c-999-\ndrivers/gpu/drm/armada/armada_crtc.c:1000:err_crtc_init:\ndrivers/gpu/drm/armada/armada_crtc.c-1001-\tprimary-\u003efuncs-\u003edestroy(primary);\n--\ndrivers/gpu/drm/ast/ast_mode.c=936=static const struct drm_crtc_funcs ast_crtc_funcs = {\n--\ndrivers/gpu/drm/ast/ast_mode.c-944-\ndrivers/gpu/drm/ast/ast_mode.c:945:static int ast_crtc_init(struct ast_device *ast)\ndrivers/gpu/drm/ast/ast_mode.c-946-{\n--\ndrivers/gpu/drm/ast/ast_mode.c-950-\ndrivers/gpu/drm/ast/ast_mode.c:951:\tret = drm_crtc_init_with_planes(dev, crtc, \u0026ast-\u003eprimary_plane.base,\ndrivers/gpu/drm/ast/ast_mode.c-952-\t\t\t\t\t\u0026ast-\u003ecursor_plane.base.base, \u0026ast_crtc_funcs,\n--\ndrivers/gpu/drm/ast/ast_mode.c=1017=int ast_mode_config_init(struct ast_device *ast)\n--\ndrivers/gpu/drm/ast/ast_mode.c-1052-\ndrivers/gpu/drm/ast/ast_mode.c:1053:\tret = ast_crtc_init(ast);\ndrivers/gpu/drm/ast/ast_mode.c-1054-\tif (ret)\n--\ndrivers/gpu/drm/drm_crtc.c-65- * \u0026struct drm_crtc (possibly as part of a larger structure) and registers it\ndrivers/gpu/drm/drm_crtc.c:66: * with a call to drm_crtc_init_with_planes().\ndrivers/gpu/drm/drm_crtc.c-67- *\n--\ndrivers/gpu/drm/drm_crtc.c=253=__printf(6, 0)\ndrivers/gpu/drm/drm_crtc.c:254:static int __drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,\ndrivers/gpu/drm/drm_crtc.c-255-\t\t\t\t struct drm_plane *primary,\n--\ndrivers/gpu/drm/drm_crtc.c-330-/**\ndrivers/gpu/drm/drm_crtc.c:331: * drm_crtc_init_with_planes - Initialise a new CRTC object with\ndrivers/gpu/drm/drm_crtc.c-332- * specified primary and cursor planes.\n--\ndrivers/gpu/drm/drm_crtc.c-340- * Inits a new object created as base part of a driver crtc object. Drivers\ndrivers/gpu/drm/drm_crtc.c:341: * should use this function instead of drm_crtc_init(), which is only provided\ndrivers/gpu/drm/drm_crtc.c-342- * for backwards compatibility with drivers which do not yet support universal\n--\ndrivers/gpu/drm/drm_crtc.c-351- * Note: consider using drmm_crtc_alloc_with_planes() or\ndrivers/gpu/drm/drm_crtc.c:352: * drmm_crtc_init_with_planes() instead of drm_crtc_init_with_planes()\ndrivers/gpu/drm/drm_crtc.c-353- * to let the DRM managed resource infrastructure take care of cleanup\n--\ndrivers/gpu/drm/drm_crtc.c-358- */\ndrivers/gpu/drm/drm_crtc.c:359:int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,\ndrivers/gpu/drm/drm_crtc.c-360-\t\t\t struct drm_plane *primary,\n--\ndrivers/gpu/drm/drm_crtc.c-370-\tva_start(ap, name);\ndrivers/gpu/drm/drm_crtc.c:371:\tret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,\ndrivers/gpu/drm/drm_crtc.c-372-\t\t\t\t\t name, ap);\n--\ndrivers/gpu/drm/drm_crtc.c-376-}\ndrivers/gpu/drm/drm_crtc.c:377:EXPORT_SYMBOL(drm_crtc_init_with_planes);\ndrivers/gpu/drm/drm_crtc.c-378-\ndrivers/gpu/drm/drm_crtc.c:379:static void drmm_crtc_init_with_planes_cleanup(struct drm_device *dev,\ndrivers/gpu/drm/drm_crtc.c-380-\t\t\t\t\t void *ptr)\n--\ndrivers/gpu/drm/drm_crtc.c=387=__printf(6, 0)\ndrivers/gpu/drm/drm_crtc.c:388:static int __drmm_crtc_init_with_planes(struct drm_device *dev,\ndrivers/gpu/drm/drm_crtc.c-389-\t\t\t\t\tstruct drm_crtc *crtc,\n--\ndrivers/gpu/drm/drm_crtc.c-399-\ndrivers/gpu/drm/drm_crtc.c:400:\tret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,\ndrivers/gpu/drm/drm_crtc.c-401-\t\t\t\t\t name, args);\n--\ndrivers/gpu/drm/drm_crtc.c-404-\ndrivers/gpu/drm/drm_crtc.c:405:\tret = drmm_add_action_or_reset(dev, drmm_crtc_init_with_planes_cleanup,\ndrivers/gpu/drm/drm_crtc.c-406-\t\t\t\t crtc);\n--\ndrivers/gpu/drm/drm_crtc.c-413-/**\ndrivers/gpu/drm/drm_crtc.c:414: * drmm_crtc_init_with_planes - Initialise a new CRTC object with\ndrivers/gpu/drm/drm_crtc.c-415- * specified primary and cursor planes.\n--\ndrivers/gpu/drm/drm_crtc.c-423- * Inits a new object created as base part of a driver crtc object. Drivers\ndrivers/gpu/drm/drm_crtc.c:424: * should use this function instead of drm_crtc_init(), which is only provided\ndrivers/gpu/drm/drm_crtc.c-425- * for backwards compatibility with drivers which do not yet support universal\n--\ndrivers/gpu/drm/drm_crtc.c-439- */\ndrivers/gpu/drm/drm_crtc.c:440:int drmm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,\ndrivers/gpu/drm/drm_crtc.c-441-\t\t\t struct drm_plane *primary,\n--\ndrivers/gpu/drm/drm_crtc.c-449-\tva_start(ap, name);\ndrivers/gpu/drm/drm_crtc.c:450:\tret = __drmm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,\ndrivers/gpu/drm/drm_crtc.c-451-\t\t\t\t\t name, ap);\n--\ndrivers/gpu/drm/drm_crtc.c-457-}\ndrivers/gpu/drm/drm_crtc.c:458:EXPORT_SYMBOL(drmm_crtc_init_with_planes);\ndrivers/gpu/drm/drm_crtc.c-459-\ndrivers/gpu/drm/drm_crtc.c=460=void *__drmm_crtc_alloc_with_planes(struct drm_device *dev,\n--\ndrivers/gpu/drm/drm_crtc.c-481-\tva_start(ap, name);\ndrivers/gpu/drm/drm_crtc.c:482:\tret = __drmm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,\ndrivers/gpu/drm/drm_crtc.c-483-\t\t\t\t\t name, ap);\n--\ndrivers/gpu/drm/drm_modeset_helper.c=114=static const struct drm_plane_funcs primary_plane_funcs = {\n--\ndrivers/gpu/drm/drm_modeset_helper.c-118-/**\ndrivers/gpu/drm/drm_modeset_helper.c:119: * drm_crtc_init - Legacy CRTC initialization function\ndrivers/gpu/drm/drm_modeset_helper.c-120- * @dev: DRM device\n--\ndrivers/gpu/drm/drm_modeset_helper.c-141- */\ndrivers/gpu/drm/drm_modeset_helper.c:142:int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,\ndrivers/gpu/drm/drm_modeset_helper.c-143-\t\t const struct drm_crtc_funcs *funcs)\n--\ndrivers/gpu/drm/drm_modeset_helper.c-147-\ndrivers/gpu/drm/drm_modeset_helper.c:148:\t/* possible_crtc's will be filled in later by crtc_init */\ndrivers/gpu/drm/drm_modeset_helper.c-149-\tprimary = __drm_universal_plane_alloc(dev, sizeof(*primary), 0, 0,\n--\ndrivers/gpu/drm/drm_modeset_helper.c-162-\ndrivers/gpu/drm/drm_modeset_helper.c:163:\tret = drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs, NULL);\ndrivers/gpu/drm/drm_modeset_helper.c-164-\tif (ret)\n--\ndrivers/gpu/drm/drm_modeset_helper.c-173-}\ndrivers/gpu/drm/drm_modeset_helper.c:174:EXPORT_SYMBOL(drm_crtc_init);\ndrivers/gpu/drm/drm_modeset_helper.c-175-\n--\ndrivers/gpu/drm/drm_plane.c-69- * relies on the driver to set the primary and optionally the cursor plane used\ndrivers/gpu/drm/drm_plane.c:70: * for legacy IOCTLs. This is done by calling drm_crtc_init_with_planes(). All\ndrivers/gpu/drm/drm_plane.c-71- * drivers must provide one primary plane per CRTC to avoid surprising legacy\n--\ndrivers/gpu/drm/drm_simple_kms_helper.c=335=int drm_simple_display_pipe_init(struct drm_device *dev,\n--\ndrivers/gpu/drm/drm_simple_kms_helper.c-359-\tdrm_crtc_helper_add(crtc, \u0026drm_simple_kms_crtc_helper_funcs);\ndrivers/gpu/drm/drm_simple_kms_helper.c:360:\tret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,\ndrivers/gpu/drm/drm_simple_kms_helper.c-361-\t\t\t\t\t\u0026drm_simple_kms_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/exynos/exynos_drm_crtc.c=173=struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,\n--\ndrivers/gpu/drm/exynos/exynos_drm_crtc.c-192-\ndrivers/gpu/drm/exynos/exynos_drm_crtc.c:193:\tret = drm_crtc_init_with_planes(drm_dev, crtc, plane, NULL,\ndrivers/gpu/drm/exynos/exynos_drm_crtc.c-194-\t\t\t\t\t\u0026exynos_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c=170=int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev)\n--\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c-181-\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c:182:\tret = drm_crtc_init_with_planes(fsl_dev-\u003edrm, crtc, primary, NULL,\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c-183-\t\t\t\t\t\u0026fsl_dcu_drm_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c=207=struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)\n--\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c-217-\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c:218:\t/* possible_crtc's will be filled in later by crtc_init */\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c-219-\tret = drm_universal_plane_init(dev, primary, 0,\n--\ndrivers/gpu/drm/gma500/framebuffer.c=101=void psb_modeset_init(struct drm_device *dev)\n--\ndrivers/gpu/drm/gma500/framebuffer.c-116-\tfor (i = 0; i \u003c dev_priv-\u003enum_pipe; i++)\ndrivers/gpu/drm/gma500/framebuffer.c:117:\t\tpsb_intel_crtc_init(dev, i, mode_dev);\ndrivers/gpu/drm/gma500/framebuffer.c-118-\n--\ndrivers/gpu/drm/gma500/psb_intel_display.c=446=static void psb_intel_cursor_init(struct drm_device *dev,\n--\ndrivers/gpu/drm/gma500/psb_intel_display.c-473-\ndrivers/gpu/drm/gma500/psb_intel_display.c:474:void psb_intel_crtc_init(struct drm_device *dev, int pipe,\ndrivers/gpu/drm/gma500/psb_intel_display.c-475-\t\t struct psb_intel_mode_device *mode_dev)\n--\ndrivers/gpu/drm/gma500/psb_intel_display.c-496-\ndrivers/gpu/drm/gma500/psb_intel_display.c:497:\tdrm_crtc_init(dev, \u0026gma_crtc-\u003ebase, \u0026gma_crtc_funcs);\ndrivers/gpu/drm/gma500/psb_intel_display.c-498-\n--\ndrivers/gpu/drm/gma500/psb_intel_drv.h=183=int psb_intel_ddc_get_modes(struct drm_connector *connector,\n--\ndrivers/gpu/drm/gma500/psb_intel_drv.h-185-\ndrivers/gpu/drm/gma500/psb_intel_drv.h:186:extern void psb_intel_crtc_init(struct drm_device *dev, int pipe,\ndrivers/gpu/drm/gma500/psb_intel_drv.h-187-\t\t\t struct psb_intel_mode_device *mode_dev);\n--\ndrivers/gpu/drm/gud/gud_drv.c=436=static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id)\n\n"
} |
| 55/2 | 2026/08/08 15:37 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 66636 output: 21 thoughts: 22 Thoughts: Okay, here's my attempt at summarizing that thought process, keeping in mind I'm speaking to a fellow expert: **Navigating the STMMAC Traffic Class Initialization** Right, so I'm digging into the STMMAC driver again, specifically around traffic classes. And, as I suspected, the `stmmac_tc_init` function... *aha!* ... yep, just confirmed it's right where it should be: nestled comfortably in `stmmac_tc.c`. That's where all the traffic class initialization logic resides, I presume. Good, that narrows down my search considerably. Time to dive into the code. |
| 56/2 | 2026/08/08 15:37 | tool | grepper |
0mArgs:{
"Expression": "stmmac_tc_init"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/hwif.h=571=struct stmmac_tc_ops {\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.h-590-\ndrivers/net/ethernet/stmicro/stmmac/hwif.h:591:#define stmmac_tc_init(__priv, __args...) \\\ndrivers/net/ethernet/stmicro/stmmac/hwif.h-592-\tstmmac_do_callback(__priv, tc, init, __args)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7832=static int __stmmac_dvr_probe(struct device *device,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7956-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7957:\tret = stmmac_tc_init(priv, priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7958-\tif (!ret) {\n"
} |
| 57/2 | 2026/08/08 15:37 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 67123 output: 17 thoughts: 19 Thoughts: Okay, let's dive into this. Here's my take on those thoughts, as if they're my own: **Analyzing the STMMAC Traffic Class Initialization** Alright, I'm thinking I need to understand how the traffic class setup works within the STMMAC driver. Specifically, my focus is on the `tc_init` function located in `stmmac_tc.c`. I'm going to carefully dissect what this function does, step-by-step, to see how the traffic class configurations are initially established for the MAC. I'm especially interested in how it interacts with the hardware, the registers being touched, the data structures it populates, and any assumptions it makes about the underlying hardware's capabilities. I'm anticipating that this is where the core of the traffic management logic begins, the foundation for shaping and scheduling. Understanding the initialization is key. |
| 58/2 | 2026/08/08 15:37 | tool | grepper |
0mArgs:{
"Expression": "tc_init"
}Results: {
"Output": "\nFull output is too long, showing 500 out of 3017 lines.\nUse more precise expression if possible.\n\narch/alpha/kernel/rtc.c=203=static int __init\narch/alpha/kernel/rtc.c:204:alpha_rtc_init(void)\narch/alpha/kernel/rtc.c-205-{\n--\narch/alpha/kernel/rtc.c-225-}\narch/alpha/kernel/rtc.c:226:device_initcall(alpha_rtc_init);\n--\narch/arm/mach-dove/common.c=151=void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)\n--\narch/arm/mach-dove/common.c-160- ****************************************************************************/\narch/arm/mach-dove/common.c:161:static void __init dove_rtc_init(void)\narch/arm/mach-dove/common.c-162-{\narch/arm/mach-dove/common.c:163:\torion_rtc_init(DOVE_RTC_PHYS_BASE, IRQ_DOVE_RTC);\narch/arm/mach-dove/common.c-164-}\n--\narch/arm/mach-dove/common.c=415=void __init dove_init(void)\n--\narch/arm/mach-dove/common.c-429-\tdove_init_pmu_legacy(\u0026pmu_data);\narch/arm/mach-dove/common.c:430:\tdove_rtc_init();\narch/arm/mach-dove/common.c-431-\tdove_xor0_init();\n--\narch/arm/mach-footbridge/common.h=5=extern void isa_timer_init(void);\narch/arm/mach-footbridge/common.h-6-\narch/arm/mach-footbridge/common.h:7:extern void isa_rtc_init(void);\narch/arm/mach-footbridge/common.h-8-\n--\narch/arm/mach-footbridge/isa-rtc.c-26-\narch/arm/mach-footbridge/isa-rtc.c:27:void __init isa_rtc_init(void)\narch/arm/mach-footbridge/isa-rtc.c-28-{\n--\narch/arm/mach-footbridge/isa.c=78=static int __init footbridge_isa_init(void)\n--\narch/arm/mach-footbridge/isa.c-82-\t/* Personal server doesn't have RTC */\narch/arm/mach-footbridge/isa.c:83:\tisa_rtc_init();\narch/arm/mach-footbridge/isa.c-84-\terr = platform_device_register(\u0026rtc_device);\n--\narch/arm/plat-orion/common.c=221=static struct resource orion_rtc_resource[2];\narch/arm/plat-orion/common.c-222-\narch/arm/plat-orion/common.c:223:void __init orion_rtc_init(unsigned long mapbase,\narch/arm/plat-orion/common.c-224-\t\t\t unsigned long irq)\n--\narch/arm/plat-orion/include/plat/common.h=32=void __init orion_uart3_init(void __iomem *membase,\n--\narch/arm/plat-orion/include/plat/common.h-36-\narch/arm/plat-orion/include/plat/common.h:37:void __init orion_rtc_init(unsigned long mapbase,\narch/arm/plat-orion/include/plat/common.h-38-\t\t\t unsigned long irq);\n--\narch/arm64/kvm/arm.c=921=int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu)\n--\narch/arm64/kvm/arm.c-997-\narch/arm64/kvm/arm.c:998:bool kvm_arch_intc_initialized(struct kvm *kvm)\narch/arm64/kvm/arm.c-999-{\n--\narch/loongarch/kvm/irqfd.c=70=int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,\n--\narch/loongarch/kvm/irqfd.c-86-\narch/loongarch/kvm/irqfd.c:87:bool kvm_arch_intc_initialized(struct kvm *kvm)\narch/loongarch/kvm/irqfd.c-88-{\n--\narch/m68k/kernel/time.c=131=static const struct rtc_class_ops generic_rtc_ops = {\n--\narch/m68k/kernel/time.c-136-\narch/m68k/kernel/time.c:137:static int __init rtc_init(void)\narch/m68k/kernel/time.c-138-{\n--\narch/m68k/kernel/time.c-149-\narch/m68k/kernel/time.c:150:module_init(rtc_init);\narch/m68k/kernel/time.c-151-#endif /* CONFIG_RTC_DRV_GENERIC */\n--\narch/mips/kernel/smp-mt.c=46=static unsigned int __init smvp_vpe_init(unsigned int tc, unsigned int mvpconf0,\n--\narch/mips/kernel/smp-mt.c-80-\narch/mips/kernel/smp-mt.c:81:static void __init smvp_tc_init(unsigned int tc, unsigned int mvpconf0)\narch/mips/kernel/smp-mt.c-82-{\n--\narch/mips/kernel/smp-mt.c=184=static void __init vsmp_smp_setup(void)\n--\narch/mips/kernel/smp-mt.c-214-\narch/mips/kernel/smp-mt.c:215:\t\tsmvp_tc_init(tc, mvpconf0);\narch/mips/kernel/smp-mt.c-216-\t\tncpu = smvp_vpe_init(tc, mvpconf0, ncpu);\n--\narch/mips/sgi-ip27/ip27-common.h=9=extern void hub_rt_clock_event_init(void);\narch/mips/sgi-ip27/ip27-common.h:10:extern void hub_rtc_init(nasid_t nasid);\narch/mips/sgi-ip27/ip27-common.h-11-extern void install_cpu_nmi_handler(int slice);\n--\narch/mips/sgi-ip27/ip27-init.c=45=static void per_hub_init(nasid_t nasid)\n--\narch/mips/sgi-ip27/ip27-init.c-58-\narch/mips/sgi-ip27/ip27-init.c:59:\thub_rtc_init(nasid);\narch/mips/sgi-ip27/ip27-init.c-60-\n--\narch/mips/sgi-ip27/ip27-timer.c=130=void __init plat_time_init(void)\n--\narch/mips/sgi-ip27/ip27-timer.c-136-\narch/mips/sgi-ip27/ip27-timer.c:137:void hub_rtc_init(nasid_t nasid)\narch/mips/sgi-ip27/ip27-timer.c-138-{\n--\narch/mips/txx9/rbtx4927/setup.c=282=static void __init rbtx4927_time_init(void)\n--\narch/mips/txx9/rbtx4927/setup.c-286-\narch/mips/txx9/rbtx4927/setup.c:287:static void __init toshiba_rbtx4927_rtc_init(void)\narch/mips/txx9/rbtx4927/setup.c-288-{\n--\narch/mips/txx9/rbtx4927/setup.c=339=static void __init rbtx4927_device_init(void)\narch/mips/txx9/rbtx4927/setup.c-340-{\narch/mips/txx9/rbtx4927/setup.c:341:\ttoshiba_rbtx4927_rtc_init();\narch/mips/txx9/rbtx4927/setup.c-342-\trbtx4927_ne_init();\n--\narch/parisc/kernel/time.c=166=static const struct rtc_class_ops rtc_generic_ops = {\n--\narch/parisc/kernel/time.c-170-\narch/parisc/kernel/time.c:171:static int __init rtc_init(void)\narch/parisc/kernel/time.c-172-{\n--\narch/parisc/kernel/time.c-180-}\narch/parisc/kernel/time.c:181:device_initcall(rtc_init);\narch/parisc/kernel/time.c-182-#endif\n--\narch/powerpc/kernel/time.c=1087=static const struct rtc_class_ops rtc_generic_ops = {\n--\narch/powerpc/kernel/time.c-1091-\narch/powerpc/kernel/time.c:1092:static int __init rtc_init(void)\narch/powerpc/kernel/time.c-1093-{\n--\narch/powerpc/kernel/time.c-1105-\narch/powerpc/kernel/time.c:1106:device_initcall(rtc_init);\narch/powerpc/kernel/time.c-1107-#endif\n--\narch/powerpc/kvm/powerpc.c=1879=static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,\n--\narch/powerpc/kvm/powerpc.c-1999-\narch/powerpc/kvm/powerpc.c:2000:bool kvm_arch_intc_initialized(struct kvm *kvm)\narch/powerpc/kvm/powerpc.c-2001-{\n--\narch/powerpc/platforms/ps3/time.c=43=time64_t __init ps3_get_boot_time(void)\n--\narch/powerpc/platforms/ps3/time.c-47-\narch/powerpc/platforms/ps3/time.c:48:static int __init ps3_rtc_init(void)\narch/powerpc/platforms/ps3/time.c-49-{\n--\narch/powerpc/platforms/ps3/time.c-58-}\narch/powerpc/platforms/ps3/time.c:59:device_initcall(ps3_rtc_init);\n--\narch/um/drivers/rtc_kern.c=180=static struct platform_driver uml_rtc_driver = {\n--\narch/um/drivers/rtc_kern.c-187-\narch/um/drivers/rtc_kern.c:188:static int __init uml_rtc_init(void)\narch/um/drivers/rtc_kern.c-189-{\n--\narch/um/drivers/rtc_kern.c-212-}\narch/um/drivers/rtc_kern.c:213:device_initcall(uml_rtc_init);\n--\narch/x86/kernel/apic/x2apic_uv_x.c=1102=static __init void map_low_mmrs(void)\n--\narch/x86/kernel/apic/x2apic_uv_x.c-1110-\narch/x86/kernel/apic/x2apic_uv_x.c:1111:static __init void uv_rtc_init(void)\narch/x86/kernel/apic/x2apic_uv_x.c-1112-{\n--\narch/x86/kernel/apic/x2apic_uv_x.c=1647=static void __init uv_system_init_hub(void)\n--\narch/x86/kernel/apic/x2apic_uv_x.c-1690-\thub_info.coherency_domain_number = sn_coherency_id;\narch/x86/kernel/apic/x2apic_uv_x.c:1691:\tuv_rtc_init();\narch/x86/kernel/apic/x2apic_uv_x.c-1692-\n--\narch/x86/platform/olpc/olpc-xo1-rtc.c=48=static struct platform_device xo1_rtc_device = {\n--\narch/x86/platform/olpc/olpc-xo1-rtc.c-55-\narch/x86/platform/olpc/olpc-xo1-rtc.c:56:static int __init xo1_rtc_init(void)\narch/x86/platform/olpc/olpc-xo1-rtc.c-57-{\n--\narch/x86/platform/olpc/olpc-xo1-rtc.c-79-}\narch/x86/platform/olpc/olpc-xo1-rtc.c:80:arch_initcall(xo1_rtc_init);\n--\ndrivers/acpi/internal.h=50=static inline void acpi_dock_add(struct acpi_device *adev) {}\n--\ndrivers/acpi/internal.h-52-#ifdef CONFIG_X86\ndrivers/acpi/internal.h:53:void acpi_cmos_rtc_init(void);\ndrivers/acpi/internal.h-54-#else\ndrivers/acpi/internal.h:55:static inline void acpi_cmos_rtc_init(void) {}\ndrivers/acpi/internal.h-56-#endif\n--\ndrivers/acpi/scan.c=2821=void __init acpi_scan_init(void)\n--\ndrivers/acpi/scan.c-2831-\tacpi_apd_init();\ndrivers/acpi/scan.c:2832:\tacpi_cmos_rtc_init();\ndrivers/acpi/scan.c-2833-\tacpi_container_init();\n--\ndrivers/acpi/x86/cmos_rtc.c=98=static struct acpi_scan_handler cmos_rtc_handler = {\n--\ndrivers/acpi/x86/cmos_rtc.c-102-\ndrivers/acpi/x86/cmos_rtc.c:103:void __init acpi_cmos_rtc_init(void)\ndrivers/acpi/x86/cmos_rtc.c-104-{\n--\ndrivers/gpu/drm/adp/adp_drv.c=368=static int adp_setup_crtc(struct adp_drv_private *adp)\n--\ndrivers/gpu/drm/adp/adp_drv.c-377-\ndrivers/gpu/drm/adp/adp_drv.c:378:\tret = drm_crtc_init_with_planes(drm, \u0026adp-\u003ecrtc, primary,\ndrivers/gpu/drm/adp/adp_drv.c-379-\t\t\t\t\tNULL, \u0026adp_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c=56=static const struct drm_crtc_helper_funcs amdgpu_vkms_crtc_helper_funcs = {\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c-59-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:60:static int amdgpu_vkms_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c-61-\t\t\t struct drm_plane *primary, struct drm_plane *cursor)\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c-66-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:67:\tret = drm_crtc_init_with_planes(dev, crtc, primary, cursor,\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c-68-\t\t\t\t\t\u0026amdgpu_vkms_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c=319=static int amdgpu_vkms_output_init(struct drm_device *dev, struct\n--\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c-331-\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c:332:\tret = amdgpu_vkms_crtc_init(dev, crtc, primary, cursor);\ndrivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c-333-\tif (ret)\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c=2692=static const struct drm_plane_helper_funcs dce_v10_0_drm_primary_plane_helper_funcs = {\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c-2696-\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c:2697:static int dce_v10_0_crtc_init(struct amdgpu_device *adev, int index)\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c-2698-{\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c-2705-\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c:2706:\tdrm_crtc_init(adev_to_drm(adev), \u0026amdgpu_crtc-\u003ebase, \u0026dce_v10_0_crtc_funcs);\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c-2707-\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c=2776=static int dce_v10_0_sw_init(struct amdgpu_ip_block *ip_block)\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c-2818-\tfor (i = 0; i \u003c adev-\u003emode_info.num_crtc; i++) {\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c:2819:\t\tr = dce_v10_0_crtc_init(adev, i);\ndrivers/gpu/drm/amd/amdgpu/dce_v10_0.c-2820-\t\tif (r)\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c=2659=static const struct drm_plane_helper_funcs dce_v6_0_drm_primary_plane_helper_funcs = {\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c-2663-\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c:2664:static int dce_v6_0_crtc_init(struct amdgpu_device *adev, int index)\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c-2665-{\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c-2672-\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c:2673:\tdrm_crtc_init(adev_to_drm(adev), \u0026amdgpu_crtc-\u003ebase, \u0026dce_v6_0_crtc_funcs);\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c-2674-\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c=2727=static int dce_v6_0_sw_init(struct amdgpu_ip_block *ip_block)\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c-2767-\tfor (i = 0; i \u003c adev-\u003emode_info.num_crtc; i++) {\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c:2768:\t\tr = dce_v6_0_crtc_init(adev, i);\ndrivers/gpu/drm/amd/amdgpu/dce_v6_0.c-2769-\t\tif (r)\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c=2617=static const struct drm_plane_helper_funcs dce_v8_0_drm_primary_plane_helper_funcs = {\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c-2621-\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c:2622:static int dce_v8_0_crtc_init(struct amdgpu_device *adev, int index)\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c-2623-{\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c-2630-\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c:2631:\tdrm_crtc_init(adev_to_drm(adev), \u0026amdgpu_crtc-\u003ebase, \u0026dce_v8_0_crtc_funcs);\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c-2632-\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c=2690=static int dce_v8_0_sw_init(struct amdgpu_ip_block *ip_block)\n--\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c-2736-\tfor (i = 0; i \u003c adev-\u003emode_info.num_crtc; i++) {\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c:2737:\t\tr = dce_v8_0_crtc_init(adev, i);\ndrivers/gpu/drm/amd/amdgpu/dce_v8_0.c-2738-\t\tif (r)\n--\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c=5699=static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)\n--\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c-5779-\tfor (i = 0; i \u003c dm-\u003edc-\u003ecaps.max_streams; i++)\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c:5780:\t\tif (amdgpu_dm_crtc_init(dm, mode_info-\u003eplanes[i], i)) {\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c-5781-\t\t\tdrm_err(adev_to_drm(adev), \"KMS: Failed to initialize crtc\\n\");\n--\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c=718=static struct amdgpu_dm_ism_config default_ism_config = {\n--\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c-726-\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c:727:int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c-728-\t\t\t struct drm_plane *plane,\n--\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c-746-\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c:747:\tres = drm_crtc_init_with_planes(\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c-748-\t\t\tdm-\u003eddev,\n--\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h=49=void amdgpu_dm_crtc_disable_vblank(struct drm_crtc *crtc);\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h-50-\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h:51:int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,\ndrivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h-52-\t\t\tstruct drm_plane *plane,\n--\ndrivers/gpu/drm/arm/display/komeda/komeda_crtc.c=638=static int komeda_crtc_add(struct komeda_kms_dev *kms,\n--\ndrivers/gpu/drm/arm/display/komeda/komeda_crtc.c-646-\ndrivers/gpu/drm/arm/display/komeda/komeda_crtc.c:647:\terr = drm_crtc_init_with_planes(base, crtc,\ndrivers/gpu/drm/arm/display/komeda/komeda_crtc.c-648-\t\t\t\t\tget_crtc_primary(kms, kcrtc), NULL,\n--\ndrivers/gpu/drm/arm/hdlcd_crtc.c=327=int hdlcd_setup_crtc(struct drm_device *drm)\n--\ndrivers/gpu/drm/arm/hdlcd_crtc.c-336-\ndrivers/gpu/drm/arm/hdlcd_crtc.c:337:\tret = drm_crtc_init_with_planes(drm, \u0026hdlcd-\u003ecrtc, primary, NULL,\ndrivers/gpu/drm/arm/hdlcd_crtc.c-338-\t\t\t\t\t\u0026hdlcd_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/arm/malidp_crtc.c=511=static const struct drm_crtc_funcs malidp_crtc_funcs = {\n--\ndrivers/gpu/drm/arm/malidp_crtc.c-520-\ndrivers/gpu/drm/arm/malidp_crtc.c:521:int malidp_crtc_init(struct drm_device *drm)\ndrivers/gpu/drm/arm/malidp_crtc.c-522-{\n--\ndrivers/gpu/drm/arm/malidp_crtc.c-544-\ndrivers/gpu/drm/arm/malidp_crtc.c:545:\tret = drmm_crtc_init_with_planes(drm, \u0026malidp-\u003ecrtc, primary, NULL,\ndrivers/gpu/drm/arm/malidp_crtc.c-546-\t\t\t\t\t \u0026malidp_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/arm/malidp_drv.c=396=static int malidp_init(struct drm_device *drm)\n--\ndrivers/gpu/drm/arm/malidp_drv.c-412-\ndrivers/gpu/drm/arm/malidp_drv.c:413:\tret = malidp_crtc_init(drm);\ndrivers/gpu/drm/arm/malidp_drv.c-414-\tif (ret)\n--\ndrivers/gpu/drm/arm/malidp_drv.h=89=int malidp_de_planes_init(struct drm_device *drm);\ndrivers/gpu/drm/arm/malidp_drv.h:90:int malidp_crtc_init(struct drm_device *drm);\ndrivers/gpu/drm/arm/malidp_drv.h-91-\n--\ndrivers/gpu/drm/armada/armada_510.c=15=struct armada510_variant_data {\n--\ndrivers/gpu/drm/armada/armada_510.c-19-\ndrivers/gpu/drm/armada/armada_510.c:20:static int armada510_crtc_init(struct armada_crtc *dcrtc, struct device *dev)\ndrivers/gpu/drm/armada/armada_510.c-21-{\n--\ndrivers/gpu/drm/armada/armada_510.c=153=const struct armada_variant armada510_ops = {\ndrivers/gpu/drm/armada/armada_510.c-154-\t.has_spu_adv_reg = true,\ndrivers/gpu/drm/armada/armada_510.c:155:\t.init = armada510_crtc_init,\ndrivers/gpu/drm/armada/armada_510.c-156-\t.compute_clock = armada510_crtc_compute_clock,\n--\ndrivers/gpu/drm/armada/armada_crtc.c=910=static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,\n--\ndrivers/gpu/drm/armada/armada_crtc.c-984-\ndrivers/gpu/drm/armada/armada_crtc.c:985:\tret = drm_crtc_init_with_planes(drm, \u0026dcrtc-\u003ecrtc, primary, NULL,\ndrivers/gpu/drm/armada/armada_crtc.c-986-\t\t\t\t\t\u0026armada_crtc_funcs, NULL);\ndrivers/gpu/drm/armada/armada_crtc.c-987-\tif (ret)\ndrivers/gpu/drm/armada/armada_crtc.c:988:\t\tgoto err_crtc_init;\ndrivers/gpu/drm/armada/armada_crtc.c-989-\n--\ndrivers/gpu/drm/armada/armada_crtc.c-999-\ndrivers/gpu/drm/armada/armada_crtc.c:1000:err_crtc_init:\ndrivers/gpu/drm/armada/armada_crtc.c-1001-\tprimary-\u003efuncs-\u003edestroy(primary);\n--\ndrivers/gpu/drm/ast/ast_mode.c=936=static const struct drm_crtc_funcs ast_crtc_funcs = {\n--\ndrivers/gpu/drm/ast/ast_mode.c-944-\ndrivers/gpu/drm/ast/ast_mode.c:945:static int ast_crtc_init(struct ast_device *ast)\ndrivers/gpu/drm/ast/ast_mode.c-946-{\n--\ndrivers/gpu/drm/ast/ast_mode.c-950-\ndrivers/gpu/drm/ast/ast_mode.c:951:\tret = drm_crtc_init_with_planes(dev, crtc, \u0026ast-\u003eprimary_plane.base,\ndrivers/gpu/drm/ast/ast_mode.c-952-\t\t\t\t\t\u0026ast-\u003ecursor_plane.base.base, \u0026ast_crtc_funcs,\n--\ndrivers/gpu/drm/ast/ast_mode.c=1017=int ast_mode_config_init(struct ast_device *ast)\n--\ndrivers/gpu/drm/ast/ast_mode.c-1052-\ndrivers/gpu/drm/ast/ast_mode.c:1053:\tret = ast_crtc_init(ast);\ndrivers/gpu/drm/ast/ast_mode.c-1054-\tif (ret)\n--\ndrivers/gpu/drm/drm_crtc.c-65- * \u0026struct drm_crtc (possibly as part of a larger structure) and registers it\ndrivers/gpu/drm/drm_crtc.c:66: * with a call to drm_crtc_init_with_planes().\ndrivers/gpu/drm/drm_crtc.c-67- *\n--\ndrivers/gpu/drm/drm_crtc.c=253=__printf(6, 0)\ndrivers/gpu/drm/drm_crtc.c:254:static int __drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,\ndrivers/gpu/drm/drm_crtc.c-255-\t\t\t\t struct drm_plane *primary,\n--\ndrivers/gpu/drm/drm_crtc.c-330-/**\ndrivers/gpu/drm/drm_crtc.c:331: * drm_crtc_init_with_planes - Initialise a new CRTC object with\ndrivers/gpu/drm/drm_crtc.c-332- * specified primary and cursor planes.\n--\ndrivers/gpu/drm/drm_crtc.c-340- * Inits a new object created as base part of a driver crtc object. Drivers\ndrivers/gpu/drm/drm_crtc.c:341: * should use this function instead of drm_crtc_init(), which is only provided\ndrivers/gpu/drm/drm_crtc.c-342- * for backwards compatibility with drivers which do not yet support universal\n--\ndrivers/gpu/drm/drm_crtc.c-351- * Note: consider using drmm_crtc_alloc_with_planes() or\ndrivers/gpu/drm/drm_crtc.c:352: * drmm_crtc_init_with_planes() instead of drm_crtc_init_with_planes()\ndrivers/gpu/drm/drm_crtc.c-353- * to let the DRM managed resource infrastructure take care of cleanup\n--\ndrivers/gpu/drm/drm_crtc.c-358- */\ndrivers/gpu/drm/drm_crtc.c:359:int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,\ndrivers/gpu/drm/drm_crtc.c-360-\t\t\t struct drm_plane *primary,\n--\ndrivers/gpu/drm/drm_crtc.c-370-\tva_start(ap, name);\ndrivers/gpu/drm/drm_crtc.c:371:\tret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,\ndrivers/gpu/drm/drm_crtc.c-372-\t\t\t\t\t name, ap);\n--\ndrivers/gpu/drm/drm_crtc.c-376-}\ndrivers/gpu/drm/drm_crtc.c:377:EXPORT_SYMBOL(drm_crtc_init_with_planes);\ndrivers/gpu/drm/drm_crtc.c-378-\ndrivers/gpu/drm/drm_crtc.c:379:static void drmm_crtc_init_with_planes_cleanup(struct drm_device *dev,\ndrivers/gpu/drm/drm_crtc.c-380-\t\t\t\t\t void *ptr)\n--\ndrivers/gpu/drm/drm_crtc.c=387=__printf(6, 0)\ndrivers/gpu/drm/drm_crtc.c:388:static int __drmm_crtc_init_with_planes(struct drm_device *dev,\ndrivers/gpu/drm/drm_crtc.c-389-\t\t\t\t\tstruct drm_crtc *crtc,\n--\ndrivers/gpu/drm/drm_crtc.c-399-\ndrivers/gpu/drm/drm_crtc.c:400:\tret = __drm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,\ndrivers/gpu/drm/drm_crtc.c-401-\t\t\t\t\t name, args);\n--\ndrivers/gpu/drm/drm_crtc.c-404-\ndrivers/gpu/drm/drm_crtc.c:405:\tret = drmm_add_action_or_reset(dev, drmm_crtc_init_with_planes_cleanup,\ndrivers/gpu/drm/drm_crtc.c-406-\t\t\t\t crtc);\n--\ndrivers/gpu/drm/drm_crtc.c-413-/**\ndrivers/gpu/drm/drm_crtc.c:414: * drmm_crtc_init_with_planes - Initialise a new CRTC object with\ndrivers/gpu/drm/drm_crtc.c-415- * specified primary and cursor planes.\n--\ndrivers/gpu/drm/drm_crtc.c-423- * Inits a new object created as base part of a driver crtc object. Drivers\ndrivers/gpu/drm/drm_crtc.c:424: * should use this function instead of drm_crtc_init(), which is only provided\ndrivers/gpu/drm/drm_crtc.c-425- * for backwards compatibility with drivers which do not yet support universal\n--\ndrivers/gpu/drm/drm_crtc.c-439- */\ndrivers/gpu/drm/drm_crtc.c:440:int drmm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,\ndrivers/gpu/drm/drm_crtc.c-441-\t\t\t struct drm_plane *primary,\n--\ndrivers/gpu/drm/drm_crtc.c-449-\tva_start(ap, name);\ndrivers/gpu/drm/drm_crtc.c:450:\tret = __drmm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,\ndrivers/gpu/drm/drm_crtc.c-451-\t\t\t\t\t name, ap);\n--\ndrivers/gpu/drm/drm_crtc.c-457-}\ndrivers/gpu/drm/drm_crtc.c:458:EXPORT_SYMBOL(drmm_crtc_init_with_planes);\ndrivers/gpu/drm/drm_crtc.c-459-\ndrivers/gpu/drm/drm_crtc.c=460=void *__drmm_crtc_alloc_with_planes(struct drm_device *dev,\n--\ndrivers/gpu/drm/drm_crtc.c-481-\tva_start(ap, name);\ndrivers/gpu/drm/drm_crtc.c:482:\tret = __drmm_crtc_init_with_planes(dev, crtc, primary, cursor, funcs,\ndrivers/gpu/drm/drm_crtc.c-483-\t\t\t\t\t name, ap);\n--\ndrivers/gpu/drm/drm_modeset_helper.c=114=static const struct drm_plane_funcs primary_plane_funcs = {\n--\ndrivers/gpu/drm/drm_modeset_helper.c-118-/**\ndrivers/gpu/drm/drm_modeset_helper.c:119: * drm_crtc_init - Legacy CRTC initialization function\ndrivers/gpu/drm/drm_modeset_helper.c-120- * @dev: DRM device\n--\ndrivers/gpu/drm/drm_modeset_helper.c-141- */\ndrivers/gpu/drm/drm_modeset_helper.c:142:int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,\ndrivers/gpu/drm/drm_modeset_helper.c-143-\t\t const struct drm_crtc_funcs *funcs)\n--\ndrivers/gpu/drm/drm_modeset_helper.c-147-\ndrivers/gpu/drm/drm_modeset_helper.c:148:\t/* possible_crtc's will be filled in later by crtc_init */\ndrivers/gpu/drm/drm_modeset_helper.c-149-\tprimary = __drm_universal_plane_alloc(dev, sizeof(*primary), 0, 0,\n--\ndrivers/gpu/drm/drm_modeset_helper.c-162-\ndrivers/gpu/drm/drm_modeset_helper.c:163:\tret = drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs, NULL);\ndrivers/gpu/drm/drm_modeset_helper.c-164-\tif (ret)\n--\ndrivers/gpu/drm/drm_modeset_helper.c-173-}\ndrivers/gpu/drm/drm_modeset_helper.c:174:EXPORT_SYMBOL(drm_crtc_init);\ndrivers/gpu/drm/drm_modeset_helper.c-175-\n--\ndrivers/gpu/drm/drm_plane.c-69- * relies on the driver to set the primary and optionally the cursor plane used\ndrivers/gpu/drm/drm_plane.c:70: * for legacy IOCTLs. This is done by calling drm_crtc_init_with_planes(). All\ndrivers/gpu/drm/drm_plane.c-71- * drivers must provide one primary plane per CRTC to avoid surprising legacy\n--\ndrivers/gpu/drm/drm_simple_kms_helper.c=335=int drm_simple_display_pipe_init(struct drm_device *dev,\n--\ndrivers/gpu/drm/drm_simple_kms_helper.c-359-\tdrm_crtc_helper_add(crtc, \u0026drm_simple_kms_crtc_helper_funcs);\ndrivers/gpu/drm/drm_simple_kms_helper.c:360:\tret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,\ndrivers/gpu/drm/drm_simple_kms_helper.c-361-\t\t\t\t\t\u0026drm_simple_kms_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/exynos/exynos_drm_crtc.c=173=struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,\n--\ndrivers/gpu/drm/exynos/exynos_drm_crtc.c-192-\ndrivers/gpu/drm/exynos/exynos_drm_crtc.c:193:\tret = drm_crtc_init_with_planes(drm_dev, crtc, plane, NULL,\ndrivers/gpu/drm/exynos/exynos_drm_crtc.c-194-\t\t\t\t\t\u0026exynos_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c=170=int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev)\n--\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c-181-\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c:182:\tret = drm_crtc_init_with_planes(fsl_dev-\u003edrm, crtc, primary, NULL,\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c-183-\t\t\t\t\t\u0026fsl_dcu_drm_crtc_funcs, NULL);\n--\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c=207=struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)\n--\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c-217-\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c:218:\t/* possible_crtc's will be filled in later by crtc_init */\ndrivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c-219-\tret = drm_universal_plane_init(dev, primary, 0,\n--\ndrivers/gpu/drm/gma500/framebuffer.c=101=void psb_modeset_init(struct drm_device *dev)\n--\ndrivers/gpu/drm/gma500/framebuffer.c-116-\tfor (i = 0; i \u003c dev_priv-\u003enum_pipe; i++)\ndrivers/gpu/drm/gma500/framebuffer.c:117:\t\tpsb_intel_crtc_init(dev, i, mode_dev);\ndrivers/gpu/drm/gma500/framebuffer.c-118-\n--\ndrivers/gpu/drm/gma500/psb_intel_display.c=446=static void psb_intel_cursor_init(struct drm_device *dev,\n--\ndrivers/gpu/drm/gma500/psb_intel_display.c-473-\ndrivers/gpu/drm/gma500/psb_intel_display.c:474:void psb_intel_crtc_init(struct drm_device *dev, int pipe,\ndrivers/gpu/drm/gma500/psb_intel_display.c-475-\t\t struct psb_intel_mode_device *mode_dev)\n--\ndrivers/gpu/drm/gma500/psb_intel_display.c-496-\ndrivers/gpu/drm/gma500/psb_intel_display.c:497:\tdrm_crtc_init(dev, \u0026gma_crtc-\u003ebase, \u0026gma_crtc_funcs);\ndrivers/gpu/drm/gma500/psb_intel_display.c-498-\n--\ndrivers/gpu/drm/gma500/psb_intel_drv.h=183=int psb_intel_ddc_get_modes(struct drm_connector *connector,\n--\ndrivers/gpu/drm/gma500/psb_intel_drv.h-185-\ndrivers/gpu/drm/gma500/psb_intel_drv.h:186:extern void psb_intel_crtc_init(struct drm_device *dev, int pipe,\ndrivers/gpu/drm/gma500/psb_intel_drv.h-187-\t\t\t struct psb_intel_mode_device *mode_dev);\n--\ndrivers/gpu/drm/gud/gud_drv.c=436=static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id)\n\n"
} |
| 59/2 | 2026/08/08 15:37 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 79338 output: 44 thoughts: 34 Thoughts: Okay, let's dive into this. Here's how I'd approach this task. **Investigating the `tc_init` Function within the STMMAC Driver** Right, so I need to understand how the traffic control features are initialized within the STMMAC Ethernet driver. My first instinct is always to go straight to the source. The filename, `stmmac_tc.c`, strongly suggests this is where I'll find the TC-specific code. And I'm pretty sure I recall that `tc_init` is a common naming convention for initialization functions related to traffic control in the Linux kernel. Therefore, the most efficient starting point is to *grep* for the string `tc_init` within that file, specifically `drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c`. That grep command should quickly identify all instances of that function name, allowing me to quickly understand its usage, entry points, and dependencies within the larger driver structure. This should allow me to formulate a mental model of how TC features are being initialized for this hardware. I want to build a foundational understanding quickly, then I can move on to other areas to understand more complex implementations. |
| 60/2 | 2026/08/08 15:37 | tool | grepper |
0mArgs:{
"Expression": "tc_init",
"PathPrefix": "drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c=235=static int tc_rfs_init(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-258-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:259:static int tc_init(struct stmmac_priv *priv)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-260-{\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c=1457=const struct stmmac_tc_ops dwmac4_tc_ops = {\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:1458:\t.init = tc_init,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1459-\t.setup_cls_u32 = tc_setup_cls_u32,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c=1469=const struct stmmac_tc_ops dwmac510_tc_ops = {\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:1470:\t.init = tc_init,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1471-\t.setup_cls_u32 = tc_setup_cls_u32,\n"
} |
| 61/2 | 2026/08/08 15:37 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 80093 output: 49 thoughts: 9 Thoughts: Okay, here's my interpretation of that thought process, tailored for an expert audience, and written in the first person: **Initial Assessment of the Task** Alright, the directive is clear. I'm being prompted to examine and summarize the thought process that's triggered by the command "Let's read `tc_init`." Immediately, my mind jumps to the specifics. I know `tc_init` likely refers to a crucial initialization function or module within a system. Given my expertise, I'm expecting this is related to thread context initialization, transaction coordination, or possibly even a timecode or timestamp initialization. The implication is I'm being asked to reflect on how a person *thinks* about diving into the code of a function with such a name. The "Let's read" part is direct; it signals a clear intention to engage with the code. |
| 62/2 | 2026/08/08 15:37 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c",
"FirstLine": 259,
"LineCount": 20
}Results: {
"Contents": " 259:\tstatic int tc_init(struct stmmac_priv *priv)\n 260:\t{\n 261:\t\tstruct dma_features *dma_cap = \u0026priv-\u003edma_cap;\n 262:\t\tunsigned int count;\n 263:\t\tint ret, i;\n 264:\t\n 265:\t\tpriv-\u003eflow_entries_max = dma_cap-\u003el3l4fnum;\n 266:\t\tif (priv-\u003eflow_entries_max) {\n 267:\t\t\tpriv-\u003eflow_entries = devm_kcalloc(priv-\u003edevice,\n 268:\t\t\t\t\t\t\t priv-\u003eflow_entries_max,\n 269:\t\t\t\t\t\t\t sizeof(*priv-\u003eflow_entries),\n 270:\t\t\t\t\t\t\t GFP_KERNEL);\n 271:\t\t\tif (!priv-\u003eflow_entries)\n 272:\t\t\t\treturn -ENOMEM;\n 273:\t\n 274:\t\t\tfor (i = 0; i \u003c priv-\u003eflow_entries_max; i++)\n 275:\t\t\t\tpriv-\u003eflow_entries[i].idx = i;\n 276:\t\n 277:\t\t\tdev_info(priv-\u003edevice, \"Enabled L3L4 Flow TC (entries=%d)\\n\",\n 278:\t\t\t\t priv-\u003eflow_entries_max);\n"
} |
| 63/2 | 2026/08/08 15:37 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 80678 output: 51 thoughts: 346 Thoughts: **Analyzing the STMMAC Driver's Resilience to Dummy Hardware**
Okay, so I'm thinking about this STMMAC driver, and it looks like it's surprisingly robust when dealing with non-existent or dummy hardware. The key is that `stmmac_pci_probe` will happily chug along, registering the network device even if there's no actual hardware present. I can see why: `stmmac_get_hw_features` reads zero and returns zero, and so `priv->hw_cap_support` ends up being zero. This prevents the driver from accessing hardware features that it doesn't know about.
Then I look at `stmmac_hw_init`. It calls `stmmac_hwif_init`, which sees a version of zero and falls back to a default `min_id` of zero. This looks very reasonable. From here, `stmmac_tc_init` succeeds and, crucially, `register_netdev` gets called. Boom, the network device is registered, even with zero hardware. This is where things get interesting from a testing perspective.
Because a netdev is registered, syzkaller can now send `tc` netlink commands to it, and my focus is on the new patches adding support for `TC_SETUP_QDISC_ETS` and `TC_SETUP_QDISC_MQPRIO` offload. I’m thinking, can we reach `tc_setup_ets`? Let's check in `stmmac_setup_tc`:
```c
switch (type) {
...
case TC_SETUP_QDISC_ETS:
ret = stmmac_tc_setup_ets(priv, priv, type_data);
break;
```
Yes, it looks like `stmmac_tc_setup_ets` is directly reachable based on this logic. That calls `tc_setup_ets` through `dwmac4_tc_ops` or `dwmac510_tc_ops`. I should read `tc_setup_ets`.
|
| 64/2 | 2026/08/08 15:37 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c",
"FirstLine": 1227,
"LineCount": 100
}Results: {
"Contents": "1227:\tstatic int tc_setup_ets_sched(struct stmmac_priv *priv,\n1228:\t\t\t\t struct tc_ets_qopt_offload *qopt)\n1229:\t{\n1230:\t\tstruct tc_ets_qopt_offload_replace_params *p = \u0026qopt-\u003ereplace_params;\n1231:\t\tstruct plat_stmmacenet_data *pdata = priv-\u003eplat;\n1232:\t\tint err, i;\n1233:\t\n1234:\t\tif (!priv-\u003edma_cap.dcben)\n1235:\t\t\treturn -EOPNOTSUPP;\n1236:\t\n1237:\t\tif (qopt-\u003eparent != TC_H_ROOT)\n1238:\t\t\treturn -EOPNOTSUPP;\n1239:\t\n1240:\t\tif (p-\u003ebands \u003e pdata-\u003etx_queues_to_use)\n1241:\t\t\treturn -EOPNOTSUPP;\n1242:\t\n1243:\t\tfor (i = 0; i \u003c pdata-\u003etx_queues_to_use; i++) {\n1244:\t\t\tif (pdata-\u003etx_queues_cfg[i].mode_to_use == MTL_QUEUE_AVB)\n1245:\t\t\t\treturn -EOPNOTSUPP;\n1246:\t\t}\n1247:\t\n1248:\t\tfor (i = 0; i \u003c p-\u003ebands; i++) {\n1249:\t\t\tif (!p-\u003equanta[i])\n1250:\t\t\t\treturn -EOPNOTSUPP;\n1251:\t\n1252:\t\t\tif (p-\u003equanta[i] \u003e MTL_TXQ_WEIGHT_QUANTUM_MAX)\n1253:\t\t\t\treturn -EOPNOTSUPP;\n1254:\t\t}\n1255:\t\n1256:\t\terr = netif_set_real_num_tx_queues(priv-\u003edev, p-\u003ebands);\n1257:\t\tif (err)\n1258:\t\t\treturn err;\n1259:\t\n1260:\t\tfor (i = 0; i \u003c pdata-\u003etx_queues_to_use; i++) {\n1261:\t\t\tu32 quantum = i \u003c p-\u003ebands ? p-\u003equanta[i] : 0;\n1262:\t\n1263:\t\t\tpriv-\u003eqdisc.quanta[i] = quantum;\n1264:\t\t\tstmmac_set_mtl_tx_queue_weight(priv, priv-\u003ehw, quantum, i);\n1265:\t\t}\n1266:\t\n1267:\t\tstmmac_prog_mtl_tx_algorithms(priv, priv-\u003ehw, MTL_TX_ALGORITHM_DWRR);\n1268:\t\tpriv-\u003eqdisc.algo = MTL_TX_ALGORITHM_DWRR;\n1269:\t\tpriv-\u003eqdisc.handle = qopt-\u003ehandle;\n1270:\t\tpriv-\u003eqdisc.bands = p-\u003ebands;\n1271:\t\tpriv-\u003eqdisc.enable = true;\n1272:\t\n1273:\t\treturn 0;\n1274:\t}\n1275:\t\n1276:\tstatic int tc_setup_ets_destroy(struct stmmac_priv *priv,\n1277:\t\t\t\t\tstruct tc_ets_qopt_offload *qopt)\n1278:\t{\n1279:\t\tif (qopt-\u003eparent != TC_H_ROOT ||\n1280:\t\t qopt-\u003ehandle != priv-\u003eqdisc.handle)\n1281:\t\t\treturn -EOPNOTSUPP;\n1282:\t\n1283:\t\tif (!priv-\u003eqdisc.enable ||\n1284:\t\t priv-\u003eqdisc.algo != MTL_TX_ALGORITHM_DWRR)\n1285:\t\t\treturn -EOPNOTSUPP;\n1286:\t\n1287:\t\tstmmac_qdisc_restore_dt_config(priv);\n1288:\t\n1289:\t\treturn 0;\n1290:\t}\n1291:\t\n1292:\tstatic int tc_setup_ets(struct stmmac_priv *priv,\n1293:\t\t\t\tstruct tc_ets_qopt_offload *qopt)\n1294:\t{\n1295:\t\tswitch (qopt-\u003ecommand) {\n1296:\t\tcase TC_ETS_REPLACE:\n1297:\t\t\treturn tc_setup_ets_sched(priv, qopt);\n1298:\t\tcase TC_ETS_DESTROY:\n1299:\t\t\treturn tc_setup_ets_destroy(priv, qopt);\n1300:\t\tcase TC_ETS_GRAFT:\n1301:\t\t\tbreak;\n1302:\t\tcase TC_ETS_STATS:\n1303:\t\t\tif (qopt-\u003eparent == TC_H_ROOT \u0026\u0026\n1304:\t\t\t qopt-\u003ehandle == priv-\u003eqdisc.handle \u0026\u0026\n1305:\t\t\t priv-\u003eqdisc.enable \u0026\u0026\n1306:\t\t\t priv-\u003eqdisc.algo == MTL_TX_ALGORITHM_DWRR)\n1307:\t\t\t\tbreak;\n1308:\t\t\tfallthrough;\n1309:\t\tdefault:\n1310:\t\t\treturn -EOPNOTSUPP;\n1311:\t\t}\n1312:\t\n1313:\t\treturn 0;\n1314:\t}\n1315:\t\n1316:\tstatic int tc_query_caps(struct stmmac_priv *priv,\n1317:\t\t\t\t struct tc_query_caps_base *base)\n1318:\t{\n1319:\t\tswitch (base-\u003etype) {\n1320:\t\tcase TC_SETUP_QDISC_MQPRIO: {\n1321:\t\t\tstruct tc_mqprio_caps *caps = base-\u003ecaps;\n1322:\t\n1323:\t\t\tcaps-\u003evalidate_queue_counts = true;\n1324:\t\n1325:\t\t\treturn 0;\n1326:\t\t}\n"
} |
| 65/2 | 2026/08/08 15:37 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 83089 output: 50 thoughts: 110 Thoughts: **Analyzing the ETS Scheduling Issue** Okay, so I'm looking at this `tc_setup_ets_sched` function and something's not adding up. I see it starts by checking `!priv->dma_cap.dcben`. The problem is, if `stmmac_get_hw_features` returns zero, the entire `priv->dma_cap` structure gets zeroed out. That means `priv->dma_cap.dcben` is going to be zero, right? Which, in turn, is going to make `tc_setup_ets_sched` return `-EOPNOTSUPP`. That's not good. We need to figure out why this is happening. The hardware should support DCBEN. Alright, let's turn our attention to `tc_setup_dwmac510_mqprio`. Maybe there's some useful information there. |
| 66/2 | 2026/08/08 15:38 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c",
"FirstLine": 1361,
"LineCount": 50
}Results: {
"Contents": "1361:\tstatic int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,\n1362:\t\t\t\t\t struct tc_mqprio_qopt_offload *mqprio)\n1363:\t{\n1364:\t\tstruct netlink_ext_ack *extack = mqprio-\u003eextack;\n1365:\t\tstruct tc_mqprio_qopt *qopt = \u0026mqprio-\u003eqopt;\n1366:\t\tu32 offset, count, num_stack_tx_queues = 0;\n1367:\t\tstruct net_device *ndev = priv-\u003edev;\n1368:\t\tu32 num_tc = qopt-\u003enum_tc;\n1369:\t\tint i, tc, err;\n1370:\t\n1371:\t\tif (!num_tc) {\n1372:\t\t\tstmmac_reset_tc_mqprio(ndev, extack);\n1373:\t\t\treturn 0;\n1374:\t\t}\n1375:\t\n1376:\t\tif (!priv-\u003edma_cap.dcben)\n1377:\t\t\treturn -EOPNOTSUPP;\n1378:\t\n1379:\t\t/* Forcing strict priority conflicts with the CBS algorithm of AVB\n1380:\t\t * queues, so reject the offload when any queue is configured as AVB.\n1381:\t\t */\n1382:\t\tfor (i = 0; i \u003c priv-\u003eplat-\u003etx_queues_to_use; i++) {\n1383:\t\t\tif (priv-\u003eplat-\u003etx_queues_cfg[i].mode_to_use == MTL_QUEUE_AVB)\n1384:\t\t\t\treturn -EOPNOTSUPP;\n1385:\t\t}\n1386:\t\n1387:\t\terr = netdev_set_num_tc(ndev, num_tc);\n1388:\t\tif (err)\n1389:\t\t\treturn err;\n1390:\t\n1391:\t\tfor (u32 tc = 0; tc \u003c num_tc; tc++) {\n1392:\t\t\toffset = qopt-\u003eoffset[tc];\n1393:\t\t\tcount = qopt-\u003ecount[tc];\n1394:\t\t\tnum_stack_tx_queues += count;\n1395:\t\n1396:\t\t\tif (offset + count \u003e priv-\u003eplat-\u003etx_queues_to_use)\n1397:\t\t\t\tgoto err_reset_tc;\n1398:\t\n1399:\t\t\t/* The offload switches the MTL scheduler to strict priority,\n1400:\t\t\t * which only supports a 1:1 TC to TX queue mapping.\n1401:\t\t\t */\n1402:\t\t\tif (count \u003e 1)\n1403:\t\t\t\tgoto err_reset_tc;\n1404:\t\n1405:\t\t\terr = netdev_set_tc_queue(ndev, tc, count, offset);\n1406:\t\t\tif (err)\n1407:\t\t\t\tgoto err_reset_tc;\n1408:\t\t}\n1409:\t\n1410:\t\terr = netif_set_real_num_tx_queues(ndev, num_stack_tx_queues);\n"
} |
| 67/2 | 2026/08/08 15:38 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 84284 output: 23 thoughts: 210 Thoughts: **Analyzing the STMMAC Driver's Hardware Feature Detection** Okay, so I'm looking at this STMMAC driver code, and I see this check: `!priv->dma_cap.dcben`. Right, so if `stmmac_get_hw_features` returns zero, then `priv->dma_cap.dcben` gets set to zero, and both functions bail out with `-EOPNOTSUPP`. That makes sense. But can syzkaller's PCI fuzzer actually give us a *non-zero* value from `stmmac_get_hw_features`? Ah, right, of course it can. The PCI fuzzer intercepts `readl`, so it can inject fuzzed values. Got it. Wait a minute... `stmmac_get_hw_features` reads from `MAC_HW_FEATURE0`, `MAC_HW_FEATURE1`, `MAC_HW_FEATURE2`, and `MAC_HW_FEATURE3`. So, if the fuzzer hands back values with the `dcben` bit set in any of those registers, then `priv->dma_cap.dcben` will be set to one. Right, that's the key. Now, let's go back and take a closer look at `stmmac_get_hw_features`... |
| 68/2 | 2026/08/08 15:38 | tool | grepper |
0mArgs:{
"Expression": "stmmac_get_hw_features"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/stmmac_main.c=3145=static void stmmac_mmc_setup(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3159-/**\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3160: * stmmac_get_hw_features - get MAC capabilities from the HW cap. register.\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3161- * @priv: driver private structure\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3167- */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3168:static int stmmac_get_hw_features(struct stmmac_priv *priv)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3169-{\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7443=static int stmmac_hw_init(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7457-\t/* Get the HW capability (new GMAC newer than 3.50a) */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7458:\tpriv-\u003ehw_cap_support = stmmac_get_hw_features(priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7459-\tif (priv-\u003ehw_cap_support) {\n"
} |
| 69/2 | 2026/08/08 15:38 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 85279 output: 50 thoughts: 15 Thoughts: Okay, here's my attempt at summarizing the thought process, as requested, aimed at an expert audience and in the first person: **Diving into `stmmac_get_hw_features`** Right, let's pull up the source code for `stmmac_get_hw_features`. I need to get a clear picture of how this function determines and reports the hardware capabilities of the STMicroelectronics MAC driver. I'm assuming it's responsible for things like feature flags for different hardware variations, perhaps related to jumbo frames, checksum offload, or flow control capabilities. My immediate thought is, I need to understand the data structures it accesses and manipulates, particularly any bitfields or enumerated types that define these features. I anticipate it'll probably query hardware registers, and I'll need to see how it maps those register values to internal flags. I'll be looking for any potential conditional logic based on detected silicon revision, or perhaps DT (Device Tree) bindings, that might influence what features are reported. I want to see if they're using a lookup table, a series of if-else statements, or a more elegant method. The efficiency of this function is going to be important, especially if it's called frequently during device initialization or hotplug events. I'll need to examine if it's potentially vulnerable to any race conditions, if it is multi-threaded. Finally, I’ll keep a close eye out for any comments or documentation that shed light on why certain features are implemented or absent in specific hardware revisions. Let's see what we've got. |
| 70/2 | 2026/08/08 15:38 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/stmmac_main.c",
"FirstLine": 3168,
"LineCount": 20
}Results: {
"Contents": "3168:\tstatic int stmmac_get_hw_features(struct stmmac_priv *priv)\n3169:\t{\n3170:\t\treturn stmmac_get_hw_feature(priv, priv-\u003eioaddr, \u0026priv-\u003edma_cap) == 0;\n3171:\t}\n3172:\t\n3173:\t/**\n3174:\t * stmmac_check_ether_addr - check if the MAC addr is valid\n3175:\t * @priv: driver private structure\n3176:\t * Description:\n3177:\t * it is to verify if the MAC address is valid, in case of failures it\n3178:\t * generates a random MAC address\n3179:\t */\n3180:\tstatic void stmmac_check_ether_addr(struct stmmac_priv *priv)\n3181:\t{\n3182:\t\tu8 addr[ETH_ALEN];\n3183:\t\n3184:\t\tif (!is_valid_ether_addr(priv-\u003edev-\u003edev_addr)) {\n3185:\t\t\tstmmac_get_umac_addr(priv, priv-\u003ehw, addr, 0);\n3186:\t\t\tif (is_valid_ether_addr(addr))\n3187:\t\t\t\teth_hw_addr_set(priv-\u003edev, addr);\n"
} |
| 71/2 | 2026/08/08 15:38 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 86033 output: 23 thoughts: 15 Thoughts: Okay, here's my take on those thoughts, framed as an expert's internal monologue: **Delving into the `stmmac_get_hw_feature` Callback** Right, so `stmmac_get_hw_feature`. Straight to the point, this is a callback function. It's a key piece of the puzzle within the STMMAC driver framework, obviously. It means that the STMMAC driver isn't directly handling this hardware feature retrieval itself. Instead, it's designed to *defer* this task to another part of the system, likely a lower-level hardware abstraction layer or perhaps a board-specific module. The whole concept of callbacks is well-understood: it's about providing a mechanism for modularity and flexibility. I'd expect this callback to be called at initialization or when specific hardware features are needed to be checked. This is where the hardware knowledge lives and it helps when the driver needs specific details that it can't know. The driver *needs* something to tell it about what the hardware *can* do, rather than trying to guess. This design implies a clear separation of concerns, which is good. It keeps the core STMMAC code clean and relatively hardware-agnostic. The driver is asking: "Hey, what features are supported on *this* particular hardware?" and it expects a response. I'd want to understand the signature of this callback. What parameters does it take? What does it return? Knowing that will provide key insights. I'll need to know whether it's returning a bitmask, an enumerated type, or something else entirely. That'll inform how the driver then *interprets* the capabilities of the hardware. And of course, I'd want to see how the driver *uses* this information, what the code is doing after it receives the information about the features. That's where you start to understand the implications of different hardware feature sets. Essentially, `stmmac_get_hw_feature` is an entry point for hardware-specific configuration, and it's a critical part of a robust and adaptable STMMAC implementation. |
| 72/2 | 2026/08/08 15:38 | tool | grepper |
0mArgs:{
"Expression": "stmmac_get_hw_feature"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/hwif.h=167=struct stmmac_dma_ops {\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.h-273-\tstmmac_do_callback(__priv, dma, dma_interrupt, __priv, __args)\ndrivers/net/ethernet/stmicro/stmmac/hwif.h:274:#define stmmac_get_hw_feature(__priv, __args...) \\\ndrivers/net/ethernet/stmicro/stmmac/hwif.h-275-\tstmmac_do_callback(__priv, dma, get_hw_feature, __args)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=3145=static void stmmac_mmc_setup(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3159-/**\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3160: * stmmac_get_hw_features - get MAC capabilities from the HW cap. register.\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3161- * @priv: driver private structure\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3167- */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3168:static int stmmac_get_hw_features(struct stmmac_priv *priv)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3169-{\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3170:\treturn stmmac_get_hw_feature(priv, priv-\u003eioaddr, \u0026priv-\u003edma_cap) == 0;\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3171-}\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7443=static int stmmac_hw_init(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7457-\t/* Get the HW capability (new GMAC newer than 3.50a) */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7458:\tpriv-\u003ehw_cap_support = stmmac_get_hw_features(priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7459-\tif (priv-\u003ehw_cap_support) {\n"
} |
| 73/2 | 2026/08/08 15:38 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 87253 output: 23 thoughts: 30 Thoughts: Okay, here's my interpretation of that thought process, assuming I'm an expert in this field, presented as a first-person summary: **Analyzing `dwmac4_dma_ops` and Feature Retrieval** Right, so I'm looking at `dwmac4_dma_ops`. And, as I understand it, within that structure, there's a specific function pointer, `get_hw_feature`. The key here is noticing the convention. My mind immediately makes the connection and associates this function pointer with its actual implementation. In this case, it appears that `get_hw_feature` for `dwmac4_dma_ops` is assigned to `dwmac4_get_hw_feature`. It's a straightforward naming convention, which makes it easy to understand what the code is doing. It's the standard practice. This particular line is a good example of well-structured code. |
| 74/2 | 2026/08/08 15:38 | tool | grepper |
0mArgs:{
"Expression": "dwmac4_get_hw_feature"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c=325=static void dwmac4_dma_tx_chan_op_mode(struct stmmac_priv *priv,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c-379-\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c:380:static int dwmac4_get_hw_feature(void __iomem *ioaddr,\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c-381-\t\t\t\t struct dma_features *dma_cap)\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c=569=const struct stmmac_dma_ops dwmac4_dma_ops = {\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c-586-\t.dma_interrupt = dwmac4_dma_interrupt,\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c:587:\t.get_hw_feature = dwmac4_get_hw_feature,\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c-588-\t.rx_watchdog = dwmac4_rx_watchdog,\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c=599=const struct stmmac_dma_ops dwmac410_dma_ops = {\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c-616-\t.dma_interrupt = dwmac4_dma_interrupt,\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c:617:\t.get_hw_feature = dwmac4_get_hw_feature,\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c-618-\t.rx_watchdog = dwmac4_rx_watchdog,\n"
} |
| 75/2 | 2026/08/08 15:38 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 88062 output: 50 thoughts: 15 Thoughts: Okay, let's dive into this. Here's my take on `dwmac4_get_hw_feature`: **Analyzing `dwmac4_get_hw_feature`** Alright, so the first thing I'm doing is getting into the code for `dwmac4_get_hw_feature`. Based on the naming, I'm expecting this function to tell me something about the hardware features supported by the DWMAC (likely a specific revision, given the "4" in the name) Ethernet controller. I’m guessing it's going to return a bitmask or a structure with boolean flags, detailing capabilities like jumbo frame support, flow control, checksum offload, and other relevant hardware-accelerated functionality. I'm also betting there'll be some conditional logic in there to handle different silicon revisions or configuration options. Let's see what the implementation reveals about how it determines and returns these hardware capabilities. I expect a careful reading will provide insight into how the controller's features are probed and exposed to the driver. |
| 76/2 | 2026/08/08 15:38 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c",
"FirstLine": 380,
"LineCount": 20
}Results: {
"Contents": " 380:\tstatic int dwmac4_get_hw_feature(void __iomem *ioaddr,\n 381:\t\t\t\t\t struct dma_features *dma_cap)\n 382:\t{\n 383:\t\tu32 hw_cap = readl(ioaddr + GMAC_HW_FEATURE0);\n 384:\t\n 385:\t\t/* MAC HW feature0 */\n 386:\t\tdma_cap-\u003embps_10_100 = (hw_cap \u0026 GMAC_HW_FEAT_MIISEL);\n 387:\t\tdma_cap-\u003embps_1000 = (hw_cap \u0026 GMAC_HW_FEAT_GMIISEL) \u003e\u003e 1;\n 388:\t\tdma_cap-\u003ehalf_duplex = (hw_cap \u0026 GMAC_HW_FEAT_HDSEL) \u003e\u003e 2;\n 389:\t\tdma_cap-\u003evlhash = (hw_cap \u0026 GMAC_HW_FEAT_VLHASH) \u003e\u003e 4;\n 390:\t\tdma_cap-\u003emulti_addr = (hw_cap \u0026 GMAC_HW_FEAT_ADDMAC) \u003e\u003e 18;\n 391:\t\tdma_cap-\u003epcs = (hw_cap \u0026 GMAC_HW_FEAT_PCSSEL) \u003e\u003e 3;\n 392:\t\tdma_cap-\u003esma_mdio = (hw_cap \u0026 GMAC_HW_FEAT_SMASEL) \u003e\u003e 5;\n 393:\t\tdma_cap-\u003epmt_remote_wake_up = (hw_cap \u0026 GMAC_HW_FEAT_RWKSEL) \u003e\u003e 6;\n 394:\t\tdma_cap-\u003epmt_magic_frame = (hw_cap \u0026 GMAC_HW_FEAT_MGKSEL) \u003e\u003e 7;\n 395:\t\t/* MMC */\n 396:\t\tdma_cap-\u003ermon = (hw_cap \u0026 GMAC_HW_FEAT_MMCSEL) \u003e\u003e 8;\n 397:\t\t/* IEEE 1588-2008 */\n 398:\t\tdma_cap-\u003eatime_stamp = (hw_cap \u0026 GMAC_HW_FEAT_TSSEL) \u003e\u003e 12;\n 399:\t\t/* 802.3az - Energy-Efficient Ethernet (EEE) */\n"
} |
| 77/2 | 2026/08/08 15:38 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 88932 output: 50 thoughts: 8 Thoughts: Okay, I'm ready. Let's do this. I'll summarize the thought process as if it were my own. Here we go: **Diving Deeper: Assessing the Information** Alright, that's enough of the overview. Now, I need to really dig in and analyze this. The initial context gives me a starting point, of course, but that's not enough to form a complete picture. I'm going to have to carefully dissect this. I have to read more of it, understand the nuances, consider any alternative interpretations, and make sure my understanding is accurate and comprehensive. This isn't something I can rush; the devil, as they say, is in the details, and I need to be certain I have a solid grasp before I make any judgments or come to any conclusions. Let's see what else there is to examine, and I'll keep an open mind for additional perspectives. |
| 78/2 | 2026/08/08 15:39 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c",
"FirstLine": 400,
"LineCount": 50
}Results: {
"Contents": " 400:\t\tdma_cap-\u003eeee = (hw_cap \u0026 GMAC_HW_FEAT_EEESEL) \u003e\u003e 13;\n 401:\t\t/* TX and RX csum */\n 402:\t\tdma_cap-\u003etx_coe = (hw_cap \u0026 GMAC_HW_FEAT_TXCOSEL) \u003e\u003e 14;\n 403:\t\tdma_cap-\u003erx_coe = (hw_cap \u0026 GMAC_HW_FEAT_RXCOESEL) \u003e\u003e 16;\n 404:\t\tdma_cap-\u003evlins = (hw_cap \u0026 GMAC_HW_FEAT_SAVLANINS) \u003e\u003e 27;\n 405:\t\tdma_cap-\u003earpoffsel = (hw_cap \u0026 GMAC_HW_FEAT_ARPOFFSEL) \u003e\u003e 9;\n 406:\t\n 407:\t\tdma_cap-\u003eactphyif = FIELD_GET(DMA_HW_FEAT_ACTPHYIF, hw_cap);\n 408:\t\n 409:\t\t/* MAC HW feature1 */\n 410:\t\thw_cap = readl(ioaddr + GMAC_HW_FEATURE1);\n 411:\t\tdma_cap-\u003el3l4fnum = (hw_cap \u0026 GMAC_HW_FEAT_L3L4FNUM) \u003e\u003e 27;\n 412:\t\tdma_cap-\u003ehash_tb_sz = (hw_cap \u0026 GMAC_HW_HASH_TB_SZ) \u003e\u003e 24;\n 413:\t\tdma_cap-\u003eav = (hw_cap \u0026 GMAC_HW_FEAT_AVSEL) \u003e\u003e 20;\n 414:\t\tdma_cap-\u003etsoen = (hw_cap \u0026 GMAC_HW_TSOEN) \u003e\u003e 18;\n 415:\t\tdma_cap-\u003esphen = (hw_cap \u0026 GMAC_HW_FEAT_SPHEN) \u003e\u003e 17;\n 416:\t\tdma_cap-\u003edcben = (hw_cap \u0026 GMAC_HW_FEAT_DCBEN) \u003e\u003e 16;\n 417:\t\n 418:\t\tdma_cap-\u003eaddr64 = (hw_cap \u0026 GMAC_HW_ADDR64) \u003e\u003e 14;\n 419:\t\tswitch (dma_cap-\u003eaddr64) {\n 420:\t\tcase 0:\n 421:\t\t\tdma_cap-\u003eaddr64 = 32;\n 422:\t\t\tbreak;\n 423:\t\tcase 1:\n 424:\t\t\tdma_cap-\u003eaddr64 = 40;\n 425:\t\t\tbreak;\n 426:\t\tcase 2:\n 427:\t\t\tdma_cap-\u003eaddr64 = 48;\n 428:\t\t\tbreak;\n 429:\t\tdefault:\n 430:\t\t\tdma_cap-\u003eaddr64 = 32;\n 431:\t\t\tbreak;\n 432:\t\t}\n 433:\t\n 434:\t\t/* RX and TX FIFO sizes are encoded as log2(n / 128). Undo that by\n 435:\t\t * shifting and store the sizes in bytes.\n 436:\t\t */\n 437:\t\tdma_cap-\u003etx_fifo_size = 128 \u003c\u003c ((hw_cap \u0026 GMAC_HW_TXFIFOSIZE) \u003e\u003e 6);\n 438:\t\tdma_cap-\u003erx_fifo_size = 128 \u003c\u003c ((hw_cap \u0026 GMAC_HW_RXFIFOSIZE) \u003e\u003e 0);\n 439:\t\t/* MAC HW feature2 */\n 440:\t\thw_cap = readl(ioaddr + GMAC_HW_FEATURE2);\n 441:\t\t/* TX and RX number of channels */\n 442:\t\tdma_cap-\u003enumber_rx_channel =\n 443:\t\t\t((hw_cap \u0026 GMAC_HW_FEAT_RXCHCNT) \u003e\u003e 12) + 1;\n 444:\t\tdma_cap-\u003enumber_tx_channel =\n 445:\t\t\t((hw_cap \u0026 GMAC_HW_FEAT_TXCHCNT) \u003e\u003e 18) + 1;\n 446:\t\t/* TX and RX number of queues */\n 447:\t\tdma_cap-\u003enumber_rx_queues =\n 448:\t\t\t((hw_cap \u0026 GMAC_HW_FEAT_RXQCNT) \u003e\u003e 0) + 1;\n 449:\t\tdma_cap-\u003enumber_tx_queues =\n"
} |
| 79/2 | 2026/08/08 15:39 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 90324 output: 21 thoughts: 1181 Thoughts: **Fuzzing Strategy for stmmac Driver's Traffic Control (TC) Offload Features** Okay, so the goal is to evaluate the new Traffic Control (TC) offload features added to the `stmmac` driver, specifically ETS and MQPRIO, and to understand the implications of fuzzing them. Let's break this down. First, it appears that `dma_cap->dcben` is conditionally set based on `GMAC_HW_FEATURE1`. Syzkaller's PCI fuzzer can definitely manipulate `GMAC_HW_FEATURE1`, potentially setting `GMAC_HW_FEAT_DCBEN`. Now, the `stmmac_get_hw_features` function is key. It returns 0 on success, meaning the `priv->hw_cap_support` will be set to 1. If the fuzzer sets the appropriate bit, `priv->dma_cap.dcben` gets set, and that should enable the new TC functionality (`tc_setup_ets` and `tc_setup_dwmac510_mqprio`). I need to determine if QEMU emulates `stmmac`, but it seems like Syzkaller's PCI fuzzer is the most reliable way to trigger this code path. Given `stmmac_pci`'s PCI driver status, Syzkaller should have no problem fuzzing it. The patch modifies `stmmac_tc.c`, `stmmac_main.c`, and `stmmac_fpe.c`. The changes in `stmmac_tc.c` add `tc_setup_ets` and change `tc_setup_dwmac510_mqprio`. The `stmmac_main.c` changes impact functions like `stmmac_set_tx_queue_weight`, `stmmac_mac_config_tx_queues_prio`, `stmmac_mtl_configuration`, `stmmac_hw_setup`, and `stmmac_setup_tc`. The changes in `stmmac_fpe.c` modify `dwmac5_fpe_map_preemption_class`. These are reachable via `tc` netlink commands or during device open/resume, making them viable fuzzing targets. Yes, this is worth fuzzing because it introduces new TC offload features. My next step is to identify the most effective fuzz targets. From the code changes, these functions stand out: * `tc_setup_ets` * `tc_setup_ets_sched` * `tc_setup_ets_destroy` * `stmmac_qdisc_restore_dt_config` * `tc_setup_dwmac510_mqprio` * `stmmac_set_tx_queue_weight` * `stmmac_mac_config_tx_queues_prio` * `dwmac5_fpe_map_preemption_class` * `stmmac_setup_tc` Since I prefer non-static, non-inlined entry points, I need to focus on: `stmmac_set_tx_queue_weight`, `stmmac_mac_config_tx_queues_prio`, `dwmac5_fpe_map_preemption_class` and `stmmac_setup_tc`. These functions are more likely to have distinct symbol addresses and therefore be better fuzzing targets. |
| 80/2 | 2026/08/08 15:39 | tool | grepper |
0mArgs:{
"Expression": "stmmac_setup_tc"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/stmmac_main.c=6404=static int stmmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-6413-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:6414:static int stmmac_setup_tc_block_cb(enum tc_setup_type type, void *type_data,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-6415-\t\t\t\t void *cb_priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=6440=static LIST_HEAD(stmmac_block_cb_list);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-6441-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:6442:static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-6443-\t\t\t void *type_data)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-6461-\t\t\t\t\t\t \u0026stmmac_block_cb_list,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:6462:\t\t\t\t\t\t stmmac_setup_tc_block_cb,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-6463-\t\t\t\t\t\t priv, priv, true);\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=7346=static const struct net_device_ops stmmac_netdev_ops = {\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7357-\t.ndo_get_stats64 = stmmac_get_stats64,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7358:\t.ndo_setup_tc = stmmac_setup_tc,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-7359-\t.ndo_select_queue = stmmac_select_queue,\n"
} |
| 81/2 | 2026/08/08 15:39 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 92946 output: 27 thoughts: 214 Thoughts: **Analyzing the Static Nature of `stmmac_setup_tc` and Identifying Suitable Entry Points** Okay, so `stmmac_setup_tc` is declared as `static`. That's a bit of a wrinkle because it's the `ndo_setup_tc` callback, which implies it's an entry point into the driver. My initial concern is that being static might mean it's not present in the symbol table if the compiler gets clever with renaming or inlining. But hold on, the address of `stmmac_setup_tc` *is* being taken because it's a function pointer (`ndo_setup_tc`). The compiler can't completely inline it in this case; it *must* emit a standalone function with its own address. So, it *should* have a distinct symbol. However, the prompt specifically says we should "Prefer non-static, non-inlined API entrypoint functions". Alright, time to look more closely at the code and identify candidates that fit the bill. Let's see... looking at the patch, I see `stmmac_set_tx_queue_weight`, `stmmac_mac_config_tx_queues_prio`, and `dwmac5_fpe_map_preemption_class`. These *could* be good alternatives, let's start by checking `dwmac5_fpe_map_preemption_class` to see if it's declared as non-static. |
| 82/2 | 2026/08/08 15:39 | tool | grepper |
0mArgs:{
"Expression": "dwmac5_fpe_map_preemption_class"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c=934=const struct stmmac_ops dwmac410_ops = {\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_core.c-968-\t.config_l4_filter = dwmac4_config_l4_filter,\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_core.c:969:\t.fpe_map_preemption_class = dwmac5_fpe_map_preemption_class,\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_core.c-970-};\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_core.c=972=const struct stmmac_ops dwmac510_ops = {\n--\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_core.c-1010-\t.config_l4_filter = dwmac4_config_l4_filter,\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_core.c:1011:\t.fpe_map_preemption_class = dwmac5_fpe_map_preemption_class,\ndrivers/net/ethernet/stmicro/stmmac/dwmac4_core.c-1012-};\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c=189=void stmmac_fpe_set_add_frag_size(struct stmmac_priv *priv, u32 add_frag_size)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c-202-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c:203:int dwmac5_fpe_map_preemption_class(struct net_device *ndev,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c-204-\t\t\t\t struct netlink_ext_ack *extack, u32 pclass)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_fpe.h=18=void stmmac_fpe_set_add_frag_size(struct stmmac_priv *priv, u32 add_frag_size);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_fpe.h-19-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_fpe.h:20:int dwmac5_fpe_map_preemption_class(struct net_device *ndev,\ndrivers/net/ethernet/stmicro/stmmac/stmmac_fpe.h-21-\t\t\t\t struct netlink_ext_ack *extack, u32 pclass);\n"
} |
| 83/2 | 2026/08/08 15:39 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 94245 output: 25 thoughts: 74 Thoughts: Okay, here's my take on those thoughts, framed as my own mental processing: **Analyzing Potential Driver Export Issues** Right, so I've confirmed that `dwmac5_fpe_map_preemption_class` isn't declared static. Good to know. And the same goes for `stmmac_set_tx_queue_weight` and `stmmac_mac_config_tx_queues_prio`. Now, the key question is, are these symbols actually *exported* to the kernel or module space, or are they simply not static within their own compilation unit? That's the critical distinction. If they're not exported, then, while not static, they are not intended for use outside the module. If they *are* exported, that's where we need to delve deeper and understand the reasons behind their non-static nature and usage. |
| 84/2 | 2026/08/08 15:39 | tool | grepper |
0mArgs:{
"Expression": "stmmac_set_tx_queue_weight"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/stmmac.h=403=extern const struct dev_pm_ops stmmac_simple_pm_ops;\ndrivers/net/ethernet/stmicro/stmmac/stmmac.h-404-\ndrivers/net/ethernet/stmicro/stmmac/stmmac.h:405:void stmmac_set_tx_queue_weight(struct stmmac_priv *priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac.h-406-void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv);\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=3400=static void stmmac_set_rings_length(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3417-/**\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3418: * stmmac_set_tx_queue_weight - Set TX queue weight\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3419- * @priv: driver private structure\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3421- */\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3422:void stmmac_set_tx_queue_weight(struct stmmac_priv *priv)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3423-{\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=3572=static void stmmac_mtl_configuration(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3577-\tif (tx_queues_count \u003e 1)\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3578:\t\tstmmac_set_tx_queue_weight(priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-3579-\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c=1216=static void stmmac_qdisc_restore_dt_config(struct stmmac_priv *priv)\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1220-\tnetif_set_real_num_tx_queues(priv-\u003edev, priv-\u003eplat-\u003etx_queues_to_use);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:1221:\tstmmac_set_tx_queue_weight(priv);\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1222-\tstmmac_mac_config_tx_queues_prio(priv);\n"
} |
| 85/2 | 2026/08/08 15:39 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 95354 output: 21 thoughts: 680 Thoughts: **My Thought Process on Symbol Selection**
Okay, so I need to choose the right focus symbols for this analysis, and they need to be non-static where possible. I'm initially thinking:
* `stmmac_set_tx_queue_weight`
* `stmmac_mac_config_tx_queues_prio`
* `dwmac5_fpe_map_preemption_class`
But wait, `tc_setup_ets` and `tc_setup_dwmac510_mqprio` are the *main* functions for the new offloads, even if they're static. And since `stmmac_setup_tc` is the overall entry point for all things `tc` related in this driver, it seems wise to include that as well.
Ah, but the prompt emphasizes preferring non-static, non-inlined entry points. So, I need to be sure. I know static functions can be inlined by the compiler, but sometimes the function address is still taken and assigned in the code. I recall from experience that happens in a lot of TC functions, for example, `tc_setup_ets` in the `dwmac4_tc_ops` structure:
```c
const struct stmmac_tc_ops dwmac4_tc_ops = {
.init = tc_init,
.setup_cls_u32 = tc_setup_cls_u32,
.setup_cls = tc_setup_cls,
.setup_taprio = tc_setup_taprio_without_fpe,
.setup_etf = tc_setup_etf,
.setup_ets = tc_setup_ets,
.query_caps = tc_query_caps,
.setup_mqprio = tc_setup_mqprio_unimplemented,
};
```
Since the address of `tc_setup_ets` is explicitly being taken and stored within `dwmac4_tc_ops`, it won't be completely inlined and should have a distinct symbol address. That means I can include it, same for `tc_setup_dwmac510_mqprio`.
Even though `tc_setup_ets` is static, tools like syzkaller can still correctly identify it as long as I provide the static function name, which might be something like `tc_setup_ets.isra.0`. It should still work.
So, taking all this into consideration, I will include:
* `stmmac_setup_tc` (the primary entry point)
* `tc_setup_ets`
* `tc_setup_dwmac510_mqprio`
* `stmmac_set_tx_queue_weight`
* `stmmac_mac_config_tx_queues_prio`
* `dwmac5_fpe_map_preemption_class`
Finally, before submitting, I should verify the required configs. I'm pretty sure `CONFIG_STMMAC_ETH` will be the main one. I need to make sure I am not missing any others that could be needed. Since the change is in `stmmac_tc.c`, I'll check if that file's compilation is conditional.
|
| 86/2 | 2026/08/08 15:39 | tool | grepper |
0mArgs:{
"Expression": "stmmac_tc.o"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/Makefile=3=stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o\t\\\n--\ndrivers/net/ethernet/stmicro/stmmac/Makefile-7-\t dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \\\ndrivers/net/ethernet/stmicro/stmmac/Makefile:8:\t stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o dwxgmac2_descs.o \\\ndrivers/net/ethernet/stmicro/stmmac/Makefile-9-\t stmmac_xdp.o stmmac_est.o stmmac_fpe.o stmmac_vlan.o \\\n--\ndrivers/net/ethernet/stmicro/stmmac/common.h=613=struct mac_device_info {\n--\ndrivers/net/ethernet/stmicro/stmmac/common.h-618-\tconst struct stmmac_hwtimestamp *ptp;\ndrivers/net/ethernet/stmicro/stmmac/common.h:619:\tconst struct stmmac_tc_ops *tc;\ndrivers/net/ethernet/stmicro/stmmac/common.h-620-\tconst struct stmmac_mmc_ops *mmc;\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.h=569=struct tc_query_caps_base;\ndrivers/net/ethernet/stmicro/stmmac/hwif.h-570-\ndrivers/net/ethernet/stmicro/stmmac/hwif.h:571:struct stmmac_tc_ops {\ndrivers/net/ethernet/stmicro/stmmac/hwif.h-572-\tint (*init)(struct stmmac_priv *priv);\n--\ndrivers/net/ethernet/stmicro/stmmac/hwif.h=694=extern const struct stmmac_ops dwmac510_ops;\ndrivers/net/ethernet/stmicro/stmmac/hwif.h:695:extern const struct stmmac_tc_ops dwmac4_tc_ops;\ndrivers/net/ethernet/stmicro/stmmac/hwif.h:696:extern const struct stmmac_tc_ops dwmac510_tc_ops;\ndrivers/net/ethernet/stmicro/stmmac/hwif.h-697-\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c=1449=static int tc_setup_mqprio_unimplemented(struct stmmac_priv *priv,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1456-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:1457:const struct stmmac_tc_ops dwmac4_tc_ops = {\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1458-\t.init = tc_init,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1468-\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:1469:const struct stmmac_tc_ops dwmac510_tc_ops = {\ndrivers/net/ethernet/stmicro/stmmac/stmmac_tc.c-1470-\t.init = tc_init,\n"
} |
| 87/2 | 2026/08/08 15:39 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 97719 output: 23 thoughts: 76 Thoughts: **Investigating the STM32 MAC Driver Configuration** Okay, so the `stmmac` Ethernet driver gets compiled automatically when `CONFIG_STMMAC_ETH` is flipped on. That's straightforward enough, but I'm digging deeper into its traffic control (tc) offload capabilities. I need to make sure I've got all the ducks in a row for proper functionality. My immediate question is, beyond the base driver configuration, are there any *other* configuration options I should be mindful of for `tc` offloading to be fully functional? I'm thinking specifically about things like `CONFIG_NET_SCH_MQPRIO` and `CONFIG_NET_SCH_ETS`. Are these dependencies, or are they implicitly handled? To be certain, I should verify that `TC_SETUP_QDISC_ETS` is defined without any conditionality. This would give me a clear indication of whether or not ETS is essential for the setup to work. I need a clear picture of the conditional compilation paths here. |
| 88/2 | 2026/08/08 15:40 | tool | grepper |
0mArgs:{
"Expression": "TC_SETUP_QDISC_ETS"
}Results: {
"Output": "drivers/net/dsa/microchip/ksz8.c=326=static int ksz8_port_queue_split(struct ksz_device *dev, int port, int queues)\n--\ndrivers/net/dsa/microchip/ksz8.c-342-\t\t * too. Default value for KSZ8873 family is strict priority,\ndrivers/net/dsa/microchip/ksz8.c:343:\t\t * which should be enabled by using TC_SETUP_QDISC_ETS, not\ndrivers/net/dsa/microchip/ksz8.c-344-\t\t * by default.\n--\ndrivers/net/dsa/microchip/ksz8.c=1999=static int ksz8_setup_tc(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/microchip/ksz8.c-2004-\t\treturn ksz_setup_tc_cbs(ds, port, type_data);\ndrivers/net/dsa/microchip/ksz8.c:2005:\tcase TC_SETUP_QDISC_ETS:\ndrivers/net/dsa/microchip/ksz8.c-2006-\t\treturn ksz8_tc_setup_qdisc_ets(ds, port, type_data);\n--\ndrivers/net/dsa/microchip/ksz_common.c=3280=int ksz_setup_tc(struct dsa_switch *ds, int port,\n--\ndrivers/net/dsa/microchip/ksz_common.c-3285-\t\treturn ksz_setup_tc_cbs(ds, port, type_data);\ndrivers/net/dsa/microchip/ksz_common.c:3286:\tcase TC_SETUP_QDISC_ETS:\ndrivers/net/dsa/microchip/ksz_common.c-3287-\t\treturn ksz_tc_setup_qdisc_ets(ds, port, type_data);\n--\ndrivers/net/ethernet/airoha/airoha_eth.c=3324=static int airoha_dev_tc_setup(struct net_device *dev,\n--\ndrivers/net/ethernet/airoha/airoha_eth.c-3327-\tswitch (type) {\ndrivers/net/ethernet/airoha/airoha_eth.c:3328:\tcase TC_SETUP_QDISC_ETS:\ndrivers/net/ethernet/airoha/airoha_eth.c-3329-\t\treturn airoha_tc_setup_qdisc_ets(dev, type_data);\n--\ndrivers/net/ethernet/mellanox/mlxsw/spectrum.c=1057=static int mlxsw_sp_setup_tc(struct net_device *dev, enum tc_setup_type type,\n--\ndrivers/net/ethernet/mellanox/mlxsw/spectrum.c-1068-\t\treturn mlxsw_sp_setup_tc_prio(mlxsw_sp_port, type_data);\ndrivers/net/ethernet/mellanox/mlxsw/spectrum.c:1069:\tcase TC_SETUP_QDISC_ETS:\ndrivers/net/ethernet/mellanox/mlxsw/spectrum.c-1070-\t\treturn mlxsw_sp_setup_tc_ets(mlxsw_sp_port, type_data);\n--\ndrivers/net/ethernet/microchip/lan966x/lan966x_tc.c=119=int lan966x_tc_setup(struct net_device *dev, enum tc_setup_type type,\n--\ndrivers/net/ethernet/microchip/lan966x/lan966x_tc.c-132-\t\treturn lan966x_tc_setup_qdisc_cbs(port, type_data);\ndrivers/net/ethernet/microchip/lan966x/lan966x_tc.c:133:\tcase TC_SETUP_QDISC_ETS:\ndrivers/net/ethernet/microchip/lan966x/lan966x_tc.c-134-\t\treturn lan966x_tc_setup_qdisc_ets(port, type_data);\n--\ndrivers/net/ethernet/microchip/sparx5/sparx5_tc.c=157=int sparx5_port_setup_tc(struct net_device *ndev, enum tc_setup_type type,\n--\ndrivers/net/ethernet/microchip/sparx5/sparx5_tc.c-166-\t\treturn sparx5_tc_setup_qdisc_tbf(ndev, type_data);\ndrivers/net/ethernet/microchip/sparx5/sparx5_tc.c:167:\tcase TC_SETUP_QDISC_ETS:\ndrivers/net/ethernet/microchip/sparx5/sparx5_tc.c-168-\t\treturn sparx5_tc_setup_qdisc_ets(ndev, type_data);\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c=6442=static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,\n--\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-6473-\t\tbreak;\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c:6474:\tcase TC_SETUP_QDISC_ETS:\ndrivers/net/ethernet/stmicro/stmmac/stmmac_main.c-6475-\t\tret = stmmac_tc_setup_ets(priv, priv, type_data);\n--\ndrivers/net/netdevsim/tc.c=77=nsim_setup_tc(struct net_device *dev, enum tc_setup_type type, void *type_data)\n--\ndrivers/net/netdevsim/tc.c-83-\t\treturn nsim_setup_tc_taprio(dev, type_data);\ndrivers/net/netdevsim/tc.c:84:\tcase TC_SETUP_QDISC_ETS:\ndrivers/net/netdevsim/tc.c-85-\t\treturn nsim_setup_tc_ets(dev, type_data);\n--\ninclude/linux/netdevice.h=952=enum tc_setup_type {\n--\ninclude/linux/netdevice.h-968-\tTC_SETUP_FT,\ninclude/linux/netdevice.h:969:\tTC_SETUP_QDISC_ETS,\ninclude/linux/netdevice.h-970-\tTC_SETUP_QDISC_TBF,\n--\nnet/sched/sch_ets.c=112=static void ets_offload_change(struct Qdisc *sch)\n--\nnet/sched/sch_ets.c-153-\nnet/sched/sch_ets.c:154:\tdev-\u003enetdev_ops-\u003endo_setup_tc(dev, TC_SETUP_QDISC_ETS, \u0026qopt);\nnet/sched/sch_ets.c-155-}\n--\nnet/sched/sch_ets.c=157=static void ets_offload_destroy(struct Qdisc *sch)\n--\nnet/sched/sch_ets.c-167-\tqopt.parent = sch-\u003eparent;\nnet/sched/sch_ets.c:168:\tdev-\u003enetdev_ops-\u003endo_setup_tc(dev, TC_SETUP_QDISC_ETS, \u0026qopt);\nnet/sched/sch_ets.c-169-}\n--\nnet/sched/sch_ets.c=171=static void ets_offload_graft(struct Qdisc *sch, struct Qdisc *new,\n--\nnet/sched/sch_ets.c-183-\nnet/sched/sch_ets.c:184:\tqdisc_offload_graft_helper(dev, sch, new, old, TC_SETUP_QDISC_ETS,\nnet/sched/sch_ets.c-185-\t\t\t\t \u0026qopt, extack);\n--\nnet/sched/sch_ets.c=188=static int ets_offload_dump(struct Qdisc *sch)\n--\nnet/sched/sch_ets.c-197-\nnet/sched/sch_ets.c:198:\treturn qdisc_offload_dump_helper(sch, TC_SETUP_QDISC_ETS, \u0026qopt);\nnet/sched/sch_ets.c-199-}\n"
} |
| 89/2 | 2026/08/08 15:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 100161 output: 20 thoughts: 119 Thoughts: **Investigating ETS and MQPRIO Qdisc Offload Configuration** Okay, so I'm digging into this ETS qdisc offload, and the first thing I see is `TC_SETUP_QDISC_ETS` is defined in `include/linux/netdevice.h`. That makes sense. Looking at the code usage, `net/sched/sch_ets.c` is where it's being used. So, if I'm understanding this correctly, to even *use* the ETS qdisc and trigger the offload, I'm going to need `CONFIG_NET_SCH_ETS` enabled in the kernel config. And, of course, MQPRIO is in the mix as well; looks like `CONFIG_NET_SCH_MQPRIO` is necessary for that offload. Just to be absolutely sure, I'll double-check that `CONFIG_NET_SCH_ETS` and `CONFIG_NET_SCH_MQPRIO` are indeed the correct config names, just to avoid any missteps later on. Gotta be certain I'm using the right symbols. |
| 90/2 | 2026/08/08 15:40 | tool | grepper |
0mArgs:{
"Expression": "config NET_SCH_ETS"
}Results: {
"Output": "net/sched/Kconfig=363=config NET_SCH_PLUG\n--\nnet/sched/Kconfig-388-\nnet/sched/Kconfig:389:config NET_SCH_ETS\nnet/sched/Kconfig-390-\ttristate \"Enhanced transmission selection scheduler (ETS)\"\n"
} |
| 91/2 | 2026/08/08 15:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 100622 output: 22 thoughts: 2 Thoughts: Okay, here's the summary, assuming "Yes" is the complete text and I'm an expert in whatever field it implicitly touches upon: **Affirmation and Immediate Understanding** Right, that's it. *Yes*. The simplicity of it is almost elegant. It's a concise encapsulation of... well, whatever context this is referring to, I already understand it. There's no need for further explanation or elaboration. The implied agreement or confirmation resonates perfectly with my established knowledge and expertise. This single word serves as a conclusive evaluation. It's an unambiguous affirmation. |
| 92/2 | 2026/08/08 15:40 | tool | grepper |
0mArgs:{
"Expression": "config NET_SCH_MQPRIO"
}Results: {
"Output": "net/sched/Kconfig=156=config NET_SCH_ETF\n--\nnet/sched/Kconfig-166-\nnet/sched/Kconfig:167:config NET_SCH_MQPRIO_LIB\nnet/sched/Kconfig-168-\ttristate\n--\nnet/sched/Kconfig=207=config NET_SCH_DRR\n--\nnet/sched/Kconfig-217-\nnet/sched/Kconfig:218:config NET_SCH_MQPRIO\nnet/sched/Kconfig-219-\ttristate \"Multi-queue priority scheduler (MQPRIO)\"\n"
} |
| 93/2 | 2026/08/08 15:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 100932 output: 20 thoughts: 76 Thoughts: Okay, here's my interpretation of those thoughts, phrased as if they're my own: **Configuring the Ethernet Driver** Right, that seems straightforward enough. It looks like I need to ensure these configurations are enabled: `STMMAC_ETH`, `NET_SCH_ETS`, and `NET_SCH_MQPRIO`. Hang on a second… I think I remember seeing something about `stmmac_pci` being compiled in when I enable `CONFIG_STMMAC_ETH`. But is `stmmac_pci` a separate configuration option in itself? Need to check the details there, to make sure I don't overlook a critical dependent config. |
| 94/2 | 2026/08/08 15:40 | tool | grepper |
0mArgs:{
"Expression": "config STMMAC_PCI"
}Results: {
"Output": "drivers/net/ethernet/stmicro/stmmac/Kconfig=398=config DWMAC_MOTORCOMM\n--\ndrivers/net/ethernet/stmicro/stmmac/Kconfig-406-\ndrivers/net/ethernet/stmicro/stmmac/Kconfig:407:config STMMAC_PCI\ndrivers/net/ethernet/stmicro/stmmac/Kconfig-408-\ttristate \"STMMAC PCI bus support\"\n"
} |
| 95/2 | 2026/08/08 15:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 101302 output: 44 thoughts: 37 Thoughts: Okay, here's my take on those thoughts, tailored for an expert audience: **Diving into the STMMAC Configuration** Right, so `STMMAC_PCI` appears to be a distinct configuration option. It's not just a flag buried within something else. Time to get down to brass tacks and inspect the Kconfig file for the STMMAC driver. I need to understand exactly how this feature is defined, what dependencies it might have, and what other settings it interacts with. This is likely where the magic happens, and understanding this Kconfig structure is crucial to seeing how the PCI variant fits into the bigger STMMAC picture. This will also show me if there are any specific PCI-related dependencies or constraints that are defined in this configuration file. From there, I'll be able to decide how best to interact with it. |
| 96/2 | 2026/08/08 15:40 | tool | read-file |
0mArgs:{
"File": "drivers/net/ethernet/stmicro/stmmac/Kconfig",
"FirstLine": 407,
"LineCount": 20
}Results: {
"Contents": " 407:\tconfig STMMAC_PCI\n 408:\t\ttristate \"STMMAC PCI bus support\"\n 409:\t\tdepends on PCI\n 410:\t\tdepends on COMMON_CLK\n 411:\t\tselect STMMAC_LIBPCI\n 412:\t\thelp\n 413:\t\t This selects the platform specific bus support for the stmmac driver.\n 414:\t\t This driver was tested on XLINX XC2V3000 FF1152AMT0221\n 415:\t\t D1215994A VIRTEX FPGA board and SNPS QoS IPK Prototyping Kit.\n 416:\t\n 417:\t\t If you have a controller with this interface, say Y or M here.\n 418:\t\n 419:\t\t If unsure, say N.\n 420:\tendif # STMMAC_ETH\n"
} |
| 97/2 | 2026/08/08 15:40 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 101803 output: 229 thoughts: 1461 Thoughts: **My Analysis of STMMAC Driver Fuzzing Configuration** Okay, so I need to configure syzkaller to effectively fuzz the stmmac driver's new ETS and MQPRIO offload functionality. First things first, I need to ensure the correct configuration options are enabled to make the driver accessible. Clearly, `STMMAC_PCI` is essential for the PCI probing, which is the most reliable method for syzkaller to interact with the driver. I confirmed that `STMMAC_PCI` depends on `STMMAC_ETH`, so both must be enabled. I'll also enable `NET_SCH_ETS` and `NET_SCH_MQPRIO` for the specific features I'm targeting. I double-checked; while platform devices are *possible* to fuzz, PCI is the easiest method. So, `STMMAC_PCI` it is. And no, it does *not* require a `DWMAC_INTEL` or other similar option; probing by PCI ID using the stmmac_pci wrapper and ID 0x1108 will be sufficient. Now, on to the focus symbols. I carefully reviewed the available functions. The prompt states a preference for non-static, non-inlined entry points. Originally, I identified `stmmac_setup_tc`, `tc_setup_ets`, `tc_setup_dwmac510_mqprio`, `stmmac_set_tx_queue_weight`, `stmmac_mac_config_tx_queues_prio`, and `dwmac5_fpe_map_preemption_class` as potential targets. However, `tc_setup_ets` and `tc_setup_dwmac510_mqprio` are static functions assigned to function pointers and they will not be inlined. I determined that these will work for what syzkaller will search for. I've ensured these are the exact names by confirming the function signatures. I'm reasonably confident in this selection: * `stmmac_setup_tc` * `tc_setup_ets` * `tc_setup_dwmac510_mqprio` * `stmmac_set_tx_queue_weight` * `stmmac_mac_config_tx_queues_prio` * `dwmac5_fpe_map_preemption_class` I checked for other relevant functions but believe this set should be sufficient. I also verified the main entry point is `stmmac_setup_tc` and that the other functions are called from `stmmac_mtl_configuration`, `stmmac_hw_setup`, `stmmac_open`, and `stmmac_resume`, which ensures they get hit. Syzkaller should be able to cover the new offload paths by probing via PCI and interacting with the registered netdev via `tc` netlink commands. Therefore, the "WorthFuzzing" flag is set to true. My final configuration for syzkaller is: **FocusSymbols:** - stmmac_setup_tc - tc_setup_ets - tc_setup_dwmac510_mqprio - stmmac_set_tx_queue_weight - stmmac_mac_config_tx_queues_prio - dwmac5_fpe_map_preemption_class **EnableConfigs:** - STMMAC_ETH - STMMAC_PCI - NET_SCH_ETS - NET_SCH_MQPRIO I'm confident this setup will effectively focus syzkaller on the key parts of this driver, and expose new bugs. |
| 98/2 | 2026/08/08 15:40 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"STMMAC_ETH",
"STMMAC_PCI",
"NET_SCH_ETS",
"NET_SCH_MQPRIO"
],
"FocusSymbols": [
"stmmac_setup_tc",
"tc_setup_ets",
"tc_setup_dwmac510_mqprio",
"stmmac_set_tx_queue_weight",
"stmmac_mac_config_tx_queues_prio",
"dwmac5_fpe_map_preemption_class"
],
"Reasoning": "The patch adds support for ETS (Enhanced Transmission Selection) and MQPRIO qdisc offloads to the stmmac driver. This involves modifying the tc setup callbacks and queue configuration logic. The driver can be probed via the stmmac_pci wrapper using syzkaller's PCI fuzzer, and the new offload paths can be reached by sending tc netlink commands to the registered netdev.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"STMMAC_ETH",
"STMMAC_PCI",
"NET_SCH_ETS",
"NET_SCH_MQPRIO"
],
"FocusSymbols": [
"stmmac_setup_tc",
"tc_setup_ets",
"tc_setup_dwmac510_mqprio",
"stmmac_set_tx_queue_weight",
"stmmac_mac_config_tx_queues_prio",
"dwmac5_fpe_map_preemption_class"
],
"Reasoning": "The patch adds support for ETS (Enhanced Transmission Selection) and MQPRIO qdisc offloads to the stmmac driver. This involves modifying the tc setup callbacks and queue configuration logic. The driver can be probed via the stmmac_pci wrapper using syzkaller's PCI fuzzer, and the new offload paths can be reached by sending tc netlink commands to the registered netdev.",
"WorthFuzzing": true
} |
| 99/1 | 2026/08/08 15:40 | action | If |
0mArgs:{
"WorthFuzzing": true
}Results: null |
| 100/2 | 2026/08/08 15:40 | agent | kmsan-evaluator |
0mModel:best-expensive Args: null Results: {
"KMSANReasoning": "The patch adds hardware offload support for ETS (Enhanced Transmission Selection) and MQPRIO in the stmmac driver. It introduces a new `qdisc` structure within the driver's private data (`struct stmmac_priv`) to store the configuration and modifies the queue setup functions to apply these settings to the hardware. The private data structure is zero-initialized upon allocation by the networking core (`alloc_netdev_mqs` uses `kvzalloc`). The offload parameters (`struct tc_ets_qopt_offload`, `struct tc_mqprio_qopt_offload`) are provided by the kernel's qdisc subsystem and are only read by the driver to configure the hardware; no data is copied back to userspace. There are no new allocations of complex data structures or uninitialized buffers that could lead to information leaks or uninitialized memory use. Any potential bugs introduced by this patch, such as out-of-bounds array accesses or use-after-free, would be effectively caught by standard KASAN and other default debugging tools. Therefore, a dedicated KMSAN fuzzing session is not required.",
"NeedsKMSAN": false
}Instruction: You are an expert Linux kernel security engineer specializing in kernel memory
error detectors (KASAN and KMSAN). Your job is to review the provided patch series and
determine if the code changes justify spawning a dedicated KMSAN (KernelMemorySanitizer)
fuzzing session in addition to standard KASAN fuzzing.
CRITICAL DISTINCTION BETWEEN KASAN AND KMSAN:
- Standard KASAN kernel builds (upstream-apparmor-kasan.config) already enable
a comprehensive suite of debugging tools and sanitizers, including KASAN
(out-of-bounds accesses, use-after-free, double free, invalid free), LOCKDEP
(locking bugs and deadlocks), UB-sanitizers, and memory corruption checks.
- KMSAN (KernelMemorySanitizer) detects reads of UNINITIALIZED memory (stack, heap,
or page allocations) and kernel-to-user memory info-leaks.
Rule: THERE IS NO SENSE IN RUNNING A KMSAN SESSION IF A BUG CAN BE CAUGHT BY KASAN,
LOCKDEP, OR OTHER STANDARD BUG DETECTORS.
A dedicated KMSAN fuzzing session incurs significant resource costs. You must ONLY
set NeedsKMSAN=true if the code changes introduce or expose UNINITIALIZED MEMORY risks
that are detected ONLY by KMSAN.
Look holistically at the patch series and surrounding code. Even if no direct
uninitialized field accesses or new buffer allocations are added in the diff itself,
a patch may alter control flow, bounds checking, or data length calculations in ways
that change how the rest of the code operates on existing buffers (e.g. allowing
uninitialized stack/heap memory to be read, copied to user space, or used in control
flow). Do not hesitate to use your code access tools to inspect the surrounding code,
called functions, and callers.
Set NeedsKMSAN=true ONLY IF the patch introduces or modifies:
1. Kernel structures sent to user space (via copy_to_user, put_user, netlink skb
attributes, ioctl output arguments, socket options, or BPF buffers) where fields
or structure padding might not be fully initialized/zeroed.
2. Conditional logic or branching that depends on potentially uninitialized variables
or struct fields.
3. Allocation or initialization of complex data structures where uninitialized fields
could be read later in reachable code paths.
4. Bounds checks, lengths, or logic in a way that allows surrounding code to access
uninitialized bytes of existing buffers.
Set NeedsKMSAN=false IF:
- The code changes primarily risk out-of-bounds access, array overflows, NULL pointer
dereferences, locking deadlocks, or use-after-free bugs (these are already caught
by KASAN, LOCKDEP, or standard bug detectors).
- All stack/heap structures touched or introduced by the patch are fully zeroed
or initialized (e.g. using = {0}, memset, kzalloc) before being read or copied.
- The patch does not introduce any risk of uninitialized memory usage or info-leaks.
Use your code access tools to inspect the surrounding code if necessary, then provide
detailed KMSANReasoning contrasting KASAN vs KMSAN applicability for this patch.
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 222c434c8acd601577a64983289d41de3bcbe278
Author: syz-cluster <triage@syzkaller.com>
Date: Sat Aug 8 14:56:44 2026 +0000
syz-cluster: applied patch under review
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index 04dafec021b4f..b70883a53b09a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -580,6 +580,8 @@ struct stmmac_tc_ops {
struct tc_taprio_qopt_offload *qopt);
int (*setup_etf)(struct stmmac_priv *priv,
struct tc_etf_qopt_offload *qopt);
+ int (*setup_ets)(struct stmmac_priv *priv,
+ struct tc_ets_qopt_offload *qopt);
int (*query_caps)(struct stmmac_priv *priv,
struct tc_query_caps_base *base);
int (*setup_mqprio)(struct stmmac_priv *priv,
@@ -598,6 +600,8 @@ struct stmmac_tc_ops {
stmmac_do_callback(__priv, tc, setup_taprio, __args)
#define stmmac_tc_setup_etf(__priv, __args...) \
stmmac_do_callback(__priv, tc, setup_etf, __args)
+#define stmmac_tc_setup_ets(__priv, __args...) \
+ stmmac_do_callback(__priv, tc, setup_ets, __args)
#define stmmac_tc_query_caps(__priv, __args...) \
stmmac_do_callback(__priv, tc, query_caps, __args)
#define stmmac_tc_setup_mqprio(__priv, __args...) \
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 8ba8f03e1ce03..1967279a4cccc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -301,6 +301,14 @@ struct stmmac_priv {
/* Protect est parameters */
struct mutex est_lock;
struct stmmac_est *est;
+ struct {
+ bool enable;
+ u8 algo;
+ u8 bands;
+ u32 handle;
+ u32 quanta[MTL_MAX_TX_QUEUES];
+ u32 prio[MTL_MAX_TX_QUEUES];
+ } qdisc;
struct dma_features dma_cap;
struct stmmac_counters mmc;
int hw_cap_support;
@@ -394,6 +402,8 @@ enum stmmac_state {
extern const struct dev_pm_ops stmmac_simple_pm_ops;
+void stmmac_set_tx_queue_weight(struct stmmac_priv *priv);
+void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv);
int stmmac_mdio_unregister(struct net_device *ndev);
int stmmac_mdio_register(struct net_device *ndev);
int stmmac_mdio_reset(struct mii_bus *mii);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
index c54c702243517..d84b6fdc01b3a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_fpe.c
@@ -205,7 +205,10 @@ int dwmac5_fpe_map_preemption_class(struct net_device *ndev,
{
u32 val, offset, count, queue_weight, preemptible_txqs = 0;
struct stmmac_priv *priv = netdev_priv(ndev);
+ struct plat_stmmacenet_data *pdata = priv->plat;
int num_tc = netdev_get_num_tc(ndev);
+ u32 sched_algo;
+ bool ets;
if (!pclass)
goto update_mapping;
@@ -216,6 +219,11 @@ int dwmac5_fpe_map_preemption_class(struct net_device *ndev,
* "The number of Tx DMA channels is equal to the number of Tx queues,
* and is direct one-to-one mapping."
*/
+
+ sched_algo = priv->qdisc.enable ? priv->qdisc.algo
+ : pdata->tx_sched_algorithm;
+ ets = priv->qdisc.enable && sched_algo == MTL_TX_ALGORITHM_DWRR;
+
for (u32 tc = 0; tc < num_tc; tc++) {
count = ndev->tc_to_txq[tc].count;
offset = ndev->tc_to_txq[tc].offset;
@@ -227,16 +235,20 @@ int dwmac5_fpe_map_preemption_class(struct net_device *ndev,
if (count == 1)
continue;
- if (priv->plat->tx_sched_algorithm == MTL_TX_ALGORITHM_SP) {
+ if (sched_algo == MTL_TX_ALGORITHM_SP) {
NL_SET_ERR_MSG_MOD(extack, ALG_ERR_MSG);
return -EINVAL;
}
- queue_weight = priv->plat->tx_queues_cfg[offset].weight;
+ queue_weight = ets ? priv->qdisc.quanta[offset]
+ : pdata->tx_queues_cfg[offset].weight;
for (u32 i = 1; i < count; i++) {
- if (priv->plat->tx_queues_cfg[offset + i].weight !=
- queue_weight) {
+ u32 weight;
+
+ weight = ets ? priv->qdisc.quanta[offset + i]
+ : pdata->tx_queues_cfg[offset + i].weight;
+ if (weight != queue_weight) {
NL_SET_ERR_MSG_FMT_MOD(extack, WEIGHT_ERR_MSG,
queue_weight, tc);
return -EINVAL;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index b2b7d0242dd3c..5aee03ebe1312 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3419,14 +3419,22 @@ static void stmmac_set_rings_length(struct stmmac_priv *priv)
* @priv: driver private structure
* Description: It is used for setting TX queues weight
*/
-static void stmmac_set_tx_queue_weight(struct stmmac_priv *priv)
+void stmmac_set_tx_queue_weight(struct stmmac_priv *priv)
{
- u8 tx_queues_count = priv->plat->tx_queues_to_use;
+ struct plat_stmmacenet_data *pdata = priv->plat;
+ u8 tx_queues_count = pdata->tx_queues_to_use;
u32 weight;
u8 queue;
for (queue = 0; queue < tx_queues_count; queue++) {
- weight = priv->plat->tx_queues_cfg[queue].weight;
+ if (pdata->tx_queues_cfg[queue].mode_to_use == MTL_QUEUE_AVB)
+ continue;
+
+ if (priv->qdisc.enable &&
+ priv->qdisc.algo == MTL_TX_ALGORITHM_DWRR)
+ weight = priv->qdisc.quanta[queue];
+ else
+ weight = pdata->tx_queues_cfg[queue].weight;
stmmac_set_mtl_tx_queue_weight(priv, priv->hw, weight, queue);
}
}
@@ -3499,18 +3507,23 @@ static void stmmac_mac_config_rx_queues_prio(struct stmmac_priv *priv)
* @priv: driver private structure
* Description: It is used for configuring the TX Queue Priority
*/
-static void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv)
+void stmmac_mac_config_tx_queues_prio(struct stmmac_priv *priv)
{
u8 tx_queues_count = priv->plat->tx_queues_to_use;
u8 queue;
- u32 prio;
for (queue = 0; queue < tx_queues_count; queue++) {
- if (!priv->plat->tx_queues_cfg[queue].use_prio)
+ if (priv->qdisc.enable &&
+ priv->qdisc.algo == MTL_TX_ALGORITHM_SP) {
+ stmmac_tx_queue_prio(priv, priv->hw,
+ priv->qdisc.prio[queue], queue);
continue;
+ }
- prio = priv->plat->tx_queues_cfg[queue].prio;
- stmmac_tx_queue_prio(priv, priv->hw, prio, queue);
+ if (priv->plat->tx_queues_cfg[queue].use_prio)
+ stmmac_tx_queue_prio(priv, priv->hw,
+ priv->plat->tx_queues_cfg[queue].prio,
+ queue);
}
}
@@ -3570,9 +3583,15 @@ static void stmmac_mtl_configuration(struct stmmac_priv *priv)
priv->plat->rx_sched_algorithm);
/* Configure MTL TX algorithms */
- if (tx_queues_count > 1)
- stmmac_prog_mtl_tx_algorithms(priv, priv->hw,
- priv->plat->tx_sched_algorithm);
+ if (tx_queues_count > 1) {
+ u8 tx_sched_algo;
+
+ if (priv->qdisc.enable)
+ tx_sched_algo = priv->qdisc.algo;
+ else
+ tx_sched_algo = priv->plat->tx_sched_algorithm;
+ stmmac_prog_mtl_tx_algorithms(priv, priv->hw, tx_sched_algo);
+ }
/* Configure CBS in AVB TX queues */
if (tx_queues_count > 1)
@@ -3738,7 +3757,11 @@ static int stmmac_hw_setup(struct net_device *dev)
/* Configure real RX and TX queues */
netif_set_real_num_rx_queues(dev, priv->plat->rx_queues_to_use);
- netif_set_real_num_tx_queues(dev, priv->plat->tx_queues_to_use);
+ if (priv->qdisc.enable && priv->qdisc.algo == MTL_TX_ALGORITHM_DWRR)
+ netif_set_real_num_tx_queues(dev, priv->qdisc.bands);
+ else
+ netif_set_real_num_tx_queues(dev,
+ priv->plat->tx_queues_to_use);
/* Start the ball rolling... */
stmmac_start_all_dma(priv);
@@ -6420,26 +6443,45 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,
void *type_data)
{
struct stmmac_priv *priv = netdev_priv(ndev);
+ int ret;
+
+ ret = pm_runtime_resume_and_get(priv->device);
+ if (ret < 0)
+ return ret;
switch (type) {
case TC_QUERY_CAPS:
- return stmmac_tc_query_caps(priv, priv, type_data);
+ ret = stmmac_tc_query_caps(priv, priv, type_data);
+ break;
case TC_SETUP_QDISC_MQPRIO:
- return stmmac_tc_setup_mqprio(priv, priv, type_data);
+ ret = stmmac_tc_setup_mqprio(priv, priv, type_data);
+ break;
case TC_SETUP_BLOCK:
- return flow_block_cb_setup_simple(type_data,
- &stmmac_block_cb_list,
- stmmac_setup_tc_block_cb,
- priv, priv, true);
+ ret = flow_block_cb_setup_simple(type_data,
+ &stmmac_block_cb_list,
+ stmmac_setup_tc_block_cb,
+ priv, priv, true);
+ break;
case TC_SETUP_QDISC_CBS:
- return stmmac_tc_setup_cbs(priv, priv, type_data);
+ ret = stmmac_tc_setup_cbs(priv, priv, type_data);
+ break;
case TC_SETUP_QDISC_TAPRIO:
- return stmmac_tc_setup_taprio(priv, priv, type_data);
+ ret = stmmac_tc_setup_taprio(priv, priv, type_data);
+ break;
case TC_SETUP_QDISC_ETF:
- return stmmac_tc_setup_etf(priv, priv, type_data);
+ ret = stmmac_tc_setup_etf(priv, priv, type_data);
+ break;
+ case TC_SETUP_QDISC_ETS:
+ ret = stmmac_tc_setup_ets(priv, priv, type_data);
+ break;
default:
- return -EOPNOTSUPP;
+ ret = -EOPNOTSUPP;
+ break;
}
+
+ pm_runtime_put(priv->device);
+
+ return ret;
}
static u16 stmmac_select_queue(struct net_device *dev, struct sk_buff *skb,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
index 14cabe76e53ec..336350d6786b3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c
@@ -1210,6 +1210,109 @@ static int tc_setup_etf(struct stmmac_priv *priv,
return 0;
}
+/* Max quantum value supported by the MTL DWRR scheduler */
+#define MTL_TXQ_WEIGHT_QUANTUM_MAX 0x1312d0
+
+static void stmmac_qdisc_restore_dt_config(struct stmmac_priv *priv)
+{
+ /* reset to the dt configured algorithm. */
+ priv->qdisc.enable = false;
+ netif_set_real_num_tx_queues(priv->dev, priv->plat->tx_queues_to_use);
+ stmmac_set_tx_queue_weight(priv);
+ stmmac_mac_config_tx_queues_prio(priv);
+ stmmac_prog_mtl_tx_algorithms(priv, priv->hw,
+ priv->plat->tx_sched_algorithm);
+}
+
+static int tc_setup_ets_sched(struct stmmac_priv *priv,
+ struct tc_ets_qopt_offload *qopt)
+{
+ struct tc_ets_qopt_offload_replace_params *p = &qopt->replace_params;
+ struct plat_stmmacenet_data *pdata = priv->plat;
+ int err, i;
+
+ if (!priv->dma_cap.dcben)
+ return -EOPNOTSUPP;
+
+ if (qopt->parent != TC_H_ROOT)
+ return -EOPNOTSUPP;
+
+ if (p->bands > pdata->tx_queues_to_use)
+ return -EOPNOTSUPP;
+
+ for (i = 0; i < pdata->tx_queues_to_use; i++) {
+ if (pdata->tx_queues_cfg[i].mode_to_use == MTL_QUEUE_AVB)
+ return -EOPNOTSUPP;
+ }
+
+ for (i = 0; i < p->bands; i++) {
+ if (!p->quanta[i])
+ return -EOPNOTSUPP;
+
+ if (p->quanta[i] > MTL_TXQ_WEIGHT_QUANTUM_MAX)
+ return -EOPNOTSUPP;
+ }
+
+ err = netif_set_real_num_tx_queues(priv->dev, p->bands);
+ if (err)
+ return err;
+
+ for (i = 0; i < pdata->tx_queues_to_use; i++) {
+ u32 quantum = i < p->bands ? p->quanta[i] : 0;
+
+ priv->qdisc.quanta[i] = quantum;
+ stmmac_set_mtl_tx_queue_weight(priv, priv->hw, quantum, i);
+ }
+
+ stmmac_prog_mtl_tx_algorithms(priv, priv->hw, MTL_TX_ALGORITHM_DWRR);
+ priv->qdisc.algo = MTL_TX_ALGORITHM_DWRR;
+ priv->qdisc.handle = qopt->handle;
+ priv->qdisc.bands = p->bands;
+ priv->qdisc.enable = true;
+
+ return 0;
+}
+
+static int tc_setup_ets_destroy(struct stmmac_priv *priv,
+ struct tc_ets_qopt_offload *qopt)
+{
+ if (qopt->parent != TC_H_ROOT ||
+ qopt->handle != priv->qdisc.handle)
+ return -EOPNOTSUPP;
+
+ if (!priv->qdisc.enable ||
+ priv->qdisc.algo != MTL_TX_ALGORITHM_DWRR)
+ return -EOPNOTSUPP;
+
+ stmmac_qdisc_restore_dt_config(priv);
+
+ return 0;
+}
+
+static int tc_setup_ets(struct stmmac_priv *priv,
+ struct tc_ets_qopt_offload *qopt)
+{
+ switch (qopt->command) {
+ case TC_ETS_REPLACE:
+ return tc_setup_ets_sched(priv, qopt);
+ case TC_ETS_DESTROY:
+ return tc_setup_ets_destroy(priv, qopt);
+ case TC_ETS_GRAFT:
+ break;
+ case TC_ETS_STATS:
+ if (qopt->parent == TC_H_ROOT &&
+ qopt->handle == priv->qdisc.handle &&
+ priv->qdisc.enable &&
+ priv->qdisc.algo == MTL_TX_ALGORITHM_DWRR)
+ break;
+ fallthrough;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
static int tc_query_caps(struct stmmac_priv *priv,
struct tc_query_caps_base *base)
{
@@ -1243,8 +1346,16 @@ static void stmmac_reset_tc_mqprio(struct net_device *ndev,
struct stmmac_priv *priv = netdev_priv(ndev);
netdev_reset_tc(ndev);
- netif_set_real_num_tx_queues(ndev, priv->plat->tx_queues_to_use);
stmmac_fpe_map_preemption_class(priv, ndev, extack, 0);
+
+ if (priv->qdisc.enable && priv->qdisc.algo == MTL_TX_ALGORITHM_SP) {
+ stmmac_qdisc_restore_dt_config(priv);
+ } else {
+ u8 bands = priv->qdisc.enable ? priv->qdisc.bands
+ : priv->plat->tx_queues_to_use;
+
+ netif_set_real_num_tx_queues(ndev, bands);
+ }
}
static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
@@ -1255,13 +1366,24 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
u32 offset, count, num_stack_tx_queues = 0;
struct net_device *ndev = priv->dev;
u32 num_tc = qopt->num_tc;
- int err;
+ int i, tc, err;
if (!num_tc) {
stmmac_reset_tc_mqprio(ndev, extack);
return 0;
}
+ if (!priv->dma_cap.dcben)
+ return -EOPNOTSUPP;
+
+ /* Forcing strict priority conflicts with the CBS algorithm of AVB
+ * queues, so reject the offload when any queue is configured as AVB.
+ */
+ for (i = 0; i < priv->plat->tx_queues_to_use; i++) {
+ if (priv->plat->tx_queues_cfg[i].mode_to_use == MTL_QUEUE_AVB)
+ return -EOPNOTSUPP;
+ }
+
err = netdev_set_num_tc(ndev, num_tc);
if (err)
return err;
@@ -1271,6 +1393,15 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
count = qopt->count[tc];
num_stack_tx_queues += count;
+ if (offset + count > priv->plat->tx_queues_to_use)
+ goto err_reset_tc;
+
+ /* The offload switches the MTL scheduler to strict priority,
+ * which only supports a 1:1 TC to TX queue mapping.
+ */
+ if (count > 1)
+ goto err_reset_tc;
+
err = netdev_set_tc_queue(ndev, tc, count, offset);
if (err)
goto err_reset_tc;
@@ -1285,6 +1416,28 @@ static int tc_setup_dwmac510_mqprio(struct stmmac_priv *priv,
if (err)
goto err_reset_tc;
+ for (i = 0; i < priv->plat->tx_queues_to_use; i++) {
+ u32 prio = 0;
+
+ for (tc = 0; tc < num_tc; tc++) {
+ int p;
+
+ if (qopt->offset[tc] != i)
+ continue;
+
+ for (p = 0; p < ARRAY_SIZE(qopt->prio_tc_map); p++)
+ if (qopt->prio_tc_map[p] == tc)
+ prio |= BIT(p);
+ break;
+ }
+
+ priv->qdisc.prio[i] = prio;
+ stmmac_tx_queue_prio(priv, priv->hw, prio, i);
+ }
+ stmmac_prog_mtl_tx_algorithms(priv, priv->hw, MTL_TX_ALGORITHM_SP);
+ priv->qdisc.algo = MTL_TX_ALGORITHM_SP;
+ priv->qdisc.enable = true;
+
return 0;
err_reset_tc:
@@ -1308,6 +1461,7 @@ const struct stmmac_tc_ops dwmac4_tc_ops = {
.setup_cls = tc_setup_cls,
.setup_taprio = tc_setup_taprio_without_fpe,
.setup_etf = tc_setup_etf,
+ .setup_ets = tc_setup_ets,
.query_caps = tc_query_caps,
.setup_mqprio = tc_setup_mqprio_unimplemented,
};
@@ -1319,6 +1473,7 @@ const struct stmmac_tc_ops dwmac510_tc_ops = {
.setup_cls = tc_setup_cls,
.setup_taprio = tc_setup_taprio,
.setup_etf = tc_setup_etf,
+ .setup_ets = tc_setup_ets,
.query_caps = tc_query_caps,
.setup_mqprio = tc_setup_dwmac510_mqprio,
};
|
| 101/3 | 2026/08/08 15:40 | llm | kmsan-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 8595 output: 260 thoughts: 1033 Thoughts: **Analyzing the ETS/MQPRIO Offload Patch for Potential Uninitialized Memory Issues** Okay, so this patch is introducing support for ETS and MQPRIO offload within the stmmac driver. My initial concern, as always, is around potential uninitialized memory reads. Let's break this down systematically. First, I see a `qdisc` structure added to `struct stmmac_priv`. This makes sense; it's the logical place to store the ETS/MQPRIO configuration. Good practice. I immediately checked how `struct stmmac_priv` is allocated. The code uses `alloc_etherdev_mqs`, which, as I recall, eventually calls `kvzalloc` via `alloc_netdev_mqs`. Excellent, that means `priv->qdisc` is zero-initialized right from the start. That alleviates a significant chunk of my concern. The patch handles `struct tc_ets_qopt_offload` and `struct tc_mqprio_qopt_offload` structures. These are passed *from* the networking core *to* the driver, acting as a means of configuration for the hardware. My initial reflex is to verify there's no data being unintentionally passed back to userspace, which could then expose uninitialized data. However, the driver *reads* these structures for configuration purposes. It doesn't appear to be *writing* back to these structures to send anything to user space. It only breaks for `TC_ETS_STATS` which won't cause the values to be used, and this case returns either `0` or `-EOPNOTSUPP`. I then took a look at how `tc_setup_dwmac510_mqprio` is handling its input. It reads several values from the `qopt` structure (`num_tc`, `count[tc]`, `offset[tc]`, `prio_tc_map[p]`). These are all inputs. Again, this is the expected behavior for an offload driver: It configures the hardware based on user-provided parameters coming from the kernel's traffic control framework. So, am I seeing any real risk here of uninitialized memory being used? Not really. `priv->qdisc` is explicitly zero-initialized. The `qopt` structures are fully initialized by the qdisc code in the kernel. This is primarily about controlling hardware and data flow based on kernel's configuration. The patch seems to be very well-contained. There's no new data being copied to userspace. I also glanced at the `stmmac_setup_tc` and `pm_runtime_resume_and_get` sections to ensure proper power management interaction, and it is a typical usage with `pm_runtime_resume_and_get` and `pm_runtime_put`, and it should not have caused any issues. Based on this analysis, I'm fairly confident that this patch doesn't introduce any new uninitialized memory vulnerabilities. Standard KASAN and other kernel sanitizers should be sufficient to catch any out-of-bounds or use-after-free issues that might arise, but I do not believe KMSAN is needed here. |
| 102/3 | 2026/08/08 15:41 | tool | set-results |
0mArgs:{
"KMSANReasoning": "The patch adds hardware offload support for ETS (Enhanced Transmission Selection) and MQPRIO in the stmmac driver. It introduces a new `qdisc` structure within the driver's private data (`struct stmmac_priv`) to store the configuration and modifies the queue setup functions to apply these settings to the hardware. The private data structure is zero-initialized upon allocation by the networking core (`alloc_netdev_mqs` uses `kvzalloc`). The offload parameters (`struct tc_ets_qopt_offload`, `struct tc_mqprio_qopt_offload`) are provided by the kernel's qdisc subsystem and are only read by the driver to configure the hardware; no data is copied back to userspace. There are no new allocations of complex data structures or uninitialized buffers that could lead to information leaks or uninitialized memory use. Any potential bugs introduced by this patch, such as out-of-bounds array accesses or use-after-free, would be effectively caught by standard KASAN and other default debugging tools. Therefore, a dedicated KMSAN fuzzing session is not required.",
"NeedsKMSAN": false
}Results: {
"KMSANReasoning": "The patch adds hardware offload support for ETS (Enhanced Transmission Selection) and MQPRIO in the stmmac driver. It introduces a new `qdisc` structure within the driver's private data (`struct stmmac_priv`) to store the configuration and modifies the queue setup functions to apply these settings to the hardware. The private data structure is zero-initialized upon allocation by the networking core (`alloc_netdev_mqs` uses `kvzalloc`). The offload parameters (`struct tc_ets_qopt_offload`, `struct tc_mqprio_qopt_offload`) are provided by the kernel's qdisc subsystem and are only read by the driver to configure the hardware; no data is copied back to userspace. There are no new allocations of complex data structures or uninitialized buffers that could lead to information leaks or uninitialized memory use. Any potential bugs introduced by this patch, such as out-of-bounds array accesses or use-after-free, would be effectively caught by standard KASAN and other default debugging tools. Therefore, a dedicated KMSAN fuzzing session is not required.",
"NeedsKMSAN": false
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|