xref: /illumos-gate/usr/src/uts/common/io/i40e/core/i40e_adminq.c (revision df36e06d12cbf655ddf22339ef8c39fa2b83ebf8)
19d26e4fcSRobert Mustacchi /******************************************************************************
29d26e4fcSRobert Mustacchi 
3*df36e06dSRobert Mustacchi   Copyright (c) 2013-2018, Intel Corporation
49d26e4fcSRobert Mustacchi   All rights reserved.
59d26e4fcSRobert Mustacchi 
69d26e4fcSRobert Mustacchi   Redistribution and use in source and binary forms, with or without
79d26e4fcSRobert Mustacchi   modification, are permitted provided that the following conditions are met:
89d26e4fcSRobert Mustacchi 
99d26e4fcSRobert Mustacchi    1. Redistributions of source code must retain the above copyright notice,
109d26e4fcSRobert Mustacchi       this list of conditions and the following disclaimer.
119d26e4fcSRobert Mustacchi 
129d26e4fcSRobert Mustacchi    2. Redistributions in binary form must reproduce the above copyright
139d26e4fcSRobert Mustacchi       notice, this list of conditions and the following disclaimer in the
149d26e4fcSRobert Mustacchi       documentation and/or other materials provided with the distribution.
159d26e4fcSRobert Mustacchi 
169d26e4fcSRobert Mustacchi    3. Neither the name of the Intel Corporation nor the names of its
179d26e4fcSRobert Mustacchi       contributors may be used to endorse or promote products derived from
189d26e4fcSRobert Mustacchi       this software without specific prior written permission.
199d26e4fcSRobert Mustacchi 
209d26e4fcSRobert Mustacchi   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
219d26e4fcSRobert Mustacchi   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
229d26e4fcSRobert Mustacchi   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
239d26e4fcSRobert Mustacchi   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
249d26e4fcSRobert Mustacchi   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
259d26e4fcSRobert Mustacchi   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
269d26e4fcSRobert Mustacchi   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
279d26e4fcSRobert Mustacchi   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
289d26e4fcSRobert Mustacchi   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
299d26e4fcSRobert Mustacchi   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
309d26e4fcSRobert Mustacchi   POSSIBILITY OF SUCH DAMAGE.
319d26e4fcSRobert Mustacchi 
329d26e4fcSRobert Mustacchi ******************************************************************************/
333d75a287SRobert Mustacchi /*$FreeBSD$*/
349d26e4fcSRobert Mustacchi 
359d26e4fcSRobert Mustacchi #include "i40e_status.h"
369d26e4fcSRobert Mustacchi #include "i40e_type.h"
379d26e4fcSRobert Mustacchi #include "i40e_register.h"
389d26e4fcSRobert Mustacchi #include "i40e_adminq.h"
399d26e4fcSRobert Mustacchi #include "i40e_prototype.h"
409d26e4fcSRobert Mustacchi 
419d26e4fcSRobert Mustacchi /**
429d26e4fcSRobert Mustacchi  *  i40e_adminq_init_regs - Initialize AdminQ registers
439d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
449d26e4fcSRobert Mustacchi  *
459d26e4fcSRobert Mustacchi  *  This assumes the alloc_asq and alloc_arq functions have already been called
469d26e4fcSRobert Mustacchi  **/
i40e_adminq_init_regs(struct i40e_hw * hw)479d26e4fcSRobert Mustacchi static void i40e_adminq_init_regs(struct i40e_hw *hw)
489d26e4fcSRobert Mustacchi {
499d26e4fcSRobert Mustacchi 	/* set head and tail registers in our local struct */
509d26e4fcSRobert Mustacchi 	if (i40e_is_vf(hw)) {
519d26e4fcSRobert Mustacchi 		hw->aq.asq.tail = I40E_VF_ATQT1;
529d26e4fcSRobert Mustacchi 		hw->aq.asq.head = I40E_VF_ATQH1;
539d26e4fcSRobert Mustacchi 		hw->aq.asq.len  = I40E_VF_ATQLEN1;
549d26e4fcSRobert Mustacchi 		hw->aq.asq.bal  = I40E_VF_ATQBAL1;
559d26e4fcSRobert Mustacchi 		hw->aq.asq.bah  = I40E_VF_ATQBAH1;
569d26e4fcSRobert Mustacchi 		hw->aq.arq.tail = I40E_VF_ARQT1;
579d26e4fcSRobert Mustacchi 		hw->aq.arq.head = I40E_VF_ARQH1;
589d26e4fcSRobert Mustacchi 		hw->aq.arq.len  = I40E_VF_ARQLEN1;
599d26e4fcSRobert Mustacchi 		hw->aq.arq.bal  = I40E_VF_ARQBAL1;
609d26e4fcSRobert Mustacchi 		hw->aq.arq.bah  = I40E_VF_ARQBAH1;
619d26e4fcSRobert Mustacchi 	} else {
629d26e4fcSRobert Mustacchi 		hw->aq.asq.tail = I40E_PF_ATQT;
639d26e4fcSRobert Mustacchi 		hw->aq.asq.head = I40E_PF_ATQH;
649d26e4fcSRobert Mustacchi 		hw->aq.asq.len  = I40E_PF_ATQLEN;
659d26e4fcSRobert Mustacchi 		hw->aq.asq.bal  = I40E_PF_ATQBAL;
669d26e4fcSRobert Mustacchi 		hw->aq.asq.bah  = I40E_PF_ATQBAH;
679d26e4fcSRobert Mustacchi 		hw->aq.arq.tail = I40E_PF_ARQT;
689d26e4fcSRobert Mustacchi 		hw->aq.arq.head = I40E_PF_ARQH;
699d26e4fcSRobert Mustacchi 		hw->aq.arq.len  = I40E_PF_ARQLEN;
709d26e4fcSRobert Mustacchi 		hw->aq.arq.bal  = I40E_PF_ARQBAL;
719d26e4fcSRobert Mustacchi 		hw->aq.arq.bah  = I40E_PF_ARQBAH;
729d26e4fcSRobert Mustacchi 	}
739d26e4fcSRobert Mustacchi }
749d26e4fcSRobert Mustacchi 
759d26e4fcSRobert Mustacchi /**
769d26e4fcSRobert Mustacchi  *  i40e_alloc_adminq_asq_ring - Allocate Admin Queue send rings
779d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
789d26e4fcSRobert Mustacchi  **/
i40e_alloc_adminq_asq_ring(struct i40e_hw * hw)799d26e4fcSRobert Mustacchi enum i40e_status_code i40e_alloc_adminq_asq_ring(struct i40e_hw *hw)
809d26e4fcSRobert Mustacchi {
819d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code;
829d26e4fcSRobert Mustacchi 
839d26e4fcSRobert Mustacchi 	ret_code = i40e_allocate_dma_mem(hw, &hw->aq.asq.desc_buf,
849d26e4fcSRobert Mustacchi 					 i40e_mem_atq_ring,
859d26e4fcSRobert Mustacchi 					 (hw->aq.num_asq_entries *
869d26e4fcSRobert Mustacchi 					 sizeof(struct i40e_aq_desc)),
879d26e4fcSRobert Mustacchi 					 I40E_ADMINQ_DESC_ALIGNMENT);
889d26e4fcSRobert Mustacchi 	if (ret_code)
899d26e4fcSRobert Mustacchi 		return ret_code;
909d26e4fcSRobert Mustacchi 
919d26e4fcSRobert Mustacchi 	ret_code = i40e_allocate_virt_mem(hw, &hw->aq.asq.cmd_buf,
929d26e4fcSRobert Mustacchi 					  (hw->aq.num_asq_entries *
939d26e4fcSRobert Mustacchi 					  sizeof(struct i40e_asq_cmd_details)));
949d26e4fcSRobert Mustacchi 	if (ret_code) {
959d26e4fcSRobert Mustacchi 		i40e_free_dma_mem(hw, &hw->aq.asq.desc_buf);
969d26e4fcSRobert Mustacchi 		return ret_code;
979d26e4fcSRobert Mustacchi 	}
989d26e4fcSRobert Mustacchi 
999d26e4fcSRobert Mustacchi 	return ret_code;
1009d26e4fcSRobert Mustacchi }
1019d26e4fcSRobert Mustacchi 
1029d26e4fcSRobert Mustacchi /**
1039d26e4fcSRobert Mustacchi  *  i40e_alloc_adminq_arq_ring - Allocate Admin Queue receive rings
1049d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
1059d26e4fcSRobert Mustacchi  **/
i40e_alloc_adminq_arq_ring(struct i40e_hw * hw)1069d26e4fcSRobert Mustacchi enum i40e_status_code i40e_alloc_adminq_arq_ring(struct i40e_hw *hw)
1079d26e4fcSRobert Mustacchi {
1089d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code;
1099d26e4fcSRobert Mustacchi 
1109d26e4fcSRobert Mustacchi 	ret_code = i40e_allocate_dma_mem(hw, &hw->aq.arq.desc_buf,
1119d26e4fcSRobert Mustacchi 					 i40e_mem_arq_ring,
1129d26e4fcSRobert Mustacchi 					 (hw->aq.num_arq_entries *
1139d26e4fcSRobert Mustacchi 					 sizeof(struct i40e_aq_desc)),
1149d26e4fcSRobert Mustacchi 					 I40E_ADMINQ_DESC_ALIGNMENT);
1159d26e4fcSRobert Mustacchi 
1169d26e4fcSRobert Mustacchi 	return ret_code;
1179d26e4fcSRobert Mustacchi }
1189d26e4fcSRobert Mustacchi 
1199d26e4fcSRobert Mustacchi /**
1209d26e4fcSRobert Mustacchi  *  i40e_free_adminq_asq - Free Admin Queue send rings
1219d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
1229d26e4fcSRobert Mustacchi  *
1239d26e4fcSRobert Mustacchi  *  This assumes the posted send buffers have already been cleaned
1249d26e4fcSRobert Mustacchi  *  and de-allocated
1259d26e4fcSRobert Mustacchi  **/
i40e_free_adminq_asq(struct i40e_hw * hw)1269d26e4fcSRobert Mustacchi void i40e_free_adminq_asq(struct i40e_hw *hw)
1279d26e4fcSRobert Mustacchi {
128*df36e06dSRobert Mustacchi 	i40e_free_virt_mem(hw, &hw->aq.asq.cmd_buf);
1299d26e4fcSRobert Mustacchi 	i40e_free_dma_mem(hw, &hw->aq.asq.desc_buf);
1309d26e4fcSRobert Mustacchi }
1319d26e4fcSRobert Mustacchi 
1329d26e4fcSRobert Mustacchi /**
1339d26e4fcSRobert Mustacchi  *  i40e_free_adminq_arq - Free Admin Queue receive rings
1349d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
1359d26e4fcSRobert Mustacchi  *
1369d26e4fcSRobert Mustacchi  *  This assumes the posted receive buffers have already been cleaned
1379d26e4fcSRobert Mustacchi  *  and de-allocated
1389d26e4fcSRobert Mustacchi  **/
i40e_free_adminq_arq(struct i40e_hw * hw)1399d26e4fcSRobert Mustacchi void i40e_free_adminq_arq(struct i40e_hw *hw)
1409d26e4fcSRobert Mustacchi {
1419d26e4fcSRobert Mustacchi 	i40e_free_dma_mem(hw, &hw->aq.arq.desc_buf);
1429d26e4fcSRobert Mustacchi }
1439d26e4fcSRobert Mustacchi 
1449d26e4fcSRobert Mustacchi /**
1459d26e4fcSRobert Mustacchi  *  i40e_alloc_arq_bufs - Allocate pre-posted buffers for the receive queue
1469d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
1479d26e4fcSRobert Mustacchi  **/
i40e_alloc_arq_bufs(struct i40e_hw * hw)1489d26e4fcSRobert Mustacchi static enum i40e_status_code i40e_alloc_arq_bufs(struct i40e_hw *hw)
1499d26e4fcSRobert Mustacchi {
1509d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code;
1519d26e4fcSRobert Mustacchi 	struct i40e_aq_desc *desc;
1529d26e4fcSRobert Mustacchi 	struct i40e_dma_mem *bi;
1539d26e4fcSRobert Mustacchi 	int i;
1549d26e4fcSRobert Mustacchi 
1559d26e4fcSRobert Mustacchi 	/* We'll be allocating the buffer info memory first, then we can
1569d26e4fcSRobert Mustacchi 	 * allocate the mapped buffers for the event processing
1579d26e4fcSRobert Mustacchi 	 */
1589d26e4fcSRobert Mustacchi 
1599d26e4fcSRobert Mustacchi 	/* buffer_info structures do not need alignment */
1609d26e4fcSRobert Mustacchi 	ret_code = i40e_allocate_virt_mem(hw, &hw->aq.arq.dma_head,
1619d26e4fcSRobert Mustacchi 		(hw->aq.num_arq_entries * sizeof(struct i40e_dma_mem)));
1629d26e4fcSRobert Mustacchi 	if (ret_code)
1639d26e4fcSRobert Mustacchi 		goto alloc_arq_bufs;
1649d26e4fcSRobert Mustacchi 	hw->aq.arq.r.arq_bi = (struct i40e_dma_mem *)hw->aq.arq.dma_head.va;
1659d26e4fcSRobert Mustacchi 
1669d26e4fcSRobert Mustacchi 	/* allocate the mapped buffers */
1679d26e4fcSRobert Mustacchi 	for (i = 0; i < hw->aq.num_arq_entries; i++) {
1689d26e4fcSRobert Mustacchi 		bi = &hw->aq.arq.r.arq_bi[i];
1699d26e4fcSRobert Mustacchi 		ret_code = i40e_allocate_dma_mem(hw, bi,
1709d26e4fcSRobert Mustacchi 						 i40e_mem_arq_buf,
1719d26e4fcSRobert Mustacchi 						 hw->aq.arq_buf_size,
1729d26e4fcSRobert Mustacchi 						 I40E_ADMINQ_DESC_ALIGNMENT);
1739d26e4fcSRobert Mustacchi 		if (ret_code)
1749d26e4fcSRobert Mustacchi 			goto unwind_alloc_arq_bufs;
1759d26e4fcSRobert Mustacchi 
1769d26e4fcSRobert Mustacchi 		/* now configure the descriptors for use */
1779d26e4fcSRobert Mustacchi 		desc = I40E_ADMINQ_DESC(hw->aq.arq, i);
1789d26e4fcSRobert Mustacchi 
1799d26e4fcSRobert Mustacchi 		desc->flags = CPU_TO_LE16(I40E_AQ_FLAG_BUF);
1809d26e4fcSRobert Mustacchi 		if (hw->aq.arq_buf_size > I40E_AQ_LARGE_BUF)
1819d26e4fcSRobert Mustacchi 			desc->flags |= CPU_TO_LE16(I40E_AQ_FLAG_LB);
1829d26e4fcSRobert Mustacchi 		desc->opcode = 0;
1839d26e4fcSRobert Mustacchi 		/* This is in accordance with Admin queue design, there is no
1849d26e4fcSRobert Mustacchi 		 * register for buffer size configuration
1859d26e4fcSRobert Mustacchi 		 */
1869d26e4fcSRobert Mustacchi 		desc->datalen = CPU_TO_LE16((u16)bi->size);
1879d26e4fcSRobert Mustacchi 		desc->retval = 0;
1889d26e4fcSRobert Mustacchi 		desc->cookie_high = 0;
1899d26e4fcSRobert Mustacchi 		desc->cookie_low = 0;
1909d26e4fcSRobert Mustacchi 		desc->params.external.addr_high =
1919d26e4fcSRobert Mustacchi 			CPU_TO_LE32(I40E_HI_DWORD(bi->pa));
1929d26e4fcSRobert Mustacchi 		desc->params.external.addr_low =
1939d26e4fcSRobert Mustacchi 			CPU_TO_LE32(I40E_LO_DWORD(bi->pa));
1949d26e4fcSRobert Mustacchi 		desc->params.external.param0 = 0;
1959d26e4fcSRobert Mustacchi 		desc->params.external.param1 = 0;
1969d26e4fcSRobert Mustacchi 	}
1979d26e4fcSRobert Mustacchi 
1989d26e4fcSRobert Mustacchi alloc_arq_bufs:
1999d26e4fcSRobert Mustacchi 	return ret_code;
2009d26e4fcSRobert Mustacchi 
2019d26e4fcSRobert Mustacchi unwind_alloc_arq_bufs:
2029d26e4fcSRobert Mustacchi 	/* don't try to free the one that failed... */
2039d26e4fcSRobert Mustacchi 	i--;
2049d26e4fcSRobert Mustacchi 	for (; i >= 0; i--)
2059d26e4fcSRobert Mustacchi 		i40e_free_dma_mem(hw, &hw->aq.arq.r.arq_bi[i]);
2069d26e4fcSRobert Mustacchi 	i40e_free_virt_mem(hw, &hw->aq.arq.dma_head);
2079d26e4fcSRobert Mustacchi 
2089d26e4fcSRobert Mustacchi 	return ret_code;
2099d26e4fcSRobert Mustacchi }
2109d26e4fcSRobert Mustacchi 
2119d26e4fcSRobert Mustacchi /**
2129d26e4fcSRobert Mustacchi  *  i40e_alloc_asq_bufs - Allocate empty buffer structs for the send queue
2139d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
2149d26e4fcSRobert Mustacchi  **/
i40e_alloc_asq_bufs(struct i40e_hw * hw)2159d26e4fcSRobert Mustacchi static enum i40e_status_code i40e_alloc_asq_bufs(struct i40e_hw *hw)
2169d26e4fcSRobert Mustacchi {
2179d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code;
2189d26e4fcSRobert Mustacchi 	struct i40e_dma_mem *bi;
2199d26e4fcSRobert Mustacchi 	int i;
2209d26e4fcSRobert Mustacchi 
2219d26e4fcSRobert Mustacchi 	/* No mapped memory needed yet, just the buffer info structures */
2229d26e4fcSRobert Mustacchi 	ret_code = i40e_allocate_virt_mem(hw, &hw->aq.asq.dma_head,
2239d26e4fcSRobert Mustacchi 		(hw->aq.num_asq_entries * sizeof(struct i40e_dma_mem)));
2249d26e4fcSRobert Mustacchi 	if (ret_code)
2259d26e4fcSRobert Mustacchi 		goto alloc_asq_bufs;
2269d26e4fcSRobert Mustacchi 	hw->aq.asq.r.asq_bi = (struct i40e_dma_mem *)hw->aq.asq.dma_head.va;
2279d26e4fcSRobert Mustacchi 
2289d26e4fcSRobert Mustacchi 	/* allocate the mapped buffers */
2299d26e4fcSRobert Mustacchi 	for (i = 0; i < hw->aq.num_asq_entries; i++) {
2309d26e4fcSRobert Mustacchi 		bi = &hw->aq.asq.r.asq_bi[i];
2319d26e4fcSRobert Mustacchi 		ret_code = i40e_allocate_dma_mem(hw, bi,
2329d26e4fcSRobert Mustacchi 						 i40e_mem_asq_buf,
2339d26e4fcSRobert Mustacchi 						 hw->aq.asq_buf_size,
2349d26e4fcSRobert Mustacchi 						 I40E_ADMINQ_DESC_ALIGNMENT);
2359d26e4fcSRobert Mustacchi 		if (ret_code)
2369d26e4fcSRobert Mustacchi 			goto unwind_alloc_asq_bufs;
2379d26e4fcSRobert Mustacchi 	}
2389d26e4fcSRobert Mustacchi alloc_asq_bufs:
2399d26e4fcSRobert Mustacchi 	return ret_code;
2409d26e4fcSRobert Mustacchi 
2419d26e4fcSRobert Mustacchi unwind_alloc_asq_bufs:
2429d26e4fcSRobert Mustacchi 	/* don't try to free the one that failed... */
2439d26e4fcSRobert Mustacchi 	i--;
2449d26e4fcSRobert Mustacchi 	for (; i >= 0; i--)
2459d26e4fcSRobert Mustacchi 		i40e_free_dma_mem(hw, &hw->aq.asq.r.asq_bi[i]);
2469d26e4fcSRobert Mustacchi 	i40e_free_virt_mem(hw, &hw->aq.asq.dma_head);
2479d26e4fcSRobert Mustacchi 
2489d26e4fcSRobert Mustacchi 	return ret_code;
2499d26e4fcSRobert Mustacchi }
2509d26e4fcSRobert Mustacchi 
2519d26e4fcSRobert Mustacchi /**
2529d26e4fcSRobert Mustacchi  *  i40e_free_arq_bufs - Free receive queue buffer info elements
2539d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
2549d26e4fcSRobert Mustacchi  **/
i40e_free_arq_bufs(struct i40e_hw * hw)2559d26e4fcSRobert Mustacchi static void i40e_free_arq_bufs(struct i40e_hw *hw)
2569d26e4fcSRobert Mustacchi {
2579d26e4fcSRobert Mustacchi 	int i;
2589d26e4fcSRobert Mustacchi 
2599d26e4fcSRobert Mustacchi 	/* free descriptors */
2609d26e4fcSRobert Mustacchi 	for (i = 0; i < hw->aq.num_arq_entries; i++)
2619d26e4fcSRobert Mustacchi 		i40e_free_dma_mem(hw, &hw->aq.arq.r.arq_bi[i]);
2629d26e4fcSRobert Mustacchi 
2639d26e4fcSRobert Mustacchi 	/* free the descriptor memory */
2649d26e4fcSRobert Mustacchi 	i40e_free_dma_mem(hw, &hw->aq.arq.desc_buf);
2659d26e4fcSRobert Mustacchi 
2669d26e4fcSRobert Mustacchi 	/* free the dma header */
2679d26e4fcSRobert Mustacchi 	i40e_free_virt_mem(hw, &hw->aq.arq.dma_head);
2689d26e4fcSRobert Mustacchi }
2699d26e4fcSRobert Mustacchi 
2709d26e4fcSRobert Mustacchi /**
2719d26e4fcSRobert Mustacchi  *  i40e_free_asq_bufs - Free send queue buffer info elements
2729d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
2739d26e4fcSRobert Mustacchi  **/
i40e_free_asq_bufs(struct i40e_hw * hw)2749d26e4fcSRobert Mustacchi static void i40e_free_asq_bufs(struct i40e_hw *hw)
2759d26e4fcSRobert Mustacchi {
2769d26e4fcSRobert Mustacchi 	int i;
2779d26e4fcSRobert Mustacchi 
2789d26e4fcSRobert Mustacchi 	/* only unmap if the address is non-NULL */
2799d26e4fcSRobert Mustacchi 	for (i = 0; i < hw->aq.num_asq_entries; i++)
2809d26e4fcSRobert Mustacchi 		if (hw->aq.asq.r.asq_bi[i].pa)
2819d26e4fcSRobert Mustacchi 			i40e_free_dma_mem(hw, &hw->aq.asq.r.asq_bi[i]);
2829d26e4fcSRobert Mustacchi 
2839d26e4fcSRobert Mustacchi 	/* free the buffer info list */
2849d26e4fcSRobert Mustacchi 	i40e_free_virt_mem(hw, &hw->aq.asq.cmd_buf);
2859d26e4fcSRobert Mustacchi 
2869d26e4fcSRobert Mustacchi 	/* free the descriptor memory */
2879d26e4fcSRobert Mustacchi 	i40e_free_dma_mem(hw, &hw->aq.asq.desc_buf);
2889d26e4fcSRobert Mustacchi 
2899d26e4fcSRobert Mustacchi 	/* free the dma header */
2909d26e4fcSRobert Mustacchi 	i40e_free_virt_mem(hw, &hw->aq.asq.dma_head);
2919d26e4fcSRobert Mustacchi }
2929d26e4fcSRobert Mustacchi 
2939d26e4fcSRobert Mustacchi /**
2949d26e4fcSRobert Mustacchi  *  i40e_config_asq_regs - configure ASQ registers
2959d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
2969d26e4fcSRobert Mustacchi  *
2979d26e4fcSRobert Mustacchi  *  Configure base address and length registers for the transmit queue
2989d26e4fcSRobert Mustacchi  **/
i40e_config_asq_regs(struct i40e_hw * hw)2999d26e4fcSRobert Mustacchi static enum i40e_status_code i40e_config_asq_regs(struct i40e_hw *hw)
3009d26e4fcSRobert Mustacchi {
3019d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
3029d26e4fcSRobert Mustacchi 	u32 reg = 0;
3039d26e4fcSRobert Mustacchi 
3049d26e4fcSRobert Mustacchi 	/* Clear Head and Tail */
3059d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.asq.head, 0);
3069d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.asq.tail, 0);
3079d26e4fcSRobert Mustacchi 
3089d26e4fcSRobert Mustacchi 	/* set starting point */
309*df36e06dSRobert Mustacchi 	if (!i40e_is_vf(hw))
3109d26e4fcSRobert Mustacchi 		wr32(hw, hw->aq.asq.len, (hw->aq.num_asq_entries |
3119d26e4fcSRobert Mustacchi 					  I40E_PF_ATQLEN_ATQENABLE_MASK));
312*df36e06dSRobert Mustacchi 	if (i40e_is_vf(hw))
313*df36e06dSRobert Mustacchi 		wr32(hw, hw->aq.asq.len, (hw->aq.num_asq_entries |
314*df36e06dSRobert Mustacchi 					  I40E_VF_ATQLEN1_ATQENABLE_MASK));
3159d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.asq.bal, I40E_LO_DWORD(hw->aq.asq.desc_buf.pa));
3169d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.asq.bah, I40E_HI_DWORD(hw->aq.asq.desc_buf.pa));
3179d26e4fcSRobert Mustacchi 
3189d26e4fcSRobert Mustacchi 	/* Check one register to verify that config was applied */
3199d26e4fcSRobert Mustacchi 	reg = rd32(hw, hw->aq.asq.bal);
3209d26e4fcSRobert Mustacchi 	if (reg != I40E_LO_DWORD(hw->aq.asq.desc_buf.pa))
3219d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_ADMIN_QUEUE_ERROR;
3229d26e4fcSRobert Mustacchi 
3239d26e4fcSRobert Mustacchi 	return ret_code;
3249d26e4fcSRobert Mustacchi }
3259d26e4fcSRobert Mustacchi 
3269d26e4fcSRobert Mustacchi /**
3279d26e4fcSRobert Mustacchi  *  i40e_config_arq_regs - ARQ register configuration
3289d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
3299d26e4fcSRobert Mustacchi  *
3309d26e4fcSRobert Mustacchi  * Configure base address and length registers for the receive (event queue)
3319d26e4fcSRobert Mustacchi  **/
i40e_config_arq_regs(struct i40e_hw * hw)3329d26e4fcSRobert Mustacchi static enum i40e_status_code i40e_config_arq_regs(struct i40e_hw *hw)
3339d26e4fcSRobert Mustacchi {
3349d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
3359d26e4fcSRobert Mustacchi 	u32 reg = 0;
3369d26e4fcSRobert Mustacchi 
3379d26e4fcSRobert Mustacchi 	/* Clear Head and Tail */
3389d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.arq.head, 0);
3399d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.arq.tail, 0);
3409d26e4fcSRobert Mustacchi 
3419d26e4fcSRobert Mustacchi 	/* set starting point */
342*df36e06dSRobert Mustacchi 	if (!i40e_is_vf(hw))
3439d26e4fcSRobert Mustacchi 		wr32(hw, hw->aq.arq.len, (hw->aq.num_arq_entries |
3449d26e4fcSRobert Mustacchi 					  I40E_PF_ARQLEN_ARQENABLE_MASK));
345*df36e06dSRobert Mustacchi 	if (i40e_is_vf(hw))
346*df36e06dSRobert Mustacchi 		wr32(hw, hw->aq.arq.len, (hw->aq.num_arq_entries |
347*df36e06dSRobert Mustacchi 					  I40E_VF_ARQLEN1_ARQENABLE_MASK));
3489d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.arq.bal, I40E_LO_DWORD(hw->aq.arq.desc_buf.pa));
3499d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.arq.bah, I40E_HI_DWORD(hw->aq.arq.desc_buf.pa));
3509d26e4fcSRobert Mustacchi 
3519d26e4fcSRobert Mustacchi 	/* Update tail in the HW to post pre-allocated buffers */
3529d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.arq.tail, hw->aq.num_arq_entries - 1);
3539d26e4fcSRobert Mustacchi 
3549d26e4fcSRobert Mustacchi 	/* Check one register to verify that config was applied */
3559d26e4fcSRobert Mustacchi 	reg = rd32(hw, hw->aq.arq.bal);
3569d26e4fcSRobert Mustacchi 	if (reg != I40E_LO_DWORD(hw->aq.arq.desc_buf.pa))
3579d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_ADMIN_QUEUE_ERROR;
3589d26e4fcSRobert Mustacchi 
3599d26e4fcSRobert Mustacchi 	return ret_code;
3609d26e4fcSRobert Mustacchi }
3619d26e4fcSRobert Mustacchi 
3629d26e4fcSRobert Mustacchi /**
3639d26e4fcSRobert Mustacchi  *  i40e_init_asq - main initialization routine for ASQ
3649d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
3659d26e4fcSRobert Mustacchi  *
3669d26e4fcSRobert Mustacchi  *  This is the main initialization routine for the Admin Send Queue
3679d26e4fcSRobert Mustacchi  *  Prior to calling this function, drivers *MUST* set the following fields
3689d26e4fcSRobert Mustacchi  *  in the hw->aq structure:
3699d26e4fcSRobert Mustacchi  *     - hw->aq.num_asq_entries
3709d26e4fcSRobert Mustacchi  *     - hw->aq.arq_buf_size
3719d26e4fcSRobert Mustacchi  *
3729d26e4fcSRobert Mustacchi  *  Do *NOT* hold the lock when calling this as the memory allocation routines
3739d26e4fcSRobert Mustacchi  *  called are not going to be atomic context safe
3749d26e4fcSRobert Mustacchi  **/
i40e_init_asq(struct i40e_hw * hw)3759d26e4fcSRobert Mustacchi enum i40e_status_code i40e_init_asq(struct i40e_hw *hw)
3769d26e4fcSRobert Mustacchi {
3779d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
3789d26e4fcSRobert Mustacchi 
3799d26e4fcSRobert Mustacchi 	if (hw->aq.asq.count > 0) {
3809d26e4fcSRobert Mustacchi 		/* queue already initialized */
3819d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_NOT_READY;
3829d26e4fcSRobert Mustacchi 		goto init_adminq_exit;
3839d26e4fcSRobert Mustacchi 	}
3849d26e4fcSRobert Mustacchi 
3859d26e4fcSRobert Mustacchi 	/* verify input for valid configuration */
3869d26e4fcSRobert Mustacchi 	if ((hw->aq.num_asq_entries == 0) ||
3879d26e4fcSRobert Mustacchi 	    (hw->aq.asq_buf_size == 0)) {
3889d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_CONFIG;
3899d26e4fcSRobert Mustacchi 		goto init_adminq_exit;
3909d26e4fcSRobert Mustacchi 	}
3919d26e4fcSRobert Mustacchi 
3929d26e4fcSRobert Mustacchi 	hw->aq.asq.next_to_use = 0;
3939d26e4fcSRobert Mustacchi 	hw->aq.asq.next_to_clean = 0;
3949d26e4fcSRobert Mustacchi 
3959d26e4fcSRobert Mustacchi 	/* allocate the ring memory */
3969d26e4fcSRobert Mustacchi 	ret_code = i40e_alloc_adminq_asq_ring(hw);
3979d26e4fcSRobert Mustacchi 	if (ret_code != I40E_SUCCESS)
3989d26e4fcSRobert Mustacchi 		goto init_adminq_exit;
3999d26e4fcSRobert Mustacchi 
4009d26e4fcSRobert Mustacchi 	/* allocate buffers in the rings */
4019d26e4fcSRobert Mustacchi 	ret_code = i40e_alloc_asq_bufs(hw);
4029d26e4fcSRobert Mustacchi 	if (ret_code != I40E_SUCCESS)
4039d26e4fcSRobert Mustacchi 		goto init_adminq_free_rings;
4049d26e4fcSRobert Mustacchi 
4059d26e4fcSRobert Mustacchi 	/* initialize base registers */
4069d26e4fcSRobert Mustacchi 	ret_code = i40e_config_asq_regs(hw);
4079d26e4fcSRobert Mustacchi 	if (ret_code != I40E_SUCCESS)
408*df36e06dSRobert Mustacchi 		goto init_config_regs;
4099d26e4fcSRobert Mustacchi 
4109d26e4fcSRobert Mustacchi 	/* success! */
4113d75a287SRobert Mustacchi 	hw->aq.asq.count = hw->aq.num_asq_entries;
4129d26e4fcSRobert Mustacchi 	goto init_adminq_exit;
4139d26e4fcSRobert Mustacchi 
4149d26e4fcSRobert Mustacchi init_adminq_free_rings:
4159d26e4fcSRobert Mustacchi 	i40e_free_adminq_asq(hw);
416*df36e06dSRobert Mustacchi 	return ret_code;
417*df36e06dSRobert Mustacchi 
418*df36e06dSRobert Mustacchi init_config_regs:
419*df36e06dSRobert Mustacchi 	i40e_free_asq_bufs(hw);
4209d26e4fcSRobert Mustacchi 
4219d26e4fcSRobert Mustacchi init_adminq_exit:
4229d26e4fcSRobert Mustacchi 	return ret_code;
4239d26e4fcSRobert Mustacchi }
4249d26e4fcSRobert Mustacchi 
4259d26e4fcSRobert Mustacchi /**
4269d26e4fcSRobert Mustacchi  *  i40e_init_arq - initialize ARQ
4279d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
4289d26e4fcSRobert Mustacchi  *
4299d26e4fcSRobert Mustacchi  *  The main initialization routine for the Admin Receive (Event) Queue.
4309d26e4fcSRobert Mustacchi  *  Prior to calling this function, drivers *MUST* set the following fields
4319d26e4fcSRobert Mustacchi  *  in the hw->aq structure:
4329d26e4fcSRobert Mustacchi  *     - hw->aq.num_asq_entries
4339d26e4fcSRobert Mustacchi  *     - hw->aq.arq_buf_size
4349d26e4fcSRobert Mustacchi  *
4359d26e4fcSRobert Mustacchi  *  Do *NOT* hold the lock when calling this as the memory allocation routines
4369d26e4fcSRobert Mustacchi  *  called are not going to be atomic context safe
4379d26e4fcSRobert Mustacchi  **/
i40e_init_arq(struct i40e_hw * hw)4389d26e4fcSRobert Mustacchi enum i40e_status_code i40e_init_arq(struct i40e_hw *hw)
4399d26e4fcSRobert Mustacchi {
4409d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
4419d26e4fcSRobert Mustacchi 
4429d26e4fcSRobert Mustacchi 	if (hw->aq.arq.count > 0) {
4439d26e4fcSRobert Mustacchi 		/* queue already initialized */
4449d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_NOT_READY;
4459d26e4fcSRobert Mustacchi 		goto init_adminq_exit;
4469d26e4fcSRobert Mustacchi 	}
4479d26e4fcSRobert Mustacchi 
4489d26e4fcSRobert Mustacchi 	/* verify input for valid configuration */
4499d26e4fcSRobert Mustacchi 	if ((hw->aq.num_arq_entries == 0) ||
4509d26e4fcSRobert Mustacchi 	    (hw->aq.arq_buf_size == 0)) {
4519d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_CONFIG;
4529d26e4fcSRobert Mustacchi 		goto init_adminq_exit;
4539d26e4fcSRobert Mustacchi 	}
4549d26e4fcSRobert Mustacchi 
4559d26e4fcSRobert Mustacchi 	hw->aq.arq.next_to_use = 0;
4569d26e4fcSRobert Mustacchi 	hw->aq.arq.next_to_clean = 0;
4579d26e4fcSRobert Mustacchi 
4589d26e4fcSRobert Mustacchi 	/* allocate the ring memory */
4599d26e4fcSRobert Mustacchi 	ret_code = i40e_alloc_adminq_arq_ring(hw);
4609d26e4fcSRobert Mustacchi 	if (ret_code != I40E_SUCCESS)
4619d26e4fcSRobert Mustacchi 		goto init_adminq_exit;
4629d26e4fcSRobert Mustacchi 
4639d26e4fcSRobert Mustacchi 	/* allocate buffers in the rings */
4649d26e4fcSRobert Mustacchi 	ret_code = i40e_alloc_arq_bufs(hw);
4659d26e4fcSRobert Mustacchi 	if (ret_code != I40E_SUCCESS)
4669d26e4fcSRobert Mustacchi 		goto init_adminq_free_rings;
4679d26e4fcSRobert Mustacchi 
4689d26e4fcSRobert Mustacchi 	/* initialize base registers */
4699d26e4fcSRobert Mustacchi 	ret_code = i40e_config_arq_regs(hw);
4709d26e4fcSRobert Mustacchi 	if (ret_code != I40E_SUCCESS)
4719d26e4fcSRobert Mustacchi 		goto init_adminq_free_rings;
4729d26e4fcSRobert Mustacchi 
4739d26e4fcSRobert Mustacchi 	/* success! */
4743d75a287SRobert Mustacchi 	hw->aq.arq.count = hw->aq.num_arq_entries;
4759d26e4fcSRobert Mustacchi 	goto init_adminq_exit;
4769d26e4fcSRobert Mustacchi 
4779d26e4fcSRobert Mustacchi init_adminq_free_rings:
4789d26e4fcSRobert Mustacchi 	i40e_free_adminq_arq(hw);
4799d26e4fcSRobert Mustacchi 
4809d26e4fcSRobert Mustacchi init_adminq_exit:
4819d26e4fcSRobert Mustacchi 	return ret_code;
4829d26e4fcSRobert Mustacchi }
4839d26e4fcSRobert Mustacchi 
4849d26e4fcSRobert Mustacchi /**
4859d26e4fcSRobert Mustacchi  *  i40e_shutdown_asq - shutdown the ASQ
4869d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
4879d26e4fcSRobert Mustacchi  *
4889d26e4fcSRobert Mustacchi  *  The main shutdown routine for the Admin Send Queue
4899d26e4fcSRobert Mustacchi  **/
i40e_shutdown_asq(struct i40e_hw * hw)4909d26e4fcSRobert Mustacchi enum i40e_status_code i40e_shutdown_asq(struct i40e_hw *hw)
4919d26e4fcSRobert Mustacchi {
4929d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
4939d26e4fcSRobert Mustacchi 
4943d75a287SRobert Mustacchi 	i40e_acquire_spinlock(&hw->aq.asq_spinlock);
4953d75a287SRobert Mustacchi 
4963d75a287SRobert Mustacchi 	if (hw->aq.asq.count == 0) {
4973d75a287SRobert Mustacchi 		ret_code = I40E_ERR_NOT_READY;
4983d75a287SRobert Mustacchi 		goto shutdown_asq_out;
4993d75a287SRobert Mustacchi 	}
5009d26e4fcSRobert Mustacchi 
5019d26e4fcSRobert Mustacchi 	/* Stop firmware AdminQ processing */
5029d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.asq.head, 0);
5039d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.asq.tail, 0);
5049d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.asq.len, 0);
5059d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.asq.bal, 0);
5069d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.asq.bah, 0);
5079d26e4fcSRobert Mustacchi 
5089d26e4fcSRobert Mustacchi 	hw->aq.asq.count = 0; /* to indicate uninitialized queue */
5099d26e4fcSRobert Mustacchi 
5109d26e4fcSRobert Mustacchi 	/* free ring buffers */
5119d26e4fcSRobert Mustacchi 	i40e_free_asq_bufs(hw);
5129d26e4fcSRobert Mustacchi 
5133d75a287SRobert Mustacchi shutdown_asq_out:
5149d26e4fcSRobert Mustacchi 	i40e_release_spinlock(&hw->aq.asq_spinlock);
5159d26e4fcSRobert Mustacchi 	return ret_code;
5169d26e4fcSRobert Mustacchi }
5179d26e4fcSRobert Mustacchi 
5189d26e4fcSRobert Mustacchi /**
5199d26e4fcSRobert Mustacchi  *  i40e_shutdown_arq - shutdown ARQ
5209d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
5219d26e4fcSRobert Mustacchi  *
5229d26e4fcSRobert Mustacchi  *  The main shutdown routine for the Admin Receive Queue
5239d26e4fcSRobert Mustacchi  **/
i40e_shutdown_arq(struct i40e_hw * hw)5249d26e4fcSRobert Mustacchi enum i40e_status_code i40e_shutdown_arq(struct i40e_hw *hw)
5259d26e4fcSRobert Mustacchi {
5269d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
5279d26e4fcSRobert Mustacchi 
5283d75a287SRobert Mustacchi 	i40e_acquire_spinlock(&hw->aq.arq_spinlock);
5293d75a287SRobert Mustacchi 
5303d75a287SRobert Mustacchi 	if (hw->aq.arq.count == 0) {
5313d75a287SRobert Mustacchi 		ret_code = I40E_ERR_NOT_READY;
5323d75a287SRobert Mustacchi 		goto shutdown_arq_out;
5333d75a287SRobert Mustacchi 	}
5349d26e4fcSRobert Mustacchi 
5359d26e4fcSRobert Mustacchi 	/* Stop firmware AdminQ processing */
5369d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.arq.head, 0);
5379d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.arq.tail, 0);
5389d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.arq.len, 0);
5399d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.arq.bal, 0);
5409d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.arq.bah, 0);
5419d26e4fcSRobert Mustacchi 
5429d26e4fcSRobert Mustacchi 	hw->aq.arq.count = 0; /* to indicate uninitialized queue */
5439d26e4fcSRobert Mustacchi 
5449d26e4fcSRobert Mustacchi 	/* free ring buffers */
5459d26e4fcSRobert Mustacchi 	i40e_free_arq_bufs(hw);
5469d26e4fcSRobert Mustacchi 
5473d75a287SRobert Mustacchi shutdown_arq_out:
5489d26e4fcSRobert Mustacchi 	i40e_release_spinlock(&hw->aq.arq_spinlock);
5499d26e4fcSRobert Mustacchi 	return ret_code;
5509d26e4fcSRobert Mustacchi }
5519d26e4fcSRobert Mustacchi 
5529d26e4fcSRobert Mustacchi /**
5533d75a287SRobert Mustacchi  *  i40e_resume_aq - resume AQ processing from 0
5543d75a287SRobert Mustacchi  *  @hw: pointer to the hardware structure
5553d75a287SRobert Mustacchi  **/
i40e_resume_aq(struct i40e_hw * hw)5563d75a287SRobert Mustacchi static void i40e_resume_aq(struct i40e_hw *hw)
5573d75a287SRobert Mustacchi {
5583d75a287SRobert Mustacchi 	/* Registers are reset after PF reset */
5593d75a287SRobert Mustacchi 	hw->aq.asq.next_to_use = 0;
5603d75a287SRobert Mustacchi 	hw->aq.asq.next_to_clean = 0;
5613d75a287SRobert Mustacchi 
5623d75a287SRobert Mustacchi 	i40e_config_asq_regs(hw);
5633d75a287SRobert Mustacchi 
5643d75a287SRobert Mustacchi 	hw->aq.arq.next_to_use = 0;
5653d75a287SRobert Mustacchi 	hw->aq.arq.next_to_clean = 0;
5663d75a287SRobert Mustacchi 
5673d75a287SRobert Mustacchi 	i40e_config_arq_regs(hw);
5683d75a287SRobert Mustacchi }
5693d75a287SRobert Mustacchi 
5703d75a287SRobert Mustacchi /**
571*df36e06dSRobert Mustacchi  *  i40e_set_hw_flags - set HW flags
572*df36e06dSRobert Mustacchi  *  @hw: pointer to the hardware structure
573*df36e06dSRobert Mustacchi  **/
i40e_set_hw_flags(struct i40e_hw * hw)574*df36e06dSRobert Mustacchi static void i40e_set_hw_flags(struct i40e_hw *hw)
575*df36e06dSRobert Mustacchi {
576*df36e06dSRobert Mustacchi 	struct i40e_adminq_info *aq = &hw->aq;
577*df36e06dSRobert Mustacchi 
578*df36e06dSRobert Mustacchi 	hw->flags = 0;
579*df36e06dSRobert Mustacchi 
580*df36e06dSRobert Mustacchi 	switch (hw->mac.type) {
581*df36e06dSRobert Mustacchi 	case I40E_MAC_XL710:
582*df36e06dSRobert Mustacchi 		if (aq->api_maj_ver > 1 ||
583*df36e06dSRobert Mustacchi 		    (aq->api_maj_ver == 1 &&
584*df36e06dSRobert Mustacchi 		     aq->api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_XL710)) {
585*df36e06dSRobert Mustacchi 			hw->flags |= I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE;
586*df36e06dSRobert Mustacchi 			hw->flags |= I40E_HW_FLAG_FW_LLDP_STOPPABLE;
587*df36e06dSRobert Mustacchi 			/* The ability to RX (not drop) 802.1ad frames */
588*df36e06dSRobert Mustacchi 			hw->flags |= I40E_HW_FLAG_802_1AD_CAPABLE;
589*df36e06dSRobert Mustacchi 		}
590*df36e06dSRobert Mustacchi 		break;
591*df36e06dSRobert Mustacchi 	case I40E_MAC_X722:
592*df36e06dSRobert Mustacchi 		hw->flags |= I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE |
593*df36e06dSRobert Mustacchi 			     I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK;
594*df36e06dSRobert Mustacchi 
595*df36e06dSRobert Mustacchi 		if (aq->api_maj_ver > 1 ||
596*df36e06dSRobert Mustacchi 		    (aq->api_maj_ver == 1 &&
597*df36e06dSRobert Mustacchi 		     aq->api_min_ver >= I40E_MINOR_VER_FW_LLDP_STOPPABLE_X722))
598*df36e06dSRobert Mustacchi 			hw->flags |= I40E_HW_FLAG_FW_LLDP_STOPPABLE;
599*df36e06dSRobert Mustacchi 
600*df36e06dSRobert Mustacchi 		if (aq->api_maj_ver > 1 ||
601*df36e06dSRobert Mustacchi 		    (aq->api_maj_ver == 1 &&
602*df36e06dSRobert Mustacchi 		     aq->api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_X722))
603*df36e06dSRobert Mustacchi 			hw->flags |= I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE;
604*df36e06dSRobert Mustacchi 
605*df36e06dSRobert Mustacchi 		if (aq->api_maj_ver > 1 ||
606*df36e06dSRobert Mustacchi 		    (aq->api_maj_ver == 1 &&
607*df36e06dSRobert Mustacchi 		     aq->api_min_ver >= I40E_MINOR_VER_FW_REQUEST_FEC_X722))
608*df36e06dSRobert Mustacchi 			hw->flags |= I40E_HW_FLAG_X722_FEC_REQUEST_CAPABLE;
609*df36e06dSRobert Mustacchi 
610*df36e06dSRobert Mustacchi 		/* fall through */
611*df36e06dSRobert Mustacchi 	default:
612*df36e06dSRobert Mustacchi 		break;
613*df36e06dSRobert Mustacchi 	}
614*df36e06dSRobert Mustacchi 
615*df36e06dSRobert Mustacchi 	/* Newer versions of firmware require lock when reading the NVM */
616*df36e06dSRobert Mustacchi 	if (aq->api_maj_ver > 1 ||
617*df36e06dSRobert Mustacchi 	    (aq->api_maj_ver == 1 &&
618*df36e06dSRobert Mustacchi 	     aq->api_min_ver >= 5))
619*df36e06dSRobert Mustacchi 		hw->flags |= I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK;
620*df36e06dSRobert Mustacchi 
621*df36e06dSRobert Mustacchi 	if (aq->api_maj_ver > 1 ||
622*df36e06dSRobert Mustacchi 	    (aq->api_maj_ver == 1 &&
623*df36e06dSRobert Mustacchi 	     aq->api_min_ver >= 8)) {
624*df36e06dSRobert Mustacchi 		hw->flags |= I40E_HW_FLAG_FW_LLDP_PERSISTENT;
625*df36e06dSRobert Mustacchi 		hw->flags |= I40E_HW_FLAG_DROP_MODE;
626*df36e06dSRobert Mustacchi 	}
627*df36e06dSRobert Mustacchi 
628*df36e06dSRobert Mustacchi 	if (aq->api_maj_ver > 1 ||
629*df36e06dSRobert Mustacchi 	    (aq->api_maj_ver == 1 &&
630*df36e06dSRobert Mustacchi 	     aq->api_min_ver >= 9))
631*df36e06dSRobert Mustacchi 		hw->flags |= I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED;
632*df36e06dSRobert Mustacchi }
633*df36e06dSRobert Mustacchi 
634*df36e06dSRobert Mustacchi /**
6359d26e4fcSRobert Mustacchi  *  i40e_init_adminq - main initialization routine for Admin Queue
6369d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
6379d26e4fcSRobert Mustacchi  *
6389d26e4fcSRobert Mustacchi  *  Prior to calling this function, drivers *MUST* set the following fields
6399d26e4fcSRobert Mustacchi  *  in the hw->aq structure:
6409d26e4fcSRobert Mustacchi  *     - hw->aq.num_asq_entries
6419d26e4fcSRobert Mustacchi  *     - hw->aq.num_arq_entries
6429d26e4fcSRobert Mustacchi  *     - hw->aq.arq_buf_size
6439d26e4fcSRobert Mustacchi  *     - hw->aq.asq_buf_size
6449d26e4fcSRobert Mustacchi  **/
i40e_init_adminq(struct i40e_hw * hw)6459d26e4fcSRobert Mustacchi enum i40e_status_code i40e_init_adminq(struct i40e_hw *hw)
6469d26e4fcSRobert Mustacchi {
647*df36e06dSRobert Mustacchi 	struct i40e_adminq_info *aq = &hw->aq;
648*df36e06dSRobert Mustacchi 	enum i40e_status_code ret_code;
6499d26e4fcSRobert Mustacchi 	u16 cfg_ptr, oem_hi, oem_lo;
6503d75a287SRobert Mustacchi 	u16 eetrack_lo, eetrack_hi;
6519d26e4fcSRobert Mustacchi 	int retry = 0;
6523d75a287SRobert Mustacchi 
6539d26e4fcSRobert Mustacchi 	/* verify input for valid configuration */
654*df36e06dSRobert Mustacchi 	if (aq->num_arq_entries == 0 ||
655*df36e06dSRobert Mustacchi 	    aq->num_asq_entries == 0 ||
656*df36e06dSRobert Mustacchi 	    aq->arq_buf_size == 0 ||
657*df36e06dSRobert Mustacchi 	    aq->asq_buf_size == 0) {
6589d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_CONFIG;
6599d26e4fcSRobert Mustacchi 		goto init_adminq_exit;
6609d26e4fcSRobert Mustacchi 	}
661*df36e06dSRobert Mustacchi 	i40e_init_spinlock(&aq->asq_spinlock);
662*df36e06dSRobert Mustacchi 	i40e_init_spinlock(&aq->arq_spinlock);
6639d26e4fcSRobert Mustacchi 
6649d26e4fcSRobert Mustacchi 	/* Set up register offsets */
6659d26e4fcSRobert Mustacchi 	i40e_adminq_init_regs(hw);
6669d26e4fcSRobert Mustacchi 
6679d26e4fcSRobert Mustacchi 	/* setup ASQ command write back timeout */
6689d26e4fcSRobert Mustacchi 	hw->aq.asq_cmd_timeout = I40E_ASQ_CMD_TIMEOUT;
6699d26e4fcSRobert Mustacchi 
6709d26e4fcSRobert Mustacchi 	/* allocate the ASQ */
6719d26e4fcSRobert Mustacchi 	ret_code = i40e_init_asq(hw);
6729d26e4fcSRobert Mustacchi 	if (ret_code != I40E_SUCCESS)
6739d26e4fcSRobert Mustacchi 		goto init_adminq_destroy_spinlocks;
6749d26e4fcSRobert Mustacchi 
6759d26e4fcSRobert Mustacchi 	/* allocate the ARQ */
6769d26e4fcSRobert Mustacchi 	ret_code = i40e_init_arq(hw);
6779d26e4fcSRobert Mustacchi 	if (ret_code != I40E_SUCCESS)
6789d26e4fcSRobert Mustacchi 		goto init_adminq_free_asq;
6799d26e4fcSRobert Mustacchi 
680*df36e06dSRobert Mustacchi 	/* VF has no need of firmware */
681*df36e06dSRobert Mustacchi 	if (i40e_is_vf(hw))
682*df36e06dSRobert Mustacchi 		goto init_adminq_exit;
6839d26e4fcSRobert Mustacchi 	/* There are some cases where the firmware may not be quite ready
6849d26e4fcSRobert Mustacchi 	 * for AdminQ operations, so we retry the AdminQ setup a few times
6859d26e4fcSRobert Mustacchi 	 * if we see timeouts in this first AQ call.
6869d26e4fcSRobert Mustacchi 	 */
6879d26e4fcSRobert Mustacchi 	do {
6889d26e4fcSRobert Mustacchi 		ret_code = i40e_aq_get_firmware_version(hw,
689*df36e06dSRobert Mustacchi 							&aq->fw_maj_ver,
690*df36e06dSRobert Mustacchi 							&aq->fw_min_ver,
691*df36e06dSRobert Mustacchi 							&aq->fw_build,
692*df36e06dSRobert Mustacchi 							&aq->api_maj_ver,
693*df36e06dSRobert Mustacchi 							&aq->api_min_ver,
6949d26e4fcSRobert Mustacchi 							NULL);
6959d26e4fcSRobert Mustacchi 		if (ret_code != I40E_ERR_ADMIN_QUEUE_TIMEOUT)
6969d26e4fcSRobert Mustacchi 			break;
6979d26e4fcSRobert Mustacchi 		retry++;
6989d26e4fcSRobert Mustacchi 		i40e_msec_delay(100);
6999d26e4fcSRobert Mustacchi 		i40e_resume_aq(hw);
7009d26e4fcSRobert Mustacchi 	} while (retry < 10);
7019d26e4fcSRobert Mustacchi 	if (ret_code != I40E_SUCCESS)
7029d26e4fcSRobert Mustacchi 		goto init_adminq_free_arq;
7039d26e4fcSRobert Mustacchi 
704*df36e06dSRobert Mustacchi 	/*
705*df36e06dSRobert Mustacchi 	 * Some features were introduced in different FW API version
706*df36e06dSRobert Mustacchi 	 * for different MAC type.
707*df36e06dSRobert Mustacchi 	 */
708*df36e06dSRobert Mustacchi 	i40e_set_hw_flags(hw);
709*df36e06dSRobert Mustacchi 
7109d26e4fcSRobert Mustacchi 	/* get the NVM version info */
7119d26e4fcSRobert Mustacchi 	i40e_read_nvm_word(hw, I40E_SR_NVM_DEV_STARTER_VERSION,
7129d26e4fcSRobert Mustacchi 			   &hw->nvm.version);
7139d26e4fcSRobert Mustacchi 	i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_LO, &eetrack_lo);
7149d26e4fcSRobert Mustacchi 	i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_HI, &eetrack_hi);
7159d26e4fcSRobert Mustacchi 	hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;
7169d26e4fcSRobert Mustacchi 	i40e_read_nvm_word(hw, I40E_SR_BOOT_CONFIG_PTR, &cfg_ptr);
7179d26e4fcSRobert Mustacchi 	i40e_read_nvm_word(hw, (cfg_ptr + I40E_NVM_OEM_VER_OFF),
7189d26e4fcSRobert Mustacchi 			   &oem_hi);
7199d26e4fcSRobert Mustacchi 	i40e_read_nvm_word(hw, (cfg_ptr + (I40E_NVM_OEM_VER_OFF + 1)),
7209d26e4fcSRobert Mustacchi 			   &oem_lo);
7219d26e4fcSRobert Mustacchi 	hw->nvm.oem_ver = ((u32)oem_hi << 16) | oem_lo;
7229d26e4fcSRobert Mustacchi 
723*df36e06dSRobert Mustacchi 	if (aq->api_maj_ver > I40E_FW_API_VERSION_MAJOR) {
7249d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_FIRMWARE_API_VERSION;
7259d26e4fcSRobert Mustacchi 		goto init_adminq_free_arq;
7269d26e4fcSRobert Mustacchi 	}
7279d26e4fcSRobert Mustacchi 
7289d26e4fcSRobert Mustacchi 	/* pre-emptive resource lock release */
7299d26e4fcSRobert Mustacchi 	i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
7303d75a287SRobert Mustacchi 	hw->nvm_release_on_done = FALSE;
7319d26e4fcSRobert Mustacchi 	hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
7329d26e4fcSRobert Mustacchi 
7339d26e4fcSRobert Mustacchi 	ret_code = I40E_SUCCESS;
7349d26e4fcSRobert Mustacchi 
7359d26e4fcSRobert Mustacchi 	/* success! */
7369d26e4fcSRobert Mustacchi 	goto init_adminq_exit;
7379d26e4fcSRobert Mustacchi 
7389d26e4fcSRobert Mustacchi init_adminq_free_arq:
7399d26e4fcSRobert Mustacchi 	i40e_shutdown_arq(hw);
7409d26e4fcSRobert Mustacchi init_adminq_free_asq:
7419d26e4fcSRobert Mustacchi 	i40e_shutdown_asq(hw);
7429d26e4fcSRobert Mustacchi init_adminq_destroy_spinlocks:
743*df36e06dSRobert Mustacchi 	i40e_destroy_spinlock(&aq->asq_spinlock);
744*df36e06dSRobert Mustacchi 	i40e_destroy_spinlock(&aq->arq_spinlock);
7459d26e4fcSRobert Mustacchi 
7469d26e4fcSRobert Mustacchi init_adminq_exit:
7479d26e4fcSRobert Mustacchi 	return ret_code;
7489d26e4fcSRobert Mustacchi }
7499d26e4fcSRobert Mustacchi 
7509d26e4fcSRobert Mustacchi /**
7519d26e4fcSRobert Mustacchi  *  i40e_shutdown_adminq - shutdown routine for the Admin Queue
7529d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
7539d26e4fcSRobert Mustacchi  **/
i40e_shutdown_adminq(struct i40e_hw * hw)7549d26e4fcSRobert Mustacchi enum i40e_status_code i40e_shutdown_adminq(struct i40e_hw *hw)
7559d26e4fcSRobert Mustacchi {
7569d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
7579d26e4fcSRobert Mustacchi 
7589d26e4fcSRobert Mustacchi 	if (i40e_check_asq_alive(hw))
7599d26e4fcSRobert Mustacchi 		i40e_aq_queue_shutdown(hw, TRUE);
7609d26e4fcSRobert Mustacchi 
7619d26e4fcSRobert Mustacchi 	i40e_shutdown_asq(hw);
7629d26e4fcSRobert Mustacchi 	i40e_shutdown_arq(hw);
7639d26e4fcSRobert Mustacchi 	i40e_destroy_spinlock(&hw->aq.asq_spinlock);
7649d26e4fcSRobert Mustacchi 	i40e_destroy_spinlock(&hw->aq.arq_spinlock);
7659d26e4fcSRobert Mustacchi 
7669d26e4fcSRobert Mustacchi 	if (hw->nvm_buff.va)
7679d26e4fcSRobert Mustacchi 		i40e_free_virt_mem(hw, &hw->nvm_buff);
7689d26e4fcSRobert Mustacchi 
7699d26e4fcSRobert Mustacchi 	return ret_code;
7709d26e4fcSRobert Mustacchi }
7719d26e4fcSRobert Mustacchi 
7729d26e4fcSRobert Mustacchi /**
7739d26e4fcSRobert Mustacchi  *  i40e_clean_asq - cleans Admin send queue
7749d26e4fcSRobert Mustacchi  *  @hw: pointer to the hardware structure
7759d26e4fcSRobert Mustacchi  *
7769d26e4fcSRobert Mustacchi  *  returns the number of free desc
7779d26e4fcSRobert Mustacchi  **/
i40e_clean_asq(struct i40e_hw * hw)7789d26e4fcSRobert Mustacchi u16 i40e_clean_asq(struct i40e_hw *hw)
7799d26e4fcSRobert Mustacchi {
7809d26e4fcSRobert Mustacchi 	struct i40e_adminq_ring *asq = &(hw->aq.asq);
7819d26e4fcSRobert Mustacchi 	struct i40e_asq_cmd_details *details;
7829d26e4fcSRobert Mustacchi 	u16 ntc = asq->next_to_clean;
7839d26e4fcSRobert Mustacchi 	struct i40e_aq_desc desc_cb;
7849d26e4fcSRobert Mustacchi 	struct i40e_aq_desc *desc;
7859d26e4fcSRobert Mustacchi 
7869d26e4fcSRobert Mustacchi 	desc = I40E_ADMINQ_DESC(*asq, ntc);
7879d26e4fcSRobert Mustacchi 	details = I40E_ADMINQ_DETAILS(*asq, ntc);
7889d26e4fcSRobert Mustacchi 	while (rd32(hw, hw->aq.asq.head) != ntc) {
789*df36e06dSRobert Mustacchi 		i40e_debug(hw, I40E_DEBUG_AQ_COMMAND,
7909d26e4fcSRobert Mustacchi 			   "ntc %d head %d.\n", ntc, rd32(hw, hw->aq.asq.head));
7919d26e4fcSRobert Mustacchi 
7929d26e4fcSRobert Mustacchi 		if (details->callback) {
7939d26e4fcSRobert Mustacchi 			I40E_ADMINQ_CALLBACK cb_func =
7949d26e4fcSRobert Mustacchi 					(I40E_ADMINQ_CALLBACK)details->callback;
7959d26e4fcSRobert Mustacchi 			i40e_memcpy(&desc_cb, desc, sizeof(struct i40e_aq_desc),
7969d26e4fcSRobert Mustacchi 				    I40E_DMA_TO_DMA);
7979d26e4fcSRobert Mustacchi 			cb_func(hw, &desc_cb);
7989d26e4fcSRobert Mustacchi 		}
7999d26e4fcSRobert Mustacchi 		i40e_memset(desc, 0, sizeof(*desc), I40E_DMA_MEM);
8009d26e4fcSRobert Mustacchi 		i40e_memset(details, 0, sizeof(*details), I40E_NONDMA_MEM);
8019d26e4fcSRobert Mustacchi 		ntc++;
8029d26e4fcSRobert Mustacchi 		if (ntc == asq->count)
8039d26e4fcSRobert Mustacchi 			ntc = 0;
8049d26e4fcSRobert Mustacchi 		desc = I40E_ADMINQ_DESC(*asq, ntc);
8059d26e4fcSRobert Mustacchi 		details = I40E_ADMINQ_DETAILS(*asq, ntc);
8069d26e4fcSRobert Mustacchi 	}
8079d26e4fcSRobert Mustacchi 
8089d26e4fcSRobert Mustacchi 	asq->next_to_clean = ntc;
8099d26e4fcSRobert Mustacchi 
8109d26e4fcSRobert Mustacchi 	return I40E_DESC_UNUSED(asq);
8119d26e4fcSRobert Mustacchi }
8129d26e4fcSRobert Mustacchi 
8139d26e4fcSRobert Mustacchi /**
8149d26e4fcSRobert Mustacchi  *  i40e_asq_done - check if FW has processed the Admin Send Queue
8159d26e4fcSRobert Mustacchi  *  @hw: pointer to the hw struct
8169d26e4fcSRobert Mustacchi  *
8179d26e4fcSRobert Mustacchi  *  Returns TRUE if the firmware has processed all descriptors on the
8189d26e4fcSRobert Mustacchi  *  admin send queue. Returns FALSE if there are still requests pending.
8199d26e4fcSRobert Mustacchi  **/
i40e_asq_done(struct i40e_hw * hw)820*df36e06dSRobert Mustacchi bool i40e_asq_done(struct i40e_hw *hw)
8219d26e4fcSRobert Mustacchi {
8229d26e4fcSRobert Mustacchi 	/* AQ designers suggest use of head for better
8239d26e4fcSRobert Mustacchi 	 * timing reliability than DD bit
8249d26e4fcSRobert Mustacchi 	 */
8259d26e4fcSRobert Mustacchi 	return rd32(hw, hw->aq.asq.head) == hw->aq.asq.next_to_use;
8269d26e4fcSRobert Mustacchi 
8279d26e4fcSRobert Mustacchi }
8289d26e4fcSRobert Mustacchi 
8299d26e4fcSRobert Mustacchi /**
8309d26e4fcSRobert Mustacchi  *  i40e_asq_send_command - send command to Admin Queue
8319d26e4fcSRobert Mustacchi  *  @hw: pointer to the hw struct
8329d26e4fcSRobert Mustacchi  *  @desc: prefilled descriptor describing the command (non DMA mem)
8339d26e4fcSRobert Mustacchi  *  @buff: buffer to use for indirect commands
8349d26e4fcSRobert Mustacchi  *  @buff_size: size of buffer for indirect commands
8359d26e4fcSRobert Mustacchi  *  @cmd_details: pointer to command details structure
8369d26e4fcSRobert Mustacchi  *
8379d26e4fcSRobert Mustacchi  *  This is the main send command driver routine for the Admin Queue send
8389d26e4fcSRobert Mustacchi  *  queue.  It runs the queue, cleans the queue, etc
8399d26e4fcSRobert Mustacchi  **/
i40e_asq_send_command(struct i40e_hw * hw,struct i40e_aq_desc * desc,void * buff,u16 buff_size,struct i40e_asq_cmd_details * cmd_details)8409d26e4fcSRobert Mustacchi enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw,
8419d26e4fcSRobert Mustacchi 				struct i40e_aq_desc *desc,
8429d26e4fcSRobert Mustacchi 				void *buff, /* can be NULL */
8439d26e4fcSRobert Mustacchi 				u16  buff_size,
8449d26e4fcSRobert Mustacchi 				struct i40e_asq_cmd_details *cmd_details)
8459d26e4fcSRobert Mustacchi {
8469d26e4fcSRobert Mustacchi 	enum i40e_status_code status = I40E_SUCCESS;
8479d26e4fcSRobert Mustacchi 	struct i40e_dma_mem *dma_buff = NULL;
8489d26e4fcSRobert Mustacchi 	struct i40e_asq_cmd_details *details;
8499d26e4fcSRobert Mustacchi 	struct i40e_aq_desc *desc_on_ring;
8509d26e4fcSRobert Mustacchi 	bool cmd_completed = FALSE;
8519d26e4fcSRobert Mustacchi 	u16  retval = 0;
8529d26e4fcSRobert Mustacchi 	u32  val = 0;
8539d26e4fcSRobert Mustacchi 
8543d75a287SRobert Mustacchi 	i40e_acquire_spinlock(&hw->aq.asq_spinlock);
8553d75a287SRobert Mustacchi 
8569d26e4fcSRobert Mustacchi 	hw->aq.asq_last_status = I40E_AQ_RC_OK;
8579d26e4fcSRobert Mustacchi 
8583d75a287SRobert Mustacchi 	if (hw->aq.asq.count == 0) {
8593d75a287SRobert Mustacchi 		i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
8603d75a287SRobert Mustacchi 			   "AQTX: Admin queue not initialized.\n");
8613d75a287SRobert Mustacchi 		status = I40E_ERR_QUEUE_EMPTY;
8623d75a287SRobert Mustacchi 		goto asq_send_command_error;
8633d75a287SRobert Mustacchi 	}
8643d75a287SRobert Mustacchi 
8659d26e4fcSRobert Mustacchi 	val = rd32(hw, hw->aq.asq.head);
8669d26e4fcSRobert Mustacchi 	if (val >= hw->aq.num_asq_entries) {
8679d26e4fcSRobert Mustacchi 		i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
8689d26e4fcSRobert Mustacchi 			   "AQTX: head overrun at %d\n", val);
869*df36e06dSRobert Mustacchi 		status = I40E_ERR_ADMIN_QUEUE_FULL;
8703d75a287SRobert Mustacchi 		goto asq_send_command_error;
8719d26e4fcSRobert Mustacchi 	}
8729d26e4fcSRobert Mustacchi 
8739d26e4fcSRobert Mustacchi 	details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
8749d26e4fcSRobert Mustacchi 	if (cmd_details) {
8759d26e4fcSRobert Mustacchi 		i40e_memcpy(details,
8769d26e4fcSRobert Mustacchi 			    cmd_details,
8779d26e4fcSRobert Mustacchi 			    sizeof(struct i40e_asq_cmd_details),
8789d26e4fcSRobert Mustacchi 			    I40E_NONDMA_TO_NONDMA);
8799d26e4fcSRobert Mustacchi 
8809d26e4fcSRobert Mustacchi 		/* If the cmd_details are defined copy the cookie.  The
8819d26e4fcSRobert Mustacchi 		 * CPU_TO_LE32 is not needed here because the data is ignored
8829d26e4fcSRobert Mustacchi 		 * by the FW, only used by the driver
8839d26e4fcSRobert Mustacchi 		 */
8849d26e4fcSRobert Mustacchi 		if (details->cookie) {
8859d26e4fcSRobert Mustacchi 			desc->cookie_high =
8869d26e4fcSRobert Mustacchi 				CPU_TO_LE32(I40E_HI_DWORD(details->cookie));
8879d26e4fcSRobert Mustacchi 			desc->cookie_low =
8889d26e4fcSRobert Mustacchi 				CPU_TO_LE32(I40E_LO_DWORD(details->cookie));
8899d26e4fcSRobert Mustacchi 		}
8909d26e4fcSRobert Mustacchi 	} else {
8919d26e4fcSRobert Mustacchi 		i40e_memset(details, 0,
8929d26e4fcSRobert Mustacchi 			    sizeof(struct i40e_asq_cmd_details),
8939d26e4fcSRobert Mustacchi 			    I40E_NONDMA_MEM);
8949d26e4fcSRobert Mustacchi 	}
8959d26e4fcSRobert Mustacchi 
8969d26e4fcSRobert Mustacchi 	/* clear requested flags and then set additional flags if defined */
8979d26e4fcSRobert Mustacchi 	desc->flags &= ~CPU_TO_LE16(details->flags_dis);
8989d26e4fcSRobert Mustacchi 	desc->flags |= CPU_TO_LE16(details->flags_ena);
8999d26e4fcSRobert Mustacchi 
9009d26e4fcSRobert Mustacchi 	if (buff_size > hw->aq.asq_buf_size) {
9019d26e4fcSRobert Mustacchi 		i40e_debug(hw,
9029d26e4fcSRobert Mustacchi 			   I40E_DEBUG_AQ_MESSAGE,
9039d26e4fcSRobert Mustacchi 			   "AQTX: Invalid buffer size: %d.\n",
9049d26e4fcSRobert Mustacchi 			   buff_size);
9059d26e4fcSRobert Mustacchi 		status = I40E_ERR_INVALID_SIZE;
9069d26e4fcSRobert Mustacchi 		goto asq_send_command_error;
9079d26e4fcSRobert Mustacchi 	}
9089d26e4fcSRobert Mustacchi 
9099d26e4fcSRobert Mustacchi 	if (details->postpone && !details->async) {
9109d26e4fcSRobert Mustacchi 		i40e_debug(hw,
9119d26e4fcSRobert Mustacchi 			   I40E_DEBUG_AQ_MESSAGE,
9129d26e4fcSRobert Mustacchi 			   "AQTX: Async flag not set along with postpone flag");
9139d26e4fcSRobert Mustacchi 		status = I40E_ERR_PARAM;
9149d26e4fcSRobert Mustacchi 		goto asq_send_command_error;
9159d26e4fcSRobert Mustacchi 	}
9169d26e4fcSRobert Mustacchi 
9179d26e4fcSRobert Mustacchi 	/* call clean and check queue available function to reclaim the
9189d26e4fcSRobert Mustacchi 	 * descriptors that were processed by FW, the function returns the
9199d26e4fcSRobert Mustacchi 	 * number of desc available
9209d26e4fcSRobert Mustacchi 	 */
9219d26e4fcSRobert Mustacchi 	/* the clean function called here could be called in a separate thread
9229d26e4fcSRobert Mustacchi 	 * in case of asynchronous completions
9239d26e4fcSRobert Mustacchi 	 */
9249d26e4fcSRobert Mustacchi 	if (i40e_clean_asq(hw) == 0) {
9259d26e4fcSRobert Mustacchi 		i40e_debug(hw,
9269d26e4fcSRobert Mustacchi 			   I40E_DEBUG_AQ_MESSAGE,
9279d26e4fcSRobert Mustacchi 			   "AQTX: Error queue is full.\n");
9289d26e4fcSRobert Mustacchi 		status = I40E_ERR_ADMIN_QUEUE_FULL;
9299d26e4fcSRobert Mustacchi 		goto asq_send_command_error;
9309d26e4fcSRobert Mustacchi 	}
9319d26e4fcSRobert Mustacchi 
9329d26e4fcSRobert Mustacchi 	/* initialize the temp desc pointer with the right desc */
9339d26e4fcSRobert Mustacchi 	desc_on_ring = I40E_ADMINQ_DESC(hw->aq.asq, hw->aq.asq.next_to_use);
9349d26e4fcSRobert Mustacchi 
9359d26e4fcSRobert Mustacchi 	/* if the desc is available copy the temp desc to the right place */
9369d26e4fcSRobert Mustacchi 	i40e_memcpy(desc_on_ring, desc, sizeof(struct i40e_aq_desc),
9379d26e4fcSRobert Mustacchi 		    I40E_NONDMA_TO_DMA);
9389d26e4fcSRobert Mustacchi 
9399d26e4fcSRobert Mustacchi 	/* if buff is not NULL assume indirect command */
9409d26e4fcSRobert Mustacchi 	if (buff != NULL) {
9419d26e4fcSRobert Mustacchi 		dma_buff = &(hw->aq.asq.r.asq_bi[hw->aq.asq.next_to_use]);
9429d26e4fcSRobert Mustacchi 		/* copy the user buff into the respective DMA buff */
9439d26e4fcSRobert Mustacchi 		i40e_memcpy(dma_buff->va, buff, buff_size,
9449d26e4fcSRobert Mustacchi 			    I40E_NONDMA_TO_DMA);
9459d26e4fcSRobert Mustacchi 		desc_on_ring->datalen = CPU_TO_LE16(buff_size);
9469d26e4fcSRobert Mustacchi 
9479d26e4fcSRobert Mustacchi 		/* Update the address values in the desc with the pa value
9489d26e4fcSRobert Mustacchi 		 * for respective buffer
9499d26e4fcSRobert Mustacchi 		 */
9509d26e4fcSRobert Mustacchi 		desc_on_ring->params.external.addr_high =
9519d26e4fcSRobert Mustacchi 				CPU_TO_LE32(I40E_HI_DWORD(dma_buff->pa));
9529d26e4fcSRobert Mustacchi 		desc_on_ring->params.external.addr_low =
9539d26e4fcSRobert Mustacchi 				CPU_TO_LE32(I40E_LO_DWORD(dma_buff->pa));
9549d26e4fcSRobert Mustacchi 	}
9559d26e4fcSRobert Mustacchi 
9569d26e4fcSRobert Mustacchi 	/* bump the tail */
957*df36e06dSRobert Mustacchi 	i40e_debug(hw, I40E_DEBUG_AQ_COMMAND, "AQTX: desc and buffer:\n");
9589d26e4fcSRobert Mustacchi 	i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring,
9599d26e4fcSRobert Mustacchi 		      buff, buff_size);
9609d26e4fcSRobert Mustacchi 	(hw->aq.asq.next_to_use)++;
9619d26e4fcSRobert Mustacchi 	if (hw->aq.asq.next_to_use == hw->aq.asq.count)
9629d26e4fcSRobert Mustacchi 		hw->aq.asq.next_to_use = 0;
9639d26e4fcSRobert Mustacchi 	if (!details->postpone)
9649d26e4fcSRobert Mustacchi 		wr32(hw, hw->aq.asq.tail, hw->aq.asq.next_to_use);
9659d26e4fcSRobert Mustacchi 
9669d26e4fcSRobert Mustacchi 	/* if cmd_details are not defined or async flag is not set,
9679d26e4fcSRobert Mustacchi 	 * we need to wait for desc write back
9689d26e4fcSRobert Mustacchi 	 */
9699d26e4fcSRobert Mustacchi 	if (!details->async && !details->postpone) {
9709d26e4fcSRobert Mustacchi 		u32 total_delay = 0;
9719d26e4fcSRobert Mustacchi 
9729d26e4fcSRobert Mustacchi 		do {
9739d26e4fcSRobert Mustacchi 			/* AQ designers suggest use of head for better
9749d26e4fcSRobert Mustacchi 			 * timing reliability than DD bit
9759d26e4fcSRobert Mustacchi 			 */
9769d26e4fcSRobert Mustacchi 			if (i40e_asq_done(hw))
9779d26e4fcSRobert Mustacchi 				break;
97893f1cac5SPaul Winder 			i40e_usec_delay(50);
97993f1cac5SPaul Winder 			total_delay += 50;
9809d26e4fcSRobert Mustacchi 		} while (total_delay < hw->aq.asq_cmd_timeout);
9819d26e4fcSRobert Mustacchi 	}
9829d26e4fcSRobert Mustacchi 
9839d26e4fcSRobert Mustacchi 	/* if ready, copy the desc back to temp */
9849d26e4fcSRobert Mustacchi 	if (i40e_asq_done(hw)) {
9859d26e4fcSRobert Mustacchi 		i40e_memcpy(desc, desc_on_ring, sizeof(struct i40e_aq_desc),
9869d26e4fcSRobert Mustacchi 			    I40E_DMA_TO_NONDMA);
9879d26e4fcSRobert Mustacchi 		if (buff != NULL)
9889d26e4fcSRobert Mustacchi 			i40e_memcpy(buff, dma_buff->va, buff_size,
9899d26e4fcSRobert Mustacchi 				    I40E_DMA_TO_NONDMA);
9909d26e4fcSRobert Mustacchi 		retval = LE16_TO_CPU(desc->retval);
9919d26e4fcSRobert Mustacchi 		if (retval != 0) {
9929d26e4fcSRobert Mustacchi 			i40e_debug(hw,
9939d26e4fcSRobert Mustacchi 				   I40E_DEBUG_AQ_MESSAGE,
9949d26e4fcSRobert Mustacchi 				   "AQTX: Command completed with error 0x%X.\n",
9959d26e4fcSRobert Mustacchi 				   retval);
9969d26e4fcSRobert Mustacchi 
9979d26e4fcSRobert Mustacchi 			/* strip off FW internal code */
9989d26e4fcSRobert Mustacchi 			retval &= 0xff;
9999d26e4fcSRobert Mustacchi 		}
10009d26e4fcSRobert Mustacchi 		cmd_completed = TRUE;
10019d26e4fcSRobert Mustacchi 		if ((enum i40e_admin_queue_err)retval == I40E_AQ_RC_OK)
10029d26e4fcSRobert Mustacchi 			status = I40E_SUCCESS;
1003*df36e06dSRobert Mustacchi 		else if ((enum i40e_admin_queue_err)retval == I40E_AQ_RC_EBUSY)
1004*df36e06dSRobert Mustacchi 			status = I40E_ERR_NOT_READY;
10059d26e4fcSRobert Mustacchi 		else
10069d26e4fcSRobert Mustacchi 			status = I40E_ERR_ADMIN_QUEUE_ERROR;
10079d26e4fcSRobert Mustacchi 		hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval;
10089d26e4fcSRobert Mustacchi 	}
10099d26e4fcSRobert Mustacchi 
1010*df36e06dSRobert Mustacchi 	i40e_debug(hw, I40E_DEBUG_AQ_COMMAND,
10119d26e4fcSRobert Mustacchi 		   "AQTX: desc and buffer writeback:\n");
10129d26e4fcSRobert Mustacchi 	i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff, buff_size);
10139d26e4fcSRobert Mustacchi 
10149d26e4fcSRobert Mustacchi 	/* save writeback aq if requested */
10159d26e4fcSRobert Mustacchi 	if (details->wb_desc)
10169d26e4fcSRobert Mustacchi 		i40e_memcpy(details->wb_desc, desc_on_ring,
10179d26e4fcSRobert Mustacchi 			    sizeof(struct i40e_aq_desc), I40E_DMA_TO_NONDMA);
10189d26e4fcSRobert Mustacchi 
10199d26e4fcSRobert Mustacchi 	/* update the error if time out occurred */
10209d26e4fcSRobert Mustacchi 	if ((!cmd_completed) &&
10219d26e4fcSRobert Mustacchi 	    (!details->async && !details->postpone)) {
102293f1cac5SPaul Winder 		if (rd32(hw, hw->aq.asq.len) & I40E_GL_ATQLEN_ATQCRIT_MASK) {
102393f1cac5SPaul Winder 			i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
102493f1cac5SPaul Winder 				   "AQTX: AQ Critical error.\n");
102593f1cac5SPaul Winder 			status = I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR;
102693f1cac5SPaul Winder 		} else {
102793f1cac5SPaul Winder 			i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
10289d26e4fcSRobert Mustacchi 				   "AQTX: Writeback timeout.\n");
10299d26e4fcSRobert Mustacchi 			status = I40E_ERR_ADMIN_QUEUE_TIMEOUT;
10309d26e4fcSRobert Mustacchi 		}
103193f1cac5SPaul Winder 	}
10329d26e4fcSRobert Mustacchi 
10339d26e4fcSRobert Mustacchi asq_send_command_error:
10349d26e4fcSRobert Mustacchi 	i40e_release_spinlock(&hw->aq.asq_spinlock);
10359d26e4fcSRobert Mustacchi 	return status;
10369d26e4fcSRobert Mustacchi }
10379d26e4fcSRobert Mustacchi 
10389d26e4fcSRobert Mustacchi /**
10399d26e4fcSRobert Mustacchi  *  i40e_fill_default_direct_cmd_desc - AQ descriptor helper function
10409d26e4fcSRobert Mustacchi  *  @desc:     pointer to the temp descriptor (non DMA mem)
10419d26e4fcSRobert Mustacchi  *  @opcode:   the opcode can be used to decide which flags to turn off or on
10429d26e4fcSRobert Mustacchi  *
10439d26e4fcSRobert Mustacchi  *  Fill the desc with default values
10449d26e4fcSRobert Mustacchi  **/
i40e_fill_default_direct_cmd_desc(struct i40e_aq_desc * desc,u16 opcode)10459d26e4fcSRobert Mustacchi void i40e_fill_default_direct_cmd_desc(struct i40e_aq_desc *desc,
10469d26e4fcSRobert Mustacchi 				       u16 opcode)
10479d26e4fcSRobert Mustacchi {
10489d26e4fcSRobert Mustacchi 	/* zero out the desc */
10499d26e4fcSRobert Mustacchi 	i40e_memset((void *)desc, 0, sizeof(struct i40e_aq_desc),
10509d26e4fcSRobert Mustacchi 		    I40E_NONDMA_MEM);
10519d26e4fcSRobert Mustacchi 	desc->opcode = CPU_TO_LE16(opcode);
10529d26e4fcSRobert Mustacchi 	desc->flags = CPU_TO_LE16(I40E_AQ_FLAG_SI);
10539d26e4fcSRobert Mustacchi }
10549d26e4fcSRobert Mustacchi 
10559d26e4fcSRobert Mustacchi /**
10569d26e4fcSRobert Mustacchi  *  i40e_clean_arq_element
10579d26e4fcSRobert Mustacchi  *  @hw: pointer to the hw struct
10589d26e4fcSRobert Mustacchi  *  @e: event info from the receive descriptor, includes any buffers
10599d26e4fcSRobert Mustacchi  *  @pending: number of events that could be left to process
10609d26e4fcSRobert Mustacchi  *
10619d26e4fcSRobert Mustacchi  *  This function cleans one Admin Receive Queue element and returns
10629d26e4fcSRobert Mustacchi  *  the contents through e.  It can also return how many events are
10639d26e4fcSRobert Mustacchi  *  left to process through 'pending'
10649d26e4fcSRobert Mustacchi  **/
i40e_clean_arq_element(struct i40e_hw * hw,struct i40e_arq_event_info * e,u16 * pending)10659d26e4fcSRobert Mustacchi enum i40e_status_code i40e_clean_arq_element(struct i40e_hw *hw,
10669d26e4fcSRobert Mustacchi 					     struct i40e_arq_event_info *e,
10679d26e4fcSRobert Mustacchi 					     u16 *pending)
10689d26e4fcSRobert Mustacchi {
10699d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
10709d26e4fcSRobert Mustacchi 	u16 ntc = hw->aq.arq.next_to_clean;
10719d26e4fcSRobert Mustacchi 	struct i40e_aq_desc *desc;
10729d26e4fcSRobert Mustacchi 	struct i40e_dma_mem *bi;
10739d26e4fcSRobert Mustacchi 	u16 desc_idx;
10749d26e4fcSRobert Mustacchi 	u16 datalen;
10759d26e4fcSRobert Mustacchi 	u16 flags;
10769d26e4fcSRobert Mustacchi 	u16 ntu;
10779d26e4fcSRobert Mustacchi 
10783d75a287SRobert Mustacchi 	/* pre-clean the event info */
10793d75a287SRobert Mustacchi 	i40e_memset(&e->desc, 0, sizeof(e->desc), I40E_NONDMA_MEM);
10803d75a287SRobert Mustacchi 
10819d26e4fcSRobert Mustacchi 	/* take the lock before we start messing with the ring */
10829d26e4fcSRobert Mustacchi 	i40e_acquire_spinlock(&hw->aq.arq_spinlock);
10839d26e4fcSRobert Mustacchi 
10843d75a287SRobert Mustacchi 	if (hw->aq.arq.count == 0) {
10853d75a287SRobert Mustacchi 		i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
10863d75a287SRobert Mustacchi 			   "AQRX: Admin queue not initialized.\n");
10873d75a287SRobert Mustacchi 		ret_code = I40E_ERR_QUEUE_EMPTY;
10883d75a287SRobert Mustacchi 		goto clean_arq_element_err;
10893d75a287SRobert Mustacchi 	}
10903d75a287SRobert Mustacchi 
10919d26e4fcSRobert Mustacchi 	/* set next_to_use to head */
109293f1cac5SPaul Winder 	if (!i40e_is_vf(hw))
109393f1cac5SPaul Winder 		ntu = rd32(hw, hw->aq.arq.head) & I40E_PF_ARQH_ARQH_MASK;
109493f1cac5SPaul Winder 	else
109593f1cac5SPaul Winder 		ntu = rd32(hw, hw->aq.arq.head) & I40E_VF_ARQH1_ARQH_MASK;
10969d26e4fcSRobert Mustacchi 	if (ntu == ntc) {
10979d26e4fcSRobert Mustacchi 		/* nothing to do - shouldn't need to update ring's values */
10989d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_ADMIN_QUEUE_NO_WORK;
10999d26e4fcSRobert Mustacchi 		goto clean_arq_element_out;
11009d26e4fcSRobert Mustacchi 	}
11019d26e4fcSRobert Mustacchi 
11029d26e4fcSRobert Mustacchi 	/* now clean the next descriptor */
11039d26e4fcSRobert Mustacchi 	desc = I40E_ADMINQ_DESC(hw->aq.arq, ntc);
11049d26e4fcSRobert Mustacchi 	desc_idx = ntc;
11059d26e4fcSRobert Mustacchi 
11063d75a287SRobert Mustacchi 	hw->aq.arq_last_status =
11073d75a287SRobert Mustacchi 		(enum i40e_admin_queue_err)LE16_TO_CPU(desc->retval);
11089d26e4fcSRobert Mustacchi 	flags = LE16_TO_CPU(desc->flags);
11099d26e4fcSRobert Mustacchi 	if (flags & I40E_AQ_FLAG_ERR) {
11109d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_ADMIN_QUEUE_ERROR;
11119d26e4fcSRobert Mustacchi 		i40e_debug(hw,
11129d26e4fcSRobert Mustacchi 			   I40E_DEBUG_AQ_MESSAGE,
11139d26e4fcSRobert Mustacchi 			   "AQRX: Event received with error 0x%X.\n",
11149d26e4fcSRobert Mustacchi 			   hw->aq.arq_last_status);
11159d26e4fcSRobert Mustacchi 	}
11169d26e4fcSRobert Mustacchi 
11179d26e4fcSRobert Mustacchi 	i40e_memcpy(&e->desc, desc, sizeof(struct i40e_aq_desc),
11189d26e4fcSRobert Mustacchi 		    I40E_DMA_TO_NONDMA);
11199d26e4fcSRobert Mustacchi 	datalen = LE16_TO_CPU(desc->datalen);
11209d26e4fcSRobert Mustacchi 	e->msg_len = min(datalen, e->buf_len);
11219d26e4fcSRobert Mustacchi 	if (e->msg_buf != NULL && (e->msg_len != 0))
11229d26e4fcSRobert Mustacchi 		i40e_memcpy(e->msg_buf,
11239d26e4fcSRobert Mustacchi 			    hw->aq.arq.r.arq_bi[desc_idx].va,
11249d26e4fcSRobert Mustacchi 			    e->msg_len, I40E_DMA_TO_NONDMA);
11259d26e4fcSRobert Mustacchi 
1126*df36e06dSRobert Mustacchi 	i40e_debug(hw, I40E_DEBUG_AQ_COMMAND, "AQRX: desc and buffer:\n");
11279d26e4fcSRobert Mustacchi 	i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf,
11289d26e4fcSRobert Mustacchi 		      hw->aq.arq_buf_size);
11299d26e4fcSRobert Mustacchi 
11309d26e4fcSRobert Mustacchi 	/* Restore the original datalen and buffer address in the desc,
11319d26e4fcSRobert Mustacchi 	 * FW updates datalen to indicate the event message
11329d26e4fcSRobert Mustacchi 	 * size
11339d26e4fcSRobert Mustacchi 	 */
11349d26e4fcSRobert Mustacchi 	bi = &hw->aq.arq.r.arq_bi[ntc];
11359d26e4fcSRobert Mustacchi 	i40e_memset((void *)desc, 0, sizeof(struct i40e_aq_desc), I40E_DMA_MEM);
11369d26e4fcSRobert Mustacchi 
11379d26e4fcSRobert Mustacchi 	desc->flags = CPU_TO_LE16(I40E_AQ_FLAG_BUF);
11389d26e4fcSRobert Mustacchi 	if (hw->aq.arq_buf_size > I40E_AQ_LARGE_BUF)
11399d26e4fcSRobert Mustacchi 		desc->flags |= CPU_TO_LE16(I40E_AQ_FLAG_LB);
11409d26e4fcSRobert Mustacchi 	desc->datalen = CPU_TO_LE16((u16)bi->size);
11419d26e4fcSRobert Mustacchi 	desc->params.external.addr_high = CPU_TO_LE32(I40E_HI_DWORD(bi->pa));
11429d26e4fcSRobert Mustacchi 	desc->params.external.addr_low = CPU_TO_LE32(I40E_LO_DWORD(bi->pa));
11439d26e4fcSRobert Mustacchi 
11449d26e4fcSRobert Mustacchi 	/* set tail = the last cleaned desc index. */
11459d26e4fcSRobert Mustacchi 	wr32(hw, hw->aq.arq.tail, ntc);
11469d26e4fcSRobert Mustacchi 	/* ntc is updated to tail + 1 */
11479d26e4fcSRobert Mustacchi 	ntc++;
11489d26e4fcSRobert Mustacchi 	if (ntc == hw->aq.num_arq_entries)
11499d26e4fcSRobert Mustacchi 		ntc = 0;
11509d26e4fcSRobert Mustacchi 	hw->aq.arq.next_to_clean = ntc;
11519d26e4fcSRobert Mustacchi 	hw->aq.arq.next_to_use = ntu;
11529d26e4fcSRobert Mustacchi 
115393f1cac5SPaul Winder 	i40e_nvmupd_check_wait_event(hw, LE16_TO_CPU(e->desc.opcode), &e->desc);
11549d26e4fcSRobert Mustacchi clean_arq_element_out:
11559d26e4fcSRobert Mustacchi 	/* Set pending if needed, unlock and return */
11569d26e4fcSRobert Mustacchi 	if (pending != NULL)
11579d26e4fcSRobert Mustacchi 		*pending = (ntc > ntu ? hw->aq.arq.count : 0) + (ntu - ntc);
11583d75a287SRobert Mustacchi clean_arq_element_err:
11599d26e4fcSRobert Mustacchi 	i40e_release_spinlock(&hw->aq.arq_spinlock);
11609d26e4fcSRobert Mustacchi 
11619d26e4fcSRobert Mustacchi 	return ret_code;
11629d26e4fcSRobert Mustacchi }
11639d26e4fcSRobert Mustacchi 
1164