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