fm10k: do not assume VF always has 1 queue
authorJacob Keller <jacob.e.keller@intel.com>
Tue, 25 Aug 2015 00:27:24 +0000 (17:27 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 15 Sep 2016 06:27:39 +0000 (08:27 +0200)
[ Upstream commit 1340181fe435ccb8ca2f996b8680bd9566860619 ]

It is possible that the PF has not yet assigned resources to the VF.
Although rare, this could result in the VF attempting to read queues it
does not own and result in FUM or THI faults in the PF. To prevent this,
check queue 0 before we continue in init_hw_vf.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Krishneil Singh <Krishneil.k.singh@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/intel/fm10k/fm10k_type.h
drivers/net/ethernet/intel/fm10k/fm10k_vf.c

index 318a212f0a78e54e9705780b23a6ba3dd6ddba4b..35afd711d14460eb28c8a7c10e0120898b80a19c 100644 (file)
@@ -77,6 +77,7 @@ struct fm10k_hw;
 #define FM10K_PCIE_SRIOV_CTRL_VFARI            0x10
 
 #define FM10K_ERR_PARAM                                -2
+#define FM10K_ERR_NO_RESOURCES                 -3
 #define FM10K_ERR_REQUESTS_PENDING             -4
 #define FM10K_ERR_RESET_REQUESTED              -5
 #define FM10K_ERR_DMA_PENDING                  -6
index 36c8b0aa08fd2eeadfbc7b87ee5ce9d8d619b589..3a18ef1cc017866442a782c9c2c0ec4061c39cdc 100644 (file)
@@ -103,7 +103,12 @@ static s32 fm10k_init_hw_vf(struct fm10k_hw *hw)
        s32 err;
        u16 i;
 
-       /* assume we always have at least 1 queue */
+       /* verify we have at least 1 queue */
+       if (!~fm10k_read_reg(hw, FM10K_TXQCTL(0)) ||
+           !~fm10k_read_reg(hw, FM10K_RXQCTL(0)))
+               return FM10K_ERR_NO_RESOURCES;
+
+       /* determine how many queues we have */
        for (i = 1; tqdloc0 && (i < FM10K_MAX_QUEUES_POOL); i++) {
                /* verify the Descriptor cache offsets are increasing */
                tqdloc = ~fm10k_read_reg(hw, FM10K_TQDLOC(i));