e1000e: Fix EIAC register implementation
authorDmitry Fleytman <dmitry@daynix.com>
Thu, 15 Sep 2016 06:14:30 +0000 (09:14 +0300)
committerJason Wang <jasowang@redhat.com>
Tue, 27 Sep 2016 09:54:22 +0000 (17:54 +0800)
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>
hw/net/e1000e_core.c

index 02981364a3bfed4df8eacbd73c38651923b58743..6505983c12e603073722addc9284af42faecbd63 100644 (file)
@@ -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