diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/net/e1000e_core.c | 10 | ||||
-rw-r--r-- | hw/net/virtio-net.c | 3 |
2 files changed, 11 insertions, 2 deletions
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c index 28c5be1506..81405640f0 100644 --- a/hw/net/e1000e_core.c +++ b/hw/net/e1000e_core.c @@ -2454,14 +2454,20 @@ e1000e_set_ics(E1000ECore *core, int index, uint32_t val) static void e1000e_set_icr(E1000ECore *core, int index, uint32_t val) { + uint32_t icr = 0; if ((core->mac[ICR] & E1000_ICR_ASSERTED) && (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) { trace_e1000e_irq_icr_process_iame(); e1000e_clear_ims_bits(core, core->mac[IAM]); } - trace_e1000e_irq_icr_write(val, core->mac[ICR], core->mac[ICR] & ~val); - core->mac[ICR] &= ~val; + icr = core->mac[ICR] & ~val; + /* Windows driver expects that the "receive overrun" bit and other + * ones to be cleared when the "Other" bit (#24) is cleared. + */ + icr = (val & E1000_ICR_OTHER) ? (icr & ~E1000_ICR_OTHER_CAUSES) : icr; + trace_e1000e_irq_icr_write(val, core->mac[ICR], icr); + core->mac[ICR] = icr; e1000e_update_interrupt_state(core); } diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 7d091c9259..98bd683f31 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1522,9 +1522,12 @@ static void virtio_net_del_queue(VirtIONet *n, int index) if (q->tx_timer) { timer_del(q->tx_timer); timer_free(q->tx_timer); + q->tx_timer = NULL; } else { qemu_bh_delete(q->tx_bh); + q->tx_bh = NULL; } + q->tx_waiting = 0; virtio_del_queue(vdev, index * 2 + 1); } |