net/dpaa: support FMC parser for VSP
authorJun Yang <jun.yang@nxp.com>
Fri, 4 Sep 2020 08:39:29 +0000 (14:09 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Fri, 18 Sep 2020 16:55:08 +0000 (18:55 +0200)
FMC tool generates and saves the setup in a file.
This patch help Parse the /tmp/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>
Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>
drivers/net/dpaa/dpaa_ethdev.c
drivers/net/dpaa/dpaa_ethdev.h
drivers/net/dpaa/dpaa_fmc.c [new file with mode: 0644]
drivers/net/dpaa/meson.build

index 8e7eb98..0ce2f5a 100644 (file)
@@ -259,6 +259,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)
@@ -334,6 +344,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;
@@ -1699,7 +1712,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();
index dd182c4..1b8e120 100644 (file)
 #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
 #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 (file)
index 0000000..0ef3622
--- /dev/null
@@ -0,0 +1,475 @@
+/* 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_REPS          64
+
+typedef struct fmc_port_t {
+       e_fm_port_type type;
+       unsigned int number;
+       struct fm_pcd_net_env_params_t distinction_units;
+       struct ioc_fm_port_pcd_params_t pcd_param;
+       struct ioc_fm_port_pcd_prs_params_t prs_param;
+       struct ioc_fm_port_pcd_kg_params_t kg_param;
+       struct ioc_fm_port_pcd_cc_params_t cc_param;
+       char name[FMC_NAME_LEN];
+       char cctree_name[FMC_NAME_LEN];
+       t_handle handle;
+       t_handle env_id_handle;
+       t_handle env_id_dev_id;
+       t_handle cctree_handle;
+       t_handle cctree_dev_id;
+
+       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 vsp_param;
+
+       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_dev_id[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_dev_id[FMC_MANIP_MAX];
+
+       unsigned int hdr_count;
+       struct fm_pcd_manip_params_t hdr[FMC_HMANIP_MAX];
+       uint8_t insert_data[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_dev_id[FMC_HMANIP_MAX];
+       unsigned int hdr_has_next[FMC_HMANIP_MAX];
+       unsigned int hdr_next[FMC_HMANIP_MAX];
+} fmc_fman;
+
+typedef enum fmc_apply_order_e {
+       fmcengine_start,
+       fmcengine_end,
+       fmcport_start,
+       fmcport_end,
+       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_fm_pcd_prs_sw_params 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_dev_id[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_dev_id[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_dev_id[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_dev_id[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_REPS];
+       unsigned char repentry_frag[FMC_REPLICATORS_NUM][FM_PCD_MAX_REPS];
+       unsigned int repentry_manip[FMC_REPLICATORS_NUM][FM_PCD_MAX_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_dev_id[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,
+                               int apply_idx,
+                               uint16_t *rxq_idx, int max_nb_rxq,
+                               uint32_t *fqids, int8_t *vspids)
+{
+       int idx = fmc->apply_order[apply_idx].index;
+       uint32_t i;
+
+       if (!fmc->scheme[idx].override_storage_profile &&
+               fif->is_shared_mac) {
+               DPAA_PMD_WARN("No VSP assigned to scheme %d for sharemac %d!",
+                       idx, fif->mac_idx);
+               DPAA_PMD_WARN("Risk to receive pkts from skb pool to CRASH!");
+       }
+
+       if (e_IOC_FM_PCD_DONE ==
+               fmc->scheme[idx].next_engine) {
+               for (i = 0; i < fmc->scheme[idx]
+                       .key_ext_and_hash.hash_dist_num_of_fqids; i++) {
+                       uint32_t fqid = fmc->scheme[idx].base_fqid + i;
+                       int k, found = 0;
+
+                       if (fqid == fif->fqid_rx_def) {
+                               if (fif->is_shared_mac &&
+                               fmc->scheme[idx].override_storage_profile &&
+                               fmc->scheme[idx].storage_profile.direct &&
+                               fmc->scheme[idx].storage_profile
+                               .profile_select.direct_relative_profile_id !=
+                               fif->base_profile_id) {
+                                       DPAA_PMD_ERR("Def RXQ must be associated with def VSP on sharemac!");
+
+                                       return -1;
+                               }
+                               continue;
+                       }
+
+                       if (fif->is_shared_mac &&
+                       !fmc->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->scheme[idx].override_storage_profile &&
+                               fmc->scheme[idx].storage_profile.direct &&
+                               fmc->scheme[idx].storage_profile
+                               .profile_select.direct_relative_profile_id ==
+                               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->scheme[idx].override_storage_profile) {
+                               if (fmc->scheme[idx].storage_profile.direct) {
+                                       vspids[(*rxq_idx)] =
+                                               fmc->scheme[idx].storage_profile
+                                               .profile_select
+                                               .direct_relative_profile_id;
+                               } 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 fmcengine_start:
+                       break;
+               case fmcengine_end:
+                       break;
+               case fmcport_start:
+                       current_port = dpaa_port_fmc_port_parse(fif,
+                                                               fmc_model, i);
+                       break;
+               case fmcport_end:
+                       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;
+}
index 51f1f32..c00dba6 100644 (file)
@@ -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'