1 /* SPDX-License-Identifier: GPL-2.0 */ 2 // Copyright (c) 2025 Broadcom. 3 4 #ifndef __BNG_RES_H__ 5 #define __BNG_RES_H__ 6 7 #include "roce_hsi.h" 8 9 #define BNG_ROCE_FW_MAX_TIMEOUT 60 10 11 #define PTR_CNT_PER_PG (PAGE_SIZE / sizeof(void *)) 12 #define PTR_MAX_IDX_PER_PG (PTR_CNT_PER_PG - 1) 13 #define PTR_PG(x) (((x) & ~PTR_MAX_IDX_PER_PG) / PTR_CNT_PER_PG) 14 #define PTR_IDX(x) ((x) & PTR_MAX_IDX_PER_PG) 15 16 #define HWQ_CMP(idx, hwq) ((idx) & ((hwq)->max_elements - 1)) 17 #define HWQ_FREE_SLOTS(hwq) (hwq->max_elements - \ 18 ((HWQ_CMP(hwq->prod, hwq)\ 19 - HWQ_CMP(hwq->cons, hwq))\ 20 & (hwq->max_elements - 1))) 21 22 #define MAX_PBL_LVL_0_PGS 1 23 #define MAX_PBL_LVL_1_PGS 512 24 #define MAX_PBL_LVL_1_PGS_SHIFT 9 25 #define MAX_PBL_LVL_1_PGS_FOR_LVL_2 256 26 #define MAX_PBL_LVL_2_PGS (256 * 512) 27 #define MAX_PDL_LVL_SHIFT 9 28 29 #define BNG_RE_DBR_VALID (0x1UL << 26) 30 #define BNG_RE_DBR_EPOCH_SHIFT 24 31 #define BNG_RE_DBR_TOGGLE_SHIFT 25 32 33 #define BNG_MAX_TQM_ALLOC_REQ 48 34 35 struct bng_re_reg_desc { 36 u8 bar_id; 37 resource_size_t bar_base; 38 unsigned long offset; 39 void __iomem *bar_reg; 40 size_t len; 41 }; 42 43 struct bng_re_db_info { 44 void __iomem *db; 45 void __iomem *priv_db; 46 struct bng_re_hwq *hwq; 47 u32 xid; 48 u32 max_slot; 49 u32 flags; 50 u8 toggle; 51 }; 52 53 enum bng_re_db_info_flags_mask { 54 BNG_RE_FLAG_EPOCH_CONS_SHIFT = 0x0UL, 55 BNG_RE_FLAG_EPOCH_PROD_SHIFT = 0x1UL, 56 BNG_RE_FLAG_EPOCH_CONS_MASK = 0x1UL, 57 BNG_RE_FLAG_EPOCH_PROD_MASK = 0x2UL, 58 }; 59 60 enum bng_re_db_epoch_flag_shift { 61 BNG_RE_DB_EPOCH_CONS_SHIFT = BNG_RE_DBR_EPOCH_SHIFT, 62 BNG_RE_DB_EPOCH_PROD_SHIFT = (BNG_RE_DBR_EPOCH_SHIFT - 1), 63 }; 64 65 struct bng_re_chip_ctx { 66 u16 chip_num; 67 u16 hw_stats_size; 68 u64 hwrm_intf_ver; 69 u16 hwrm_cmd_max_timeout; 70 }; 71 72 struct bng_re_pbl { 73 u32 pg_count; 74 u32 pg_size; 75 void **pg_arr; 76 dma_addr_t *pg_map_arr; 77 }; 78 79 enum bng_re_pbl_lvl { 80 BNG_PBL_LVL_0, 81 BNG_PBL_LVL_1, 82 BNG_PBL_LVL_2, 83 BNG_PBL_LVL_MAX 84 }; 85 86 enum bng_re_hwq_type { 87 BNG_HWQ_TYPE_CTX, 88 BNG_HWQ_TYPE_QUEUE 89 }; 90 91 struct bng_re_sg_info { 92 u32 npages; 93 u32 pgshft; 94 u32 pgsize; 95 bool nopte; 96 }; 97 98 struct bng_re_hwq_attr { 99 struct bng_re_res *res; 100 struct bng_re_sg_info *sginfo; 101 enum bng_re_hwq_type type; 102 u32 depth; 103 u32 stride; 104 u32 aux_stride; 105 u32 aux_depth; 106 }; 107 108 struct bng_re_hwq { 109 struct pci_dev *pdev; 110 /* lock to protect hwq */ 111 spinlock_t lock; 112 struct bng_re_pbl pbl[BNG_PBL_LVL_MAX + 1]; 113 /* Valid values: 0, 1, 2 */ 114 enum bng_re_pbl_lvl level; 115 /* PBL entries */ 116 void **pbl_ptr; 117 /* PBL dma_addr */ 118 dma_addr_t *pbl_dma_ptr; 119 u32 max_elements; 120 u32 depth; 121 u16 element_size; 122 u32 prod; 123 u32 cons; 124 /* queue entry per page */ 125 u16 qe_ppg; 126 }; 127 128 struct bng_re_res { 129 struct pci_dev *pdev; 130 struct bng_re_chip_ctx *cctx; 131 struct bng_re_dev_attr *dattr; 132 }; 133 134 static inline void *bng_re_get_qe(struct bng_re_hwq *hwq, 135 u32 indx, u64 *pg) 136 { 137 u32 pg_num, pg_idx; 138 139 pg_num = (indx / hwq->qe_ppg); 140 pg_idx = (indx % hwq->qe_ppg); 141 if (pg) 142 *pg = (u64)&hwq->pbl_ptr[pg_num]; 143 return (void *)(hwq->pbl_ptr[pg_num] + hwq->element_size * pg_idx); 144 } 145 146 #define BNG_RE_INIT_DBHDR(xid, type, indx, toggle) \ 147 (((u64)(((xid) & DBC_DBC_XID_MASK) | DBC_DBC_PATH_ROCE | \ 148 (type) | BNG_RE_DBR_VALID) << 32) | (indx) | \ 149 (((u32)(toggle)) << (BNG_RE_DBR_TOGGLE_SHIFT))) 150 151 static inline void bng_re_ring_db(struct bng_re_db_info *info, 152 u32 type) 153 { 154 u64 key = 0; 155 u32 indx; 156 u8 toggle = 0; 157 158 if (type == DBC_DBC_TYPE_CQ_ARMALL || 159 type == DBC_DBC_TYPE_CQ_ARMSE) 160 toggle = info->toggle; 161 162 indx = (info->hwq->cons & DBC_DBC_INDEX_MASK) | 163 ((info->flags & BNG_RE_FLAG_EPOCH_CONS_MASK) << 164 BNG_RE_DB_EPOCH_CONS_SHIFT); 165 166 key = BNG_RE_INIT_DBHDR(info->xid, type, indx, toggle); 167 writeq(key, info->db); 168 } 169 170 static inline void bng_re_ring_nq_db(struct bng_re_db_info *info, 171 struct bng_re_chip_ctx *cctx, 172 bool arm) 173 { 174 u32 type; 175 176 type = arm ? DBC_DBC_TYPE_NQ_ARM : DBC_DBC_TYPE_NQ; 177 bng_re_ring_db(info, type); 178 } 179 180 static inline void bng_re_hwq_incr_cons(u32 max_elements, u32 *cons, u32 cnt, 181 u32 *dbinfo_flags) 182 { 183 /* move cons and update toggle/epoch if wrap around */ 184 *cons += cnt; 185 if (*cons >= max_elements) { 186 *cons %= max_elements; 187 *dbinfo_flags ^= 1UL << BNG_RE_FLAG_EPOCH_CONS_SHIFT; 188 } 189 } 190 191 static inline bool _is_max_srq_ext_supported(u16 dev_cap_ext_flags_2) 192 { 193 return !!(dev_cap_ext_flags_2 & CREQ_QUERY_FUNC_RESP_SB_MAX_SRQ_EXTENDED); 194 } 195 196 void bng_re_free_hwq(struct bng_re_res *res, 197 struct bng_re_hwq *hwq); 198 199 int bng_re_alloc_init_hwq(struct bng_re_hwq *hwq, 200 struct bng_re_hwq_attr *hwq_attr); 201 #endif 202