1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun /* Copyright(c) 2013 - 2018 Intel Corporation. */ 3*4882a593Smuzhiyun 4*4882a593Smuzhiyun #ifndef _I40E_HMC_H_ 5*4882a593Smuzhiyun #define _I40E_HMC_H_ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #define I40E_HMC_MAX_BP_COUNT 512 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun /* forward-declare the HW struct for the compiler */ 10*4882a593Smuzhiyun struct i40e_hw; 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun #define I40E_HMC_INFO_SIGNATURE 0x484D5347 /* HMSG */ 13*4882a593Smuzhiyun #define I40E_HMC_PD_CNT_IN_SD 512 14*4882a593Smuzhiyun #define I40E_HMC_DIRECT_BP_SIZE 0x200000 /* 2M */ 15*4882a593Smuzhiyun #define I40E_HMC_PAGED_BP_SIZE 4096 16*4882a593Smuzhiyun #define I40E_HMC_PD_BP_BUF_ALIGNMENT 4096 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun struct i40e_hmc_obj_info { 19*4882a593Smuzhiyun u64 base; /* base addr in FPM */ 20*4882a593Smuzhiyun u32 max_cnt; /* max count available for this hmc func */ 21*4882a593Smuzhiyun u32 cnt; /* count of objects driver actually wants to create */ 22*4882a593Smuzhiyun u64 size; /* size in bytes of one object */ 23*4882a593Smuzhiyun }; 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun enum i40e_sd_entry_type { 26*4882a593Smuzhiyun I40E_SD_TYPE_INVALID = 0, 27*4882a593Smuzhiyun I40E_SD_TYPE_PAGED = 1, 28*4882a593Smuzhiyun I40E_SD_TYPE_DIRECT = 2 29*4882a593Smuzhiyun }; 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun struct i40e_hmc_bp { 32*4882a593Smuzhiyun enum i40e_sd_entry_type entry_type; 33*4882a593Smuzhiyun struct i40e_dma_mem addr; /* populate to be used by hw */ 34*4882a593Smuzhiyun u32 sd_pd_index; 35*4882a593Smuzhiyun u32 ref_cnt; 36*4882a593Smuzhiyun }; 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun struct i40e_hmc_pd_entry { 39*4882a593Smuzhiyun struct i40e_hmc_bp bp; 40*4882a593Smuzhiyun u32 sd_index; 41*4882a593Smuzhiyun bool rsrc_pg; 42*4882a593Smuzhiyun bool valid; 43*4882a593Smuzhiyun }; 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun struct i40e_hmc_pd_table { 46*4882a593Smuzhiyun struct i40e_dma_mem pd_page_addr; /* populate to be used by hw */ 47*4882a593Smuzhiyun struct i40e_hmc_pd_entry *pd_entry; /* [512] for sw book keeping */ 48*4882a593Smuzhiyun struct i40e_virt_mem pd_entry_virt_mem; /* virt mem for pd_entry */ 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun u32 ref_cnt; 51*4882a593Smuzhiyun u32 sd_index; 52*4882a593Smuzhiyun }; 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun struct i40e_hmc_sd_entry { 55*4882a593Smuzhiyun enum i40e_sd_entry_type entry_type; 56*4882a593Smuzhiyun bool valid; 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun union { 59*4882a593Smuzhiyun struct i40e_hmc_pd_table pd_table; 60*4882a593Smuzhiyun struct i40e_hmc_bp bp; 61*4882a593Smuzhiyun } u; 62*4882a593Smuzhiyun }; 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun struct i40e_hmc_sd_table { 65*4882a593Smuzhiyun struct i40e_virt_mem addr; /* used to track sd_entry allocations */ 66*4882a593Smuzhiyun u32 sd_cnt; 67*4882a593Smuzhiyun u32 ref_cnt; 68*4882a593Smuzhiyun struct i40e_hmc_sd_entry *sd_entry; /* (sd_cnt*512) entries max */ 69*4882a593Smuzhiyun }; 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun struct i40e_hmc_info { 72*4882a593Smuzhiyun u32 signature; 73*4882a593Smuzhiyun /* equals to pci func num for PF and dynamically allocated for VFs */ 74*4882a593Smuzhiyun u8 hmc_fn_id; 75*4882a593Smuzhiyun u16 first_sd_index; /* index of the first available SD */ 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun /* hmc objects */ 78*4882a593Smuzhiyun struct i40e_hmc_obj_info *hmc_obj; 79*4882a593Smuzhiyun struct i40e_virt_mem hmc_obj_virt_mem; 80*4882a593Smuzhiyun struct i40e_hmc_sd_table sd_table; 81*4882a593Smuzhiyun }; 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun #define I40E_INC_SD_REFCNT(sd_table) ((sd_table)->ref_cnt++) 84*4882a593Smuzhiyun #define I40E_INC_PD_REFCNT(pd_table) ((pd_table)->ref_cnt++) 85*4882a593Smuzhiyun #define I40E_INC_BP_REFCNT(bp) ((bp)->ref_cnt++) 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun #define I40E_DEC_SD_REFCNT(sd_table) ((sd_table)->ref_cnt--) 88*4882a593Smuzhiyun #define I40E_DEC_PD_REFCNT(pd_table) ((pd_table)->ref_cnt--) 89*4882a593Smuzhiyun #define I40E_DEC_BP_REFCNT(bp) ((bp)->ref_cnt--) 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun /** 92*4882a593Smuzhiyun * I40E_SET_PF_SD_ENTRY - marks the sd entry as valid in the hardware 93*4882a593Smuzhiyun * @hw: pointer to our hw struct 94*4882a593Smuzhiyun * @pa: pointer to physical address 95*4882a593Smuzhiyun * @sd_index: segment descriptor index 96*4882a593Smuzhiyun * @type: if sd entry is direct or paged 97*4882a593Smuzhiyun **/ 98*4882a593Smuzhiyun #define I40E_SET_PF_SD_ENTRY(hw, pa, sd_index, type) \ 99*4882a593Smuzhiyun { \ 100*4882a593Smuzhiyun u32 val1, val2, val3; \ 101*4882a593Smuzhiyun val1 = (u32)(upper_32_bits(pa)); \ 102*4882a593Smuzhiyun val2 = (u32)(pa) | (I40E_HMC_MAX_BP_COUNT << \ 103*4882a593Smuzhiyun I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) | \ 104*4882a593Smuzhiyun ((((type) == I40E_SD_TYPE_PAGED) ? 0 : 1) << \ 105*4882a593Smuzhiyun I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT) | \ 106*4882a593Smuzhiyun BIT(I40E_PFHMC_SDDATALOW_PMSDVALID_SHIFT); \ 107*4882a593Smuzhiyun val3 = (sd_index) | BIT_ULL(I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \ 108*4882a593Smuzhiyun wr32((hw), I40E_PFHMC_SDDATAHIGH, val1); \ 109*4882a593Smuzhiyun wr32((hw), I40E_PFHMC_SDDATALOW, val2); \ 110*4882a593Smuzhiyun wr32((hw), I40E_PFHMC_SDCMD, val3); \ 111*4882a593Smuzhiyun } 112*4882a593Smuzhiyun 113*4882a593Smuzhiyun /** 114*4882a593Smuzhiyun * I40E_CLEAR_PF_SD_ENTRY - marks the sd entry as invalid in the hardware 115*4882a593Smuzhiyun * @hw: pointer to our hw struct 116*4882a593Smuzhiyun * @sd_index: segment descriptor index 117*4882a593Smuzhiyun * @type: if sd entry is direct or paged 118*4882a593Smuzhiyun **/ 119*4882a593Smuzhiyun #define I40E_CLEAR_PF_SD_ENTRY(hw, sd_index, type) \ 120*4882a593Smuzhiyun { \ 121*4882a593Smuzhiyun u32 val2, val3; \ 122*4882a593Smuzhiyun val2 = (I40E_HMC_MAX_BP_COUNT << \ 123*4882a593Smuzhiyun I40E_PFHMC_SDDATALOW_PMSDBPCOUNT_SHIFT) | \ 124*4882a593Smuzhiyun ((((type) == I40E_SD_TYPE_PAGED) ? 0 : 1) << \ 125*4882a593Smuzhiyun I40E_PFHMC_SDDATALOW_PMSDTYPE_SHIFT); \ 126*4882a593Smuzhiyun val3 = (sd_index) | BIT_ULL(I40E_PFHMC_SDCMD_PMSDWR_SHIFT); \ 127*4882a593Smuzhiyun wr32((hw), I40E_PFHMC_SDDATAHIGH, 0); \ 128*4882a593Smuzhiyun wr32((hw), I40E_PFHMC_SDDATALOW, val2); \ 129*4882a593Smuzhiyun wr32((hw), I40E_PFHMC_SDCMD, val3); \ 130*4882a593Smuzhiyun } 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun /** 133*4882a593Smuzhiyun * I40E_INVALIDATE_PF_HMC_PD - Invalidates the pd cache in the hardware 134*4882a593Smuzhiyun * @hw: pointer to our hw struct 135*4882a593Smuzhiyun * @sd_idx: segment descriptor index 136*4882a593Smuzhiyun * @pd_idx: page descriptor index 137*4882a593Smuzhiyun **/ 138*4882a593Smuzhiyun #define I40E_INVALIDATE_PF_HMC_PD(hw, sd_idx, pd_idx) \ 139*4882a593Smuzhiyun wr32((hw), I40E_PFHMC_PDINV, \ 140*4882a593Smuzhiyun (((sd_idx) << I40E_PFHMC_PDINV_PMSDIDX_SHIFT) | \ 141*4882a593Smuzhiyun ((pd_idx) << I40E_PFHMC_PDINV_PMPDIDX_SHIFT))) 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun /** 144*4882a593Smuzhiyun * I40E_FIND_SD_INDEX_LIMIT - finds segment descriptor index limit 145*4882a593Smuzhiyun * @hmc_info: pointer to the HMC configuration information structure 146*4882a593Smuzhiyun * @type: type of HMC resources we're searching 147*4882a593Smuzhiyun * @index: starting index for the object 148*4882a593Smuzhiyun * @cnt: number of objects we're trying to create 149*4882a593Smuzhiyun * @sd_idx: pointer to return index of the segment descriptor in question 150*4882a593Smuzhiyun * @sd_limit: pointer to return the maximum number of segment descriptors 151*4882a593Smuzhiyun * 152*4882a593Smuzhiyun * This function calculates the segment descriptor index and index limit 153*4882a593Smuzhiyun * for the resource defined by i40e_hmc_rsrc_type. 154*4882a593Smuzhiyun **/ 155*4882a593Smuzhiyun #define I40E_FIND_SD_INDEX_LIMIT(hmc_info, type, index, cnt, sd_idx, sd_limit)\ 156*4882a593Smuzhiyun { \ 157*4882a593Smuzhiyun u64 fpm_addr, fpm_limit; \ 158*4882a593Smuzhiyun fpm_addr = (hmc_info)->hmc_obj[(type)].base + \ 159*4882a593Smuzhiyun (hmc_info)->hmc_obj[(type)].size * (index); \ 160*4882a593Smuzhiyun fpm_limit = fpm_addr + (hmc_info)->hmc_obj[(type)].size * (cnt);\ 161*4882a593Smuzhiyun *(sd_idx) = (u32)(fpm_addr / I40E_HMC_DIRECT_BP_SIZE); \ 162*4882a593Smuzhiyun *(sd_limit) = (u32)((fpm_limit - 1) / I40E_HMC_DIRECT_BP_SIZE); \ 163*4882a593Smuzhiyun /* add one more to the limit to correct our range */ \ 164*4882a593Smuzhiyun *(sd_limit) += 1; \ 165*4882a593Smuzhiyun } 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun /** 168*4882a593Smuzhiyun * I40E_FIND_PD_INDEX_LIMIT - finds page descriptor index limit 169*4882a593Smuzhiyun * @hmc_info: pointer to the HMC configuration information struct 170*4882a593Smuzhiyun * @type: HMC resource type we're examining 171*4882a593Smuzhiyun * @idx: starting index for the object 172*4882a593Smuzhiyun * @cnt: number of objects we're trying to create 173*4882a593Smuzhiyun * @pd_index: pointer to return page descriptor index 174*4882a593Smuzhiyun * @pd_limit: pointer to return page descriptor index limit 175*4882a593Smuzhiyun * 176*4882a593Smuzhiyun * Calculates the page descriptor index and index limit for the resource 177*4882a593Smuzhiyun * defined by i40e_hmc_rsrc_type. 178*4882a593Smuzhiyun **/ 179*4882a593Smuzhiyun #define I40E_FIND_PD_INDEX_LIMIT(hmc_info, type, idx, cnt, pd_index, pd_limit)\ 180*4882a593Smuzhiyun { \ 181*4882a593Smuzhiyun u64 fpm_adr, fpm_limit; \ 182*4882a593Smuzhiyun fpm_adr = (hmc_info)->hmc_obj[(type)].base + \ 183*4882a593Smuzhiyun (hmc_info)->hmc_obj[(type)].size * (idx); \ 184*4882a593Smuzhiyun fpm_limit = fpm_adr + (hmc_info)->hmc_obj[(type)].size * (cnt); \ 185*4882a593Smuzhiyun *(pd_index) = (u32)(fpm_adr / I40E_HMC_PAGED_BP_SIZE); \ 186*4882a593Smuzhiyun *(pd_limit) = (u32)((fpm_limit - 1) / I40E_HMC_PAGED_BP_SIZE); \ 187*4882a593Smuzhiyun /* add one more to the limit to correct our range */ \ 188*4882a593Smuzhiyun *(pd_limit) += 1; \ 189*4882a593Smuzhiyun } 190*4882a593Smuzhiyun i40e_status i40e_add_sd_table_entry(struct i40e_hw *hw, 191*4882a593Smuzhiyun struct i40e_hmc_info *hmc_info, 192*4882a593Smuzhiyun u32 sd_index, 193*4882a593Smuzhiyun enum i40e_sd_entry_type type, 194*4882a593Smuzhiyun u64 direct_mode_sz); 195*4882a593Smuzhiyun 196*4882a593Smuzhiyun i40e_status i40e_add_pd_table_entry(struct i40e_hw *hw, 197*4882a593Smuzhiyun struct i40e_hmc_info *hmc_info, 198*4882a593Smuzhiyun u32 pd_index, 199*4882a593Smuzhiyun struct i40e_dma_mem *rsrc_pg); 200*4882a593Smuzhiyun i40e_status i40e_remove_pd_bp(struct i40e_hw *hw, 201*4882a593Smuzhiyun struct i40e_hmc_info *hmc_info, 202*4882a593Smuzhiyun u32 idx); 203*4882a593Smuzhiyun i40e_status i40e_prep_remove_sd_bp(struct i40e_hmc_info *hmc_info, 204*4882a593Smuzhiyun u32 idx); 205*4882a593Smuzhiyun i40e_status i40e_remove_sd_bp_new(struct i40e_hw *hw, 206*4882a593Smuzhiyun struct i40e_hmc_info *hmc_info, 207*4882a593Smuzhiyun u32 idx, bool is_pf); 208*4882a593Smuzhiyun i40e_status i40e_prep_remove_pd_page(struct i40e_hmc_info *hmc_info, 209*4882a593Smuzhiyun u32 idx); 210*4882a593Smuzhiyun i40e_status i40e_remove_pd_page_new(struct i40e_hw *hw, 211*4882a593Smuzhiyun struct i40e_hmc_info *hmc_info, 212*4882a593Smuzhiyun u32 idx, bool is_pf); 213*4882a593Smuzhiyun 214*4882a593Smuzhiyun #endif /* _I40E_HMC_H_ */ 215