xref: /dpdk/drivers/net/dpaa/dpaa_flow.c (revision daa02b5cddbb8e11b31d41e2bf7bb1ae64dcae2f)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2017-2019,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 DPAA_MAX_NUM_ETH_DEV	8
18 
19 static inline
20 ioc_fm_pcd_extract_entry_t *
21 SCH_EXT_ARR(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx)
22 {
23 return &scheme_params->param.key_ext_and_hash.extract_array[hdr_idx];
24 }
25 
26 #define SCH_EXT_HDR(scheme_params, hdr_idx) \
27 	SCH_EXT_ARR(scheme_params, hdr_idx)->extract_params.extract_by_hdr
28 
29 #define SCH_EXT_FULL_FLD(scheme_params, hdr_idx) \
30 	SCH_EXT_HDR(scheme_params, hdr_idx).extract_by_hdr_type.full_field
31 
32 /* FM global info */
33 struct dpaa_fm_info {
34 	t_handle fman_handle;
35 	t_handle pcd_handle;
36 };
37 
38 /*FM model to read and write from file */
39 struct dpaa_fm_model {
40 	uint32_t dev_count;
41 	uint8_t device_order[DPAA_MAX_NUM_ETH_DEV];
42 	t_fm_port_params fm_port_params[DPAA_MAX_NUM_ETH_DEV];
43 	t_handle netenv_devid[DPAA_MAX_NUM_ETH_DEV];
44 	t_handle scheme_devid[DPAA_MAX_NUM_ETH_DEV][2];
45 };
46 
47 static struct dpaa_fm_info fm_info;
48 static struct dpaa_fm_model fm_model;
49 static const char *fm_log = "/tmp/fmdpdk.bin";
50 
51 static inline uint8_t fm_default_vsp_id(struct fman_if *fif)
52 {
53 	/* Avoid being same as base profile which could be used
54 	 * for kernel interface of shared mac.
55 	 */
56 	if (fif->base_profile_id)
57 		return 0;
58 	else
59 		return DPAA_DEFAULT_RXQ_VSP_ID;
60 }
61 
62 static void fm_prev_cleanup(void)
63 {
64 	uint32_t fman_id = 0, i = 0, devid;
65 	struct dpaa_if dpaa_intf = {0};
66 	t_fm_pcd_params fm_pcd_params = {0};
67 	PMD_INIT_FUNC_TRACE();
68 
69 	fm_info.fman_handle = fm_open(fman_id);
70 	if (!fm_info.fman_handle) {
71 		printf("\n%s- unable to open FMAN", __func__);
72 		return;
73 	}
74 
75 	fm_pcd_params.h_fm = fm_info.fman_handle;
76 	fm_pcd_params.prs_support = true;
77 	fm_pcd_params.kg_support = true;
78 	/* FM PCD Open */
79 	fm_info.pcd_handle = fm_pcd_open(&fm_pcd_params);
80 	if (!fm_info.pcd_handle) {
81 		printf("\n%s- unable to open PCD", __func__);
82 		return;
83 	}
84 
85 	while (i < fm_model.dev_count) {
86 		devid = fm_model.device_order[i];
87 		/* FM Port Open */
88 		fm_model.fm_port_params[devid].h_fm = fm_info.fman_handle;
89 		dpaa_intf.port_handle =
90 				fm_port_open(&fm_model.fm_port_params[devid]);
91 		dpaa_intf.scheme_handle[0] = create_device(fm_info.pcd_handle,
92 					fm_model.scheme_devid[devid][0]);
93 		dpaa_intf.scheme_count = 1;
94 		if (fm_model.scheme_devid[devid][1]) {
95 			dpaa_intf.scheme_handle[1] =
96 				create_device(fm_info.pcd_handle,
97 					fm_model.scheme_devid[devid][1]);
98 			if (dpaa_intf.scheme_handle[1])
99 				dpaa_intf.scheme_count++;
100 		}
101 
102 		dpaa_intf.netenv_handle = create_device(fm_info.pcd_handle,
103 					fm_model.netenv_devid[devid]);
104 		i++;
105 		if (!dpaa_intf.netenv_handle ||
106 			!dpaa_intf.scheme_handle[0] ||
107 			!dpaa_intf.port_handle)
108 			continue;
109 
110 		if (dpaa_fm_deconfig(&dpaa_intf, NULL))
111 			printf("\nDPAA FM deconfig failed\n");
112 	}
113 
114 	if (dpaa_fm_term())
115 		printf("\nDPAA FM term failed\n");
116 
117 	memset(&fm_model, 0, sizeof(struct dpaa_fm_model));
118 }
119 
120 void dpaa_write_fm_config_to_file(void)
121 {
122 	size_t bytes_write;
123 	FILE *fp = fopen(fm_log, "wb");
124 	PMD_INIT_FUNC_TRACE();
125 
126 	if (!fp) {
127 		DPAA_PMD_ERR("File open failed");
128 		return;
129 	}
130 	bytes_write = fwrite(&fm_model, sizeof(struct dpaa_fm_model), 1, fp);
131 	if (!bytes_write) {
132 		DPAA_PMD_WARN("No bytes write");
133 		fclose(fp);
134 		return;
135 	}
136 	fclose(fp);
137 }
138 
139 static void dpaa_read_fm_config_from_file(void)
140 {
141 	size_t bytes_read;
142 	FILE *fp = fopen(fm_log, "rb");
143 	PMD_INIT_FUNC_TRACE();
144 
145 	if (!fp)
146 		return;
147 	DPAA_PMD_INFO("Previous DPDK-FM config instance present, cleaning up.");
148 
149 	bytes_read = fread(&fm_model, sizeof(struct dpaa_fm_model), 1, fp);
150 	if (!bytes_read) {
151 		DPAA_PMD_WARN("No bytes read");
152 		fclose(fp);
153 		return;
154 	}
155 	fclose(fp);
156 
157 	/*FM cleanup from previous configured app */
158 	fm_prev_cleanup();
159 }
160 
161 static inline int
162 set_hash_params_eth(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx)
163 {
164 	int k;
165 
166 	for (k = 0; k < 2; k++) {
167 		SCH_EXT_ARR(scheme_params, hdr_idx)->type =
168 						e_IOC_FM_PCD_EXTRACT_BY_HDR;
169 		SCH_EXT_HDR(scheme_params, hdr_idx).hdr =
170 						HEADER_TYPE_ETH;
171 		SCH_EXT_HDR(scheme_params, hdr_idx).hdr_index =
172 						e_IOC_FM_PCD_HDR_INDEX_NONE;
173 		SCH_EXT_HDR(scheme_params, hdr_idx).type =
174 						e_IOC_FM_PCD_EXTRACT_FULL_FIELD;
175 		if (k == 0)
176 			SCH_EXT_FULL_FLD(scheme_params, hdr_idx).eth =
177 						IOC_NET_HF_ETH_SA;
178 		else
179 			SCH_EXT_FULL_FLD(scheme_params, hdr_idx).eth =
180 						IOC_NET_HF_ETH_DA;
181 		hdr_idx++;
182 	}
183 	return hdr_idx;
184 }
185 
186 static inline int
187 set_hash_params_ipv4(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx)
188 {
189 	int k;
190 
191 	for (k = 0; k < 2; k++) {
192 		SCH_EXT_ARR(scheme_params, hdr_idx)->type =
193 						e_IOC_FM_PCD_EXTRACT_BY_HDR;
194 		SCH_EXT_HDR(scheme_params, hdr_idx).hdr =
195 						HEADER_TYPE_IPV4;
196 		SCH_EXT_HDR(scheme_params, hdr_idx).hdr_index =
197 						e_IOC_FM_PCD_HDR_INDEX_NONE;
198 		SCH_EXT_HDR(scheme_params, hdr_idx).type =
199 						e_IOC_FM_PCD_EXTRACT_FULL_FIELD;
200 		if (k == 0)
201 			SCH_EXT_FULL_FLD(scheme_params, hdr_idx).ipv4 =
202 					ioc_net_hf_ipv_4_src_ip;
203 		else
204 			SCH_EXT_FULL_FLD(scheme_params, hdr_idx).ipv4 =
205 					ioc_net_hf_ipv_4_dst_ip;
206 		hdr_idx++;
207 	}
208 	return hdr_idx;
209 }
210 
211 static inline int
212 set_hash_params_ipv6(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx)
213 {
214 	int k;
215 
216 	for (k = 0; k < 2; k++) {
217 		SCH_EXT_ARR(scheme_params, hdr_idx)->type =
218 						e_IOC_FM_PCD_EXTRACT_BY_HDR;
219 		SCH_EXT_HDR(scheme_params, hdr_idx).hdr =
220 							HEADER_TYPE_IPV6;
221 		SCH_EXT_HDR(scheme_params, hdr_idx).hdr_index =
222 						e_IOC_FM_PCD_HDR_INDEX_NONE;
223 		SCH_EXT_HDR(scheme_params, hdr_idx).type =
224 						e_IOC_FM_PCD_EXTRACT_FULL_FIELD;
225 		if (k == 0)
226 			SCH_EXT_FULL_FLD(scheme_params, hdr_idx).ipv6 =
227 					ioc_net_hf_ipv_6_src_ip;
228 		else
229 			SCH_EXT_FULL_FLD(scheme_params, hdr_idx).ipv6 =
230 					ioc_net_hf_ipv_6_dst_ip;
231 		hdr_idx++;
232 	}
233 	return hdr_idx;
234 }
235 
236 static inline int
237 set_hash_params_udp(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx)
238 {
239 	int k;
240 
241 	for (k = 0; k < 2; k++) {
242 		SCH_EXT_ARR(scheme_params, hdr_idx)->type =
243 						e_IOC_FM_PCD_EXTRACT_BY_HDR;
244 		SCH_EXT_HDR(scheme_params, hdr_idx).hdr =
245 						HEADER_TYPE_UDP;
246 		SCH_EXT_HDR(scheme_params, hdr_idx).hdr_index =
247 						e_IOC_FM_PCD_HDR_INDEX_NONE;
248 		SCH_EXT_HDR(scheme_params, hdr_idx).type =
249 						e_IOC_FM_PCD_EXTRACT_FULL_FIELD;
250 		if (k == 0)
251 			SCH_EXT_FULL_FLD(scheme_params, hdr_idx).udp =
252 					IOC_NET_HF_UDP_PORT_SRC;
253 		else
254 			SCH_EXT_FULL_FLD(scheme_params, hdr_idx).udp =
255 					IOC_NET_HF_UDP_PORT_DST;
256 		hdr_idx++;
257 	}
258 	return hdr_idx;
259 }
260 
261 static inline int
262 set_hash_params_tcp(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx)
263 {
264 	int k;
265 
266 	for (k = 0; k < 2; k++) {
267 		SCH_EXT_ARR(scheme_params, hdr_idx)->type =
268 						e_IOC_FM_PCD_EXTRACT_BY_HDR;
269 		SCH_EXT_HDR(scheme_params, hdr_idx).hdr =
270 						HEADER_TYPE_TCP;
271 		SCH_EXT_HDR(scheme_params, hdr_idx).hdr_index =
272 						e_IOC_FM_PCD_HDR_INDEX_NONE;
273 		SCH_EXT_HDR(scheme_params, hdr_idx).type =
274 						e_IOC_FM_PCD_EXTRACT_FULL_FIELD;
275 		if (k == 0)
276 			SCH_EXT_FULL_FLD(scheme_params, hdr_idx).tcp =
277 					IOC_NET_HF_TCP_PORT_SRC;
278 		else
279 			SCH_EXT_FULL_FLD(scheme_params, hdr_idx).tcp =
280 					IOC_NET_HF_TCP_PORT_DST;
281 		hdr_idx++;
282 	}
283 	return hdr_idx;
284 }
285 
286 static inline int
287 set_hash_params_sctp(ioc_fm_pcd_kg_scheme_params_t *scheme_params, int hdr_idx)
288 {
289 	int k;
290 
291 	for (k = 0; k < 2; k++) {
292 		SCH_EXT_ARR(scheme_params, hdr_idx)->type =
293 						e_IOC_FM_PCD_EXTRACT_BY_HDR;
294 		SCH_EXT_HDR(scheme_params, hdr_idx).hdr =
295 						HEADER_TYPE_SCTP;
296 		SCH_EXT_HDR(scheme_params, hdr_idx).hdr_index =
297 						e_IOC_FM_PCD_HDR_INDEX_NONE;
298 		SCH_EXT_HDR(scheme_params, hdr_idx).type =
299 						e_IOC_FM_PCD_EXTRACT_FULL_FIELD;
300 		if (k == 0)
301 			SCH_EXT_FULL_FLD(scheme_params, hdr_idx).sctp =
302 					IOC_NET_HF_SCTP_PORT_SRC;
303 		else
304 			SCH_EXT_FULL_FLD(scheme_params, hdr_idx).sctp =
305 					IOC_NET_HF_SCTP_PORT_DST;
306 		hdr_idx++;
307 	}
308 	return hdr_idx;
309 }
310 
311 /* Set scheme params for hash distribution */
312 static int set_scheme_params(ioc_fm_pcd_kg_scheme_params_t *scheme_params,
313 	ioc_fm_pcd_net_env_params_t *dist_units,
314 	struct dpaa_if *dpaa_intf,
315 	struct fman_if *fif)
316 {
317 	int dist_idx, hdr_idx = 0;
318 	PMD_INIT_FUNC_TRACE();
319 
320 	if (fif->num_profiles) {
321 		scheme_params->param.override_storage_profile = true;
322 		scheme_params->param.storage_profile.direct = true;
323 		scheme_params->param.storage_profile.profile_select
324 			.direct_relative_profile_id = fm_default_vsp_id(fif);
325 	}
326 
327 	scheme_params->param.use_hash = 1;
328 	scheme_params->param.modify = false;
329 	scheme_params->param.always_direct = false;
330 	scheme_params->param.scheme_counter.update = 1;
331 	scheme_params->param.scheme_counter.value = 0;
332 	scheme_params->param.next_engine = e_IOC_FM_PCD_DONE;
333 	scheme_params->param.base_fqid = dpaa_intf->rx_queues[0].fqid;
334 	scheme_params->param.net_env_params.net_env_id =
335 		dpaa_intf->netenv_handle;
336 	scheme_params->param.net_env_params.num_of_distinction_units =
337 		dist_units->param.num_of_distinction_units;
338 
339 	scheme_params->param.key_ext_and_hash.hash_dist_num_of_fqids =
340 			dpaa_intf->nb_rx_queues;
341 	scheme_params->param.key_ext_and_hash.num_of_used_extracts =
342 			2 * dist_units->param.num_of_distinction_units;
343 
344 	for (dist_idx = 0; dist_idx <
345 		dist_units->param.num_of_distinction_units;
346 		dist_idx++) {
347 		switch (dist_units->param.units[dist_idx].hdrs[0].hdr) {
348 		case HEADER_TYPE_ETH:
349 			hdr_idx = set_hash_params_eth(scheme_params, hdr_idx);
350 			break;
351 
352 		case HEADER_TYPE_IPV4:
353 			hdr_idx = set_hash_params_ipv4(scheme_params, hdr_idx);
354 			break;
355 
356 		case HEADER_TYPE_IPV6:
357 			hdr_idx = set_hash_params_ipv6(scheme_params, hdr_idx);
358 			break;
359 
360 		case HEADER_TYPE_UDP:
361 			hdr_idx = set_hash_params_udp(scheme_params, hdr_idx);
362 			break;
363 
364 		case HEADER_TYPE_TCP:
365 			hdr_idx = set_hash_params_tcp(scheme_params, hdr_idx);
366 			break;
367 
368 		case HEADER_TYPE_SCTP:
369 			hdr_idx = set_hash_params_sctp(scheme_params, hdr_idx);
370 			break;
371 
372 		default:
373 			DPAA_PMD_ERR("Invalid Distinction Unit");
374 			return -1;
375 		}
376 	}
377 
378 	return 0;
379 }
380 
381 static void set_dist_units(ioc_fm_pcd_net_env_params_t *dist_units,
382 			   uint64_t req_dist_set)
383 {
384 	uint32_t loop = 0, dist_idx = 0, dist_field = 0;
385 	int l2_configured = 0, ipv4_configured = 0, ipv6_configured = 0;
386 	int udp_configured = 0, tcp_configured = 0, sctp_configured = 0;
387 	PMD_INIT_FUNC_TRACE();
388 
389 	if (!req_dist_set)
390 		dist_units->param.units[dist_idx++].hdrs[0].hdr =
391 			HEADER_TYPE_ETH;
392 
393 	while (req_dist_set) {
394 		if (req_dist_set % 2 != 0) {
395 			dist_field = 1U << loop;
396 			switch (dist_field) {
397 			case RTE_ETH_RSS_L2_PAYLOAD:
398 
399 				if (l2_configured)
400 					break;
401 				l2_configured = 1;
402 
403 				dist_units->param.units[dist_idx++].hdrs[0].hdr
404 					= HEADER_TYPE_ETH;
405 				break;
406 
407 			case RTE_ETH_RSS_IPV4:
408 			case RTE_ETH_RSS_FRAG_IPV4:
409 			case RTE_ETH_RSS_NONFRAG_IPV4_OTHER:
410 
411 				if (ipv4_configured)
412 					break;
413 				ipv4_configured = 1;
414 				dist_units->param.units[dist_idx++].hdrs[0].hdr
415 					= HEADER_TYPE_IPV4;
416 				break;
417 
418 			case RTE_ETH_RSS_IPV6:
419 			case RTE_ETH_RSS_FRAG_IPV6:
420 			case RTE_ETH_RSS_NONFRAG_IPV6_OTHER:
421 			case RTE_ETH_RSS_IPV6_EX:
422 
423 				if (ipv6_configured)
424 					break;
425 				ipv6_configured = 1;
426 				dist_units->param.units[dist_idx++].hdrs[0].hdr
427 					= HEADER_TYPE_IPV6;
428 				break;
429 
430 			case RTE_ETH_RSS_NONFRAG_IPV4_TCP:
431 			case RTE_ETH_RSS_NONFRAG_IPV6_TCP:
432 			case RTE_ETH_RSS_IPV6_TCP_EX:
433 
434 				if (tcp_configured)
435 					break;
436 				tcp_configured = 1;
437 				dist_units->param.units[dist_idx++].hdrs[0].hdr
438 					= HEADER_TYPE_TCP;
439 				break;
440 
441 			case RTE_ETH_RSS_NONFRAG_IPV4_UDP:
442 			case RTE_ETH_RSS_NONFRAG_IPV6_UDP:
443 			case RTE_ETH_RSS_IPV6_UDP_EX:
444 
445 				if (udp_configured)
446 					break;
447 				udp_configured = 1;
448 				dist_units->param.units[dist_idx++].hdrs[0].hdr
449 					= HEADER_TYPE_UDP;
450 				break;
451 
452 			case RTE_ETH_RSS_NONFRAG_IPV4_SCTP:
453 			case RTE_ETH_RSS_NONFRAG_IPV6_SCTP:
454 
455 				if (sctp_configured)
456 					break;
457 				sctp_configured = 1;
458 
459 				dist_units->param.units[dist_idx++].hdrs[0].hdr
460 					= HEADER_TYPE_SCTP;
461 				break;
462 
463 			default:
464 				DPAA_PMD_ERR("Bad flow distribution option");
465 			}
466 		}
467 		req_dist_set = req_dist_set >> 1;
468 		loop++;
469 	}
470 
471 	/* Dist units is set to dist_idx */
472 	dist_units->param.num_of_distinction_units = dist_idx;
473 }
474 
475 /* Apply PCD configuration on interface */
476 static inline int set_port_pcd(struct dpaa_if *dpaa_intf)
477 {
478 	int ret = 0;
479 	unsigned int idx;
480 	ioc_fm_port_pcd_params_t pcd_param;
481 	ioc_fm_port_pcd_prs_params_t prs_param;
482 	ioc_fm_port_pcd_kg_params_t  kg_param;
483 
484 	PMD_INIT_FUNC_TRACE();
485 
486 	/* PCD support for hash distribution */
487 	uint8_t pcd_support = e_FM_PORT_PCD_SUPPORT_PRS_AND_KG;
488 
489 	memset(&pcd_param, 0, sizeof(pcd_param));
490 	memset(&prs_param, 0, sizeof(prs_param));
491 	memset(&kg_param, 0, sizeof(kg_param));
492 
493 	/* Set parse params */
494 	prs_param.first_prs_hdr = HEADER_TYPE_ETH;
495 
496 	/* Set kg params */
497 	for (idx = 0; idx < dpaa_intf->scheme_count; idx++)
498 		kg_param.scheme_ids[idx] = dpaa_intf->scheme_handle[idx];
499 	kg_param.num_schemes = dpaa_intf->scheme_count;
500 
501 	/* Set pcd params */
502 	pcd_param.net_env_id = dpaa_intf->netenv_handle;
503 	pcd_param.pcd_support = pcd_support;
504 	pcd_param.p_kg_params = &kg_param;
505 	pcd_param.p_prs_params = &prs_param;
506 
507 	/* FM PORT Disable */
508 	ret = fm_port_disable(dpaa_intf->port_handle);
509 	if (ret != E_OK) {
510 		DPAA_PMD_ERR("fm_port_disable: Failed");
511 		return ret;
512 	}
513 
514 	/* FM PORT SetPCD */
515 	ret = fm_port_set_pcd(dpaa_intf->port_handle, &pcd_param);
516 	if (ret != E_OK) {
517 		DPAA_PMD_ERR("fm_port_set_pcd: Failed");
518 		return ret;
519 	}
520 
521 	/* FM PORT Enable */
522 	ret = fm_port_enable(dpaa_intf->port_handle);
523 	if (ret != E_OK) {
524 		DPAA_PMD_ERR("fm_port_enable: Failed");
525 		goto fm_port_delete_pcd;
526 	}
527 
528 	return 0;
529 
530 fm_port_delete_pcd:
531 	/* FM PORT DeletePCD */
532 	ret = fm_port_delete_pcd(dpaa_intf->port_handle);
533 	if (ret != E_OK) {
534 		DPAA_PMD_ERR("fm_port_delete_pcd: Failed\n");
535 		return ret;
536 	}
537 	return -1;
538 }
539 
540 /* Unset PCD NerEnv and scheme */
541 static inline void unset_pcd_netenv_scheme(struct dpaa_if *dpaa_intf)
542 {
543 	int ret;
544 	PMD_INIT_FUNC_TRACE();
545 
546 	/* reduce scheme count */
547 	if (dpaa_intf->scheme_count)
548 		dpaa_intf->scheme_count--;
549 
550 	DPAA_PMD_DEBUG("KG SCHEME DEL %d handle =%p",
551 		dpaa_intf->scheme_count,
552 		dpaa_intf->scheme_handle[dpaa_intf->scheme_count]);
553 
554 	ret = fm_pcd_kg_scheme_delete(dpaa_intf->scheme_handle
555 					[dpaa_intf->scheme_count]);
556 	if (ret != E_OK)
557 		DPAA_PMD_ERR("fm_pcd_kg_scheme_delete: Failed");
558 
559 	dpaa_intf->scheme_handle[dpaa_intf->scheme_count] = NULL;
560 }
561 
562 /* Set PCD NetEnv and Scheme and default scheme */
563 static inline int set_default_scheme(struct dpaa_if *dpaa_intf)
564 {
565 	ioc_fm_pcd_kg_scheme_params_t scheme_params;
566 	int idx = dpaa_intf->scheme_count;
567 	PMD_INIT_FUNC_TRACE();
568 
569 	/* Set PCD NetEnvCharacteristics */
570 	memset(&scheme_params, 0, sizeof(scheme_params));
571 
572 	/* Adding 10 to default schemes as the number of interface would be
573 	 * lesser than 10 and the relative scheme ids should be unique for
574 	 * every scheme.
575 	 */
576 	scheme_params.param.scm_id.relative_scheme_id =
577 		10 + dpaa_intf->ifid;
578 	scheme_params.param.use_hash = 0;
579 	scheme_params.param.next_engine = e_IOC_FM_PCD_DONE;
580 	scheme_params.param.net_env_params.num_of_distinction_units = 0;
581 	scheme_params.param.net_env_params.net_env_id =
582 		dpaa_intf->netenv_handle;
583 	scheme_params.param.base_fqid = dpaa_intf->rx_queues[0].fqid;
584 	scheme_params.param.key_ext_and_hash.hash_dist_num_of_fqids = 1;
585 	scheme_params.param.key_ext_and_hash.num_of_used_extracts = 0;
586 	scheme_params.param.modify = false;
587 	scheme_params.param.always_direct = false;
588 	scheme_params.param.scheme_counter.update = 1;
589 	scheme_params.param.scheme_counter.value = 0;
590 
591 	/* FM PCD KgSchemeSet */
592 	dpaa_intf->scheme_handle[idx] =
593 		fm_pcd_kg_scheme_set(fm_info.pcd_handle, &scheme_params);
594 	DPAA_PMD_DEBUG("KG SCHEME SET %d handle =%p",
595 		idx, dpaa_intf->scheme_handle[idx]);
596 	if (!dpaa_intf->scheme_handle[idx]) {
597 		DPAA_PMD_ERR("fm_pcd_kg_scheme_set: Failed");
598 		return -1;
599 	}
600 
601 	fm_model.scheme_devid[dpaa_intf->ifid][idx] =
602 				get_device_id(dpaa_intf->scheme_handle[idx]);
603 	dpaa_intf->scheme_count++;
604 	return 0;
605 }
606 
607 
608 /* Set PCD NetEnv and Scheme and default scheme */
609 static inline int set_pcd_netenv_scheme(struct dpaa_if *dpaa_intf,
610 					uint64_t req_dist_set,
611 					struct fman_if *fif)
612 {
613 	int ret = -1;
614 	ioc_fm_pcd_net_env_params_t dist_units;
615 	ioc_fm_pcd_kg_scheme_params_t scheme_params;
616 	int idx = dpaa_intf->scheme_count;
617 	PMD_INIT_FUNC_TRACE();
618 
619 	/* Set PCD NetEnvCharacteristics */
620 	memset(&dist_units, 0, sizeof(dist_units));
621 	memset(&scheme_params, 0, sizeof(scheme_params));
622 
623 	/* Set dist unit header type */
624 	set_dist_units(&dist_units, req_dist_set);
625 
626 	scheme_params.param.scm_id.relative_scheme_id = dpaa_intf->ifid;
627 
628 	/* Set PCD Scheme params */
629 	ret = set_scheme_params(&scheme_params, &dist_units, dpaa_intf, fif);
630 	if (ret) {
631 		DPAA_PMD_ERR("Set scheme params: Failed");
632 		return -1;
633 	}
634 
635 	/* FM PCD KgSchemeSet */
636 	dpaa_intf->scheme_handle[idx] =
637 		fm_pcd_kg_scheme_set(fm_info.pcd_handle, &scheme_params);
638 	DPAA_PMD_DEBUG("KG SCHEME SET %d handle =%p",
639 			idx, dpaa_intf->scheme_handle[idx]);
640 	if (!dpaa_intf->scheme_handle[idx]) {
641 		DPAA_PMD_ERR("fm_pcd_kg_scheme_set: Failed");
642 		return -1;
643 	}
644 
645 	fm_model.scheme_devid[dpaa_intf->ifid][idx] =
646 				get_device_id(dpaa_intf->scheme_handle[idx]);
647 	dpaa_intf->scheme_count++;
648 	return 0;
649 }
650 
651 
652 static inline int get_port_type(struct fman_if *fif)
653 {
654 	if (fif->mac_type == fman_mac_1g)
655 		return e_FM_PORT_TYPE_RX;
656 	else if (fif->mac_type == fman_mac_2_5g)
657 		return e_FM_PORT_TYPE_RX_2_5G;
658 	else if (fif->mac_type == fman_mac_10g)
659 		return e_FM_PORT_TYPE_RX_10G;
660 
661 	DPAA_PMD_ERR("MAC type unsupported");
662 	return -1;
663 }
664 
665 static inline int set_fm_port_handle(struct dpaa_if *dpaa_intf,
666 				     uint64_t req_dist_set,
667 				     struct fman_if *fif)
668 {
669 	t_fm_port_params	fm_port_params;
670 	ioc_fm_pcd_net_env_params_t dist_units;
671 	PMD_INIT_FUNC_TRACE();
672 
673 	/* FMAN mac indexes mappings (0 is unused,
674 	 * first 8 are for 1G, next for 10G ports
675 	 */
676 	uint8_t mac_idx[] = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1};
677 
678 	/* Memset FM port params */
679 	memset(&fm_port_params, 0, sizeof(fm_port_params));
680 
681 	/* Set FM port params */
682 	fm_port_params.h_fm = fm_info.fman_handle;
683 	fm_port_params.port_type = get_port_type(fif);
684 	fm_port_params.port_id = mac_idx[fif->mac_idx];
685 
686 	/* FM PORT Open */
687 	dpaa_intf->port_handle = fm_port_open(&fm_port_params);
688 	if (!dpaa_intf->port_handle) {
689 		DPAA_PMD_ERR("fm_port_open: Failed\n");
690 		return -1;
691 	}
692 
693 	fm_model.fm_port_params[dpaa_intf->ifid] = fm_port_params;
694 
695 	/* Set PCD NetEnvCharacteristics */
696 	memset(&dist_units, 0, sizeof(dist_units));
697 
698 	/* Set dist unit header type */
699 	set_dist_units(&dist_units, req_dist_set);
700 
701 	/* FM PCD NetEnvCharacteristicsSet */
702 	dpaa_intf->netenv_handle =
703 		fm_pcd_net_env_characteristics_set(fm_info.pcd_handle,
704 							&dist_units);
705 	if (!dpaa_intf->netenv_handle) {
706 		DPAA_PMD_ERR("fm_pcd_net_env_characteristics_set: Failed");
707 		return -1;
708 	}
709 
710 	fm_model.netenv_devid[dpaa_intf->ifid] =
711 				get_device_id(dpaa_intf->netenv_handle);
712 
713 	return 0;
714 }
715 
716 /* De-Configure DPAA FM */
717 int dpaa_fm_deconfig(struct dpaa_if *dpaa_intf,
718 			struct fman_if *fif __rte_unused)
719 {
720 	int ret;
721 	unsigned int idx;
722 
723 	PMD_INIT_FUNC_TRACE();
724 
725 	/* FM PORT Disable */
726 	ret = fm_port_disable(dpaa_intf->port_handle);
727 	if (ret != E_OK) {
728 		DPAA_PMD_ERR("fm_port_disable: Failed");
729 		return ret;
730 	}
731 
732 	/* FM PORT DeletePCD */
733 	ret = fm_port_delete_pcd(dpaa_intf->port_handle);
734 	if (ret != E_OK) {
735 		DPAA_PMD_ERR("fm_port_delete_pcd: Failed");
736 		return ret;
737 	}
738 
739 	for (idx = 0; idx < dpaa_intf->scheme_count; idx++) {
740 		DPAA_PMD_DEBUG("KG SCHEME DEL %d, handle =%p",
741 			idx, dpaa_intf->scheme_handle[idx]);
742 		/* FM PCD KgSchemeDelete */
743 		ret = fm_pcd_kg_scheme_delete(dpaa_intf->scheme_handle[idx]);
744 		if (ret != E_OK) {
745 			DPAA_PMD_ERR("fm_pcd_kg_scheme_delete: Failed");
746 			return ret;
747 		}
748 		dpaa_intf->scheme_handle[idx] = NULL;
749 	}
750 	/* FM PCD NetEnvCharacteristicsDelete */
751 	ret = fm_pcd_net_env_characteristics_delete(dpaa_intf->netenv_handle);
752 	if (ret != E_OK) {
753 		DPAA_PMD_ERR("fm_pcd_net_env_characteristics_delete: Failed");
754 		return ret;
755 	}
756 	dpaa_intf->netenv_handle = NULL;
757 
758 	if (fif && fif->is_shared_mac) {
759 		ret = fm_port_enable(dpaa_intf->port_handle);
760 		if (ret != E_OK) {
761 			DPAA_PMD_ERR("shared mac re-enable failed");
762 			return ret;
763 		}
764 	}
765 
766 	/* FM PORT Close */
767 	fm_port_close(dpaa_intf->port_handle);
768 	dpaa_intf->port_handle = NULL;
769 
770 	/* Set scheme count to 0 */
771 	dpaa_intf->scheme_count = 0;
772 
773 	return 0;
774 }
775 
776 int dpaa_fm_config(struct rte_eth_dev *dev, uint64_t req_dist_set)
777 {
778 	struct dpaa_if *dpaa_intf = dev->data->dev_private;
779 	struct fman_if *fif = dev->process_private;
780 	int ret;
781 	unsigned int i = 0;
782 	PMD_INIT_FUNC_TRACE();
783 
784 	if (dpaa_intf->port_handle) {
785 		if (dpaa_fm_deconfig(dpaa_intf, fif))
786 			DPAA_PMD_ERR("DPAA FM deconfig failed");
787 	}
788 
789 	if (!dev->data->nb_rx_queues)
790 		return 0;
791 
792 	if (dev->data->nb_rx_queues & (dev->data->nb_rx_queues - 1)) {
793 		DPAA_PMD_ERR("No of queues should be power of 2");
794 		return -1;
795 	}
796 
797 	dpaa_intf->nb_rx_queues = dev->data->nb_rx_queues;
798 
799 	/* Open FM Port and set it in port info */
800 	ret = set_fm_port_handle(dpaa_intf, req_dist_set, fif);
801 	if (ret) {
802 		DPAA_PMD_ERR("Set FM Port handle: Failed");
803 		return -1;
804 	}
805 
806 	if (fif->num_profiles) {
807 		for (i = 0; i < dpaa_intf->nb_rx_queues; i++)
808 			dpaa_intf->rx_queues[i].vsp_id =
809 				fm_default_vsp_id(fif);
810 
811 		i = 0;
812 	}
813 
814 	/* Set PCD netenv and scheme */
815 	if (req_dist_set) {
816 		ret = set_pcd_netenv_scheme(dpaa_intf, req_dist_set, fif);
817 		if (ret) {
818 			DPAA_PMD_ERR("Set PCD NetEnv and Scheme dist: Failed");
819 			goto unset_fm_port_handle;
820 		}
821 	}
822 	/* Set default netenv and scheme */
823 	if (!fif->is_shared_mac) {
824 		ret = set_default_scheme(dpaa_intf);
825 		if (ret) {
826 			DPAA_PMD_ERR("Set PCD NetEnv and Scheme: Failed");
827 			goto unset_pcd_netenv_scheme1;
828 		}
829 	}
830 
831 	/* Set Port PCD */
832 	ret = set_port_pcd(dpaa_intf);
833 	if (ret) {
834 		DPAA_PMD_ERR("Set Port PCD: Failed");
835 		goto unset_pcd_netenv_scheme;
836 	}
837 
838 	for (; i < fm_model.dev_count; i++)
839 		if (fm_model.device_order[i] == dpaa_intf->ifid)
840 			return 0;
841 
842 	fm_model.device_order[fm_model.dev_count] = dpaa_intf->ifid;
843 	fm_model.dev_count++;
844 
845 	return 0;
846 
847 unset_pcd_netenv_scheme:
848 	unset_pcd_netenv_scheme(dpaa_intf);
849 
850 unset_pcd_netenv_scheme1:
851 	unset_pcd_netenv_scheme(dpaa_intf);
852 
853 unset_fm_port_handle:
854 	/* FM PORT Close */
855 	fm_port_close(dpaa_intf->port_handle);
856 	dpaa_intf->port_handle = NULL;
857 	return -1;
858 }
859 
860 int dpaa_fm_init(void)
861 {
862 	t_handle fman_handle;
863 	t_handle pcd_handle;
864 	t_fm_pcd_params fm_pcd_params = {0};
865 	/* Hard-coded : fman id 0 since one fman is present in LS104x */
866 	int fman_id = 0, ret;
867 	PMD_INIT_FUNC_TRACE();
868 
869 	dpaa_read_fm_config_from_file();
870 
871 	/* FM Open */
872 	fman_handle = fm_open(fman_id);
873 	if (!fman_handle) {
874 		DPAA_PMD_ERR("fm_open: Failed");
875 		return -1;
876 	}
877 
878 	/* FM PCD Open */
879 	fm_pcd_params.h_fm = fman_handle;
880 	fm_pcd_params.prs_support = true;
881 	fm_pcd_params.kg_support = true;
882 	pcd_handle = fm_pcd_open(&fm_pcd_params);
883 	if (!pcd_handle) {
884 		fm_close(fman_handle);
885 		DPAA_PMD_ERR("fm_pcd_open: Failed");
886 		return -1;
887 	}
888 
889 	/* FM PCD Enable */
890 	ret = fm_pcd_enable(pcd_handle);
891 	if (ret) {
892 		fm_close(fman_handle);
893 		fm_pcd_close(pcd_handle);
894 		DPAA_PMD_ERR("fm_pcd_enable: Failed");
895 		return -1;
896 	}
897 
898 	/* Set fman and pcd handle in fm info */
899 	fm_info.fman_handle = fman_handle;
900 	fm_info.pcd_handle = pcd_handle;
901 
902 	return 0;
903 }
904 
905 
906 /* De-initialization of FM */
907 int dpaa_fm_term(void)
908 {
909 	int ret;
910 
911 	PMD_INIT_FUNC_TRACE();
912 
913 	if (fm_info.pcd_handle && fm_info.fman_handle) {
914 		/* FM PCD Disable */
915 		ret = fm_pcd_disable(fm_info.pcd_handle);
916 		if (ret) {
917 			DPAA_PMD_ERR("fm_pcd_disable: Failed");
918 			return -1;
919 		}
920 
921 		/* FM PCD Close */
922 		fm_pcd_close(fm_info.pcd_handle);
923 		fm_info.pcd_handle = NULL;
924 	}
925 
926 	if (fm_info.fman_handle) {
927 		/* FM Close */
928 		fm_close(fm_info.fman_handle);
929 		fm_info.fman_handle = NULL;
930 	}
931 
932 	if (access(fm_log, F_OK) != -1) {
933 		ret = remove(fm_log);
934 		if (ret)
935 			DPAA_PMD_ERR("File remove: Failed");
936 	}
937 	return 0;
938 }
939 
940 static int dpaa_port_vsp_configure(struct dpaa_if *dpaa_intf,
941 		uint8_t vsp_id, t_handle fman_handle,
942 		struct fman_if *fif)
943 {
944 	t_fm_vsp_params vsp_params;
945 	t_fm_buffer_prefix_content buf_prefix_cont;
946 	uint8_t mac_idx[] = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1};
947 	uint8_t idx = mac_idx[fif->mac_idx];
948 	int ret;
949 
950 	if (vsp_id == fif->base_profile_id && fif->is_shared_mac) {
951 		/* For shared interface, VSP of base
952 		 * profile is default pool located in kernel.
953 		 */
954 		dpaa_intf->vsp_bpid[vsp_id] = 0;
955 		return 0;
956 	}
957 
958 	if (vsp_id >= DPAA_VSP_PROFILE_MAX_NUM) {
959 		DPAA_PMD_ERR("VSP ID %d exceeds MAX number %d",
960 			vsp_id, DPAA_VSP_PROFILE_MAX_NUM);
961 		return -1;
962 	}
963 
964 	memset(&vsp_params, 0, sizeof(vsp_params));
965 	vsp_params.h_fm = fman_handle;
966 	vsp_params.relative_profile_id = vsp_id;
967 	vsp_params.port_params.port_id = idx;
968 	if (fif->mac_type == fman_mac_1g) {
969 		vsp_params.port_params.port_type = e_FM_PORT_TYPE_RX;
970 	} else if (fif->mac_type == fman_mac_2_5g) {
971 		vsp_params.port_params.port_type = e_FM_PORT_TYPE_RX_2_5G;
972 	} else if (fif->mac_type == fman_mac_10g) {
973 		vsp_params.port_params.port_type = e_FM_PORT_TYPE_RX_10G;
974 	} else {
975 		DPAA_PMD_ERR("Mac type %d error", fif->mac_type);
976 		return -1;
977 	}
978 	vsp_params.ext_buf_pools.num_of_pools_used = 1;
979 	vsp_params.ext_buf_pools.ext_buf_pool[0].id =
980 		dpaa_intf->vsp_bpid[vsp_id];
981 	vsp_params.ext_buf_pools.ext_buf_pool[0].size =
982 		RTE_MBUF_DEFAULT_BUF_SIZE;
983 
984 	dpaa_intf->vsp_handle[vsp_id] = fm_vsp_config(&vsp_params);
985 	if (!dpaa_intf->vsp_handle[vsp_id]) {
986 		DPAA_PMD_ERR("fm_vsp_config error for profile %d", vsp_id);
987 		return -EINVAL;
988 	}
989 
990 	/* configure the application buffer (structure, size and
991 	 * content)
992 	 */
993 
994 	memset(&buf_prefix_cont, 0, sizeof(buf_prefix_cont));
995 
996 	buf_prefix_cont.priv_data_size = 16;
997 	buf_prefix_cont.data_align = 64;
998 	buf_prefix_cont.pass_prs_result = true;
999 	buf_prefix_cont.pass_time_stamp = true;
1000 	buf_prefix_cont.pass_hash_result = false;
1001 	buf_prefix_cont.pass_all_other_pcdinfo = false;
1002 	buf_prefix_cont.manip_ext_space =
1003 		RTE_PKTMBUF_HEADROOM - DPAA_MBUF_HW_ANNOTATION;
1004 
1005 	ret = fm_vsp_config_buffer_prefix_content(dpaa_intf->vsp_handle[vsp_id],
1006 					       &buf_prefix_cont);
1007 	if (ret != E_OK) {
1008 		DPAA_PMD_ERR("fm_vsp_config_buffer_prefix_content error for profile %d err: %d",
1009 			     vsp_id, ret);
1010 		return ret;
1011 	}
1012 
1013 	/* initialize the FM VSP module */
1014 	ret = fm_vsp_init(dpaa_intf->vsp_handle[vsp_id]);
1015 	if (ret != E_OK) {
1016 		DPAA_PMD_ERR("fm_vsp_init error for profile %d err:%d",
1017 			 vsp_id, ret);
1018 		return ret;
1019 	}
1020 
1021 	return 0;
1022 }
1023 
1024 int dpaa_port_vsp_update(struct dpaa_if *dpaa_intf,
1025 		bool fmc_mode, uint8_t vsp_id, uint32_t bpid,
1026 		struct fman_if *fif)
1027 {
1028 	int ret = 0;
1029 	t_handle fman_handle;
1030 
1031 	if (!fif->num_profiles)
1032 		return 0;
1033 
1034 	if (vsp_id >= fif->num_profiles)
1035 		return 0;
1036 
1037 	if (dpaa_intf->vsp_bpid[vsp_id] == bpid)
1038 		return 0;
1039 
1040 	if (dpaa_intf->vsp_handle[vsp_id]) {
1041 		ret = fm_vsp_free(dpaa_intf->vsp_handle[vsp_id]);
1042 		if (ret != E_OK) {
1043 			DPAA_PMD_ERR("Error fm_vsp_free: err %d vsp_handle[%d]",
1044 				     ret, vsp_id);
1045 			return ret;
1046 		}
1047 		dpaa_intf->vsp_handle[vsp_id] = 0;
1048 	}
1049 
1050 	if (fmc_mode)
1051 		fman_handle = fm_open(0);
1052 	else
1053 		fman_handle = fm_info.fman_handle;
1054 
1055 	dpaa_intf->vsp_bpid[vsp_id] = bpid;
1056 
1057 	return dpaa_port_vsp_configure(dpaa_intf, vsp_id, fman_handle, fif);
1058 }
1059 
1060 int dpaa_port_vsp_cleanup(struct dpaa_if *dpaa_intf, struct fman_if *fif)
1061 {
1062 	int idx, ret;
1063 
1064 	for (idx = 0; idx < (uint8_t)fif->num_profiles; idx++) {
1065 		if (dpaa_intf->vsp_handle[idx]) {
1066 			ret = fm_vsp_free(dpaa_intf->vsp_handle[idx]);
1067 			if (ret != E_OK) {
1068 				DPAA_PMD_ERR("Error fm_vsp_free: err %d"
1069 					     " vsp_handle[%d]", ret, idx);
1070 				return ret;
1071 			}
1072 		}
1073 	}
1074 
1075 	return E_OK;
1076 }
1077