1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016-2020 Intel Corporation
3  */
4 
5 #ifndef __DLB_HW_TYPES_H
6 #define __DLB_HW_TYPES_H
7 
8 #include "../../dlb_user.h"
9 #include "dlb_osdep_types.h"
10 #include "dlb_osdep_list.h"
11 
12 #define DLB_MAX_NUM_DOMAINS 32
13 #define DLB_MAX_NUM_LDB_QUEUES 128
14 #define DLB_MAX_NUM_LDB_PORTS 64
15 #define DLB_MAX_NUM_DIR_PORTS 128
16 #define DLB_MAX_NUM_LDB_CREDITS 16384
17 #define DLB_MAX_NUM_DIR_CREDITS 4096
18 #define DLB_MAX_NUM_LDB_CREDIT_POOLS 64
19 #define DLB_MAX_NUM_DIR_CREDIT_POOLS 64
20 #define DLB_MAX_NUM_HIST_LIST_ENTRIES 5120
21 #define DLB_MAX_NUM_AQOS_ENTRIES 2048
22 #define DLB_MAX_NUM_TOTAL_OUTSTANDING_COMPLETIONS 4096
23 #define DLB_MAX_NUM_QIDS_PER_LDB_CQ 8
24 #define DLB_MAX_NUM_SEQUENCE_NUMBER_GROUPS 4
25 #define DLB_MAX_NUM_SEQUENCE_NUMBER_MODES 6
26 #define DLB_QID_PRIORITIES 8
27 #define DLB_NUM_ARB_WEIGHTS 8
28 #define DLB_MAX_WEIGHT 255
29 #define DLB_MAX_PORT_CREDIT_QUANTUM 1023
30 #define DLB_MAX_CQ_COMP_CHECK_LOOPS 409600
31 #define DLB_MAX_QID_EMPTY_CHECK_LOOPS (32 * 64 * 1024 * (800 / 30))
32 #define DLB_HZ 800000000
33 
34 /* Used for DLB A-stepping workaround for hardware write buffer lock up issue */
35 #define DLB_A_STEP_MAX_PORTS 128
36 
37 #define DLB_PF_DEV_ID 0x270B
38 
39 /* Interrupt related macros */
40 #define DLB_PF_NUM_NON_CQ_INTERRUPT_VECTORS 8
41 #define DLB_PF_NUM_CQ_INTERRUPT_VECTORS	 64
42 #define DLB_PF_TOTAL_NUM_INTERRUPT_VECTORS \
43 	(DLB_PF_NUM_NON_CQ_INTERRUPT_VECTORS + \
44 	 DLB_PF_NUM_CQ_INTERRUPT_VECTORS)
45 #define DLB_PF_NUM_COMPRESSED_MODE_VECTORS \
46 	(DLB_PF_NUM_NON_CQ_INTERRUPT_VECTORS + 1)
47 #define DLB_PF_NUM_PACKED_MODE_VECTORS	 DLB_PF_TOTAL_NUM_INTERRUPT_VECTORS
48 #define DLB_PF_COMPRESSED_MODE_CQ_VECTOR_ID DLB_PF_NUM_NON_CQ_INTERRUPT_VECTORS
49 
50 #define DLB_PF_NUM_ALARM_INTERRUPT_VECTORS 4
51 #define DLB_INT_ALARM 0
52 #define DLB_INT_INGRESS_ERROR 3
53 
54 #define DLB_ALARM_HW_SOURCE_SYS 0
55 #define DLB_ALARM_HW_SOURCE_DLB 1
56 
57 #define DLB_ALARM_HW_UNIT_CHP 1
58 #define DLB_ALARM_HW_UNIT_LSP 3
59 
60 #define DLB_ALARM_HW_CHP_AID_OUT_OF_CREDITS 6
61 #define DLB_ALARM_HW_CHP_AID_ILLEGAL_ENQ 7
62 #define DLB_ALARM_HW_LSP_AID_EXCESS_TOKEN_POPS 15
63 #define DLB_ALARM_SYS_AID_ILLEGAL_HCW 0
64 #define DLB_ALARM_SYS_AID_ILLEGAL_QID 3
65 #define DLB_ALARM_SYS_AID_DISABLED_QID 4
66 #define DLB_ALARM_SYS_AID_ILLEGAL_CQID 6
67 
68 /* Hardware-defined base addresses */
69 #define DLB_LDB_PP_BASE 0x2100000
70 #define DLB_LDB_PP_STRIDE 0x1000
71 #define DLB_LDB_PP_BOUND \
72 	(DLB_LDB_PP_BASE + DLB_LDB_PP_STRIDE * DLB_MAX_NUM_LDB_PORTS)
73 #define DLB_DIR_PP_BASE 0x2000000
74 #define DLB_DIR_PP_STRIDE 0x1000
75 #define DLB_DIR_PP_BOUND \
76 	(DLB_DIR_PP_BASE + DLB_DIR_PP_STRIDE * DLB_MAX_NUM_DIR_PORTS)
77 
78 struct dlb_freelist {
79 	u32 base;
80 	u32 bound;
81 	u32 offset;
82 };
83 
dlb_freelist_count(struct dlb_freelist * list)84 static inline u32 dlb_freelist_count(struct dlb_freelist *list)
85 {
86 	return (list->bound - list->base) - list->offset;
87 }
88 
89 struct dlb_hcw {
90 	u64 data;
91 	/* Word 3 */
92 	u16 opaque;
93 	u8 qid;
94 	u8 sched_type:2;
95 	u8 priority:3;
96 	u8 msg_type:3;
97 	/* Word 4 */
98 	u16 lock_id;
99 	u8 meas_lat:1;
100 	u8 rsvd1:2;
101 	u8 no_dec:1;
102 	u8 cmp_id:4;
103 	u8 cq_token:1;
104 	u8 qe_comp:1;
105 	u8 qe_frag:1;
106 	u8 qe_valid:1;
107 	u8 int_arm:1;
108 	u8 error:1;
109 	u8 rsvd:2;
110 };
111 
112 struct dlb_ldb_queue {
113 	struct dlb_list_entry domain_list;
114 	struct dlb_list_entry func_list;
115 	u32 id;
116 	u32 domain_id;
117 	u32 num_qid_inflights;
118 	struct dlb_freelist aqed_freelist;
119 	u8 sn_cfg_valid;
120 	u32 sn_group;
121 	u32 sn_slot;
122 	u32 num_mappings;
123 	u8 num_pending_additions;
124 	u8 owned;
125 	u8 configured;
126 };
127 
128 /* Directed ports and queues are paired by nature, so the driver tracks them
129  * with a single data structure.
130  */
131 struct dlb_dir_pq_pair {
132 	struct dlb_list_entry domain_list;
133 	struct dlb_list_entry func_list;
134 	u32 id;
135 	u32 domain_id;
136 	u8 ldb_pool_used;
137 	u8 dir_pool_used;
138 	u8 queue_configured;
139 	u8 port_configured;
140 	u8 owned;
141 	u8 enabled;
142 	u32 ref_cnt;
143 };
144 
145 enum dlb_qid_map_state {
146 	/* The slot doesn't contain a valid queue mapping */
147 	DLB_QUEUE_UNMAPPED,
148 	/* The slot contains a valid queue mapping */
149 	DLB_QUEUE_MAPPED,
150 	/* The driver is mapping a queue into this slot */
151 	DLB_QUEUE_MAP_IN_PROGRESS,
152 	/* The driver is unmapping a queue from this slot */
153 	DLB_QUEUE_UNMAP_IN_PROGRESS,
154 	/* The driver is unmapping a queue from this slot, and once complete
155 	 * will replace it with another mapping.
156 	 */
157 	DLB_QUEUE_UNMAP_IN_PROGRESS_PENDING_MAP,
158 };
159 
160 struct dlb_ldb_port_qid_map {
161 	u16 qid;
162 	u8 priority;
163 	u16 pending_qid;
164 	u8 pending_priority;
165 	enum dlb_qid_map_state state;
166 };
167 
168 struct dlb_ldb_port {
169 	struct dlb_list_entry domain_list;
170 	struct dlb_list_entry func_list;
171 	u32 id;
172 	u32 domain_id;
173 	u8 ldb_pool_used;
174 	u8 dir_pool_used;
175 	u8 init_tkn_cnt;
176 	u32 hist_list_entry_base;
177 	u32 hist_list_entry_limit;
178 	/* The qid_map represents the hardware QID mapping state. */
179 	struct dlb_ldb_port_qid_map qid_map[DLB_MAX_NUM_QIDS_PER_LDB_CQ];
180 	u32 ref_cnt;
181 	u8 num_pending_removals;
182 	u8 num_mappings;
183 	u8 owned;
184 	u8 enabled;
185 	u8 configured;
186 };
187 
188 struct dlb_credit_pool {
189 	struct dlb_list_entry domain_list;
190 	struct dlb_list_entry func_list;
191 	u32 id;
192 	u32 domain_id;
193 	u32 total_credits;
194 	u32 avail_credits;
195 	u8 owned;
196 	u8 configured;
197 };
198 
199 struct dlb_sn_group {
200 	u32 mode;
201 	u32 sequence_numbers_per_queue;
202 	u32 slot_use_bitmap;
203 	u32 id;
204 };
205 
dlb_sn_group_full(struct dlb_sn_group * group)206 static inline bool dlb_sn_group_full(struct dlb_sn_group *group)
207 {
208 	u32 mask[6] = {
209 		0xffffffff,  /* 32 SNs per queue */
210 		0x0000ffff,  /* 64 SNs per queue */
211 		0x000000ff,  /* 128 SNs per queue */
212 		0x0000000f,  /* 256 SNs per queue */
213 		0x00000003,  /* 512 SNs per queue */
214 		0x00000001}; /* 1024 SNs per queue */
215 
216 	return group->slot_use_bitmap == mask[group->mode];
217 }
218 
dlb_sn_group_alloc_slot(struct dlb_sn_group * group)219 static inline int dlb_sn_group_alloc_slot(struct dlb_sn_group *group)
220 {
221 	int bound[6] = {32, 16, 8, 4, 2, 1};
222 	int i;
223 
224 	for (i = 0; i < bound[group->mode]; i++) {
225 		if (!(group->slot_use_bitmap & (1 << i))) {
226 			group->slot_use_bitmap |= 1 << i;
227 			return i;
228 		}
229 	}
230 
231 	return -1;
232 }
233 
dlb_sn_group_free_slot(struct dlb_sn_group * group,int slot)234 static inline void dlb_sn_group_free_slot(struct dlb_sn_group *group, int slot)
235 {
236 	group->slot_use_bitmap &= ~(1 << slot);
237 }
238 
dlb_sn_group_used_slots(struct dlb_sn_group * group)239 static inline int dlb_sn_group_used_slots(struct dlb_sn_group *group)
240 {
241 	int i, cnt = 0;
242 
243 	for (i = 0; i < 32; i++)
244 		cnt += !!(group->slot_use_bitmap & (1 << i));
245 
246 	return cnt;
247 }
248 
249 struct dlb_domain {
250 	struct dlb_function_resources *parent_func;
251 	struct dlb_list_entry func_list;
252 	struct dlb_list_head used_ldb_queues;
253 	struct dlb_list_head used_ldb_ports;
254 	struct dlb_list_head used_dir_pq_pairs;
255 	struct dlb_list_head used_ldb_credit_pools;
256 	struct dlb_list_head used_dir_credit_pools;
257 	struct dlb_list_head avail_ldb_queues;
258 	struct dlb_list_head avail_ldb_ports;
259 	struct dlb_list_head avail_dir_pq_pairs;
260 	struct dlb_list_head avail_ldb_credit_pools;
261 	struct dlb_list_head avail_dir_credit_pools;
262 	u32 total_hist_list_entries;
263 	u32 avail_hist_list_entries;
264 	u32 hist_list_entry_base;
265 	u32 hist_list_entry_offset;
266 	struct dlb_freelist qed_freelist;
267 	struct dlb_freelist dqed_freelist;
268 	struct dlb_freelist aqed_freelist;
269 	u32 id;
270 	int num_pending_removals;
271 	int num_pending_additions;
272 	u8 configured;
273 	u8 started;
274 };
275 
276 struct dlb_bitmap;
277 
278 struct dlb_function_resources {
279 	u32 num_avail_domains;
280 	struct dlb_list_head avail_domains;
281 	struct dlb_list_head used_domains;
282 	u32 num_avail_ldb_queues;
283 	struct dlb_list_head avail_ldb_queues;
284 	u32 num_avail_ldb_ports;
285 	struct dlb_list_head avail_ldb_ports;
286 	u32 num_avail_dir_pq_pairs;
287 	struct dlb_list_head avail_dir_pq_pairs;
288 	struct dlb_bitmap *avail_hist_list_entries;
289 	struct dlb_bitmap *avail_qed_freelist_entries;
290 	struct dlb_bitmap *avail_dqed_freelist_entries;
291 	struct dlb_bitmap *avail_aqed_freelist_entries;
292 	u32 num_avail_ldb_credit_pools;
293 	struct dlb_list_head avail_ldb_credit_pools;
294 	u32 num_avail_dir_credit_pools;
295 	struct dlb_list_head avail_dir_credit_pools;
296 	u32 num_enabled_ldb_ports;
297 };
298 
299 /* After initialization, each resource in dlb_hw_resources is located in one of
300  * the following lists:
301  * -- The PF's available resources list. These are unconfigured resources owned
302  *	by the PF and not allocated to a DLB scheduling domain.
303  * -- A domain's available resources list. These are domain-owned unconfigured
304  *	resources.
305  * -- A domain's used resources list. These are domain-owned configured
306  *	resources.
307  *
308  * A resource moves to a new list when a domain is created or destroyed, or
309  * when the resource is configured.
310  */
311 struct dlb_hw_resources {
312 	struct dlb_ldb_queue ldb_queues[DLB_MAX_NUM_LDB_QUEUES];
313 	struct dlb_ldb_port ldb_ports[DLB_MAX_NUM_LDB_PORTS];
314 	struct dlb_dir_pq_pair dir_pq_pairs[DLB_MAX_NUM_DIR_PORTS];
315 	struct dlb_credit_pool ldb_credit_pools[DLB_MAX_NUM_LDB_CREDIT_POOLS];
316 	struct dlb_credit_pool dir_credit_pools[DLB_MAX_NUM_DIR_CREDIT_POOLS];
317 	struct dlb_sn_group sn_groups[DLB_MAX_NUM_SEQUENCE_NUMBER_GROUPS];
318 };
319 
320 struct dlb_hw {
321 	/* BAR 0 address */
322 	void  *csr_kva;
323 	unsigned long csr_phys_addr;
324 	/* BAR 2 address */
325 	void  *func_kva;
326 	unsigned long func_phys_addr;
327 
328 	/* Resource tracking */
329 	struct dlb_hw_resources rsrcs;
330 	struct dlb_function_resources pf;
331 	struct dlb_domain domains[DLB_MAX_NUM_DOMAINS];
332 };
333 
334 #endif /* __DLB_HW_TYPES_H */
335