Commit 34c1f0a45b for qemu.org

commit 34c1f0a45ba26ae493cd1a8db8bf09c8199e5a03
Author: Helge Deller <deller@gmx.de>
Date:   Thu Nov 5 00:27:14 2026 +0100

    i82596: Initialize variables at chip reset

    Do proper initialization of various pointers and register values at chip
    reset and add a timer to trigger delivery retry when the RX ring is
    full.

    Noticed-by: Keith Monahan <keith@techtravels.org>
    Signed-off-by: Helge Deller <deller@gmx.de>

diff --git a/hw/net/i82596.c b/hw/net/i82596.c
index a518aa7696..35e0b58330 100644
--- a/hw/net/i82596.c
+++ b/hw/net/i82596.c
@@ -359,6 +359,13 @@ static void i82596_s_reset(I82596State *s)
     s->last_tx_len = 0;

     s->last_good_rfa = 0;
+    s->rbd_p = I596_NULL;
+    s->rx_take_el = false;
+    s->rfd_p = I596_NULL;
+    s->rx_hold_start = 0;
+    if (s->rx_retry_timer) {
+        timer_del(s->rx_retry_timer);
+    }
     s->queue_head = 0;
     s->queue_tail = 0;
     s->queue_count = 0;
diff --git a/hw/net/i82596.h b/hw/net/i82596.h
index ec0b6a75ba..15370837cd 100644
--- a/hw/net/i82596.h
+++ b/hw/net/i82596.h
@@ -25,6 +25,7 @@ struct I82596State_st {
     NICState *nic;
     NICConf conf;
     QEMUTimer *flush_queue_timer;
+    QEMUTimer *rx_retry_timer;  /* retries delivery while the RX ring is full */
     uint8_t mode;

     QEMUTimer *throttle_timer;
@@ -78,6 +79,7 @@ struct I82596State_st {
     uint32_t rbd_p;         /* next free RBD, loaded from the first RFD at RU start */
     bool rx_take_el;        /* hold timed out: fill the EL RBD like the chip does */
     uint32_t rfd_p;         /* next RFD, loaded from the SCB at RU start */
+    int64_t rx_hold_start;  /* frames held since (virtual ns), 0 if not */
     uint8_t packet_queue[PACKET_QUEUE_SIZE][PKT_BUF_SZ];
     size_t packet_queue_len[PACKET_QUEUE_SIZE];
     int queue_head;