From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jingjing Wu Subject: [PATCH 07/52] i40e/base: grab the AQ spinlocks before clearing registers Date: Sun, 6 Sep 2015 15:11:21 +0800 Message-ID: <1441523526-26202-8-git-send-email-jingjing.wu@intel.com> References: <1441523526-26202-1-git-send-email-jingjing.wu@intel.com> To: dev@dpdk.org Return-path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 4B1AB8E7B for ; Sun, 6 Sep 2015 09:12:29 +0200 (CEST) In-Reply-To: <1441523526-26202-1-git-send-email-jingjing.wu@intel.com> List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Make sure we have the spinlocks before we clear the ARQ and ASQ management registers. Also, widen the locked portion and make a sanity check earlier in the send function to be sure we're working with safe register values. Signed-off-by: Jingjing Wu --- drivers/net/i40e/base/i40e_adminq.c | 47 ++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/drivers/net/i40e/base/i40e_adminq.c b/drivers/net/i40e/base/i40e_adminq.c index 8f9e870..175daab 100644 --- a/drivers/net/i40e/base/i40e_adminq.c +++ b/drivers/net/i40e/base/i40e_adminq.c @@ -489,8 +489,12 @@ enum i40e_status_code i40e_shutdown_asq(struct i40e_hw *hw) { enum i40e_status_code ret_code = I40E_SUCCESS; - if (hw->aq.asq.count == 0) - return I40E_ERR_NOT_READY; + i40e_acquire_spinlock(&hw->aq.asq_spinlock); + + if (hw->aq.asq.count == 0) { + ret_code = I40E_ERR_NOT_READY; + goto shutdown_asq_out; + } /* Stop firmware AdminQ processing */ wr32(hw, hw->aq.asq.head, 0); @@ -499,16 +503,13 @@ enum i40e_status_code i40e_shutdown_asq(struct i40e_hw *hw) wr32(hw, hw->aq.asq.bal, 0); wr32(hw, hw->aq.asq.bah, 0); - /* make sure spinlock is available */ - i40e_acquire_spinlock(&hw->aq.asq_spinlock); - hw->aq.asq.count = 0; /* to indicate uninitialized queue */ /* free ring buffers */ i40e_free_asq_bufs(hw); +shutdown_asq_out: i40e_release_spinlock(&hw->aq.asq_spinlock); - return ret_code; } @@ -522,8 +523,12 @@ enum i40e_status_code i40e_shutdown_arq(struct i40e_hw *hw) { enum i40e_status_code ret_code = I40E_SUCCESS; - if (hw->aq.arq.count == 0) - return I40E_ERR_NOT_READY; + i40e_acquire_spinlock(&hw->aq.arq_spinlock); + + if (hw->aq.arq.count == 0) { + ret_code = I40E_ERR_NOT_READY; + goto shutdown_arq_out; + } /* Stop firmware AdminQ processing */ wr32(hw, hw->aq.arq.head, 0); @@ -532,16 +537,13 @@ enum i40e_status_code i40e_shutdown_arq(struct i40e_hw *hw) wr32(hw, hw->aq.arq.bal, 0); wr32(hw, hw->aq.arq.bah, 0); - /* make sure spinlock is available */ - i40e_acquire_spinlock(&hw->aq.arq_spinlock); - hw->aq.arq.count = 0; /* to indicate uninitialized queue */ /* free ring buffers */ i40e_free_arq_bufs(hw); +shutdown_arq_out: i40e_release_spinlock(&hw->aq.arq_spinlock); - return ret_code; } @@ -764,19 +766,23 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw, u16 retval = 0; u32 val = 0; - val = rd32(hw, hw->aq.asq.head); - if (val >= hw->aq.num_asq_entries) { + i40e_acquire_spinlock(&hw->aq.asq_spinlock); + + hw->aq.asq_last_status = I40E_AQ_RC_OK; + + if (hw->aq.asq.count == 0) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, - "AQTX: head overrun at %d\n", val); + "AQTX: Admin queue not initialized.\n"); status = I40E_ERR_QUEUE_EMPTY; - goto asq_send_command_exit; + goto asq_send_command_error; } - if (hw->aq.asq.count == 0) { + val = rd32(hw, hw->aq.asq.head); + if (val >= hw->aq.num_asq_entries) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, - "AQTX: Admin queue not initialized.\n"); + "AQTX: head overrun at %d\n", val); status = I40E_ERR_QUEUE_EMPTY; - goto asq_send_command_exit; + goto asq_send_command_error; } details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use); @@ -806,8 +812,6 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw, desc->flags &= ~CPU_TO_LE16(details->flags_dis); desc->flags |= CPU_TO_LE16(details->flags_ena); - i40e_acquire_spinlock(&hw->aq.asq_spinlock); - if (buff_size > hw->aq.asq_buf_size) { i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, @@ -932,7 +936,6 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw, asq_send_command_error: i40e_release_spinlock(&hw->aq.asq_spinlock); -asq_send_command_exit: return status; } -- 2.4.0