Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 <akihiko.odaki@daynix.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
  • Loading branch information
akihikodaki authored and jasowang committed May 23, 2023
1 parent 882e54d commit fe619f2
Showing 1 changed file with 12 additions and 9 deletions.
21 changes: 12 additions & 9 deletions hw/net/igb_core.c
Expand Up @@ -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
Expand Down Expand Up @@ -1834,18 +1842,13 @@ 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) {
if ((causes & BIT(vector)) && !igb_eitr_should_postpone(core, vector)) {

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;
}
}
}
Expand Down

0 comments on commit fe619f2

Please sign in to comment.