From fe619f2005b15b14f718c56a57152c5c1c06b4c8 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Tue, 23 May 2023 11:43:18 +0900 Subject: [PATCH] igb: Clear EICR bits for delayed MSI-X interrupts Section 7.3.4.1 says: > When auto-clear is enabled for an interrupt cause, the EICR bit is > set when a cause event mapped to this vector occurs. When the EITR > Counter reaches zero, the MSI-X message is sent on PCIe. Then the > EICR bit is cleared and enabled to be set by a new cause event Signed-off-by: Akihiko Odaki Signed-off-by: Jason Wang --- hw/net/igb_core.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/hw/net/igb_core.c b/hw/net/igb_core.c index 20645c4764..edda07e564 100644 --- a/hw/net/igb_core.c +++ b/hw/net/igb_core.c @@ -97,23 +97,31 @@ igb_lower_legacy_irq(IGBCore *core) pci_set_irq(core->owner, 0); } -static void igb_msix_notify(IGBCore *core, unsigned int vector) +static void igb_msix_notify(IGBCore *core, unsigned int cause) { PCIDevice *dev = core->owner; uint16_t vfn; + uint32_t effective_eiac; + unsigned int vector; - vfn = 8 - (vector + 2) / IGBVF_MSIX_VEC_NUM; + vfn = 8 - (cause + 2) / IGBVF_MSIX_VEC_NUM; if (vfn < pcie_sriov_num_vfs(core->owner)) { dev = pcie_sriov_get_vf_at_index(core->owner, vfn); assert(dev); - vector = (vector + 2) % IGBVF_MSIX_VEC_NUM; - } else if (vector >= IGB_MSIX_VEC_NUM) { + vector = (cause + 2) % IGBVF_MSIX_VEC_NUM; + } else if (cause >= IGB_MSIX_VEC_NUM) { qemu_log_mask(LOG_GUEST_ERROR, "igb: Tried to use vector unavailable for PF"); return; + } else { + vector = cause; } msix_notify(dev, vector); + + trace_e1000e_irq_icr_clear_eiac(core->mac[EICR], core->mac[EIAC]); + effective_eiac = core->mac[EIAC] & BIT(cause); + core->mac[EICR] &= ~effective_eiac; } static inline void @@ -1834,7 +1842,6 @@ igb_eitr_should_postpone(IGBCore *core, int idx) static void igb_send_msix(IGBCore *core) { uint32_t causes = core->mac[EICR] & core->mac[EIMS]; - uint32_t effective_eiac; int vector; for (vector = 0; vector < IGB_INTR_NUM; ++vector) { @@ -1842,10 +1849,6 @@ static void igb_send_msix(IGBCore *core) trace_e1000e_irq_msix_notify_vec(vector); igb_msix_notify(core, vector); - - trace_e1000e_irq_icr_clear_eiac(core->mac[EICR], core->mac[EIAC]); - effective_eiac = core->mac[EIAC] & BIT(vector); - core->mac[EICR] &= ~effective_eiac; } } } -- 2.11.0