[21/37] net/dpaa: add fmc parser support for VSP
diff mbox series

Message ID 20200527132326.1382-22-hemant.agrawal@nxp.com
State Changes Requested, archived
Delegated to: Ferruh Yigit
Headers show
Series
  • NXP DPAAx enhancements
Related show

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/checkpatch warning coding style issues

Commit Message

Hemant Agrawal May 27, 2020, 1:23 p.m. UTC
From: Jun Yang <jun.yang@nxp.com>

Parse the fmc.bin generated by fmc to setup
RXQs for each port on fmc mode.
The parser gets the fqids and vspids from fmc.bin.

Signed-off-by: Jun Yang <jun.yang@nxp.com>
---
 drivers/net/dpaa/Makefile      |   1 +
 drivers/net/dpaa/dpaa_ethdev.c |  26 +-
 drivers/net/dpaa/dpaa_ethdev.h |  10 +-
 drivers/net/dpaa/dpaa_fmc.c    | 488 +++++++++++++++++++++++++++++++++
 drivers/net/dpaa/meson.build   |   3 +-
 5 files changed, 521 insertions(+), 7 deletions(-)
 create mode 100644 drivers/net/dpaa/dpaa_fmc.c

Patch
diff mbox series

diff --git a/drivers/net/dpaa/Makefile b/drivers/net/dpaa/Makefile
index d334b82a0..f4a1c0ec5 100644
--- a/drivers/net/dpaa/Makefile
+++ b/drivers/net/dpaa/Makefile
@@ -32,6 +32,7 @@  SRCS-$(CONFIG_RTE_LIBRTE_DPAA_PMD) += fmlib/fm_vsp.c
 SRCS-$(CONFIG_RTE_LIBRTE_DPAA_PMD) += dpaa_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_DPAA_PMD) += dpaa_flow.c
 SRCS-$(CONFIG_RTE_LIBRTE_DPAA_PMD) += dpaa_rxtx.c
+SRCS-$(CONFIG_RTE_LIBRTE_DPAA_PMD) += dpaa_fmc.c
 
 LDLIBS += -lrte_bus_dpaa
 LDLIBS += -lrte_mempool_dpaa
diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c
index 9cb3d213c..a508b10c3 100644
--- a/drivers/net/dpaa/dpaa_ethdev.c
+++ b/drivers/net/dpaa/dpaa_ethdev.c
@@ -261,6 +261,16 @@  dpaa_eth_dev_configure(struct rte_eth_dev *dev)
 		dev->data->scattered_rx = 1;
 	}
 
+	if (!(default_q || fmc_q)) {
+		if (dpaa_fm_config(dev,
+			eth_conf->rx_adv_conf.rss_conf.rss_hf)) {
+			dpaa_write_fm_config_to_file();
+			DPAA_PMD_ERR("FM port configuration: Failed\n");
+			return -1;
+		}
+		dpaa_write_fm_config_to_file();
+	}
+
 	/* if the interrupts were configured on this devices*/
 	if (intr_handle && intr_handle->fd) {
 		if (dev->data->dev_conf.intr_conf.lsc != 0)
@@ -336,6 +346,9 @@  static int dpaa_eth_dev_start(struct rte_eth_dev *dev)
 
 	PMD_INIT_FUNC_TRACE();
 
+	if (!(default_q || fmc_q))
+		dpaa_write_fm_config_to_file();
+
 	/* Change tx callback to the real one */
 	if (dpaa_intf->cgr_tx)
 		dev->tx_pkt_burst = dpaa_eth_queue_tx_slow;
@@ -1577,7 +1590,18 @@  dpaa_dev_init(struct rte_eth_dev *eth_dev)
 	if (default_q) {
 		num_rx_fqs = DPAA_DEFAULT_NUM_PCD_QUEUES;
 	} else if (fmc_q) {
-		num_rx_fqs = 1;
+		num_rx_fqs = dpaa_port_fmc_init(fman_intf, dev_rx_fqids,
+						dev_vspids,
+						DPAA_MAX_NUM_PCD_QUEUES);
+		if (num_rx_fqs < 0) {
+			DPAA_PMD_ERR("%s FMC initializes failed!",
+				dpaa_intf->name);
+			goto free_rx;
+		}
+		if (!num_rx_fqs) {
+			DPAA_PMD_WARN("%s is not configured by FMC.",
+				dpaa_intf->name);
+		}
 	} else {
 		/* FMCLESS mode, load balance to multiple cores.*/
 		num_rx_fqs = rte_lcore_count();
diff --git a/drivers/net/dpaa/dpaa_ethdev.h b/drivers/net/dpaa/dpaa_ethdev.h
index dd182c4d5..1b8e120e8 100644
--- a/drivers/net/dpaa/dpaa_ethdev.h
+++ b/drivers/net/dpaa/dpaa_ethdev.h
@@ -59,10 +59,10 @@ 
 #endif
 
 /* PCD frame queues */
-#define DPAA_PCD_FQID_START		0x400
-#define DPAA_PCD_FQID_MULTIPLIER	0x100
 #define DPAA_DEFAULT_NUM_PCD_QUEUES	1
-#define DPAA_MAX_NUM_PCD_QUEUES		4
+#define DPAA_VSP_PROFILE_MAX_NUM	8
+#define DPAA_MAX_NUM_PCD_QUEUES	DPAA_VSP_PROFILE_MAX_NUM
+/*Same as VSP profile number*/
 
 #define DPAA_IF_TX_PRIORITY		3
 #define DPAA_IF_RX_PRIORITY		0
@@ -103,10 +103,10 @@ 
 #define DPAA_FD_CMD_CFQ			0x00ffffff
 /**< Confirmation Frame Queue */
 
-#define DPAA_VSP_PROFILE_MAX_NUM	8
-
 #define DPAA_DEFAULT_RXQ_VSP_ID		1
 
+#define FMC_FILE "/tmp/fmc.bin"
+
 /* Each network interface is represented by one of these */
 struct dpaa_if {
 	int valid;
diff --git a/drivers/net/dpaa/dpaa_fmc.c b/drivers/net/dpaa/dpaa_fmc.c
new file mode 100644
index 000000000..b3b9a7e43
--- /dev/null
+++ b/drivers/net/dpaa/dpaa_fmc.c
@@ -0,0 +1,488 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2017-2020 NXP
+ */
+
+/* System headers */
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <dpaa_ethdev.h>
+#include <dpaa_flow.h>
+#include <rte_dpaa_logs.h>
+#include <fmlib/fm_port_ext.h>
+#include <fmlib/fm_vsp_ext.h>
+
+#define FMC_OUTPUT_FORMAT_VER 0x106
+
+#define FMC_NAME_LEN             64
+#define FMC_FMAN_NUM              2
+#define FMC_PORTS_PER_FMAN       16
+#define FMC_SCHEMES_NUM          32
+#define FMC_SCHEME_PROTOCOLS_NUM 16
+#define FMC_CC_NODES_NUM        512
+#define FMC_REPLICATORS_NUM      16
+#define FMC_PLC_NUM              64
+#define MAX_SP_CODE_SIZE      0x7C0
+#define FMC_MANIP_MAX            64
+#define FMC_HMANIP_MAX          512
+#define FMC_INSERT_MAX           56
+#define FM_PCD_MAX_NUM_OF_REPS   64
+
+typedef struct fmc_port_t {
+	e_FmPortType type;
+	unsigned int number;
+	struct fm_pcd_net_env_params_t distinctionUnits;
+	struct ioc_fm_port_pcd_params_t pcdParam;
+	struct ioc_fm_port_pcd_prs_params_t prsParam;
+	struct ioc_fm_port_pcd_kg_params_t kgParam;
+	struct ioc_fm_port_pcd_cc_params_t ccParam;
+	char name[FMC_NAME_LEN];
+	char cctree_name[FMC_NAME_LEN];
+	t_Handle handle;
+	t_Handle env_id_handle;
+	t_Handle env_id_devId;
+	t_Handle cctree_handle;
+	t_Handle cctree_devId;
+
+	unsigned int schemes_count;
+	unsigned int schemes[FMC_SCHEMES_NUM];
+	unsigned int ccnodes_count;
+	unsigned int ccnodes[FMC_CC_NODES_NUM];
+	unsigned int htnodes_count;
+	unsigned int htnodes[FMC_CC_NODES_NUM];
+
+	unsigned int replicators_count;
+	unsigned int replicators[FMC_REPLICATORS_NUM];
+	ioc_fm_port_vsp_alloc_params_t vspParam;
+
+	unsigned int ccroot_count;
+	unsigned int ccroot[FMC_CC_NODES_NUM];
+	enum ioc_fm_pcd_engine ccroot_type[FMC_CC_NODES_NUM];
+	unsigned int ccroot_manip[FMC_CC_NODES_NUM];
+
+	unsigned int reasm_index;
+} fmc_port;
+
+typedef struct fmc_fman_t {
+	unsigned int number;
+	unsigned int port_count;
+	unsigned int ports[FMC_PORTS_PER_FMAN];
+	char name[FMC_NAME_LEN];
+	t_Handle handle;
+	char pcd_name[FMC_NAME_LEN];
+	t_Handle pcd_handle;
+	unsigned int kg_payload_offset;
+
+	unsigned int offload_support;
+
+	unsigned int reasm_count;
+	struct fm_pcd_manip_params_t reasm[FMC_MANIP_MAX];
+	char reasm_name[FMC_MANIP_MAX][FMC_NAME_LEN];
+	t_Handle reasm_handle[FMC_MANIP_MAX];
+	t_Handle reasm_devId[FMC_MANIP_MAX];
+
+	unsigned int frag_count;
+	struct fm_pcd_manip_params_t frag[FMC_MANIP_MAX];
+	char frag_name[FMC_MANIP_MAX][FMC_NAME_LEN];
+	t_Handle frag_handle[FMC_MANIP_MAX];
+	t_Handle frag_devId[FMC_MANIP_MAX];
+
+	unsigned int hdr_count;
+	struct fm_pcd_manip_params_t hdr[FMC_HMANIP_MAX];
+	uint8_t insertData[FMC_HMANIP_MAX][FMC_INSERT_MAX];
+	char hdr_name[FMC_HMANIP_MAX][FMC_NAME_LEN];
+	t_Handle hdr_handle[FMC_HMANIP_MAX];
+	t_Handle hdr_devId[FMC_HMANIP_MAX];
+	unsigned int hdr_hasNext[FMC_HMANIP_MAX];
+	unsigned int hdr_next[FMC_HMANIP_MAX];
+} fmc_fman;
+
+typedef enum fmc_apply_order_e {
+	FMCEngineStart,
+	FMCEngineEnd,
+	FMCPortStart,
+	FMCPortEnd,
+	FMCScheme,
+	FMCCCNode,
+	FMCHTNode,
+	FMCCCTree,
+	FMCPolicer,
+	FMCReplicator,
+	FMCManipulation
+} fmc_apply_order_e;
+
+typedef struct fmc_apply_order_t {
+	fmc_apply_order_e type;
+	unsigned int index;
+} fmc_apply_order;
+
+struct fmc_model_t {
+	unsigned int format_version;
+	unsigned int sp_enable;
+	t_FmPcdPrsSwParams sp;
+	uint8_t spcode[MAX_SP_CODE_SIZE];
+
+	unsigned int fman_count;
+	fmc_fman fman[FMC_FMAN_NUM];
+
+	unsigned int port_count;
+	fmc_port port[FMC_FMAN_NUM * FMC_PORTS_PER_FMAN];
+
+	unsigned int scheme_count;
+	char scheme_name[FMC_SCHEMES_NUM][FMC_NAME_LEN];
+	t_Handle scheme_handle[FMC_SCHEMES_NUM];
+	t_Handle scheme_devId[FMC_SCHEMES_NUM];
+	struct fm_pcd_kg_scheme_params_t scheme[FMC_SCHEMES_NUM];
+
+	unsigned int ccnode_count;
+	char ccnode_name[FMC_CC_NODES_NUM][FMC_NAME_LEN];
+	t_Handle ccnode_handle[FMC_CC_NODES_NUM];
+	t_Handle ccnode_devId[FMC_CC_NODES_NUM];
+	struct fm_pcd_cc_node_params_t ccnode[FMC_CC_NODES_NUM];
+	uint8_t cckeydata[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]
+					[FM_PCD_MAX_SIZE_OF_KEY];
+	unsigned char ccmask[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]
+						[FM_PCD_MAX_SIZE_OF_KEY];
+	unsigned int
+		ccentry_action_index[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
+	enum ioc_fm_pcd_engine
+		ccentry_action_type[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
+	unsigned char ccentry_frag[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
+	unsigned int ccentry_manip[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
+	unsigned int ccmiss_action_index[FMC_CC_NODES_NUM];
+	enum ioc_fm_pcd_engine ccmiss_action_type[FMC_CC_NODES_NUM];
+	unsigned char ccmiss_frag[FMC_CC_NODES_NUM];
+	unsigned int ccmiss_manip[FMC_CC_NODES_NUM];
+
+	unsigned int htnode_count;
+	char htnode_name[FMC_CC_NODES_NUM][FMC_NAME_LEN];
+	t_Handle htnode_handle[FMC_CC_NODES_NUM];
+	t_Handle htnode_devId[FMC_CC_NODES_NUM];
+	struct fm_pcd_hash_table_params_t htnode[FMC_CC_NODES_NUM];
+
+	unsigned int htentry_count[FMC_CC_NODES_NUM];
+	struct ioc_fm_pcd_cc_key_params_t
+		htentry[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
+	uint8_t htkeydata[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS]
+					[FM_PCD_MAX_SIZE_OF_KEY];
+	unsigned int
+		htentry_action_index[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
+	enum ioc_fm_pcd_engine
+		htentry_action_type[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
+	unsigned char htentry_frag[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
+	unsigned int htentry_manip[FMC_CC_NODES_NUM][FM_PCD_MAX_NUM_OF_KEYS];
+
+	unsigned int htmiss_action_index[FMC_CC_NODES_NUM];
+	enum ioc_fm_pcd_engine htmiss_action_type[FMC_CC_NODES_NUM];
+	unsigned char htmiss_frag[FMC_CC_NODES_NUM];
+	unsigned int htmiss_manip[FMC_CC_NODES_NUM];
+
+	unsigned int replicator_count;
+	char replicator_name[FMC_REPLICATORS_NUM][FMC_NAME_LEN];
+	t_Handle replicator_handle[FMC_REPLICATORS_NUM];
+	t_Handle replicator_devId[FMC_REPLICATORS_NUM];
+	struct fm_pcd_frm_replic_group_params_t replicator[FMC_REPLICATORS_NUM];
+	unsigned int
+	 repentry_action_index[FMC_REPLICATORS_NUM][FM_PCD_MAX_NUM_OF_REPS];
+	unsigned char repentry_frag[FMC_REPLICATORS_NUM][FM_PCD_MAX_NUM_OF_REPS];
+	unsigned int repentry_manip[FMC_REPLICATORS_NUM][FM_PCD_MAX_NUM_OF_REPS];
+
+	unsigned int policer_count;
+	char policer_name[FMC_PLC_NUM][FMC_NAME_LEN];
+	struct fm_pcd_plcr_profile_params_t policer[FMC_PLC_NUM];
+	t_Handle policer_handle[FMC_PLC_NUM];
+	t_Handle policer_devId[FMC_PLC_NUM];
+	unsigned int policer_action_index[FMC_PLC_NUM][3];
+
+	unsigned int apply_order_count;
+	fmc_apply_order apply_order[FMC_FMAN_NUM *
+		FMC_PORTS_PER_FMAN *
+		(FMC_SCHEMES_NUM + FMC_CC_NODES_NUM)];
+};
+
+struct fmc_model_t *g_fmc_model;
+
+static int dpaa_port_fmc_port_parse(
+	struct fman_if *fif,
+	const struct fmc_model_t *fmc_model,
+	int apply_idx)
+{
+	int current_port = fmc_model->apply_order[apply_idx].index;
+	const fmc_port *pport = &fmc_model->port[current_port];
+	const uint8_t mac_idx[] = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1};
+	const uint8_t mac_type[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
+
+	if (mac_idx[fif->mac_idx] != pport->number ||
+		mac_type[fif->mac_idx] != pport->type)
+		return -1;
+
+	return current_port;
+}
+
+static int dpaa_port_fmc_scheme_parse(
+	struct fman_if *fif,
+	const struct fmc_model_t *fmc_model,
+	int apply_idx,
+	uint16_t *rxq_idx, int max_nb_rxq,
+	uint32_t *fqids, int8_t *vspids)
+{
+	int scheme_idx = fmc_model->apply_order[apply_idx].index;
+	uint32_t i;
+
+	if (!fmc_model->scheme[scheme_idx].override_storage_profile &&
+		fif->is_shared_mac) {
+		DPAA_PMD_WARN("No VSP is assigned to sheme %d for sharemac %d!",
+			scheme_idx, fif->mac_idx);
+		DPAA_PMD_WARN("Risk to receive pkts from skb pool to CRASH!");
+	}
+
+	if (e_IOC_FM_PCD_DONE ==
+		fmc_model->scheme[scheme_idx].next_engine) {
+		for (i = 0; i < fmc_model->scheme[scheme_idx]
+			.key_extract_and_hash_params.hash_distribution_num_of_fqids; i++) {
+			uint32_t fqid = fmc_model->scheme[scheme_idx].base_fqid + i;
+			int k, found = 0;
+
+			if (fqid == fif->fqid_rx_def) {
+				if (fif->is_shared_mac &&
+				fmc_model->scheme[scheme_idx].override_storage_profile &&
+				fmc_model->scheme[scheme_idx].storage_profile.direct &&
+				fmc_model->scheme[scheme_idx].storage_profile
+				.profile_select.direct_relative_profileId !=
+				fif->base_profile_id) {
+					DPAA_PMD_ERR(
+					"Default RXQ must be associated"
+					" with default VSP on sharemac!");
+
+					return -1;
+				}
+				continue;
+			}
+
+			if (fif->is_shared_mac &&
+			!fmc_model->scheme[scheme_idx].override_storage_profile) {
+				DPAA_PMD_ERR(
+					"RXQ to DPDK must be associated"
+					" with VSP on sharemac!");
+				return -1;
+			}
+
+			if (fif->is_shared_mac &&
+			fmc_model->scheme[scheme_idx].override_storage_profile &&
+			fmc_model->scheme[scheme_idx].storage_profile.direct &&
+			fmc_model->scheme[scheme_idx].storage_profile
+			.profile_select.direct_relative_profileId ==
+			fif->base_profile_id) {
+				DPAA_PMD_ERR(
+					"RXQ can't be associated"
+					" with default VSP on sharemac!");
+
+				return -1;
+			}
+
+			if ((*rxq_idx) >= max_nb_rxq) {
+				DPAA_PMD_DEBUG(
+					"Too many queues in FMC policy"
+					"%d overflow %d",
+					(*rxq_idx), max_nb_rxq);
+
+				continue;
+			}
+
+			for (k = 0; k < (*rxq_idx); k++) {
+				if (fqids[k] == fqid) {
+					found = 1;
+					break;
+				}
+			}
+
+			if (found)
+				continue;
+			fqids[(*rxq_idx)] = fqid;
+			if (fmc_model->scheme[scheme_idx].override_storage_profile) {
+				if (fmc_model->scheme[scheme_idx].storage_profile.direct) {
+					vspids[(*rxq_idx)] =
+						fmc_model->scheme[scheme_idx].storage_profile
+							.profile_select.direct_relative_profileId;
+				} else {
+					vspids[(*rxq_idx)] = -1;
+				}
+			} else {
+				vspids[(*rxq_idx)] = -1;
+			}
+			(*rxq_idx)++;
+		}
+	}
+
+	return 0;
+}
+
+static int dpaa_port_fmc_ccnode_parse(
+	struct fman_if *fif,
+	const struct fmc_model_t *fmc_model,
+	int apply_idx,
+	uint16_t *rxq_idx, int max_nb_rxq,
+	uint32_t *fqids, int8_t *vspids)
+{
+	uint16_t j, k, found = 0;
+	const struct ioc_keys_params_t *keys_params;
+	uint32_t fqid, cc_idx = fmc_model->apply_order[apply_idx].index;
+
+	keys_params = &fmc_model->ccnode[cc_idx].keys_params;
+
+	if ((*rxq_idx) >= max_nb_rxq) {
+		DPAA_PMD_WARN(
+			"Too many queues in FMC policy"
+			"%d overflow %d",
+			(*rxq_idx), max_nb_rxq);
+
+		return 0;
+	}
+
+	for (j = 0; j < keys_params->num_of_keys; ++j) {
+		found = 0;
+		fqid = keys_params->key_params[j].cc_next_engine_params
+			.params.enqueue_params.new_fqid;
+
+		if (keys_params->key_params[j].cc_next_engine_params
+			.next_engine != e_IOC_FM_PCD_DONE) {
+			DPAA_PMD_WARN("FMC CC next engine not support");
+			continue;
+		}
+		if (keys_params->key_params[j].cc_next_engine_params
+			.params.enqueue_params.action !=
+			e_IOC_FM_PCD_ENQ_FRAME)
+			continue;
+		for (k = 0; k < (*rxq_idx); k++) {
+			if (fqids[k] == fqid) {
+				found = 1;
+				break;
+			}
+		}
+		if (found)
+			continue;
+
+		if ((*rxq_idx) >= max_nb_rxq) {
+			DPAA_PMD_WARN(
+				"Too many queues in FMC policy"
+				"%d overflow %d",
+				(*rxq_idx), max_nb_rxq);
+
+			return 0;
+		}
+
+		fqids[(*rxq_idx)] = fqid;
+		vspids[(*rxq_idx)] =
+			keys_params->key_params[j].cc_next_engine_params
+				.params.enqueue_params
+				.new_relative_storage_profile_id;
+
+		if (vspids[(*rxq_idx)] == fif->base_profile_id &&
+		    fif->is_shared_mac) {
+			DPAA_PMD_ERR(
+				"VSP %d can NOT be used on DPDK.",
+				vspids[(*rxq_idx)]);
+			DPAA_PMD_ERR(
+			"It is associated to skb pool of shared interface.");
+
+				return -1;
+		}
+		(*rxq_idx)++;
+	}
+
+	return 0;
+}
+
+int dpaa_port_fmc_init(struct fman_if *fif,
+		       uint32_t *fqids, int8_t *vspids, int max_nb_rxq)
+{
+	int current_port = -1, ret;
+	uint16_t rxq_idx = 0;
+	const struct fmc_model_t *fmc_model;
+	uint32_t i;
+
+	if (!g_fmc_model) {
+		size_t bytes_read;
+		FILE *fp = fopen(FMC_FILE, "rb");
+
+		if (!fp) {
+			DPAA_PMD_ERR("%s not exists", FMC_FILE);
+			return -1;
+		}
+
+		g_fmc_model = rte_malloc(NULL, sizeof(struct fmc_model_t), 64);
+		if (!g_fmc_model) {
+			DPAA_PMD_ERR("FMC memory alloc failed");
+			fclose(fp);
+			return -1;
+		}
+
+		bytes_read = fread(g_fmc_model,
+					sizeof(struct fmc_model_t), 1, fp);
+		if (!bytes_read) {
+			DPAA_PMD_ERR("No bytes read");
+			fclose(fp);
+			rte_free(g_fmc_model);
+			g_fmc_model = NULL;
+			return -1;
+		}
+		fclose(fp);
+	}
+
+	fmc_model = g_fmc_model;
+
+	if (fmc_model->format_version != FMC_OUTPUT_FORMAT_VER)
+		return -1;
+
+	for (i = 0; i < fmc_model->apply_order_count; i++) {
+		switch (fmc_model->apply_order[i].type) {
+		case FMCEngineStart:
+			break;
+		case FMCEngineEnd:
+			break;
+		case FMCPortStart:
+			current_port = dpaa_port_fmc_port_parse(
+				fif, fmc_model, i);
+			break;
+		case FMCPortEnd:
+			break;
+		case FMCScheme:
+			if (current_port < 0)
+				break;
+
+			ret = dpaa_port_fmc_scheme_parse(
+				fif, fmc_model,
+				i, &rxq_idx, max_nb_rxq, fqids, vspids);
+			if (ret)
+				return ret;
+
+			break;
+		case FMCCCNode:
+			if (current_port < 0)
+				break;
+
+			ret = dpaa_port_fmc_ccnode_parse(fif, fmc_model,
+				i, &rxq_idx, max_nb_rxq, fqids, vspids);
+			if (ret)
+				return ret;
+
+			break;
+		case FMCHTNode:
+			break;
+		case FMCReplicator:
+			break;
+		case FMCCCTree:
+			break;
+		case FMCPolicer:
+			break;
+		case FMCManipulation:
+			break;
+		default:
+			break;
+		}
+	}
+
+	return rxq_idx;
+}
diff --git a/drivers/net/dpaa/meson.build b/drivers/net/dpaa/meson.build
index 191500001..451c68823 100644
--- a/drivers/net/dpaa/meson.build
+++ b/drivers/net/dpaa/meson.build
@@ -11,7 +11,8 @@  sources = files('dpaa_ethdev.c',
 		'fmlib/fm_lib.c',
 		'fmlib/fm_vsp.c',
 		'dpaa_flow.c',
-		'dpaa_rxtx.c')
+		'dpaa_rxtx.c',
+		'dpaa_fmc.c')
 
 if cc.has_argument('-Wno-pointer-arith')
 	cflags += '-Wno-pointer-arith'