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