summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDmitry Fleytman <dmitry@daynix.com>2016-09-15 09:14:30 +0300
committerJason Wang <jasowang@redhat.com>2016-09-27 17:54:22 +0800
commitb38636b83727d611a354217fa9d17de5872d7da4 (patch)
tree8cd7abcf94abac3cfee1ff8ed26976f1ff29be08
parent4100c026b69001f774bfff30b5773a2418306f8c (diff)
downloadfocaccia-qemu-b38636b83727d611a354217fa9d17de5872d7da4.tar.gz
focaccia-qemu-b38636b83727d611a354217fa9d17de5872d7da4.zip
e1000e: Fix EIAC register implementation
This patch fixes 2 issues:

1. Bits set in EIAC register should be cleared
   from IMS when EIAM is not used.
2. Only bit that corresonds to the interrupt being
   raised should be cleared.

See spec. 10.2.4.7 Interrupt Auto Clear

Signed-off-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
-rw-r--r--hw/net/e1000e_core.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
index 02981364a3..6505983c12 100644
--- a/hw/net/e1000e_core.c
+++ b/hw/net/e1000e_core.c
@@ -2015,13 +2015,17 @@ e1000e_msix_notify_one(E1000ECore *core, uint32_t cause, uint32_t int_cfg)
 
     trace_e1000e_irq_icr_clear_eiac(core->mac[ICR], core->mac[EIAC]);
 
-    if (core->mac[EIAC] & E1000_ICR_OTHER) {
-        effective_eiac = (core->mac[EIAC] & E1000_EIAC_MASK) |
-                         E1000_ICR_OTHER_CAUSES;
-    } else {
-        effective_eiac = core->mac[EIAC] & E1000_EIAC_MASK;
+    effective_eiac = core->mac[EIAC] & cause;
+
+    if (effective_eiac == E1000_ICR_OTHER) {
+        effective_eiac |= E1000_ICR_OTHER_CAUSES;
     }
+
     core->mac[ICR] &= ~effective_eiac;
+
+    if (!(core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) {
+        core->mac[IMS] &= ~effective_eiac;
+    }
 }
 
 static void