Module Name: src Committed By: msaitoh Date: Tue Oct 3 03:12:29 UTC 2017
Modified Files: src/sys/dev/pci/ixgbe: ixv.c Log Message: Fix a problem that mailbox interrupt never occured. Bit definitions of PF's interrupt related registers and VF's interrupt registers a completely different. VF's registers (VF{EICR, EICS, EIMS, EIMC, EIAC, EIAM})'s bits are just MSI-X vector bitmask, so read/write correctly. Read VTEICR instead of VTEICS in ixv_msix_mbx (note that "PF" has a errata that EICS is required to read the cause). Don't write IXGBE_VTEICR in ixv_msix_mbx() because we use auto-clear for mailbox interrupt. We have gotten link status change by timer instead of interrupt before this fix... To generate a diff of this commit: cvs rdiff -u -r1.67 -r1.68 src/sys/dev/pci/ixgbe/ixv.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/ixgbe/ixv.c diff -u src/sys/dev/pci/ixgbe/ixv.c:1.67 src/sys/dev/pci/ixgbe/ixv.c:1.68 --- src/sys/dev/pci/ixgbe/ixv.c:1.67 Tue Oct 3 02:55:37 2017 +++ src/sys/dev/pci/ixgbe/ixv.c Tue Oct 3 03:12:29 2017 @@ -1,4 +1,4 @@ -/*$NetBSD: ixv.c,v 1.67 2017/10/03 02:55:37 msaitoh Exp $*/ +/*$NetBSD: ixv.c,v 1.68 2017/10/03 03:12:29 msaitoh Exp $*/ /****************************************************************************** @@ -682,7 +682,10 @@ ixv_init_locked(struct adapter *adapter) struct ifnet *ifp = adapter->ifp; device_t dev = adapter->dev; struct ixgbe_hw *hw = &adapter->hw; + struct ix_queue *que = adapter->queues; int error = 0; + uint32_t mask; + int i; INIT_DEBUGOUT("ixv_init_locked: begin"); KASSERT(mutex_owned(&adapter->core_mtx)); @@ -756,7 +759,10 @@ ixv_init_locked(struct adapter *adapter) ixv_configure_ivars(adapter); /* Set up auto-mask */ - IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, IXGBE_EICS_RTX_QUEUE); + mask = (1 << adapter->vector); + for (i = 0; i < adapter->num_queues; i++, que++) + mask |= (1 << que->msix); + IXGBE_WRITE_REG(hw, IXGBE_VTEIAM, mask); /* Set moderation on the Link interrupt */ IXGBE_WRITE_REG(hw, IXGBE_VTEITR(adapter->vector), IXGBE_LINK_ITR); @@ -911,15 +917,17 @@ ixv_msix_mbx(void *arg) ++adapter->link_irq.ev_count; /* First get the cause */ - reg = IXGBE_READ_REG(hw, IXGBE_VTEICS); + reg = IXGBE_READ_REG(hw, IXGBE_VTEICR); +#if 0 /* NetBSD: We use auto-clear, so it's not required to write VTEICR */ /* Clear interrupt with write */ - IXGBE_WRITE_REG(hw, IXGBE_VTEICR, reg); + IXGBE_WRITE_REG(hw, IXGBE_VTEICR, (1 << adapter->vector)); +#endif /* Link status change */ - if (reg & IXGBE_EICR_LSC) + if (reg & (1 << adapter->vector)) softint_schedule(adapter->link_si); - IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, IXGBE_EIMS_OTHER); + IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, (1 << adapter->vector)); return 1; } /* ixv_msix_mbx */ @@ -1846,16 +1854,18 @@ ixv_enable_intr(struct adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; struct ix_queue *que = adapter->queues; - u32 mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE); - - - IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, mask); + u32 mask; + int i; - mask = IXGBE_EIMS_ENABLE_MASK; - mask &= ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC); + /* For VTEIAC */ + mask = (1 << adapter->vector); + for (i = 0; i < adapter->num_queues; i++, que++) + mask |= (1 << que->msix); IXGBE_WRITE_REG(hw, IXGBE_VTEIAC, mask); - for (int i = 0; i < adapter->num_queues; i++, que++) + /* For VTEIMS */ + IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, (1 << adapter->vector)); + for (i = 0; i < adapter->num_queues; i++, que++) ixv_enable_queue(adapter, que->msix); IXGBE_WRITE_FLUSH(hw);