xref: /linux/drivers/infiniband/hw/bng_re/bng_res.h (revision 4f830cd8d7fe3e98fc12d25f347ed461e11fc1de)
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