xref: /dpdk/drivers/net/dpaa/dpaa_fmc.c (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2017-2021 NXP
3  */
4 
5 /* System headers */
6 #include <stdio.h>
7 #include <inttypes.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10 
11 #include <dpaa_ethdev.h>
12 #include <dpaa_flow.h>
13 #include <rte_dpaa_logs.h>
14 #include <fmlib/fm_port_ext.h>
15 #include <fmlib/fm_vsp_ext.h>
16 
17 #define FMC_OUTPUT_FORMAT_VER 0x106
18 
19 #define FMC_NAME_LEN             64
20 #define FMC_FMAN_NUM              2
21 #define FMC_PORTS_PER_FMAN       16
22 #define FMC_SCHEMES_NUM          32
23 #define FMC_SCHEME_PROTOCOLS_NUM 16
24 #define FMC_CC_NODES_NUM        512
25 #define FMC_REPLICATORS_NUM      16
26 #define FMC_PLC_NUM              64
27 #define MAX_SP_CODE_SIZE      0x7C0
28 #define FMC_MANIP_MAX            64
29 #define FMC_HMANIP_MAX          512
30 #define FMC_INSERT_MAX           56
31 #define FM_PCD_MAX_REPS          64
32 
33 typedef struct fmc_port_t {
34 	e_fm_port_type type;
35 	unsigned int number;
36 	struct fm_pcd_net_env_params_t distinction_units;
37 	struct ioc_fm_port_pcd_params_t pcd_param;
38 	struct ioc_fm_port_pcd_prs_params_t prs_param;
39 	struct ioc_fm_port_pcd_kg_params_t kg_param;
40 	struct ioc_fm_port_pcd_cc_params_t cc_param;
41 	char name[FMC_NAME_LEN];
42 	char cctree_name[FMC_NAME_LEN];
43 	t_handle handle;
44 	t_handle env_id_handle;
45 	t_handle env_id_dev_id;
46 	t_handle cctree_handle;
47 	t_handle cctree_dev_id;
48 
49 	unsigned int schemes_count;
50 	unsigned int schemes[FMC_SCHEMES_NUM];
51 	unsigned int ccnodes_count;
52 	unsigned int ccnodes[FMC_CC_NODES_NUM];
53 	unsigned int htnodes_count;
54 	unsigned int htnodes[FMC_CC_NODES_NUM];
55 
56 	unsigned int replicators_count;
57 	unsigned int replicators[FMC_REPLICATORS_NUM];
58 	ioc_fm_port_vsp_alloc_params_t vsp_param;
59 
60 	unsigned int ccroot_count;
61 	unsigned int ccroot[FMC_CC_NODES_NUM];
62 	enum ioc_fm_pcd_engine ccroot_type[FMC_CC_NODES_NUM];
63 	unsigned int ccroot_manip[FMC_CC_NODES_NUM];
64 
65 	unsigned int reasm_index;
66 } fmc_port;
67 
68 typedef struct fmc_fman_t {
69 	unsigned int number;
70 	unsigned int port_count;
71 	unsigned int ports[FMC_PORTS_PER_FMAN];
72 	char name[FMC_NAME_LEN];
73 	t_handle handle;
74 	char pcd_name[FMC_NAME_LEN];
75 	t_handle pcd_handle;
76 	unsigned int kg_payload_offset;
77 
78 	unsigned int offload_support;
79 
80 	unsigned int reasm_count;
81 	struct fm_pcd_manip_params_t reasm[FMC_MANIP_MAX];
82 	char reasm_name[FMC_MANIP_MAX][FMC_NAME_LEN];
83 	t_handle reasm_handle[FMC_MANIP_MAX];
84 	t_handle reasm_dev_id[FMC_MANIP_MAX];
85 
86 	unsigned int frag_count;
87 	struct fm_pcd_manip_params_t frag[FMC_MANIP_MAX];
88 	char frag_name[FMC_MANIP_MAX][FMC_NAME_LEN];
89 	t_handle frag_handle[FMC_MANIP_MAX];
90 	t_handle frag_dev_id[FMC_MANIP_MAX];
91 
92 	unsigned int hdr_count;
93 	struct fm_pcd_manip_params_t hdr[FMC_HMANIP_MAX];
94 	uint8_t insert_data[FMC_HMANIP_MAX][FMC_INSERT_MAX];
95 	char hdr_name[FMC_HMANIP_MAX][FMC_NAME_LEN];
96 	t_handle hdr_handle[FMC_HMANIP_MAX];
97 	t_handle hdr_dev_id[FMC_HMANIP_MAX];
98 	unsigned int hdr_has_next[FMC_HMANIP_MAX];
99 	unsigned int hdr_next[FMC_HMANIP_MAX];
100 } fmc_fman;
101 
102 typedef enum fmc_apply_order_e {
103 	fmcengine_start,
104 	fmcengine_end,
105 	fmcport_start,
106 	fmcport_end,
107 	fmcscheme,
108 	fmcccnode,
109 	fmchtnode,
110 	fmccctree,
111 	fmcpolicer,
112 	fmcreplicator,
113 	fmcmanipulation
114 } fmc_apply_order_e;
115 
116 typedef struct fmc_apply_order_t {
117 	fmc_apply_order_e type;
118 	unsigned int index;
119 } fmc_apply_order;
120 
121 struct fmc_model_t {
122 	unsigned int format_version;
123 	unsigned int sp_enable;
124 	t_fm_pcd_prs_sw_params sp;
125 	uint8_t spcode[MAX_SP_CODE_SIZE];
126 
127 	unsigned int fman_count;
128 	fmc_fman fman[FMC_FMAN_NUM];
129 
130 	unsigned int port_count;
131 	fmc_port port[FMC_FMAN_NUM * FMC_PORTS_PER_FMAN];
132 
133 	unsigned int scheme_count;
134 	char scheme_name[FMC_SCHEMES_NUM][FMC_NAME_LEN];
135 	t_handle scheme_handle[FMC_SCHEMES_NUM];
136 	t_handle scheme_dev_id[FMC_SCHEMES_NUM];
137 	struct fm_pcd_kg_scheme_params_t scheme[FMC_SCHEMES_NUM];
138 
139 	unsigned int ccnode_count;
140 	char ccnode_name[FMC_CC_NODES_NUM][FMC_NAME_LEN];
141 	t_handle ccnode_handle[FMC_CC_NODES_NUM];
142 	t_handle ccnode_dev_id[FMC_CC_NODES_NUM];
143 	struct fm_pcd_cc_node_params_t ccnode[FMC_CC_NODES_NUM];
144 	uint8_t cckeydata[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]
145 					[FM_PCD_MAX_SIZE_OF_KEY];
146 	unsigned char ccmask[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]
147 						[FM_PCD_MAX_SIZE_OF_KEY];
148 	unsigned int
149 		ccentry_action_index[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
150 	enum ioc_fm_pcd_engine
151 		ccentry_action_type[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
152 	unsigned char ccentry_frag[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
153 	unsigned int ccentry_manip[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
154 	unsigned int ccmiss_action_index[FMC_CC_NODES_NUM];
155 	enum ioc_fm_pcd_engine ccmiss_action_type[FMC_CC_NODES_NUM];
156 	unsigned char ccmiss_frag[FMC_CC_NODES_NUM];
157 	unsigned int ccmiss_manip[FMC_CC_NODES_NUM];
158 
159 	unsigned int htnode_count;
160 	char htnode_name[FMC_CC_NODES_NUM][FMC_NAME_LEN];
161 	t_handle htnode_handle[FMC_CC_NODES_NUM];
162 	t_handle htnode_dev_id[FMC_CC_NODES_NUM];
163 	struct fm_pcd_hash_table_params_t htnode[FMC_CC_NODES_NUM];
164 
165 	unsigned int htentry_count[FMC_CC_NODES_NUM];
166 	struct ioc_fm_pcd_cc_key_params_t
167 		htentry[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
168 	uint8_t htkeydata[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]
169 					[FM_PCD_MAX_SIZE_OF_KEY];
170 	unsigned int
171 		htentry_action_index[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
172 	enum ioc_fm_pcd_engine
173 		htentry_action_type[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
174 	unsigned char htentry_frag[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
175 	unsigned int htentry_manip[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
176 
177 	unsigned int htmiss_action_index[FMC_CC_NODES_NUM];
178 	enum ioc_fm_pcd_engine htmiss_action_type[FMC_CC_NODES_NUM];
179 	unsigned char htmiss_frag[FMC_CC_NODES_NUM];
180 	unsigned int htmiss_manip[FMC_CC_NODES_NUM];
181 
182 	unsigned int replicator_count;
183 	char replicator_name[FMC_REPLICATORS_NUM][FMC_NAME_LEN];
184 	t_handle replicator_handle[FMC_REPLICATORS_NUM];
185 	t_handle replicator_dev_id[FMC_REPLICATORS_NUM];
186 	struct fm_pcd_frm_replic_group_params_t replicator[FMC_REPLICATORS_NUM];
187 	unsigned int
188 	 repentry_action_index[FMC_REPLICATORS_NUM][FM_PCD_MAX_REPS];
189 	unsigned char repentry_frag[FMC_REPLICATORS_NUM][FM_PCD_MAX_REPS];
190 	unsigned int repentry_manip[FMC_REPLICATORS_NUM][FM_PCD_MAX_REPS];
191 
192 	unsigned int policer_count;
193 	char policer_name[FMC_PLC_NUM][FMC_NAME_LEN];
194 	struct fm_pcd_plcr_profile_params_t policer[FMC_PLC_NUM];
195 	t_handle policer_handle[FMC_PLC_NUM];
196 	t_handle policer_dev_id[FMC_PLC_NUM];
197 	unsigned int policer_action_index[FMC_PLC_NUM][3];
198 
199 	unsigned int apply_order_count;
200 	fmc_apply_order apply_order[FMC_FMAN_NUM *
201 		FMC_PORTS_PER_FMAN *
202 		(FMC_SCHEMES_NUM + FMC_CC_NODES_NUM)];
203 };
204 
205 struct fmc_model_t *g_fmc_model;
206 
207 static int dpaa_port_fmc_port_parse(struct fman_if *fif,
208 				    const struct fmc_model_t *fmc_model,
209 				    int apply_idx)
210 {
211 	int current_port = fmc_model->apply_order[apply_idx].index;
212 	const fmc_port *pport = &fmc_model->port[current_port];
213 	const uint8_t mac_idx[] = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1};
214 	const uint8_t mac_type[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
215 
216 	if (mac_idx[fif->mac_idx] != pport->number ||
217 		mac_type[fif->mac_idx] != pport->type)
218 		return -1;
219 
220 	return current_port;
221 }
222 
223 static int dpaa_port_fmc_scheme_parse(struct fman_if *fif,
224 				const struct fmc_model_t *fmc,
225 				int apply_idx,
226 				uint16_t *rxq_idx, int max_nb_rxq,
227 				uint32_t *fqids, int8_t *vspids)
228 {
229 	int idx = fmc->apply_order[apply_idx].index;
230 	uint32_t i;
231 
232 	if (!fmc->scheme[idx].override_storage_profile &&
233 		fif->is_shared_mac) {
234 		DPAA_PMD_WARN("No VSP assigned to scheme %d for sharemac %d!",
235 			idx, fif->mac_idx);
236 		DPAA_PMD_WARN("Risk to receive pkts from skb pool to CRASH!");
237 	}
238 
239 	if (e_IOC_FM_PCD_DONE ==
240 		fmc->scheme[idx].next_engine) {
241 		for (i = 0; i < fmc->scheme[idx]
242 			.key_ext_and_hash.hash_dist_num_of_fqids; i++) {
243 			uint32_t fqid = fmc->scheme[idx].base_fqid + i;
244 			int k, found = 0;
245 
246 			if (fqid == fif->fqid_rx_def ||
247 			    (fqid >= fif->fqid_rx_pcd &&
248 					fqid < (fif->fqid_rx_pcd +
249 						fif->fqid_rx_pcd_count))) {
250 				if (fif->is_shared_mac &&
251 				fmc->scheme[idx].override_storage_profile &&
252 				fmc->scheme[idx].storage_profile.direct &&
253 				fmc->scheme[idx].storage_profile
254 				.profile_select.direct_relative_profile_id !=
255 				fif->base_profile_id) {
256 					DPAA_PMD_ERR("Def RXQ must be associated with def VSP on sharemac!");
257 
258 					return -1;
259 				}
260 				continue;
261 			}
262 
263 			if (fif->is_shared_mac &&
264 			!fmc->scheme[idx].override_storage_profile) {
265 				DPAA_PMD_ERR("RXQ to DPDK must be associated with VSP on sharemac!");
266 				return -1;
267 			}
268 
269 			if (fif->is_shared_mac &&
270 				fmc->scheme[idx].override_storage_profile &&
271 				fmc->scheme[idx].storage_profile.direct &&
272 				fmc->scheme[idx].storage_profile
273 				.profile_select.direct_relative_profile_id ==
274 				fif->base_profile_id) {
275 				DPAA_PMD_ERR("RXQ can't be associated with default VSP on sharemac!");
276 
277 				return -1;
278 			}
279 
280 			if ((*rxq_idx) >= max_nb_rxq) {
281 				DPAA_PMD_DEBUG("Too many queues in FMC policy"
282 					"%d overflow %d",
283 					(*rxq_idx), max_nb_rxq);
284 
285 				continue;
286 			}
287 
288 			for (k = 0; k < (*rxq_idx); k++) {
289 				if (fqids[k] == fqid) {
290 					found = 1;
291 					break;
292 				}
293 			}
294 
295 			if (found)
296 				continue;
297 			fqids[(*rxq_idx)] = fqid;
298 			if (fmc->scheme[idx].override_storage_profile) {
299 				if (fmc->scheme[idx].storage_profile.direct) {
300 					vspids[(*rxq_idx)] =
301 						fmc->scheme[idx].storage_profile
302 						.profile_select
303 						.direct_relative_profile_id;
304 				} else {
305 					vspids[(*rxq_idx)] = -1;
306 				}
307 			} else {
308 				vspids[(*rxq_idx)] = -1;
309 			}
310 			(*rxq_idx)++;
311 		}
312 	}
313 
314 	return 0;
315 }
316 
317 static int dpaa_port_fmc_ccnode_parse(struct fman_if *fif,
318 				      const struct fmc_model_t *fmc_model,
319 				      int apply_idx,
320 				      uint16_t *rxq_idx, int max_nb_rxq,
321 				      uint32_t *fqids, int8_t *vspids)
322 {
323 	uint16_t j, k, found = 0;
324 	const struct ioc_keys_params_t *keys_params;
325 	uint32_t fqid, cc_idx = fmc_model->apply_order[apply_idx].index;
326 
327 	keys_params = &fmc_model->ccnode[cc_idx].keys_params;
328 
329 	if ((*rxq_idx) >= max_nb_rxq) {
330 		DPAA_PMD_WARN("Too many queues in FMC policy %d overflow %d",
331 			      (*rxq_idx), max_nb_rxq);
332 
333 		return 0;
334 	}
335 
336 	for (j = 0; j < keys_params->num_of_keys; ++j) {
337 		found = 0;
338 		fqid = keys_params->key_params[j].cc_next_engine_params
339 			.params.enqueue_params.new_fqid;
340 
341 		/* We read DPDK queue from last classification rule present in
342 		 * FMC policy file. Hence, this check is required here.
343 		 * Also, the last classification rule in FMC policy file must
344 		 * have userspace queue so that it can be used by DPDK
345 		 * application.
346 		 */
347 		if (keys_params->key_params[j].cc_next_engine_params
348 			.next_engine != e_IOC_FM_PCD_DONE) {
349 			DPAA_PMD_WARN("FMC CC next engine not support");
350 			continue;
351 		}
352 		if (keys_params->key_params[j].cc_next_engine_params
353 			.params.enqueue_params.action !=
354 			e_IOC_FM_PCD_ENQ_FRAME)
355 			continue;
356 		for (k = 0; k < (*rxq_idx); k++) {
357 			if (fqids[k] == fqid) {
358 				found = 1;
359 				break;
360 			}
361 		}
362 		if (found)
363 			continue;
364 
365 		if ((*rxq_idx) >= max_nb_rxq) {
366 			DPAA_PMD_WARN("Too many queues in FMC policy %d overflow %d",
367 				      (*rxq_idx), max_nb_rxq);
368 
369 			return 0;
370 		}
371 
372 		fqids[(*rxq_idx)] = fqid;
373 		vspids[(*rxq_idx)] =
374 			keys_params->key_params[j].cc_next_engine_params
375 				.params.enqueue_params
376 				.new_relative_storage_profile_id;
377 
378 		if (vspids[(*rxq_idx)] == fif->base_profile_id &&
379 		    fif->is_shared_mac) {
380 			DPAA_PMD_ERR("VSP %d can NOT be used on DPDK.",
381 				     vspids[(*rxq_idx)]);
382 			DPAA_PMD_ERR("It is associated to skb pool of shared interface.");
383 			return -1;
384 		}
385 		(*rxq_idx)++;
386 	}
387 
388 	return 0;
389 }
390 
391 int dpaa_port_fmc_init(struct fman_if *fif,
392 		       uint32_t *fqids, int8_t *vspids, int max_nb_rxq)
393 {
394 	int current_port = -1, ret;
395 	uint16_t rxq_idx = 0;
396 	const struct fmc_model_t *fmc_model;
397 	uint32_t i;
398 
399 	if (!g_fmc_model) {
400 		size_t bytes_read;
401 		FILE *fp = fopen(FMC_FILE, "rb");
402 
403 		if (!fp) {
404 			DPAA_PMD_ERR("%s not exists", FMC_FILE);
405 			return -1;
406 		}
407 
408 		g_fmc_model = rte_malloc(NULL, sizeof(struct fmc_model_t), 64);
409 		if (!g_fmc_model) {
410 			DPAA_PMD_ERR("FMC memory alloc failed");
411 			fclose(fp);
412 			return -1;
413 		}
414 
415 		bytes_read = fread(g_fmc_model,
416 				   sizeof(struct fmc_model_t), 1, fp);
417 		if (!bytes_read) {
418 			DPAA_PMD_ERR("No bytes read");
419 			fclose(fp);
420 			rte_free(g_fmc_model);
421 			g_fmc_model = NULL;
422 			return -1;
423 		}
424 		fclose(fp);
425 	}
426 
427 	fmc_model = g_fmc_model;
428 
429 	if (fmc_model->format_version != FMC_OUTPUT_FORMAT_VER)
430 		return -1;
431 
432 	for (i = 0; i < fmc_model->apply_order_count; i++) {
433 		switch (fmc_model->apply_order[i].type) {
434 		case fmcengine_start:
435 			break;
436 		case fmcengine_end:
437 			break;
438 		case fmcport_start:
439 			current_port = dpaa_port_fmc_port_parse(fif,
440 								fmc_model, i);
441 			break;
442 		case fmcport_end:
443 			break;
444 		case fmcscheme:
445 			if (current_port < 0)
446 				break;
447 
448 			ret = dpaa_port_fmc_scheme_parse(fif, fmc_model,
449 							 i, &rxq_idx,
450 							 max_nb_rxq,
451 							 fqids, vspids);
452 			if (ret)
453 				return ret;
454 
455 			break;
456 		case fmcccnode:
457 			if (current_port < 0)
458 				break;
459 
460 			ret = dpaa_port_fmc_ccnode_parse(fif, fmc_model,
461 							 i, &rxq_idx,
462 							 max_nb_rxq, fqids,
463 							 vspids);
464 			if (ret)
465 				return ret;
466 
467 			break;
468 		case fmchtnode:
469 			break;
470 		case fmcreplicator:
471 			break;
472 		case fmccctree:
473 			break;
474 		case fmcpolicer:
475 			break;
476 		case fmcmanipulation:
477 			break;
478 		default:
479 			break;
480 		}
481 	}
482 
483 	return rxq_idx;
484 }
485