xref: /illumos-gate/usr/src/uts/common/io/i40e/core/i40e_lan_hmc.c (revision 9d26e4fc021e249c93c2861629cc665e4f5bd4d6)
1*9d26e4fcSRobert Mustacchi /******************************************************************************
2*9d26e4fcSRobert Mustacchi 
3*9d26e4fcSRobert Mustacchi   Copyright (c) 2013-2015, Intel Corporation
4*9d26e4fcSRobert Mustacchi   All rights reserved.
5*9d26e4fcSRobert Mustacchi 
6*9d26e4fcSRobert Mustacchi   Redistribution and use in source and binary forms, with or without
7*9d26e4fcSRobert Mustacchi   modification, are permitted provided that the following conditions are met:
8*9d26e4fcSRobert Mustacchi 
9*9d26e4fcSRobert Mustacchi    1. Redistributions of source code must retain the above copyright notice,
10*9d26e4fcSRobert Mustacchi       this list of conditions and the following disclaimer.
11*9d26e4fcSRobert Mustacchi 
12*9d26e4fcSRobert Mustacchi    2. Redistributions in binary form must reproduce the above copyright
13*9d26e4fcSRobert Mustacchi       notice, this list of conditions and the following disclaimer in the
14*9d26e4fcSRobert Mustacchi       documentation and/or other materials provided with the distribution.
15*9d26e4fcSRobert Mustacchi 
16*9d26e4fcSRobert Mustacchi    3. Neither the name of the Intel Corporation nor the names of its
17*9d26e4fcSRobert Mustacchi       contributors may be used to endorse or promote products derived from
18*9d26e4fcSRobert Mustacchi       this software without specific prior written permission.
19*9d26e4fcSRobert Mustacchi 
20*9d26e4fcSRobert Mustacchi   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21*9d26e4fcSRobert Mustacchi   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22*9d26e4fcSRobert Mustacchi   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23*9d26e4fcSRobert Mustacchi   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24*9d26e4fcSRobert Mustacchi   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25*9d26e4fcSRobert Mustacchi   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26*9d26e4fcSRobert Mustacchi   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27*9d26e4fcSRobert Mustacchi   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28*9d26e4fcSRobert Mustacchi   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29*9d26e4fcSRobert Mustacchi   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30*9d26e4fcSRobert Mustacchi   POSSIBILITY OF SUCH DAMAGE.
31*9d26e4fcSRobert Mustacchi 
32*9d26e4fcSRobert Mustacchi ******************************************************************************/
33*9d26e4fcSRobert Mustacchi /*$FreeBSD: head/sys/dev/ixl/i40e_lan_hmc.c 284049 2015-06-05 22:52:42Z jfv $*/
34*9d26e4fcSRobert Mustacchi 
35*9d26e4fcSRobert Mustacchi #include "i40e_osdep.h"
36*9d26e4fcSRobert Mustacchi #include "i40e_register.h"
37*9d26e4fcSRobert Mustacchi #include "i40e_type.h"
38*9d26e4fcSRobert Mustacchi #include "i40e_hmc.h"
39*9d26e4fcSRobert Mustacchi #include "i40e_lan_hmc.h"
40*9d26e4fcSRobert Mustacchi #include "i40e_prototype.h"
41*9d26e4fcSRobert Mustacchi 
42*9d26e4fcSRobert Mustacchi /* lan specific interface functions */
43*9d26e4fcSRobert Mustacchi 
44*9d26e4fcSRobert Mustacchi /**
45*9d26e4fcSRobert Mustacchi  * i40e_align_l2obj_base - aligns base object pointer to 512 bytes
46*9d26e4fcSRobert Mustacchi  * @offset: base address offset needing alignment
47*9d26e4fcSRobert Mustacchi  *
48*9d26e4fcSRobert Mustacchi  * Aligns the layer 2 function private memory so it's 512-byte aligned.
49*9d26e4fcSRobert Mustacchi  **/
50*9d26e4fcSRobert Mustacchi static u64 i40e_align_l2obj_base(u64 offset)
51*9d26e4fcSRobert Mustacchi {
52*9d26e4fcSRobert Mustacchi 	u64 aligned_offset = offset;
53*9d26e4fcSRobert Mustacchi 
54*9d26e4fcSRobert Mustacchi 	if ((offset % I40E_HMC_L2OBJ_BASE_ALIGNMENT) > 0)
55*9d26e4fcSRobert Mustacchi 		aligned_offset += (I40E_HMC_L2OBJ_BASE_ALIGNMENT -
56*9d26e4fcSRobert Mustacchi 				   (offset % I40E_HMC_L2OBJ_BASE_ALIGNMENT));
57*9d26e4fcSRobert Mustacchi 
58*9d26e4fcSRobert Mustacchi 	return aligned_offset;
59*9d26e4fcSRobert Mustacchi }
60*9d26e4fcSRobert Mustacchi 
61*9d26e4fcSRobert Mustacchi /**
62*9d26e4fcSRobert Mustacchi  * i40e_calculate_l2fpm_size - calculates layer 2 FPM memory size
63*9d26e4fcSRobert Mustacchi  * @txq_num: number of Tx queues needing backing context
64*9d26e4fcSRobert Mustacchi  * @rxq_num: number of Rx queues needing backing context
65*9d26e4fcSRobert Mustacchi  * @fcoe_cntx_num: amount of FCoE statefull contexts needing backing context
66*9d26e4fcSRobert Mustacchi  * @fcoe_filt_num: number of FCoE filters needing backing context
67*9d26e4fcSRobert Mustacchi  *
68*9d26e4fcSRobert Mustacchi  * Calculates the maximum amount of memory for the function required, based
69*9d26e4fcSRobert Mustacchi  * on the number of resources it must provide context for.
70*9d26e4fcSRobert Mustacchi  **/
71*9d26e4fcSRobert Mustacchi u64 i40e_calculate_l2fpm_size(u32 txq_num, u32 rxq_num,
72*9d26e4fcSRobert Mustacchi 			      u32 fcoe_cntx_num, u32 fcoe_filt_num)
73*9d26e4fcSRobert Mustacchi {
74*9d26e4fcSRobert Mustacchi 	u64 fpm_size = 0;
75*9d26e4fcSRobert Mustacchi 
76*9d26e4fcSRobert Mustacchi 	fpm_size = txq_num * I40E_HMC_OBJ_SIZE_TXQ;
77*9d26e4fcSRobert Mustacchi 	fpm_size = i40e_align_l2obj_base(fpm_size);
78*9d26e4fcSRobert Mustacchi 
79*9d26e4fcSRobert Mustacchi 	fpm_size += (rxq_num * I40E_HMC_OBJ_SIZE_RXQ);
80*9d26e4fcSRobert Mustacchi 	fpm_size = i40e_align_l2obj_base(fpm_size);
81*9d26e4fcSRobert Mustacchi 
82*9d26e4fcSRobert Mustacchi 	fpm_size += (fcoe_cntx_num * I40E_HMC_OBJ_SIZE_FCOE_CNTX);
83*9d26e4fcSRobert Mustacchi 	fpm_size = i40e_align_l2obj_base(fpm_size);
84*9d26e4fcSRobert Mustacchi 
85*9d26e4fcSRobert Mustacchi 	fpm_size += (fcoe_filt_num * I40E_HMC_OBJ_SIZE_FCOE_FILT);
86*9d26e4fcSRobert Mustacchi 	fpm_size = i40e_align_l2obj_base(fpm_size);
87*9d26e4fcSRobert Mustacchi 
88*9d26e4fcSRobert Mustacchi 	return fpm_size;
89*9d26e4fcSRobert Mustacchi }
90*9d26e4fcSRobert Mustacchi 
91*9d26e4fcSRobert Mustacchi /**
92*9d26e4fcSRobert Mustacchi  * i40e_init_lan_hmc - initialize i40e_hmc_info struct
93*9d26e4fcSRobert Mustacchi  * @hw: pointer to the HW structure
94*9d26e4fcSRobert Mustacchi  * @txq_num: number of Tx queues needing backing context
95*9d26e4fcSRobert Mustacchi  * @rxq_num: number of Rx queues needing backing context
96*9d26e4fcSRobert Mustacchi  * @fcoe_cntx_num: amount of FCoE statefull contexts needing backing context
97*9d26e4fcSRobert Mustacchi  * @fcoe_filt_num: number of FCoE filters needing backing context
98*9d26e4fcSRobert Mustacchi  *
99*9d26e4fcSRobert Mustacchi  * This function will be called once per physical function initialization.
100*9d26e4fcSRobert Mustacchi  * It will fill out the i40e_hmc_obj_info structure for LAN objects based on
101*9d26e4fcSRobert Mustacchi  * the driver's provided input, as well as information from the HMC itself
102*9d26e4fcSRobert Mustacchi  * loaded from NVRAM.
103*9d26e4fcSRobert Mustacchi  *
104*9d26e4fcSRobert Mustacchi  * Assumptions:
105*9d26e4fcSRobert Mustacchi  *   - HMC Resource Profile has been selected before calling this function.
106*9d26e4fcSRobert Mustacchi  **/
107*9d26e4fcSRobert Mustacchi enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
108*9d26e4fcSRobert Mustacchi 					u32 rxq_num, u32 fcoe_cntx_num,
109*9d26e4fcSRobert Mustacchi 					u32 fcoe_filt_num)
110*9d26e4fcSRobert Mustacchi {
111*9d26e4fcSRobert Mustacchi 	struct i40e_hmc_obj_info *obj, *full_obj;
112*9d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
113*9d26e4fcSRobert Mustacchi 	u64 l2fpm_size;
114*9d26e4fcSRobert Mustacchi 	u32 size_exp;
115*9d26e4fcSRobert Mustacchi 
116*9d26e4fcSRobert Mustacchi 	hw->hmc.signature = I40E_HMC_INFO_SIGNATURE;
117*9d26e4fcSRobert Mustacchi 	hw->hmc.hmc_fn_id = hw->pf_id;
118*9d26e4fcSRobert Mustacchi 
119*9d26e4fcSRobert Mustacchi 	/* allocate memory for hmc_obj */
120*9d26e4fcSRobert Mustacchi 	ret_code = i40e_allocate_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem,
121*9d26e4fcSRobert Mustacchi 			sizeof(struct i40e_hmc_obj_info) * I40E_HMC_LAN_MAX);
122*9d26e4fcSRobert Mustacchi 	if (ret_code)
123*9d26e4fcSRobert Mustacchi 		goto init_lan_hmc_out;
124*9d26e4fcSRobert Mustacchi 	hw->hmc.hmc_obj = (struct i40e_hmc_obj_info *)
125*9d26e4fcSRobert Mustacchi 			  hw->hmc.hmc_obj_virt_mem.va;
126*9d26e4fcSRobert Mustacchi 
127*9d26e4fcSRobert Mustacchi 	/* The full object will be used to create the LAN HMC SD */
128*9d26e4fcSRobert Mustacchi 	full_obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_FULL];
129*9d26e4fcSRobert Mustacchi 	full_obj->max_cnt = 0;
130*9d26e4fcSRobert Mustacchi 	full_obj->cnt = 0;
131*9d26e4fcSRobert Mustacchi 	full_obj->base = 0;
132*9d26e4fcSRobert Mustacchi 	full_obj->size = 0;
133*9d26e4fcSRobert Mustacchi 
134*9d26e4fcSRobert Mustacchi 	/* Tx queue context information */
135*9d26e4fcSRobert Mustacchi 	obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX];
136*9d26e4fcSRobert Mustacchi 	obj->max_cnt = rd32(hw, I40E_GLHMC_LANQMAX);
137*9d26e4fcSRobert Mustacchi 	obj->cnt = txq_num;
138*9d26e4fcSRobert Mustacchi 	obj->base = 0;
139*9d26e4fcSRobert Mustacchi 	size_exp = rd32(hw, I40E_GLHMC_LANTXOBJSZ);
140*9d26e4fcSRobert Mustacchi 	obj->size = BIT_ULL(size_exp);
141*9d26e4fcSRobert Mustacchi 
142*9d26e4fcSRobert Mustacchi 	/* validate values requested by driver don't exceed HMC capacity */
143*9d26e4fcSRobert Mustacchi 	if (txq_num > obj->max_cnt) {
144*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
145*9d26e4fcSRobert Mustacchi 		DEBUGOUT3("i40e_init_lan_hmc: Tx context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
146*9d26e4fcSRobert Mustacchi 			  txq_num, obj->max_cnt, ret_code);
147*9d26e4fcSRobert Mustacchi 		goto init_lan_hmc_out;
148*9d26e4fcSRobert Mustacchi 	}
149*9d26e4fcSRobert Mustacchi 
150*9d26e4fcSRobert Mustacchi 	/* aggregate values into the full LAN object for later */
151*9d26e4fcSRobert Mustacchi 	full_obj->max_cnt += obj->max_cnt;
152*9d26e4fcSRobert Mustacchi 	full_obj->cnt += obj->cnt;
153*9d26e4fcSRobert Mustacchi 
154*9d26e4fcSRobert Mustacchi 	/* Rx queue context information */
155*9d26e4fcSRobert Mustacchi 	obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_RX];
156*9d26e4fcSRobert Mustacchi 	obj->max_cnt = rd32(hw, I40E_GLHMC_LANQMAX);
157*9d26e4fcSRobert Mustacchi 	obj->cnt = rxq_num;
158*9d26e4fcSRobert Mustacchi 	obj->base = hw->hmc.hmc_obj[I40E_HMC_LAN_TX].base +
159*9d26e4fcSRobert Mustacchi 		    (hw->hmc.hmc_obj[I40E_HMC_LAN_TX].cnt *
160*9d26e4fcSRobert Mustacchi 		     hw->hmc.hmc_obj[I40E_HMC_LAN_TX].size);
161*9d26e4fcSRobert Mustacchi 	obj->base = i40e_align_l2obj_base(obj->base);
162*9d26e4fcSRobert Mustacchi 	size_exp = rd32(hw, I40E_GLHMC_LANRXOBJSZ);
163*9d26e4fcSRobert Mustacchi 	obj->size = BIT_ULL(size_exp);
164*9d26e4fcSRobert Mustacchi 
165*9d26e4fcSRobert Mustacchi 	/* validate values requested by driver don't exceed HMC capacity */
166*9d26e4fcSRobert Mustacchi 	if (rxq_num > obj->max_cnt) {
167*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
168*9d26e4fcSRobert Mustacchi 		DEBUGOUT3("i40e_init_lan_hmc: Rx context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
169*9d26e4fcSRobert Mustacchi 			  rxq_num, obj->max_cnt, ret_code);
170*9d26e4fcSRobert Mustacchi 		goto init_lan_hmc_out;
171*9d26e4fcSRobert Mustacchi 	}
172*9d26e4fcSRobert Mustacchi 
173*9d26e4fcSRobert Mustacchi 	/* aggregate values into the full LAN object for later */
174*9d26e4fcSRobert Mustacchi 	full_obj->max_cnt += obj->max_cnt;
175*9d26e4fcSRobert Mustacchi 	full_obj->cnt += obj->cnt;
176*9d26e4fcSRobert Mustacchi 
177*9d26e4fcSRobert Mustacchi 	/* FCoE context information */
178*9d26e4fcSRobert Mustacchi 	obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX];
179*9d26e4fcSRobert Mustacchi 	obj->max_cnt = rd32(hw, I40E_GLHMC_FCOEMAX);
180*9d26e4fcSRobert Mustacchi 	obj->cnt = fcoe_cntx_num;
181*9d26e4fcSRobert Mustacchi 	obj->base = hw->hmc.hmc_obj[I40E_HMC_LAN_RX].base +
182*9d26e4fcSRobert Mustacchi 		    (hw->hmc.hmc_obj[I40E_HMC_LAN_RX].cnt *
183*9d26e4fcSRobert Mustacchi 		     hw->hmc.hmc_obj[I40E_HMC_LAN_RX].size);
184*9d26e4fcSRobert Mustacchi 	obj->base = i40e_align_l2obj_base(obj->base);
185*9d26e4fcSRobert Mustacchi 	size_exp = rd32(hw, I40E_GLHMC_FCOEDDPOBJSZ);
186*9d26e4fcSRobert Mustacchi 	obj->size = BIT_ULL(size_exp);
187*9d26e4fcSRobert Mustacchi 
188*9d26e4fcSRobert Mustacchi 	/* validate values requested by driver don't exceed HMC capacity */
189*9d26e4fcSRobert Mustacchi 	if (fcoe_cntx_num > obj->max_cnt) {
190*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
191*9d26e4fcSRobert Mustacchi 		DEBUGOUT3("i40e_init_lan_hmc: FCoE context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
192*9d26e4fcSRobert Mustacchi 			  fcoe_cntx_num, obj->max_cnt, ret_code);
193*9d26e4fcSRobert Mustacchi 		goto init_lan_hmc_out;
194*9d26e4fcSRobert Mustacchi 	}
195*9d26e4fcSRobert Mustacchi 
196*9d26e4fcSRobert Mustacchi 	/* aggregate values into the full LAN object for later */
197*9d26e4fcSRobert Mustacchi 	full_obj->max_cnt += obj->max_cnt;
198*9d26e4fcSRobert Mustacchi 	full_obj->cnt += obj->cnt;
199*9d26e4fcSRobert Mustacchi 
200*9d26e4fcSRobert Mustacchi 	/* FCoE filter information */
201*9d26e4fcSRobert Mustacchi 	obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_FILT];
202*9d26e4fcSRobert Mustacchi 	obj->max_cnt = rd32(hw, I40E_GLHMC_FCOEFMAX);
203*9d26e4fcSRobert Mustacchi 	obj->cnt = fcoe_filt_num;
204*9d26e4fcSRobert Mustacchi 	obj->base = hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].base +
205*9d26e4fcSRobert Mustacchi 		    (hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].cnt *
206*9d26e4fcSRobert Mustacchi 		     hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].size);
207*9d26e4fcSRobert Mustacchi 	obj->base = i40e_align_l2obj_base(obj->base);
208*9d26e4fcSRobert Mustacchi 	size_exp = rd32(hw, I40E_GLHMC_FCOEFOBJSZ);
209*9d26e4fcSRobert Mustacchi 	obj->size = BIT_ULL(size_exp);
210*9d26e4fcSRobert Mustacchi 
211*9d26e4fcSRobert Mustacchi 	/* validate values requested by driver don't exceed HMC capacity */
212*9d26e4fcSRobert Mustacchi 	if (fcoe_filt_num > obj->max_cnt) {
213*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
214*9d26e4fcSRobert Mustacchi 		DEBUGOUT3("i40e_init_lan_hmc: FCoE filter: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
215*9d26e4fcSRobert Mustacchi 			  fcoe_filt_num, obj->max_cnt, ret_code);
216*9d26e4fcSRobert Mustacchi 		goto init_lan_hmc_out;
217*9d26e4fcSRobert Mustacchi 	}
218*9d26e4fcSRobert Mustacchi 
219*9d26e4fcSRobert Mustacchi 	/* aggregate values into the full LAN object for later */
220*9d26e4fcSRobert Mustacchi 	full_obj->max_cnt += obj->max_cnt;
221*9d26e4fcSRobert Mustacchi 	full_obj->cnt += obj->cnt;
222*9d26e4fcSRobert Mustacchi 
223*9d26e4fcSRobert Mustacchi 	hw->hmc.first_sd_index = 0;
224*9d26e4fcSRobert Mustacchi 	hw->hmc.sd_table.ref_cnt = 0;
225*9d26e4fcSRobert Mustacchi 	l2fpm_size = i40e_calculate_l2fpm_size(txq_num, rxq_num, fcoe_cntx_num,
226*9d26e4fcSRobert Mustacchi 					       fcoe_filt_num);
227*9d26e4fcSRobert Mustacchi 	if (NULL == hw->hmc.sd_table.sd_entry) {
228*9d26e4fcSRobert Mustacchi 		hw->hmc.sd_table.sd_cnt = (u32)
229*9d26e4fcSRobert Mustacchi 				   (l2fpm_size + I40E_HMC_DIRECT_BP_SIZE - 1) /
230*9d26e4fcSRobert Mustacchi 				   I40E_HMC_DIRECT_BP_SIZE;
231*9d26e4fcSRobert Mustacchi 
232*9d26e4fcSRobert Mustacchi 		/* allocate the sd_entry members in the sd_table */
233*9d26e4fcSRobert Mustacchi 		ret_code = i40e_allocate_virt_mem(hw, &hw->hmc.sd_table.addr,
234*9d26e4fcSRobert Mustacchi 					  (sizeof(struct i40e_hmc_sd_entry) *
235*9d26e4fcSRobert Mustacchi 					  hw->hmc.sd_table.sd_cnt));
236*9d26e4fcSRobert Mustacchi 		if (ret_code)
237*9d26e4fcSRobert Mustacchi 			goto init_lan_hmc_out;
238*9d26e4fcSRobert Mustacchi 		hw->hmc.sd_table.sd_entry =
239*9d26e4fcSRobert Mustacchi 			(struct i40e_hmc_sd_entry *)hw->hmc.sd_table.addr.va;
240*9d26e4fcSRobert Mustacchi 	}
241*9d26e4fcSRobert Mustacchi 	/* store in the LAN full object for later */
242*9d26e4fcSRobert Mustacchi 	full_obj->size = l2fpm_size;
243*9d26e4fcSRobert Mustacchi 
244*9d26e4fcSRobert Mustacchi init_lan_hmc_out:
245*9d26e4fcSRobert Mustacchi 	return ret_code;
246*9d26e4fcSRobert Mustacchi }
247*9d26e4fcSRobert Mustacchi 
248*9d26e4fcSRobert Mustacchi /**
249*9d26e4fcSRobert Mustacchi  * i40e_remove_pd_page - Remove a page from the page descriptor table
250*9d26e4fcSRobert Mustacchi  * @hw: pointer to the HW structure
251*9d26e4fcSRobert Mustacchi  * @hmc_info: pointer to the HMC configuration information structure
252*9d26e4fcSRobert Mustacchi  * @idx: segment descriptor index to find the relevant page descriptor
253*9d26e4fcSRobert Mustacchi  *
254*9d26e4fcSRobert Mustacchi  * This function:
255*9d26e4fcSRobert Mustacchi  *	1. Marks the entry in pd table (for paged address mode) invalid
256*9d26e4fcSRobert Mustacchi  *	2. write to register PMPDINV to invalidate the backing page in FV cache
257*9d26e4fcSRobert Mustacchi  *	3. Decrement the ref count for  pd_entry
258*9d26e4fcSRobert Mustacchi  * assumptions:
259*9d26e4fcSRobert Mustacchi  *	1. caller can deallocate the memory used by pd after this function
260*9d26e4fcSRobert Mustacchi  *	   returns.
261*9d26e4fcSRobert Mustacchi  **/
262*9d26e4fcSRobert Mustacchi static enum i40e_status_code i40e_remove_pd_page(struct i40e_hw *hw,
263*9d26e4fcSRobert Mustacchi 						 struct i40e_hmc_info *hmc_info,
264*9d26e4fcSRobert Mustacchi 						 u32 idx)
265*9d26e4fcSRobert Mustacchi {
266*9d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
267*9d26e4fcSRobert Mustacchi 
268*9d26e4fcSRobert Mustacchi 	if (i40e_prep_remove_pd_page(hmc_info, idx) == I40E_SUCCESS)
269*9d26e4fcSRobert Mustacchi 		ret_code = i40e_remove_pd_page_new(hw, hmc_info, idx, TRUE);
270*9d26e4fcSRobert Mustacchi 
271*9d26e4fcSRobert Mustacchi 	return ret_code;
272*9d26e4fcSRobert Mustacchi }
273*9d26e4fcSRobert Mustacchi 
274*9d26e4fcSRobert Mustacchi /**
275*9d26e4fcSRobert Mustacchi  * i40e_remove_sd_bp - remove a backing page from a segment descriptor
276*9d26e4fcSRobert Mustacchi  * @hw: pointer to our HW structure
277*9d26e4fcSRobert Mustacchi  * @hmc_info: pointer to the HMC configuration information structure
278*9d26e4fcSRobert Mustacchi  * @idx: the page index
279*9d26e4fcSRobert Mustacchi  *
280*9d26e4fcSRobert Mustacchi  * This function:
281*9d26e4fcSRobert Mustacchi  *	1. Marks the entry in sd table (for direct address mode) invalid
282*9d26e4fcSRobert Mustacchi  *	2. write to register PMSDCMD, PMSDDATALOW(PMSDDATALOW.PMSDVALID set
283*9d26e4fcSRobert Mustacchi  *	   to 0) and PMSDDATAHIGH to invalidate the sd page
284*9d26e4fcSRobert Mustacchi  *	3. Decrement the ref count for the sd_entry
285*9d26e4fcSRobert Mustacchi  * assumptions:
286*9d26e4fcSRobert Mustacchi  *	1. caller can deallocate the memory used by backing storage after this
287*9d26e4fcSRobert Mustacchi  *	   function returns.
288*9d26e4fcSRobert Mustacchi  **/
289*9d26e4fcSRobert Mustacchi static enum i40e_status_code i40e_remove_sd_bp(struct i40e_hw *hw,
290*9d26e4fcSRobert Mustacchi 					       struct i40e_hmc_info *hmc_info,
291*9d26e4fcSRobert Mustacchi 					       u32 idx)
292*9d26e4fcSRobert Mustacchi {
293*9d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
294*9d26e4fcSRobert Mustacchi 
295*9d26e4fcSRobert Mustacchi 	if (i40e_prep_remove_sd_bp(hmc_info, idx) == I40E_SUCCESS)
296*9d26e4fcSRobert Mustacchi 		ret_code = i40e_remove_sd_bp_new(hw, hmc_info, idx, TRUE);
297*9d26e4fcSRobert Mustacchi 
298*9d26e4fcSRobert Mustacchi 	return ret_code;
299*9d26e4fcSRobert Mustacchi }
300*9d26e4fcSRobert Mustacchi 
301*9d26e4fcSRobert Mustacchi /**
302*9d26e4fcSRobert Mustacchi  * i40e_create_lan_hmc_object - allocate backing store for hmc objects
303*9d26e4fcSRobert Mustacchi  * @hw: pointer to the HW structure
304*9d26e4fcSRobert Mustacchi  * @info: pointer to i40e_hmc_create_obj_info struct
305*9d26e4fcSRobert Mustacchi  *
306*9d26e4fcSRobert Mustacchi  * This will allocate memory for PDs and backing pages and populate
307*9d26e4fcSRobert Mustacchi  * the sd and pd entries.
308*9d26e4fcSRobert Mustacchi  **/
309*9d26e4fcSRobert Mustacchi enum i40e_status_code i40e_create_lan_hmc_object(struct i40e_hw *hw,
310*9d26e4fcSRobert Mustacchi 				struct i40e_hmc_lan_create_obj_info *info)
311*9d26e4fcSRobert Mustacchi {
312*9d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
313*9d26e4fcSRobert Mustacchi 	struct i40e_hmc_sd_entry *sd_entry;
314*9d26e4fcSRobert Mustacchi 	u32 pd_idx1 = 0, pd_lmt1 = 0;
315*9d26e4fcSRobert Mustacchi 	u32 pd_idx = 0, pd_lmt = 0;
316*9d26e4fcSRobert Mustacchi 	bool pd_error = FALSE;
317*9d26e4fcSRobert Mustacchi 	u32 sd_idx, sd_lmt;
318*9d26e4fcSRobert Mustacchi 	u64 sd_size;
319*9d26e4fcSRobert Mustacchi 	u32 i, j;
320*9d26e4fcSRobert Mustacchi 
321*9d26e4fcSRobert Mustacchi 	if (NULL == info) {
322*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_BAD_PTR;
323*9d26e4fcSRobert Mustacchi 		DEBUGOUT("i40e_create_lan_hmc_object: bad info ptr\n");
324*9d26e4fcSRobert Mustacchi 		goto exit;
325*9d26e4fcSRobert Mustacchi 	}
326*9d26e4fcSRobert Mustacchi 	if (NULL == info->hmc_info) {
327*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_BAD_PTR;
328*9d26e4fcSRobert Mustacchi 		DEBUGOUT("i40e_create_lan_hmc_object: bad hmc_info ptr\n");
329*9d26e4fcSRobert Mustacchi 		goto exit;
330*9d26e4fcSRobert Mustacchi 	}
331*9d26e4fcSRobert Mustacchi 	if (I40E_HMC_INFO_SIGNATURE != info->hmc_info->signature) {
332*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_BAD_PTR;
333*9d26e4fcSRobert Mustacchi 		DEBUGOUT("i40e_create_lan_hmc_object: bad signature\n");
334*9d26e4fcSRobert Mustacchi 		goto exit;
335*9d26e4fcSRobert Mustacchi 	}
336*9d26e4fcSRobert Mustacchi 
337*9d26e4fcSRobert Mustacchi 	if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
338*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX;
339*9d26e4fcSRobert Mustacchi 		DEBUGOUT1("i40e_create_lan_hmc_object: returns error %d\n",
340*9d26e4fcSRobert Mustacchi 			  ret_code);
341*9d26e4fcSRobert Mustacchi 		goto exit;
342*9d26e4fcSRobert Mustacchi 	}
343*9d26e4fcSRobert Mustacchi 	if ((info->start_idx + info->count) >
344*9d26e4fcSRobert Mustacchi 	    info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
345*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
346*9d26e4fcSRobert Mustacchi 		DEBUGOUT1("i40e_create_lan_hmc_object: returns error %d\n",
347*9d26e4fcSRobert Mustacchi 			  ret_code);
348*9d26e4fcSRobert Mustacchi 		goto exit;
349*9d26e4fcSRobert Mustacchi 	}
350*9d26e4fcSRobert Mustacchi 
351*9d26e4fcSRobert Mustacchi 	/* find sd index and limit */
352*9d26e4fcSRobert Mustacchi 	I40E_FIND_SD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
353*9d26e4fcSRobert Mustacchi 				 info->start_idx, info->count,
354*9d26e4fcSRobert Mustacchi 				 &sd_idx, &sd_lmt);
355*9d26e4fcSRobert Mustacchi 	if (sd_idx >= info->hmc_info->sd_table.sd_cnt ||
356*9d26e4fcSRobert Mustacchi 	    sd_lmt > info->hmc_info->sd_table.sd_cnt) {
357*9d26e4fcSRobert Mustacchi 			ret_code = I40E_ERR_INVALID_SD_INDEX;
358*9d26e4fcSRobert Mustacchi 			goto exit;
359*9d26e4fcSRobert Mustacchi 	}
360*9d26e4fcSRobert Mustacchi 	/* find pd index */
361*9d26e4fcSRobert Mustacchi 	I40E_FIND_PD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
362*9d26e4fcSRobert Mustacchi 				 info->start_idx, info->count, &pd_idx,
363*9d26e4fcSRobert Mustacchi 				 &pd_lmt);
364*9d26e4fcSRobert Mustacchi 
365*9d26e4fcSRobert Mustacchi 	/* This is to cover for cases where you may not want to have an SD with
366*9d26e4fcSRobert Mustacchi 	 * the full 2M memory but something smaller. By not filling out any
367*9d26e4fcSRobert Mustacchi 	 * size, the function will default the SD size to be 2M.
368*9d26e4fcSRobert Mustacchi 	 */
369*9d26e4fcSRobert Mustacchi 	if (info->direct_mode_sz == 0)
370*9d26e4fcSRobert Mustacchi 		sd_size = I40E_HMC_DIRECT_BP_SIZE;
371*9d26e4fcSRobert Mustacchi 	else
372*9d26e4fcSRobert Mustacchi 		sd_size = info->direct_mode_sz;
373*9d26e4fcSRobert Mustacchi 
374*9d26e4fcSRobert Mustacchi 	/* check if all the sds are valid. If not, allocate a page and
375*9d26e4fcSRobert Mustacchi 	 * initialize it.
376*9d26e4fcSRobert Mustacchi 	 */
377*9d26e4fcSRobert Mustacchi 	for (j = sd_idx; j < sd_lmt; j++) {
378*9d26e4fcSRobert Mustacchi 		/* update the sd table entry */
379*9d26e4fcSRobert Mustacchi 		ret_code = i40e_add_sd_table_entry(hw, info->hmc_info, j,
380*9d26e4fcSRobert Mustacchi 						   info->entry_type,
381*9d26e4fcSRobert Mustacchi 						   sd_size);
382*9d26e4fcSRobert Mustacchi 		if (I40E_SUCCESS != ret_code)
383*9d26e4fcSRobert Mustacchi 			goto exit_sd_error;
384*9d26e4fcSRobert Mustacchi 		sd_entry = &info->hmc_info->sd_table.sd_entry[j];
385*9d26e4fcSRobert Mustacchi 		if (I40E_SD_TYPE_PAGED == sd_entry->entry_type) {
386*9d26e4fcSRobert Mustacchi 			/* check if all the pds in this sd are valid. If not,
387*9d26e4fcSRobert Mustacchi 			 * allocate a page and initialize it.
388*9d26e4fcSRobert Mustacchi 			 */
389*9d26e4fcSRobert Mustacchi 
390*9d26e4fcSRobert Mustacchi 			/* find pd_idx and pd_lmt in this sd */
391*9d26e4fcSRobert Mustacchi 			pd_idx1 = max(pd_idx, (j * I40E_HMC_MAX_BP_COUNT));
392*9d26e4fcSRobert Mustacchi 			pd_lmt1 = min(pd_lmt,
393*9d26e4fcSRobert Mustacchi 				      ((j + 1) * I40E_HMC_MAX_BP_COUNT));
394*9d26e4fcSRobert Mustacchi 			for (i = pd_idx1; i < pd_lmt1; i++) {
395*9d26e4fcSRobert Mustacchi 				/* update the pd table entry */
396*9d26e4fcSRobert Mustacchi 				ret_code = i40e_add_pd_table_entry(hw,
397*9d26e4fcSRobert Mustacchi 								info->hmc_info,
398*9d26e4fcSRobert Mustacchi 								i, NULL);
399*9d26e4fcSRobert Mustacchi 				if (I40E_SUCCESS != ret_code) {
400*9d26e4fcSRobert Mustacchi 					pd_error = TRUE;
401*9d26e4fcSRobert Mustacchi 					break;
402*9d26e4fcSRobert Mustacchi 				}
403*9d26e4fcSRobert Mustacchi 			}
404*9d26e4fcSRobert Mustacchi 			if (pd_error) {
405*9d26e4fcSRobert Mustacchi 				/* remove the backing pages from pd_idx1 to i */
406*9d26e4fcSRobert Mustacchi 				while (i && (i > pd_idx1)) {
407*9d26e4fcSRobert Mustacchi 					i40e_remove_pd_bp(hw, info->hmc_info,
408*9d26e4fcSRobert Mustacchi 							  (i - 1));
409*9d26e4fcSRobert Mustacchi 					i--;
410*9d26e4fcSRobert Mustacchi 				}
411*9d26e4fcSRobert Mustacchi 			}
412*9d26e4fcSRobert Mustacchi 		}
413*9d26e4fcSRobert Mustacchi 		if (!sd_entry->valid) {
414*9d26e4fcSRobert Mustacchi 			sd_entry->valid = TRUE;
415*9d26e4fcSRobert Mustacchi 			switch (sd_entry->entry_type) {
416*9d26e4fcSRobert Mustacchi 			case I40E_SD_TYPE_PAGED:
417*9d26e4fcSRobert Mustacchi 				I40E_SET_PF_SD_ENTRY(hw,
418*9d26e4fcSRobert Mustacchi 					sd_entry->u.pd_table.pd_page_addr.pa,
419*9d26e4fcSRobert Mustacchi 					j, sd_entry->entry_type);
420*9d26e4fcSRobert Mustacchi 				break;
421*9d26e4fcSRobert Mustacchi 			case I40E_SD_TYPE_DIRECT:
422*9d26e4fcSRobert Mustacchi 				I40E_SET_PF_SD_ENTRY(hw, sd_entry->u.bp.addr.pa,
423*9d26e4fcSRobert Mustacchi 						     j, sd_entry->entry_type);
424*9d26e4fcSRobert Mustacchi 				break;
425*9d26e4fcSRobert Mustacchi 			default:
426*9d26e4fcSRobert Mustacchi 				ret_code = I40E_ERR_INVALID_SD_TYPE;
427*9d26e4fcSRobert Mustacchi 				goto exit;
428*9d26e4fcSRobert Mustacchi 			}
429*9d26e4fcSRobert Mustacchi 		}
430*9d26e4fcSRobert Mustacchi 	}
431*9d26e4fcSRobert Mustacchi 	goto exit;
432*9d26e4fcSRobert Mustacchi 
433*9d26e4fcSRobert Mustacchi exit_sd_error:
434*9d26e4fcSRobert Mustacchi 	/* cleanup for sd entries from j to sd_idx */
435*9d26e4fcSRobert Mustacchi 	while (j && (j > sd_idx)) {
436*9d26e4fcSRobert Mustacchi 		sd_entry = &info->hmc_info->sd_table.sd_entry[j - 1];
437*9d26e4fcSRobert Mustacchi 		switch (sd_entry->entry_type) {
438*9d26e4fcSRobert Mustacchi 		case I40E_SD_TYPE_PAGED:
439*9d26e4fcSRobert Mustacchi 			pd_idx1 = max(pd_idx,
440*9d26e4fcSRobert Mustacchi 				      ((j - 1) * I40E_HMC_MAX_BP_COUNT));
441*9d26e4fcSRobert Mustacchi 			pd_lmt1 = min(pd_lmt, (j * I40E_HMC_MAX_BP_COUNT));
442*9d26e4fcSRobert Mustacchi 			for (i = pd_idx1; i < pd_lmt1; i++)
443*9d26e4fcSRobert Mustacchi 				i40e_remove_pd_bp(hw, info->hmc_info, i);
444*9d26e4fcSRobert Mustacchi 			i40e_remove_pd_page(hw, info->hmc_info, (j - 1));
445*9d26e4fcSRobert Mustacchi 			break;
446*9d26e4fcSRobert Mustacchi 		case I40E_SD_TYPE_DIRECT:
447*9d26e4fcSRobert Mustacchi 			i40e_remove_sd_bp(hw, info->hmc_info, (j - 1));
448*9d26e4fcSRobert Mustacchi 			break;
449*9d26e4fcSRobert Mustacchi 		default:
450*9d26e4fcSRobert Mustacchi 			ret_code = I40E_ERR_INVALID_SD_TYPE;
451*9d26e4fcSRobert Mustacchi 			break;
452*9d26e4fcSRobert Mustacchi 		}
453*9d26e4fcSRobert Mustacchi 		j--;
454*9d26e4fcSRobert Mustacchi 	}
455*9d26e4fcSRobert Mustacchi exit:
456*9d26e4fcSRobert Mustacchi 	return ret_code;
457*9d26e4fcSRobert Mustacchi }
458*9d26e4fcSRobert Mustacchi 
459*9d26e4fcSRobert Mustacchi /**
460*9d26e4fcSRobert Mustacchi  * i40e_configure_lan_hmc - prepare the HMC backing store
461*9d26e4fcSRobert Mustacchi  * @hw: pointer to the hw structure
462*9d26e4fcSRobert Mustacchi  * @model: the model for the layout of the SD/PD tables
463*9d26e4fcSRobert Mustacchi  *
464*9d26e4fcSRobert Mustacchi  * - This function will be called once per physical function initialization.
465*9d26e4fcSRobert Mustacchi  * - This function will be called after i40e_init_lan_hmc() and before
466*9d26e4fcSRobert Mustacchi  *   any LAN/FCoE HMC objects can be created.
467*9d26e4fcSRobert Mustacchi  **/
468*9d26e4fcSRobert Mustacchi enum i40e_status_code i40e_configure_lan_hmc(struct i40e_hw *hw,
469*9d26e4fcSRobert Mustacchi 					     enum i40e_hmc_model model)
470*9d26e4fcSRobert Mustacchi {
471*9d26e4fcSRobert Mustacchi 	struct i40e_hmc_lan_create_obj_info info;
472*9d26e4fcSRobert Mustacchi 	u8 hmc_fn_id = hw->hmc.hmc_fn_id;
473*9d26e4fcSRobert Mustacchi 	struct i40e_hmc_obj_info *obj;
474*9d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
475*9d26e4fcSRobert Mustacchi 
476*9d26e4fcSRobert Mustacchi 	/* Initialize part of the create object info struct */
477*9d26e4fcSRobert Mustacchi 	info.hmc_info = &hw->hmc;
478*9d26e4fcSRobert Mustacchi 	info.rsrc_type = I40E_HMC_LAN_FULL;
479*9d26e4fcSRobert Mustacchi 	info.start_idx = 0;
480*9d26e4fcSRobert Mustacchi 	info.direct_mode_sz = hw->hmc.hmc_obj[I40E_HMC_LAN_FULL].size;
481*9d26e4fcSRobert Mustacchi 
482*9d26e4fcSRobert Mustacchi 	/* Build the SD entry for the LAN objects */
483*9d26e4fcSRobert Mustacchi 	switch (model) {
484*9d26e4fcSRobert Mustacchi 	case I40E_HMC_MODEL_DIRECT_PREFERRED:
485*9d26e4fcSRobert Mustacchi 	case I40E_HMC_MODEL_DIRECT_ONLY:
486*9d26e4fcSRobert Mustacchi 		info.entry_type = I40E_SD_TYPE_DIRECT;
487*9d26e4fcSRobert Mustacchi 		/* Make one big object, a single SD */
488*9d26e4fcSRobert Mustacchi 		info.count = 1;
489*9d26e4fcSRobert Mustacchi 		ret_code = i40e_create_lan_hmc_object(hw, &info);
490*9d26e4fcSRobert Mustacchi 		if ((ret_code != I40E_SUCCESS) && (model == I40E_HMC_MODEL_DIRECT_PREFERRED))
491*9d26e4fcSRobert Mustacchi 			goto try_type_paged;
492*9d26e4fcSRobert Mustacchi 		else if (ret_code != I40E_SUCCESS)
493*9d26e4fcSRobert Mustacchi 			goto configure_lan_hmc_out;
494*9d26e4fcSRobert Mustacchi 		/* else clause falls through the break */
495*9d26e4fcSRobert Mustacchi 		break;
496*9d26e4fcSRobert Mustacchi 	case I40E_HMC_MODEL_PAGED_ONLY:
497*9d26e4fcSRobert Mustacchi try_type_paged:
498*9d26e4fcSRobert Mustacchi 		info.entry_type = I40E_SD_TYPE_PAGED;
499*9d26e4fcSRobert Mustacchi 		/* Make one big object in the PD table */
500*9d26e4fcSRobert Mustacchi 		info.count = 1;
501*9d26e4fcSRobert Mustacchi 		ret_code = i40e_create_lan_hmc_object(hw, &info);
502*9d26e4fcSRobert Mustacchi 		if (ret_code != I40E_SUCCESS)
503*9d26e4fcSRobert Mustacchi 			goto configure_lan_hmc_out;
504*9d26e4fcSRobert Mustacchi 		break;
505*9d26e4fcSRobert Mustacchi 	default:
506*9d26e4fcSRobert Mustacchi 		/* unsupported type */
507*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_INVALID_SD_TYPE;
508*9d26e4fcSRobert Mustacchi 		DEBUGOUT1("i40e_configure_lan_hmc: Unknown SD type: %d\n",
509*9d26e4fcSRobert Mustacchi 			  ret_code);
510*9d26e4fcSRobert Mustacchi 		goto configure_lan_hmc_out;
511*9d26e4fcSRobert Mustacchi 	}
512*9d26e4fcSRobert Mustacchi 
513*9d26e4fcSRobert Mustacchi 	/* Configure and program the FPM registers so objects can be created */
514*9d26e4fcSRobert Mustacchi 
515*9d26e4fcSRobert Mustacchi 	/* Tx contexts */
516*9d26e4fcSRobert Mustacchi 	obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX];
517*9d26e4fcSRobert Mustacchi 	wr32(hw, I40E_GLHMC_LANTXBASE(hmc_fn_id),
518*9d26e4fcSRobert Mustacchi 	     (u32)((obj->base & I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK) / 512));
519*9d26e4fcSRobert Mustacchi 	wr32(hw, I40E_GLHMC_LANTXCNT(hmc_fn_id), obj->cnt);
520*9d26e4fcSRobert Mustacchi 
521*9d26e4fcSRobert Mustacchi 	/* Rx contexts */
522*9d26e4fcSRobert Mustacchi 	obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_RX];
523*9d26e4fcSRobert Mustacchi 	wr32(hw, I40E_GLHMC_LANRXBASE(hmc_fn_id),
524*9d26e4fcSRobert Mustacchi 	     (u32)((obj->base & I40E_GLHMC_LANRXBASE_FPMLANRXBASE_MASK) / 512));
525*9d26e4fcSRobert Mustacchi 	wr32(hw, I40E_GLHMC_LANRXCNT(hmc_fn_id), obj->cnt);
526*9d26e4fcSRobert Mustacchi 
527*9d26e4fcSRobert Mustacchi 	/* FCoE contexts */
528*9d26e4fcSRobert Mustacchi 	obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX];
529*9d26e4fcSRobert Mustacchi 	wr32(hw, I40E_GLHMC_FCOEDDPBASE(hmc_fn_id),
530*9d26e4fcSRobert Mustacchi 	 (u32)((obj->base & I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_MASK) / 512));
531*9d26e4fcSRobert Mustacchi 	wr32(hw, I40E_GLHMC_FCOEDDPCNT(hmc_fn_id), obj->cnt);
532*9d26e4fcSRobert Mustacchi 
533*9d26e4fcSRobert Mustacchi 	/* FCoE filters */
534*9d26e4fcSRobert Mustacchi 	obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_FILT];
535*9d26e4fcSRobert Mustacchi 	wr32(hw, I40E_GLHMC_FCOEFBASE(hmc_fn_id),
536*9d26e4fcSRobert Mustacchi 	     (u32)((obj->base & I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_MASK) / 512));
537*9d26e4fcSRobert Mustacchi 	wr32(hw, I40E_GLHMC_FCOEFCNT(hmc_fn_id), obj->cnt);
538*9d26e4fcSRobert Mustacchi 
539*9d26e4fcSRobert Mustacchi configure_lan_hmc_out:
540*9d26e4fcSRobert Mustacchi 	return ret_code;
541*9d26e4fcSRobert Mustacchi }
542*9d26e4fcSRobert Mustacchi 
543*9d26e4fcSRobert Mustacchi /**
544*9d26e4fcSRobert Mustacchi  * i40e_delete_hmc_object - remove hmc objects
545*9d26e4fcSRobert Mustacchi  * @hw: pointer to the HW structure
546*9d26e4fcSRobert Mustacchi  * @info: pointer to i40e_hmc_delete_obj_info struct
547*9d26e4fcSRobert Mustacchi  *
548*9d26e4fcSRobert Mustacchi  * This will de-populate the SDs and PDs.  It frees
549*9d26e4fcSRobert Mustacchi  * the memory for PDS and backing storage.  After this function is returned,
550*9d26e4fcSRobert Mustacchi  * caller should deallocate memory allocated previously for
551*9d26e4fcSRobert Mustacchi  * book-keeping information about PDs and backing storage.
552*9d26e4fcSRobert Mustacchi  **/
553*9d26e4fcSRobert Mustacchi enum i40e_status_code i40e_delete_lan_hmc_object(struct i40e_hw *hw,
554*9d26e4fcSRobert Mustacchi 				struct i40e_hmc_lan_delete_obj_info *info)
555*9d26e4fcSRobert Mustacchi {
556*9d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
557*9d26e4fcSRobert Mustacchi 	struct i40e_hmc_pd_table *pd_table;
558*9d26e4fcSRobert Mustacchi 	u32 pd_idx, pd_lmt, rel_pd_idx;
559*9d26e4fcSRobert Mustacchi 	u32 sd_idx, sd_lmt;
560*9d26e4fcSRobert Mustacchi 	u32 i, j;
561*9d26e4fcSRobert Mustacchi 
562*9d26e4fcSRobert Mustacchi 	if (NULL == info) {
563*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_BAD_PTR;
564*9d26e4fcSRobert Mustacchi 		DEBUGOUT("i40e_delete_hmc_object: bad info ptr\n");
565*9d26e4fcSRobert Mustacchi 		goto exit;
566*9d26e4fcSRobert Mustacchi 	}
567*9d26e4fcSRobert Mustacchi 	if (NULL == info->hmc_info) {
568*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_BAD_PTR;
569*9d26e4fcSRobert Mustacchi 		DEBUGOUT("i40e_delete_hmc_object: bad info->hmc_info ptr\n");
570*9d26e4fcSRobert Mustacchi 		goto exit;
571*9d26e4fcSRobert Mustacchi 	}
572*9d26e4fcSRobert Mustacchi 	if (I40E_HMC_INFO_SIGNATURE != info->hmc_info->signature) {
573*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_BAD_PTR;
574*9d26e4fcSRobert Mustacchi 		DEBUGOUT("i40e_delete_hmc_object: bad hmc_info->signature\n");
575*9d26e4fcSRobert Mustacchi 		goto exit;
576*9d26e4fcSRobert Mustacchi 	}
577*9d26e4fcSRobert Mustacchi 
578*9d26e4fcSRobert Mustacchi 	if (NULL == info->hmc_info->sd_table.sd_entry) {
579*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_BAD_PTR;
580*9d26e4fcSRobert Mustacchi 		DEBUGOUT("i40e_delete_hmc_object: bad sd_entry\n");
581*9d26e4fcSRobert Mustacchi 		goto exit;
582*9d26e4fcSRobert Mustacchi 	}
583*9d26e4fcSRobert Mustacchi 
584*9d26e4fcSRobert Mustacchi 	if (NULL == info->hmc_info->hmc_obj) {
585*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_BAD_PTR;
586*9d26e4fcSRobert Mustacchi 		DEBUGOUT("i40e_delete_hmc_object: bad hmc_info->hmc_obj\n");
587*9d26e4fcSRobert Mustacchi 		goto exit;
588*9d26e4fcSRobert Mustacchi 	}
589*9d26e4fcSRobert Mustacchi 	if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
590*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX;
591*9d26e4fcSRobert Mustacchi 		DEBUGOUT1("i40e_delete_hmc_object: returns error %d\n",
592*9d26e4fcSRobert Mustacchi 			  ret_code);
593*9d26e4fcSRobert Mustacchi 		goto exit;
594*9d26e4fcSRobert Mustacchi 	}
595*9d26e4fcSRobert Mustacchi 
596*9d26e4fcSRobert Mustacchi 	if ((info->start_idx + info->count) >
597*9d26e4fcSRobert Mustacchi 	    info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
598*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
599*9d26e4fcSRobert Mustacchi 		DEBUGOUT1("i40e_delete_hmc_object: returns error %d\n",
600*9d26e4fcSRobert Mustacchi 			  ret_code);
601*9d26e4fcSRobert Mustacchi 		goto exit;
602*9d26e4fcSRobert Mustacchi 	}
603*9d26e4fcSRobert Mustacchi 
604*9d26e4fcSRobert Mustacchi 	I40E_FIND_PD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
605*9d26e4fcSRobert Mustacchi 				 info->start_idx, info->count, &pd_idx,
606*9d26e4fcSRobert Mustacchi 				 &pd_lmt);
607*9d26e4fcSRobert Mustacchi 
608*9d26e4fcSRobert Mustacchi 	for (j = pd_idx; j < pd_lmt; j++) {
609*9d26e4fcSRobert Mustacchi 		sd_idx = j / I40E_HMC_PD_CNT_IN_SD;
610*9d26e4fcSRobert Mustacchi 
611*9d26e4fcSRobert Mustacchi 		if (I40E_SD_TYPE_PAGED !=
612*9d26e4fcSRobert Mustacchi 		    info->hmc_info->sd_table.sd_entry[sd_idx].entry_type)
613*9d26e4fcSRobert Mustacchi 			continue;
614*9d26e4fcSRobert Mustacchi 
615*9d26e4fcSRobert Mustacchi 		rel_pd_idx = j % I40E_HMC_PD_CNT_IN_SD;
616*9d26e4fcSRobert Mustacchi 
617*9d26e4fcSRobert Mustacchi 		pd_table =
618*9d26e4fcSRobert Mustacchi 			&info->hmc_info->sd_table.sd_entry[sd_idx].u.pd_table;
619*9d26e4fcSRobert Mustacchi 		if (pd_table->pd_entry[rel_pd_idx].valid) {
620*9d26e4fcSRobert Mustacchi 			ret_code = i40e_remove_pd_bp(hw, info->hmc_info, j);
621*9d26e4fcSRobert Mustacchi 			if (I40E_SUCCESS != ret_code)
622*9d26e4fcSRobert Mustacchi 				goto exit;
623*9d26e4fcSRobert Mustacchi 		}
624*9d26e4fcSRobert Mustacchi 	}
625*9d26e4fcSRobert Mustacchi 
626*9d26e4fcSRobert Mustacchi 	/* find sd index and limit */
627*9d26e4fcSRobert Mustacchi 	I40E_FIND_SD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
628*9d26e4fcSRobert Mustacchi 				 info->start_idx, info->count,
629*9d26e4fcSRobert Mustacchi 				 &sd_idx, &sd_lmt);
630*9d26e4fcSRobert Mustacchi 	if (sd_idx >= info->hmc_info->sd_table.sd_cnt ||
631*9d26e4fcSRobert Mustacchi 	    sd_lmt > info->hmc_info->sd_table.sd_cnt) {
632*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_INVALID_SD_INDEX;
633*9d26e4fcSRobert Mustacchi 		goto exit;
634*9d26e4fcSRobert Mustacchi 	}
635*9d26e4fcSRobert Mustacchi 
636*9d26e4fcSRobert Mustacchi 	for (i = sd_idx; i < sd_lmt; i++) {
637*9d26e4fcSRobert Mustacchi 		if (!info->hmc_info->sd_table.sd_entry[i].valid)
638*9d26e4fcSRobert Mustacchi 			continue;
639*9d26e4fcSRobert Mustacchi 		switch (info->hmc_info->sd_table.sd_entry[i].entry_type) {
640*9d26e4fcSRobert Mustacchi 		case I40E_SD_TYPE_DIRECT:
641*9d26e4fcSRobert Mustacchi 			ret_code = i40e_remove_sd_bp(hw, info->hmc_info, i);
642*9d26e4fcSRobert Mustacchi 			if (I40E_SUCCESS != ret_code)
643*9d26e4fcSRobert Mustacchi 				goto exit;
644*9d26e4fcSRobert Mustacchi 			break;
645*9d26e4fcSRobert Mustacchi 		case I40E_SD_TYPE_PAGED:
646*9d26e4fcSRobert Mustacchi 			ret_code = i40e_remove_pd_page(hw, info->hmc_info, i);
647*9d26e4fcSRobert Mustacchi 			if (I40E_SUCCESS != ret_code)
648*9d26e4fcSRobert Mustacchi 				goto exit;
649*9d26e4fcSRobert Mustacchi 			break;
650*9d26e4fcSRobert Mustacchi 		default:
651*9d26e4fcSRobert Mustacchi 			break;
652*9d26e4fcSRobert Mustacchi 		}
653*9d26e4fcSRobert Mustacchi 	}
654*9d26e4fcSRobert Mustacchi exit:
655*9d26e4fcSRobert Mustacchi 	return ret_code;
656*9d26e4fcSRobert Mustacchi }
657*9d26e4fcSRobert Mustacchi 
658*9d26e4fcSRobert Mustacchi /**
659*9d26e4fcSRobert Mustacchi  * i40e_shutdown_lan_hmc - Remove HMC backing store, free allocated memory
660*9d26e4fcSRobert Mustacchi  * @hw: pointer to the hw structure
661*9d26e4fcSRobert Mustacchi  *
662*9d26e4fcSRobert Mustacchi  * This must be called by drivers as they are shutting down and being
663*9d26e4fcSRobert Mustacchi  * removed from the OS.
664*9d26e4fcSRobert Mustacchi  **/
665*9d26e4fcSRobert Mustacchi enum i40e_status_code i40e_shutdown_lan_hmc(struct i40e_hw *hw)
666*9d26e4fcSRobert Mustacchi {
667*9d26e4fcSRobert Mustacchi 	struct i40e_hmc_lan_delete_obj_info info;
668*9d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code;
669*9d26e4fcSRobert Mustacchi 
670*9d26e4fcSRobert Mustacchi 	info.hmc_info = &hw->hmc;
671*9d26e4fcSRobert Mustacchi 	info.rsrc_type = I40E_HMC_LAN_FULL;
672*9d26e4fcSRobert Mustacchi 	info.start_idx = 0;
673*9d26e4fcSRobert Mustacchi 	info.count = 1;
674*9d26e4fcSRobert Mustacchi 
675*9d26e4fcSRobert Mustacchi 	/* delete the object */
676*9d26e4fcSRobert Mustacchi 	ret_code = i40e_delete_lan_hmc_object(hw, &info);
677*9d26e4fcSRobert Mustacchi 
678*9d26e4fcSRobert Mustacchi 	/* free the SD table entry for LAN */
679*9d26e4fcSRobert Mustacchi 	i40e_free_virt_mem(hw, &hw->hmc.sd_table.addr);
680*9d26e4fcSRobert Mustacchi 	hw->hmc.sd_table.sd_cnt = 0;
681*9d26e4fcSRobert Mustacchi 	hw->hmc.sd_table.sd_entry = NULL;
682*9d26e4fcSRobert Mustacchi 
683*9d26e4fcSRobert Mustacchi 	/* free memory used for hmc_obj */
684*9d26e4fcSRobert Mustacchi 	i40e_free_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem);
685*9d26e4fcSRobert Mustacchi 	hw->hmc.hmc_obj = NULL;
686*9d26e4fcSRobert Mustacchi 
687*9d26e4fcSRobert Mustacchi 	return ret_code;
688*9d26e4fcSRobert Mustacchi }
689*9d26e4fcSRobert Mustacchi 
690*9d26e4fcSRobert Mustacchi #define I40E_HMC_STORE(_struct, _ele)		\
691*9d26e4fcSRobert Mustacchi 	offsetof(struct _struct, _ele),		\
692*9d26e4fcSRobert Mustacchi 	FIELD_SIZEOF(struct _struct, _ele)
693*9d26e4fcSRobert Mustacchi 
694*9d26e4fcSRobert Mustacchi struct i40e_context_ele {
695*9d26e4fcSRobert Mustacchi 	u16 offset;
696*9d26e4fcSRobert Mustacchi 	u16 size_of;
697*9d26e4fcSRobert Mustacchi 	u16 width;
698*9d26e4fcSRobert Mustacchi 	u16 lsb;
699*9d26e4fcSRobert Mustacchi };
700*9d26e4fcSRobert Mustacchi 
701*9d26e4fcSRobert Mustacchi /* LAN Tx Queue Context */
702*9d26e4fcSRobert Mustacchi static struct i40e_context_ele i40e_hmc_txq_ce_info[] = {
703*9d26e4fcSRobert Mustacchi 					     /* Field      Width    LSB */
704*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, head),           13,      0 },
705*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, new_context),     1,     30 },
706*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, base),           57,     32 },
707*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, fc_ena),          1,     89 },
708*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, timesync_ena),    1,     90 },
709*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, fd_ena),          1,     91 },
710*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, alt_vlan_ena),    1,     92 },
711*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, cpuid),           8,     96 },
712*9d26e4fcSRobert Mustacchi /* line 1 */
713*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, thead_wb),       13,  0 + 128 },
714*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, head_wb_ena),     1, 32 + 128 },
715*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, qlen),           13, 33 + 128 },
716*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, tphrdesc_ena),    1, 46 + 128 },
717*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, tphrpacket_ena),  1, 47 + 128 },
718*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, tphwdesc_ena),    1, 48 + 128 },
719*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, head_wb_addr),   64, 64 + 128 },
720*9d26e4fcSRobert Mustacchi /* line 7 */
721*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, crc),            32,  0 + (7 * 128) },
722*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, rdylist),        10, 84 + (7 * 128) },
723*9d26e4fcSRobert Mustacchi 	{I40E_HMC_STORE(i40e_hmc_obj_txq, rdylist_act),     1, 94 + (7 * 128) },
724*9d26e4fcSRobert Mustacchi 	{ 0 }
725*9d26e4fcSRobert Mustacchi };
726*9d26e4fcSRobert Mustacchi 
727*9d26e4fcSRobert Mustacchi /* LAN Rx Queue Context */
728*9d26e4fcSRobert Mustacchi static struct i40e_context_ele i40e_hmc_rxq_ce_info[] = {
729*9d26e4fcSRobert Mustacchi 					 /* Field      Width    LSB */
730*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, head),        13,	0   },
731*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, cpuid),        8,	13  },
732*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, base),        57,	32  },
733*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, qlen),        13,	89  },
734*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, dbuff),        7,	102 },
735*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, hbuff),        5,	109 },
736*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, dtype),        2,	114 },
737*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, dsize),        1,	116 },
738*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, crcstrip),     1,	117 },
739*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, fc_ena),       1,	118 },
740*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, l2tsel),       1,	119 },
741*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, hsplit_0),     4,	120 },
742*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, hsplit_1),     2,	124 },
743*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, showiv),       1,	127 },
744*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, rxmax),       14,	174 },
745*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, tphrdesc_ena), 1,	193 },
746*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, tphwdesc_ena), 1,	194 },
747*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, tphdata_ena),  1,	195 },
748*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, tphhead_ena),  1,	196 },
749*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, lrxqthresh),   3,	198 },
750*9d26e4fcSRobert Mustacchi 	{ I40E_HMC_STORE(i40e_hmc_obj_rxq, prefena),      1,	201 },
751*9d26e4fcSRobert Mustacchi 	{ 0 }
752*9d26e4fcSRobert Mustacchi };
753*9d26e4fcSRobert Mustacchi 
754*9d26e4fcSRobert Mustacchi /**
755*9d26e4fcSRobert Mustacchi  * i40e_write_byte - replace HMC context byte
756*9d26e4fcSRobert Mustacchi  * @hmc_bits: pointer to the HMC memory
757*9d26e4fcSRobert Mustacchi  * @ce_info: a description of the struct to be read from
758*9d26e4fcSRobert Mustacchi  * @src: the struct to be read from
759*9d26e4fcSRobert Mustacchi  **/
760*9d26e4fcSRobert Mustacchi static void i40e_write_byte(u8 *hmc_bits,
761*9d26e4fcSRobert Mustacchi 			    struct i40e_context_ele *ce_info,
762*9d26e4fcSRobert Mustacchi 			    u8 *src)
763*9d26e4fcSRobert Mustacchi {
764*9d26e4fcSRobert Mustacchi 	u8 src_byte, dest_byte, mask;
765*9d26e4fcSRobert Mustacchi 	u8 *from, *dest;
766*9d26e4fcSRobert Mustacchi 	u16 shift_width;
767*9d26e4fcSRobert Mustacchi 
768*9d26e4fcSRobert Mustacchi 	/* copy from the next struct field */
769*9d26e4fcSRobert Mustacchi 	from = src + ce_info->offset;
770*9d26e4fcSRobert Mustacchi 
771*9d26e4fcSRobert Mustacchi 	/* prepare the bits and mask */
772*9d26e4fcSRobert Mustacchi 	shift_width = ce_info->lsb % 8;
773*9d26e4fcSRobert Mustacchi 	mask = BIT(ce_info->width) - 1;
774*9d26e4fcSRobert Mustacchi 
775*9d26e4fcSRobert Mustacchi 	src_byte = *from;
776*9d26e4fcSRobert Mustacchi 	src_byte &= mask;
777*9d26e4fcSRobert Mustacchi 
778*9d26e4fcSRobert Mustacchi 	/* shift to correct alignment */
779*9d26e4fcSRobert Mustacchi 	mask <<= shift_width;
780*9d26e4fcSRobert Mustacchi 	src_byte <<= shift_width;
781*9d26e4fcSRobert Mustacchi 
782*9d26e4fcSRobert Mustacchi 	/* get the current bits from the target bit string */
783*9d26e4fcSRobert Mustacchi 	dest = hmc_bits + (ce_info->lsb / 8);
784*9d26e4fcSRobert Mustacchi 
785*9d26e4fcSRobert Mustacchi 	i40e_memcpy(&dest_byte, dest, sizeof(dest_byte), I40E_DMA_TO_NONDMA);
786*9d26e4fcSRobert Mustacchi 
787*9d26e4fcSRobert Mustacchi 	dest_byte &= ~mask;	/* get the bits not changing */
788*9d26e4fcSRobert Mustacchi 	dest_byte |= src_byte;	/* add in the new bits */
789*9d26e4fcSRobert Mustacchi 
790*9d26e4fcSRobert Mustacchi 	/* put it all back */
791*9d26e4fcSRobert Mustacchi 	i40e_memcpy(dest, &dest_byte, sizeof(dest_byte), I40E_NONDMA_TO_DMA);
792*9d26e4fcSRobert Mustacchi }
793*9d26e4fcSRobert Mustacchi 
794*9d26e4fcSRobert Mustacchi /**
795*9d26e4fcSRobert Mustacchi  * i40e_write_word - replace HMC context word
796*9d26e4fcSRobert Mustacchi  * @hmc_bits: pointer to the HMC memory
797*9d26e4fcSRobert Mustacchi  * @ce_info: a description of the struct to be read from
798*9d26e4fcSRobert Mustacchi  * @src: the struct to be read from
799*9d26e4fcSRobert Mustacchi  **/
800*9d26e4fcSRobert Mustacchi static void i40e_write_word(u8 *hmc_bits,
801*9d26e4fcSRobert Mustacchi 			    struct i40e_context_ele *ce_info,
802*9d26e4fcSRobert Mustacchi 			    u8 *src)
803*9d26e4fcSRobert Mustacchi {
804*9d26e4fcSRobert Mustacchi 	u16 src_word, mask;
805*9d26e4fcSRobert Mustacchi 	u8 *from, *dest;
806*9d26e4fcSRobert Mustacchi 	u16 shift_width;
807*9d26e4fcSRobert Mustacchi 	__le16 dest_word;
808*9d26e4fcSRobert Mustacchi 
809*9d26e4fcSRobert Mustacchi 	/* copy from the next struct field */
810*9d26e4fcSRobert Mustacchi 	from = src + ce_info->offset;
811*9d26e4fcSRobert Mustacchi 
812*9d26e4fcSRobert Mustacchi 	/* prepare the bits and mask */
813*9d26e4fcSRobert Mustacchi 	shift_width = ce_info->lsb % 8;
814*9d26e4fcSRobert Mustacchi 	mask = BIT(ce_info->width) - 1;
815*9d26e4fcSRobert Mustacchi 
816*9d26e4fcSRobert Mustacchi 	/* don't swizzle the bits until after the mask because the mask bits
817*9d26e4fcSRobert Mustacchi 	 * will be in a different bit position on big endian machines
818*9d26e4fcSRobert Mustacchi 	 */
819*9d26e4fcSRobert Mustacchi 	src_word = *(u16 *)from;
820*9d26e4fcSRobert Mustacchi 	src_word &= mask;
821*9d26e4fcSRobert Mustacchi 
822*9d26e4fcSRobert Mustacchi 	/* shift to correct alignment */
823*9d26e4fcSRobert Mustacchi 	mask <<= shift_width;
824*9d26e4fcSRobert Mustacchi 	src_word <<= shift_width;
825*9d26e4fcSRobert Mustacchi 
826*9d26e4fcSRobert Mustacchi 	/* get the current bits from the target bit string */
827*9d26e4fcSRobert Mustacchi 	dest = hmc_bits + (ce_info->lsb / 8);
828*9d26e4fcSRobert Mustacchi 
829*9d26e4fcSRobert Mustacchi 	i40e_memcpy(&dest_word, dest, sizeof(dest_word), I40E_DMA_TO_NONDMA);
830*9d26e4fcSRobert Mustacchi 
831*9d26e4fcSRobert Mustacchi 	dest_word &= ~(CPU_TO_LE16(mask));	/* get the bits not changing */
832*9d26e4fcSRobert Mustacchi 	dest_word |= CPU_TO_LE16(src_word);	/* add in the new bits */
833*9d26e4fcSRobert Mustacchi 
834*9d26e4fcSRobert Mustacchi 	/* put it all back */
835*9d26e4fcSRobert Mustacchi 	i40e_memcpy(dest, &dest_word, sizeof(dest_word), I40E_NONDMA_TO_DMA);
836*9d26e4fcSRobert Mustacchi }
837*9d26e4fcSRobert Mustacchi 
838*9d26e4fcSRobert Mustacchi /**
839*9d26e4fcSRobert Mustacchi  * i40e_write_dword - replace HMC context dword
840*9d26e4fcSRobert Mustacchi  * @hmc_bits: pointer to the HMC memory
841*9d26e4fcSRobert Mustacchi  * @ce_info: a description of the struct to be read from
842*9d26e4fcSRobert Mustacchi  * @src: the struct to be read from
843*9d26e4fcSRobert Mustacchi  **/
844*9d26e4fcSRobert Mustacchi static void i40e_write_dword(u8 *hmc_bits,
845*9d26e4fcSRobert Mustacchi 			     struct i40e_context_ele *ce_info,
846*9d26e4fcSRobert Mustacchi 			     u8 *src)
847*9d26e4fcSRobert Mustacchi {
848*9d26e4fcSRobert Mustacchi 	u32 src_dword, mask;
849*9d26e4fcSRobert Mustacchi 	u8 *from, *dest;
850*9d26e4fcSRobert Mustacchi 	u16 shift_width;
851*9d26e4fcSRobert Mustacchi 	__le32 dest_dword;
852*9d26e4fcSRobert Mustacchi 
853*9d26e4fcSRobert Mustacchi 	/* copy from the next struct field */
854*9d26e4fcSRobert Mustacchi 	from = src + ce_info->offset;
855*9d26e4fcSRobert Mustacchi 
856*9d26e4fcSRobert Mustacchi 	/* prepare the bits and mask */
857*9d26e4fcSRobert Mustacchi 	shift_width = ce_info->lsb % 8;
858*9d26e4fcSRobert Mustacchi 
859*9d26e4fcSRobert Mustacchi 	/* if the field width is exactly 32 on an x86 machine, then the shift
860*9d26e4fcSRobert Mustacchi 	 * operation will not work because the SHL instructions count is masked
861*9d26e4fcSRobert Mustacchi 	 * to 5 bits so the shift will do nothing
862*9d26e4fcSRobert Mustacchi 	 */
863*9d26e4fcSRobert Mustacchi 	if (ce_info->width < 32)
864*9d26e4fcSRobert Mustacchi 		mask = BIT(ce_info->width) - 1;
865*9d26e4fcSRobert Mustacchi 	else
866*9d26e4fcSRobert Mustacchi 		mask = ~(u32)0;
867*9d26e4fcSRobert Mustacchi 
868*9d26e4fcSRobert Mustacchi 	/* don't swizzle the bits until after the mask because the mask bits
869*9d26e4fcSRobert Mustacchi 	 * will be in a different bit position on big endian machines
870*9d26e4fcSRobert Mustacchi 	 */
871*9d26e4fcSRobert Mustacchi 	src_dword = *(u32 *)from;
872*9d26e4fcSRobert Mustacchi 	src_dword &= mask;
873*9d26e4fcSRobert Mustacchi 
874*9d26e4fcSRobert Mustacchi 	/* shift to correct alignment */
875*9d26e4fcSRobert Mustacchi 	mask <<= shift_width;
876*9d26e4fcSRobert Mustacchi 	src_dword <<= shift_width;
877*9d26e4fcSRobert Mustacchi 
878*9d26e4fcSRobert Mustacchi 	/* get the current bits from the target bit string */
879*9d26e4fcSRobert Mustacchi 	dest = hmc_bits + (ce_info->lsb / 8);
880*9d26e4fcSRobert Mustacchi 
881*9d26e4fcSRobert Mustacchi 	i40e_memcpy(&dest_dword, dest, sizeof(dest_dword), I40E_DMA_TO_NONDMA);
882*9d26e4fcSRobert Mustacchi 
883*9d26e4fcSRobert Mustacchi 	dest_dword &= ~(CPU_TO_LE32(mask));	/* get the bits not changing */
884*9d26e4fcSRobert Mustacchi 	dest_dword |= CPU_TO_LE32(src_dword);	/* add in the new bits */
885*9d26e4fcSRobert Mustacchi 
886*9d26e4fcSRobert Mustacchi 	/* put it all back */
887*9d26e4fcSRobert Mustacchi 	i40e_memcpy(dest, &dest_dword, sizeof(dest_dword), I40E_NONDMA_TO_DMA);
888*9d26e4fcSRobert Mustacchi }
889*9d26e4fcSRobert Mustacchi 
890*9d26e4fcSRobert Mustacchi /**
891*9d26e4fcSRobert Mustacchi  * i40e_write_qword - replace HMC context qword
892*9d26e4fcSRobert Mustacchi  * @hmc_bits: pointer to the HMC memory
893*9d26e4fcSRobert Mustacchi  * @ce_info: a description of the struct to be read from
894*9d26e4fcSRobert Mustacchi  * @src: the struct to be read from
895*9d26e4fcSRobert Mustacchi  **/
896*9d26e4fcSRobert Mustacchi static void i40e_write_qword(u8 *hmc_bits,
897*9d26e4fcSRobert Mustacchi 			     struct i40e_context_ele *ce_info,
898*9d26e4fcSRobert Mustacchi 			     u8 *src)
899*9d26e4fcSRobert Mustacchi {
900*9d26e4fcSRobert Mustacchi 	u64 src_qword, mask;
901*9d26e4fcSRobert Mustacchi 	u8 *from, *dest;
902*9d26e4fcSRobert Mustacchi 	u16 shift_width;
903*9d26e4fcSRobert Mustacchi 	__le64 dest_qword;
904*9d26e4fcSRobert Mustacchi 
905*9d26e4fcSRobert Mustacchi 	/* copy from the next struct field */
906*9d26e4fcSRobert Mustacchi 	from = src + ce_info->offset;
907*9d26e4fcSRobert Mustacchi 
908*9d26e4fcSRobert Mustacchi 	/* prepare the bits and mask */
909*9d26e4fcSRobert Mustacchi 	shift_width = ce_info->lsb % 8;
910*9d26e4fcSRobert Mustacchi 
911*9d26e4fcSRobert Mustacchi 	/* if the field width is exactly 64 on an x86 machine, then the shift
912*9d26e4fcSRobert Mustacchi 	 * operation will not work because the SHL instructions count is masked
913*9d26e4fcSRobert Mustacchi 	 * to 6 bits so the shift will do nothing
914*9d26e4fcSRobert Mustacchi 	 */
915*9d26e4fcSRobert Mustacchi 	if (ce_info->width < 64)
916*9d26e4fcSRobert Mustacchi 		mask = BIT_ULL(ce_info->width) - 1;
917*9d26e4fcSRobert Mustacchi 	else
918*9d26e4fcSRobert Mustacchi 		mask = ~(u64)0;
919*9d26e4fcSRobert Mustacchi 
920*9d26e4fcSRobert Mustacchi 	/* don't swizzle the bits until after the mask because the mask bits
921*9d26e4fcSRobert Mustacchi 	 * will be in a different bit position on big endian machines
922*9d26e4fcSRobert Mustacchi 	 */
923*9d26e4fcSRobert Mustacchi 	src_qword = *(u64 *)from;
924*9d26e4fcSRobert Mustacchi 	src_qword &= mask;
925*9d26e4fcSRobert Mustacchi 
926*9d26e4fcSRobert Mustacchi 	/* shift to correct alignment */
927*9d26e4fcSRobert Mustacchi 	mask <<= shift_width;
928*9d26e4fcSRobert Mustacchi 	src_qword <<= shift_width;
929*9d26e4fcSRobert Mustacchi 
930*9d26e4fcSRobert Mustacchi 	/* get the current bits from the target bit string */
931*9d26e4fcSRobert Mustacchi 	dest = hmc_bits + (ce_info->lsb / 8);
932*9d26e4fcSRobert Mustacchi 
933*9d26e4fcSRobert Mustacchi 	i40e_memcpy(&dest_qword, dest, sizeof(dest_qword), I40E_DMA_TO_NONDMA);
934*9d26e4fcSRobert Mustacchi 
935*9d26e4fcSRobert Mustacchi 	dest_qword &= ~(CPU_TO_LE64(mask));	/* get the bits not changing */
936*9d26e4fcSRobert Mustacchi 	dest_qword |= CPU_TO_LE64(src_qword);	/* add in the new bits */
937*9d26e4fcSRobert Mustacchi 
938*9d26e4fcSRobert Mustacchi 	/* put it all back */
939*9d26e4fcSRobert Mustacchi 	i40e_memcpy(dest, &dest_qword, sizeof(dest_qword), I40E_NONDMA_TO_DMA);
940*9d26e4fcSRobert Mustacchi }
941*9d26e4fcSRobert Mustacchi 
942*9d26e4fcSRobert Mustacchi /**
943*9d26e4fcSRobert Mustacchi  * i40e_read_byte - read HMC context byte into struct
944*9d26e4fcSRobert Mustacchi  * @hmc_bits: pointer to the HMC memory
945*9d26e4fcSRobert Mustacchi  * @ce_info: a description of the struct to be filled
946*9d26e4fcSRobert Mustacchi  * @dest: the struct to be filled
947*9d26e4fcSRobert Mustacchi  **/
948*9d26e4fcSRobert Mustacchi static void i40e_read_byte(u8 *hmc_bits,
949*9d26e4fcSRobert Mustacchi 			   struct i40e_context_ele *ce_info,
950*9d26e4fcSRobert Mustacchi 			   u8 *dest)
951*9d26e4fcSRobert Mustacchi {
952*9d26e4fcSRobert Mustacchi 	u8 dest_byte, mask;
953*9d26e4fcSRobert Mustacchi 	u8 *src, *target;
954*9d26e4fcSRobert Mustacchi 	u16 shift_width;
955*9d26e4fcSRobert Mustacchi 
956*9d26e4fcSRobert Mustacchi 	/* prepare the bits and mask */
957*9d26e4fcSRobert Mustacchi 	shift_width = ce_info->lsb % 8;
958*9d26e4fcSRobert Mustacchi 	mask = BIT(ce_info->width) - 1;
959*9d26e4fcSRobert Mustacchi 
960*9d26e4fcSRobert Mustacchi 	/* shift to correct alignment */
961*9d26e4fcSRobert Mustacchi 	mask <<= shift_width;
962*9d26e4fcSRobert Mustacchi 
963*9d26e4fcSRobert Mustacchi 	/* get the current bits from the src bit string */
964*9d26e4fcSRobert Mustacchi 	src = hmc_bits + (ce_info->lsb / 8);
965*9d26e4fcSRobert Mustacchi 
966*9d26e4fcSRobert Mustacchi 	i40e_memcpy(&dest_byte, src, sizeof(dest_byte), I40E_DMA_TO_NONDMA);
967*9d26e4fcSRobert Mustacchi 
968*9d26e4fcSRobert Mustacchi 	dest_byte &= ~(mask);
969*9d26e4fcSRobert Mustacchi 
970*9d26e4fcSRobert Mustacchi 	dest_byte >>= shift_width;
971*9d26e4fcSRobert Mustacchi 
972*9d26e4fcSRobert Mustacchi 	/* get the address from the struct field */
973*9d26e4fcSRobert Mustacchi 	target = dest + ce_info->offset;
974*9d26e4fcSRobert Mustacchi 
975*9d26e4fcSRobert Mustacchi 	/* put it back in the struct */
976*9d26e4fcSRobert Mustacchi 	i40e_memcpy(target, &dest_byte, sizeof(dest_byte), I40E_NONDMA_TO_DMA);
977*9d26e4fcSRobert Mustacchi }
978*9d26e4fcSRobert Mustacchi 
979*9d26e4fcSRobert Mustacchi /**
980*9d26e4fcSRobert Mustacchi  * i40e_read_word - read HMC context word into struct
981*9d26e4fcSRobert Mustacchi  * @hmc_bits: pointer to the HMC memory
982*9d26e4fcSRobert Mustacchi  * @ce_info: a description of the struct to be filled
983*9d26e4fcSRobert Mustacchi  * @dest: the struct to be filled
984*9d26e4fcSRobert Mustacchi  **/
985*9d26e4fcSRobert Mustacchi static void i40e_read_word(u8 *hmc_bits,
986*9d26e4fcSRobert Mustacchi 			   struct i40e_context_ele *ce_info,
987*9d26e4fcSRobert Mustacchi 			   u8 *dest)
988*9d26e4fcSRobert Mustacchi {
989*9d26e4fcSRobert Mustacchi 	u16 dest_word, mask;
990*9d26e4fcSRobert Mustacchi 	u8 *src, *target;
991*9d26e4fcSRobert Mustacchi 	u16 shift_width;
992*9d26e4fcSRobert Mustacchi 	__le16 src_word;
993*9d26e4fcSRobert Mustacchi 
994*9d26e4fcSRobert Mustacchi 	/* prepare the bits and mask */
995*9d26e4fcSRobert Mustacchi 	shift_width = ce_info->lsb % 8;
996*9d26e4fcSRobert Mustacchi 	mask = BIT(ce_info->width) - 1;
997*9d26e4fcSRobert Mustacchi 
998*9d26e4fcSRobert Mustacchi 	/* shift to correct alignment */
999*9d26e4fcSRobert Mustacchi 	mask <<= shift_width;
1000*9d26e4fcSRobert Mustacchi 
1001*9d26e4fcSRobert Mustacchi 	/* get the current bits from the src bit string */
1002*9d26e4fcSRobert Mustacchi 	src = hmc_bits + (ce_info->lsb / 8);
1003*9d26e4fcSRobert Mustacchi 
1004*9d26e4fcSRobert Mustacchi 	i40e_memcpy(&src_word, src, sizeof(src_word), I40E_DMA_TO_NONDMA);
1005*9d26e4fcSRobert Mustacchi 
1006*9d26e4fcSRobert Mustacchi 	/* the data in the memory is stored as little endian so mask it
1007*9d26e4fcSRobert Mustacchi 	 * correctly
1008*9d26e4fcSRobert Mustacchi 	 */
1009*9d26e4fcSRobert Mustacchi 	src_word &= ~(CPU_TO_LE16(mask));
1010*9d26e4fcSRobert Mustacchi 
1011*9d26e4fcSRobert Mustacchi 	/* get the data back into host order before shifting */
1012*9d26e4fcSRobert Mustacchi 	dest_word = LE16_TO_CPU(src_word);
1013*9d26e4fcSRobert Mustacchi 
1014*9d26e4fcSRobert Mustacchi 	dest_word >>= shift_width;
1015*9d26e4fcSRobert Mustacchi 
1016*9d26e4fcSRobert Mustacchi 	/* get the address from the struct field */
1017*9d26e4fcSRobert Mustacchi 	target = dest + ce_info->offset;
1018*9d26e4fcSRobert Mustacchi 
1019*9d26e4fcSRobert Mustacchi 	/* put it back in the struct */
1020*9d26e4fcSRobert Mustacchi 	i40e_memcpy(target, &dest_word, sizeof(dest_word), I40E_NONDMA_TO_DMA);
1021*9d26e4fcSRobert Mustacchi }
1022*9d26e4fcSRobert Mustacchi 
1023*9d26e4fcSRobert Mustacchi /**
1024*9d26e4fcSRobert Mustacchi  * i40e_read_dword - read HMC context dword into struct
1025*9d26e4fcSRobert Mustacchi  * @hmc_bits: pointer to the HMC memory
1026*9d26e4fcSRobert Mustacchi  * @ce_info: a description of the struct to be filled
1027*9d26e4fcSRobert Mustacchi  * @dest: the struct to be filled
1028*9d26e4fcSRobert Mustacchi  **/
1029*9d26e4fcSRobert Mustacchi static void i40e_read_dword(u8 *hmc_bits,
1030*9d26e4fcSRobert Mustacchi 			    struct i40e_context_ele *ce_info,
1031*9d26e4fcSRobert Mustacchi 			    u8 *dest)
1032*9d26e4fcSRobert Mustacchi {
1033*9d26e4fcSRobert Mustacchi 	u32 dest_dword, mask;
1034*9d26e4fcSRobert Mustacchi 	u8 *src, *target;
1035*9d26e4fcSRobert Mustacchi 	u16 shift_width;
1036*9d26e4fcSRobert Mustacchi 	__le32 src_dword;
1037*9d26e4fcSRobert Mustacchi 
1038*9d26e4fcSRobert Mustacchi 	/* prepare the bits and mask */
1039*9d26e4fcSRobert Mustacchi 	shift_width = ce_info->lsb % 8;
1040*9d26e4fcSRobert Mustacchi 
1041*9d26e4fcSRobert Mustacchi 	/* if the field width is exactly 32 on an x86 machine, then the shift
1042*9d26e4fcSRobert Mustacchi 	 * operation will not work because the SHL instructions count is masked
1043*9d26e4fcSRobert Mustacchi 	 * to 5 bits so the shift will do nothing
1044*9d26e4fcSRobert Mustacchi 	 */
1045*9d26e4fcSRobert Mustacchi 	if (ce_info->width < 32)
1046*9d26e4fcSRobert Mustacchi 		mask = BIT(ce_info->width) - 1;
1047*9d26e4fcSRobert Mustacchi 	else
1048*9d26e4fcSRobert Mustacchi 		mask = ~(u32)0;
1049*9d26e4fcSRobert Mustacchi 
1050*9d26e4fcSRobert Mustacchi 	/* shift to correct alignment */
1051*9d26e4fcSRobert Mustacchi 	mask <<= shift_width;
1052*9d26e4fcSRobert Mustacchi 
1053*9d26e4fcSRobert Mustacchi 	/* get the current bits from the src bit string */
1054*9d26e4fcSRobert Mustacchi 	src = hmc_bits + (ce_info->lsb / 8);
1055*9d26e4fcSRobert Mustacchi 
1056*9d26e4fcSRobert Mustacchi 	i40e_memcpy(&src_dword, src, sizeof(src_dword), I40E_DMA_TO_NONDMA);
1057*9d26e4fcSRobert Mustacchi 
1058*9d26e4fcSRobert Mustacchi 	/* the data in the memory is stored as little endian so mask it
1059*9d26e4fcSRobert Mustacchi 	 * correctly
1060*9d26e4fcSRobert Mustacchi 	 */
1061*9d26e4fcSRobert Mustacchi 	src_dword &= ~(CPU_TO_LE32(mask));
1062*9d26e4fcSRobert Mustacchi 
1063*9d26e4fcSRobert Mustacchi 	/* get the data back into host order before shifting */
1064*9d26e4fcSRobert Mustacchi 	dest_dword = LE32_TO_CPU(src_dword);
1065*9d26e4fcSRobert Mustacchi 
1066*9d26e4fcSRobert Mustacchi 	dest_dword >>= shift_width;
1067*9d26e4fcSRobert Mustacchi 
1068*9d26e4fcSRobert Mustacchi 	/* get the address from the struct field */
1069*9d26e4fcSRobert Mustacchi 	target = dest + ce_info->offset;
1070*9d26e4fcSRobert Mustacchi 
1071*9d26e4fcSRobert Mustacchi 	/* put it back in the struct */
1072*9d26e4fcSRobert Mustacchi 	i40e_memcpy(target, &dest_dword, sizeof(dest_dword),
1073*9d26e4fcSRobert Mustacchi 		    I40E_NONDMA_TO_DMA);
1074*9d26e4fcSRobert Mustacchi }
1075*9d26e4fcSRobert Mustacchi 
1076*9d26e4fcSRobert Mustacchi /**
1077*9d26e4fcSRobert Mustacchi  * i40e_read_qword - read HMC context qword into struct
1078*9d26e4fcSRobert Mustacchi  * @hmc_bits: pointer to the HMC memory
1079*9d26e4fcSRobert Mustacchi  * @ce_info: a description of the struct to be filled
1080*9d26e4fcSRobert Mustacchi  * @dest: the struct to be filled
1081*9d26e4fcSRobert Mustacchi  **/
1082*9d26e4fcSRobert Mustacchi static void i40e_read_qword(u8 *hmc_bits,
1083*9d26e4fcSRobert Mustacchi 			    struct i40e_context_ele *ce_info,
1084*9d26e4fcSRobert Mustacchi 			    u8 *dest)
1085*9d26e4fcSRobert Mustacchi {
1086*9d26e4fcSRobert Mustacchi 	u64 dest_qword, mask;
1087*9d26e4fcSRobert Mustacchi 	u8 *src, *target;
1088*9d26e4fcSRobert Mustacchi 	u16 shift_width;
1089*9d26e4fcSRobert Mustacchi 	__le64 src_qword;
1090*9d26e4fcSRobert Mustacchi 
1091*9d26e4fcSRobert Mustacchi 	/* prepare the bits and mask */
1092*9d26e4fcSRobert Mustacchi 	shift_width = ce_info->lsb % 8;
1093*9d26e4fcSRobert Mustacchi 
1094*9d26e4fcSRobert Mustacchi 	/* if the field width is exactly 64 on an x86 machine, then the shift
1095*9d26e4fcSRobert Mustacchi 	 * operation will not work because the SHL instructions count is masked
1096*9d26e4fcSRobert Mustacchi 	 * to 6 bits so the shift will do nothing
1097*9d26e4fcSRobert Mustacchi 	 */
1098*9d26e4fcSRobert Mustacchi 	if (ce_info->width < 64)
1099*9d26e4fcSRobert Mustacchi 		mask = BIT_ULL(ce_info->width) - 1;
1100*9d26e4fcSRobert Mustacchi 	else
1101*9d26e4fcSRobert Mustacchi 		mask = ~(u64)0;
1102*9d26e4fcSRobert Mustacchi 
1103*9d26e4fcSRobert Mustacchi 	/* shift to correct alignment */
1104*9d26e4fcSRobert Mustacchi 	mask <<= shift_width;
1105*9d26e4fcSRobert Mustacchi 
1106*9d26e4fcSRobert Mustacchi 	/* get the current bits from the src bit string */
1107*9d26e4fcSRobert Mustacchi 	src = hmc_bits + (ce_info->lsb / 8);
1108*9d26e4fcSRobert Mustacchi 
1109*9d26e4fcSRobert Mustacchi 	i40e_memcpy(&src_qword, src, sizeof(src_qword), I40E_DMA_TO_NONDMA);
1110*9d26e4fcSRobert Mustacchi 
1111*9d26e4fcSRobert Mustacchi 	/* the data in the memory is stored as little endian so mask it
1112*9d26e4fcSRobert Mustacchi 	 * correctly
1113*9d26e4fcSRobert Mustacchi 	 */
1114*9d26e4fcSRobert Mustacchi 	src_qword &= ~(CPU_TO_LE64(mask));
1115*9d26e4fcSRobert Mustacchi 
1116*9d26e4fcSRobert Mustacchi 	/* get the data back into host order before shifting */
1117*9d26e4fcSRobert Mustacchi 	dest_qword = LE64_TO_CPU(src_qword);
1118*9d26e4fcSRobert Mustacchi 
1119*9d26e4fcSRobert Mustacchi 	dest_qword >>= shift_width;
1120*9d26e4fcSRobert Mustacchi 
1121*9d26e4fcSRobert Mustacchi 	/* get the address from the struct field */
1122*9d26e4fcSRobert Mustacchi 	target = dest + ce_info->offset;
1123*9d26e4fcSRobert Mustacchi 
1124*9d26e4fcSRobert Mustacchi 	/* put it back in the struct */
1125*9d26e4fcSRobert Mustacchi 	i40e_memcpy(target, &dest_qword, sizeof(dest_qword),
1126*9d26e4fcSRobert Mustacchi 		    I40E_NONDMA_TO_DMA);
1127*9d26e4fcSRobert Mustacchi }
1128*9d26e4fcSRobert Mustacchi 
1129*9d26e4fcSRobert Mustacchi /**
1130*9d26e4fcSRobert Mustacchi  * i40e_get_hmc_context - extract HMC context bits
1131*9d26e4fcSRobert Mustacchi  * @context_bytes: pointer to the context bit array
1132*9d26e4fcSRobert Mustacchi  * @ce_info: a description of the struct to be filled
1133*9d26e4fcSRobert Mustacchi  * @dest: the struct to be filled
1134*9d26e4fcSRobert Mustacchi  **/
1135*9d26e4fcSRobert Mustacchi static enum i40e_status_code i40e_get_hmc_context(u8 *context_bytes,
1136*9d26e4fcSRobert Mustacchi 					struct i40e_context_ele *ce_info,
1137*9d26e4fcSRobert Mustacchi 					u8 *dest)
1138*9d26e4fcSRobert Mustacchi {
1139*9d26e4fcSRobert Mustacchi 	int f;
1140*9d26e4fcSRobert Mustacchi 
1141*9d26e4fcSRobert Mustacchi 	for (f = 0; ce_info[f].width != 0; f++) {
1142*9d26e4fcSRobert Mustacchi 		switch (ce_info[f].size_of) {
1143*9d26e4fcSRobert Mustacchi 		case 1:
1144*9d26e4fcSRobert Mustacchi 			i40e_read_byte(context_bytes, &ce_info[f], dest);
1145*9d26e4fcSRobert Mustacchi 			break;
1146*9d26e4fcSRobert Mustacchi 		case 2:
1147*9d26e4fcSRobert Mustacchi 			i40e_read_word(context_bytes, &ce_info[f], dest);
1148*9d26e4fcSRobert Mustacchi 			break;
1149*9d26e4fcSRobert Mustacchi 		case 4:
1150*9d26e4fcSRobert Mustacchi 			i40e_read_dword(context_bytes, &ce_info[f], dest);
1151*9d26e4fcSRobert Mustacchi 			break;
1152*9d26e4fcSRobert Mustacchi 		case 8:
1153*9d26e4fcSRobert Mustacchi 			i40e_read_qword(context_bytes, &ce_info[f], dest);
1154*9d26e4fcSRobert Mustacchi 			break;
1155*9d26e4fcSRobert Mustacchi 		default:
1156*9d26e4fcSRobert Mustacchi 			/* nothing to do, just keep going */
1157*9d26e4fcSRobert Mustacchi 			break;
1158*9d26e4fcSRobert Mustacchi 		}
1159*9d26e4fcSRobert Mustacchi 	}
1160*9d26e4fcSRobert Mustacchi 
1161*9d26e4fcSRobert Mustacchi 	return I40E_SUCCESS;
1162*9d26e4fcSRobert Mustacchi }
1163*9d26e4fcSRobert Mustacchi 
1164*9d26e4fcSRobert Mustacchi /**
1165*9d26e4fcSRobert Mustacchi  * i40e_clear_hmc_context - zero out the HMC context bits
1166*9d26e4fcSRobert Mustacchi  * @hw:       the hardware struct
1167*9d26e4fcSRobert Mustacchi  * @context_bytes: pointer to the context bit array (DMA memory)
1168*9d26e4fcSRobert Mustacchi  * @hmc_type: the type of HMC resource
1169*9d26e4fcSRobert Mustacchi  **/
1170*9d26e4fcSRobert Mustacchi static enum i40e_status_code i40e_clear_hmc_context(struct i40e_hw *hw,
1171*9d26e4fcSRobert Mustacchi 					u8 *context_bytes,
1172*9d26e4fcSRobert Mustacchi 					enum i40e_hmc_lan_rsrc_type hmc_type)
1173*9d26e4fcSRobert Mustacchi {
1174*9d26e4fcSRobert Mustacchi 	/* clean the bit array */
1175*9d26e4fcSRobert Mustacchi 	i40e_memset(context_bytes, 0, (u32)hw->hmc.hmc_obj[hmc_type].size,
1176*9d26e4fcSRobert Mustacchi 		    I40E_DMA_MEM);
1177*9d26e4fcSRobert Mustacchi 
1178*9d26e4fcSRobert Mustacchi 	return I40E_SUCCESS;
1179*9d26e4fcSRobert Mustacchi }
1180*9d26e4fcSRobert Mustacchi 
1181*9d26e4fcSRobert Mustacchi /**
1182*9d26e4fcSRobert Mustacchi  * i40e_set_hmc_context - replace HMC context bits
1183*9d26e4fcSRobert Mustacchi  * @context_bytes: pointer to the context bit array
1184*9d26e4fcSRobert Mustacchi  * @ce_info:  a description of the struct to be filled
1185*9d26e4fcSRobert Mustacchi  * @dest:     the struct to be filled
1186*9d26e4fcSRobert Mustacchi  **/
1187*9d26e4fcSRobert Mustacchi static enum i40e_status_code i40e_set_hmc_context(u8 *context_bytes,
1188*9d26e4fcSRobert Mustacchi 					struct i40e_context_ele *ce_info,
1189*9d26e4fcSRobert Mustacchi 					u8 *dest)
1190*9d26e4fcSRobert Mustacchi {
1191*9d26e4fcSRobert Mustacchi 	int f;
1192*9d26e4fcSRobert Mustacchi 
1193*9d26e4fcSRobert Mustacchi 	for (f = 0; ce_info[f].width != 0; f++) {
1194*9d26e4fcSRobert Mustacchi 
1195*9d26e4fcSRobert Mustacchi 		/* we have to deal with each element of the HMC using the
1196*9d26e4fcSRobert Mustacchi 		 * correct size so that we are correct regardless of the
1197*9d26e4fcSRobert Mustacchi 		 * endianness of the machine
1198*9d26e4fcSRobert Mustacchi 		 */
1199*9d26e4fcSRobert Mustacchi 		switch (ce_info[f].size_of) {
1200*9d26e4fcSRobert Mustacchi 		case 1:
1201*9d26e4fcSRobert Mustacchi 			i40e_write_byte(context_bytes, &ce_info[f], dest);
1202*9d26e4fcSRobert Mustacchi 			break;
1203*9d26e4fcSRobert Mustacchi 		case 2:
1204*9d26e4fcSRobert Mustacchi 			i40e_write_word(context_bytes, &ce_info[f], dest);
1205*9d26e4fcSRobert Mustacchi 			break;
1206*9d26e4fcSRobert Mustacchi 		case 4:
1207*9d26e4fcSRobert Mustacchi 			i40e_write_dword(context_bytes, &ce_info[f], dest);
1208*9d26e4fcSRobert Mustacchi 			break;
1209*9d26e4fcSRobert Mustacchi 		case 8:
1210*9d26e4fcSRobert Mustacchi 			i40e_write_qword(context_bytes, &ce_info[f], dest);
1211*9d26e4fcSRobert Mustacchi 			break;
1212*9d26e4fcSRobert Mustacchi 		}
1213*9d26e4fcSRobert Mustacchi 	}
1214*9d26e4fcSRobert Mustacchi 
1215*9d26e4fcSRobert Mustacchi 	return I40E_SUCCESS;
1216*9d26e4fcSRobert Mustacchi }
1217*9d26e4fcSRobert Mustacchi 
1218*9d26e4fcSRobert Mustacchi /**
1219*9d26e4fcSRobert Mustacchi  * i40e_hmc_get_object_va - retrieves an object's virtual address
1220*9d26e4fcSRobert Mustacchi  * @hw: pointer to the hw structure
1221*9d26e4fcSRobert Mustacchi  * @object_base: pointer to u64 to get the va
1222*9d26e4fcSRobert Mustacchi  * @rsrc_type: the hmc resource type
1223*9d26e4fcSRobert Mustacchi  * @obj_idx: hmc object index
1224*9d26e4fcSRobert Mustacchi  *
1225*9d26e4fcSRobert Mustacchi  * This function retrieves the object's virtual address from the object
1226*9d26e4fcSRobert Mustacchi  * base pointer.  This function is used for LAN Queue contexts.
1227*9d26e4fcSRobert Mustacchi  **/
1228*9d26e4fcSRobert Mustacchi static
1229*9d26e4fcSRobert Mustacchi enum i40e_status_code i40e_hmc_get_object_va(struct i40e_hw *hw,
1230*9d26e4fcSRobert Mustacchi 					u8 **object_base,
1231*9d26e4fcSRobert Mustacchi 					enum i40e_hmc_lan_rsrc_type rsrc_type,
1232*9d26e4fcSRobert Mustacchi 					u32 obj_idx)
1233*9d26e4fcSRobert Mustacchi {
1234*9d26e4fcSRobert Mustacchi 	u32 obj_offset_in_sd, obj_offset_in_pd;
1235*9d26e4fcSRobert Mustacchi 	struct i40e_hmc_info     *hmc_info = &hw->hmc;
1236*9d26e4fcSRobert Mustacchi 	struct i40e_hmc_sd_entry *sd_entry;
1237*9d26e4fcSRobert Mustacchi 	struct i40e_hmc_pd_entry *pd_entry;
1238*9d26e4fcSRobert Mustacchi 	u32 pd_idx, pd_lmt, rel_pd_idx;
1239*9d26e4fcSRobert Mustacchi 	enum i40e_status_code ret_code = I40E_SUCCESS;
1240*9d26e4fcSRobert Mustacchi 	u64 obj_offset_in_fpm;
1241*9d26e4fcSRobert Mustacchi 	u32 sd_idx, sd_lmt;
1242*9d26e4fcSRobert Mustacchi 
1243*9d26e4fcSRobert Mustacchi 	if (NULL == hmc_info) {
1244*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_BAD_PTR;
1245*9d26e4fcSRobert Mustacchi 		DEBUGOUT("i40e_hmc_get_object_va: bad hmc_info ptr\n");
1246*9d26e4fcSRobert Mustacchi 		goto exit;
1247*9d26e4fcSRobert Mustacchi 	}
1248*9d26e4fcSRobert Mustacchi 	if (NULL == hmc_info->hmc_obj) {
1249*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_BAD_PTR;
1250*9d26e4fcSRobert Mustacchi 		DEBUGOUT("i40e_hmc_get_object_va: bad hmc_info->hmc_obj ptr\n");
1251*9d26e4fcSRobert Mustacchi 		goto exit;
1252*9d26e4fcSRobert Mustacchi 	}
1253*9d26e4fcSRobert Mustacchi 	if (NULL == object_base) {
1254*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_BAD_PTR;
1255*9d26e4fcSRobert Mustacchi 		DEBUGOUT("i40e_hmc_get_object_va: bad object_base ptr\n");
1256*9d26e4fcSRobert Mustacchi 		goto exit;
1257*9d26e4fcSRobert Mustacchi 	}
1258*9d26e4fcSRobert Mustacchi 	if (I40E_HMC_INFO_SIGNATURE != hmc_info->signature) {
1259*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_BAD_PTR;
1260*9d26e4fcSRobert Mustacchi 		DEBUGOUT("i40e_hmc_get_object_va: bad hmc_info->signature\n");
1261*9d26e4fcSRobert Mustacchi 		goto exit;
1262*9d26e4fcSRobert Mustacchi 	}
1263*9d26e4fcSRobert Mustacchi 	if (obj_idx >= hmc_info->hmc_obj[rsrc_type].cnt) {
1264*9d26e4fcSRobert Mustacchi 		DEBUGOUT1("i40e_hmc_get_object_va: returns error %d\n",
1265*9d26e4fcSRobert Mustacchi 			  ret_code);
1266*9d26e4fcSRobert Mustacchi 		ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX;
1267*9d26e4fcSRobert Mustacchi 		goto exit;
1268*9d26e4fcSRobert Mustacchi 	}
1269*9d26e4fcSRobert Mustacchi 	/* find sd index and limit */
1270*9d26e4fcSRobert Mustacchi 	I40E_FIND_SD_INDEX_LIMIT(hmc_info, rsrc_type, obj_idx, 1,
1271*9d26e4fcSRobert Mustacchi 				 &sd_idx, &sd_lmt);
1272*9d26e4fcSRobert Mustacchi 
1273*9d26e4fcSRobert Mustacchi 	sd_entry = &hmc_info->sd_table.sd_entry[sd_idx];
1274*9d26e4fcSRobert Mustacchi 	obj_offset_in_fpm = hmc_info->hmc_obj[rsrc_type].base +
1275*9d26e4fcSRobert Mustacchi 			    hmc_info->hmc_obj[rsrc_type].size * obj_idx;
1276*9d26e4fcSRobert Mustacchi 
1277*9d26e4fcSRobert Mustacchi 	if (I40E_SD_TYPE_PAGED == sd_entry->entry_type) {
1278*9d26e4fcSRobert Mustacchi 		I40E_FIND_PD_INDEX_LIMIT(hmc_info, rsrc_type, obj_idx, 1,
1279*9d26e4fcSRobert Mustacchi 					 &pd_idx, &pd_lmt);
1280*9d26e4fcSRobert Mustacchi 		rel_pd_idx = pd_idx % I40E_HMC_PD_CNT_IN_SD;
1281*9d26e4fcSRobert Mustacchi 		pd_entry = &sd_entry->u.pd_table.pd_entry[rel_pd_idx];
1282*9d26e4fcSRobert Mustacchi 		obj_offset_in_pd = (u32)(obj_offset_in_fpm %
1283*9d26e4fcSRobert Mustacchi 					 I40E_HMC_PAGED_BP_SIZE);
1284*9d26e4fcSRobert Mustacchi 		*object_base = (u8 *)pd_entry->bp.addr.va + obj_offset_in_pd;
1285*9d26e4fcSRobert Mustacchi 	} else {
1286*9d26e4fcSRobert Mustacchi 		obj_offset_in_sd = (u32)(obj_offset_in_fpm %
1287*9d26e4fcSRobert Mustacchi 					 I40E_HMC_DIRECT_BP_SIZE);
1288*9d26e4fcSRobert Mustacchi 		*object_base = (u8 *)sd_entry->u.bp.addr.va + obj_offset_in_sd;
1289*9d26e4fcSRobert Mustacchi 	}
1290*9d26e4fcSRobert Mustacchi exit:
1291*9d26e4fcSRobert Mustacchi 	return ret_code;
1292*9d26e4fcSRobert Mustacchi }
1293*9d26e4fcSRobert Mustacchi 
1294*9d26e4fcSRobert Mustacchi /**
1295*9d26e4fcSRobert Mustacchi  * i40e_get_lan_tx_queue_context - return the HMC context for the queue
1296*9d26e4fcSRobert Mustacchi  * @hw:    the hardware struct
1297*9d26e4fcSRobert Mustacchi  * @queue: the queue we care about
1298*9d26e4fcSRobert Mustacchi  * @s:     the struct to be filled
1299*9d26e4fcSRobert Mustacchi  **/
1300*9d26e4fcSRobert Mustacchi enum i40e_status_code i40e_get_lan_tx_queue_context(struct i40e_hw *hw,
1301*9d26e4fcSRobert Mustacchi 						    u16 queue,
1302*9d26e4fcSRobert Mustacchi 						    struct i40e_hmc_obj_txq *s)
1303*9d26e4fcSRobert Mustacchi {
1304*9d26e4fcSRobert Mustacchi 	enum i40e_status_code err;
1305*9d26e4fcSRobert Mustacchi 	u8 *context_bytes;
1306*9d26e4fcSRobert Mustacchi 
1307*9d26e4fcSRobert Mustacchi 	err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_TX, queue);
1308*9d26e4fcSRobert Mustacchi 	if (err < 0)
1309*9d26e4fcSRobert Mustacchi 		return err;
1310*9d26e4fcSRobert Mustacchi 
1311*9d26e4fcSRobert Mustacchi 	return i40e_get_hmc_context(context_bytes,
1312*9d26e4fcSRobert Mustacchi 				    i40e_hmc_txq_ce_info, (u8 *)s);
1313*9d26e4fcSRobert Mustacchi }
1314*9d26e4fcSRobert Mustacchi 
1315*9d26e4fcSRobert Mustacchi /**
1316*9d26e4fcSRobert Mustacchi  * i40e_clear_lan_tx_queue_context - clear the HMC context for the queue
1317*9d26e4fcSRobert Mustacchi  * @hw:    the hardware struct
1318*9d26e4fcSRobert Mustacchi  * @queue: the queue we care about
1319*9d26e4fcSRobert Mustacchi  **/
1320*9d26e4fcSRobert Mustacchi enum i40e_status_code i40e_clear_lan_tx_queue_context(struct i40e_hw *hw,
1321*9d26e4fcSRobert Mustacchi 						      u16 queue)
1322*9d26e4fcSRobert Mustacchi {
1323*9d26e4fcSRobert Mustacchi 	enum i40e_status_code err;
1324*9d26e4fcSRobert Mustacchi 	u8 *context_bytes;
1325*9d26e4fcSRobert Mustacchi 
1326*9d26e4fcSRobert Mustacchi 	err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_TX, queue);
1327*9d26e4fcSRobert Mustacchi 	if (err < 0)
1328*9d26e4fcSRobert Mustacchi 		return err;
1329*9d26e4fcSRobert Mustacchi 
1330*9d26e4fcSRobert Mustacchi 	return i40e_clear_hmc_context(hw, context_bytes, I40E_HMC_LAN_TX);
1331*9d26e4fcSRobert Mustacchi }
1332*9d26e4fcSRobert Mustacchi 
1333*9d26e4fcSRobert Mustacchi /**
1334*9d26e4fcSRobert Mustacchi  * i40e_set_lan_tx_queue_context - set the HMC context for the queue
1335*9d26e4fcSRobert Mustacchi  * @hw:    the hardware struct
1336*9d26e4fcSRobert Mustacchi  * @queue: the queue we care about
1337*9d26e4fcSRobert Mustacchi  * @s:     the struct to be filled
1338*9d26e4fcSRobert Mustacchi  **/
1339*9d26e4fcSRobert Mustacchi enum i40e_status_code i40e_set_lan_tx_queue_context(struct i40e_hw *hw,
1340*9d26e4fcSRobert Mustacchi 						    u16 queue,
1341*9d26e4fcSRobert Mustacchi 						    struct i40e_hmc_obj_txq *s)
1342*9d26e4fcSRobert Mustacchi {
1343*9d26e4fcSRobert Mustacchi 	enum i40e_status_code err;
1344*9d26e4fcSRobert Mustacchi 	u8 *context_bytes;
1345*9d26e4fcSRobert Mustacchi 
1346*9d26e4fcSRobert Mustacchi 	err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_TX, queue);
1347*9d26e4fcSRobert Mustacchi 	if (err < 0)
1348*9d26e4fcSRobert Mustacchi 		return err;
1349*9d26e4fcSRobert Mustacchi 
1350*9d26e4fcSRobert Mustacchi 	return i40e_set_hmc_context(context_bytes,
1351*9d26e4fcSRobert Mustacchi 				    i40e_hmc_txq_ce_info, (u8 *)s);
1352*9d26e4fcSRobert Mustacchi }
1353*9d26e4fcSRobert Mustacchi 
1354*9d26e4fcSRobert Mustacchi /**
1355*9d26e4fcSRobert Mustacchi  * i40e_get_lan_rx_queue_context - return the HMC context for the queue
1356*9d26e4fcSRobert Mustacchi  * @hw:    the hardware struct
1357*9d26e4fcSRobert Mustacchi  * @queue: the queue we care about
1358*9d26e4fcSRobert Mustacchi  * @s:     the struct to be filled
1359*9d26e4fcSRobert Mustacchi  **/
1360*9d26e4fcSRobert Mustacchi enum i40e_status_code i40e_get_lan_rx_queue_context(struct i40e_hw *hw,
1361*9d26e4fcSRobert Mustacchi 						    u16 queue,
1362*9d26e4fcSRobert Mustacchi 						    struct i40e_hmc_obj_rxq *s)
1363*9d26e4fcSRobert Mustacchi {
1364*9d26e4fcSRobert Mustacchi 	enum i40e_status_code err;
1365*9d26e4fcSRobert Mustacchi 	u8 *context_bytes;
1366*9d26e4fcSRobert Mustacchi 
1367*9d26e4fcSRobert Mustacchi 	err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_RX, queue);
1368*9d26e4fcSRobert Mustacchi 	if (err < 0)
1369*9d26e4fcSRobert Mustacchi 		return err;
1370*9d26e4fcSRobert Mustacchi 
1371*9d26e4fcSRobert Mustacchi 	return i40e_get_hmc_context(context_bytes,
1372*9d26e4fcSRobert Mustacchi 				    i40e_hmc_rxq_ce_info, (u8 *)s);
1373*9d26e4fcSRobert Mustacchi }
1374*9d26e4fcSRobert Mustacchi 
1375*9d26e4fcSRobert Mustacchi /**
1376*9d26e4fcSRobert Mustacchi  * i40e_clear_lan_rx_queue_context - clear the HMC context for the queue
1377*9d26e4fcSRobert Mustacchi  * @hw:    the hardware struct
1378*9d26e4fcSRobert Mustacchi  * @queue: the queue we care about
1379*9d26e4fcSRobert Mustacchi  **/
1380*9d26e4fcSRobert Mustacchi enum i40e_status_code i40e_clear_lan_rx_queue_context(struct i40e_hw *hw,
1381*9d26e4fcSRobert Mustacchi 						      u16 queue)
1382*9d26e4fcSRobert Mustacchi {
1383*9d26e4fcSRobert Mustacchi 	enum i40e_status_code err;
1384*9d26e4fcSRobert Mustacchi 	u8 *context_bytes;
1385*9d26e4fcSRobert Mustacchi 
1386*9d26e4fcSRobert Mustacchi 	err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_RX, queue);
1387*9d26e4fcSRobert Mustacchi 	if (err < 0)
1388*9d26e4fcSRobert Mustacchi 		return err;
1389*9d26e4fcSRobert Mustacchi 
1390*9d26e4fcSRobert Mustacchi 	return i40e_clear_hmc_context(hw, context_bytes, I40E_HMC_LAN_RX);
1391*9d26e4fcSRobert Mustacchi }
1392*9d26e4fcSRobert Mustacchi 
1393*9d26e4fcSRobert Mustacchi /**
1394*9d26e4fcSRobert Mustacchi  * i40e_set_lan_rx_queue_context - set the HMC context for the queue
1395*9d26e4fcSRobert Mustacchi  * @hw:    the hardware struct
1396*9d26e4fcSRobert Mustacchi  * @queue: the queue we care about
1397*9d26e4fcSRobert Mustacchi  * @s:     the struct to be filled
1398*9d26e4fcSRobert Mustacchi  **/
1399*9d26e4fcSRobert Mustacchi enum i40e_status_code i40e_set_lan_rx_queue_context(struct i40e_hw *hw,
1400*9d26e4fcSRobert Mustacchi 						    u16 queue,
1401*9d26e4fcSRobert Mustacchi 						    struct i40e_hmc_obj_rxq *s)
1402*9d26e4fcSRobert Mustacchi {
1403*9d26e4fcSRobert Mustacchi 	enum i40e_status_code err;
1404*9d26e4fcSRobert Mustacchi 	u8 *context_bytes;
1405*9d26e4fcSRobert Mustacchi 
1406*9d26e4fcSRobert Mustacchi 	err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_RX, queue);
1407*9d26e4fcSRobert Mustacchi 	if (err < 0)
1408*9d26e4fcSRobert Mustacchi 		return err;
1409*9d26e4fcSRobert Mustacchi 
1410*9d26e4fcSRobert Mustacchi 	return i40e_set_hmc_context(context_bytes,
1411*9d26e4fcSRobert Mustacchi 				    i40e_hmc_rxq_ce_info, (u8 *)s);
1412*9d26e4fcSRobert Mustacchi }
1413