Commit 7edcb320 authored by Antoine Kaufmann's avatar Antoine Kaufmann
Browse files

i40e_bm: support for MSI-X

parent 1eccc875
......@@ -29,12 +29,24 @@ void i40e_bm::setup_intro(struct cosim_pcie_proto_dev_intro &di)
di.bars[BAR_REGS].flags = COSIM_PCIE_PROTO_BAR_64;
di.bars[BAR_IO].len = 32;
di.bars[BAR_IO].flags = COSIM_PCIE_PROTO_BAR_IO;
di.bars[BAR_MSIX].len = 32 * 1024;
di.bars[BAR_MSIX].flags = COSIM_PCIE_PROTO_BAR_64 |
COSIM_PCIE_PROTO_BAR_DUMMY;
di.pci_vendor_id = I40E_INTEL_VENDOR_ID;
di.pci_device_id = I40E_DEV_ID_QSFP_A;
di.pci_class = 0x02;
di.pci_subclass = 0x00;
di.pci_revision = 0x01;
di.pci_msi_nvecs = 32;
di.pci_msix_nvecs = 0x80;
di.pci_msix_table_bar = BAR_MSIX;
di.pci_msix_pba_bar = BAR_MSIX;
di.pci_msix_table_offset = 0x0;
di.pci_msix_pba_offset = 0x1000;
di.psi_msix_cap_offset = 0x70;
}
void i40e_bm::dma_complete(nicbm::DMAOp &op)
......@@ -195,6 +207,18 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr)
addr <= I40E_PFQF_HLUT(I40E_PFQF_HLUT_MAX_INDEX))
{
val = regs.pfqf_hlut[(addr - I40E_PFQF_HLUT(0)) / 128];
} else if (addr >= I40E_PFINT_ITRN(0, 0) &&
addr <= I40E_PFINT_ITRN(0, NUM_PFINTS - 1))
{
val = regs.pfint_itrn[0][(addr - I40E_PFINT_ITRN(0, 0)) / 4];
} else if (addr >= I40E_PFINT_ITRN(1, 0) &&
addr <= I40E_PFINT_ITRN(1, NUM_PFINTS - 1))
{
val = regs.pfint_itrn[1][(addr - I40E_PFINT_ITRN(1, 0)) / 4];
} else if (addr >= I40E_PFINT_ITRN(2, 0) &&
addr <= I40E_PFINT_ITRN(2, NUM_PFINTS - 1))
{
val = regs.pfint_itrn[2][(addr - I40E_PFINT_ITRN(2, 0)) / 4];
} else {
switch (addr) {
......@@ -249,6 +273,10 @@ uint32_t i40e_bm::reg_mem_read32(uint64_t addr)
regs.pfint_icr0 = 0;
break;
case I40E_PFINT_STAT_CTL0:
val = regs.pfint_stat_ctl0;
break;
case I40E_PFINT_DYN_CTL0:
val = regs.pfint_dyn_ctl0;
break;
......@@ -504,6 +532,18 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val)
addr <= I40E_PFQF_HLUT(I40E_PFQF_HLUT_MAX_INDEX))
{
regs.pfqf_hlut[(addr - I40E_PFQF_HLUT(0)) / 128] = val;
} else if (addr >= I40E_PFINT_ITRN(0, 0) &&
addr <= I40E_PFINT_ITRN(0, NUM_PFINTS - 1))
{
regs.pfint_itrn[0][(addr - I40E_PFINT_ITRN(0, 0)) / 4] = val;
} else if (addr >= I40E_PFINT_ITRN(1, 0) &&
addr <= I40E_PFINT_ITRN(1, NUM_PFINTS - 1))
{
regs.pfint_itrn[1][(addr - I40E_PFINT_ITRN(1, 0)) / 4] = val;
} else if (addr >= I40E_PFINT_ITRN(2, 0) &&
addr <= I40E_PFINT_ITRN(2, NUM_PFINTS - 1))
{
regs.pfint_itrn[2][(addr - I40E_PFINT_ITRN(2, 0)) / 4] = val;
} else {
switch (addr) {
case I40E_PFGEN_CTRL:
......@@ -543,6 +583,9 @@ void i40e_bm::reg_mem_write32(uint64_t addr, uint32_t val)
case I40E_PFINT_ICR0:
regs.pfint_icr0 = val;
break;
case I40E_PFINT_STAT_CTL0:
regs.pfint_stat_ctl0 = val;
break;
case I40E_PFINT_DYN_CTL0:
regs.pfint_dyn_ctl0 = val;
break;
......@@ -659,22 +702,28 @@ void i40e_bm::timed_event(nicbm::TimedEvent &ev)
logger::endl;
#endif
iev.armed = false;
runner->msi_issue(0);
}
void i40e_bm::signal_interrupt(uint16_t vector, uint8_t itr)
{
if (vector != 0) {
log << "signal_interrupt() only supports vector 0" << logger::endl;
if (int_msix_en) {
runner->msix_issue(iev.vector);
} else if (iev.vector > 0) {
log << "timed_event: MSI-X disabled, but vector != 0" << logger::endl;
abort();
} else if (int_msi_en) {
runner->msi_issue(0);
}
}
void i40e_bm::signal_interrupt(uint16_t vector, uint8_t itr)
{
int_ev &iev = intevs[vector];
uint64_t mindelay;
if (itr <= 2) {
// itr 0-2
mindelay = regs.pfint_itr0[itr];
if (vector == 0)
mindelay = regs.pfint_itr0[itr];
else
mindelay = regs.pfint_itrn[itr][vector];
mindelay *= 2000000ULL;
} else if (itr == 3) {
// noitr
......
......@@ -474,9 +474,10 @@ protected:
static const unsigned BAR_REGS = 0;
static const unsigned BAR_IO = 2;
static const unsigned BAR_MSIX = 3;
static const uint32_t NUM_QUEUES = 1536;
static const uint32_t NUM_PFINTS = 512;
static const uint32_t NUM_PFINTS = 128;
static const uint32_t NUM_VSIS = 384;
static const uint16_t MAX_MTU = 2048;
static const uint8_t NUM_ITR = 3;
......@@ -489,7 +490,9 @@ protected:
uint32_t pfint_icr0_ena;
uint32_t pfint_icr0;
uint32_t pfint_itr0[NUM_ITR];
uint32_t pfint_itrn[NUM_ITR][NUM_PFINTS];
uint32_t pfint_stat_ctl0;
uint32_t pfint_dyn_ctl0;
uint32_t pfint_dyn_ctln[NUM_PFINTS - 1];
uint32_t pfint_lnklstn[NUM_PFINTS - 1];
......
......@@ -194,15 +194,10 @@ void lan_queue_base::interrupt()
#endif
uint16_t msix_idx = (qctl & I40E_QINT_TQCTL_MSIX_INDX_MASK) >>
I40E_QINT_TQCTL_ITR_INDX_SHIFT;
I40E_QINT_TQCTL_MSIX_INDX_SHIFT;
uint8_t msix0_idx = (qctl & I40E_QINT_TQCTL_MSIX0_INDX_MASK) >>
I40E_QINT_TQCTL_MSIX0_INDX_SHIFT;
if (msix_idx != 0) {
log << "TODO: only int 0 is supported" << logger::endl;
abort();
}
bool cause_ena = !!(qctl & I40E_QINT_TQCTL_CAUSE_ENA_MASK) &&
!!(gctl & I40E_PFINT_DYN_CTL0_INTENA_MASK);
if (!cause_ena) {
......@@ -212,16 +207,17 @@ void lan_queue_base::interrupt()
return;
}
// TODO throttling?
if (msix_idx == 0) {
#ifdef DEBUG_LAN
log << " setting int0.qidx=" << msix0_idx << logger::endl;
log << " setting int0.qidx=" << msix0_idx << logger::endl;
#endif
lanmgr.dev.regs.pfint_icr0 |= I40E_PFINT_ICR0_INTEVENT_MASK |
(1 << (I40E_PFINT_ICR0_QUEUE_0_SHIFT + msix0_idx));
lanmgr.dev.regs.pfint_icr0 |= I40E_PFINT_ICR0_INTEVENT_MASK |
(1 << (I40E_PFINT_ICR0_QUEUE_0_SHIFT + msix0_idx));
}
uint8_t itr = (qctl & I40E_QINT_TQCTL_ITR_INDX_MASK) >>
I40E_QINT_TQCTL_ITR_INDX_SHIFT;
lanmgr.dev.signal_interrupt(0, itr);
lanmgr.dev.signal_interrupt(msix_idx, itr);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment