/* initialize base registers */
ret_code = i40e_config_arq_regs(hw);
if (ret_code != I40E_SUCCESS)
- goto init_adminq_free_rings;
+ goto init_config_regs;
/* success! */
hw->aq.arq.count = hw->aq.num_arq_entries;
init_adminq_free_rings:
i40e_free_adminq_arq(hw);
+ return ret_code;
+
+init_config_regs:
+ i40e_free_arq_bufs(hw);
init_adminq_exit:
return ret_code;
}
/**
- * i40e_asq_send_command - send command to Admin Queue
+ * i40e_asq_send_command_exec - send command to Admin Queue
* @hw: pointer to the hw struct
* @desc: prefilled descriptor describing the command (non DMA mem)
* @buff: buffer to use for indirect commands
* This is the main send command driver routine for the Admin Queue send
* queue. It runs the queue, cleans the queue, etc
**/
-enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw,
- struct i40e_aq_desc *desc,
- void *buff, /* can be NULL */
- u16 buff_size,
- struct i40e_asq_cmd_details *cmd_details)
+STATIC enum i40e_status_code
+i40e_asq_send_command_exec(struct i40e_hw *hw,
+ struct i40e_aq_desc *desc,
+ void *buff, /* can be NULL */
+ u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details)
{
enum i40e_status_code status = I40E_SUCCESS;
struct i40e_dma_mem *dma_buff = NULL;
u16 retval = 0;
u32 val = 0;
- i40e_acquire_spinlock(&hw->aq.asq_spinlock);
-
hw->aq.asq_last_status = I40E_AQ_RC_OK;
if (hw->aq.asq.count == 0) {
}
asq_send_command_error:
+ return status;
+}
+
+/**
+ * i40e_asq_send_command - send command to Admin Queue
+ * @hw: pointer to the hw struct
+ * @desc: prefilled descriptor describing the command (non DMA mem)
+ * @buff: buffer to use for indirect commands
+ * @buff_size: size of buffer for indirect commands
+ * @cmd_details: pointer to command details structure
+ *
+ * Acquires the lock and calls the main send command execution
+ * routine.
+ **/
+enum i40e_status_code
+i40e_asq_send_command(struct i40e_hw *hw,
+ struct i40e_aq_desc *desc,
+ void *buff, /* can be NULL */
+ u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ enum i40e_status_code status = I40E_SUCCESS;
+
+ i40e_acquire_spinlock(&hw->aq.asq_spinlock);
+ status = i40e_asq_send_command_exec(hw, desc, buff, buff_size,
+ cmd_details);
+ i40e_release_spinlock(&hw->aq.asq_spinlock);
+ return status;
+}
+
+/**
+ * i40e_asq_send_command_v2 - send command to Admin Queue
+ * @hw: pointer to the hw struct
+ * @desc: prefilled descriptor describing the command (non DMA mem)
+ * @buff: buffer to use for indirect commands
+ * @buff_size: size of buffer for indirect commands
+ * @cmd_details: pointer to command details structure
+ * @aq_status: pointer to Admin Queue status return value
+ *
+ * Acquires the lock and calls the main send command execution
+ * routine. Returns the last Admin Queue status in aq_status
+ * to avoid race conditions in access to hw->aq.asq_last_status.
+ **/
+enum i40e_status_code
+i40e_asq_send_command_v2(struct i40e_hw *hw,
+ struct i40e_aq_desc *desc,
+ void *buff, /* can be NULL */
+ u16 buff_size,
+ struct i40e_asq_cmd_details *cmd_details,
+ enum i40e_admin_queue_err *aq_status)
+{
+ enum i40e_status_code status = I40E_SUCCESS;
+
+ i40e_acquire_spinlock(&hw->aq.asq_spinlock);
+ status = i40e_asq_send_command_exec(hw, desc, buff, buff_size,
+ cmd_details);
+ if (aq_status)
+ *aq_status = hw->aq.asq_last_status;
i40e_release_spinlock(&hw->aq.asq_spinlock);
return status;
}