net/fm10k/base: improve re-map queues handle
authorQi Zhang <qi.z.zhang@intel.com>
Wed, 8 Mar 2017 06:19:03 +0000 (01:19 -0500)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 4 Apr 2017 13:52:52 +0000 (15:52 +0200)
Avoid potential FUM fault errors on a VF when updating MAC address
and VLAN information. Only use the register flow when the mailbox is
disconnected, by checking if the enqueue_tx returns
FM10K_MBX_ERR_NO_MBX. If the mailbox message can be sent, there is no
reason to bother with the register writes which are only intended to
be used during VF driver initialization.

Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
drivers/net/fm10k/base/fm10k_common.c
drivers/net/fm10k/base/fm10k_pf.c

index 7acc1ba..29f35d7 100644 (file)
@@ -230,6 +230,9 @@ s32 fm10k_disable_queues_generic(struct fm10k_hw *hw, u16 q_cnt)
        /* clear tx_ready to prevent any false hits for reset */
        hw->mac.tx_ready = false;
 
+       if (FM10K_REMOVED(hw->hw_addr))
+               return FM10K_SUCCESS;
+
        /* clear the enable bit for all rings */
        for (i = 0; i < q_cnt; i++) {
                reg = FM10K_READ_REG(hw, FM10K_TXDCTL(i));
index bce2913..5b1098e 100644 (file)
@@ -926,9 +926,35 @@ STATIC s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,
        fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_DEFAULT_MAC,
                                    vf_info->mac, vf_vid);
 
-       /* load onto outgoing mailbox, ignore any errors on enqueue */
-       if (vf_info->mbx.ops.enqueue_tx)
-               vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
+       /* Configure Queue control register with new VLAN ID. The TXQCTL
+        * register is RO from the VF, so the PF must do this even in the
+        * case of notifying the VF of a new VID via the mailbox.
+        */
+       txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) &
+                FM10K_TXQCTL_VID_MASK;
+       txqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
+                 FM10K_TXQCTL_VF | vf_idx;
+
+       for (i = 0; i < queues_per_pool; i++)
+               FM10K_WRITE_REG(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl);
+
+       /* try loading a message onto outgoing mailbox first */
+       if (vf_info->mbx.ops.enqueue_tx) {
+               err = vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
+               if (err != FM10K_MBX_ERR_NO_MBX)
+                       return err;
+               err = FM10K_SUCCESS;
+       }
+
+       /* If we aren't connected to a mailbox, this is most likely because
+        * the VF driver is not running. It should thus be safe to re-map
+        * queues and use the registers to pass the MAC address so that the VF
+        * driver gets correct information during its initialization.
+        */
+
+       /* MAP Tx queue back to 0 temporarily, and disable it */
+       FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), 0);
+       FM10K_WRITE_REG(hw, FM10K_TXDCTL(vf_q_idx), 0);
 
        /* verify ring has disabled before modifying base address registers */
        txdctl = FM10K_READ_REG(hw, FM10K_TXDCTL(vf_q_idx));
@@ -967,16 +993,6 @@ STATIC s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,
                                                   FM10K_TDLEN_ITR_SCALE_SHIFT);
 
 err_out:
-       /* configure Queue control register */
-       txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) &
-                FM10K_TXQCTL_VID_MASK;
-       txqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
-                 FM10K_TXQCTL_VF | vf_idx;
-
-       /* assign VLAN ID */
-       for (i = 0; i < queues_per_pool; i++)
-               FM10K_WRITE_REG(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl);
-
        /* restore the queue back to VF ownership */
        FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), vf_q_idx);
        return err;