summary refs log tree commit diff stats
path: root/hw/lan9118.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/lan9118.c')
-rw-r--r--hw/lan9118.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/hw/lan9118.c b/hw/lan9118.c
index 4c42fe94c2..3f3c05df4c 100644
--- a/hw/lan9118.c
+++ b/hw/lan9118.c
@@ -228,6 +228,12 @@ static void lan9118_update(lan9118_state *s)
     if ((s->irq_cfg & IRQ_EN) == 0) {
         level = 0;
     }
+    if ((s->irq_cfg & (IRQ_TYPE | IRQ_POL)) != (IRQ_TYPE | IRQ_POL)) {
+        /* Interrupt is active low unless we're configured as
+         * active-high polarity, push-pull type.
+         */
+        level = !level;
+    }
     qemu_set_irq(s->irq, level);
 }
 
@@ -294,8 +300,7 @@ static void phy_reset(lan9118_state *s)
 static void lan9118_reset(DeviceState *d)
 {
     lan9118_state *s = FROM_SYSBUS(lan9118_state, sysbus_from_qdev(d));
-
-    s->irq_cfg &= ~(IRQ_TYPE | IRQ_POL);
+    s->irq_cfg &= (IRQ_TYPE | IRQ_POL);
     s->int_sts = 0;
     s->int_en = 0;
     s->fifo_int = 0x48000000;
@@ -904,7 +909,8 @@ static void lan9118_writel(void *opaque, target_phys_addr_t offset,
     switch (offset) {
     case CSR_IRQ_CFG:
         /* TODO: Implement interrupt deassertion intervals.  */
-        s->irq_cfg = (s->irq_cfg & IRQ_INT) | (val & IRQ_EN);
+        val &= (IRQ_EN | IRQ_POL | IRQ_TYPE);
+        s->irq_cfg = (s->irq_cfg & IRQ_INT) | val;
         break;
     case CSR_INT_STS:
         s->int_sts &= ~val;