161ae650dSJack F Vogel /******************************************************************************
261ae650dSJack F Vogel
3f4cc2d17SEric Joyner Copyright (c) 2013-2018, Intel Corporation
461ae650dSJack F Vogel All rights reserved.
561ae650dSJack F Vogel
661ae650dSJack F Vogel Redistribution and use in source and binary forms, with or without
761ae650dSJack F Vogel modification, are permitted provided that the following conditions are met:
861ae650dSJack F Vogel
961ae650dSJack F Vogel 1. Redistributions of source code must retain the above copyright notice,
1061ae650dSJack F Vogel this list of conditions and the following disclaimer.
1161ae650dSJack F Vogel
1261ae650dSJack F Vogel 2. Redistributions in binary form must reproduce the above copyright
1361ae650dSJack F Vogel notice, this list of conditions and the following disclaimer in the
1461ae650dSJack F Vogel documentation and/or other materials provided with the distribution.
1561ae650dSJack F Vogel
1661ae650dSJack F Vogel 3. Neither the name of the Intel Corporation nor the names of its
1761ae650dSJack F Vogel contributors may be used to endorse or promote products derived from
1861ae650dSJack F Vogel this software without specific prior written permission.
1961ae650dSJack F Vogel
2061ae650dSJack F Vogel THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
2161ae650dSJack F Vogel AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2261ae650dSJack F Vogel IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2361ae650dSJack F Vogel ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
2461ae650dSJack F Vogel LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2561ae650dSJack F Vogel CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2661ae650dSJack F Vogel SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2761ae650dSJack F Vogel INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2861ae650dSJack F Vogel CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2961ae650dSJack F Vogel ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3061ae650dSJack F Vogel POSSIBILITY OF SUCH DAMAGE.
3161ae650dSJack F Vogel
3261ae650dSJack F Vogel ******************************************************************************/
3361ae650dSJack F Vogel
3461ae650dSJack F Vogel #include "i40e_osdep.h"
3561ae650dSJack F Vogel #include "i40e_register.h"
3661ae650dSJack F Vogel #include "i40e_type.h"
3761ae650dSJack F Vogel #include "i40e_hmc.h"
3861ae650dSJack F Vogel #include "i40e_lan_hmc.h"
3961ae650dSJack F Vogel #include "i40e_prototype.h"
4061ae650dSJack F Vogel
4161ae650dSJack F Vogel /* lan specific interface functions */
4261ae650dSJack F Vogel
4361ae650dSJack F Vogel /**
4461ae650dSJack F Vogel * i40e_align_l2obj_base - aligns base object pointer to 512 bytes
4561ae650dSJack F Vogel * @offset: base address offset needing alignment
4661ae650dSJack F Vogel *
4761ae650dSJack F Vogel * Aligns the layer 2 function private memory so it's 512-byte aligned.
4861ae650dSJack F Vogel **/
i40e_align_l2obj_base(u64 offset)4961ae650dSJack F Vogel static u64 i40e_align_l2obj_base(u64 offset)
5061ae650dSJack F Vogel {
5161ae650dSJack F Vogel u64 aligned_offset = offset;
5261ae650dSJack F Vogel
5361ae650dSJack F Vogel if ((offset % I40E_HMC_L2OBJ_BASE_ALIGNMENT) > 0)
5461ae650dSJack F Vogel aligned_offset += (I40E_HMC_L2OBJ_BASE_ALIGNMENT -
5561ae650dSJack F Vogel (offset % I40E_HMC_L2OBJ_BASE_ALIGNMENT));
5661ae650dSJack F Vogel
5761ae650dSJack F Vogel return aligned_offset;
5861ae650dSJack F Vogel }
5961ae650dSJack F Vogel
6061ae650dSJack F Vogel /**
6161ae650dSJack F Vogel * i40e_calculate_l2fpm_size - calculates layer 2 FPM memory size
6261ae650dSJack F Vogel * @txq_num: number of Tx queues needing backing context
6361ae650dSJack F Vogel * @rxq_num: number of Rx queues needing backing context
6461ae650dSJack F Vogel * @fcoe_cntx_num: amount of FCoE statefull contexts needing backing context
6561ae650dSJack F Vogel * @fcoe_filt_num: number of FCoE filters needing backing context
6661ae650dSJack F Vogel *
6761ae650dSJack F Vogel * Calculates the maximum amount of memory for the function required, based
6861ae650dSJack F Vogel * on the number of resources it must provide context for.
6961ae650dSJack F Vogel **/
i40e_calculate_l2fpm_size(u32 txq_num,u32 rxq_num,u32 fcoe_cntx_num,u32 fcoe_filt_num)7061ae650dSJack F Vogel u64 i40e_calculate_l2fpm_size(u32 txq_num, u32 rxq_num,
7161ae650dSJack F Vogel u32 fcoe_cntx_num, u32 fcoe_filt_num)
7261ae650dSJack F Vogel {
7361ae650dSJack F Vogel u64 fpm_size = 0;
7461ae650dSJack F Vogel
7561ae650dSJack F Vogel fpm_size = txq_num * I40E_HMC_OBJ_SIZE_TXQ;
7661ae650dSJack F Vogel fpm_size = i40e_align_l2obj_base(fpm_size);
7761ae650dSJack F Vogel
7861ae650dSJack F Vogel fpm_size += (rxq_num * I40E_HMC_OBJ_SIZE_RXQ);
7961ae650dSJack F Vogel fpm_size = i40e_align_l2obj_base(fpm_size);
8061ae650dSJack F Vogel
8161ae650dSJack F Vogel fpm_size += (fcoe_cntx_num * I40E_HMC_OBJ_SIZE_FCOE_CNTX);
8261ae650dSJack F Vogel fpm_size = i40e_align_l2obj_base(fpm_size);
8361ae650dSJack F Vogel
8461ae650dSJack F Vogel fpm_size += (fcoe_filt_num * I40E_HMC_OBJ_SIZE_FCOE_FILT);
8561ae650dSJack F Vogel fpm_size = i40e_align_l2obj_base(fpm_size);
8661ae650dSJack F Vogel
8761ae650dSJack F Vogel return fpm_size;
8861ae650dSJack F Vogel }
8961ae650dSJack F Vogel
9061ae650dSJack F Vogel /**
9161ae650dSJack F Vogel * i40e_init_lan_hmc - initialize i40e_hmc_info struct
9261ae650dSJack F Vogel * @hw: pointer to the HW structure
9361ae650dSJack F Vogel * @txq_num: number of Tx queues needing backing context
9461ae650dSJack F Vogel * @rxq_num: number of Rx queues needing backing context
9561ae650dSJack F Vogel * @fcoe_cntx_num: amount of FCoE statefull contexts needing backing context
9661ae650dSJack F Vogel * @fcoe_filt_num: number of FCoE filters needing backing context
9761ae650dSJack F Vogel *
9861ae650dSJack F Vogel * This function will be called once per physical function initialization.
9961ae650dSJack F Vogel * It will fill out the i40e_hmc_obj_info structure for LAN objects based on
10061ae650dSJack F Vogel * the driver's provided input, as well as information from the HMC itself
10161ae650dSJack F Vogel * loaded from NVRAM.
10261ae650dSJack F Vogel *
10361ae650dSJack F Vogel * Assumptions:
10461ae650dSJack F Vogel * - HMC Resource Profile has been selected before calling this function.
10561ae650dSJack F Vogel **/
i40e_init_lan_hmc(struct i40e_hw * hw,u32 txq_num,u32 rxq_num,u32 fcoe_cntx_num,u32 fcoe_filt_num)10661ae650dSJack F Vogel enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
10761ae650dSJack F Vogel u32 rxq_num, u32 fcoe_cntx_num,
10861ae650dSJack F Vogel u32 fcoe_filt_num)
10961ae650dSJack F Vogel {
11061ae650dSJack F Vogel struct i40e_hmc_obj_info *obj, *full_obj;
11161ae650dSJack F Vogel enum i40e_status_code ret_code = I40E_SUCCESS;
11261ae650dSJack F Vogel u64 l2fpm_size;
11361ae650dSJack F Vogel u32 size_exp;
11461ae650dSJack F Vogel
11561ae650dSJack F Vogel hw->hmc.signature = I40E_HMC_INFO_SIGNATURE;
11661ae650dSJack F Vogel hw->hmc.hmc_fn_id = hw->pf_id;
11761ae650dSJack F Vogel
11861ae650dSJack F Vogel /* allocate memory for hmc_obj */
11961ae650dSJack F Vogel ret_code = i40e_allocate_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem,
12061ae650dSJack F Vogel sizeof(struct i40e_hmc_obj_info) * I40E_HMC_LAN_MAX);
12161ae650dSJack F Vogel if (ret_code)
12261ae650dSJack F Vogel goto init_lan_hmc_out;
12361ae650dSJack F Vogel hw->hmc.hmc_obj = (struct i40e_hmc_obj_info *)
12461ae650dSJack F Vogel hw->hmc.hmc_obj_virt_mem.va;
12561ae650dSJack F Vogel
12661ae650dSJack F Vogel /* The full object will be used to create the LAN HMC SD */
12761ae650dSJack F Vogel full_obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_FULL];
12861ae650dSJack F Vogel full_obj->max_cnt = 0;
12961ae650dSJack F Vogel full_obj->cnt = 0;
13061ae650dSJack F Vogel full_obj->base = 0;
13161ae650dSJack F Vogel full_obj->size = 0;
13261ae650dSJack F Vogel
13361ae650dSJack F Vogel /* Tx queue context information */
13461ae650dSJack F Vogel obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX];
13561ae650dSJack F Vogel obj->max_cnt = rd32(hw, I40E_GLHMC_LANQMAX);
13661ae650dSJack F Vogel obj->cnt = txq_num;
13761ae650dSJack F Vogel obj->base = 0;
13861ae650dSJack F Vogel size_exp = rd32(hw, I40E_GLHMC_LANTXOBJSZ);
139be771cdaSJack F Vogel obj->size = BIT_ULL(size_exp);
14061ae650dSJack F Vogel
14161ae650dSJack F Vogel /* validate values requested by driver don't exceed HMC capacity */
14261ae650dSJack F Vogel if (txq_num > obj->max_cnt) {
14361ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
14461ae650dSJack F Vogel DEBUGOUT3("i40e_init_lan_hmc: Tx context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
14561ae650dSJack F Vogel txq_num, obj->max_cnt, ret_code);
146b4a7ce06SEric Joyner goto free_hmc_out;
14761ae650dSJack F Vogel }
14861ae650dSJack F Vogel
14961ae650dSJack F Vogel /* aggregate values into the full LAN object for later */
15061ae650dSJack F Vogel full_obj->max_cnt += obj->max_cnt;
15161ae650dSJack F Vogel full_obj->cnt += obj->cnt;
15261ae650dSJack F Vogel
15361ae650dSJack F Vogel /* Rx queue context information */
15461ae650dSJack F Vogel obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_RX];
15561ae650dSJack F Vogel obj->max_cnt = rd32(hw, I40E_GLHMC_LANQMAX);
15661ae650dSJack F Vogel obj->cnt = rxq_num;
15761ae650dSJack F Vogel obj->base = hw->hmc.hmc_obj[I40E_HMC_LAN_TX].base +
15861ae650dSJack F Vogel (hw->hmc.hmc_obj[I40E_HMC_LAN_TX].cnt *
15961ae650dSJack F Vogel hw->hmc.hmc_obj[I40E_HMC_LAN_TX].size);
16061ae650dSJack F Vogel obj->base = i40e_align_l2obj_base(obj->base);
16161ae650dSJack F Vogel size_exp = rd32(hw, I40E_GLHMC_LANRXOBJSZ);
162be771cdaSJack F Vogel obj->size = BIT_ULL(size_exp);
16361ae650dSJack F Vogel
16461ae650dSJack F Vogel /* validate values requested by driver don't exceed HMC capacity */
16561ae650dSJack F Vogel if (rxq_num > obj->max_cnt) {
16661ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
16761ae650dSJack F Vogel DEBUGOUT3("i40e_init_lan_hmc: Rx context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
16861ae650dSJack F Vogel rxq_num, obj->max_cnt, ret_code);
169b4a7ce06SEric Joyner goto free_hmc_out;
17061ae650dSJack F Vogel }
17161ae650dSJack F Vogel
17261ae650dSJack F Vogel /* aggregate values into the full LAN object for later */
17361ae650dSJack F Vogel full_obj->max_cnt += obj->max_cnt;
17461ae650dSJack F Vogel full_obj->cnt += obj->cnt;
17561ae650dSJack F Vogel
17661ae650dSJack F Vogel /* FCoE context information */
17761ae650dSJack F Vogel obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX];
17861ae650dSJack F Vogel obj->max_cnt = rd32(hw, I40E_GLHMC_FCOEMAX);
17961ae650dSJack F Vogel obj->cnt = fcoe_cntx_num;
18061ae650dSJack F Vogel obj->base = hw->hmc.hmc_obj[I40E_HMC_LAN_RX].base +
18161ae650dSJack F Vogel (hw->hmc.hmc_obj[I40E_HMC_LAN_RX].cnt *
18261ae650dSJack F Vogel hw->hmc.hmc_obj[I40E_HMC_LAN_RX].size);
18361ae650dSJack F Vogel obj->base = i40e_align_l2obj_base(obj->base);
18461ae650dSJack F Vogel size_exp = rd32(hw, I40E_GLHMC_FCOEDDPOBJSZ);
185be771cdaSJack F Vogel obj->size = BIT_ULL(size_exp);
18661ae650dSJack F Vogel
18761ae650dSJack F Vogel /* validate values requested by driver don't exceed HMC capacity */
18861ae650dSJack F Vogel if (fcoe_cntx_num > obj->max_cnt) {
18961ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
19061ae650dSJack F Vogel DEBUGOUT3("i40e_init_lan_hmc: FCoE context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
19161ae650dSJack F Vogel fcoe_cntx_num, obj->max_cnt, ret_code);
192b4a7ce06SEric Joyner goto free_hmc_out;
19361ae650dSJack F Vogel }
19461ae650dSJack F Vogel
19561ae650dSJack F Vogel /* aggregate values into the full LAN object for later */
19661ae650dSJack F Vogel full_obj->max_cnt += obj->max_cnt;
19761ae650dSJack F Vogel full_obj->cnt += obj->cnt;
19861ae650dSJack F Vogel
19961ae650dSJack F Vogel /* FCoE filter information */
20061ae650dSJack F Vogel obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_FILT];
20161ae650dSJack F Vogel obj->max_cnt = rd32(hw, I40E_GLHMC_FCOEFMAX);
20261ae650dSJack F Vogel obj->cnt = fcoe_filt_num;
20361ae650dSJack F Vogel obj->base = hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].base +
20461ae650dSJack F Vogel (hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].cnt *
20561ae650dSJack F Vogel hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].size);
20661ae650dSJack F Vogel obj->base = i40e_align_l2obj_base(obj->base);
20761ae650dSJack F Vogel size_exp = rd32(hw, I40E_GLHMC_FCOEFOBJSZ);
208be771cdaSJack F Vogel obj->size = BIT_ULL(size_exp);
20961ae650dSJack F Vogel
21061ae650dSJack F Vogel /* validate values requested by driver don't exceed HMC capacity */
21161ae650dSJack F Vogel if (fcoe_filt_num > obj->max_cnt) {
21261ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
21361ae650dSJack F Vogel DEBUGOUT3("i40e_init_lan_hmc: FCoE filter: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
21461ae650dSJack F Vogel fcoe_filt_num, obj->max_cnt, ret_code);
215b4a7ce06SEric Joyner goto free_hmc_out;
21661ae650dSJack F Vogel }
21761ae650dSJack F Vogel
21861ae650dSJack F Vogel /* aggregate values into the full LAN object for later */
21961ae650dSJack F Vogel full_obj->max_cnt += obj->max_cnt;
22061ae650dSJack F Vogel full_obj->cnt += obj->cnt;
22161ae650dSJack F Vogel
22261ae650dSJack F Vogel hw->hmc.first_sd_index = 0;
22361ae650dSJack F Vogel hw->hmc.sd_table.ref_cnt = 0;
22461ae650dSJack F Vogel l2fpm_size = i40e_calculate_l2fpm_size(txq_num, rxq_num, fcoe_cntx_num,
22561ae650dSJack F Vogel fcoe_filt_num);
22661ae650dSJack F Vogel if (NULL == hw->hmc.sd_table.sd_entry) {
22761ae650dSJack F Vogel hw->hmc.sd_table.sd_cnt = (u32)
22861ae650dSJack F Vogel (l2fpm_size + I40E_HMC_DIRECT_BP_SIZE - 1) /
22961ae650dSJack F Vogel I40E_HMC_DIRECT_BP_SIZE;
23061ae650dSJack F Vogel
23161ae650dSJack F Vogel /* allocate the sd_entry members in the sd_table */
23261ae650dSJack F Vogel ret_code = i40e_allocate_virt_mem(hw, &hw->hmc.sd_table.addr,
23361ae650dSJack F Vogel (sizeof(struct i40e_hmc_sd_entry) *
23461ae650dSJack F Vogel hw->hmc.sd_table.sd_cnt));
23561ae650dSJack F Vogel if (ret_code)
236b4a7ce06SEric Joyner goto free_hmc_out;
23761ae650dSJack F Vogel hw->hmc.sd_table.sd_entry =
23861ae650dSJack F Vogel (struct i40e_hmc_sd_entry *)hw->hmc.sd_table.addr.va;
23961ae650dSJack F Vogel }
24061ae650dSJack F Vogel /* store in the LAN full object for later */
24161ae650dSJack F Vogel full_obj->size = l2fpm_size;
24261ae650dSJack F Vogel
24361ae650dSJack F Vogel init_lan_hmc_out:
24461ae650dSJack F Vogel return ret_code;
245b4a7ce06SEric Joyner free_hmc_out:
246b4a7ce06SEric Joyner if (hw->hmc.hmc_obj_virt_mem.va)
247b4a7ce06SEric Joyner i40e_free_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem);
248b4a7ce06SEric Joyner
249b4a7ce06SEric Joyner return ret_code;
25061ae650dSJack F Vogel }
25161ae650dSJack F Vogel
25261ae650dSJack F Vogel /**
25361ae650dSJack F Vogel * i40e_remove_pd_page - Remove a page from the page descriptor table
25461ae650dSJack F Vogel * @hw: pointer to the HW structure
25561ae650dSJack F Vogel * @hmc_info: pointer to the HMC configuration information structure
25661ae650dSJack F Vogel * @idx: segment descriptor index to find the relevant page descriptor
25761ae650dSJack F Vogel *
25861ae650dSJack F Vogel * This function:
25961ae650dSJack F Vogel * 1. Marks the entry in pd table (for paged address mode) invalid
26061ae650dSJack F Vogel * 2. write to register PMPDINV to invalidate the backing page in FV cache
26161ae650dSJack F Vogel * 3. Decrement the ref count for pd_entry
26261ae650dSJack F Vogel * assumptions:
26361ae650dSJack F Vogel * 1. caller can deallocate the memory used by pd after this function
26461ae650dSJack F Vogel * returns.
26561ae650dSJack F Vogel **/
i40e_remove_pd_page(struct i40e_hw * hw,struct i40e_hmc_info * hmc_info,u32 idx)26661ae650dSJack F Vogel static enum i40e_status_code i40e_remove_pd_page(struct i40e_hw *hw,
26761ae650dSJack F Vogel struct i40e_hmc_info *hmc_info,
26861ae650dSJack F Vogel u32 idx)
26961ae650dSJack F Vogel {
27061ae650dSJack F Vogel enum i40e_status_code ret_code = I40E_SUCCESS;
27161ae650dSJack F Vogel
27261ae650dSJack F Vogel if (i40e_prep_remove_pd_page(hmc_info, idx) == I40E_SUCCESS)
27361ae650dSJack F Vogel ret_code = i40e_remove_pd_page_new(hw, hmc_info, idx, TRUE);
27461ae650dSJack F Vogel
27561ae650dSJack F Vogel return ret_code;
27661ae650dSJack F Vogel }
27761ae650dSJack F Vogel
27861ae650dSJack F Vogel /**
27961ae650dSJack F Vogel * i40e_remove_sd_bp - remove a backing page from a segment descriptor
28061ae650dSJack F Vogel * @hw: pointer to our HW structure
28161ae650dSJack F Vogel * @hmc_info: pointer to the HMC configuration information structure
28261ae650dSJack F Vogel * @idx: the page index
28361ae650dSJack F Vogel *
28461ae650dSJack F Vogel * This function:
28561ae650dSJack F Vogel * 1. Marks the entry in sd table (for direct address mode) invalid
28661ae650dSJack F Vogel * 2. write to register PMSDCMD, PMSDDATALOW(PMSDDATALOW.PMSDVALID set
28761ae650dSJack F Vogel * to 0) and PMSDDATAHIGH to invalidate the sd page
28861ae650dSJack F Vogel * 3. Decrement the ref count for the sd_entry
28961ae650dSJack F Vogel * assumptions:
29061ae650dSJack F Vogel * 1. caller can deallocate the memory used by backing storage after this
29161ae650dSJack F Vogel * function returns.
29261ae650dSJack F Vogel **/
i40e_remove_sd_bp(struct i40e_hw * hw,struct i40e_hmc_info * hmc_info,u32 idx)29361ae650dSJack F Vogel static enum i40e_status_code i40e_remove_sd_bp(struct i40e_hw *hw,
29461ae650dSJack F Vogel struct i40e_hmc_info *hmc_info,
29561ae650dSJack F Vogel u32 idx)
29661ae650dSJack F Vogel {
29761ae650dSJack F Vogel enum i40e_status_code ret_code = I40E_SUCCESS;
29861ae650dSJack F Vogel
29961ae650dSJack F Vogel if (i40e_prep_remove_sd_bp(hmc_info, idx) == I40E_SUCCESS)
30061ae650dSJack F Vogel ret_code = i40e_remove_sd_bp_new(hw, hmc_info, idx, TRUE);
30161ae650dSJack F Vogel
30261ae650dSJack F Vogel return ret_code;
30361ae650dSJack F Vogel }
30461ae650dSJack F Vogel
30561ae650dSJack F Vogel /**
30661ae650dSJack F Vogel * i40e_create_lan_hmc_object - allocate backing store for hmc objects
30761ae650dSJack F Vogel * @hw: pointer to the HW structure
30861ae650dSJack F Vogel * @info: pointer to i40e_hmc_create_obj_info struct
30961ae650dSJack F Vogel *
31061ae650dSJack F Vogel * This will allocate memory for PDs and backing pages and populate
31161ae650dSJack F Vogel * the sd and pd entries.
31261ae650dSJack F Vogel **/
i40e_create_lan_hmc_object(struct i40e_hw * hw,struct i40e_hmc_lan_create_obj_info * info)31361ae650dSJack F Vogel enum i40e_status_code i40e_create_lan_hmc_object(struct i40e_hw *hw,
31461ae650dSJack F Vogel struct i40e_hmc_lan_create_obj_info *info)
31561ae650dSJack F Vogel {
31661ae650dSJack F Vogel enum i40e_status_code ret_code = I40E_SUCCESS;
31761ae650dSJack F Vogel struct i40e_hmc_sd_entry *sd_entry;
31861ae650dSJack F Vogel u32 pd_idx1 = 0, pd_lmt1 = 0;
31961ae650dSJack F Vogel u32 pd_idx = 0, pd_lmt = 0;
32061ae650dSJack F Vogel bool pd_error = FALSE;
32161ae650dSJack F Vogel u32 sd_idx, sd_lmt;
32261ae650dSJack F Vogel u64 sd_size;
32361ae650dSJack F Vogel u32 i, j;
32461ae650dSJack F Vogel
32561ae650dSJack F Vogel if (NULL == info) {
32661ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR;
32761ae650dSJack F Vogel DEBUGOUT("i40e_create_lan_hmc_object: bad info ptr\n");
32861ae650dSJack F Vogel goto exit;
32961ae650dSJack F Vogel }
33061ae650dSJack F Vogel if (NULL == info->hmc_info) {
33161ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR;
33261ae650dSJack F Vogel DEBUGOUT("i40e_create_lan_hmc_object: bad hmc_info ptr\n");
33361ae650dSJack F Vogel goto exit;
33461ae650dSJack F Vogel }
33561ae650dSJack F Vogel if (I40E_HMC_INFO_SIGNATURE != info->hmc_info->signature) {
33661ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR;
33761ae650dSJack F Vogel DEBUGOUT("i40e_create_lan_hmc_object: bad signature\n");
33861ae650dSJack F Vogel goto exit;
33961ae650dSJack F Vogel }
34061ae650dSJack F Vogel
34161ae650dSJack F Vogel if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
34261ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX;
34361ae650dSJack F Vogel DEBUGOUT1("i40e_create_lan_hmc_object: returns error %d\n",
34461ae650dSJack F Vogel ret_code);
34561ae650dSJack F Vogel goto exit;
34661ae650dSJack F Vogel }
34761ae650dSJack F Vogel if ((info->start_idx + info->count) >
34861ae650dSJack F Vogel info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
34961ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
35061ae650dSJack F Vogel DEBUGOUT1("i40e_create_lan_hmc_object: returns error %d\n",
35161ae650dSJack F Vogel ret_code);
35261ae650dSJack F Vogel goto exit;
35361ae650dSJack F Vogel }
35461ae650dSJack F Vogel
35561ae650dSJack F Vogel /* find sd index and limit */
35661ae650dSJack F Vogel I40E_FIND_SD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
35761ae650dSJack F Vogel info->start_idx, info->count,
35861ae650dSJack F Vogel &sd_idx, &sd_lmt);
35961ae650dSJack F Vogel if (sd_idx >= info->hmc_info->sd_table.sd_cnt ||
36061ae650dSJack F Vogel sd_lmt > info->hmc_info->sd_table.sd_cnt) {
36161ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_SD_INDEX;
36261ae650dSJack F Vogel goto exit;
36361ae650dSJack F Vogel }
36461ae650dSJack F Vogel /* find pd index */
36561ae650dSJack F Vogel I40E_FIND_PD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
36661ae650dSJack F Vogel info->start_idx, info->count, &pd_idx,
36761ae650dSJack F Vogel &pd_lmt);
36861ae650dSJack F Vogel
36961ae650dSJack F Vogel /* This is to cover for cases where you may not want to have an SD with
37061ae650dSJack F Vogel * the full 2M memory but something smaller. By not filling out any
37161ae650dSJack F Vogel * size, the function will default the SD size to be 2M.
37261ae650dSJack F Vogel */
37361ae650dSJack F Vogel if (info->direct_mode_sz == 0)
37461ae650dSJack F Vogel sd_size = I40E_HMC_DIRECT_BP_SIZE;
37561ae650dSJack F Vogel else
37661ae650dSJack F Vogel sd_size = info->direct_mode_sz;
37761ae650dSJack F Vogel
37861ae650dSJack F Vogel /* check if all the sds are valid. If not, allocate a page and
37961ae650dSJack F Vogel * initialize it.
38061ae650dSJack F Vogel */
38161ae650dSJack F Vogel for (j = sd_idx; j < sd_lmt; j++) {
38261ae650dSJack F Vogel /* update the sd table entry */
38361ae650dSJack F Vogel ret_code = i40e_add_sd_table_entry(hw, info->hmc_info, j,
38461ae650dSJack F Vogel info->entry_type,
38561ae650dSJack F Vogel sd_size);
38661ae650dSJack F Vogel if (I40E_SUCCESS != ret_code)
38761ae650dSJack F Vogel goto exit_sd_error;
38861ae650dSJack F Vogel sd_entry = &info->hmc_info->sd_table.sd_entry[j];
38961ae650dSJack F Vogel if (I40E_SD_TYPE_PAGED == sd_entry->entry_type) {
39061ae650dSJack F Vogel /* check if all the pds in this sd are valid. If not,
39161ae650dSJack F Vogel * allocate a page and initialize it.
39261ae650dSJack F Vogel */
39361ae650dSJack F Vogel
39461ae650dSJack F Vogel /* find pd_idx and pd_lmt in this sd */
39561ae650dSJack F Vogel pd_idx1 = max(pd_idx, (j * I40E_HMC_MAX_BP_COUNT));
39661ae650dSJack F Vogel pd_lmt1 = min(pd_lmt,
39761ae650dSJack F Vogel ((j + 1) * I40E_HMC_MAX_BP_COUNT));
39861ae650dSJack F Vogel for (i = pd_idx1; i < pd_lmt1; i++) {
39961ae650dSJack F Vogel /* update the pd table entry */
40061ae650dSJack F Vogel ret_code = i40e_add_pd_table_entry(hw,
40161ae650dSJack F Vogel info->hmc_info,
402be771cdaSJack F Vogel i, NULL);
40361ae650dSJack F Vogel if (I40E_SUCCESS != ret_code) {
40461ae650dSJack F Vogel pd_error = TRUE;
40561ae650dSJack F Vogel break;
40661ae650dSJack F Vogel }
40761ae650dSJack F Vogel }
40861ae650dSJack F Vogel if (pd_error) {
40961ae650dSJack F Vogel /* remove the backing pages from pd_idx1 to i */
41061ae650dSJack F Vogel while (i && (i > pd_idx1)) {
41161ae650dSJack F Vogel i40e_remove_pd_bp(hw, info->hmc_info,
41261ae650dSJack F Vogel (i - 1));
41361ae650dSJack F Vogel i--;
41461ae650dSJack F Vogel }
41561ae650dSJack F Vogel }
41661ae650dSJack F Vogel }
41761ae650dSJack F Vogel if (!sd_entry->valid) {
41861ae650dSJack F Vogel sd_entry->valid = TRUE;
41961ae650dSJack F Vogel switch (sd_entry->entry_type) {
42061ae650dSJack F Vogel case I40E_SD_TYPE_PAGED:
42161ae650dSJack F Vogel I40E_SET_PF_SD_ENTRY(hw,
42261ae650dSJack F Vogel sd_entry->u.pd_table.pd_page_addr.pa,
42361ae650dSJack F Vogel j, sd_entry->entry_type);
42461ae650dSJack F Vogel break;
42561ae650dSJack F Vogel case I40E_SD_TYPE_DIRECT:
42661ae650dSJack F Vogel I40E_SET_PF_SD_ENTRY(hw, sd_entry->u.bp.addr.pa,
42761ae650dSJack F Vogel j, sd_entry->entry_type);
42861ae650dSJack F Vogel break;
42961ae650dSJack F Vogel default:
43061ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_SD_TYPE;
43161ae650dSJack F Vogel goto exit;
43261ae650dSJack F Vogel }
43361ae650dSJack F Vogel }
43461ae650dSJack F Vogel }
43561ae650dSJack F Vogel goto exit;
43661ae650dSJack F Vogel
43761ae650dSJack F Vogel exit_sd_error:
43861ae650dSJack F Vogel /* cleanup for sd entries from j to sd_idx */
43961ae650dSJack F Vogel while (j && (j > sd_idx)) {
44061ae650dSJack F Vogel sd_entry = &info->hmc_info->sd_table.sd_entry[j - 1];
44161ae650dSJack F Vogel switch (sd_entry->entry_type) {
44261ae650dSJack F Vogel case I40E_SD_TYPE_PAGED:
44361ae650dSJack F Vogel pd_idx1 = max(pd_idx,
44461ae650dSJack F Vogel ((j - 1) * I40E_HMC_MAX_BP_COUNT));
44561ae650dSJack F Vogel pd_lmt1 = min(pd_lmt, (j * I40E_HMC_MAX_BP_COUNT));
446be771cdaSJack F Vogel for (i = pd_idx1; i < pd_lmt1; i++)
44761ae650dSJack F Vogel i40e_remove_pd_bp(hw, info->hmc_info, i);
44861ae650dSJack F Vogel i40e_remove_pd_page(hw, info->hmc_info, (j - 1));
44961ae650dSJack F Vogel break;
45061ae650dSJack F Vogel case I40E_SD_TYPE_DIRECT:
45161ae650dSJack F Vogel i40e_remove_sd_bp(hw, info->hmc_info, (j - 1));
45261ae650dSJack F Vogel break;
45361ae650dSJack F Vogel default:
45461ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_SD_TYPE;
45561ae650dSJack F Vogel break;
45661ae650dSJack F Vogel }
45761ae650dSJack F Vogel j--;
45861ae650dSJack F Vogel }
45961ae650dSJack F Vogel exit:
46061ae650dSJack F Vogel return ret_code;
46161ae650dSJack F Vogel }
46261ae650dSJack F Vogel
46361ae650dSJack F Vogel /**
46461ae650dSJack F Vogel * i40e_configure_lan_hmc - prepare the HMC backing store
46561ae650dSJack F Vogel * @hw: pointer to the hw structure
46661ae650dSJack F Vogel * @model: the model for the layout of the SD/PD tables
46761ae650dSJack F Vogel *
46861ae650dSJack F Vogel * - This function will be called once per physical function initialization.
46961ae650dSJack F Vogel * - This function will be called after i40e_init_lan_hmc() and before
47061ae650dSJack F Vogel * any LAN/FCoE HMC objects can be created.
47161ae650dSJack F Vogel **/
i40e_configure_lan_hmc(struct i40e_hw * hw,enum i40e_hmc_model model)47261ae650dSJack F Vogel enum i40e_status_code i40e_configure_lan_hmc(struct i40e_hw *hw,
47361ae650dSJack F Vogel enum i40e_hmc_model model)
47461ae650dSJack F Vogel {
47561ae650dSJack F Vogel struct i40e_hmc_lan_create_obj_info info;
47661ae650dSJack F Vogel u8 hmc_fn_id = hw->hmc.hmc_fn_id;
47761ae650dSJack F Vogel struct i40e_hmc_obj_info *obj;
47861ae650dSJack F Vogel enum i40e_status_code ret_code = I40E_SUCCESS;
47961ae650dSJack F Vogel
48061ae650dSJack F Vogel /* Initialize part of the create object info struct */
48161ae650dSJack F Vogel info.hmc_info = &hw->hmc;
48261ae650dSJack F Vogel info.rsrc_type = I40E_HMC_LAN_FULL;
48361ae650dSJack F Vogel info.start_idx = 0;
48461ae650dSJack F Vogel info.direct_mode_sz = hw->hmc.hmc_obj[I40E_HMC_LAN_FULL].size;
48561ae650dSJack F Vogel
48661ae650dSJack F Vogel /* Build the SD entry for the LAN objects */
48761ae650dSJack F Vogel switch (model) {
48861ae650dSJack F Vogel case I40E_HMC_MODEL_DIRECT_PREFERRED:
48961ae650dSJack F Vogel case I40E_HMC_MODEL_DIRECT_ONLY:
49061ae650dSJack F Vogel info.entry_type = I40E_SD_TYPE_DIRECT;
49161ae650dSJack F Vogel /* Make one big object, a single SD */
49261ae650dSJack F Vogel info.count = 1;
49361ae650dSJack F Vogel ret_code = i40e_create_lan_hmc_object(hw, &info);
49461ae650dSJack F Vogel if ((ret_code != I40E_SUCCESS) && (model == I40E_HMC_MODEL_DIRECT_PREFERRED))
49561ae650dSJack F Vogel goto try_type_paged;
49661ae650dSJack F Vogel else if (ret_code != I40E_SUCCESS)
49761ae650dSJack F Vogel goto configure_lan_hmc_out;
49861ae650dSJack F Vogel /* else clause falls through the break */
49961ae650dSJack F Vogel break;
50061ae650dSJack F Vogel case I40E_HMC_MODEL_PAGED_ONLY:
50161ae650dSJack F Vogel try_type_paged:
50261ae650dSJack F Vogel info.entry_type = I40E_SD_TYPE_PAGED;
50361ae650dSJack F Vogel /* Make one big object in the PD table */
50461ae650dSJack F Vogel info.count = 1;
50561ae650dSJack F Vogel ret_code = i40e_create_lan_hmc_object(hw, &info);
50661ae650dSJack F Vogel if (ret_code != I40E_SUCCESS)
50761ae650dSJack F Vogel goto configure_lan_hmc_out;
50861ae650dSJack F Vogel break;
50961ae650dSJack F Vogel default:
51061ae650dSJack F Vogel /* unsupported type */
51161ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_SD_TYPE;
51261ae650dSJack F Vogel DEBUGOUT1("i40e_configure_lan_hmc: Unknown SD type: %d\n",
51361ae650dSJack F Vogel ret_code);
51461ae650dSJack F Vogel goto configure_lan_hmc_out;
51561ae650dSJack F Vogel }
51661ae650dSJack F Vogel
51761ae650dSJack F Vogel /* Configure and program the FPM registers so objects can be created */
51861ae650dSJack F Vogel
51961ae650dSJack F Vogel /* Tx contexts */
52061ae650dSJack F Vogel obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX];
52161ae650dSJack F Vogel wr32(hw, I40E_GLHMC_LANTXBASE(hmc_fn_id),
52261ae650dSJack F Vogel (u32)((obj->base & I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK) / 512));
52361ae650dSJack F Vogel wr32(hw, I40E_GLHMC_LANTXCNT(hmc_fn_id), obj->cnt);
52461ae650dSJack F Vogel
52561ae650dSJack F Vogel /* Rx contexts */
52661ae650dSJack F Vogel obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_RX];
52761ae650dSJack F Vogel wr32(hw, I40E_GLHMC_LANRXBASE(hmc_fn_id),
52861ae650dSJack F Vogel (u32)((obj->base & I40E_GLHMC_LANRXBASE_FPMLANRXBASE_MASK) / 512));
52961ae650dSJack F Vogel wr32(hw, I40E_GLHMC_LANRXCNT(hmc_fn_id), obj->cnt);
53061ae650dSJack F Vogel
53161ae650dSJack F Vogel /* FCoE contexts */
53261ae650dSJack F Vogel obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX];
53361ae650dSJack F Vogel wr32(hw, I40E_GLHMC_FCOEDDPBASE(hmc_fn_id),
53461ae650dSJack F Vogel (u32)((obj->base & I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_MASK) / 512));
53561ae650dSJack F Vogel wr32(hw, I40E_GLHMC_FCOEDDPCNT(hmc_fn_id), obj->cnt);
53661ae650dSJack F Vogel
53761ae650dSJack F Vogel /* FCoE filters */
53861ae650dSJack F Vogel obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_FILT];
53961ae650dSJack F Vogel wr32(hw, I40E_GLHMC_FCOEFBASE(hmc_fn_id),
54061ae650dSJack F Vogel (u32)((obj->base & I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_MASK) / 512));
54161ae650dSJack F Vogel wr32(hw, I40E_GLHMC_FCOEFCNT(hmc_fn_id), obj->cnt);
54261ae650dSJack F Vogel
54361ae650dSJack F Vogel configure_lan_hmc_out:
54461ae650dSJack F Vogel return ret_code;
54561ae650dSJack F Vogel }
54661ae650dSJack F Vogel
54761ae650dSJack F Vogel /**
548*abf77452SKrzysztof Galazka * i40e_delete_lan_hmc_object - remove hmc objects
54961ae650dSJack F Vogel * @hw: pointer to the HW structure
55061ae650dSJack F Vogel * @info: pointer to i40e_hmc_delete_obj_info struct
55161ae650dSJack F Vogel *
55261ae650dSJack F Vogel * This will de-populate the SDs and PDs. It frees
55361ae650dSJack F Vogel * the memory for PDS and backing storage. After this function is returned,
55461ae650dSJack F Vogel * caller should deallocate memory allocated previously for
55561ae650dSJack F Vogel * book-keeping information about PDs and backing storage.
55661ae650dSJack F Vogel **/
i40e_delete_lan_hmc_object(struct i40e_hw * hw,struct i40e_hmc_lan_delete_obj_info * info)55761ae650dSJack F Vogel enum i40e_status_code i40e_delete_lan_hmc_object(struct i40e_hw *hw,
55861ae650dSJack F Vogel struct i40e_hmc_lan_delete_obj_info *info)
55961ae650dSJack F Vogel {
56061ae650dSJack F Vogel enum i40e_status_code ret_code = I40E_SUCCESS;
56161ae650dSJack F Vogel struct i40e_hmc_pd_table *pd_table;
56261ae650dSJack F Vogel u32 pd_idx, pd_lmt, rel_pd_idx;
56361ae650dSJack F Vogel u32 sd_idx, sd_lmt;
56461ae650dSJack F Vogel u32 i, j;
56561ae650dSJack F Vogel
56661ae650dSJack F Vogel if (NULL == info) {
56761ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR;
56861ae650dSJack F Vogel DEBUGOUT("i40e_delete_hmc_object: bad info ptr\n");
56961ae650dSJack F Vogel goto exit;
57061ae650dSJack F Vogel }
57161ae650dSJack F Vogel if (NULL == info->hmc_info) {
57261ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR;
57361ae650dSJack F Vogel DEBUGOUT("i40e_delete_hmc_object: bad info->hmc_info ptr\n");
57461ae650dSJack F Vogel goto exit;
57561ae650dSJack F Vogel }
57661ae650dSJack F Vogel if (I40E_HMC_INFO_SIGNATURE != info->hmc_info->signature) {
57761ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR;
57861ae650dSJack F Vogel DEBUGOUT("i40e_delete_hmc_object: bad hmc_info->signature\n");
57961ae650dSJack F Vogel goto exit;
58061ae650dSJack F Vogel }
58161ae650dSJack F Vogel
58261ae650dSJack F Vogel if (NULL == info->hmc_info->sd_table.sd_entry) {
58361ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR;
58461ae650dSJack F Vogel DEBUGOUT("i40e_delete_hmc_object: bad sd_entry\n");
58561ae650dSJack F Vogel goto exit;
58661ae650dSJack F Vogel }
58761ae650dSJack F Vogel
58861ae650dSJack F Vogel if (NULL == info->hmc_info->hmc_obj) {
58961ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR;
59061ae650dSJack F Vogel DEBUGOUT("i40e_delete_hmc_object: bad hmc_info->hmc_obj\n");
59161ae650dSJack F Vogel goto exit;
59261ae650dSJack F Vogel }
59361ae650dSJack F Vogel if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
59461ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX;
59561ae650dSJack F Vogel DEBUGOUT1("i40e_delete_hmc_object: returns error %d\n",
59661ae650dSJack F Vogel ret_code);
59761ae650dSJack F Vogel goto exit;
59861ae650dSJack F Vogel }
59961ae650dSJack F Vogel
60061ae650dSJack F Vogel if ((info->start_idx + info->count) >
60161ae650dSJack F Vogel info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
60261ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
60361ae650dSJack F Vogel DEBUGOUT1("i40e_delete_hmc_object: returns error %d\n",
60461ae650dSJack F Vogel ret_code);
60561ae650dSJack F Vogel goto exit;
60661ae650dSJack F Vogel }
60761ae650dSJack F Vogel
60861ae650dSJack F Vogel I40E_FIND_PD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
60961ae650dSJack F Vogel info->start_idx, info->count, &pd_idx,
61061ae650dSJack F Vogel &pd_lmt);
61161ae650dSJack F Vogel
61261ae650dSJack F Vogel for (j = pd_idx; j < pd_lmt; j++) {
61361ae650dSJack F Vogel sd_idx = j / I40E_HMC_PD_CNT_IN_SD;
61461ae650dSJack F Vogel
61561ae650dSJack F Vogel if (I40E_SD_TYPE_PAGED !=
61661ae650dSJack F Vogel info->hmc_info->sd_table.sd_entry[sd_idx].entry_type)
61761ae650dSJack F Vogel continue;
61861ae650dSJack F Vogel
61961ae650dSJack F Vogel rel_pd_idx = j % I40E_HMC_PD_CNT_IN_SD;
62061ae650dSJack F Vogel
62161ae650dSJack F Vogel pd_table =
62261ae650dSJack F Vogel &info->hmc_info->sd_table.sd_entry[sd_idx].u.pd_table;
62361ae650dSJack F Vogel if (pd_table->pd_entry[rel_pd_idx].valid) {
62461ae650dSJack F Vogel ret_code = i40e_remove_pd_bp(hw, info->hmc_info, j);
62561ae650dSJack F Vogel if (I40E_SUCCESS != ret_code)
62661ae650dSJack F Vogel goto exit;
62761ae650dSJack F Vogel }
62861ae650dSJack F Vogel }
62961ae650dSJack F Vogel
63061ae650dSJack F Vogel /* find sd index and limit */
63161ae650dSJack F Vogel I40E_FIND_SD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
63261ae650dSJack F Vogel info->start_idx, info->count,
63361ae650dSJack F Vogel &sd_idx, &sd_lmt);
63461ae650dSJack F Vogel if (sd_idx >= info->hmc_info->sd_table.sd_cnt ||
63561ae650dSJack F Vogel sd_lmt > info->hmc_info->sd_table.sd_cnt) {
63661ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_SD_INDEX;
63761ae650dSJack F Vogel goto exit;
63861ae650dSJack F Vogel }
63961ae650dSJack F Vogel
64061ae650dSJack F Vogel for (i = sd_idx; i < sd_lmt; i++) {
64161ae650dSJack F Vogel if (!info->hmc_info->sd_table.sd_entry[i].valid)
64261ae650dSJack F Vogel continue;
64361ae650dSJack F Vogel switch (info->hmc_info->sd_table.sd_entry[i].entry_type) {
64461ae650dSJack F Vogel case I40E_SD_TYPE_DIRECT:
64561ae650dSJack F Vogel ret_code = i40e_remove_sd_bp(hw, info->hmc_info, i);
64661ae650dSJack F Vogel if (I40E_SUCCESS != ret_code)
64761ae650dSJack F Vogel goto exit;
64861ae650dSJack F Vogel break;
64961ae650dSJack F Vogel case I40E_SD_TYPE_PAGED:
65061ae650dSJack F Vogel ret_code = i40e_remove_pd_page(hw, info->hmc_info, i);
65161ae650dSJack F Vogel if (I40E_SUCCESS != ret_code)
65261ae650dSJack F Vogel goto exit;
65361ae650dSJack F Vogel break;
65461ae650dSJack F Vogel default:
65561ae650dSJack F Vogel break;
65661ae650dSJack F Vogel }
65761ae650dSJack F Vogel }
65861ae650dSJack F Vogel exit:
65961ae650dSJack F Vogel return ret_code;
66061ae650dSJack F Vogel }
66161ae650dSJack F Vogel
66261ae650dSJack F Vogel /**
66361ae650dSJack F Vogel * i40e_shutdown_lan_hmc - Remove HMC backing store, free allocated memory
66461ae650dSJack F Vogel * @hw: pointer to the hw structure
66561ae650dSJack F Vogel *
66661ae650dSJack F Vogel * This must be called by drivers as they are shutting down and being
66761ae650dSJack F Vogel * removed from the OS.
66861ae650dSJack F Vogel **/
i40e_shutdown_lan_hmc(struct i40e_hw * hw)66961ae650dSJack F Vogel enum i40e_status_code i40e_shutdown_lan_hmc(struct i40e_hw *hw)
67061ae650dSJack F Vogel {
67161ae650dSJack F Vogel struct i40e_hmc_lan_delete_obj_info info;
67261ae650dSJack F Vogel enum i40e_status_code ret_code;
67361ae650dSJack F Vogel
67461ae650dSJack F Vogel info.hmc_info = &hw->hmc;
67561ae650dSJack F Vogel info.rsrc_type = I40E_HMC_LAN_FULL;
67661ae650dSJack F Vogel info.start_idx = 0;
67761ae650dSJack F Vogel info.count = 1;
67861ae650dSJack F Vogel
67961ae650dSJack F Vogel /* delete the object */
68061ae650dSJack F Vogel ret_code = i40e_delete_lan_hmc_object(hw, &info);
68161ae650dSJack F Vogel
68261ae650dSJack F Vogel /* free the SD table entry for LAN */
68361ae650dSJack F Vogel i40e_free_virt_mem(hw, &hw->hmc.sd_table.addr);
68461ae650dSJack F Vogel hw->hmc.sd_table.sd_cnt = 0;
68561ae650dSJack F Vogel hw->hmc.sd_table.sd_entry = NULL;
68661ae650dSJack F Vogel
68761ae650dSJack F Vogel /* free memory used for hmc_obj */
68861ae650dSJack F Vogel i40e_free_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem);
68961ae650dSJack F Vogel hw->hmc.hmc_obj = NULL;
69061ae650dSJack F Vogel
69161ae650dSJack F Vogel return ret_code;
69261ae650dSJack F Vogel }
69361ae650dSJack F Vogel
69461ae650dSJack F Vogel #define I40E_HMC_STORE(_struct, _ele) \
69561ae650dSJack F Vogel offsetof(struct _struct, _ele), \
69661ae650dSJack F Vogel FIELD_SIZEOF(struct _struct, _ele)
69761ae650dSJack F Vogel
69861ae650dSJack F Vogel struct i40e_context_ele {
69961ae650dSJack F Vogel u16 offset;
70061ae650dSJack F Vogel u16 size_of;
70161ae650dSJack F Vogel u16 width;
70261ae650dSJack F Vogel u16 lsb;
70361ae650dSJack F Vogel };
70461ae650dSJack F Vogel
70561ae650dSJack F Vogel /* LAN Tx Queue Context */
70661ae650dSJack F Vogel static struct i40e_context_ele i40e_hmc_txq_ce_info[] = {
70761ae650dSJack F Vogel /* Field Width LSB */
70861ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, head), 13, 0 },
70961ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, new_context), 1, 30 },
71061ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, base), 57, 32 },
71161ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, fc_ena), 1, 89 },
71261ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, timesync_ena), 1, 90 },
71361ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, fd_ena), 1, 91 },
71461ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, alt_vlan_ena), 1, 92 },
71561ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, cpuid), 8, 96 },
71661ae650dSJack F Vogel /* line 1 */
71761ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, thead_wb), 13, 0 + 128 },
71861ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, head_wb_ena), 1, 32 + 128 },
71961ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, qlen), 13, 33 + 128 },
72061ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, tphrdesc_ena), 1, 46 + 128 },
72161ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, tphrpacket_ena), 1, 47 + 128 },
72261ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, tphwdesc_ena), 1, 48 + 128 },
72361ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, head_wb_addr), 64, 64 + 128 },
72461ae650dSJack F Vogel /* line 7 */
72561ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, crc), 32, 0 + (7 * 128) },
72661ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, rdylist), 10, 84 + (7 * 128) },
72761ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, rdylist_act), 1, 94 + (7 * 128) },
72861ae650dSJack F Vogel { 0 }
72961ae650dSJack F Vogel };
73061ae650dSJack F Vogel
73161ae650dSJack F Vogel /* LAN Rx Queue Context */
73261ae650dSJack F Vogel static struct i40e_context_ele i40e_hmc_rxq_ce_info[] = {
73361ae650dSJack F Vogel /* Field Width LSB */
73461ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, head), 13, 0 },
73561ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, cpuid), 8, 13 },
73661ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, base), 57, 32 },
73761ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, qlen), 13, 89 },
73861ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, dbuff), 7, 102 },
73961ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, hbuff), 5, 109 },
74061ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, dtype), 2, 114 },
74161ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, dsize), 1, 116 },
74261ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, crcstrip), 1, 117 },
74361ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, fc_ena), 1, 118 },
74461ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, l2tsel), 1, 119 },
74561ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, hsplit_0), 4, 120 },
74661ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, hsplit_1), 2, 124 },
74761ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, showiv), 1, 127 },
74861ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, rxmax), 14, 174 },
74961ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphrdesc_ena), 1, 193 },
75061ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphwdesc_ena), 1, 194 },
75161ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphdata_ena), 1, 195 },
75261ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphhead_ena), 1, 196 },
75361ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, lrxqthresh), 3, 198 },
75461ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, prefena), 1, 201 },
75561ae650dSJack F Vogel { 0 }
75661ae650dSJack F Vogel };
75761ae650dSJack F Vogel
75861ae650dSJack F Vogel /**
75961ae650dSJack F Vogel * i40e_write_byte - replace HMC context byte
76061ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory
76161ae650dSJack F Vogel * @ce_info: a description of the struct to be read from
76261ae650dSJack F Vogel * @src: the struct to be read from
76361ae650dSJack F Vogel **/
i40e_write_byte(u8 * hmc_bits,struct i40e_context_ele * ce_info,u8 * src)76461ae650dSJack F Vogel static void i40e_write_byte(u8 *hmc_bits,
76561ae650dSJack F Vogel struct i40e_context_ele *ce_info,
76661ae650dSJack F Vogel u8 *src)
76761ae650dSJack F Vogel {
76861ae650dSJack F Vogel u8 src_byte, dest_byte, mask;
76961ae650dSJack F Vogel u8 *from, *dest;
77061ae650dSJack F Vogel u16 shift_width;
77161ae650dSJack F Vogel
77261ae650dSJack F Vogel /* copy from the next struct field */
77361ae650dSJack F Vogel from = src + ce_info->offset;
77461ae650dSJack F Vogel
77561ae650dSJack F Vogel /* prepare the bits and mask */
77661ae650dSJack F Vogel shift_width = ce_info->lsb % 8;
7777f70bec6SEric Joyner mask = (u8)(BIT(ce_info->width) - 1);
77861ae650dSJack F Vogel
77961ae650dSJack F Vogel src_byte = *from;
78061ae650dSJack F Vogel src_byte &= mask;
78161ae650dSJack F Vogel
78261ae650dSJack F Vogel /* shift to correct alignment */
78361ae650dSJack F Vogel mask <<= shift_width;
78461ae650dSJack F Vogel src_byte <<= shift_width;
78561ae650dSJack F Vogel
78661ae650dSJack F Vogel /* get the current bits from the target bit string */
78761ae650dSJack F Vogel dest = hmc_bits + (ce_info->lsb / 8);
78861ae650dSJack F Vogel
78961ae650dSJack F Vogel i40e_memcpy(&dest_byte, dest, sizeof(dest_byte), I40E_DMA_TO_NONDMA);
79061ae650dSJack F Vogel
79161ae650dSJack F Vogel dest_byte &= ~mask; /* get the bits not changing */
79261ae650dSJack F Vogel dest_byte |= src_byte; /* add in the new bits */
79361ae650dSJack F Vogel
79461ae650dSJack F Vogel /* put it all back */
79561ae650dSJack F Vogel i40e_memcpy(dest, &dest_byte, sizeof(dest_byte), I40E_NONDMA_TO_DMA);
79661ae650dSJack F Vogel }
79761ae650dSJack F Vogel
79861ae650dSJack F Vogel /**
79961ae650dSJack F Vogel * i40e_write_word - replace HMC context word
80061ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory
80161ae650dSJack F Vogel * @ce_info: a description of the struct to be read from
80261ae650dSJack F Vogel * @src: the struct to be read from
80361ae650dSJack F Vogel **/
i40e_write_word(u8 * hmc_bits,struct i40e_context_ele * ce_info,u8 * src)80461ae650dSJack F Vogel static void i40e_write_word(u8 *hmc_bits,
80561ae650dSJack F Vogel struct i40e_context_ele *ce_info,
80661ae650dSJack F Vogel u8 *src)
80761ae650dSJack F Vogel {
80861ae650dSJack F Vogel u16 src_word, mask;
80961ae650dSJack F Vogel u8 *from, *dest;
81061ae650dSJack F Vogel u16 shift_width;
81161ae650dSJack F Vogel __le16 dest_word;
81261ae650dSJack F Vogel
81361ae650dSJack F Vogel /* copy from the next struct field */
81461ae650dSJack F Vogel from = src + ce_info->offset;
81561ae650dSJack F Vogel
81661ae650dSJack F Vogel /* prepare the bits and mask */
81761ae650dSJack F Vogel shift_width = ce_info->lsb % 8;
818be771cdaSJack F Vogel mask = BIT(ce_info->width) - 1;
81961ae650dSJack F Vogel
82061ae650dSJack F Vogel /* don't swizzle the bits until after the mask because the mask bits
82161ae650dSJack F Vogel * will be in a different bit position on big endian machines
82261ae650dSJack F Vogel */
82361ae650dSJack F Vogel src_word = *(u16 *)from;
82461ae650dSJack F Vogel src_word &= mask;
82561ae650dSJack F Vogel
82661ae650dSJack F Vogel /* shift to correct alignment */
82761ae650dSJack F Vogel mask <<= shift_width;
82861ae650dSJack F Vogel src_word <<= shift_width;
82961ae650dSJack F Vogel
83061ae650dSJack F Vogel /* get the current bits from the target bit string */
83161ae650dSJack F Vogel dest = hmc_bits + (ce_info->lsb / 8);
83261ae650dSJack F Vogel
83361ae650dSJack F Vogel i40e_memcpy(&dest_word, dest, sizeof(dest_word), I40E_DMA_TO_NONDMA);
83461ae650dSJack F Vogel
83561ae650dSJack F Vogel dest_word &= ~(CPU_TO_LE16(mask)); /* get the bits not changing */
83661ae650dSJack F Vogel dest_word |= CPU_TO_LE16(src_word); /* add in the new bits */
83761ae650dSJack F Vogel
83861ae650dSJack F Vogel /* put it all back */
83961ae650dSJack F Vogel i40e_memcpy(dest, &dest_word, sizeof(dest_word), I40E_NONDMA_TO_DMA);
84061ae650dSJack F Vogel }
84161ae650dSJack F Vogel
84261ae650dSJack F Vogel /**
84361ae650dSJack F Vogel * i40e_write_dword - replace HMC context dword
84461ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory
84561ae650dSJack F Vogel * @ce_info: a description of the struct to be read from
84661ae650dSJack F Vogel * @src: the struct to be read from
84761ae650dSJack F Vogel **/
i40e_write_dword(u8 * hmc_bits,struct i40e_context_ele * ce_info,u8 * src)84861ae650dSJack F Vogel static void i40e_write_dword(u8 *hmc_bits,
84961ae650dSJack F Vogel struct i40e_context_ele *ce_info,
85061ae650dSJack F Vogel u8 *src)
85161ae650dSJack F Vogel {
85261ae650dSJack F Vogel u32 src_dword, mask;
85361ae650dSJack F Vogel u8 *from, *dest;
85461ae650dSJack F Vogel u16 shift_width;
85561ae650dSJack F Vogel __le32 dest_dword;
85661ae650dSJack F Vogel
85761ae650dSJack F Vogel /* copy from the next struct field */
85861ae650dSJack F Vogel from = src + ce_info->offset;
85961ae650dSJack F Vogel
86061ae650dSJack F Vogel /* prepare the bits and mask */
86161ae650dSJack F Vogel shift_width = ce_info->lsb % 8;
86261ae650dSJack F Vogel
86361ae650dSJack F Vogel /* if the field width is exactly 32 on an x86 machine, then the shift
86461ae650dSJack F Vogel * operation will not work because the SHL instructions count is masked
86561ae650dSJack F Vogel * to 5 bits so the shift will do nothing
86661ae650dSJack F Vogel */
86761ae650dSJack F Vogel if (ce_info->width < 32)
868be771cdaSJack F Vogel mask = BIT(ce_info->width) - 1;
86961ae650dSJack F Vogel else
870f247dc25SJack F Vogel mask = ~(u32)0;
87161ae650dSJack F Vogel
87261ae650dSJack F Vogel /* don't swizzle the bits until after the mask because the mask bits
87361ae650dSJack F Vogel * will be in a different bit position on big endian machines
87461ae650dSJack F Vogel */
87561ae650dSJack F Vogel src_dword = *(u32 *)from;
87661ae650dSJack F Vogel src_dword &= mask;
87761ae650dSJack F Vogel
87861ae650dSJack F Vogel /* shift to correct alignment */
87961ae650dSJack F Vogel mask <<= shift_width;
88061ae650dSJack F Vogel src_dword <<= shift_width;
88161ae650dSJack F Vogel
88261ae650dSJack F Vogel /* get the current bits from the target bit string */
88361ae650dSJack F Vogel dest = hmc_bits + (ce_info->lsb / 8);
88461ae650dSJack F Vogel
88561ae650dSJack F Vogel i40e_memcpy(&dest_dword, dest, sizeof(dest_dword), I40E_DMA_TO_NONDMA);
88661ae650dSJack F Vogel
88761ae650dSJack F Vogel dest_dword &= ~(CPU_TO_LE32(mask)); /* get the bits not changing */
88861ae650dSJack F Vogel dest_dword |= CPU_TO_LE32(src_dword); /* add in the new bits */
88961ae650dSJack F Vogel
89061ae650dSJack F Vogel /* put it all back */
89161ae650dSJack F Vogel i40e_memcpy(dest, &dest_dword, sizeof(dest_dword), I40E_NONDMA_TO_DMA);
89261ae650dSJack F Vogel }
89361ae650dSJack F Vogel
89461ae650dSJack F Vogel /**
89561ae650dSJack F Vogel * i40e_write_qword - replace HMC context qword
89661ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory
89761ae650dSJack F Vogel * @ce_info: a description of the struct to be read from
89861ae650dSJack F Vogel * @src: the struct to be read from
89961ae650dSJack F Vogel **/
i40e_write_qword(u8 * hmc_bits,struct i40e_context_ele * ce_info,u8 * src)90061ae650dSJack F Vogel static void i40e_write_qword(u8 *hmc_bits,
90161ae650dSJack F Vogel struct i40e_context_ele *ce_info,
90261ae650dSJack F Vogel u8 *src)
90361ae650dSJack F Vogel {
90461ae650dSJack F Vogel u64 src_qword, mask;
90561ae650dSJack F Vogel u8 *from, *dest;
90661ae650dSJack F Vogel u16 shift_width;
90761ae650dSJack F Vogel __le64 dest_qword;
90861ae650dSJack F Vogel
90961ae650dSJack F Vogel /* copy from the next struct field */
91061ae650dSJack F Vogel from = src + ce_info->offset;
91161ae650dSJack F Vogel
91261ae650dSJack F Vogel /* prepare the bits and mask */
91361ae650dSJack F Vogel shift_width = ce_info->lsb % 8;
91461ae650dSJack F Vogel
91561ae650dSJack F Vogel /* if the field width is exactly 64 on an x86 machine, then the shift
91661ae650dSJack F Vogel * operation will not work because the SHL instructions count is masked
91761ae650dSJack F Vogel * to 6 bits so the shift will do nothing
91861ae650dSJack F Vogel */
91961ae650dSJack F Vogel if (ce_info->width < 64)
920be771cdaSJack F Vogel mask = BIT_ULL(ce_info->width) - 1;
92161ae650dSJack F Vogel else
922f247dc25SJack F Vogel mask = ~(u64)0;
92361ae650dSJack F Vogel
92461ae650dSJack F Vogel /* don't swizzle the bits until after the mask because the mask bits
92561ae650dSJack F Vogel * will be in a different bit position on big endian machines
92661ae650dSJack F Vogel */
92761ae650dSJack F Vogel src_qword = *(u64 *)from;
92861ae650dSJack F Vogel src_qword &= mask;
92961ae650dSJack F Vogel
93061ae650dSJack F Vogel /* shift to correct alignment */
93161ae650dSJack F Vogel mask <<= shift_width;
93261ae650dSJack F Vogel src_qword <<= shift_width;
93361ae650dSJack F Vogel
93461ae650dSJack F Vogel /* get the current bits from the target bit string */
93561ae650dSJack F Vogel dest = hmc_bits + (ce_info->lsb / 8);
93661ae650dSJack F Vogel
93761ae650dSJack F Vogel i40e_memcpy(&dest_qword, dest, sizeof(dest_qword), I40E_DMA_TO_NONDMA);
93861ae650dSJack F Vogel
93961ae650dSJack F Vogel dest_qword &= ~(CPU_TO_LE64(mask)); /* get the bits not changing */
94061ae650dSJack F Vogel dest_qword |= CPU_TO_LE64(src_qword); /* add in the new bits */
94161ae650dSJack F Vogel
94261ae650dSJack F Vogel /* put it all back */
94361ae650dSJack F Vogel i40e_memcpy(dest, &dest_qword, sizeof(dest_qword), I40E_NONDMA_TO_DMA);
94461ae650dSJack F Vogel }
94561ae650dSJack F Vogel
94661ae650dSJack F Vogel /**
94761ae650dSJack F Vogel * i40e_read_byte - read HMC context byte into struct
94861ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory
94961ae650dSJack F Vogel * @ce_info: a description of the struct to be filled
95061ae650dSJack F Vogel * @dest: the struct to be filled
95161ae650dSJack F Vogel **/
i40e_read_byte(u8 * hmc_bits,struct i40e_context_ele * ce_info,u8 * dest)95261ae650dSJack F Vogel static void i40e_read_byte(u8 *hmc_bits,
95361ae650dSJack F Vogel struct i40e_context_ele *ce_info,
95461ae650dSJack F Vogel u8 *dest)
95561ae650dSJack F Vogel {
95661ae650dSJack F Vogel u8 dest_byte, mask;
95761ae650dSJack F Vogel u8 *src, *target;
95861ae650dSJack F Vogel u16 shift_width;
95961ae650dSJack F Vogel
96061ae650dSJack F Vogel /* prepare the bits and mask */
96161ae650dSJack F Vogel shift_width = ce_info->lsb % 8;
9627f70bec6SEric Joyner mask = (u8)(BIT(ce_info->width) - 1);
96361ae650dSJack F Vogel
96461ae650dSJack F Vogel /* shift to correct alignment */
96561ae650dSJack F Vogel mask <<= shift_width;
96661ae650dSJack F Vogel
96761ae650dSJack F Vogel /* get the current bits from the src bit string */
96861ae650dSJack F Vogel src = hmc_bits + (ce_info->lsb / 8);
96961ae650dSJack F Vogel
97061ae650dSJack F Vogel i40e_memcpy(&dest_byte, src, sizeof(dest_byte), I40E_DMA_TO_NONDMA);
97161ae650dSJack F Vogel
97261ae650dSJack F Vogel dest_byte &= ~(mask);
97361ae650dSJack F Vogel
97461ae650dSJack F Vogel dest_byte >>= shift_width;
97561ae650dSJack F Vogel
97661ae650dSJack F Vogel /* get the address from the struct field */
97761ae650dSJack F Vogel target = dest + ce_info->offset;
97861ae650dSJack F Vogel
97961ae650dSJack F Vogel /* put it back in the struct */
98061ae650dSJack F Vogel i40e_memcpy(target, &dest_byte, sizeof(dest_byte), I40E_NONDMA_TO_DMA);
98161ae650dSJack F Vogel }
98261ae650dSJack F Vogel
98361ae650dSJack F Vogel /**
98461ae650dSJack F Vogel * i40e_read_word - read HMC context word into struct
98561ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory
98661ae650dSJack F Vogel * @ce_info: a description of the struct to be filled
98761ae650dSJack F Vogel * @dest: the struct to be filled
98861ae650dSJack F Vogel **/
i40e_read_word(u8 * hmc_bits,struct i40e_context_ele * ce_info,u8 * dest)98961ae650dSJack F Vogel static void i40e_read_word(u8 *hmc_bits,
99061ae650dSJack F Vogel struct i40e_context_ele *ce_info,
99161ae650dSJack F Vogel u8 *dest)
99261ae650dSJack F Vogel {
99361ae650dSJack F Vogel u16 dest_word, mask;
99461ae650dSJack F Vogel u8 *src, *target;
99561ae650dSJack F Vogel u16 shift_width;
99661ae650dSJack F Vogel __le16 src_word;
99761ae650dSJack F Vogel
99861ae650dSJack F Vogel /* prepare the bits and mask */
99961ae650dSJack F Vogel shift_width = ce_info->lsb % 8;
1000be771cdaSJack F Vogel mask = BIT(ce_info->width) - 1;
100161ae650dSJack F Vogel
100261ae650dSJack F Vogel /* shift to correct alignment */
100361ae650dSJack F Vogel mask <<= shift_width;
100461ae650dSJack F Vogel
100561ae650dSJack F Vogel /* get the current bits from the src bit string */
100661ae650dSJack F Vogel src = hmc_bits + (ce_info->lsb / 8);
100761ae650dSJack F Vogel
100861ae650dSJack F Vogel i40e_memcpy(&src_word, src, sizeof(src_word), I40E_DMA_TO_NONDMA);
100961ae650dSJack F Vogel
101061ae650dSJack F Vogel /* the data in the memory is stored as little endian so mask it
101161ae650dSJack F Vogel * correctly
101261ae650dSJack F Vogel */
101361ae650dSJack F Vogel src_word &= ~(CPU_TO_LE16(mask));
101461ae650dSJack F Vogel
101561ae650dSJack F Vogel /* get the data back into host order before shifting */
101661ae650dSJack F Vogel dest_word = LE16_TO_CPU(src_word);
101761ae650dSJack F Vogel
101861ae650dSJack F Vogel dest_word >>= shift_width;
101961ae650dSJack F Vogel
102061ae650dSJack F Vogel /* get the address from the struct field */
102161ae650dSJack F Vogel target = dest + ce_info->offset;
102261ae650dSJack F Vogel
102361ae650dSJack F Vogel /* put it back in the struct */
102461ae650dSJack F Vogel i40e_memcpy(target, &dest_word, sizeof(dest_word), I40E_NONDMA_TO_DMA);
102561ae650dSJack F Vogel }
102661ae650dSJack F Vogel
102761ae650dSJack F Vogel /**
102861ae650dSJack F Vogel * i40e_read_dword - read HMC context dword into struct
102961ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory
103061ae650dSJack F Vogel * @ce_info: a description of the struct to be filled
103161ae650dSJack F Vogel * @dest: the struct to be filled
103261ae650dSJack F Vogel **/
i40e_read_dword(u8 * hmc_bits,struct i40e_context_ele * ce_info,u8 * dest)103361ae650dSJack F Vogel static void i40e_read_dword(u8 *hmc_bits,
103461ae650dSJack F Vogel struct i40e_context_ele *ce_info,
103561ae650dSJack F Vogel u8 *dest)
103661ae650dSJack F Vogel {
103761ae650dSJack F Vogel u32 dest_dword, mask;
103861ae650dSJack F Vogel u8 *src, *target;
103961ae650dSJack F Vogel u16 shift_width;
104061ae650dSJack F Vogel __le32 src_dword;
104161ae650dSJack F Vogel
104261ae650dSJack F Vogel /* prepare the bits and mask */
104361ae650dSJack F Vogel shift_width = ce_info->lsb % 8;
104461ae650dSJack F Vogel
104561ae650dSJack F Vogel /* if the field width is exactly 32 on an x86 machine, then the shift
104661ae650dSJack F Vogel * operation will not work because the SHL instructions count is masked
104761ae650dSJack F Vogel * to 5 bits so the shift will do nothing
104861ae650dSJack F Vogel */
104961ae650dSJack F Vogel if (ce_info->width < 32)
1050be771cdaSJack F Vogel mask = BIT(ce_info->width) - 1;
105161ae650dSJack F Vogel else
1052f247dc25SJack F Vogel mask = ~(u32)0;
105361ae650dSJack F Vogel
105461ae650dSJack F Vogel /* shift to correct alignment */
105561ae650dSJack F Vogel mask <<= shift_width;
105661ae650dSJack F Vogel
105761ae650dSJack F Vogel /* get the current bits from the src bit string */
105861ae650dSJack F Vogel src = hmc_bits + (ce_info->lsb / 8);
105961ae650dSJack F Vogel
106061ae650dSJack F Vogel i40e_memcpy(&src_dword, src, sizeof(src_dword), I40E_DMA_TO_NONDMA);
106161ae650dSJack F Vogel
106261ae650dSJack F Vogel /* the data in the memory is stored as little endian so mask it
106361ae650dSJack F Vogel * correctly
106461ae650dSJack F Vogel */
106561ae650dSJack F Vogel src_dword &= ~(CPU_TO_LE32(mask));
106661ae650dSJack F Vogel
106761ae650dSJack F Vogel /* get the data back into host order before shifting */
106861ae650dSJack F Vogel dest_dword = LE32_TO_CPU(src_dword);
106961ae650dSJack F Vogel
107061ae650dSJack F Vogel dest_dword >>= shift_width;
107161ae650dSJack F Vogel
107261ae650dSJack F Vogel /* get the address from the struct field */
107361ae650dSJack F Vogel target = dest + ce_info->offset;
107461ae650dSJack F Vogel
107561ae650dSJack F Vogel /* put it back in the struct */
107661ae650dSJack F Vogel i40e_memcpy(target, &dest_dword, sizeof(dest_dword),
107761ae650dSJack F Vogel I40E_NONDMA_TO_DMA);
107861ae650dSJack F Vogel }
107961ae650dSJack F Vogel
108061ae650dSJack F Vogel /**
108161ae650dSJack F Vogel * i40e_read_qword - read HMC context qword into struct
108261ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory
108361ae650dSJack F Vogel * @ce_info: a description of the struct to be filled
108461ae650dSJack F Vogel * @dest: the struct to be filled
108561ae650dSJack F Vogel **/
i40e_read_qword(u8 * hmc_bits,struct i40e_context_ele * ce_info,u8 * dest)108661ae650dSJack F Vogel static void i40e_read_qword(u8 *hmc_bits,
108761ae650dSJack F Vogel struct i40e_context_ele *ce_info,
108861ae650dSJack F Vogel u8 *dest)
108961ae650dSJack F Vogel {
109061ae650dSJack F Vogel u64 dest_qword, mask;
109161ae650dSJack F Vogel u8 *src, *target;
109261ae650dSJack F Vogel u16 shift_width;
109361ae650dSJack F Vogel __le64 src_qword;
109461ae650dSJack F Vogel
109561ae650dSJack F Vogel /* prepare the bits and mask */
109661ae650dSJack F Vogel shift_width = ce_info->lsb % 8;
109761ae650dSJack F Vogel
109861ae650dSJack F Vogel /* if the field width is exactly 64 on an x86 machine, then the shift
109961ae650dSJack F Vogel * operation will not work because the SHL instructions count is masked
110061ae650dSJack F Vogel * to 6 bits so the shift will do nothing
110161ae650dSJack F Vogel */
110261ae650dSJack F Vogel if (ce_info->width < 64)
1103be771cdaSJack F Vogel mask = BIT_ULL(ce_info->width) - 1;
110461ae650dSJack F Vogel else
1105f247dc25SJack F Vogel mask = ~(u64)0;
110661ae650dSJack F Vogel
110761ae650dSJack F Vogel /* shift to correct alignment */
110861ae650dSJack F Vogel mask <<= shift_width;
110961ae650dSJack F Vogel
111061ae650dSJack F Vogel /* get the current bits from the src bit string */
111161ae650dSJack F Vogel src = hmc_bits + (ce_info->lsb / 8);
111261ae650dSJack F Vogel
111361ae650dSJack F Vogel i40e_memcpy(&src_qword, src, sizeof(src_qword), I40E_DMA_TO_NONDMA);
111461ae650dSJack F Vogel
111561ae650dSJack F Vogel /* the data in the memory is stored as little endian so mask it
111661ae650dSJack F Vogel * correctly
111761ae650dSJack F Vogel */
111861ae650dSJack F Vogel src_qword &= ~(CPU_TO_LE64(mask));
111961ae650dSJack F Vogel
112061ae650dSJack F Vogel /* get the data back into host order before shifting */
112161ae650dSJack F Vogel dest_qword = LE64_TO_CPU(src_qword);
112261ae650dSJack F Vogel
112361ae650dSJack F Vogel dest_qword >>= shift_width;
112461ae650dSJack F Vogel
112561ae650dSJack F Vogel /* get the address from the struct field */
112661ae650dSJack F Vogel target = dest + ce_info->offset;
112761ae650dSJack F Vogel
112861ae650dSJack F Vogel /* put it back in the struct */
112961ae650dSJack F Vogel i40e_memcpy(target, &dest_qword, sizeof(dest_qword),
113061ae650dSJack F Vogel I40E_NONDMA_TO_DMA);
113161ae650dSJack F Vogel }
113261ae650dSJack F Vogel
113361ae650dSJack F Vogel /**
113461ae650dSJack F Vogel * i40e_get_hmc_context - extract HMC context bits
113561ae650dSJack F Vogel * @context_bytes: pointer to the context bit array
113661ae650dSJack F Vogel * @ce_info: a description of the struct to be filled
113761ae650dSJack F Vogel * @dest: the struct to be filled
113861ae650dSJack F Vogel **/
i40e_get_hmc_context(u8 * context_bytes,struct i40e_context_ele * ce_info,u8 * dest)113961ae650dSJack F Vogel static enum i40e_status_code i40e_get_hmc_context(u8 *context_bytes,
114061ae650dSJack F Vogel struct i40e_context_ele *ce_info,
114161ae650dSJack F Vogel u8 *dest)
114261ae650dSJack F Vogel {
114361ae650dSJack F Vogel int f;
114461ae650dSJack F Vogel
114561ae650dSJack F Vogel for (f = 0; ce_info[f].width != 0; f++) {
114661ae650dSJack F Vogel switch (ce_info[f].size_of) {
114761ae650dSJack F Vogel case 1:
114861ae650dSJack F Vogel i40e_read_byte(context_bytes, &ce_info[f], dest);
114961ae650dSJack F Vogel break;
115061ae650dSJack F Vogel case 2:
115161ae650dSJack F Vogel i40e_read_word(context_bytes, &ce_info[f], dest);
115261ae650dSJack F Vogel break;
115361ae650dSJack F Vogel case 4:
115461ae650dSJack F Vogel i40e_read_dword(context_bytes, &ce_info[f], dest);
115561ae650dSJack F Vogel break;
115661ae650dSJack F Vogel case 8:
115761ae650dSJack F Vogel i40e_read_qword(context_bytes, &ce_info[f], dest);
115861ae650dSJack F Vogel break;
115961ae650dSJack F Vogel default:
116061ae650dSJack F Vogel /* nothing to do, just keep going */
116161ae650dSJack F Vogel break;
116261ae650dSJack F Vogel }
116361ae650dSJack F Vogel }
116461ae650dSJack F Vogel
116561ae650dSJack F Vogel return I40E_SUCCESS;
116661ae650dSJack F Vogel }
116761ae650dSJack F Vogel
116861ae650dSJack F Vogel /**
116961ae650dSJack F Vogel * i40e_clear_hmc_context - zero out the HMC context bits
117061ae650dSJack F Vogel * @hw: the hardware struct
117161ae650dSJack F Vogel * @context_bytes: pointer to the context bit array (DMA memory)
117261ae650dSJack F Vogel * @hmc_type: the type of HMC resource
117361ae650dSJack F Vogel **/
i40e_clear_hmc_context(struct i40e_hw * hw,u8 * context_bytes,enum i40e_hmc_lan_rsrc_type hmc_type)117461ae650dSJack F Vogel static enum i40e_status_code i40e_clear_hmc_context(struct i40e_hw *hw,
117561ae650dSJack F Vogel u8 *context_bytes,
117661ae650dSJack F Vogel enum i40e_hmc_lan_rsrc_type hmc_type)
117761ae650dSJack F Vogel {
117861ae650dSJack F Vogel /* clean the bit array */
117961ae650dSJack F Vogel i40e_memset(context_bytes, 0, (u32)hw->hmc.hmc_obj[hmc_type].size,
118061ae650dSJack F Vogel I40E_DMA_MEM);
118161ae650dSJack F Vogel
118261ae650dSJack F Vogel return I40E_SUCCESS;
118361ae650dSJack F Vogel }
118461ae650dSJack F Vogel
118561ae650dSJack F Vogel /**
118661ae650dSJack F Vogel * i40e_set_hmc_context - replace HMC context bits
118761ae650dSJack F Vogel * @context_bytes: pointer to the context bit array
118861ae650dSJack F Vogel * @ce_info: a description of the struct to be filled
118961ae650dSJack F Vogel * @dest: the struct to be filled
119061ae650dSJack F Vogel **/
i40e_set_hmc_context(u8 * context_bytes,struct i40e_context_ele * ce_info,u8 * dest)119161ae650dSJack F Vogel static enum i40e_status_code i40e_set_hmc_context(u8 *context_bytes,
119261ae650dSJack F Vogel struct i40e_context_ele *ce_info,
119361ae650dSJack F Vogel u8 *dest)
119461ae650dSJack F Vogel {
119561ae650dSJack F Vogel int f;
119661ae650dSJack F Vogel
119761ae650dSJack F Vogel for (f = 0; ce_info[f].width != 0; f++) {
119861ae650dSJack F Vogel
119961ae650dSJack F Vogel /* we have to deal with each element of the HMC using the
120061ae650dSJack F Vogel * correct size so that we are correct regardless of the
120161ae650dSJack F Vogel * endianness of the machine
120261ae650dSJack F Vogel */
120361ae650dSJack F Vogel switch (ce_info[f].size_of) {
120461ae650dSJack F Vogel case 1:
120561ae650dSJack F Vogel i40e_write_byte(context_bytes, &ce_info[f], dest);
120661ae650dSJack F Vogel break;
120761ae650dSJack F Vogel case 2:
120861ae650dSJack F Vogel i40e_write_word(context_bytes, &ce_info[f], dest);
120961ae650dSJack F Vogel break;
121061ae650dSJack F Vogel case 4:
121161ae650dSJack F Vogel i40e_write_dword(context_bytes, &ce_info[f], dest);
121261ae650dSJack F Vogel break;
121361ae650dSJack F Vogel case 8:
121461ae650dSJack F Vogel i40e_write_qword(context_bytes, &ce_info[f], dest);
121561ae650dSJack F Vogel break;
121661ae650dSJack F Vogel }
121761ae650dSJack F Vogel }
121861ae650dSJack F Vogel
121961ae650dSJack F Vogel return I40E_SUCCESS;
122061ae650dSJack F Vogel }
122161ae650dSJack F Vogel
122261ae650dSJack F Vogel /**
122361ae650dSJack F Vogel * i40e_hmc_get_object_va - retrieves an object's virtual address
1224b6c8f260SJack F Vogel * @hw: pointer to the hw structure
122561ae650dSJack F Vogel * @object_base: pointer to u64 to get the va
122661ae650dSJack F Vogel * @rsrc_type: the hmc resource type
122761ae650dSJack F Vogel * @obj_idx: hmc object index
122861ae650dSJack F Vogel *
122961ae650dSJack F Vogel * This function retrieves the object's virtual address from the object
123061ae650dSJack F Vogel * base pointer. This function is used for LAN Queue contexts.
123161ae650dSJack F Vogel **/
123261ae650dSJack F Vogel static
i40e_hmc_get_object_va(struct i40e_hw * hw,u8 ** object_base,enum i40e_hmc_lan_rsrc_type rsrc_type,u32 obj_idx)1233b6c8f260SJack F Vogel enum i40e_status_code i40e_hmc_get_object_va(struct i40e_hw *hw,
123461ae650dSJack F Vogel u8 **object_base,
123561ae650dSJack F Vogel enum i40e_hmc_lan_rsrc_type rsrc_type,
123661ae650dSJack F Vogel u32 obj_idx)
123761ae650dSJack F Vogel {
123861ae650dSJack F Vogel u32 obj_offset_in_sd, obj_offset_in_pd;
1239b6c8f260SJack F Vogel struct i40e_hmc_info *hmc_info = &hw->hmc;
124061ae650dSJack F Vogel struct i40e_hmc_sd_entry *sd_entry;
124161ae650dSJack F Vogel struct i40e_hmc_pd_entry *pd_entry;
124261ae650dSJack F Vogel u32 pd_idx, pd_lmt, rel_pd_idx;
124361ae650dSJack F Vogel enum i40e_status_code ret_code = I40E_SUCCESS;
124461ae650dSJack F Vogel u64 obj_offset_in_fpm;
124561ae650dSJack F Vogel u32 sd_idx, sd_lmt;
124661ae650dSJack F Vogel
124761ae650dSJack F Vogel if (NULL == hmc_info->hmc_obj) {
124861ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR;
124961ae650dSJack F Vogel DEBUGOUT("i40e_hmc_get_object_va: bad hmc_info->hmc_obj ptr\n");
125061ae650dSJack F Vogel goto exit;
125161ae650dSJack F Vogel }
125261ae650dSJack F Vogel if (NULL == object_base) {
125361ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR;
125461ae650dSJack F Vogel DEBUGOUT("i40e_hmc_get_object_va: bad object_base ptr\n");
125561ae650dSJack F Vogel goto exit;
125661ae650dSJack F Vogel }
125761ae650dSJack F Vogel if (I40E_HMC_INFO_SIGNATURE != hmc_info->signature) {
125861ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR;
125961ae650dSJack F Vogel DEBUGOUT("i40e_hmc_get_object_va: bad hmc_info->signature\n");
126061ae650dSJack F Vogel goto exit;
126161ae650dSJack F Vogel }
126261ae650dSJack F Vogel if (obj_idx >= hmc_info->hmc_obj[rsrc_type].cnt) {
126361ae650dSJack F Vogel DEBUGOUT1("i40e_hmc_get_object_va: returns error %d\n",
126461ae650dSJack F Vogel ret_code);
126561ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX;
126661ae650dSJack F Vogel goto exit;
126761ae650dSJack F Vogel }
126861ae650dSJack F Vogel /* find sd index and limit */
126961ae650dSJack F Vogel I40E_FIND_SD_INDEX_LIMIT(hmc_info, rsrc_type, obj_idx, 1,
127061ae650dSJack F Vogel &sd_idx, &sd_lmt);
127161ae650dSJack F Vogel
127261ae650dSJack F Vogel sd_entry = &hmc_info->sd_table.sd_entry[sd_idx];
127361ae650dSJack F Vogel obj_offset_in_fpm = hmc_info->hmc_obj[rsrc_type].base +
127461ae650dSJack F Vogel hmc_info->hmc_obj[rsrc_type].size * obj_idx;
127561ae650dSJack F Vogel
127661ae650dSJack F Vogel if (I40E_SD_TYPE_PAGED == sd_entry->entry_type) {
127761ae650dSJack F Vogel I40E_FIND_PD_INDEX_LIMIT(hmc_info, rsrc_type, obj_idx, 1,
127861ae650dSJack F Vogel &pd_idx, &pd_lmt);
127961ae650dSJack F Vogel rel_pd_idx = pd_idx % I40E_HMC_PD_CNT_IN_SD;
128061ae650dSJack F Vogel pd_entry = &sd_entry->u.pd_table.pd_entry[rel_pd_idx];
128161ae650dSJack F Vogel obj_offset_in_pd = (u32)(obj_offset_in_fpm %
128261ae650dSJack F Vogel I40E_HMC_PAGED_BP_SIZE);
128361ae650dSJack F Vogel *object_base = (u8 *)pd_entry->bp.addr.va + obj_offset_in_pd;
128461ae650dSJack F Vogel } else {
128561ae650dSJack F Vogel obj_offset_in_sd = (u32)(obj_offset_in_fpm %
128661ae650dSJack F Vogel I40E_HMC_DIRECT_BP_SIZE);
128761ae650dSJack F Vogel *object_base = (u8 *)sd_entry->u.bp.addr.va + obj_offset_in_sd;
128861ae650dSJack F Vogel }
128961ae650dSJack F Vogel exit:
129061ae650dSJack F Vogel return ret_code;
129161ae650dSJack F Vogel }
129261ae650dSJack F Vogel
129361ae650dSJack F Vogel /**
129461ae650dSJack F Vogel * i40e_get_lan_tx_queue_context - return the HMC context for the queue
129561ae650dSJack F Vogel * @hw: the hardware struct
129661ae650dSJack F Vogel * @queue: the queue we care about
129761ae650dSJack F Vogel * @s: the struct to be filled
129861ae650dSJack F Vogel **/
i40e_get_lan_tx_queue_context(struct i40e_hw * hw,u16 queue,struct i40e_hmc_obj_txq * s)129961ae650dSJack F Vogel enum i40e_status_code i40e_get_lan_tx_queue_context(struct i40e_hw *hw,
130061ae650dSJack F Vogel u16 queue,
130161ae650dSJack F Vogel struct i40e_hmc_obj_txq *s)
130261ae650dSJack F Vogel {
130361ae650dSJack F Vogel enum i40e_status_code err;
130461ae650dSJack F Vogel u8 *context_bytes;
130561ae650dSJack F Vogel
1306b6c8f260SJack F Vogel err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_TX, queue);
130761ae650dSJack F Vogel if (err < 0)
130861ae650dSJack F Vogel return err;
130961ae650dSJack F Vogel
131061ae650dSJack F Vogel return i40e_get_hmc_context(context_bytes,
131161ae650dSJack F Vogel i40e_hmc_txq_ce_info, (u8 *)s);
131261ae650dSJack F Vogel }
131361ae650dSJack F Vogel
131461ae650dSJack F Vogel /**
131561ae650dSJack F Vogel * i40e_clear_lan_tx_queue_context - clear the HMC context for the queue
131661ae650dSJack F Vogel * @hw: the hardware struct
131761ae650dSJack F Vogel * @queue: the queue we care about
131861ae650dSJack F Vogel **/
i40e_clear_lan_tx_queue_context(struct i40e_hw * hw,u16 queue)131961ae650dSJack F Vogel enum i40e_status_code i40e_clear_lan_tx_queue_context(struct i40e_hw *hw,
132061ae650dSJack F Vogel u16 queue)
132161ae650dSJack F Vogel {
132261ae650dSJack F Vogel enum i40e_status_code err;
132361ae650dSJack F Vogel u8 *context_bytes;
132461ae650dSJack F Vogel
1325b6c8f260SJack F Vogel err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_TX, queue);
132661ae650dSJack F Vogel if (err < 0)
132761ae650dSJack F Vogel return err;
132861ae650dSJack F Vogel
132961ae650dSJack F Vogel return i40e_clear_hmc_context(hw, context_bytes, I40E_HMC_LAN_TX);
133061ae650dSJack F Vogel }
133161ae650dSJack F Vogel
133261ae650dSJack F Vogel /**
133361ae650dSJack F Vogel * i40e_set_lan_tx_queue_context - set the HMC context for the queue
133461ae650dSJack F Vogel * @hw: the hardware struct
133561ae650dSJack F Vogel * @queue: the queue we care about
133661ae650dSJack F Vogel * @s: the struct to be filled
133761ae650dSJack F Vogel **/
i40e_set_lan_tx_queue_context(struct i40e_hw * hw,u16 queue,struct i40e_hmc_obj_txq * s)133861ae650dSJack F Vogel enum i40e_status_code i40e_set_lan_tx_queue_context(struct i40e_hw *hw,
133961ae650dSJack F Vogel u16 queue,
134061ae650dSJack F Vogel struct i40e_hmc_obj_txq *s)
134161ae650dSJack F Vogel {
134261ae650dSJack F Vogel enum i40e_status_code err;
134361ae650dSJack F Vogel u8 *context_bytes;
134461ae650dSJack F Vogel
1345b6c8f260SJack F Vogel err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_TX, queue);
134661ae650dSJack F Vogel if (err < 0)
134761ae650dSJack F Vogel return err;
134861ae650dSJack F Vogel
134961ae650dSJack F Vogel return i40e_set_hmc_context(context_bytes,
135061ae650dSJack F Vogel i40e_hmc_txq_ce_info, (u8 *)s);
135161ae650dSJack F Vogel }
135261ae650dSJack F Vogel
135361ae650dSJack F Vogel /**
135461ae650dSJack F Vogel * i40e_get_lan_rx_queue_context - return the HMC context for the queue
135561ae650dSJack F Vogel * @hw: the hardware struct
135661ae650dSJack F Vogel * @queue: the queue we care about
135761ae650dSJack F Vogel * @s: the struct to be filled
135861ae650dSJack F Vogel **/
i40e_get_lan_rx_queue_context(struct i40e_hw * hw,u16 queue,struct i40e_hmc_obj_rxq * s)135961ae650dSJack F Vogel enum i40e_status_code i40e_get_lan_rx_queue_context(struct i40e_hw *hw,
136061ae650dSJack F Vogel u16 queue,
136161ae650dSJack F Vogel struct i40e_hmc_obj_rxq *s)
136261ae650dSJack F Vogel {
136361ae650dSJack F Vogel enum i40e_status_code err;
136461ae650dSJack F Vogel u8 *context_bytes;
136561ae650dSJack F Vogel
1366b6c8f260SJack F Vogel err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_RX, queue);
136761ae650dSJack F Vogel if (err < 0)
136861ae650dSJack F Vogel return err;
136961ae650dSJack F Vogel
137061ae650dSJack F Vogel return i40e_get_hmc_context(context_bytes,
137161ae650dSJack F Vogel i40e_hmc_rxq_ce_info, (u8 *)s);
137261ae650dSJack F Vogel }
137361ae650dSJack F Vogel
137461ae650dSJack F Vogel /**
137561ae650dSJack F Vogel * i40e_clear_lan_rx_queue_context - clear the HMC context for the queue
137661ae650dSJack F Vogel * @hw: the hardware struct
137761ae650dSJack F Vogel * @queue: the queue we care about
137861ae650dSJack F Vogel **/
i40e_clear_lan_rx_queue_context(struct i40e_hw * hw,u16 queue)137961ae650dSJack F Vogel enum i40e_status_code i40e_clear_lan_rx_queue_context(struct i40e_hw *hw,
138061ae650dSJack F Vogel u16 queue)
138161ae650dSJack F Vogel {
138261ae650dSJack F Vogel enum i40e_status_code err;
138361ae650dSJack F Vogel u8 *context_bytes;
138461ae650dSJack F Vogel
1385b6c8f260SJack F Vogel err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_RX, queue);
138661ae650dSJack F Vogel if (err < 0)
138761ae650dSJack F Vogel return err;
138861ae650dSJack F Vogel
138961ae650dSJack F Vogel return i40e_clear_hmc_context(hw, context_bytes, I40E_HMC_LAN_RX);
139061ae650dSJack F Vogel }
139161ae650dSJack F Vogel
139261ae650dSJack F Vogel /**
139361ae650dSJack F Vogel * i40e_set_lan_rx_queue_context - set the HMC context for the queue
139461ae650dSJack F Vogel * @hw: the hardware struct
139561ae650dSJack F Vogel * @queue: the queue we care about
139661ae650dSJack F Vogel * @s: the struct to be filled
139761ae650dSJack F Vogel **/
i40e_set_lan_rx_queue_context(struct i40e_hw * hw,u16 queue,struct i40e_hmc_obj_rxq * s)139861ae650dSJack F Vogel enum i40e_status_code i40e_set_lan_rx_queue_context(struct i40e_hw *hw,
139961ae650dSJack F Vogel u16 queue,
140061ae650dSJack F Vogel struct i40e_hmc_obj_rxq *s)
140161ae650dSJack F Vogel {
140261ae650dSJack F Vogel enum i40e_status_code err;
140361ae650dSJack F Vogel u8 *context_bytes;
140461ae650dSJack F Vogel
1405b6c8f260SJack F Vogel err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_RX, queue);
140661ae650dSJack F Vogel if (err < 0)
140761ae650dSJack F Vogel return err;
140861ae650dSJack F Vogel
140961ae650dSJack F Vogel return i40e_set_hmc_context(context_bytes,
141061ae650dSJack F Vogel i40e_hmc_rxq_ce_info, (u8 *)s);
141161ae650dSJack F Vogel }
1412