mirror of https://github.com/xemu-project/xemu.git
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>
This commit is contained in:
parent
882e54da90
commit
fe619f2005
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue