161ae650dSJack F Vogel /****************************************************************************** 261ae650dSJack F Vogel 361ae650dSJack F Vogel Copyright (c) 2013-2014, 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); 14061ae650dSJack F Vogel obj->size = (u64)1 << 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); 16361ae650dSJack F Vogel obj->size = (u64)1 << 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); 18661ae650dSJack F Vogel obj->size = (u64)1 << 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); 20961ae650dSJack F Vogel obj->size = (u64)1 << 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, 39861ae650dSJack F Vogel i); 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)); 44261ae650dSJack 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 } 44561ae650dSJack F Vogel i40e_remove_pd_page(hw, info->hmc_info, (j - 1)); 44661ae650dSJack F Vogel break; 44761ae650dSJack F Vogel case I40E_SD_TYPE_DIRECT: 44861ae650dSJack F Vogel i40e_remove_sd_bp(hw, info->hmc_info, (j - 1)); 44961ae650dSJack F Vogel break; 45061ae650dSJack F Vogel default: 45161ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_SD_TYPE; 45261ae650dSJack F Vogel break; 45361ae650dSJack F Vogel } 45461ae650dSJack F Vogel j--; 45561ae650dSJack F Vogel } 45661ae650dSJack F Vogel exit: 45761ae650dSJack F Vogel return ret_code; 45861ae650dSJack F Vogel } 45961ae650dSJack F Vogel 46061ae650dSJack F Vogel /** 46161ae650dSJack F Vogel * i40e_configure_lan_hmc - prepare the HMC backing store 46261ae650dSJack F Vogel * @hw: pointer to the hw structure 46361ae650dSJack F Vogel * @model: the model for the layout of the SD/PD tables 46461ae650dSJack F Vogel * 46561ae650dSJack F Vogel * - This function will be called once per physical function initialization. 46661ae650dSJack F Vogel * - This function will be called after i40e_init_lan_hmc() and before 46761ae650dSJack F Vogel * any LAN/FCoE HMC objects can be created. 46861ae650dSJack F Vogel **/ 46961ae650dSJack F Vogel enum i40e_status_code i40e_configure_lan_hmc(struct i40e_hw *hw, 47061ae650dSJack F Vogel enum i40e_hmc_model model) 47161ae650dSJack F Vogel { 47261ae650dSJack F Vogel struct i40e_hmc_lan_create_obj_info info; 47361ae650dSJack F Vogel u8 hmc_fn_id = hw->hmc.hmc_fn_id; 47461ae650dSJack F Vogel struct i40e_hmc_obj_info *obj; 47561ae650dSJack F Vogel enum i40e_status_code ret_code = I40E_SUCCESS; 47661ae650dSJack F Vogel 47761ae650dSJack F Vogel /* Initialize part of the create object info struct */ 47861ae650dSJack F Vogel info.hmc_info = &hw->hmc; 47961ae650dSJack F Vogel info.rsrc_type = I40E_HMC_LAN_FULL; 48061ae650dSJack F Vogel info.start_idx = 0; 48161ae650dSJack F Vogel info.direct_mode_sz = hw->hmc.hmc_obj[I40E_HMC_LAN_FULL].size; 48261ae650dSJack F Vogel 48361ae650dSJack F Vogel /* Build the SD entry for the LAN objects */ 48461ae650dSJack F Vogel switch (model) { 48561ae650dSJack F Vogel case I40E_HMC_MODEL_DIRECT_PREFERRED: 48661ae650dSJack F Vogel case I40E_HMC_MODEL_DIRECT_ONLY: 48761ae650dSJack F Vogel info.entry_type = I40E_SD_TYPE_DIRECT; 48861ae650dSJack F Vogel /* Make one big object, a single SD */ 48961ae650dSJack F Vogel info.count = 1; 49061ae650dSJack F Vogel ret_code = i40e_create_lan_hmc_object(hw, &info); 49161ae650dSJack F Vogel if ((ret_code != I40E_SUCCESS) && (model == I40E_HMC_MODEL_DIRECT_PREFERRED)) 49261ae650dSJack F Vogel goto try_type_paged; 49361ae650dSJack F Vogel else if (ret_code != I40E_SUCCESS) 49461ae650dSJack F Vogel goto configure_lan_hmc_out; 49561ae650dSJack F Vogel /* else clause falls through the break */ 49661ae650dSJack F Vogel break; 49761ae650dSJack F Vogel case I40E_HMC_MODEL_PAGED_ONLY: 49861ae650dSJack F Vogel try_type_paged: 49961ae650dSJack F Vogel info.entry_type = I40E_SD_TYPE_PAGED; 50061ae650dSJack F Vogel /* Make one big object in the PD table */ 50161ae650dSJack F Vogel info.count = 1; 50261ae650dSJack F Vogel ret_code = i40e_create_lan_hmc_object(hw, &info); 50361ae650dSJack F Vogel if (ret_code != I40E_SUCCESS) 50461ae650dSJack F Vogel goto configure_lan_hmc_out; 50561ae650dSJack F Vogel break; 50661ae650dSJack F Vogel default: 50761ae650dSJack F Vogel /* unsupported type */ 50861ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_SD_TYPE; 50961ae650dSJack F Vogel DEBUGOUT1("i40e_configure_lan_hmc: Unknown SD type: %d\n", 51061ae650dSJack F Vogel ret_code); 51161ae650dSJack F Vogel goto configure_lan_hmc_out; 51261ae650dSJack F Vogel } 51361ae650dSJack F Vogel 51461ae650dSJack F Vogel /* Configure and program the FPM registers so objects can be created */ 51561ae650dSJack F Vogel 51661ae650dSJack F Vogel /* Tx contexts */ 51761ae650dSJack F Vogel obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX]; 51861ae650dSJack F Vogel wr32(hw, I40E_GLHMC_LANTXBASE(hmc_fn_id), 51961ae650dSJack F Vogel (u32)((obj->base & I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK) / 512)); 52061ae650dSJack F Vogel wr32(hw, I40E_GLHMC_LANTXCNT(hmc_fn_id), obj->cnt); 52161ae650dSJack F Vogel 52261ae650dSJack F Vogel /* Rx contexts */ 52361ae650dSJack F Vogel obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_RX]; 52461ae650dSJack F Vogel wr32(hw, I40E_GLHMC_LANRXBASE(hmc_fn_id), 52561ae650dSJack F Vogel (u32)((obj->base & I40E_GLHMC_LANRXBASE_FPMLANRXBASE_MASK) / 512)); 52661ae650dSJack F Vogel wr32(hw, I40E_GLHMC_LANRXCNT(hmc_fn_id), obj->cnt); 52761ae650dSJack F Vogel 52861ae650dSJack F Vogel /* FCoE contexts */ 52961ae650dSJack F Vogel obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX]; 53061ae650dSJack F Vogel wr32(hw, I40E_GLHMC_FCOEDDPBASE(hmc_fn_id), 53161ae650dSJack F Vogel (u32)((obj->base & I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_MASK) / 512)); 53261ae650dSJack F Vogel wr32(hw, I40E_GLHMC_FCOEDDPCNT(hmc_fn_id), obj->cnt); 53361ae650dSJack F Vogel 53461ae650dSJack F Vogel /* FCoE filters */ 53561ae650dSJack F Vogel obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_FILT]; 53661ae650dSJack F Vogel wr32(hw, I40E_GLHMC_FCOEFBASE(hmc_fn_id), 53761ae650dSJack F Vogel (u32)((obj->base & I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_MASK) / 512)); 53861ae650dSJack F Vogel wr32(hw, I40E_GLHMC_FCOEFCNT(hmc_fn_id), obj->cnt); 53961ae650dSJack F Vogel 54061ae650dSJack F Vogel configure_lan_hmc_out: 54161ae650dSJack F Vogel return ret_code; 54261ae650dSJack F Vogel } 54361ae650dSJack F Vogel 54461ae650dSJack F Vogel /** 54561ae650dSJack F Vogel * i40e_delete_hmc_object - remove hmc objects 54661ae650dSJack F Vogel * @hw: pointer to the HW structure 54761ae650dSJack F Vogel * @info: pointer to i40e_hmc_delete_obj_info struct 54861ae650dSJack F Vogel * 54961ae650dSJack F Vogel * This will de-populate the SDs and PDs. It frees 55061ae650dSJack F Vogel * the memory for PDS and backing storage. After this function is returned, 55161ae650dSJack F Vogel * caller should deallocate memory allocated previously for 55261ae650dSJack F Vogel * book-keeping information about PDs and backing storage. 55361ae650dSJack F Vogel **/ 55461ae650dSJack F Vogel enum i40e_status_code i40e_delete_lan_hmc_object(struct i40e_hw *hw, 55561ae650dSJack F Vogel struct i40e_hmc_lan_delete_obj_info *info) 55661ae650dSJack F Vogel { 55761ae650dSJack F Vogel enum i40e_status_code ret_code = I40E_SUCCESS; 55861ae650dSJack F Vogel struct i40e_hmc_pd_table *pd_table; 55961ae650dSJack F Vogel u32 pd_idx, pd_lmt, rel_pd_idx; 56061ae650dSJack F Vogel u32 sd_idx, sd_lmt; 56161ae650dSJack F Vogel u32 i, j; 56261ae650dSJack F Vogel 56361ae650dSJack F Vogel if (NULL == info) { 56461ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR; 56561ae650dSJack F Vogel DEBUGOUT("i40e_delete_hmc_object: bad info ptr\n"); 56661ae650dSJack F Vogel goto exit; 56761ae650dSJack F Vogel } 56861ae650dSJack F Vogel if (NULL == info->hmc_info) { 56961ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR; 57061ae650dSJack F Vogel DEBUGOUT("i40e_delete_hmc_object: bad info->hmc_info ptr\n"); 57161ae650dSJack F Vogel goto exit; 57261ae650dSJack F Vogel } 57361ae650dSJack F Vogel if (I40E_HMC_INFO_SIGNATURE != info->hmc_info->signature) { 57461ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR; 57561ae650dSJack F Vogel DEBUGOUT("i40e_delete_hmc_object: bad hmc_info->signature\n"); 57661ae650dSJack F Vogel goto exit; 57761ae650dSJack F Vogel } 57861ae650dSJack F Vogel 57961ae650dSJack F Vogel if (NULL == info->hmc_info->sd_table.sd_entry) { 58061ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR; 58161ae650dSJack F Vogel DEBUGOUT("i40e_delete_hmc_object: bad sd_entry\n"); 58261ae650dSJack F Vogel goto exit; 58361ae650dSJack F Vogel } 58461ae650dSJack F Vogel 58561ae650dSJack F Vogel if (NULL == info->hmc_info->hmc_obj) { 58661ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR; 58761ae650dSJack F Vogel DEBUGOUT("i40e_delete_hmc_object: bad hmc_info->hmc_obj\n"); 58861ae650dSJack F Vogel goto exit; 58961ae650dSJack F Vogel } 59061ae650dSJack F Vogel if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) { 59161ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX; 59261ae650dSJack F Vogel DEBUGOUT1("i40e_delete_hmc_object: returns error %d\n", 59361ae650dSJack F Vogel ret_code); 59461ae650dSJack F Vogel goto exit; 59561ae650dSJack F Vogel } 59661ae650dSJack F Vogel 59761ae650dSJack F Vogel if ((info->start_idx + info->count) > 59861ae650dSJack F Vogel info->hmc_info->hmc_obj[info->rsrc_type].cnt) { 59961ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT; 60061ae650dSJack F Vogel DEBUGOUT1("i40e_delete_hmc_object: returns error %d\n", 60161ae650dSJack F Vogel ret_code); 60261ae650dSJack F Vogel goto exit; 60361ae650dSJack F Vogel } 60461ae650dSJack F Vogel 60561ae650dSJack F Vogel I40E_FIND_PD_INDEX_LIMIT(info->hmc_info, info->rsrc_type, 60661ae650dSJack F Vogel info->start_idx, info->count, &pd_idx, 60761ae650dSJack F Vogel &pd_lmt); 60861ae650dSJack F Vogel 60961ae650dSJack F Vogel for (j = pd_idx; j < pd_lmt; j++) { 61061ae650dSJack F Vogel sd_idx = j / I40E_HMC_PD_CNT_IN_SD; 61161ae650dSJack F Vogel 61261ae650dSJack F Vogel if (I40E_SD_TYPE_PAGED != 61361ae650dSJack F Vogel info->hmc_info->sd_table.sd_entry[sd_idx].entry_type) 61461ae650dSJack F Vogel continue; 61561ae650dSJack F Vogel 61661ae650dSJack F Vogel rel_pd_idx = j % I40E_HMC_PD_CNT_IN_SD; 61761ae650dSJack F Vogel 61861ae650dSJack F Vogel pd_table = 61961ae650dSJack F Vogel &info->hmc_info->sd_table.sd_entry[sd_idx].u.pd_table; 62061ae650dSJack F Vogel if (pd_table->pd_entry[rel_pd_idx].valid) { 62161ae650dSJack F Vogel ret_code = i40e_remove_pd_bp(hw, info->hmc_info, j); 62261ae650dSJack F Vogel if (I40E_SUCCESS != ret_code) 62361ae650dSJack F Vogel goto exit; 62461ae650dSJack F Vogel } 62561ae650dSJack F Vogel } 62661ae650dSJack F Vogel 62761ae650dSJack F Vogel /* find sd index and limit */ 62861ae650dSJack F Vogel I40E_FIND_SD_INDEX_LIMIT(info->hmc_info, info->rsrc_type, 62961ae650dSJack F Vogel info->start_idx, info->count, 63061ae650dSJack F Vogel &sd_idx, &sd_lmt); 63161ae650dSJack F Vogel if (sd_idx >= info->hmc_info->sd_table.sd_cnt || 63261ae650dSJack F Vogel sd_lmt > info->hmc_info->sd_table.sd_cnt) { 63361ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_SD_INDEX; 63461ae650dSJack F Vogel goto exit; 63561ae650dSJack F Vogel } 63661ae650dSJack F Vogel 63761ae650dSJack F Vogel for (i = sd_idx; i < sd_lmt; i++) { 63861ae650dSJack F Vogel if (!info->hmc_info->sd_table.sd_entry[i].valid) 63961ae650dSJack F Vogel continue; 64061ae650dSJack F Vogel switch (info->hmc_info->sd_table.sd_entry[i].entry_type) { 64161ae650dSJack F Vogel case I40E_SD_TYPE_DIRECT: 64261ae650dSJack F Vogel ret_code = i40e_remove_sd_bp(hw, info->hmc_info, i); 64361ae650dSJack F Vogel if (I40E_SUCCESS != ret_code) 64461ae650dSJack F Vogel goto exit; 64561ae650dSJack F Vogel break; 64661ae650dSJack F Vogel case I40E_SD_TYPE_PAGED: 64761ae650dSJack F Vogel ret_code = i40e_remove_pd_page(hw, info->hmc_info, i); 64861ae650dSJack F Vogel if (I40E_SUCCESS != ret_code) 64961ae650dSJack F Vogel goto exit; 65061ae650dSJack F Vogel break; 65161ae650dSJack F Vogel default: 65261ae650dSJack F Vogel break; 65361ae650dSJack F Vogel } 65461ae650dSJack F Vogel } 65561ae650dSJack F Vogel exit: 65661ae650dSJack F Vogel return ret_code; 65761ae650dSJack F Vogel } 65861ae650dSJack F Vogel 65961ae650dSJack F Vogel /** 66061ae650dSJack F Vogel * i40e_shutdown_lan_hmc - Remove HMC backing store, free allocated memory 66161ae650dSJack F Vogel * @hw: pointer to the hw structure 66261ae650dSJack F Vogel * 66361ae650dSJack F Vogel * This must be called by drivers as they are shutting down and being 66461ae650dSJack F Vogel * removed from the OS. 66561ae650dSJack F Vogel **/ 66661ae650dSJack F Vogel enum i40e_status_code i40e_shutdown_lan_hmc(struct i40e_hw *hw) 66761ae650dSJack F Vogel { 66861ae650dSJack F Vogel struct i40e_hmc_lan_delete_obj_info info; 66961ae650dSJack F Vogel enum i40e_status_code ret_code; 67061ae650dSJack F Vogel 67161ae650dSJack F Vogel info.hmc_info = &hw->hmc; 67261ae650dSJack F Vogel info.rsrc_type = I40E_HMC_LAN_FULL; 67361ae650dSJack F Vogel info.start_idx = 0; 67461ae650dSJack F Vogel info.count = 1; 67561ae650dSJack F Vogel 67661ae650dSJack F Vogel /* delete the object */ 67761ae650dSJack F Vogel ret_code = i40e_delete_lan_hmc_object(hw, &info); 67861ae650dSJack F Vogel 67961ae650dSJack F Vogel /* free the SD table entry for LAN */ 68061ae650dSJack F Vogel i40e_free_virt_mem(hw, &hw->hmc.sd_table.addr); 68161ae650dSJack F Vogel hw->hmc.sd_table.sd_cnt = 0; 68261ae650dSJack F Vogel hw->hmc.sd_table.sd_entry = NULL; 68361ae650dSJack F Vogel 68461ae650dSJack F Vogel /* free memory used for hmc_obj */ 68561ae650dSJack F Vogel i40e_free_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem); 68661ae650dSJack F Vogel hw->hmc.hmc_obj = NULL; 68761ae650dSJack F Vogel 68861ae650dSJack F Vogel return ret_code; 68961ae650dSJack F Vogel } 69061ae650dSJack F Vogel 69161ae650dSJack F Vogel #define I40E_HMC_STORE(_struct, _ele) \ 69261ae650dSJack F Vogel offsetof(struct _struct, _ele), \ 69361ae650dSJack F Vogel FIELD_SIZEOF(struct _struct, _ele) 69461ae650dSJack F Vogel 69561ae650dSJack F Vogel struct i40e_context_ele { 69661ae650dSJack F Vogel u16 offset; 69761ae650dSJack F Vogel u16 size_of; 69861ae650dSJack F Vogel u16 width; 69961ae650dSJack F Vogel u16 lsb; 70061ae650dSJack F Vogel }; 70161ae650dSJack F Vogel 70261ae650dSJack F Vogel /* LAN Tx Queue Context */ 70361ae650dSJack F Vogel static struct i40e_context_ele i40e_hmc_txq_ce_info[] = { 70461ae650dSJack F Vogel /* Field Width LSB */ 70561ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, head), 13, 0 }, 70661ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, new_context), 1, 30 }, 70761ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, base), 57, 32 }, 70861ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, fc_ena), 1, 89 }, 70961ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, timesync_ena), 1, 90 }, 71061ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, fd_ena), 1, 91 }, 71161ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, alt_vlan_ena), 1, 92 }, 71261ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, cpuid), 8, 96 }, 71361ae650dSJack F Vogel /* line 1 */ 71461ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, thead_wb), 13, 0 + 128 }, 71561ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, head_wb_ena), 1, 32 + 128 }, 71661ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, qlen), 13, 33 + 128 }, 71761ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, tphrdesc_ena), 1, 46 + 128 }, 71861ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, tphrpacket_ena), 1, 47 + 128 }, 71961ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, tphwdesc_ena), 1, 48 + 128 }, 72061ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, head_wb_addr), 64, 64 + 128 }, 72161ae650dSJack F Vogel /* line 7 */ 72261ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, crc), 32, 0 + (7 * 128) }, 72361ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, rdylist), 10, 84 + (7 * 128) }, 72461ae650dSJack F Vogel {I40E_HMC_STORE(i40e_hmc_obj_txq, rdylist_act), 1, 94 + (7 * 128) }, 72561ae650dSJack F Vogel { 0 } 72661ae650dSJack F Vogel }; 72761ae650dSJack F Vogel 72861ae650dSJack F Vogel /* LAN Rx Queue Context */ 72961ae650dSJack F Vogel static struct i40e_context_ele i40e_hmc_rxq_ce_info[] = { 73061ae650dSJack F Vogel /* Field Width LSB */ 73161ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, head), 13, 0 }, 73261ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, cpuid), 8, 13 }, 73361ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, base), 57, 32 }, 73461ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, qlen), 13, 89 }, 73561ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, dbuff), 7, 102 }, 73661ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, hbuff), 5, 109 }, 73761ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, dtype), 2, 114 }, 73861ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, dsize), 1, 116 }, 73961ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, crcstrip), 1, 117 }, 74061ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, fc_ena), 1, 118 }, 74161ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, l2tsel), 1, 119 }, 74261ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, hsplit_0), 4, 120 }, 74361ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, hsplit_1), 2, 124 }, 74461ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, showiv), 1, 127 }, 74561ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, rxmax), 14, 174 }, 74661ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphrdesc_ena), 1, 193 }, 74761ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphwdesc_ena), 1, 194 }, 74861ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphdata_ena), 1, 195 }, 74961ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphhead_ena), 1, 196 }, 75061ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, lrxqthresh), 3, 198 }, 75161ae650dSJack F Vogel { I40E_HMC_STORE(i40e_hmc_obj_rxq, prefena), 1, 201 }, 75261ae650dSJack F Vogel { 0 } 75361ae650dSJack F Vogel }; 75461ae650dSJack F Vogel 75561ae650dSJack F Vogel /** 75661ae650dSJack F Vogel * i40e_write_byte - replace HMC context byte 75761ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory 75861ae650dSJack F Vogel * @ce_info: a description of the struct to be read from 75961ae650dSJack F Vogel * @src: the struct to be read from 76061ae650dSJack F Vogel **/ 76161ae650dSJack F Vogel static void i40e_write_byte(u8 *hmc_bits, 76261ae650dSJack F Vogel struct i40e_context_ele *ce_info, 76361ae650dSJack F Vogel u8 *src) 76461ae650dSJack F Vogel { 76561ae650dSJack F Vogel u8 src_byte, dest_byte, mask; 76661ae650dSJack F Vogel u8 *from, *dest; 76761ae650dSJack F Vogel u16 shift_width; 76861ae650dSJack F Vogel 76961ae650dSJack F Vogel /* copy from the next struct field */ 77061ae650dSJack F Vogel from = src + ce_info->offset; 77161ae650dSJack F Vogel 77261ae650dSJack F Vogel /* prepare the bits and mask */ 77361ae650dSJack F Vogel shift_width = ce_info->lsb % 8; 77461ae650dSJack F Vogel mask = ((u8)1 << ce_info->width) - 1; 77561ae650dSJack F Vogel 77661ae650dSJack F Vogel src_byte = *from; 77761ae650dSJack F Vogel src_byte &= mask; 77861ae650dSJack F Vogel 77961ae650dSJack F Vogel /* shift to correct alignment */ 78061ae650dSJack F Vogel mask <<= shift_width; 78161ae650dSJack F Vogel src_byte <<= shift_width; 78261ae650dSJack F Vogel 78361ae650dSJack F Vogel /* get the current bits from the target bit string */ 78461ae650dSJack F Vogel dest = hmc_bits + (ce_info->lsb / 8); 78561ae650dSJack F Vogel 78661ae650dSJack F Vogel i40e_memcpy(&dest_byte, dest, sizeof(dest_byte), I40E_DMA_TO_NONDMA); 78761ae650dSJack F Vogel 78861ae650dSJack F Vogel dest_byte &= ~mask; /* get the bits not changing */ 78961ae650dSJack F Vogel dest_byte |= src_byte; /* add in the new bits */ 79061ae650dSJack F Vogel 79161ae650dSJack F Vogel /* put it all back */ 79261ae650dSJack F Vogel i40e_memcpy(dest, &dest_byte, sizeof(dest_byte), I40E_NONDMA_TO_DMA); 79361ae650dSJack F Vogel } 79461ae650dSJack F Vogel 79561ae650dSJack F Vogel /** 79661ae650dSJack F Vogel * i40e_write_word - replace HMC context word 79761ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory 79861ae650dSJack F Vogel * @ce_info: a description of the struct to be read from 79961ae650dSJack F Vogel * @src: the struct to be read from 80061ae650dSJack F Vogel **/ 80161ae650dSJack F Vogel static void i40e_write_word(u8 *hmc_bits, 80261ae650dSJack F Vogel struct i40e_context_ele *ce_info, 80361ae650dSJack F Vogel u8 *src) 80461ae650dSJack F Vogel { 80561ae650dSJack F Vogel u16 src_word, mask; 80661ae650dSJack F Vogel u8 *from, *dest; 80761ae650dSJack F Vogel u16 shift_width; 80861ae650dSJack F Vogel __le16 dest_word; 80961ae650dSJack F Vogel 81061ae650dSJack F Vogel /* copy from the next struct field */ 81161ae650dSJack F Vogel from = src + ce_info->offset; 81261ae650dSJack F Vogel 81361ae650dSJack F Vogel /* prepare the bits and mask */ 81461ae650dSJack F Vogel shift_width = ce_info->lsb % 8; 81561ae650dSJack F Vogel mask = ((u16)1 << ce_info->width) - 1; 81661ae650dSJack F Vogel 81761ae650dSJack F Vogel /* don't swizzle the bits until after the mask because the mask bits 81861ae650dSJack F Vogel * will be in a different bit position on big endian machines 81961ae650dSJack F Vogel */ 82061ae650dSJack F Vogel src_word = *(u16 *)from; 82161ae650dSJack F Vogel src_word &= mask; 82261ae650dSJack F Vogel 82361ae650dSJack F Vogel /* shift to correct alignment */ 82461ae650dSJack F Vogel mask <<= shift_width; 82561ae650dSJack F Vogel src_word <<= shift_width; 82661ae650dSJack F Vogel 82761ae650dSJack F Vogel /* get the current bits from the target bit string */ 82861ae650dSJack F Vogel dest = hmc_bits + (ce_info->lsb / 8); 82961ae650dSJack F Vogel 83061ae650dSJack F Vogel i40e_memcpy(&dest_word, dest, sizeof(dest_word), I40E_DMA_TO_NONDMA); 83161ae650dSJack F Vogel 83261ae650dSJack F Vogel dest_word &= ~(CPU_TO_LE16(mask)); /* get the bits not changing */ 83361ae650dSJack F Vogel dest_word |= CPU_TO_LE16(src_word); /* add in the new bits */ 83461ae650dSJack F Vogel 83561ae650dSJack F Vogel /* put it all back */ 83661ae650dSJack F Vogel i40e_memcpy(dest, &dest_word, sizeof(dest_word), I40E_NONDMA_TO_DMA); 83761ae650dSJack F Vogel } 83861ae650dSJack F Vogel 83961ae650dSJack F Vogel /** 84061ae650dSJack F Vogel * i40e_write_dword - replace HMC context dword 84161ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory 84261ae650dSJack F Vogel * @ce_info: a description of the struct to be read from 84361ae650dSJack F Vogel * @src: the struct to be read from 84461ae650dSJack F Vogel **/ 84561ae650dSJack F Vogel static void i40e_write_dword(u8 *hmc_bits, 84661ae650dSJack F Vogel struct i40e_context_ele *ce_info, 84761ae650dSJack F Vogel u8 *src) 84861ae650dSJack F Vogel { 84961ae650dSJack F Vogel u32 src_dword, mask; 85061ae650dSJack F Vogel u8 *from, *dest; 85161ae650dSJack F Vogel u16 shift_width; 85261ae650dSJack F Vogel __le32 dest_dword; 85361ae650dSJack F Vogel 85461ae650dSJack F Vogel /* copy from the next struct field */ 85561ae650dSJack F Vogel from = src + ce_info->offset; 85661ae650dSJack F Vogel 85761ae650dSJack F Vogel /* prepare the bits and mask */ 85861ae650dSJack F Vogel shift_width = ce_info->lsb % 8; 85961ae650dSJack F Vogel 86061ae650dSJack F Vogel /* if the field width is exactly 32 on an x86 machine, then the shift 86161ae650dSJack F Vogel * operation will not work because the SHL instructions count is masked 86261ae650dSJack F Vogel * to 5 bits so the shift will do nothing 86361ae650dSJack F Vogel */ 86461ae650dSJack F Vogel if (ce_info->width < 32) 86561ae650dSJack F Vogel mask = ((u32)1 << ce_info->width) - 1; 86661ae650dSJack F Vogel else 867*f247dc25SJack F Vogel mask = ~(u32)0; 86861ae650dSJack F Vogel 86961ae650dSJack F Vogel /* don't swizzle the bits until after the mask because the mask bits 87061ae650dSJack F Vogel * will be in a different bit position on big endian machines 87161ae650dSJack F Vogel */ 87261ae650dSJack F Vogel src_dword = *(u32 *)from; 87361ae650dSJack F Vogel src_dword &= mask; 87461ae650dSJack F Vogel 87561ae650dSJack F Vogel /* shift to correct alignment */ 87661ae650dSJack F Vogel mask <<= shift_width; 87761ae650dSJack F Vogel src_dword <<= shift_width; 87861ae650dSJack F Vogel 87961ae650dSJack F Vogel /* get the current bits from the target bit string */ 88061ae650dSJack F Vogel dest = hmc_bits + (ce_info->lsb / 8); 88161ae650dSJack F Vogel 88261ae650dSJack F Vogel i40e_memcpy(&dest_dword, dest, sizeof(dest_dword), I40E_DMA_TO_NONDMA); 88361ae650dSJack F Vogel 88461ae650dSJack F Vogel dest_dword &= ~(CPU_TO_LE32(mask)); /* get the bits not changing */ 88561ae650dSJack F Vogel dest_dword |= CPU_TO_LE32(src_dword); /* add in the new bits */ 88661ae650dSJack F Vogel 88761ae650dSJack F Vogel /* put it all back */ 88861ae650dSJack F Vogel i40e_memcpy(dest, &dest_dword, sizeof(dest_dword), I40E_NONDMA_TO_DMA); 88961ae650dSJack F Vogel } 89061ae650dSJack F Vogel 89161ae650dSJack F Vogel /** 89261ae650dSJack F Vogel * i40e_write_qword - replace HMC context qword 89361ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory 89461ae650dSJack F Vogel * @ce_info: a description of the struct to be read from 89561ae650dSJack F Vogel * @src: the struct to be read from 89661ae650dSJack F Vogel **/ 89761ae650dSJack F Vogel static void i40e_write_qword(u8 *hmc_bits, 89861ae650dSJack F Vogel struct i40e_context_ele *ce_info, 89961ae650dSJack F Vogel u8 *src) 90061ae650dSJack F Vogel { 90161ae650dSJack F Vogel u64 src_qword, mask; 90261ae650dSJack F Vogel u8 *from, *dest; 90361ae650dSJack F Vogel u16 shift_width; 90461ae650dSJack F Vogel __le64 dest_qword; 90561ae650dSJack F Vogel 90661ae650dSJack F Vogel /* copy from the next struct field */ 90761ae650dSJack F Vogel from = src + ce_info->offset; 90861ae650dSJack F Vogel 90961ae650dSJack F Vogel /* prepare the bits and mask */ 91061ae650dSJack F Vogel shift_width = ce_info->lsb % 8; 91161ae650dSJack F Vogel 91261ae650dSJack F Vogel /* if the field width is exactly 64 on an x86 machine, then the shift 91361ae650dSJack F Vogel * operation will not work because the SHL instructions count is masked 91461ae650dSJack F Vogel * to 6 bits so the shift will do nothing 91561ae650dSJack F Vogel */ 91661ae650dSJack F Vogel if (ce_info->width < 64) 91761ae650dSJack F Vogel mask = ((u64)1 << ce_info->width) - 1; 91861ae650dSJack F Vogel else 919*f247dc25SJack F Vogel mask = ~(u64)0; 92061ae650dSJack F Vogel 92161ae650dSJack F Vogel /* don't swizzle the bits until after the mask because the mask bits 92261ae650dSJack F Vogel * will be in a different bit position on big endian machines 92361ae650dSJack F Vogel */ 92461ae650dSJack F Vogel src_qword = *(u64 *)from; 92561ae650dSJack F Vogel src_qword &= mask; 92661ae650dSJack F Vogel 92761ae650dSJack F Vogel /* shift to correct alignment */ 92861ae650dSJack F Vogel mask <<= shift_width; 92961ae650dSJack F Vogel src_qword <<= shift_width; 93061ae650dSJack F Vogel 93161ae650dSJack F Vogel /* get the current bits from the target bit string */ 93261ae650dSJack F Vogel dest = hmc_bits + (ce_info->lsb / 8); 93361ae650dSJack F Vogel 93461ae650dSJack F Vogel i40e_memcpy(&dest_qword, dest, sizeof(dest_qword), I40E_DMA_TO_NONDMA); 93561ae650dSJack F Vogel 93661ae650dSJack F Vogel dest_qword &= ~(CPU_TO_LE64(mask)); /* get the bits not changing */ 93761ae650dSJack F Vogel dest_qword |= CPU_TO_LE64(src_qword); /* add in the new bits */ 93861ae650dSJack F Vogel 93961ae650dSJack F Vogel /* put it all back */ 94061ae650dSJack F Vogel i40e_memcpy(dest, &dest_qword, sizeof(dest_qword), I40E_NONDMA_TO_DMA); 94161ae650dSJack F Vogel } 94261ae650dSJack F Vogel 94361ae650dSJack F Vogel /** 94461ae650dSJack F Vogel * i40e_read_byte - read HMC context byte into struct 94561ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory 94661ae650dSJack F Vogel * @ce_info: a description of the struct to be filled 94761ae650dSJack F Vogel * @dest: the struct to be filled 94861ae650dSJack F Vogel **/ 94961ae650dSJack F Vogel static void i40e_read_byte(u8 *hmc_bits, 95061ae650dSJack F Vogel struct i40e_context_ele *ce_info, 95161ae650dSJack F Vogel u8 *dest) 95261ae650dSJack F Vogel { 95361ae650dSJack F Vogel u8 dest_byte, mask; 95461ae650dSJack F Vogel u8 *src, *target; 95561ae650dSJack F Vogel u16 shift_width; 95661ae650dSJack F Vogel 95761ae650dSJack F Vogel /* prepare the bits and mask */ 95861ae650dSJack F Vogel shift_width = ce_info->lsb % 8; 95961ae650dSJack F Vogel mask = ((u8)1 << ce_info->width) - 1; 96061ae650dSJack F Vogel 96161ae650dSJack F Vogel /* shift to correct alignment */ 96261ae650dSJack F Vogel mask <<= shift_width; 96361ae650dSJack F Vogel 96461ae650dSJack F Vogel /* get the current bits from the src bit string */ 96561ae650dSJack F Vogel src = hmc_bits + (ce_info->lsb / 8); 96661ae650dSJack F Vogel 96761ae650dSJack F Vogel i40e_memcpy(&dest_byte, src, sizeof(dest_byte), I40E_DMA_TO_NONDMA); 96861ae650dSJack F Vogel 96961ae650dSJack F Vogel dest_byte &= ~(mask); 97061ae650dSJack F Vogel 97161ae650dSJack F Vogel dest_byte >>= shift_width; 97261ae650dSJack F Vogel 97361ae650dSJack F Vogel /* get the address from the struct field */ 97461ae650dSJack F Vogel target = dest + ce_info->offset; 97561ae650dSJack F Vogel 97661ae650dSJack F Vogel /* put it back in the struct */ 97761ae650dSJack F Vogel i40e_memcpy(target, &dest_byte, sizeof(dest_byte), I40E_NONDMA_TO_DMA); 97861ae650dSJack F Vogel } 97961ae650dSJack F Vogel 98061ae650dSJack F Vogel /** 98161ae650dSJack F Vogel * i40e_read_word - read HMC context word into struct 98261ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory 98361ae650dSJack F Vogel * @ce_info: a description of the struct to be filled 98461ae650dSJack F Vogel * @dest: the struct to be filled 98561ae650dSJack F Vogel **/ 98661ae650dSJack F Vogel static void i40e_read_word(u8 *hmc_bits, 98761ae650dSJack F Vogel struct i40e_context_ele *ce_info, 98861ae650dSJack F Vogel u8 *dest) 98961ae650dSJack F Vogel { 99061ae650dSJack F Vogel u16 dest_word, mask; 99161ae650dSJack F Vogel u8 *src, *target; 99261ae650dSJack F Vogel u16 shift_width; 99361ae650dSJack F Vogel __le16 src_word; 99461ae650dSJack F Vogel 99561ae650dSJack F Vogel /* prepare the bits and mask */ 99661ae650dSJack F Vogel shift_width = ce_info->lsb % 8; 99761ae650dSJack F Vogel mask = ((u16)1 << ce_info->width) - 1; 99861ae650dSJack F Vogel 99961ae650dSJack F Vogel /* shift to correct alignment */ 100061ae650dSJack F Vogel mask <<= shift_width; 100161ae650dSJack F Vogel 100261ae650dSJack F Vogel /* get the current bits from the src bit string */ 100361ae650dSJack F Vogel src = hmc_bits + (ce_info->lsb / 8); 100461ae650dSJack F Vogel 100561ae650dSJack F Vogel i40e_memcpy(&src_word, src, sizeof(src_word), I40E_DMA_TO_NONDMA); 100661ae650dSJack F Vogel 100761ae650dSJack F Vogel /* the data in the memory is stored as little endian so mask it 100861ae650dSJack F Vogel * correctly 100961ae650dSJack F Vogel */ 101061ae650dSJack F Vogel src_word &= ~(CPU_TO_LE16(mask)); 101161ae650dSJack F Vogel 101261ae650dSJack F Vogel /* get the data back into host order before shifting */ 101361ae650dSJack F Vogel dest_word = LE16_TO_CPU(src_word); 101461ae650dSJack F Vogel 101561ae650dSJack F Vogel dest_word >>= shift_width; 101661ae650dSJack F Vogel 101761ae650dSJack F Vogel /* get the address from the struct field */ 101861ae650dSJack F Vogel target = dest + ce_info->offset; 101961ae650dSJack F Vogel 102061ae650dSJack F Vogel /* put it back in the struct */ 102161ae650dSJack F Vogel i40e_memcpy(target, &dest_word, sizeof(dest_word), I40E_NONDMA_TO_DMA); 102261ae650dSJack F Vogel } 102361ae650dSJack F Vogel 102461ae650dSJack F Vogel /** 102561ae650dSJack F Vogel * i40e_read_dword - read HMC context dword into struct 102661ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory 102761ae650dSJack F Vogel * @ce_info: a description of the struct to be filled 102861ae650dSJack F Vogel * @dest: the struct to be filled 102961ae650dSJack F Vogel **/ 103061ae650dSJack F Vogel static void i40e_read_dword(u8 *hmc_bits, 103161ae650dSJack F Vogel struct i40e_context_ele *ce_info, 103261ae650dSJack F Vogel u8 *dest) 103361ae650dSJack F Vogel { 103461ae650dSJack F Vogel u32 dest_dword, mask; 103561ae650dSJack F Vogel u8 *src, *target; 103661ae650dSJack F Vogel u16 shift_width; 103761ae650dSJack F Vogel __le32 src_dword; 103861ae650dSJack F Vogel 103961ae650dSJack F Vogel /* prepare the bits and mask */ 104061ae650dSJack F Vogel shift_width = ce_info->lsb % 8; 104161ae650dSJack F Vogel 104261ae650dSJack F Vogel /* if the field width is exactly 32 on an x86 machine, then the shift 104361ae650dSJack F Vogel * operation will not work because the SHL instructions count is masked 104461ae650dSJack F Vogel * to 5 bits so the shift will do nothing 104561ae650dSJack F Vogel */ 104661ae650dSJack F Vogel if (ce_info->width < 32) 104761ae650dSJack F Vogel mask = ((u32)1 << ce_info->width) - 1; 104861ae650dSJack F Vogel else 1049*f247dc25SJack F Vogel mask = ~(u32)0; 105061ae650dSJack F Vogel 105161ae650dSJack F Vogel /* shift to correct alignment */ 105261ae650dSJack F Vogel mask <<= shift_width; 105361ae650dSJack F Vogel 105461ae650dSJack F Vogel /* get the current bits from the src bit string */ 105561ae650dSJack F Vogel src = hmc_bits + (ce_info->lsb / 8); 105661ae650dSJack F Vogel 105761ae650dSJack F Vogel i40e_memcpy(&src_dword, src, sizeof(src_dword), I40E_DMA_TO_NONDMA); 105861ae650dSJack F Vogel 105961ae650dSJack F Vogel /* the data in the memory is stored as little endian so mask it 106061ae650dSJack F Vogel * correctly 106161ae650dSJack F Vogel */ 106261ae650dSJack F Vogel src_dword &= ~(CPU_TO_LE32(mask)); 106361ae650dSJack F Vogel 106461ae650dSJack F Vogel /* get the data back into host order before shifting */ 106561ae650dSJack F Vogel dest_dword = LE32_TO_CPU(src_dword); 106661ae650dSJack F Vogel 106761ae650dSJack F Vogel dest_dword >>= shift_width; 106861ae650dSJack F Vogel 106961ae650dSJack F Vogel /* get the address from the struct field */ 107061ae650dSJack F Vogel target = dest + ce_info->offset; 107161ae650dSJack F Vogel 107261ae650dSJack F Vogel /* put it back in the struct */ 107361ae650dSJack F Vogel i40e_memcpy(target, &dest_dword, sizeof(dest_dword), 107461ae650dSJack F Vogel I40E_NONDMA_TO_DMA); 107561ae650dSJack F Vogel } 107661ae650dSJack F Vogel 107761ae650dSJack F Vogel /** 107861ae650dSJack F Vogel * i40e_read_qword - read HMC context qword into struct 107961ae650dSJack F Vogel * @hmc_bits: pointer to the HMC memory 108061ae650dSJack F Vogel * @ce_info: a description of the struct to be filled 108161ae650dSJack F Vogel * @dest: the struct to be filled 108261ae650dSJack F Vogel **/ 108361ae650dSJack F Vogel static void i40e_read_qword(u8 *hmc_bits, 108461ae650dSJack F Vogel struct i40e_context_ele *ce_info, 108561ae650dSJack F Vogel u8 *dest) 108661ae650dSJack F Vogel { 108761ae650dSJack F Vogel u64 dest_qword, mask; 108861ae650dSJack F Vogel u8 *src, *target; 108961ae650dSJack F Vogel u16 shift_width; 109061ae650dSJack F Vogel __le64 src_qword; 109161ae650dSJack F Vogel 109261ae650dSJack F Vogel /* prepare the bits and mask */ 109361ae650dSJack F Vogel shift_width = ce_info->lsb % 8; 109461ae650dSJack F Vogel 109561ae650dSJack F Vogel /* if the field width is exactly 64 on an x86 machine, then the shift 109661ae650dSJack F Vogel * operation will not work because the SHL instructions count is masked 109761ae650dSJack F Vogel * to 6 bits so the shift will do nothing 109861ae650dSJack F Vogel */ 109961ae650dSJack F Vogel if (ce_info->width < 64) 110061ae650dSJack F Vogel mask = ((u64)1 << ce_info->width) - 1; 110161ae650dSJack F Vogel else 1102*f247dc25SJack F Vogel mask = ~(u64)0; 110361ae650dSJack F Vogel 110461ae650dSJack F Vogel /* shift to correct alignment */ 110561ae650dSJack F Vogel mask <<= shift_width; 110661ae650dSJack F Vogel 110761ae650dSJack F Vogel /* get the current bits from the src bit string */ 110861ae650dSJack F Vogel src = hmc_bits + (ce_info->lsb / 8); 110961ae650dSJack F Vogel 111061ae650dSJack F Vogel i40e_memcpy(&src_qword, src, sizeof(src_qword), I40E_DMA_TO_NONDMA); 111161ae650dSJack F Vogel 111261ae650dSJack F Vogel /* the data in the memory is stored as little endian so mask it 111361ae650dSJack F Vogel * correctly 111461ae650dSJack F Vogel */ 111561ae650dSJack F Vogel src_qword &= ~(CPU_TO_LE64(mask)); 111661ae650dSJack F Vogel 111761ae650dSJack F Vogel /* get the data back into host order before shifting */ 111861ae650dSJack F Vogel dest_qword = LE64_TO_CPU(src_qword); 111961ae650dSJack F Vogel 112061ae650dSJack F Vogel dest_qword >>= shift_width; 112161ae650dSJack F Vogel 112261ae650dSJack F Vogel /* get the address from the struct field */ 112361ae650dSJack F Vogel target = dest + ce_info->offset; 112461ae650dSJack F Vogel 112561ae650dSJack F Vogel /* put it back in the struct */ 112661ae650dSJack F Vogel i40e_memcpy(target, &dest_qword, sizeof(dest_qword), 112761ae650dSJack F Vogel I40E_NONDMA_TO_DMA); 112861ae650dSJack F Vogel } 112961ae650dSJack F Vogel 113061ae650dSJack F Vogel /** 113161ae650dSJack F Vogel * i40e_get_hmc_context - extract HMC context bits 113261ae650dSJack F Vogel * @context_bytes: pointer to the context bit array 113361ae650dSJack F Vogel * @ce_info: a description of the struct to be filled 113461ae650dSJack F Vogel * @dest: the struct to be filled 113561ae650dSJack F Vogel **/ 113661ae650dSJack F Vogel static enum i40e_status_code i40e_get_hmc_context(u8 *context_bytes, 113761ae650dSJack F Vogel struct i40e_context_ele *ce_info, 113861ae650dSJack F Vogel u8 *dest) 113961ae650dSJack F Vogel { 114061ae650dSJack F Vogel int f; 114161ae650dSJack F Vogel 114261ae650dSJack F Vogel for (f = 0; ce_info[f].width != 0; f++) { 114361ae650dSJack F Vogel switch (ce_info[f].size_of) { 114461ae650dSJack F Vogel case 1: 114561ae650dSJack F Vogel i40e_read_byte(context_bytes, &ce_info[f], dest); 114661ae650dSJack F Vogel break; 114761ae650dSJack F Vogel case 2: 114861ae650dSJack F Vogel i40e_read_word(context_bytes, &ce_info[f], dest); 114961ae650dSJack F Vogel break; 115061ae650dSJack F Vogel case 4: 115161ae650dSJack F Vogel i40e_read_dword(context_bytes, &ce_info[f], dest); 115261ae650dSJack F Vogel break; 115361ae650dSJack F Vogel case 8: 115461ae650dSJack F Vogel i40e_read_qword(context_bytes, &ce_info[f], dest); 115561ae650dSJack F Vogel break; 115661ae650dSJack F Vogel default: 115761ae650dSJack F Vogel /* nothing to do, just keep going */ 115861ae650dSJack F Vogel break; 115961ae650dSJack F Vogel } 116061ae650dSJack F Vogel } 116161ae650dSJack F Vogel 116261ae650dSJack F Vogel return I40E_SUCCESS; 116361ae650dSJack F Vogel } 116461ae650dSJack F Vogel 116561ae650dSJack F Vogel /** 116661ae650dSJack F Vogel * i40e_clear_hmc_context - zero out the HMC context bits 116761ae650dSJack F Vogel * @hw: the hardware struct 116861ae650dSJack F Vogel * @context_bytes: pointer to the context bit array (DMA memory) 116961ae650dSJack F Vogel * @hmc_type: the type of HMC resource 117061ae650dSJack F Vogel **/ 117161ae650dSJack F Vogel static enum i40e_status_code i40e_clear_hmc_context(struct i40e_hw *hw, 117261ae650dSJack F Vogel u8 *context_bytes, 117361ae650dSJack F Vogel enum i40e_hmc_lan_rsrc_type hmc_type) 117461ae650dSJack F Vogel { 117561ae650dSJack F Vogel /* clean the bit array */ 117661ae650dSJack F Vogel i40e_memset(context_bytes, 0, (u32)hw->hmc.hmc_obj[hmc_type].size, 117761ae650dSJack F Vogel I40E_DMA_MEM); 117861ae650dSJack F Vogel 117961ae650dSJack F Vogel return I40E_SUCCESS; 118061ae650dSJack F Vogel } 118161ae650dSJack F Vogel 118261ae650dSJack F Vogel /** 118361ae650dSJack F Vogel * i40e_set_hmc_context - replace HMC context bits 118461ae650dSJack F Vogel * @context_bytes: pointer to the context bit array 118561ae650dSJack F Vogel * @ce_info: a description of the struct to be filled 118661ae650dSJack F Vogel * @dest: the struct to be filled 118761ae650dSJack F Vogel **/ 118861ae650dSJack F Vogel static enum i40e_status_code i40e_set_hmc_context(u8 *context_bytes, 118961ae650dSJack F Vogel struct i40e_context_ele *ce_info, 119061ae650dSJack F Vogel u8 *dest) 119161ae650dSJack F Vogel { 119261ae650dSJack F Vogel int f; 119361ae650dSJack F Vogel 119461ae650dSJack F Vogel for (f = 0; ce_info[f].width != 0; f++) { 119561ae650dSJack F Vogel 119661ae650dSJack F Vogel /* we have to deal with each element of the HMC using the 119761ae650dSJack F Vogel * correct size so that we are correct regardless of the 119861ae650dSJack F Vogel * endianness of the machine 119961ae650dSJack F Vogel */ 120061ae650dSJack F Vogel switch (ce_info[f].size_of) { 120161ae650dSJack F Vogel case 1: 120261ae650dSJack F Vogel i40e_write_byte(context_bytes, &ce_info[f], dest); 120361ae650dSJack F Vogel break; 120461ae650dSJack F Vogel case 2: 120561ae650dSJack F Vogel i40e_write_word(context_bytes, &ce_info[f], dest); 120661ae650dSJack F Vogel break; 120761ae650dSJack F Vogel case 4: 120861ae650dSJack F Vogel i40e_write_dword(context_bytes, &ce_info[f], dest); 120961ae650dSJack F Vogel break; 121061ae650dSJack F Vogel case 8: 121161ae650dSJack F Vogel i40e_write_qword(context_bytes, &ce_info[f], dest); 121261ae650dSJack F Vogel break; 121361ae650dSJack F Vogel } 121461ae650dSJack F Vogel } 121561ae650dSJack F Vogel 121661ae650dSJack F Vogel return I40E_SUCCESS; 121761ae650dSJack F Vogel } 121861ae650dSJack F Vogel 121961ae650dSJack F Vogel /** 122061ae650dSJack F Vogel * i40e_hmc_get_object_va - retrieves an object's virtual address 122161ae650dSJack F Vogel * @hmc_info: pointer to i40e_hmc_info struct 122261ae650dSJack F Vogel * @object_base: pointer to u64 to get the va 122361ae650dSJack F Vogel * @rsrc_type: the hmc resource type 122461ae650dSJack F Vogel * @obj_idx: hmc object index 122561ae650dSJack F Vogel * 122661ae650dSJack F Vogel * This function retrieves the object's virtual address from the object 122761ae650dSJack F Vogel * base pointer. This function is used for LAN Queue contexts. 122861ae650dSJack F Vogel **/ 122961ae650dSJack F Vogel static 123061ae650dSJack F Vogel enum i40e_status_code i40e_hmc_get_object_va(struct i40e_hmc_info *hmc_info, 123161ae650dSJack F Vogel u8 **object_base, 123261ae650dSJack F Vogel enum i40e_hmc_lan_rsrc_type rsrc_type, 123361ae650dSJack F Vogel u32 obj_idx) 123461ae650dSJack F Vogel { 123561ae650dSJack F Vogel u32 obj_offset_in_sd, obj_offset_in_pd; 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) { 124461ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR; 124561ae650dSJack F Vogel DEBUGOUT("i40e_hmc_get_object_va: bad hmc_info ptr\n"); 124661ae650dSJack F Vogel goto exit; 124761ae650dSJack F Vogel } 124861ae650dSJack F Vogel if (NULL == hmc_info->hmc_obj) { 124961ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR; 125061ae650dSJack F Vogel DEBUGOUT("i40e_hmc_get_object_va: bad hmc_info->hmc_obj ptr\n"); 125161ae650dSJack F Vogel goto exit; 125261ae650dSJack F Vogel } 125361ae650dSJack F Vogel if (NULL == object_base) { 125461ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR; 125561ae650dSJack F Vogel DEBUGOUT("i40e_hmc_get_object_va: bad object_base ptr\n"); 125661ae650dSJack F Vogel goto exit; 125761ae650dSJack F Vogel } 125861ae650dSJack F Vogel if (I40E_HMC_INFO_SIGNATURE != hmc_info->signature) { 125961ae650dSJack F Vogel ret_code = I40E_ERR_BAD_PTR; 126061ae650dSJack F Vogel DEBUGOUT("i40e_hmc_get_object_va: bad hmc_info->signature\n"); 126161ae650dSJack F Vogel goto exit; 126261ae650dSJack F Vogel } 126361ae650dSJack F Vogel if (obj_idx >= hmc_info->hmc_obj[rsrc_type].cnt) { 126461ae650dSJack F Vogel DEBUGOUT1("i40e_hmc_get_object_va: returns error %d\n", 126561ae650dSJack F Vogel ret_code); 126661ae650dSJack F Vogel ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX; 126761ae650dSJack F Vogel goto exit; 126861ae650dSJack F Vogel } 126961ae650dSJack F Vogel /* find sd index and limit */ 127061ae650dSJack F Vogel I40E_FIND_SD_INDEX_LIMIT(hmc_info, rsrc_type, obj_idx, 1, 127161ae650dSJack F Vogel &sd_idx, &sd_lmt); 127261ae650dSJack F Vogel 127361ae650dSJack F Vogel sd_entry = &hmc_info->sd_table.sd_entry[sd_idx]; 127461ae650dSJack F Vogel obj_offset_in_fpm = hmc_info->hmc_obj[rsrc_type].base + 127561ae650dSJack F Vogel hmc_info->hmc_obj[rsrc_type].size * obj_idx; 127661ae650dSJack F Vogel 127761ae650dSJack F Vogel if (I40E_SD_TYPE_PAGED == sd_entry->entry_type) { 127861ae650dSJack F Vogel I40E_FIND_PD_INDEX_LIMIT(hmc_info, rsrc_type, obj_idx, 1, 127961ae650dSJack F Vogel &pd_idx, &pd_lmt); 128061ae650dSJack F Vogel rel_pd_idx = pd_idx % I40E_HMC_PD_CNT_IN_SD; 128161ae650dSJack F Vogel pd_entry = &sd_entry->u.pd_table.pd_entry[rel_pd_idx]; 128261ae650dSJack F Vogel obj_offset_in_pd = (u32)(obj_offset_in_fpm % 128361ae650dSJack F Vogel I40E_HMC_PAGED_BP_SIZE); 128461ae650dSJack F Vogel *object_base = (u8 *)pd_entry->bp.addr.va + obj_offset_in_pd; 128561ae650dSJack F Vogel } else { 128661ae650dSJack F Vogel obj_offset_in_sd = (u32)(obj_offset_in_fpm % 128761ae650dSJack F Vogel I40E_HMC_DIRECT_BP_SIZE); 128861ae650dSJack F Vogel *object_base = (u8 *)sd_entry->u.bp.addr.va + obj_offset_in_sd; 128961ae650dSJack F Vogel } 129061ae650dSJack F Vogel exit: 129161ae650dSJack F Vogel return ret_code; 129261ae650dSJack F Vogel } 129361ae650dSJack F Vogel 129461ae650dSJack F Vogel /** 129561ae650dSJack F Vogel * i40e_get_lan_tx_queue_context - return the HMC context for the queue 129661ae650dSJack F Vogel * @hw: the hardware struct 129761ae650dSJack F Vogel * @queue: the queue we care about 129861ae650dSJack F Vogel * @s: the struct to be filled 129961ae650dSJack F Vogel **/ 130061ae650dSJack F Vogel enum i40e_status_code i40e_get_lan_tx_queue_context(struct i40e_hw *hw, 130161ae650dSJack F Vogel u16 queue, 130261ae650dSJack F Vogel struct i40e_hmc_obj_txq *s) 130361ae650dSJack F Vogel { 130461ae650dSJack F Vogel enum i40e_status_code err; 130561ae650dSJack F Vogel u8 *context_bytes; 130661ae650dSJack F Vogel 130761ae650dSJack F Vogel err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, 130861ae650dSJack F Vogel I40E_HMC_LAN_TX, queue); 130961ae650dSJack F Vogel if (err < 0) 131061ae650dSJack F Vogel return err; 131161ae650dSJack F Vogel 131261ae650dSJack F Vogel return i40e_get_hmc_context(context_bytes, 131361ae650dSJack F Vogel i40e_hmc_txq_ce_info, (u8 *)s); 131461ae650dSJack F Vogel } 131561ae650dSJack F Vogel 131661ae650dSJack F Vogel /** 131761ae650dSJack F Vogel * i40e_clear_lan_tx_queue_context - clear the HMC context for the queue 131861ae650dSJack F Vogel * @hw: the hardware struct 131961ae650dSJack F Vogel * @queue: the queue we care about 132061ae650dSJack F Vogel **/ 132161ae650dSJack F Vogel enum i40e_status_code i40e_clear_lan_tx_queue_context(struct i40e_hw *hw, 132261ae650dSJack F Vogel u16 queue) 132361ae650dSJack F Vogel { 132461ae650dSJack F Vogel enum i40e_status_code err; 132561ae650dSJack F Vogel u8 *context_bytes; 132661ae650dSJack F Vogel 132761ae650dSJack F Vogel err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, 132861ae650dSJack F Vogel I40E_HMC_LAN_TX, queue); 132961ae650dSJack F Vogel if (err < 0) 133061ae650dSJack F Vogel return err; 133161ae650dSJack F Vogel 133261ae650dSJack F Vogel return i40e_clear_hmc_context(hw, context_bytes, I40E_HMC_LAN_TX); 133361ae650dSJack F Vogel } 133461ae650dSJack F Vogel 133561ae650dSJack F Vogel /** 133661ae650dSJack F Vogel * i40e_set_lan_tx_queue_context - set the HMC context for the queue 133761ae650dSJack F Vogel * @hw: the hardware struct 133861ae650dSJack F Vogel * @queue: the queue we care about 133961ae650dSJack F Vogel * @s: the struct to be filled 134061ae650dSJack F Vogel **/ 134161ae650dSJack F Vogel enum i40e_status_code i40e_set_lan_tx_queue_context(struct i40e_hw *hw, 134261ae650dSJack F Vogel u16 queue, 134361ae650dSJack F Vogel struct i40e_hmc_obj_txq *s) 134461ae650dSJack F Vogel { 134561ae650dSJack F Vogel enum i40e_status_code err; 134661ae650dSJack F Vogel u8 *context_bytes; 134761ae650dSJack F Vogel 134861ae650dSJack F Vogel err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, 134961ae650dSJack F Vogel I40E_HMC_LAN_TX, queue); 135061ae650dSJack F Vogel if (err < 0) 135161ae650dSJack F Vogel return err; 135261ae650dSJack F Vogel 135361ae650dSJack F Vogel return i40e_set_hmc_context(context_bytes, 135461ae650dSJack F Vogel i40e_hmc_txq_ce_info, (u8 *)s); 135561ae650dSJack F Vogel } 135661ae650dSJack F Vogel 135761ae650dSJack F Vogel /** 135861ae650dSJack F Vogel * i40e_get_lan_rx_queue_context - return the HMC context for the queue 135961ae650dSJack F Vogel * @hw: the hardware struct 136061ae650dSJack F Vogel * @queue: the queue we care about 136161ae650dSJack F Vogel * @s: the struct to be filled 136261ae650dSJack F Vogel **/ 136361ae650dSJack F Vogel enum i40e_status_code i40e_get_lan_rx_queue_context(struct i40e_hw *hw, 136461ae650dSJack F Vogel u16 queue, 136561ae650dSJack F Vogel struct i40e_hmc_obj_rxq *s) 136661ae650dSJack F Vogel { 136761ae650dSJack F Vogel enum i40e_status_code err; 136861ae650dSJack F Vogel u8 *context_bytes; 136961ae650dSJack F Vogel 137061ae650dSJack F Vogel err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, 137161ae650dSJack F Vogel I40E_HMC_LAN_RX, queue); 137261ae650dSJack F Vogel if (err < 0) 137361ae650dSJack F Vogel return err; 137461ae650dSJack F Vogel 137561ae650dSJack F Vogel return i40e_get_hmc_context(context_bytes, 137661ae650dSJack F Vogel i40e_hmc_rxq_ce_info, (u8 *)s); 137761ae650dSJack F Vogel } 137861ae650dSJack F Vogel 137961ae650dSJack F Vogel /** 138061ae650dSJack F Vogel * i40e_clear_lan_rx_queue_context - clear the HMC context for the queue 138161ae650dSJack F Vogel * @hw: the hardware struct 138261ae650dSJack F Vogel * @queue: the queue we care about 138361ae650dSJack F Vogel **/ 138461ae650dSJack F Vogel enum i40e_status_code i40e_clear_lan_rx_queue_context(struct i40e_hw *hw, 138561ae650dSJack F Vogel u16 queue) 138661ae650dSJack F Vogel { 138761ae650dSJack F Vogel enum i40e_status_code err; 138861ae650dSJack F Vogel u8 *context_bytes; 138961ae650dSJack F Vogel 139061ae650dSJack F Vogel err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, 139161ae650dSJack F Vogel I40E_HMC_LAN_RX, queue); 139261ae650dSJack F Vogel if (err < 0) 139361ae650dSJack F Vogel return err; 139461ae650dSJack F Vogel 139561ae650dSJack F Vogel return i40e_clear_hmc_context(hw, context_bytes, I40E_HMC_LAN_RX); 139661ae650dSJack F Vogel } 139761ae650dSJack F Vogel 139861ae650dSJack F Vogel /** 139961ae650dSJack F Vogel * i40e_set_lan_rx_queue_context - set the HMC context for the queue 140061ae650dSJack F Vogel * @hw: the hardware struct 140161ae650dSJack F Vogel * @queue: the queue we care about 140261ae650dSJack F Vogel * @s: the struct to be filled 140361ae650dSJack F Vogel **/ 140461ae650dSJack F Vogel enum i40e_status_code i40e_set_lan_rx_queue_context(struct i40e_hw *hw, 140561ae650dSJack F Vogel u16 queue, 140661ae650dSJack F Vogel struct i40e_hmc_obj_rxq *s) 140761ae650dSJack F Vogel { 140861ae650dSJack F Vogel enum i40e_status_code err; 140961ae650dSJack F Vogel u8 *context_bytes; 141061ae650dSJack F Vogel 141161ae650dSJack F Vogel err = i40e_hmc_get_object_va(&hw->hmc, &context_bytes, 141261ae650dSJack F Vogel I40E_HMC_LAN_RX, queue); 141361ae650dSJack F Vogel if (err < 0) 141461ae650dSJack F Vogel return err; 141561ae650dSJack F Vogel 141661ae650dSJack F Vogel return i40e_set_hmc_context(context_bytes, 141761ae650dSJack F Vogel i40e_hmc_rxq_ce_info, (u8 *)s); 141861ae650dSJack F Vogel } 1419