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