]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'ixgbe'
authorDavid S. Miller <davem@davemloft.net>
Thu, 16 Jan 2014 05:48:42 +0000 (21:48 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 16 Jan 2014 05:48:42 +0000 (21:48 -0800)
Aaron Brown says:

====================
Intel Wired LAN Driver Updates

This series contains several updates from Alex to ixgbe.

To avoid head of line blocking in the event a VF stops cleaning Rx descriptors
he makes sure QDE bits are set for a VF before the Rx queues are enabled.

To avoid a situation where the head write-back registers can remain set ofter
the driver is unloaded he clears them on a VF reset.

Alexander Duyck (2):
  ixgbe: Force QDE via PFQDE for VFs during reset
  ixgbe: Clear head write-back registers on VF reset
====================

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 359f6e60320d7321388d5c84f6c55827b051ff71..0558c7139f38ec307c3ce503856735cb7a970e37 100644 (file)
@@ -631,11 +631,14 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
 
 static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
 {
+       struct ixgbe_ring_feature *vmdq = &adapter->ring_feature[RING_F_VMDQ];
        struct ixgbe_hw *hw = &adapter->hw;
        unsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses;
        u32 reg, reg_offset, vf_shift;
        u32 msgbuf[4] = {0, 0, 0, 0};
        u8 *addr = (u8 *)(&msgbuf[1]);
+       u32 q_per_pool = __ALIGN_MASK(1, ~vmdq->mask);
+       int i;
 
        e_info(probe, "VF Reset msg received from vf %d\n", vf);
 
@@ -654,6 +657,17 @@ static int ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
        reg |= 1 << vf_shift;
        IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), reg);
 
+       /* force drop enable for all VF Rx queues */
+       for (i = vf * q_per_pool; i < ((vf + 1) * q_per_pool); i++) {
+               /* flush previous write */
+               IXGBE_WRITE_FLUSH(hw);
+
+               /* indicate to hardware that we want to set drop enable */
+               reg = IXGBE_QDE_WRITE | IXGBE_QDE_ENABLE;
+               reg |= i <<  IXGBE_QDE_IDX_SHIFT;
+               IXGBE_WRITE_REG(hw, IXGBE_QDE, reg);
+       }
+
        /* enable receive for vf */
        reg = IXGBE_READ_REG(hw, IXGBE_VFRE(reg_offset));
        reg |= 1 << vf_shift;
@@ -684,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 7c19e969576f60160649f3ea95b6033582ed9552..0d39cfc4a3bf2aa84294b4a12cf91b4a3a5353da 100644 (file)
@@ -1980,9 +1980,10 @@ enum {
 #define IXGBE_FWSM_TS_ENABLED  0x1
 
 /* Queue Drop Enable */
-#define IXGBE_QDE_ENABLE     0x00000001
-#define IXGBE_QDE_IDX_MASK   0x00007F00
-#define IXGBE_QDE_IDX_SHIFT           8
+#define IXGBE_QDE_ENABLE       0x00000001
+#define IXGBE_QDE_IDX_MASK     0x00007F00
+#define IXGBE_QDE_IDX_SHIFT    8
+#define IXGBE_QDE_WRITE                0x00010000
 
 #define IXGBE_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */
 #define IXGBE_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */
@@ -2173,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,