aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbevf
diff options
context:
space:
mode:
authorGreg Rose <gregory.v.rose@intel.com>2010-05-05 19:57:49 +0000
committerDavid S. Miller <davem@davemloft.net>2010-05-06 00:31:45 -0700
commit08259594e047170923ef11d1482648642bfe606f (patch)
tree467b904e16abbc8f5a634a4178a680cc9abada48 /drivers/net/ixgbevf
parent8a07a22d856f37e580557c1a13c8eb8662f9cc11 (diff)
downloadkernel_samsung_smdk4412-08259594e047170923ef11d1482648642bfe606f.zip
kernel_samsung_smdk4412-08259594e047170923ef11d1482648642bfe606f.tar.gz
kernel_samsung_smdk4412-08259594e047170923ef11d1482648642bfe606f.tar.bz2
ixgbevf: Cache PF ack bit in interrupt
When the PF acks a message from the VF the VF gets an interrupt. It must cache the ack bit so that polling SW will not miss the ack. Also avoid reading the message buffer on acks because that also will clear the ack bit. Signed-off-by: Greg Rose <gregory.v.rose@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbevf')
-rw-r--r--drivers/net/ixgbevf/ixgbevf_main.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index 0870740..460c37f 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -961,12 +961,28 @@ static irqreturn_t ixgbevf_msix_mbx(int irq, void *data)
eicr = IXGBE_READ_REG(hw, IXGBE_VTEICS);
IXGBE_WRITE_REG(hw, IXGBE_VTEICR, eicr);
+ if (!hw->mbx.ops.check_for_ack(hw)) {
+ /*
+ * checking for the ack clears the PFACK bit. Place
+ * it back in the v2p_mailbox cache so that anyone
+ * polling for an ack will not miss it. Also
+ * avoid the read below because the code to read
+ * the mailbox will also clear the ack bit. This was
+ * causing lost acks. Just cache the bit and exit
+ * the IRQ handler.
+ */
+ hw->mbx.v2p_mailbox |= IXGBE_VFMAILBOX_PFACK;
+ goto out;
+ }
+
+ /* Not an ack interrupt, go ahead and read the message */
hw->mbx.ops.read(hw, &msg, 1);
if ((msg & IXGBE_MBVFICR_VFREQ_MASK) == IXGBE_PF_CONTROL_MSG)
mod_timer(&adapter->watchdog_timer,
round_jiffies(jiffies + 1));
+out:
return IRQ_HANDLED;
}