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);