net/ice/base: add capabilities when in safe mode
authorQi Zhang <qi.z.zhang@intel.com>
Thu, 29 Aug 2019 02:36:04 +0000 (10:36 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 7 Oct 2019 13:00:53 +0000 (15:00 +0200)
The dynamic device personalization (DDP) file download onto the device
can fail, and when this happens the driver has to transition to "safe
mode" where only basic functionality is possible.

The device though doesn't understand safe mode, and so the opcodes to
discover device/function capabilities (0x000A and 0x000B) return all
the capabilities of the device, which includes capabilities that the
driver cannot support when in safe mode.

The initialization flows in the driver are based on the capabilities
information (obtained by the driver with the above mentioned opcodes).
To reuse the same initialization flows in safe mode, it becomes
necessary for the driver to override the currently stored capabilities
information with safe mode capabilities. This is done by a new function
introduced in this patch - ice_set_safe_mode_caps.

Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Signed-off-by: Paul M Stillwell Jr <paul.m.stillwell.jr@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
Acked-by: Xiaolong Ye <xiaolong.ye@intel.com>
drivers/net/ice/base/ice_common.c
drivers/net/ice/base/ice_common.h

index ae78371..9907d9d 100644 (file)
@@ -2171,6 +2171,70 @@ ice_discover_caps(struct ice_hw *hw, enum ice_adminq_opc opc)
        return status;
 }
 
+/**
+ * ice_set_safe_mode_caps - Override dev/func capabilities when in safe mode
+ * @hw: pointer to the hardware structure
+ */
+void ice_set_safe_mode_caps(struct ice_hw *hw)
+{
+       struct ice_hw_func_caps *func_caps = &hw->func_caps;
+       struct ice_hw_dev_caps *dev_caps = &hw->dev_caps;
+       u32 valid_func, rxq_first_id, txq_first_id;
+       u32 msix_vector_first_id, max_mtu;
+       u32 num_funcs;
+
+       /* cache some func_caps values that should be restored after memset */
+       valid_func = func_caps->common_cap.valid_functions;
+       txq_first_id = func_caps->common_cap.txq_first_id;
+       rxq_first_id = func_caps->common_cap.rxq_first_id;
+       msix_vector_first_id = func_caps->common_cap.msix_vector_first_id;
+       max_mtu = func_caps->common_cap.max_mtu;
+
+       /* unset func capabilities */
+       memset(func_caps, 0, sizeof(*func_caps));
+
+       /* restore cached values */
+       func_caps->common_cap.valid_functions = valid_func;
+       func_caps->common_cap.txq_first_id = txq_first_id;
+       func_caps->common_cap.rxq_first_id = rxq_first_id;
+       func_caps->common_cap.msix_vector_first_id = msix_vector_first_id;
+       func_caps->common_cap.max_mtu = max_mtu;
+
+       /* one Tx and one Rx queue in safe mode */
+       func_caps->common_cap.num_rxq = 1;
+       func_caps->common_cap.num_txq = 1;
+
+       /* two MSIX vectors, one for traffic and one for misc causes */
+       func_caps->common_cap.num_msix_vectors = 2;
+       func_caps->guar_num_vsi = 1;
+
+       /* cache some dev_caps values that should be restored after memset */
+       valid_func = dev_caps->common_cap.valid_functions;
+       txq_first_id = dev_caps->common_cap.txq_first_id;
+       rxq_first_id = dev_caps->common_cap.rxq_first_id;
+       msix_vector_first_id = dev_caps->common_cap.msix_vector_first_id;
+       max_mtu = dev_caps->common_cap.max_mtu;
+       num_funcs = dev_caps->num_funcs;
+
+       /* unset dev capabilities */
+       memset(dev_caps, 0, sizeof(*dev_caps));
+
+       /* restore cached values */
+       dev_caps->common_cap.valid_functions = valid_func;
+       dev_caps->common_cap.txq_first_id = txq_first_id;
+       dev_caps->common_cap.rxq_first_id = rxq_first_id;
+       dev_caps->common_cap.msix_vector_first_id = msix_vector_first_id;
+       dev_caps->common_cap.max_mtu = max_mtu;
+       dev_caps->num_funcs = num_funcs;
+
+       /* one Tx and one Rx queue per function in safe mode */
+       dev_caps->common_cap.num_rxq = num_funcs;
+       dev_caps->common_cap.num_txq = num_funcs;
+
+       /* two MSIX vectors per function */
+       dev_caps->common_cap.num_msix_vectors = 2 * num_funcs;
+}
+
 /**
  * ice_get_caps - get info about the HW
  * @hw: pointer to the hardware structure
index d865021..df1fece 100644 (file)
@@ -61,6 +61,8 @@ void ice_clear_pxe_mode(struct ice_hw *hw);
 
 enum ice_status ice_get_caps(struct ice_hw *hw);
 
+void ice_set_safe_mode_caps(struct ice_hw *hw);
+
 /* Define a macro that will align a pointer to point to the next memory address
  * that falls on the given power of 2 (i.e., 2, 4, 8, 16, 32, 64...). For
  * example, given the variable pointer = 0x1006, then after the following call: