i40e: Admin queue shutdown fixes
authorAnjali Singhai Jain <anjali.singhai@intel.com>
Thu, 28 Nov 2013 06:39:45 +0000 (06:39 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Mon, 6 Jan 2014 11:26:23 +0000 (03:26 -0800)
Always call the AQ call to shutdown the queue in the shutdown path.

Check ASQ is alive before issuing the AQ command since we might be
resetting to recover from a bad state in which case we should not
issue the AQ command.

Use the register variable for length so it can be used by PF, VF
and GL AQ commands.

Change-Id: Ic3d305687ea3f1a6afa84e864b7a27bd38a9af32
Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_adminq.c
drivers/net/ethernet/intel/i40e/i40e_common.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_prototype.h

index d04ad3b202e3b88df0701a4985a3fc9de89a4baa..f75b5733f34c77474e6f699f36e1e744d347b558 100644 (file)
@@ -609,6 +609,9 @@ i40e_status i40e_shutdown_adminq(struct i40e_hw *hw)
 {
        i40e_status ret_code = 0;
 
+       if (i40e_check_asq_alive(hw))
+               i40e_aq_queue_shutdown(hw, true);
+
        i40e_shutdown_asq(hw);
        i40e_shutdown_arq(hw);
 
index 161d6ff93fd63d0a9c301cd82ac42023071f8332..7cd59cefcc3b2c6a4cf3064a48fbc667ae9a87a7 100644 (file)
@@ -125,6 +125,44 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
        }
 }
 
+/**
+ * i40e_check_asq_alive
+ * @hw: pointer to the hw struct
+ *
+ * Returns true if Queue is enabled else false.
+ **/
+bool i40e_check_asq_alive(struct i40e_hw *hw)
+{
+       return !!(rd32(hw, hw->aq.asq.len) & I40E_PF_ATQLEN_ATQENABLE_MASK);
+}
+
+/**
+ * i40e_aq_queue_shutdown
+ * @hw: pointer to the hw struct
+ * @unloading: is the driver unloading itself
+ *
+ * Tell the Firmware that we're shutting down the AdminQ and whether
+ * or not the driver is unloading as well.
+ **/
+i40e_status i40e_aq_queue_shutdown(struct i40e_hw *hw,
+                                            bool unloading)
+{
+       struct i40e_aq_desc desc;
+       struct i40e_aqc_queue_shutdown *cmd =
+               (struct i40e_aqc_queue_shutdown *)&desc.params.raw;
+       i40e_status status;
+
+       i40e_fill_default_direct_cmd_desc(&desc,
+                                         i40e_aqc_opc_queue_shutdown);
+
+       if (unloading)
+               cmd->driver_unloading = cpu_to_le32(I40E_AQ_DRIVER_UNLOADING);
+       status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
+
+       return status;
+}
+
+
 /**
  * i40e_init_shared_code - Initialize the shared code
  * @hw: pointer to hardware structure
@@ -478,31 +516,6 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
 }
 
 /* Admin command wrappers */
-/**
- * i40e_aq_queue_shutdown
- * @hw: pointer to the hw struct
- * @unloading: is the driver unloading itself
- *
- * Tell the Firmware that we're shutting down the AdminQ and whether
- * or not the driver is unloading as well.
- **/
-i40e_status i40e_aq_queue_shutdown(struct i40e_hw *hw,
-                                            bool unloading)
-{
-       struct i40e_aq_desc desc;
-       struct i40e_aqc_queue_shutdown *cmd =
-               (struct i40e_aqc_queue_shutdown *)&desc.params.raw;
-       i40e_status status;
-
-       i40e_fill_default_direct_cmd_desc(&desc,
-                                         i40e_aqc_opc_queue_shutdown);
-
-       if (unloading)
-               cmd->driver_unloading = cpu_to_le32(I40E_AQ_DRIVER_UNLOADING);
-       status = i40e_asq_send_command(hw, &desc, NULL, 0, NULL);
-
-       return status;
-}
 
 /**
  * i40e_aq_set_link_restart_an
index 9c16aa8194bb7416c60f741e63181f5fd8dacddd..c97fc0c9aa1faf0922a40802854d562f93ae6cfc 100644 (file)
@@ -7854,7 +7854,6 @@ static void i40e_remove(struct pci_dev *pdev)
                         "Failed to destroy the HMC resources: %d\n", ret_code);
 
        /* shutdown the adminq */
-       i40e_aq_queue_shutdown(&pf->hw, true);
        ret_code = i40e_shutdown_adminq(&pf->hw);
        if (ret_code)
                dev_warn(&pdev->dev,
index 800f3c816284cac40b3018470563eeba83bbb4bd..e05d303105a7b65fbd5ecdb5273681b1196df79c 100644 (file)
@@ -59,6 +59,9 @@ void i40e_debug_aq(struct i40e_hw *hw,
                   void *buffer);
 
 void i40e_idle_aq(struct i40e_hw *hw);
+bool i40e_check_asq_alive(struct i40e_hw *hw);
+i40e_status i40e_aq_queue_shutdown(struct i40e_hw *hw,
+                                  bool unloading);
 
 u32 i40e_led_get(struct i40e_hw *hw);
 void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink);
@@ -69,8 +72,6 @@ i40e_status i40e_aq_get_firmware_version(struct i40e_hw *hw,
                                u16 *fw_major_version, u16 *fw_minor_version,
                                u16 *api_major_version, u16 *api_minor_version,
                                struct i40e_asq_cmd_details *cmd_details);
-i40e_status i40e_aq_queue_shutdown(struct i40e_hw *hw,
-                                            bool unloading);
 i40e_status i40e_aq_set_phy_reset(struct i40e_hw *hw,
                                struct i40e_asq_cmd_details *cmd_details);
 i40e_status i40e_aq_set_default_vsi(struct i40e_hw *hw, u16 vsi_id,