ixgbe: Clear head write-back registers on VF reset
authorAlexander Duyck <alexander.h.duyck@intel.com>
Thu, 16 Jan 2014 01:38:41 +0000 (17:38 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 16 Jan 2014 05:48:18 +0000 (21:48 -0800)
The Tx head write-back registers are not cleared during an FLR or VF reset.
As a result a configuration that had head write-back enabled can leave the
registers set after the driver is unloaded.  If the next driver loaded doesn't
use the write-back registers this can lead to a bad configuration where
head write-back is enabled, but the driver didn't request it.

To avoid this situation the PF should be resetting the Tx head write-back
registers when the VF requests a reset.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Phil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h

index 43e10c67ac4e278a08f2fe8c860635d275e31bc6..0558c7139f38ec307c3ce503856735cb7a970e37 100644 (file)
@@ -698,6 +698,15 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
        reg |= (1 << vf_shift);
        IXGBE_WRITE_REG(hw, IXGBE_VMECM(reg_offset), reg);
 
+       /*
+        * Reset the VFs TDWBAL and TDWBAH registers
+        * which are not cleared by an FLR
+        */
+       for (i = 0; i < q_per_pool; i++) {
+               IXGBE_WRITE_REG(hw, IXGBE_PVFTDWBAHn(q_per_pool, vf, i), 0);
+               IXGBE_WRITE_REG(hw, IXGBE_PVFTDWBALn(q_per_pool, vf, i), 0);
+       }
+
        /* reply to reset with ack and vf mac address */
        msgbuf[0] = IXGBE_VF_RESET;
        if (!is_zero_ether_addr(vf_mac)) {
index d8e59f42b85c1b75bfcdfa8de97b2c3d51c0f1ee..0d39cfc4a3bf2aa84294b4a12cf91b4a3a5353da 100644 (file)
@@ -2174,6 +2174,14 @@ enum {
 #define IXGBE_MBVFICR(_i)              (0x00710 + ((_i) * 4))
 #define IXGBE_VFLRE(_i)                ((((_i) & 1) ? 0x001C0 : 0x00600))
 #define IXGBE_VFLREC(_i)               (0x00700 + ((_i) * 4))
+/* Translated register #defines */
+#define IXGBE_PVFTDWBAL(P)     (0x06038 + (0x40 * (P)))
+#define IXGBE_PVFTDWBAH(P)     (0x0603C + (0x40 * (P)))
+
+#define IXGBE_PVFTDWBALn(q_per_pool, vf_number, vf_q_index) \
+               (IXGBE_PVFTDWBAL((q_per_pool)*(vf_number) + (vf_q_index)))
+#define IXGBE_PVFTDWBAHn(q_per_pool, vf_number, vf_q_index) \
+               (IXGBE_PVFTDWBAH((q_per_pool)*(vf_number) + (vf_q_index)))
 
 enum ixgbe_fdir_pballoc_type {
        IXGBE_FDIR_PBALLOC_NONE = 0,