AI Trajectory


Trajectory: (Expand/Collapse All)
Seq Timestamp Type Name Duration
0/0 2026/10/05 22:32 flow patch-triage
1m Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "KMSANReasoning": "",
  "NeedsKMSAN": false,
  "Reasoning": "The patch modifies the Broadcom GENET Ethernet driver (bcmgenet), which is an SoC network controller found on Broadcom ARM/MIPS platforms (BCM7xxx, Raspberry Pi 4). The driver is registered as a platform driver matching device-tree compatible strings and specific ARM64 ACPI tables. It is structurally unreachable in standard virtualized environments (QEMU/GCE) on amd64, as there is no corresponding hardware emulation. Therefore, the modified code cannot be executed during fuzzing on amd64.",
  "WorthFuzzing": false
}

1/1 2026/10/05 22:32 action read-patch-diff
0m Args:
null

Results:
{
  "PatchDiff": "commit e3555e5e58d491fdb2bc13fe3078af4f30593172\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate:   Mon Oct 5 22:32:47 2026 +0000\n\n    syz-cluster: applied patch under review\n\ndiff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c\nindex 4c9db2f9fc25f..faa13f12ce7e6 100644\n--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c\n+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c\n@@ -48,17 +48,44 @@\n #define GENET_Q0_TX_BD_CNT\t\\\n \t(TOTAL_DESC - priv-\u003ehw_params-\u003etx_queues * priv-\u003ehw_params-\u003etx_bds_per_q)\n \n-#define RX_BUF_LENGTH\t\t2048\n #define SKB_ALIGNMENT\t\t32\n \n+/* RBUF and TBUF hand a frame to the DMA once the threshold is reached. Both\n+ * registers are 8 bit in units of 16 bytes and want a multiple of the 256\n+ * byte burst size, so 0xf0 is the largest usable value.\n+ */\n+#define ENET_THLD_UNIT\t\t16\n+#define ENET_THLD_BURST\t\t256\n+#define ENET_THLD_DEFAULT\t0x80\n+#define ENET_THLD_MAX\t\t0xf0\n+\n+/* A frame ending just past the transmit threshold stops the transmitter once\n+ * a shorter frame follows, so pad frames that land there this far past it.\n+ */\n+#define ENET_TX_SAFE_MARGIN\t64\n+\n /* Page pool RX buffer layout:\n  * RSB(64) + pad(2) | frame data | skb_shared_info\n- * The HW writes the 64B RSB + 2B alignment padding before the frame.\n+ * The HW writes the 64B RSB before every descriptor of a frame. Only the\n+ * first one also gets the 2B alignment padding.\n  */\n-#define GENET_RSB_PAD\t\t(sizeof(struct status_64) + 2)\n+#define GENET_RBUF_ALIGN\t2\n+#define GENET_RSB_PAD\t\t(sizeof(struct status_64) + GENET_RBUF_ALIGN)\n \n-/* RX buffer plus the skb_shared_info napi_build_skb() places behind it */\n-#define GENET_RX_BUF_SIZE\tSKB_HEAD_ALIGN(RX_BUF_LENGTH)\n+/* A descriptor never spans more than one page, which also holds\n+ * skb_shared_info behind the frame, so on 4K pages the page bounds the\n+ * threshold before the register does. Larger pages fit several descriptors.\n+ */\n+#define ENET_SHINFO_LEN\t\tSKB_DATA_ALIGN(sizeof(struct skb_shared_info))\n+#define ENET_THLD_PAGE_LEN\tround_down(PAGE_SIZE - ENET_SHINFO_LEN - \\\n+\t\t\t\t\t   sizeof(struct status_64), \\\n+\t\t\t\t\t   ENET_THLD_BURST)\n+#define ENET_THLD_MAX_LEN\tmin_t(unsigned int, \\\n+\t\t\t\t      ENET_THLD_MAX * ENET_THLD_UNIT, \\\n+\t\t\t\t      ENET_THLD_PAGE_LEN)\n+\n+/* UMAC_MAX_FRAME_LEN is 14 bits wide and counts the FCS */\n+#define ENET_MAX_JUMBO_MTU\t(GENMASK(13, 0) - ENET_FRAME_OVERHEAD)\n \n /* Tx/Rx DMA register offset, skip 256 descriptors */\n #define WORDS_PER_BD(p)\t\t(p-\u003ehw_params-\u003ewords_per_bd)\n@@ -2148,6 +2175,31 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)\n \t\tgoto out;\n \t}\n \n+\t/* The MAC holds a frame to insert its checksum, but only as much as\n+\t * its FIFO takes. Longer frames are dropped silently.\n+\t */\n+\tif (unlikely(skb-\u003elen \u003e priv-\u003etx_thld_len) \u0026\u0026\n+\t    skb-\u003eip_summed == CHECKSUM_PARTIAL) {\n+\t\tif (skb_checksum_help(skb)) {\n+\t\t\tBCMGENET_STATS64_INC((\u0026ring-\u003estats64), dropped);\n+\t\t\tdev_kfree_skb_any(skb);\n+\t\t\tret = NETDEV_TX_OK;\n+\t\t\tgoto out;\n+\t\t}\n+\t}\n+\n+\t/* Keep the frame out of the window just past the threshold */\n+\tif (unlikely(skb-\u003elen \u003e priv-\u003etx_thld_len \u0026\u0026\n+\t\t     skb-\u003elen \u003c priv-\u003etx_thld_len + ENET_TX_SAFE_MARGIN)) {\n+\t\tif (skb_put_padto(skb, priv-\u003etx_thld_len + ENET_TX_SAFE_MARGIN)) {\n+\t\t\tBCMGENET_STATS64_INC((\u0026ring-\u003estats64), dropped);\n+\t\t\tret = NETDEV_TX_OK;\n+\t\t\tgoto out;\n+\t\t}\n+\t}\n+\n+\tnr_frags = skb_shinfo(skb)-\u003enr_frags;\n+\n \t/* Retain how many bytes will be sent on the wire, without TSB inserted\n \t * by transmit checksum offload\n \t */\n@@ -2252,7 +2304,7 @@ static int bcmgenet_rx_refill(struct bcmgenet_rx_ring *ring,\n \t\t\t      struct enet_cb *cb)\n {\n \tstruct bcmgenet_priv *priv = ring-\u003epriv;\n-\tunsigned int size = GENET_RX_BUF_SIZE;\n+\tunsigned int size = SKB_HEAD_ALIGN(priv-\u003erx_buf_len);\n \tunsigned int offset;\n \tdma_addr_t mapping;\n \tstruct page *page;\n@@ -2267,7 +2319,7 @@ static int bcmgenet_rx_refill(struct bcmgenet_rx_ring *ring,\n \n \t/* page_pool handles DMA mapping via PP_FLAG_DMA_MAP */\n \tmapping = page_pool_get_dma_addr(page) + offset;\n-\tdma_sync_single_for_device(\u0026priv-\u003epdev-\u003edev, mapping, RX_BUF_LENGTH,\n+\tdma_sync_single_for_device(\u0026priv-\u003epdev-\u003edev, mapping, priv-\u003erx_buf_len,\n \t\t\t\t   DMA_FROM_DEVICE);\n \n \tcb-\u003erx_page = page;\n@@ -2278,6 +2330,54 @@ static int bcmgenet_rx_refill(struct bcmgenet_rx_ring *ring,\n \treturn 0;\n }\n \n+/* Drop the frame being collected. Its remaining descriptors carry no SOP,\n+ * so they are dropped quietly until the next one does.\n+ */\n+static void bcmgenet_discard_frags(struct bcmgenet_rx_ring *ring)\n+{\n+\tring-\u003efrag_drop = true;\n+\n+\tif (!ring-\u003efrag_head)\n+\t\treturn;\n+\n+\tdev_kfree_skb_any(ring-\u003efrag_head);\n+\tring-\u003efrag_head = NULL;\n+}\n+\n+/* A frame longer than the threshold arrives in several descriptors, each with\n+ * its own status block. Only the first one carries a header, so hand the page\n+ * of every later one to the frame already being collected. Returns the frame\n+ * once EOP is in, NULL while more descriptors are expected or once the frame\n+ * had to be dropped.\n+ */\n+static struct sk_buff *bcmgenet_add_frag(struct bcmgenet_rx_ring *ring,\n+\t\t\t\t\t struct page *page,\n+\t\t\t\t\t unsigned int offset,\n+\t\t\t\t\t unsigned int size,\n+\t\t\t\t\t unsigned int dma_flag,\n+\t\t\t\t\t unsigned int len)\n+{\n+\tstruct sk_buff *head = ring-\u003efrag_head;\n+\n+\tif (unlikely(skb_shinfo(head)-\u003enr_frags \u003e= MAX_SKB_FRAGS)) {\n+\t\tBCMGENET_STATS64_INC((\u0026ring-\u003estats64), fragmented_errors);\n+\t\tbcmgenet_discard_frags(ring);\n+\t\tpage_pool_put_full_page(ring-\u003epage_pool, page, true);\n+\t\treturn NULL;\n+\t}\n+\n+\tskb_add_rx_frag(head, skb_shinfo(head)-\u003enr_frags, page,\n+\t\t\toffset + sizeof(struct status_64),\n+\t\t\tlen - sizeof(struct status_64), size);\n+\n+\tif (!(dma_flag \u0026 DMA_EOP))\n+\t\treturn NULL;\n+\n+\tring-\u003efrag_head = NULL;\n+\n+\treturn head;\n+}\n+\n /* bcmgenet_desc_rx - descriptor based rx process.\n  * this could be called from bottom half, or from NAPI polling method.\n  */\n@@ -2329,6 +2429,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,\n \t\tunsigned int rx_offset, rx_size;\n \t\tstruct status_64 *status;\n \t\tstruct page *rx_page;\n+\t\tunsigned int min_len;\n \t\tvoid *hard_start;\n \t\t__be16 rx_csum;\n \n@@ -2341,14 +2442,15 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,\n \n \t\tif (bcmgenet_rx_refill(ring, cb)) {\n \t\t\tBCMGENET_STATS64_INC(stats, dropped);\n+\t\t\tbcmgenet_discard_frags(ring);\n \t\t\tgoto next;\n \t\t}\n \n \t\t/* Sync the full buffer; the HW may have written anywhere\n-\t\t * up to RX_BUF_LENGTH.\n+\t\t * up to priv-\u003erx_buf_len.\n \t\t */\n \t\tpage_pool_dma_sync_for_cpu(ring-\u003epage_pool, rx_page, rx_offset,\n-\t\t\t\t\t   RX_BUF_LENGTH);\n+\t\t\t\t\t   priv-\u003erx_buf_len);\n \n \t\thard_start = page_address(rx_page) + rx_offset;\n \t\tstatus = (struct status_64 *)hard_start;\n@@ -2365,20 +2467,34 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,\n \t\t\t  __func__, p_index, ring-\u003ec_index,\n \t\t\t  ring-\u003eread_ptr, dma_length_status);\n \n+\t\t/* Only the first descriptor carries the alignment pad */\n+\t\tmin_len = dma_flag \u0026 DMA_SOP ? GENET_RSB_PAD\n+\t\t\t\t\t     : sizeof(struct status_64);\n+\n \t\t/* Reject lengths that would underflow the SKB build path. */\n-\t\tif (unlikely(len \u003e RX_BUF_LENGTH || len \u003c GENET_RSB_PAD)) {\n+\t\tif (unlikely(len \u003e priv-\u003erx_buf_len || len \u003c min_len)) {\n \t\t\tnetif_err(priv, rx_status, dev,\n \t\t\t\t  \"invalid packet length %d\\n\", len);\n \t\t\tBCMGENET_STATS64_INC(stats, length_errors);\n+\t\t\tbcmgenet_discard_frags(ring);\n \t\t\tpage_pool_put_full_page(ring-\u003epage_pool, rx_page,\n \t\t\t\t\t\ttrue);\n \t\t\tgoto next;\n \t\t}\n \n-\t\tif (unlikely(!(dma_flag \u0026 DMA_EOP) || !(dma_flag \u0026 DMA_SOP))) {\n-\t\t\tnetif_err(priv, rx_status, dev,\n-\t\t\t\t  \"dropping fragmented packet!\\n\");\n-\t\t\tBCMGENET_STATS64_INC(stats, fragmented_errors);\n+\t\t/* A new SOP resynchronizes after an incomplete frame */\n+\t\tif (dma_flag \u0026 DMA_SOP) {\n+\t\t\tif (ring-\u003efrag_head) {\n+\t\t\t\tBCMGENET_STATS64_INC(stats, fragmented_errors);\n+\t\t\t\tbcmgenet_discard_frags(ring);\n+\t\t\t}\n+\t\t\tring-\u003efrag_drop = false;\n+\t\t} else if (unlikely(!ring-\u003efrag_head)) {\n+\t\t\t/* Rest of a dropped frame, or no SOP seen yet */\n+\t\t\tif (!ring-\u003efrag_drop) {\n+\t\t\t\tBCMGENET_STATS64_INC(stats, fragmented_errors);\n+\t\t\t\tring-\u003efrag_drop = true;\n+\t\t\t}\n \t\t\tpage_pool_put_full_page(ring-\u003epage_pool, rx_page,\n \t\t\t\t\t\ttrue);\n \t\t\tgoto next;\n@@ -2408,17 +2524,27 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,\n \t\t\t\t\t\tDMA_RX_RXER)) == DMA_RX_RXER)\n \t\t\t\tu64_stats_inc(\u0026stats-\u003eerrors);\n \t\t\tu64_stats_update_end(\u0026stats-\u003esyncp);\n+\t\t\tbcmgenet_discard_frags(ring);\n \t\t\tpage_pool_put_full_page(ring-\u003epage_pool, rx_page,\n \t\t\t\t\t\ttrue);\n \t\t\tgoto next;\n \t\t} /* error packet */\n \n+\t\tif (!(dma_flag \u0026 DMA_SOP)) {\n+\t\t\tskb = bcmgenet_add_frag(ring, rx_page, rx_offset,\n+\t\t\t\t\t\trx_size, dma_flag, len);\n+\t\t\tif (!skb)\n+\t\t\t\tgoto next;\n+\t\t\tgoto deliver;\n+\t\t}\n+\n \t\t/* Build SKB from the page - data starts at hard_start,\n \t\t * frame begins after RSB(64) + pad(2) = 66 bytes.\n \t\t */\n \t\tskb = napi_build_skb(hard_start, rx_size);\n \t\tif (unlikely(!skb)) {\n \t\t\tBCMGENET_STATS64_INC(stats, dropped);\n+\t\t\tbcmgenet_discard_frags(ring);\n \t\t\tpage_pool_put_full_page(ring-\u003epage_pool, rx_page,\n \t\t\t\t\t\ttrue);\n \t\t\tgoto next;\n@@ -2430,8 +2556,18 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,\n \t\tskb_reserve(skb, GENET_RSB_PAD);\n \t\t__skb_put(skb, len - GENET_RSB_PAD);\n \n-\t\tif (priv-\u003ecrc_fwd_en) {\n-\t\t\tskb_trim(skb, skb-\u003elen - ETH_FCS_LEN);\n+\t\tif (unlikely(!(dma_flag \u0026 DMA_EOP))) {\n+\t\t\tring-\u003efrag_head = skb;\n+\t\t\tgoto next;\n+\t\t}\n+\n+deliver:\n+\n+\t\tif (priv-\u003ecrc_fwd_en \u0026\u0026\n+\t\t    unlikely(pskb_trim(skb, skb-\u003elen - ETH_FCS_LEN))) {\n+\t\t\tBCMGENET_STATS64_INC(stats, dropped);\n+\t\t\tdev_kfree_skb_any(skb);\n+\t\t\tgoto next;\n \t\t}\n \n \t\t/* Set up checksum offload */\n@@ -2548,6 +2684,8 @@ static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)\n \t\t\tcb = ring-\u003ecbs + i;\n \t\t\tbcmgenet_free_rx_cb(cb, ring-\u003epage_pool);\n \t\t}\n+\t\t/* a partial frame still holds pages of this pool */\n+\t\tbcmgenet_discard_frags(ring);\n \t}\n }\n \n@@ -2617,6 +2755,62 @@ static void bcmgenet_link_intr_enable(struct bcmgenet_priv *priv)\n \tbcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR);\n }\n \n+/* Receive threshold in register units. Covers the alignment bytes and the\n+ * frame, but not the status block, which the hardware adds on top.\n+ */\n+static unsigned int bcmgenet_pkt_rdy_thld(unsigned int mtu)\n+{\n+\tunsigned int len = GENET_RBUF_ALIGN + mtu + ETH_HLEN + VLAN_HLEN;\n+\n+\tlen = round_up(len, ENET_THLD_BURST) / ENET_THLD_UNIT;\n+\n+\t/* Keep the reset default for the common MTUs */\n+\treturn clamp_t(unsigned int, len, ENET_THLD_DEFAULT,\n+\t\t       ENET_THLD_MAX_LEN / ENET_THLD_UNIT);\n+}\n+\n+/* Transmit threshold in register units. Frames landing in the window just\n+ * past it are padded clear of it, so pick a threshold that leaves room for\n+ * that padding inside the frame the MTU allows. Size the window against the\n+ * longest frame the MAC has to accept, since the tag count is not bounded.\n+ */\n+static unsigned int bcmgenet_tx_pkt_rdy_thld(unsigned int mtu)\n+{\n+\tunsigned int thld = ENET_THLD_MAX;\n+\n+\twhile (thld \u003e ENET_THLD_DEFAULT \u0026\u0026\n+\t       ENET_MAX_FRAME_LEN(mtu) - ETH_FCS_LEN \u003e thld * ENET_THLD_UNIT \u0026\u0026\n+\t       thld * ENET_THLD_UNIT + ENET_TX_SAFE_MARGIN \u003e mtu + ETH_HLEN)\n+\t\tthld -= ENET_THLD_BURST / ENET_THLD_UNIT;\n+\n+\treturn thld;\n+}\n+\n+/* A buffer has to hold everything the threshold lets the hardware deliver */\n+static unsigned int bcmgenet_rx_buf_len(unsigned int mtu)\n+{\n+\treturn sizeof(struct status_64) +\n+\t       bcmgenet_pkt_rdy_thld(mtu) * ENET_THLD_UNIT;\n+}\n+\n+/* Program the MTU dependent registers. Call with the MAC disabled. */\n+static void bcmgenet_set_mtu_regs(struct bcmgenet_priv *priv, unsigned int mtu)\n+{\n+\tu32 tx_thld = bcmgenet_tx_pkt_rdy_thld(mtu);\n+\tu32 thld = bcmgenet_pkt_rdy_thld(mtu);\n+\n+\tpriv-\u003etx_thld_len = tx_thld * ENET_THLD_UNIT;\n+\tbcmgenet_umac_writel(priv, ENET_MAX_FRAME_LEN(mtu), UMAC_MAX_FRAME_LEN);\n+\n+\t/* GENET v1 maps other registers at these offsets */\n+\tif (GENET_IS_V1(priv))\n+\t\treturn;\n+\n+\tbcmgenet_rbuf_writel(priv, thld, RBUF_PKT_RDY_THLD);\n+\tbcmgenet_writel(tx_thld, priv-\u003ebase + priv-\u003ehw_params-\u003etbuf_offset +\n+\t\t\tTBUF_PKT_RDY_THLD);\n+}\n+\n static void init_umac(struct bcmgenet_priv *priv)\n {\n \tstruct device *kdev = \u0026priv-\u003epdev-\u003edev;\n@@ -2633,7 +2827,7 @@ static void init_umac(struct bcmgenet_priv *priv)\n \t\t\t     UMAC_MIB_CTRL);\n \tbcmgenet_umac_writel(priv, 0, UMAC_MIB_CTRL);\n \n-\tbcmgenet_umac_writel(priv, ENET_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN);\n+\tbcmgenet_set_mtu_regs(priv, priv-\u003edev-\u003emtu);\n \n \t/* init tx registers, enable TSB */\n \treg = bcmgenet_tbuf_ctrl_get(priv);\n@@ -2739,7 +2933,7 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,\n \n \t/* Set flow period for ring != 0 */\n \tif (index)\n-\t\tflow_period_val = ENET_MAX_MTU_SIZE \u003c\u003c 16;\n+\t\tflow_period_val = ENET_MAX_FRAME_LEN(priv-\u003edev-\u003emtu) \u003c\u003c 16;\n \n \tbcmgenet_tdma_ring_writel(priv, index, 0, TDMA_PROD_INDEX);\n \tbcmgenet_tdma_ring_writel(priv, index, 0, TDMA_CONS_INDEX);\n@@ -2749,7 +2943,7 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,\n \t\t\t\t  TDMA_FLOW_PERIOD);\n \tbcmgenet_tdma_ring_writel(priv, index,\n \t\t\t\t  ((size \u003c\u003c DMA_RING_SIZE_SHIFT) |\n-\t\t\t\t   RX_BUF_LENGTH), DMA_RING_BUF_SIZE);\n+\t\t\t\t   priv-\u003erx_buf_len), DMA_RING_BUF_SIZE);\n \n \t/* Set start and end address, read and write pointers */\n \tbcmgenet_tdma_ring_writel(priv, index, start_ptr * words_per_bd,\n@@ -2768,8 +2962,9 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,\n static int bcmgenet_rx_ring_create_pool(struct bcmgenet_priv *priv,\n \t\t\t\t\tstruct bcmgenet_rx_ring *ring)\n {\n-\t/* Buffers share a page. bcmgenet_rx_refill() syncs each one for the\n-\t * device, PP_FLAG_DMA_SYNC_DEV would sync the whole page.\n+\t/* Buffers may share a page, depending on PAGE_SIZE and the MTU.\n+\t * bcmgenet_rx_refill() syncs each one for the device,\n+\t * PP_FLAG_DMA_SYNC_DEV would sync the whole page.\n \t */\n \tstruct page_pool_params pp_params = {\n \t\t.order = 0,\n@@ -2832,7 +3027,7 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv,\n \tbcmgenet_rdma_ring_writel(priv, index, 0, RDMA_CONS_INDEX);\n \tbcmgenet_rdma_ring_writel(priv, index,\n \t\t\t\t  ((size \u003c\u003c DMA_RING_SIZE_SHIFT) |\n-\t\t\t\t   RX_BUF_LENGTH), DMA_RING_BUF_SIZE);\n+\t\t\t\t   priv-\u003erx_buf_len), DMA_RING_BUF_SIZE);\n \tbcmgenet_rdma_ring_writel(priv, index,\n \t\t\t\t  (DMA_FC_THRESH_LO \u003c\u003c\n \t\t\t\t   DMA_XOFF_THRESHOLD_SHIFT) |\n@@ -3348,7 +3543,7 @@ static void bcmgenet_get_hw_addr(struct bcmgenet_priv *priv,\n \tput_unaligned_be16(addr_tmp, \u0026addr[4]);\n }\n \n-static void bcmgenet_netif_start(struct net_device *dev)\n+static void bcmgenet_netif_start(struct net_device *dev, bool start_phy)\n {\n \tstruct bcmgenet_priv *priv = netdev_priv(dev);\n \n@@ -3365,7 +3560,8 @@ static void bcmgenet_netif_start(struct net_device *dev)\n \t/* Monitor link interrupts now */\n \tbcmgenet_link_intr_enable(priv);\n \n-\tphy_start(dev-\u003ephydev);\n+\tif (start_phy)\n+\t\tphy_start(dev-\u003ephydev);\n }\n \n static int bcmgenet_open(struct net_device *dev)\n@@ -3428,8 +3624,9 @@ static int bcmgenet_open(struct net_device *dev)\n \n \tbcmgenet_phy_pause_set(dev, priv-\u003erx_pause, priv-\u003etx_pause);\n \n-\tbcmgenet_netif_start(dev);\n+\tbcmgenet_netif_start(dev, true);\n \n+\tpriv-\u003edatapath_up = true;\n \tnetif_tx_start_all_queues(dev);\n \n \treturn 0;\n@@ -3488,7 +3685,11 @@ static int bcmgenet_close(struct net_device *dev)\n \n \tnetif_dbg(priv, ifdown, dev, \"bcmgenet_close\\n\");\n \n-\tbcmgenet_netif_stop(dev, false);\n+\t/* A failed MTU change can have torn the datapath down already */\n+\tif (priv-\u003edatapath_up) {\n+\t\tbcmgenet_netif_stop(dev, false);\n+\t\tpriv-\u003edatapath_up = false;\n+\t}\n \n \t/* Really kill the PHY state machine and disconnect from it */\n \tphy_disconnect(dev-\u003ephydev);\n@@ -3736,6 +3937,71 @@ static int bcmgenet_change_carrier(struct net_device *dev, bool new_carrier)\n \treturn 0;\n }\n \n+static int bcmgenet_change_mtu(struct net_device *dev, int new_mtu)\n+{\n+\tstruct bcmgenet_priv *priv = netdev_priv(dev);\n+\tunsigned int old_mtu = dev-\u003emtu;\n+\tint ret;\n+\n+\tif (!netif_running(dev)) {\n+\t\tWRITE_ONCE(dev-\u003emtu, new_mtu);\n+\t\tpriv-\u003erx_buf_len = bcmgenet_rx_buf_len(new_mtu);\n+\t\treturn 0;\n+\t}\n+\n+\t/* The watchdog trips on an idle queue once the rings are gone */\n+\tnetif_device_detach(dev);\n+\n+\t/* Only the buffers and the MTU registers change, leave the PHY up */\n+\tbcmgenet_netif_stop(dev, false);\n+\tpriv-\u003edatapath_up = false;\n+\n+\tWRITE_ONCE(dev-\u003emtu, new_mtu);\n+\tpriv-\u003erx_buf_len = bcmgenet_rx_buf_len(new_mtu);\n+\tbcmgenet_set_mtu_regs(priv, new_mtu);\n+\n+\tret = bcmgenet_init_dma(priv, true);\n+\tif (ret) {\n+\t\t/* Retry the size that was allocated a moment ago */\n+\t\tWRITE_ONCE(dev-\u003emtu, old_mtu);\n+\t\tpriv-\u003erx_buf_len = bcmgenet_rx_buf_len(old_mtu);\n+\t\tbcmgenet_set_mtu_regs(priv, old_mtu);\n+\t\tif (bcmgenet_init_dma(priv, true)) {\n+\t\t\t/* Nothing left to run on. Take the interface down so\n+\t\t\t * that close and suspend do not tear it down twice.\n+\t\t\t */\n+\t\t\tnetdev_err(dev, \"failed to restore MTU %u, closing\\n\",\n+\t\t\t\t   old_mtu);\n+\t\t\tnetif_close(dev);\n+\n+\t\t\t/* Mark the device present again, __dev_open()\n+\t\t\t * refuses a detached one. The queues stay stopped\n+\t\t\t * because the interface is down by now.\n+\t\t\t */\n+\t\t\tnetif_device_attach(dev);\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\tbcmgenet_hfb_restore(priv);\n+\tbcmgenet_netif_start(dev, false);\n+\n+\t/* bcmgenet_netif_start() only restores the link interrupt */\n+\tif (bcmgenet_has_mdio_intr(priv))\n+\t\tbcmgenet_intrl2_0_writel(priv, UMAC_IRQ_MDIO_EVENT,\n+\t\t\t\t\t INTRL2_CPU_MASK_CLEAR);\n+\n+\t/* A link event latched while the interrupts were off is gone. Internal\n+\t * PHYs on GENET v1-v4 are not polled, so resync the state machine.\n+\t */\n+\tphy_mac_interrupt(dev-\u003ephydev);\n+\n+\tpriv-\u003edatapath_up = true;\n+\tnetif_device_attach(dev);\n+\n+\treturn ret;\n+}\n+\n static const struct net_device_ops bcmgenet_netdev_ops = {\n \t.ndo_open\t\t= bcmgenet_open,\n \t.ndo_stop\t\t= bcmgenet_close,\n@@ -3747,6 +4013,7 @@ static const struct net_device_ops bcmgenet_netdev_ops = {\n \t.ndo_set_features\t= bcmgenet_set_features,\n \t.ndo_get_stats64\t= bcmgenet_get_stats64,\n \t.ndo_change_carrier\t= bcmgenet_change_carrier,\n+\t.ndo_change_mtu\t\t= bcmgenet_change_mtu,\n };\n \n /* GENET hardware parameters/characteristics */\n@@ -4100,6 +4367,11 @@ static int bcmgenet_probe(struct platform_device *pdev)\n \t/* Mii wait queue */\n \tinit_waitqueue_head(\u0026priv-\u003ewq);\n \tbcmgenet_hfb_init(priv);\n+\n+\t/* v1 cannot program the thresholds, so it stays at the default MTU */\n+\tpriv-\u003erx_buf_len = bcmgenet_rx_buf_len(dev-\u003emtu);\n+\tif (!GENET_IS_V1(priv))\n+\t\tdev-\u003emax_mtu = ENET_MAX_JUMBO_MTU;\n \tINIT_WORK(\u0026priv-\u003ebcmgenet_irq_work, bcmgenet_irq_task);\n \n \tpriv-\u003eclk_wol = devm_clk_get_optional(\u0026priv-\u003epdev-\u003edev, \"enet-wol\");\n@@ -4312,7 +4584,7 @@ static int bcmgenet_resume(struct device *d)\n \tif (!device_may_wakeup(d))\n \t\tphy_resume(dev-\u003ephydev);\n \n-\tbcmgenet_netif_start(dev);\n+\tbcmgenet_netif_start(dev, true);\n \n \tnetif_device_attach(dev);\n \ndiff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h\nindex 86f2aed20dbe8..97c27b7920d53 100644\n--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h\n+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h\n@@ -28,13 +28,16 @@\n /* which ring is descriptor based */\n #define DESC_INDEX\t\t\t\t16\n \n-/* Body(1500) + EH_SIZE(14) + VLANTAG(4) + BRCMTAG(6) + FCS(4) = 1528.\n- * 1536 is multiple of 256 bytes\n- */\n #define ENET_BRCM_TAG_LEN\t6\n #define ENET_PAD\t\t8\n-#define ENET_MAX_MTU_SIZE\t(ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN + \\\n-\t\t\t\t ENET_BRCM_TAG_LEN + ETH_FCS_LEN + ENET_PAD)\n+\n+/* Longest frame the MAC must accept for a given MTU. ENET_PAD is slack the\n+ * driver has always carried, it rounded the default up to 1536 from 1528.\n+ */\n+#define ENET_FRAME_OVERHEAD\t(ETH_HLEN + VLAN_HLEN + ENET_BRCM_TAG_LEN + \\\n+\t\t\t\t ETH_FCS_LEN + ENET_PAD)\n+#define ENET_MAX_FRAME_LEN(mtu)\t((mtu) + ENET_FRAME_OVERHEAD)\n+\n #define DMA_MAX_BURST_LENGTH    0x10\n \n /* misc. configuration */\n@@ -219,6 +222,8 @@ struct bcmgenet_rx_stats64 {\n #define  RBUF_ALIGN_2B\t\t\t(1 \u003c\u003c 1)\n #define  RBUF_BAD_DIS\t\t\t(1 \u003c\u003c 2)\n \n+#define RBUF_PKT_RDY_THLD\t\t0x08\n+\n #define RBUF_STATUS\t\t\t0x0C\n #define  RBUF_STATUS_WOL\t\t(1 \u003c\u003c 0)\n #define  RBUF_STATUS_MPD_INTR_ACTIVE\t(1 \u003c\u003c 1)\n@@ -249,6 +254,7 @@ struct bcmgenet_rx_stats64 {\n #define TBUF_CTRL\t\t\t0x00\n #define  TBUF_64B_EN\t\t\t(1 \u003c\u003c 0)\n #define TBUF_BP_MC\t\t\t0x0C\n+#define TBUF_PKT_RDY_THLD\t\t0x10\n #define TBUF_ENERGY_CTRL\t\t0x14\n #define  TBUF_EEE_EN\t\t\t(1 \u003c\u003c 0)\n #define  TBUF_PM_EN\t\t\t(1 \u003c\u003c 1)\n@@ -575,6 +581,8 @@ struct bcmgenet_rx_ring {\n \tunsigned int\tcb_ptr;\t\t/* Rx ring initial CB ptr */\n \tunsigned int\tend_ptr;\t/* Rx ring end CB ptr */\n \tunsigned int\told_discards;\n+\tstruct sk_buff\t*frag_head;\t/* frame being reassembled */\n+\tbool\t\tfrag_drop;\t/* discarding until the next SOP */\n \tstruct bcmgenet_net_dim dim;\n \tu32\t\trx_max_coalesced_frames;\n \tu32\t\trx_coalesce_usecs;\n@@ -613,6 +621,8 @@ struct bcmgenet_priv {\n \tvoid __iomem *rx_bds;\n \tstruct enet_cb *rx_cbs;\n \tunsigned int num_rx_bds;\n+\tunsigned int rx_buf_len;\n+\tunsigned int tx_thld_len;\n \tstruct bcmgenet_rxnfc_rule rxnfc_rules[MAX_NUM_OF_FS_RULES];\n \tstruct list_head rxnfc_list;\n \n@@ -624,6 +634,7 @@ struct bcmgenet_priv {\n \tunsigned autoneg_pause:1;\n \tunsigned tx_pause:1;\n \tunsigned rx_pause:1;\n+\tunsigned datapath_up:1;\n \n \t/* MDIO bus variables */\n \twait_queue_head_t wq;\n"
}

2/1 2026/10/05 22:32 agent patch-evaluator
1m Model:
core

Args:
null

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the Broadcom GENET Ethernet driver (bcmgenet), which is an SoC network controller found on Broadcom ARM/MIPS platforms (BCM7xxx, Raspberry Pi 4). The driver is registered as a platform driver matching device-tree compatible strings and specific ARM64 ACPI tables. It is structurally unreachable in standard virtualized environments (QEMU/GCE) on amd64, as there is no corresponding hardware emulation. Therefore, the modified code cannot be executed during fuzzing on amd64.",
  "WorthFuzzing": false
}

Instruction:
You are an expert Linux kernel maintainer and security engineer.
Your job is to review a provided patch series and evaluate whether it warrants fuzzing with syzkaller.

IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in
your workspace. Do NOT rely on internal assumptions. You must actively use your code access
tools to inspect the actual source code, callers, and surrounding context.

================================================================================
1. CORE TRIAGE PHILOSOPHY
================================================================================
The goal of patch fuzzing is to discover crashes, regressions, exposed latent bugs,
and newly triggered assertions introduced by the patch series.

- REACHABILITY IS THE PRIMARY GATE:
  Fuzzing can only discover bugs in code that can actually execute in standard virtualized
  environments (GCE or QEMU, utilizing software-emulated devices like USB gadgets, netdev, tun/tap).
  If the modified code is structurally unreachable (see Section 2), it MUST NOT be fuzzed,
  regardless of whether it adds assertions or complex logic.

- DO NOT BLINDLY TRUST "NO FUNCTIONAL CHANGE" (NFCI) OR "REFACTORING" CLAIMS:
  Patch authors routinely label changes as "cleanups", "refactorings", or state
  "No functional change intended". Do NOT take these claims at face value.
  Code refactorings that rearrange logic, introduce helper functions, or alter state management
  in core subsystems frequently introduce subtle semantic shifts or uncover latent kernel bugs.
  If reachable executable code is modified or refactored, it MUST be fuzzed.

- NEW OR MODIFIED ASSERTIONS IN REACHABLE CODE MUST BE FUZZED:
  When a patch introduces or modifies runtime checks or assertions (e.g., WARN_ON*, VM_WARN_ON*,
  BUG_ON*, lockdep_assert*) in reachable code paths, it enforces new or stricter invariants.
  Even if the author believes the invariant always holds, fuzzing is essential to verify whether
  an unusual sequence of operations can violate it.

================================================================================
2. WHEN TO RETURN WorthFuzzing=false (NEGATIVE CRITERIA)
================================================================================
Return WorthFuzzing=false ONLY IF all modified code falls strictly into one or more of these categories:

- Non-kernel and non-executable changes:
  * Modifications to Documentation/, comments, or spelling fixes.
  * User-space directories, self-tests, samples, or scripts (e.g., tools/, samples/, scripts/, usr/)
    that do not affect the compiled kernel image (vmlinux) or kernel modules.
  * Purely decorative logging (e.g., message strings in pr_err, printk, dev_info) or tracepoints
    that do not alter control flow or data structures.
  * Build system or Kconfig changes that do not alter compiled C logic.
- Structurally unreachable hardware:
  * Vendor-specific PCIe switches, SmartNICs, or GPU drivers (e.g., mlxsw, pds_core, qed,
    ionic, amdgpu) requiring physical ASIC/PCIe cards not emulated in standard QEMU.
- Unreachable execution paths:
  * Driver teardown callbacks (.remove, .shutdown, pci_unregister_driver) executed only during
    physical PCI hot-unplug or manual sysfs driver unbinding.
  * Code paths exclusive to architectures other than the target architecture.

================================================================================
3. WHEN TO RETURN WorthFuzzing=true (POSITIVE CRITERIA)
================================================================================
Return WorthFuzzing=true whenever the patch touches reachable executable code, including:
- Core Subsystems:
  * Any logic modifications in memory management (mm/), synchronization/locking (kernel/locking/),
    BPF, scheduler, core networking, VFS, or syscall handling.
- Refactorings and Code Cleanups:
  * Any restructuring of reachable data structures, helper abstractions, or algorithm flows.
- Runtime Assertions and Defensive Checks:
  * Any introduction or alteration of assertions (WARN_ON*, VM_WARN_ON*, BUG_ON*, etc.) in reachable paths.
- Reachable Drivers and Protocols:
  * Drivers accessible via virtual buses (virtio, USB gadget, loopback, netlink, binder, sockets, etc.).

================================================================================
4. EXTRACTING FocusSymbols (PREVENTING DILUTION)
================================================================================
When WorthFuzzing=true, you must extract specific kernel functions into FocusSymbols to guide the fuzzer:

- AVOID UBIQUITOUS LIFECYCLE HOT-PATHS:
  Do NOT list generic, ubiquitous functions called by almost every program in the corpus
  (including, but not limited to: general memory allocators and deallocators, page fault
  and trap handlers, or core synchronization primitives; this is not an exhaustive list).
  Listing ubiquitous functions causes the fuzzer to classify thousands of unrelated tests as "focused",
  which severely dilutes fuzzing effort away from the actual changes.

- TARGET SPECIFIC FEATURE LOGIC AND ENTRYPOINTS:
  List functions that specifically implement the logic being added or altered, or direct API entrypoints
  for the subsystem feature under review.

- HANDLING STATIC INLINE FUNCTIONS IN HEADERS (.h):
  Compiler-inlined static functions (such as static inlines in mm/*.h or include/linux/*.h) lack
  distinct symbol addresses in vmlinux and cannot be targeted directly by symbol coverage filters.
  If the changes are primarily in static inline helpers, identify non-static, feature-specific caller
  functions in .c files that exercise them (avoiding ubiquitous lifecycle wrappers).

================================================================================
5. IDENTIFYING EnableConfigs
================================================================================
Identify any specific CONFIG_ options required to properly compile and reach the modified code:
- Inspect Kconfig files and #ifdef guards; do not make assumptions.
- Check "depends on" lines in Kconfig to include any non-standard parent subsystem configs needed.
- Strip any 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4").
Prefer calling several tools at the same time to save round-trips.


Use set-results tool to provide results of the analysis.
It must be called exactly once before the final reply.
Ignore results of this tool.

Prompt:
Target architecture: amd64

For your convenience, here is the diff of the changes:
commit e3555e5e58d491fdb2bc13fe3078af4f30593172
Author: syz-cluster <triage@syzkaller.com>
Date:   Mon Oct 5 22:32:47 2026 +0000

    syz-cluster: applied patch under review

diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
index 4c9db2f9fc25f..faa13f12ce7e6 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
@@ -48,17 +48,44 @@
 #define GENET_Q0_TX_BD_CNT	\
 	(TOTAL_DESC - priv->hw_params->tx_queues * priv->hw_params->tx_bds_per_q)
 
-#define RX_BUF_LENGTH		2048
 #define SKB_ALIGNMENT		32
 
+/* RBUF and TBUF hand a frame to the DMA once the threshold is reached. Both
+ * registers are 8 bit in units of 16 bytes and want a multiple of the 256
+ * byte burst size, so 0xf0 is the largest usable value.
+ */
+#define ENET_THLD_UNIT		16
+#define ENET_THLD_BURST		256
+#define ENET_THLD_DEFAULT	0x80
+#define ENET_THLD_MAX		0xf0
+
+/* A frame ending just past the transmit threshold stops the transmitter once
+ * a shorter frame follows, so pad frames that land there this far past it.
+ */
+#define ENET_TX_SAFE_MARGIN	64
+
 /* Page pool RX buffer layout:
  * RSB(64) + pad(2) | frame data | skb_shared_info
- * The HW writes the 64B RSB + 2B alignment padding before the frame.
+ * The HW writes the 64B RSB before every descriptor of a frame. Only the
+ * first one also gets the 2B alignment padding.
  */
-#define GENET_RSB_PAD		(sizeof(struct status_64) + 2)
+#define GENET_RBUF_ALIGN	2
+#define GENET_RSB_PAD		(sizeof(struct status_64) + GENET_RBUF_ALIGN)
 
-/* RX buffer plus the skb_shared_info napi_build_skb() places behind it */
-#define GENET_RX_BUF_SIZE	SKB_HEAD_ALIGN(RX_BUF_LENGTH)
+/* A descriptor never spans more than one page, which also holds
+ * skb_shared_info behind the frame, so on 4K pages the page bounds the
+ * threshold before the register does. Larger pages fit several descriptors.
+ */
+#define ENET_SHINFO_LEN		SKB_DATA_ALIGN(sizeof(struct skb_shared_info))
+#define ENET_THLD_PAGE_LEN	round_down(PAGE_SIZE - ENET_SHINFO_LEN - \
+					   sizeof(struct status_64), \
+					   ENET_THLD_BURST)
+#define ENET_THLD_MAX_LEN	min_t(unsigned int, \
+				      ENET_THLD_MAX * ENET_THLD_UNIT, \
+				      ENET_THLD_PAGE_LEN)
+
+/* UMAC_MAX_FRAME_LEN is 14 bits wide and counts the FCS */
+#define ENET_MAX_JUMBO_MTU	(GENMASK(13, 0) - ENET_FRAME_OVERHEAD)
 
 /* Tx/Rx DMA register offset, skip 256 descriptors */
 #define WORDS_PER_BD(p)		(p->hw_params->words_per_bd)
@@ -2148,6 +2175,31 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
 		goto out;
 	}
 
+	/* The MAC holds a frame to insert its checksum, but only as much as
+	 * its FIFO takes. Longer frames are dropped silently.
+	 */
+	if (unlikely(skb->len > priv->tx_thld_len) &&
+	    skb->ip_summed == CHECKSUM_PARTIAL) {
+		if (skb_checksum_help(skb)) {
+			BCMGENET_STATS64_INC((&ring->stats64), dropped);
+			dev_kfree_skb_any(skb);
+			ret = NETDEV_TX_OK;
+			goto out;
+		}
+	}
+
+	/* Keep the frame out of the window just past the threshold */
+	if (unlikely(skb->len > priv->tx_thld_len &&
+		     skb->len < priv->tx_thld_len + ENET_TX_SAFE_MARGIN)) {
+		if (skb_put_padto(skb, priv->tx_thld_len + ENET_TX_SAFE_MARGIN)) {
+			BCMGENET_STATS64_INC((&ring->stats64), dropped);
+			ret = NETDEV_TX_OK;
+			goto out;
+		}
+	}
+
+	nr_frags = skb_shinfo(skb)->nr_frags;
+
 	/* Retain how many bytes will be sent on the wire, without TSB inserted
 	 * by transmit checksum offload
 	 */
@@ -2252,7 +2304,7 @@ static int bcmgenet_rx_refill(struct bcmgenet_rx_ring *ring,
 			      struct enet_cb *cb)
 {
 	struct bcmgenet_priv *priv = ring->priv;
-	unsigned int size = GENET_RX_BUF_SIZE;
+	unsigned int size = SKB_HEAD_ALIGN(priv->rx_buf_len);
 	unsigned int offset;
 	dma_addr_t mapping;
 	struct page *page;
@@ -2267,7 +2319,7 @@ static int bcmgenet_rx_refill(struct bcmgenet_rx_ring *ring,
 
 	/* page_pool handles DMA mapping via PP_FLAG_DMA_MAP */
 	mapping = page_pool_get_dma_addr(page) + offset;
-	dma_sync_single_for_device(&priv->pdev->dev, mapping, RX_BUF_LENGTH,
+	dma_sync_single_for_device(&priv->pdev->dev, mapping, priv->rx_buf_len,
 				   DMA_FROM_DEVICE);
 
 	cb->rx_page = page;
@@ -2278,6 +2330,54 @@ static int bcmgenet_rx_refill(struct bcmgenet_rx_ring *ring,
 	return 0;
 }
 
+/* Drop the frame being collected. Its remaining descriptors carry no SOP,
+ * so they are dropped quietly until the next one does.
+ */
+static void bcmgenet_discard_frags(struct bcmgenet_rx_ring *ring)
+{
+	ring->frag_drop = true;
+
+	if (!ring->frag_head)
+		return;
+
+	dev_kfree_skb_any(ring->frag_head);
+	ring->frag_head = NULL;
+}
+
+/* A frame longer than the threshold arrives in several descriptors, each with
+ * its own status block. Only the first one carries a header, so hand the page
+ * of every later one to the frame already being collected. Returns the frame
+ * once EOP is in, NULL while more descriptors are expected or once the frame
+ * had to be dropped.
+ */
+static struct sk_buff *bcmgenet_add_frag(struct bcmgenet_rx_ring *ring,
+					 struct page *page,
+					 unsigned int offset,
+					 unsigned int size,
+					 unsigned int dma_flag,
+					 unsigned int len)
+{
+	struct sk_buff *head = ring->frag_head;
+
+	if (unlikely(skb_shinfo(head)->nr_frags >= MAX_SKB_FRAGS)) {
+		BCMGENET_STATS64_INC((&ring->stats64), fragmented_errors);
+		bcmgenet_discard_frags(ring);
+		page_pool_put_full_page(ring->page_pool, page, true);
+		return NULL;
+	}
+
+	skb_add_rx_frag(head, skb_shinfo(head)->nr_frags, page,
+			offset + sizeof(struct status_64),
+			len - sizeof(struct status_64), size);
+
+	if (!(dma_flag & DMA_EOP))
+		return NULL;
+
+	ring->frag_head = NULL;
+
+	return head;
+}
+
 /* bcmgenet_desc_rx - descriptor based rx process.
  * this could be called from bottom half, or from NAPI polling method.
  */
@@ -2329,6 +2429,7 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 		unsigned int rx_offset, rx_size;
 		struct status_64 *status;
 		struct page *rx_page;
+		unsigned int min_len;
 		void *hard_start;
 		__be16 rx_csum;
 
@@ -2341,14 +2442,15 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 
 		if (bcmgenet_rx_refill(ring, cb)) {
 			BCMGENET_STATS64_INC(stats, dropped);
+			bcmgenet_discard_frags(ring);
 			goto next;
 		}
 
 		/* Sync the full buffer; the HW may have written anywhere
-		 * up to RX_BUF_LENGTH.
+		 * up to priv->rx_buf_len.
 		 */
 		page_pool_dma_sync_for_cpu(ring->page_pool, rx_page, rx_offset,
-					   RX_BUF_LENGTH);
+					   priv->rx_buf_len);
 
 		hard_start = page_address(rx_page) + rx_offset;
 		status = (struct status_64 *)hard_start;
@@ -2365,20 +2467,34 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 			  __func__, p_index, ring->c_index,
 			  ring->read_ptr, dma_length_status);
 
+		/* Only the first descriptor carries the alignment pad */
+		min_len = dma_flag & DMA_SOP ? GENET_RSB_PAD
+					     : sizeof(struct status_64);
+
 		/* Reject lengths that would underflow the SKB build path. */
-		if (unlikely(len > RX_BUF_LENGTH || len < GENET_RSB_PAD)) {
+		if (unlikely(len > priv->rx_buf_len || len < min_len)) {
 			netif_err(priv, rx_status, dev,
 				  "invalid packet length %d\n", len);
 			BCMGENET_STATS64_INC(stats, length_errors);
+			bcmgenet_discard_frags(ring);
 			page_pool_put_full_page(ring->page_pool, rx_page,
 						true);
 			goto next;
 		}
 
-		if (unlikely(!(dma_flag & DMA_EOP) || !(dma_flag & DMA_SOP))) {
-			netif_err(priv, rx_status, dev,
-				  "dropping fragmented packet!\n");
-			BCMGENET_STATS64_INC(stats, fragmented_errors);
+		/* A new SOP resynchronizes after an incomplete frame */
+		if (dma_flag & DMA_SOP) {
+			if (ring->frag_head) {
+				BCMGENET_STATS64_INC(stats, fragmented_errors);
+				bcmgenet_discard_frags(ring);
+			}
+			ring->frag_drop = false;
+		} else if (unlikely(!ring->frag_head)) {
+			/* Rest of a dropped frame, or no SOP seen yet */
+			if (!ring->frag_drop) {
+				BCMGENET_STATS64_INC(stats, fragmented_errors);
+				ring->frag_drop = true;
+			}
 			page_pool_put_full_page(ring->page_pool, rx_page,
 						true);
 			goto next;
@@ -2408,17 +2524,27 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 						DMA_RX_RXER)) == DMA_RX_RXER)
 				u64_stats_inc(&stats->errors);
 			u64_stats_update_end(&stats->syncp);
+			bcmgenet_discard_frags(ring);
 			page_pool_put_full_page(ring->page_pool, rx_page,
 						true);
 			goto next;
 		} /* error packet */
 
+		if (!(dma_flag & DMA_SOP)) {
+			skb = bcmgenet_add_frag(ring, rx_page, rx_offset,
+						rx_size, dma_flag, len);
+			if (!skb)
+				goto next;
+			goto deliver;
+		}
+
 		/* Build SKB from the page - data starts at hard_start,
 		 * frame begins after RSB(64) + pad(2) = 66 bytes.
 		 */
 		skb = napi_build_skb(hard_start, rx_size);
 		if (unlikely(!skb)) {
 			BCMGENET_STATS64_INC(stats, dropped);
+			bcmgenet_discard_frags(ring);
 			page_pool_put_full_page(ring->page_pool, rx_page,
 						true);
 			goto next;
@@ -2430,8 +2556,18 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
 		skb_reserve(skb, GENET_RSB_PAD);
 		__skb_put(skb, len - GENET_RSB_PAD);
 
-		if (priv->crc_fwd_en) {
-			skb_trim(skb, skb->len - ETH_FCS_LEN);
+		if (unlikely(!(dma_flag & DMA_EOP))) {
+			ring->frag_head = skb;
+			goto next;
+		}
+
+deliver:
+
+		if (priv->crc_fwd_en &&
+		    unlikely(pskb_trim(skb, skb->len - ETH_FCS_LEN))) {
+			BCMGENET_STATS64_INC(stats, dropped);
+			dev_kfree_skb_any(skb);
+			goto next;
 		}
 
 		/* Set up checksum offload */
@@ -2548,6 +2684,8 @@ static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
 			cb = ring->cbs + i;
 			bcmgenet_free_rx_cb(cb, ring->page_pool);
 		}
+		/* a partial frame still holds pages of this pool */
+		bcmgenet_discard_frags(ring);
 	}
 }
 
@@ -2617,6 +2755,62 @@ static void bcmgenet_link_intr_enable(struct bcmgenet_priv *priv)
 	bcmgenet_intrl2_0_writel(priv, int0_enable, INTRL2_CPU_MASK_CLEAR);
 }
 
+/* Receive threshold in register units. Covers the alignment bytes and the
+ * frame, but not the status block, which the hardware adds on top.
+ */
+static unsigned int bcmgenet_pkt_rdy_thld(unsigned int mtu)
+{
+	unsigned int len = GENET_RBUF_ALIGN + mtu + ETH_HLEN + VLAN_HLEN;
+
+	len = round_up(len, ENET_THLD_BURST) / ENET_THLD_UNIT;
+
+	/* Keep the reset default for the common MTUs */
+	return clamp_t(unsigned int, len, ENET_THLD_DEFAULT,
+		       ENET_THLD_MAX_LEN / ENET_THLD_UNIT);
+}
+
+/* Transmit threshold in register units. Frames landing in the window just
+ * past it are padded clear of it, so pick a threshold that leaves room for
+ * that padding inside the frame the MTU allows. Size the window against the
+ * longest frame the MAC has to accept, since the tag count is not bounded.
+ */
+static unsigned int bcmgenet_tx_pkt_rdy_thld(unsigned int mtu)
+{
+	unsigned int thld = ENET_THLD_MAX;
+
+	while (thld > ENET_THLD_DEFAULT &&
+	       ENET_MAX_FRAME_LEN(mtu) - ETH_FCS_LEN > thld * ENET_THLD_UNIT &&
+	       thld * ENET_THLD_UNIT + ENET_TX_SAFE_MARGIN > mtu + ETH_HLEN)
+		thld -= ENET_THLD_BURST / ENET_THLD_UNIT;
+
+	return thld;
+}
+
+/* A buffer has to hold everything the threshold lets the hardware deliver */
+static unsigned int bcmgenet_rx_buf_len(unsigned int mtu)
+{
+	return sizeof(struct status_64) +
+	       bcmgenet_pkt_rdy_thld(mtu) * ENET_THLD_UNIT;
+}
+
+/* Program the MTU dependent registers. Call with the MAC disabled. */
+static void bcmgenet_set_mtu_regs(struct bcmgenet_priv *priv, unsigned int mtu)
+{
+	u32 tx_thld = bcmgenet_tx_pkt_rdy_thld(mtu);
+	u32 thld = bcmgenet_pkt_rdy_thld(mtu);
+
+	priv->tx_thld_len = tx_thld * ENET_THLD_UNIT;
+	bcmgenet_umac_writel(priv, ENET_MAX_FRAME_LEN(mtu), UMAC_MAX_FRAME_LEN);
+
+	/* GENET v1 maps other registers at these offsets */
+	if (GENET_IS_V1(priv))
+		return;
+
+	bcmgenet_rbuf_writel(priv, thld, RBUF_PKT_RDY_THLD);
+	bcmgenet_writel(tx_thld, priv->base + priv->hw_params->tbuf_offset +
+			TBUF_PKT_RDY_THLD);
+}
+
 static void init_umac(struct bcmgenet_priv *priv)
 {
 	struct device *kdev = &priv->pdev->dev;
@@ -2633,7 +2827,7 @@ static void init_umac(struct bcmgenet_priv *priv)
 			     UMAC_MIB_CTRL);
 	bcmgenet_umac_writel(priv, 0, UMAC_MIB_CTRL);
 
-	bcmgenet_umac_writel(priv, ENET_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN);
+	bcmgenet_set_mtu_regs(priv, priv->dev->mtu);
 
 	/* init tx registers, enable TSB */
 	reg = bcmgenet_tbuf_ctrl_get(priv);
@@ -2739,7 +2933,7 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
 
 	/* Set flow period for ring != 0 */
 	if (index)
-		flow_period_val = ENET_MAX_MTU_SIZE << 16;
+		flow_period_val = ENET_MAX_FRAME_LEN(priv->dev->mtu) << 16;
 
 	bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_PROD_INDEX);
 	bcmgenet_tdma_ring_writel(priv, index, 0, TDMA_CONS_INDEX);
@@ -2749,7 +2943,7 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
 				  TDMA_FLOW_PERIOD);
 	bcmgenet_tdma_ring_writel(priv, index,
 				  ((size << DMA_RING_SIZE_SHIFT) |
-				   RX_BUF_LENGTH), DMA_RING_BUF_SIZE);
+				   priv->rx_buf_len), DMA_RING_BUF_SIZE);
 
 	/* Set start and end address, read and write pointers */
 	bcmgenet_tdma_ring_writel(priv, index, start_ptr * words_per_bd,
@@ -2768,8 +2962,9 @@ static void bcmgenet_init_tx_ring(struct bcmgenet_priv *priv,
 static int bcmgenet_rx_ring_create_pool(struct bcmgenet_priv *priv,
 					struct bcmgenet_rx_ring *ring)
 {
-	/* Buffers share a page. bcmgenet_rx_refill() syncs each one for the
-	 * device, PP_FLAG_DMA_SYNC_DEV would sync the whole page.
+	/* Buffers may share a page, depending on PAGE_SIZE and the MTU.
+	 * bcmgenet_rx_refill() syncs each one for the device,
+	 * PP_FLAG_DMA_SYNC_DEV would sync the whole page.
 	 */
 	struct page_pool_params pp_params = {
 		.order = 0,
@@ -2832,7 +3027,7 @@ static int bcmgenet_init_rx_ring(struct bcmgenet_priv *priv,
 	bcmgenet_rdma_ring_writel(priv, index, 0, RDMA_CONS_INDEX);
 	bcmgenet_rdma_ring_writel(priv, index,
 				  ((size << DMA_RING_SIZE_SHIFT) |
-				   RX_BUF_LENGTH), DMA_RING_BUF_SIZE);
+				   priv->rx_buf_len), DMA_RING_BUF_SIZE);
 	bcmgenet_rdma_ring_writel(priv, index,
 				  (DMA_FC_THRESH_LO <<
 				   DMA_XOFF_THRESHOLD_SHIFT) |
@@ -3348,7 +3543,7 @@ static void bcmgenet_get_hw_addr(struct bcmgenet_priv *priv,
 	put_unaligned_be16(addr_tmp, &addr[4]);
 }
 
-static void bcmgenet_netif_start(struct net_device *dev)
+static void bcmgenet_netif_start(struct net_device *dev, bool start_phy)
 {
 	struct bcmgenet_priv *priv = netdev_priv(dev);
 
@@ -3365,7 +3560,8 @@ static void bcmgenet_netif_start(struct net_device *dev)
 	/* Monitor link interrupts now */
 	bcmgenet_link_intr_enable(priv);
 
-	phy_start(dev->phydev);
+	if (start_phy)
+		phy_start(dev->phydev);
 }
 
 static int bcmgenet_open(struct net_device *dev)
@@ -3428,8 +3624,9 @@ static int bcmgenet_open(struct net_device *dev)
 
 	bcmgenet_phy_pause_set(dev, priv->rx_pause, priv->tx_pause);
 
-	bcmgenet_netif_start(dev);
+	bcmgenet_netif_start(dev, true);
 
+	priv->datapath_up = true;
 	netif_tx_start_all_queues(dev);
 
 	return 0;
@@ -3488,7 +3685,11 @@ static int bcmgenet_close(struct net_device *dev)
 
 	netif_dbg(priv, ifdown, dev, "bcmgenet_close\n");
 
-	bcmgenet_netif_stop(dev, false);
+	/* A failed MTU change can have torn the datapath down already */
+	if (priv->datapath_up) {
+		bcmgenet_netif_stop(dev, false);
+		priv->datapath_up = false;
+	}
 
 	/* Really kill the PHY state machine and disconnect from it */
 	phy_disconnect(dev->phydev);
@@ -3736,6 +3937,71 @@ static int bcmgenet_change_carrier(struct net_device *dev, bool new_carrier)
 	return 0;
 }
 
+static int bcmgenet_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct bcmgenet_priv *priv = netdev_priv(dev);
+	unsigned int old_mtu = dev->mtu;
+	int ret;
+
+	if (!netif_running(dev)) {
+		WRITE_ONCE(dev->mtu, new_mtu);
+		priv->rx_buf_len = bcmgenet_rx_buf_len(new_mtu);
+		return 0;
+	}
+
+	/* The watchdog trips on an idle queue once the rings are gone */
+	netif_device_detach(dev);
+
+	/* Only the buffers and the MTU registers change, leave the PHY up */
+	bcmgenet_netif_stop(dev, false);
+	priv->datapath_up = false;
+
+	WRITE_ONCE(dev->mtu, new_mtu);
+	priv->rx_buf_len = bcmgenet_rx_buf_len(new_mtu);
+	bcmgenet_set_mtu_regs(priv, new_mtu);
+
+	ret = bcmgenet_init_dma(priv, true);
+	if (ret) {
+		/* Retry the size that was allocated a moment ago */
+		WRITE_ONCE(dev->mtu, old_mtu);
+		priv->rx_buf_len = bcmgenet_rx_buf_len(old_mtu);
+		bcmgenet_set_mtu_regs(priv, old_mtu);
+		if (bcmgenet_init_dma(priv, true)) {
+			/* Nothing left to run on. Take the interface down so
+			 * that close and suspend do not tear it down twice.
+			 */
+			netdev_err(dev, "failed to restore MTU %u, closing\n",
+				   old_mtu);
+			netif_close(dev);
+
+			/* Mark the device present again, __dev_open()
+			 * refuses a detached one. The queues stay stopped
+			 * because the interface is down by now.
+			 */
+			netif_device_attach(dev);
+			return ret;
+		}
+	}
+
+	bcmgenet_hfb_restore(priv);
+	bcmgenet_netif_start(dev, false);
+
+	/* bcmgenet_netif_start() only restores the link interrupt */
+	if (bcmgenet_has_mdio_intr(priv))
+		bcmgenet_intrl2_0_writel(priv, UMAC_IRQ_MDIO_EVENT,
+					 INTRL2_CPU_MASK_CLEAR);
+
+	/* A link event latched while the interrupts were off is gone. Internal
+	 * PHYs on GENET v1-v4 are not polled, so resync the state machine.
+	 */
+	phy_mac_interrupt(dev->phydev);
+
+	priv->datapath_up = true;
+	netif_device_attach(dev);
+
+	return ret;
+}
+
 static const struct net_device_ops bcmgenet_netdev_ops = {
 	.ndo_open		= bcmgenet_open,
 	.ndo_stop		= bcmgenet_close,
@@ -3747,6 +4013,7 @@ static const struct net_device_ops bcmgenet_netdev_ops = {
 	.ndo_set_features	= bcmgenet_set_features,
 	.ndo_get_stats64	= bcmgenet_get_stats64,
 	.ndo_change_carrier	= bcmgenet_change_carrier,
+	.ndo_change_mtu		= bcmgenet_change_mtu,
 };
 
 /* GENET hardware parameters/characteristics */
@@ -4100,6 +4367,11 @@ static int bcmgenet_probe(struct platform_device *pdev)
 	/* Mii wait queue */
 	init_waitqueue_head(&priv->wq);
 	bcmgenet_hfb_init(priv);
+
+	/* v1 cannot program the thresholds, so it stays at the default MTU */
+	priv->rx_buf_len = bcmgenet_rx_buf_len(dev->mtu);
+	if (!GENET_IS_V1(priv))
+		dev->max_mtu = ENET_MAX_JUMBO_MTU;
 	INIT_WORK(&priv->bcmgenet_irq_work, bcmgenet_irq_task);
 
 	priv->clk_wol = devm_clk_get_optional(&priv->pdev->dev, "enet-wol");
@@ -4312,7 +4584,7 @@ static int bcmgenet_resume(struct device *d)
 	if (!device_may_wakeup(d))
 		phy_resume(dev->phydev);
 
-	bcmgenet_netif_start(dev);
+	bcmgenet_netif_start(dev, true);
 
 	netif_device_attach(dev);
 
diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
index 86f2aed20dbe8..97c27b7920d53 100644
--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h
+++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h
@@ -28,13 +28,16 @@
 /* which ring is descriptor based */
 #define DESC_INDEX				16
 
-/* Body(1500) + EH_SIZE(14) + VLANTAG(4) + BRCMTAG(6) + FCS(4) = 1528.
- * 1536 is multiple of 256 bytes
- */
 #define ENET_BRCM_TAG_LEN	6
 #define ENET_PAD		8
-#define ENET_MAX_MTU_SIZE	(ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN + \
-				 ENET_BRCM_TAG_LEN + ETH_FCS_LEN + ENET_PAD)
+
+/* Longest frame the MAC must accept for a given MTU. ENET_PAD is slack the
+ * driver has always carried, it rounded the default up to 1536 from 1528.
+ */
+#define ENET_FRAME_OVERHEAD	(ETH_HLEN + VLAN_HLEN + ENET_BRCM_TAG_LEN + \
+				 ETH_FCS_LEN + ENET_PAD)
+#define ENET_MAX_FRAME_LEN(mtu)	((mtu) + ENET_FRAME_OVERHEAD)
+
 #define DMA_MAX_BURST_LENGTH    0x10
 
 /* misc. configuration */
@@ -219,6 +222,8 @@ struct bcmgenet_rx_stats64 {
 #define  RBUF_ALIGN_2B			(1 << 1)
 #define  RBUF_BAD_DIS			(1 << 2)
 
+#define RBUF_PKT_RDY_THLD		0x08
+
 #define RBUF_STATUS			0x0C
 #define  RBUF_STATUS_WOL		(1 << 0)
 #define  RBUF_STATUS_MPD_INTR_ACTIVE	(1 << 1)
@@ -249,6 +254,7 @@ struct bcmgenet_rx_stats64 {
 #define TBUF_CTRL			0x00
 #define  TBUF_64B_EN			(1 << 0)
 #define TBUF_BP_MC			0x0C
+#define TBUF_PKT_RDY_THLD		0x10
 #define TBUF_ENERGY_CTRL		0x14
 #define  TBUF_EEE_EN			(1 << 0)
 #define  TBUF_PM_EN			(1 << 1)
@@ -575,6 +581,8 @@ struct bcmgenet_rx_ring {
 	unsigned int	cb_ptr;		/* Rx ring initial CB ptr */
 	unsigned int	end_ptr;	/* Rx ring end CB ptr */
 	unsigned int	old_discards;
+	struct sk_buff	*frag_head;	/* frame being reassembled */
+	bool		frag_drop;	/* discarding until the next SOP */
 	struct bcmgenet_net_dim dim;
 	u32		rx_max_coalesced_frames;
 	u32		rx_coalesce_usecs;
@@ -613,6 +621,8 @@ struct bcmgenet_priv {
 	void __iomem *rx_bds;
 	struct enet_cb *rx_cbs;
 	unsigned int num_rx_bds;
+	unsigned int rx_buf_len;
+	unsigned int tx_thld_len;
 	struct bcmgenet_rxnfc_rule rxnfc_rules[MAX_NUM_OF_FS_RULES];
 	struct list_head rxnfc_list;
 
@@ -624,6 +634,7 @@ struct bcmgenet_priv {
 	unsigned autoneg_pause:1;
 	unsigned tx_pause:1;
 	unsigned rx_pause:1;
+	unsigned datapath_up:1;
 
 	/* MDIO bus variables */
 	wait_queue_head_t wq;

3/2 2026/10/05 22:32 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 11597
							output: 36
							thoughts: 131
						

Thoughts:
**Evaluating the Broadcom GENET Driver Patch Series**

Okay, so I need to evaluate this patch series focusing on the Broadcom GENET driver, specifically within `drivers/net/ethernet/broadcom/genet/bcmgenet.c`. The target architecture is amd64. My initial thought is to dive right in, but before I do, I need to understand this driver better.

First, the obvious: let's confirm the driver's identity. It's `bcmgenet`. Right, that rings a bell. Broadcom GENET… that’s an Ethernet MAC used in Broadcom's BCM7xxx set-top box SoCs and the Raspberry Pi 4 (BCM2711). Now comes the critical question: Can I realistically test this on amd64, even in a simulated environment like QEMU? Before I spend too much time, I *must* verify if the architecture supports the probe. A quick check of the Kconfig is in order. This will determine if I can even begin a meaningful evaluation without access to the specific hardware.



4/2 2026/10/05 22:32 tool grepper
0m Args:
{
  "Expression": "config BCMGENET",
  "PathPrefixes": [
    "drivers/net/ethernet/broadcom/"
  ]
}

Results:
{
  "Output": "drivers/net/ethernet/broadcom/Kconfig=63=config BCM63XX_ENET\n--\ndrivers/net/ethernet/broadcom/Kconfig-71-\ndrivers/net/ethernet/broadcom/Kconfig:72:config BCMGENET\ndrivers/net/ethernet/broadcom/Kconfig-73-\ttristate \"Broadcom GENET internal MAC support\"\n"
}

5/2 2026/10/05 22:32 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 12105
							output: 39
							thoughts: 24
						

Thoughts:
Here's a summary of my thought process, as requested:

**Navigating the Broadcom Ethernet Configuration**

Okay, let's dive into this. Based on what I'm looking at, my immediate thought is to check out the Broadcom Ethernet configuration file. Specifically, I need to get a handle on what's going on around line 72 in `drivers/net/ethernet/broadcom/Kconfig`. This area is likely where the core settings or dependencies for these drivers are defined. This would be the logical place to start digging to understand how this network configuration is designed. I anticipate I'll find some crucial variables, features that can be enabled/disabled, or other conditional logic that drives the build process for this driver set.



6/2 2026/10/05 22:32 tool read-file
0m Args:
{
  "File": "drivers/net/ethernet/broadcom/Kconfig",
  "FirstLine": 70,
  "LineCount": 35
}

Results:
{
  "Contents": "  70:\t\t  MIPS chipset family (BCM63XX).\n  71:\t\n  72:\tconfig BCMGENET\n  73:\t\ttristate \"Broadcom GENET internal MAC support\"\n  74:\t\tdepends on HAS_IOMEM\n  75:\t\tdepends on PTP_1588_CLOCK_OPTIONAL || !ARCH_BCM2835\n  76:\t\tselect PHYLIB\n  77:\t\tselect FIXED_PHY\n  78:\t\tselect BCM7XXX_PHY\n  79:\t\tselect MDIO_BCM_UNIMAC\n  80:\t\tselect DIMLIB\n  81:\t\tselect PAGE_POOL\n  82:\t\tselect BROADCOM_PHY if ARCH_BCM2835\n  83:\t\thelp\n  84:\t\t  This driver supports the built-in Ethernet MACs found in the\n  85:\t\t  Broadcom BCM7xxx Set Top Box family chipset.\n  86:\t\n  87:\tconfig BNX2\n  88:\t\ttristate \"QLogic bnx2 support\"\n  89:\t\tdepends on PCI\n  90:\t\tselect CRC32\n  91:\t\tselect FW_LOADER\n  92:\t\thelp\n  93:\t\t  This driver supports QLogic bnx2 gigabit Ethernet cards.\n  94:\t\n  95:\t\t  To compile this driver as a module, choose M here: the module\n  96:\t\t  will be called bnx2.  This is recommended.\n  97:\t\n  98:\tconfig CNIC\n  99:\t\ttristate \"QLogic CNIC support\"\n 100:\t\tdepends on PCI\n 101:\t\tselect BNX2\n 102:\t\tselect UIO\n 103:\t\thelp\n 104:\t\t  This driver supports offload features of QLogic bnx2 gigabit\n"
}

7/2 2026/10/05 22:32 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 12795
							output: 43
							thoughts: 38
						

Thoughts:
Okay, let's dive into this `bcmgenet` driver registration and probing. First, I need to understand the fundamental architecture – is this a platform driver, relying on resources described in the platform's device tree or similar? Perhaps it's an ACPI-based device, with its control and configuration managed through ACPI tables. Or, could it be a PCI device, leveraging the PCI bus and associated resources? I suspect it's most likely a platform driver given the name, but best to confirm. The quickest route to understanding its initialization is, without a doubt, going straight to the source. Let's start by cracking open `bcmgenet.c` and examining the driver's registration and probe functions. That should illuminate the device model and how it interacts with the system.



8/2 2026/10/05 22:32 tool grepper
0m Args:
{
  "Expression": "module_platform_driver|platform_driver",
  "PathPrefixes": [
    "drivers/net/ethernet/broadcom/genet/"
  ]
}

Results:
{
  "Output": "drivers/net/ethernet/broadcom/genet/bcmgenet.c=4697=MODULE_DEVICE_TABLE(acpi, genet_acpi_match);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-4698-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:4699:static struct platform_driver bcmgenet_driver = {\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-4700-\t.probe\t= bcmgenet_probe,\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-4709-};\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:4710:module_platform_driver(bcmgenet_driver);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-4711-\n"
}

9/2 2026/10/05 22:32 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 13294
							output: 48
							thoughts: 16
						

Thoughts:
Okay, here's my summary, tailored as if I'm an expert in the field thinking aloud:

**Checking the BCMGENET Driver Match Tables**

Alright, let's dive into this. First things first, I need to get a handle on how this `bcmgenet_driver` is behaving. My initial move here is to consult the match tables. I'm thinking, "Where are the crucial configuration elements registered? What are the driver's supported features or hardware revisions?" Knowing the match tables helps me understand the intended design and potential gotchas. I need to see how the driver identifies and binds to specific hardware configurations. Are there any unusual platform-specific conditions encoded in the tables that could explain a given behavior? Let's get down to brass tacks and assess the match tables.



10/2 2026/10/05 22:33 tool read-file
0m Args:
{
  "File": "drivers/net/ethernet/broadcom/genet/bcmgenet.c",
  "FirstLine": 4680,
  "LineCount": 40
}

Results:
{
  "Contents": "4680:\t#define bcmgenet_suspend\tNULL\n4681:\t#define bcmgenet_suspend_noirq\tNULL\n4682:\t#define bcmgenet_resume\t\tNULL\n4683:\t#define bcmgenet_resume_noirq\tNULL\n4684:\t#endif /* CONFIG_PM_SLEEP */\n4685:\t\n4686:\tstatic const struct dev_pm_ops bcmgenet_pm_ops = {\n4687:\t\t.suspend\t= bcmgenet_suspend,\n4688:\t\t.suspend_noirq\t= bcmgenet_suspend_noirq,\n4689:\t\t.resume\t\t= bcmgenet_resume,\n4690:\t\t.resume_noirq\t= bcmgenet_resume_noirq,\n4691:\t};\n4692:\t\n4693:\tstatic const struct acpi_device_id genet_acpi_match[] = {\n4694:\t\t{ \"BCM6E4E\", (kernel_ulong_t)\u0026bcm2711_plat_data },\n4695:\t\t{ },\n4696:\t};\n4697:\tMODULE_DEVICE_TABLE(acpi, genet_acpi_match);\n4698:\t\n4699:\tstatic struct platform_driver bcmgenet_driver = {\n4700:\t\t.probe\t= bcmgenet_probe,\n4701:\t\t.remove = bcmgenet_remove,\n4702:\t\t.shutdown = bcmgenet_shutdown,\n4703:\t\t.driver\t= {\n4704:\t\t\t.name\t= \"bcmgenet\",\n4705:\t\t\t.of_match_table = bcmgenet_match,\n4706:\t\t\t.pm\t= \u0026bcmgenet_pm_ops,\n4707:\t\t\t.acpi_match_table = genet_acpi_match,\n4708:\t\t},\n4709:\t};\n4710:\tmodule_platform_driver(bcmgenet_driver);\n4711:\t\n4712:\tMODULE_AUTHOR(\"Broadcom Corporation\");\n4713:\tMODULE_DESCRIPTION(\"Broadcom GENET Ethernet controller driver\");\n4714:\tMODULE_ALIAS(\"platform:bcmgenet\");\n4715:\tMODULE_LICENSE(\"GPL\");\n4716:\tMODULE_SOFTDEP(\"pre: mdio-bcm-unimac\");\n"
}

11/2 2026/10/05 22:33 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 14173
							output: 30
							thoughts: 817
						

Thoughts:
**My Assessment: BCMGENET and Reachability for Fuzzing**

Okay, here's the situation I'm looking at. I see a potential platform driver, `bcmgenet`, potentially matched via `of_match_table` or `acpi_match_table` like `"BCM6E4E"` on a Raspberry Pi 4 (bcm2711). My immediate concern is reachability for fuzzing. Can this *actually* run, and thus be fuzzed, in a standard virtualized environment like QEMU or GCE? These emulated environments are key for efficient bug hunting.

My thoughts are: can I even instantiate a platform device in a standard amd64 environment like QEMU or GCE? Let's go back to the instructions – reachability is the primary gate. If the code is unreachable in these standard, emulated environments, it's a non-starter for fuzzing, no matter what it does or what assertions it contains. I need to make sure I am focused on code that *can* be executed.

Section 2 clarifies this: I need to consider if all modified code falls into these categories. The crucial one here is "structurally unreachable hardware". This includes things like vendor-specific PCIe switches, or GPU drivers. I know for example, mlxsw, pds_core, qed, ionic, and amdgpu require physical ASICs or PCIe cards not emulated in standard QEMU. That is relevant. I then need to make sure I am not looking at "Unreachable execution paths" like tear-down callbacks.

My first thought is, is BCMGENET hardware emulated in QEMU? Does QEMU emulate bcmgenet or bcm2835 / bcm2711? In QEMU, bcm2835 is ARM. But, again, my target architecture is amd64! This means `bcmgenet` can't be probed on amd64. Even if it *could* be probed, how would that happen?

Can an ACPI device "BCM6E4E" or platform device "bcmgenet" exist on standard amd64 QEMU/GCE? No, this is highly unlikely. Platform devices generally aren't instantiated from userspace without a specific mechanism (like `module_param`) – and syzkaller, although it can be powerful, cannot directly instantiate platform devices. Unlike USB devices via raw-gadget / dummy_hcd which it can interact with via sysfs. This is a critical point.

What about ACPI or Device Tree on amd64? Standard QEMU/GCE amd64 machines use `pc` or `q35` machine types. They don't have Broadcom GENET ethernet controllers. GENET is an SoC ethernet MAC specifically for Broadcom STB (7xxx) and Raspberry Pi 4 (2711, ARM).

Could `bcmgenet` be emulated in QEMU *on* x86_64? I need to check the QEMU source code itself. My check revealed that `genet` support in QEMU was added for the Raspberry Pi 4 (which is aarch64/arm only in QEMU `raspi4b` machine). This support isn't available on x86/amd64! In fact, on amd64, there's no such device present at all.

Finally, I need to verify that there isn't a PCI wrapper or something hiding this, such that it could be indirectly accessible. Let's look at `drivers/net/ethernet/broadcom/genet/` to confirm.

In summary: it looks like this code is not reachable and therefore I shouldn't bother fuzzing it.



12/2 2026/10/05 22:33 tool codesearch-dir-index
0m Args:
{
  "Dir": "drivers/net/ethernet/broadcom/genet"
}

Results:
{
  "Files": [
    "bcmgenet.c",
    "bcmgenet.h",
    "bcmgenet_wol.c",
    "bcmmii.c"
  ],
  "Subdirs": null
}

13/2 2026/10/05 22:33 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 15887
							output: 24
							thoughts: 21
						

Thoughts:
Here's my thought process, summarized as you requested:

**Investigating Potential Kernel Dependencies**

Okay, let's dive in. I need to make absolutely sure I haven't missed anything related to "bcmgenet" within the kernel. My first step is to perform a thorough search. I'll need to identify all relevant files, configurations, and any existing references to this specific term. This search will be the foundation of my analysis, and it's crucial to be exhaustive. I need to leave no stone unturned in this initial exploration phase.



14/2 2026/10/05 22:33 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "platform_device_register.*bcmgenet"
}

Results:
{
  "error": "no matches"
}

15/2 2026/10/05 22:33 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 16064
							output: 27
							thoughts: 21
						

Thoughts:
Here's my thought process, as if I were thinking it:

**Digging into the BCMGENET Implementation**

Okay, so I need to understand how "bcmgenet" is being used within the `arch/` directory. That seems like the logical starting point for investigating its integration across the architecture. I'll initiate a search for the string "bcmgenet" across the relevant `arch/` source code. This should quickly reveal all instances where the module or related code is being directly instantiated or referenced. This search will be the foundation upon which I can identify dependencies, understand how it's initialized, and determine its role within the broader system. I anticipate that the search results will offer a starting point to begin mapping the module across the rest of the architecture.



16/2 2026/10/05 22:33 tool grepper
0m Error:
no matches

Args:
{
  "Expression": "bcmgenet",
  "PathPrefixes": [
    "arch/"
  ]
}

Results:
{
  "error": "no matches"
}

17/2 2026/10/05 22:33 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 16290
							output: 40
							thoughts: 86
						

Thoughts:
Okay, here's my interpretation of that thought process, assuming I'm already quite familiar with embedded systems, device drivers, and platform-specific initialization:

**Reflecting on Device Instantiation**

Right, so this `bcmgenet` driver, it's pretty clear that its primary instantiation pathway is going to be through the Device Tree on ARM, MIPS, and similar architectures. Then there's the ACPI method, like the `genet_acpi_match`, and that makes sense for things like a Raspberry Pi 4 that might be running UEFI. I'm wondering though, specifically about `bcmgenet_match`. Is `bcmgenet_match` actually being used as it should? Let me take a quick look at the `bcmgenet.c` source file and see what I can find.



18/2 2026/10/05 22:33 tool grepper
0m Args:
{
  "Expression": "bcmgenet_match",
  "PathPrefixes": [
    "drivers/net/ethernet/broadcom/genet/"
  ]
}

Results:
{
  "Output": "drivers/net/ethernet/broadcom/genet/bcmgenet.c=4239=static const struct bcmgenet_plat_data bcm7712_plat_data = {\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-4246-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:4247:static const struct of_device_id bcmgenet_match[] = {\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-4248-\t{ .compatible = \"brcm,genet-v1\", .data = \u0026v1_plat_data },\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-4256-};\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:4257:MODULE_DEVICE_TABLE(of, bcmgenet_match);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-4258-\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c=4699=static struct platform_driver bcmgenet_driver = {\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-4704-\t\t.name\t= \"bcmgenet\",\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:4705:\t\t.of_match_table = bcmgenet_match,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-4706-\t\t.pm\t= \u0026bcmgenet_pm_ops,\n"
}

19/2 2026/10/05 22:33 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 17036
							output: 18
							thoughts: 713
						

Thoughts:
**Analyzing the Reachability of bcmgenet on amd64 with syzkaller**

Okay, let's break this down. First, I need to confirm the architecture and device compatibility of these `brcm,genet-*` strings and "BCM6E4E". Right, they're all Broadcom SoC devices, typically MIPS, ARM, or ARM64. And "BCM6E4E" is used in Raspberry Pi 4's ARM64 UEFI. The real question is, can I even *fuzz* `bcmgenet` on `amd64` using syzkaller?

Hold on... I need to remember the limitations. Section 2 highlights structurally unreachable hardware, like vendor-specific PCIe switches, and driver teardown paths. And the overarching principle is *reachability* – can the code *actually* execute in standard virtualized environments like QEMU or GCE?

Right. So, does syzkaller have *any* way to reach `bcmgenet` on `amd64`? Can it instantiate a `platform_device`? No. Syzkaller is constrained to syscalls, emulated USB devices, and these types of things. It can't create `platform_devices` as these require SoC device tree nodes or ACPI tables, which won't probe in standard virtualized environments (QEMU x86_64 pc/q35 or GCE amd64 instances).

Therefore, I'm confident that `bcmgenet_probe` will *never* be called. If `bcmgenet_probe` isn't called, then `register_netdev` will never register a `net_device` for `bcmgenet`. Consequently, the network device operations like `bcmgenet_open`, `bcmgenet_xmit`, etc., are completely inaccessible.

Okay, just to be absolutely certain, I need to perform a thorough grep across the *entire* kernel source tree, looking for any other potential interface, sysfs or configfs entry, anything that could possibly trigger `bcmgenet`. No assumptions. I need to be 100% sure.



20/2 2026/10/05 22:33 tool grepper
0m Args:
{
  "Expression": "bcmgenet"
}

Results:
{
  "Output": "\nFull output is too long, showing 200 out of 2753 lines.\nUse more precise expression or PathPrefixes if possible.\n\nNumber of matching lines per file (7 files in total):\nDocumentation/devicetree/bindings/net/brcm,bcmgenet.yaml:1\nMAINTAINERS:1\ndrivers/net/ethernet/broadcom/genet/Makefile:1\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:751\ndrivers/net/ethernet/broadcom/genet/bcmgenet.h:56\ndrivers/net/ethernet/broadcom/genet/bcmgenet_wol.c:36\ndrivers/net/ethernet/broadcom/genet/bcmmii.c:64\n\nDocumentation/devicetree/bindings/net/brcm,bcmgenet.yaml-3----\nDocumentation/devicetree/bindings/net/brcm,bcmgenet.yaml:4:$id: http://devicetree.org/schemas/net/brcm,bcmgenet.yaml#\nDocumentation/devicetree/bindings/net/brcm,bcmgenet.yaml-5-$schema: http://devicetree.org/meta-schemas/core.yaml#\n--\nMAINTAINERS=5461=S:\tMaintained\nMAINTAINERS:5462:F:\tDocumentation/devicetree/bindings/net/brcm,bcmgenet.yaml\nMAINTAINERS-5463-F:\tDocumentation/devicetree/bindings/net/brcm,unimac-mdio.yaml\n--\ndrivers/net/ethernet/broadcom/genet/Makefile=2=obj-$(CONFIG_BCMGENET) += genet.o\ndrivers/net/ethernet/broadcom/genet/Makefile:3:genet-objs := bcmgenet.o bcmmii.o bcmgenet_wol.o\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-7-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:8:#define pr_fmt(fmt)\t\t\t\t\"bcmgenet: \" fmt\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-9-\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-40-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:41:#include \"bcmgenet.h\"\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-42-\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-100-/* Forward declarations */\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:101:static void bcmgenet_set_rx_mode(struct net_device *dev);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-102-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:103:static inline void bcmgenet_writel(u32 value, void __iomem *offset)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-104-{\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-113-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:114:static inline u32 bcmgenet_readl(void __iomem *offset)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-115-{\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-121-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:122:static inline void dmadesc_set_length_status(struct bcmgenet_priv *priv,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-123-\t\t\t\t\t     void __iomem *d, u32 value)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-124-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:125:\tbcmgenet_writel(value, d + DMA_DESC_LENGTH_STATUS);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-126-}\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-127-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:128:static inline void dmadesc_set_addr(struct bcmgenet_priv *priv,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-129-\t\t\t\t    void __iomem *d,\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-131-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:132:\tbcmgenet_writel(lower_32_bits(addr), d + DMA_DESC_ADDRESS_LO);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-133-\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-138-#ifdef CONFIG_PHYS_ADDR_T_64BIT\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:139:\tif (bcmgenet_has_40bits(priv))\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:140:\t\tbcmgenet_writel(upper_32_bits(addr), d + DMA_DESC_ADDRESS_HI);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-141-#endif\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-144-/* Combined address + length/status setter */\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:145:static inline void dmadesc_set(struct bcmgenet_priv *priv,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-146-\t\t\t       void __iomem *d, dma_addr_t addr, u32 val)\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-156-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:157:static inline u32 bcmgenet_rbuf_ctrl_get(struct bcmgenet_priv *priv)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-158-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-159-\tif (GENET_IS_V1(priv))\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:160:\t\treturn bcmgenet_rbuf_readl(priv, RBUF_FLUSH_CTRL_V1);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-161-\telse\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:162:\t\treturn bcmgenet_sys_readl(priv, SYS_RBUF_FLUSH_CTRL);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-163-}\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-164-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:165:static inline void bcmgenet_rbuf_ctrl_set(struct bcmgenet_priv *priv, u32 val)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-166-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-167-\tif (GENET_IS_V1(priv))\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:168:\t\tbcmgenet_rbuf_writel(priv, val, RBUF_FLUSH_CTRL_V1);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-169-\telse\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:170:\t\tbcmgenet_sys_writel(priv, val, SYS_RBUF_FLUSH_CTRL);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-171-}\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-176- */\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:177:static inline u32 bcmgenet_tbuf_ctrl_get(struct bcmgenet_priv *priv)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-178-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-179-\tif (GENET_IS_V1(priv))\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:180:\t\treturn bcmgenet_rbuf_readl(priv, TBUF_CTRL_V1);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-181-\telse\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:182:\t\treturn bcmgenet_readl(priv-\u003ebase +\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-183-\t\t\t\t      priv-\u003ehw_params-\u003etbuf_offset + TBUF_CTRL);\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-185-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:186:static inline void bcmgenet_tbuf_ctrl_set(struct bcmgenet_priv *priv, u32 val)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-187-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-188-\tif (GENET_IS_V1(priv))\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:189:\t\tbcmgenet_rbuf_writel(priv, val, TBUF_CTRL_V1);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-190-\telse\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:191:\t\tbcmgenet_writel(val, priv-\u003ebase +\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-192-\t\t\t\tpriv-\u003ehw_params-\u003etbuf_offset + TBUF_CTRL);\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-194-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:195:static inline u32 bcmgenet_bp_mc_get(struct bcmgenet_priv *priv)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-196-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-197-\tif (GENET_IS_V1(priv))\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:198:\t\treturn bcmgenet_rbuf_readl(priv, TBUF_BP_MC_V1);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-199-\telse\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:200:\t\treturn bcmgenet_readl(priv-\u003ebase +\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-201-\t\t\t\t      priv-\u003ehw_params-\u003etbuf_offset + TBUF_BP_MC);\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-203-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:204:static inline void bcmgenet_bp_mc_set(struct bcmgenet_priv *priv, u32 val)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-205-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-206-\tif (GENET_IS_V1(priv))\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:207:\t\tbcmgenet_rbuf_writel(priv, val, TBUF_BP_MC_V1);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-208-\telse\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:209:\t\tbcmgenet_writel(val, priv-\u003ebase +\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-210-\t\t\t\tpriv-\u003ehw_params-\u003etbuf_offset + TBUF_BP_MC);\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c=214=enum dma_reg {\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-249-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:250:static const u8 bcmgenet_dma_regs_v3plus[] = {\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-251-\t[DMA_RING_CFG]\t\t= 0x00,\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-285-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:286:static const u8 bcmgenet_dma_regs_v2[] = {\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-287-\t[DMA_RING_CFG]\t\t= 0x00,\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-313-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:314:static const u8 bcmgenet_dma_regs_v1[] = {\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-315-\t[DMA_CTRL]\t\t= 0x00,\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-340-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:341:/* Set at runtime once bcmgenet version is known */\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:342:static const u8 *bcmgenet_dma_regs;\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-343-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:344:static inline struct bcmgenet_priv *dev_to_priv(struct device *dev)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-345-{\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-348-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:349:static inline u32 bcmgenet_tdma_readl(struct bcmgenet_priv *priv,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-350-\t\t\t\t      enum dma_reg r)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-351-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:352:\treturn bcmgenet_readl(priv-\u003ebase + GENET_TDMA_REG_OFF +\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:353:\t\t\t      DMA_RINGS_SIZE + bcmgenet_dma_regs[r]);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-354-}\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-355-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:356:static inline void bcmgenet_tdma_writel(struct bcmgenet_priv *priv,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-357-\t\t\t\t\tu32 val, enum dma_reg r)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-358-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:359:\tbcmgenet_writel(val, priv-\u003ebase + GENET_TDMA_REG_OFF +\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:360:\t\t\tDMA_RINGS_SIZE + bcmgenet_dma_regs[r]);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-361-}\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-362-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:363:static inline u32 bcmgenet_rdma_readl(struct bcmgenet_priv *priv,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-364-\t\t\t\t      enum dma_reg r)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-365-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:366:\treturn bcmgenet_readl(priv-\u003ebase + GENET_RDMA_REG_OFF +\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:367:\t\t\t      DMA_RINGS_SIZE + bcmgenet_dma_regs[r]);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-368-}\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-369-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:370:static inline void bcmgenet_rdma_writel(struct bcmgenet_priv *priv,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-371-\t\t\t\t\tu32 val, enum dma_reg r)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-372-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:373:\tbcmgenet_writel(val, priv-\u003ebase + GENET_RDMA_REG_OFF +\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:374:\t\t\tDMA_RINGS_SIZE + bcmgenet_dma_regs[r]);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-375-}\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c=438=static const u8 *genet_dma_ring_regs;\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-439-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:440:static inline u32 bcmgenet_tdma_ring_readl(struct bcmgenet_priv *priv,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-441-\t\t\t\t\t   unsigned int ring,\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-443-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:444:\treturn bcmgenet_readl(priv-\u003ebase + GENET_TDMA_REG_OFF +\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-445-\t\t\t      (DMA_RING_SIZE * ring) +\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-448-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:449:static inline void bcmgenet_tdma_ring_writel(struct bcmgenet_priv *priv,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-450-\t\t\t\t\t     unsigned int ring, u32 val,\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-452-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:453:\tbcmgenet_writel(val, priv-\u003ebase + GENET_TDMA_REG_OFF +\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-454-\t\t\t(DMA_RING_SIZE * ring) +\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-457-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:458:static inline u32 bcmgenet_rdma_ring_readl(struct bcmgenet_priv *priv,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-459-\t\t\t\t\t   unsigned int ring,\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-461-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:462:\treturn bcmgenet_readl(priv-\u003ebase + GENET_RDMA_REG_OFF +\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-463-\t\t\t      (DMA_RING_SIZE * ring) +\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-466-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:467:static inline void bcmgenet_rdma_ring_writel(struct bcmgenet_priv *priv,\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-468-\t\t\t\t\t     unsigned int ring, u32 val,\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-470-{\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:471:\tbcmgenet_writel(val, priv-\u003ebase + GENET_RDMA_REG_OFF +\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-472-\t\t\t(DMA_RING_SIZE * ring) +\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-475-\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:476:static void bcmgenet_hfb_enable_filter(struct bcmgenet_priv *priv, u32 f_index)\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-477-{\n--\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-481-\tif (GENET_IS_V1(priv) || GENET_IS_V2(priv)) {\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:482:\t\treg = bcmgenet_hfb_reg_readl(priv, HFB_CTRL);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-483-\t\treg |= (1 \u003c\u003c ((f_index % 32) + RBUF_HFB_FILTER_EN_SHIFT)) |\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-484-\t\t\tRBUF_HFB_EN;\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:485:\t\tbcmgenet_hfb_reg_writel(priv, reg, HFB_CTRL);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-486-\t} else {\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c-487-\t\toffset = HFB_FLT_ENABLE_V3PLUS + (f_index \u003c 32) * sizeof(u32);\ndrivers/net/ethernet/broadcom/genet/bcmgenet.c:488:\t\treg = bcmgenet_hfb_reg_readl(priv, offset);\n\n"
}

21/2 2026/10/05 22:33 llm patch-evaluator
0m Model:
gemini-3.8-flash

Args:
null

Results:
null

Tokens:
							input: 24673
							output: 142
							thoughts: 854
						

Thoughts:
**WorthFuzzing Decision: Negative**

Okay, let's break this down. First, I need to confirm if `bcmgenet` is indeed a platform device. Yep, `bcmgenet_driver` is registered with `module_platform_driver()`. That means it's tightly coupled to the underlying hardware. Can it be instantiated without specific hardware, like device trees or ACPI tables? Absolutely not. That's the crux of it.

Now, considering the environment: we're targeting amd64 in standard virtualized setups – QEMU or Google Compute Engine. I need to be certain. I know that there's no BCMGENET emulation for x86_64 in QEMU. There are no device tree nodes or ACPI tables for BCMGENET on amd64 VMs. It is specific to Broadcom's SoC network controllers, like those in set-top boxes and the Raspberry Pi 4. It's a physical controller. It isn't something that can be emulated or dynamically instantiated either in userspace or with syzkaller.

Let's carefully refer to the section on negative criteria. Specifically, Section 2 is what's important here. I must return `WorthFuzzing=false` only if the modified code falls strictly into the listed categories.  Here it is. Structurally unreachable hardware is what concerns me: vendor-specific PCIe switches, SmartNICs, GPU drivers requiring physical hardware not emulated in standard QEMU.  This aligns perfectly with what I am observing. The core triage philosophy emphasizes reachability above all else. If the code is unreachable, it must not be fuzzed, no matter what it adds.

The target architecture is explicitly stated as amd64, which is crucial. Broadcom GENET is an SoC controller meant for ARM/MIPS chips (like those in Broadcom BCM7xxx or BCM2711). There's no hardware or QEMU emulation for BCMGENET on amd64.  So, the modified code is completely unreachable in the target environment of amd64 QEMU/GCE.

I've double-checked.  The patch modifies only `drivers/net/ethernet/broadcom/genet/bcmgenet.c` and `bcmgenet.h`. This is all contained in the `drivers/net/ethernet/broadcom/genet/` directory.

Therefore, since the modified code is structurally unreachable on amd64 in a standard virtualized environment, `WorthFuzzing` has to be false.

Now I need to construct the arguments for `set-results`. It will be:

*   `WorthFuzzing: false`
*   `Reasoning:` The BCMGENET is an SoC Ethernet MAC controller specific to Broadcom ARM/MIPS chipsets. It is a platform driver instantiated via Device Tree or specific ACPI tables and it is not emulated in standard QEMU or GCE amd64 environments. As such, the driver code is structurally unreachable on the amd64 target architecture.
*   `EnableConfigs: []` (empty, because it is not fuzzed)
*   `FocusSymbols: []` (empty, because it is not fuzzed)

And, now I will run `set-results`.



22/2 2026/10/05 22:33 tool set-results
0m Args:
{
  "EnableConfigs": [],
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the Broadcom GENET Ethernet driver (bcmgenet), which is an SoC network controller found on Broadcom ARM/MIPS platforms (BCM7xxx, Raspberry Pi 4). The driver is registered as a platform driver matching device-tree compatible strings and specific ARM64 ACPI tables. It is structurally unreachable in standard virtualized environments (QEMU/GCE) on amd64, as there is no corresponding hardware emulation. Therefore, the modified code cannot be executed during fuzzing on amd64.",
  "WorthFuzzing": false
}

Results:
{
  "EnableConfigs": null,
  "FocusSymbols": [],
  "Reasoning": "The patch modifies the Broadcom GENET Ethernet driver (bcmgenet), which is an SoC network controller found on Broadcom ARM/MIPS platforms (BCM7xxx, Raspberry Pi 4). The driver is registered as a platform driver matching device-tree compatible strings and specific ARM64 ACPI tables. It is structurally unreachable in standard virtualized environments (QEMU/GCE) on amd64, as there is no corresponding hardware emulation. Therefore, the modified code cannot be executed during fuzzing on amd64.",
  "WorthFuzzing": false
}

23/1 2026/10/05 22:33 action If
0m Args:
{
  "WorthFuzzing": false
}

Results:
null

LLM Calls Summary:
Total Calls Total Tokens Avg Tokens Total Duration (Seconds) Avg Duration (Seconds)
Tool Calls Summary:
Total Calls Total Duration (Seconds) Avg Duration (Seconds)