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