Skip to content

Commit 325782a

Browse files
jacob-kellerJeff Kirsher
authored andcommitted
fm10k: don't re-map queues when a mailbox message suffices
When the PF assigns a new MAC address to a VF it uses the base address registers to store the MAC address. This allows a VF which loads after this setup the ability to get the initial address without having to wait for a mailbox message. Unfortunately to do this, the PF must take queue ownership away from the VF, which can cause fault errors when there is already an active VF driver. This queue ownership assignment causes race condition between the PF and the VF such that potentially a VF can cause FUM fault errors due to normal PF/VF driver behavior. It is not safe to simply allow the PF to write the base address registers without taking queue ownership back as the PF must also disable the queues, and this would impact active VF use. The current code is safe because the queue ownership will prevent the VF from actually writing but does trigger the FUM fault. We can do better by simply avoiding the register write process when a mailbox message suffices. If the message can be sent over the mailbox, then we will not perform the queue ownership assignment and we won't update the base address to be the same as the MAC address. We do still have to write the TXQCTL registers in order to update the VID of the queue. This is necessary because the TXQCTL register is read-only from the VF, and thus the VF cannot do this for itself. This register does not need to wait for the Tx queue to be disabled and is safe for the PF to write during normal VF operation, so we move this write to the top of the function above the mailbox message. Without this, the TXQCTL register would be misconfigured and cause the VF to Tx hang. Signed-off-by: Jacob Keller <[email protected]> Tested-by: Krishneil Singh <[email protected]> Signed-off-by: Jeff Kirsher <[email protected]>
1 parent c689eff commit 325782a

File tree

1 file changed

+29
-17
lines changed

1 file changed

+29
-17
lines changed

drivers/net/ethernet/intel/fm10k/fm10k_pf.c

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -867,10 +867,6 @@ static s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,
867867
vf_q_idx = fm10k_vf_queue_index(hw, vf_idx);
868868
qmap_idx = qmap_stride * vf_idx;
869869

870-
/* MAP Tx queue back to 0 temporarily, and disable it */
871-
fm10k_write_reg(hw, FM10K_TQMAP(qmap_idx), 0);
872-
fm10k_write_reg(hw, FM10K_TXDCTL(vf_q_idx), 0);
873-
874870
/* Determine correct default VLAN ID. The FM10K_VLAN_OVERRIDE bit is
875871
* used here to indicate to the VF that it will not have privilege to
876872
* write VLAN_TABLE. All policy is enforced on the PF but this allows
@@ -886,9 +882,35 @@ static s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,
886882
fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_DEFAULT_MAC,
887883
vf_info->mac, vf_vid);
888884

889-
/* load onto outgoing mailbox, ignore any errors on enqueue */
890-
if (vf_info->mbx.ops.enqueue_tx)
891-
vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
885+
/* Configure Queue control register with new VLAN ID. The TXQCTL
886+
* register is RO from the VF, so the PF must do this even in the
887+
* case of notifying the VF of a new VID via the mailbox.
888+
*/
889+
txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) &
890+
FM10K_TXQCTL_VID_MASK;
891+
txqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
892+
FM10K_TXQCTL_VF | vf_idx;
893+
894+
for (i = 0; i < queues_per_pool; i++)
895+
fm10k_write_reg(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl);
896+
897+
/* try loading a message onto outgoing mailbox first */
898+
if (vf_info->mbx.ops.enqueue_tx) {
899+
err = vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg);
900+
if (err != FM10K_MBX_ERR_NO_MBX)
901+
return err;
902+
err = 0;
903+
}
904+
905+
/* If we aren't connected to a mailbox, this is most likely because
906+
* the VF driver is not running. It should thus be safe to re-map
907+
* queues and use the registers to pass the MAC address so that the VF
908+
* driver gets correct information during its initialization.
909+
*/
910+
911+
/* MAP Tx queue back to 0 temporarily, and disable it */
912+
fm10k_write_reg(hw, FM10K_TQMAP(qmap_idx), 0);
913+
fm10k_write_reg(hw, FM10K_TXDCTL(vf_q_idx), 0);
892914

893915
/* verify ring has disabled before modifying base address registers */
894916
txdctl = fm10k_read_reg(hw, FM10K_TXDCTL(vf_q_idx));
@@ -927,16 +949,6 @@ static s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw,
927949
FM10K_TDLEN_ITR_SCALE_SHIFT);
928950

929951
err_out:
930-
/* configure Queue control register */
931-
txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) &
932-
FM10K_TXQCTL_VID_MASK;
933-
txqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) |
934-
FM10K_TXQCTL_VF | vf_idx;
935-
936-
/* assign VLAN ID */
937-
for (i = 0; i < queues_per_pool; i++)
938-
fm10k_write_reg(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl);
939-
940952
/* restore the queue back to VF ownership */
941953
fm10k_write_reg(hw, FM10K_TQMAP(qmap_idx), vf_q_idx);
942954
return err;

0 commit comments

Comments
 (0)