linux/drivers/net/ethernet/intel/i40e/i40e_hmc.h
<<
>>
Prefs
   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 */
  10struct 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
  18struct 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
  25enum i40e_sd_entry_type {
  26        I40E_SD_TYPE_INVALID = 0,
  27        I40E_SD_TYPE_PAGED   = 1,
  28        I40E_SD_TYPE_DIRECT  = 2
  29};
  30
  31struct 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
  38struct i40e_hmc_pd_entry {
  39        struct i40e_hmc_bp bp;
  40        u32 sd_index;
  41        bool rsrc_pg;
  42        bool valid;
  43};
  44
  45struct 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
  54struct 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
  64struct 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
  71struct 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}
 190i40e_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
 196i40e_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);
 200i40e_status i40e_remove_pd_bp(struct i40e_hw *hw,
 201                                        struct i40e_hmc_info *hmc_info,
 202                                        u32 idx);
 203i40e_status i40e_prep_remove_sd_bp(struct i40e_hmc_info *hmc_info,
 204                                             u32 idx);
 205i40e_status i40e_remove_sd_bp_new(struct i40e_hw *hw,
 206                                            struct i40e_hmc_info *hmc_info,
 207                                            u32 idx, bool is_pf);
 208i40e_status i40e_prep_remove_pd_page(struct i40e_hmc_info *hmc_info,
 209                                               u32 idx);
 210i40e_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