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