1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016-2020 Intel Corporation
3  */
4 
5 #ifndef __DLB2_HW_TYPES_H
6 #define __DLB2_HW_TYPES_H
7 
8 #include "dlb2_user.h"
9 
10 #include "dlb2_osdep_list.h"
11 #include "dlb2_osdep_types.h"
12 
13 #define DLB2_MAX_NUM_VDEVS			16
14 #define DLB2_MAX_NUM_DOMAINS			32
15 #define DLB2_MAX_NUM_LDB_QUEUES			32 /* LDB == load-balanced */
16 #define DLB2_MAX_NUM_DIR_QUEUES			64 /* DIR == directed */
17 #define DLB2_MAX_NUM_LDB_PORTS			64
18 #define DLB2_MAX_NUM_DIR_PORTS			64
19 #define DLB2_MAX_NUM_LDB_CREDITS		(8 * 1024)
20 #define DLB2_MAX_NUM_DIR_CREDITS		(2 * 1024)
21 #define DLB2_MAX_NUM_HIST_LIST_ENTRIES		2048
22 #define DLB2_MAX_NUM_AQED_ENTRIES		2048
23 #define DLB2_MAX_NUM_QIDS_PER_LDB_CQ		8
24 #define DLB2_MAX_NUM_SEQUENCE_NUMBER_GROUPS	2
25 #define DLB2_MAX_NUM_SEQUENCE_NUMBER_MODES	5
26 #define DLB2_QID_PRIORITIES			8
27 #define DLB2_NUM_ARB_WEIGHTS			8
28 #define DLB2_MAX_WEIGHT				255
29 #define DLB2_NUM_COS_DOMAINS			4
30 #define DLB2_MAX_CQ_COMP_CHECK_LOOPS		409600
31 #define DLB2_MAX_QID_EMPTY_CHECK_LOOPS		(32 * 64 * 1024 * (800 / 30))
32 #ifdef FPGA
33 #define DLB2_HZ					2000000
34 #else
35 #define DLB2_HZ					800000000
36 #endif
37 
38 #define PCI_DEVICE_ID_INTEL_DLB2_PF 0x2710
39 #define PCI_DEVICE_ID_INTEL_DLB2_VF 0x2711
40 
41 /* Interrupt related macros */
42 #define DLB2_PF_NUM_NON_CQ_INTERRUPT_VECTORS 1
43 #define DLB2_PF_NUM_CQ_INTERRUPT_VECTORS     64
44 #define DLB2_PF_TOTAL_NUM_INTERRUPT_VECTORS \
45 	(DLB2_PF_NUM_NON_CQ_INTERRUPT_VECTORS + \
46 	 DLB2_PF_NUM_CQ_INTERRUPT_VECTORS)
47 #define DLB2_PF_NUM_COMPRESSED_MODE_VECTORS \
48 	(DLB2_PF_NUM_NON_CQ_INTERRUPT_VECTORS + 1)
49 #define DLB2_PF_NUM_PACKED_MODE_VECTORS \
50 	DLB2_PF_TOTAL_NUM_INTERRUPT_VECTORS
51 #define DLB2_PF_COMPRESSED_MODE_CQ_VECTOR_ID \
52 	DLB2_PF_NUM_NON_CQ_INTERRUPT_VECTORS
53 
54 /* DLB non-CQ interrupts (alarm, mailbox, WDT) */
55 #define DLB2_INT_NON_CQ 0
56 
57 #define DLB2_ALARM_HW_SOURCE_SYS 0
58 #define DLB2_ALARM_HW_SOURCE_DLB 1
59 
60 #define DLB2_ALARM_HW_UNIT_CHP 4
61 
62 #define DLB2_ALARM_SYS_AID_ILLEGAL_QID		3
63 #define DLB2_ALARM_SYS_AID_DISABLED_QID		4
64 #define DLB2_ALARM_SYS_AID_ILLEGAL_HCW		5
65 #define DLB2_ALARM_HW_CHP_AID_ILLEGAL_ENQ	1
66 #define DLB2_ALARM_HW_CHP_AID_EXCESS_TOKEN_POPS 2
67 
68 #define DLB2_VF_NUM_NON_CQ_INTERRUPT_VECTORS 1
69 #define DLB2_VF_NUM_CQ_INTERRUPT_VECTORS     31
70 #define DLB2_VF_BASE_CQ_VECTOR_ID	     0
71 #define DLB2_VF_LAST_CQ_VECTOR_ID	     30
72 #define DLB2_VF_MBOX_VECTOR_ID		     31
73 #define DLB2_VF_TOTAL_NUM_INTERRUPT_VECTORS \
74 	(DLB2_VF_NUM_NON_CQ_INTERRUPT_VECTORS + \
75 	 DLB2_VF_NUM_CQ_INTERRUPT_VECTORS)
76 
77 #define DLB2_VDEV_MAX_NUM_INTERRUPT_VECTORS (DLB2_MAX_NUM_LDB_PORTS + \
78 					     DLB2_MAX_NUM_DIR_PORTS + 1)
79 
80 /*
81  * Hardware-defined base addresses. Those prefixed 'DLB2_DRV' are only used by
82  * the PF driver.
83  */
84 #define DLB2_DRV_LDB_PP_BASE   0x2300000
85 #define DLB2_DRV_LDB_PP_STRIDE 0x1000
86 #define DLB2_DRV_LDB_PP_BOUND  (DLB2_DRV_LDB_PP_BASE + \
87 				DLB2_DRV_LDB_PP_STRIDE * DLB2_MAX_NUM_LDB_PORTS)
88 #define DLB2_DRV_DIR_PP_BASE   0x2200000
89 #define DLB2_DRV_DIR_PP_STRIDE 0x1000
90 #define DLB2_DRV_DIR_PP_BOUND  (DLB2_DRV_DIR_PP_BASE + \
91 				DLB2_DRV_DIR_PP_STRIDE * DLB2_MAX_NUM_DIR_PORTS)
92 #define DLB2_LDB_PP_BASE       0x2100000
93 #define DLB2_LDB_PP_STRIDE     0x1000
94 #define DLB2_LDB_PP_BOUND      (DLB2_LDB_PP_BASE + \
95 				DLB2_LDB_PP_STRIDE * DLB2_MAX_NUM_LDB_PORTS)
96 #define DLB2_LDB_PP_OFFS(id)   (DLB2_LDB_PP_BASE + (id) * DLB2_PP_SIZE)
97 #define DLB2_DIR_PP_BASE       0x2000000
98 #define DLB2_DIR_PP_STRIDE     0x1000
99 #define DLB2_DIR_PP_BOUND      (DLB2_DIR_PP_BASE + \
100 				DLB2_DIR_PP_STRIDE * DLB2_MAX_NUM_DIR_PORTS)
101 #define DLB2_DIR_PP_OFFS(id)   (DLB2_DIR_PP_BASE + (id) * DLB2_PP_SIZE)
102 
103 struct dlb2_resource_id {
104 	u32 phys_id;
105 	u32 virt_id;
106 	u8 vdev_owned;
107 	u8 vdev_id;
108 };
109 
110 struct dlb2_freelist {
111 	u32 base;
112 	u32 bound;
113 	u32 offset;
114 };
115 
dlb2_freelist_count(struct dlb2_freelist * list)116 static inline u32 dlb2_freelist_count(struct dlb2_freelist *list)
117 {
118 	return list->bound - list->base - list->offset;
119 }
120 
121 struct dlb2_hcw {
122 	u64 data;
123 	/* Word 3 */
124 	u16 opaque;
125 	u8 qid;
126 	u8 sched_type:2;
127 	u8 priority:3;
128 	u8 msg_type:3;
129 	/* Word 4 */
130 	u16 lock_id;
131 	u8 ts_flag:1;
132 	u8 rsvd1:2;
133 	u8 no_dec:1;
134 	u8 cmp_id:4;
135 	u8 cq_token:1;
136 	u8 qe_comp:1;
137 	u8 qe_frag:1;
138 	u8 qe_valid:1;
139 	u8 int_arm:1;
140 	u8 error:1;
141 	u8 rsvd:2;
142 };
143 
144 struct dlb2_ldb_queue {
145 	struct dlb2_list_entry domain_list;
146 	struct dlb2_list_entry func_list;
147 	struct dlb2_resource_id id;
148 	struct dlb2_resource_id domain_id;
149 	u32 num_qid_inflights;
150 	u32 aqed_limit;
151 	u32 sn_group; /* sn == sequence number */
152 	u32 sn_slot;
153 	u32 num_mappings;
154 	u8 sn_cfg_valid;
155 	u8 num_pending_additions;
156 	u8 owned;
157 	u8 configured;
158 };
159 
160 /*
161  * Directed ports and queues are paired by nature, so the driver tracks them
162  * with a single data structure.
163  */
164 struct dlb2_dir_pq_pair {
165 	struct dlb2_list_entry domain_list;
166 	struct dlb2_list_entry func_list;
167 	struct dlb2_resource_id id;
168 	struct dlb2_resource_id domain_id;
169 	u32 ref_cnt;
170 	u8 init_tkn_cnt;
171 	u8 queue_configured;
172 	u8 port_configured;
173 	u8 owned;
174 	u8 enabled;
175 };
176 
177 enum dlb2_qid_map_state {
178 	/* The slot doesn't contain a valid queue mapping */
179 	DLB2_QUEUE_UNMAPPED,
180 	/* The slot contains a valid queue mapping */
181 	DLB2_QUEUE_MAPPED,
182 	/* The driver is mapping a queue into this slot */
183 	DLB2_QUEUE_MAP_IN_PROG,
184 	/* The driver is unmapping a queue from this slot */
185 	DLB2_QUEUE_UNMAP_IN_PROG,
186 	/*
187 	 * The driver is unmapping a queue from this slot, and once complete
188 	 * will replace it with another mapping.
189 	 */
190 	DLB2_QUEUE_UNMAP_IN_PROG_PENDING_MAP,
191 };
192 
193 struct dlb2_ldb_port_qid_map {
194 	enum dlb2_qid_map_state state;
195 	u16 qid;
196 	u16 pending_qid;
197 	u8 priority;
198 	u8 pending_priority;
199 };
200 
201 struct dlb2_ldb_port {
202 	struct dlb2_list_entry domain_list;
203 	struct dlb2_list_entry func_list;
204 	struct dlb2_resource_id id;
205 	struct dlb2_resource_id domain_id;
206 	/* The qid_map represents the hardware QID mapping state. */
207 	struct dlb2_ldb_port_qid_map qid_map[DLB2_MAX_NUM_QIDS_PER_LDB_CQ];
208 	u32 hist_list_entry_base;
209 	u32 hist_list_entry_limit;
210 	u32 ref_cnt;
211 	u8 init_tkn_cnt;
212 	u8 num_pending_removals;
213 	u8 num_mappings;
214 	u8 owned;
215 	u8 enabled;
216 	u8 configured;
217 };
218 
219 struct dlb2_sn_group {
220 	u32 mode;
221 	u32 sequence_numbers_per_queue;
222 	u32 slot_use_bitmap;
223 	u32 id;
224 };
225 
dlb2_sn_group_full(struct dlb2_sn_group * group)226 static inline bool dlb2_sn_group_full(struct dlb2_sn_group *group)
227 {
228 	u32 mask[] = {
229 		0x0000ffff,  /* 64 SNs per queue */
230 		0x000000ff,  /* 128 SNs per queue */
231 		0x0000000f,  /* 256 SNs per queue */
232 		0x00000003,  /* 512 SNs per queue */
233 		0x00000001}; /* 1024 SNs per queue */
234 
235 	return group->slot_use_bitmap == mask[group->mode];
236 }
237 
dlb2_sn_group_alloc_slot(struct dlb2_sn_group * group)238 static inline int dlb2_sn_group_alloc_slot(struct dlb2_sn_group *group)
239 {
240 	u32 bound[6] = {16, 8, 4, 2, 1};
241 	u32 i;
242 
243 	for (i = 0; i < bound[group->mode]; i++) {
244 		if (!(group->slot_use_bitmap & (1 << i))) {
245 			group->slot_use_bitmap |= 1 << i;
246 			return i;
247 		}
248 	}
249 
250 	return -1;
251 }
252 
253 static inline void
dlb2_sn_group_free_slot(struct dlb2_sn_group * group,int slot)254 dlb2_sn_group_free_slot(struct dlb2_sn_group *group, int slot)
255 {
256 	group->slot_use_bitmap &= ~(1 << slot);
257 }
258 
dlb2_sn_group_used_slots(struct dlb2_sn_group * group)259 static inline int dlb2_sn_group_used_slots(struct dlb2_sn_group *group)
260 {
261 	int i, cnt = 0;
262 
263 	for (i = 0; i < 32; i++)
264 		cnt += !!(group->slot_use_bitmap & (1 << i));
265 
266 	return cnt;
267 }
268 
269 struct dlb2_hw_domain {
270 	struct dlb2_function_resources *parent_func;
271 	struct dlb2_list_entry func_list;
272 	struct dlb2_list_head used_ldb_queues;
273 	struct dlb2_list_head used_ldb_ports[DLB2_NUM_COS_DOMAINS];
274 	struct dlb2_list_head used_dir_pq_pairs;
275 	struct dlb2_list_head avail_ldb_queues;
276 	struct dlb2_list_head avail_ldb_ports[DLB2_NUM_COS_DOMAINS];
277 	struct dlb2_list_head avail_dir_pq_pairs;
278 	u32 total_hist_list_entries;
279 	u32 avail_hist_list_entries;
280 	u32 hist_list_entry_base;
281 	u32 hist_list_entry_offset;
282 	u32 num_ldb_credits;
283 	u32 num_dir_credits;
284 	u32 num_avail_aqed_entries;
285 	u32 num_used_aqed_entries;
286 	struct dlb2_resource_id id;
287 	int num_pending_removals;
288 	int num_pending_additions;
289 	u8 configured;
290 	u8 started;
291 };
292 
293 struct dlb2_bitmap;
294 
295 struct dlb2_function_resources {
296 	struct dlb2_list_head avail_domains;
297 	struct dlb2_list_head used_domains;
298 	struct dlb2_list_head avail_ldb_queues;
299 	struct dlb2_list_head avail_ldb_ports[DLB2_NUM_COS_DOMAINS];
300 	struct dlb2_list_head avail_dir_pq_pairs;
301 	struct dlb2_bitmap *avail_hist_list_entries;
302 	u32 num_avail_domains;
303 	u32 num_avail_ldb_queues;
304 	u32 num_avail_ldb_ports[DLB2_NUM_COS_DOMAINS];
305 	u32 num_avail_dir_pq_pairs;
306 	u32 num_avail_qed_entries;
307 	u32 num_avail_dqed_entries;
308 	u32 num_avail_aqed_entries;
309 	u8 locked; /* (VDEV only) */
310 };
311 
312 /*
313  * After initialization, each resource in dlb2_hw_resources is located in one
314  * of the following lists:
315  * -- The PF's available resources list. These are unconfigured resources owned
316  *	by the PF and not allocated to a dlb2 scheduling domain.
317  * -- A VDEV's available resources list. These are VDEV-owned unconfigured
318  *	resources not allocated to a dlb2 scheduling domain.
319  * -- A domain's available resources list. These are domain-owned unconfigured
320  *	resources.
321  * -- A domain's used resources list. These are domain-owned configured
322  *	resources.
323  *
324  * A resource moves to a new list when a VDEV or domain is created or destroyed,
325  * or when the resource is configured.
326  */
327 struct dlb2_hw_resources {
328 	struct dlb2_ldb_queue ldb_queues[DLB2_MAX_NUM_LDB_QUEUES];
329 	struct dlb2_ldb_port ldb_ports[DLB2_MAX_NUM_LDB_PORTS];
330 	struct dlb2_dir_pq_pair dir_pq_pairs[DLB2_MAX_NUM_DIR_PORTS];
331 	struct dlb2_sn_group sn_groups[DLB2_MAX_NUM_SEQUENCE_NUMBER_GROUPS];
332 };
333 
334 struct dlb2_mbox {
335 	u32 *mbox;
336 	u32 *isr_in_progress;
337 };
338 
339 struct dlb2_sw_mbox {
340 	struct dlb2_mbox vdev_to_pf;
341 	struct dlb2_mbox pf_to_vdev;
342 	void (*pf_to_vdev_inject)(void *arg);
343 	void *pf_to_vdev_inject_arg;
344 };
345 
346 struct dlb2_hw {
347 	/* BAR 0 address */
348 	void  *csr_kva;
349 	unsigned long csr_phys_addr;
350 	/* BAR 2 address */
351 	void  *func_kva;
352 	unsigned long func_phys_addr;
353 
354 	/* Resource tracking */
355 	struct dlb2_hw_resources rsrcs;
356 	struct dlb2_function_resources pf;
357 	struct dlb2_function_resources vdev[DLB2_MAX_NUM_VDEVS];
358 	struct dlb2_hw_domain domains[DLB2_MAX_NUM_DOMAINS];
359 	u8 cos_reservation[DLB2_NUM_COS_DOMAINS];
360 
361 	/* Virtualization */
362 	int virt_mode;
363 	struct dlb2_sw_mbox mbox[DLB2_MAX_NUM_VDEVS];
364 	unsigned int pasid[DLB2_MAX_NUM_VDEVS];
365 };
366 
367 #endif /* __DLB2_HW_TYPES_H */
368