From: Jun Yang <[email protected]>

Identify if soft parser protocol firmware is loaded by checking
firmware magic number.
Enable flow/parser of ECPRI, GENEVE, ROCEv2 and VXLAN's spec
only with soft parser protocol firmware being loaded.

Signed-off-by: Jun Yang <[email protected]>
---
 drivers/bus/fslmc/fslmc_bus.c    |  91 +++++++++++++++++++++-
 drivers/net/dpaa2/dpaa2_ethdev.c |   2 +
 drivers/net/dpaa2/dpaa2_flow.c   | 129 ++++++++-----------------------
 drivers/net/dpaa2/dpaa2_rxtx.c   |  10 +++
 4 files changed, 134 insertions(+), 98 deletions(-)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 2427421075..c3415bc541 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: BSD-3-Clause
  *
- *   Copyright 2016,2018-2021 NXP
+ *   Copyright 2016,2018-2026 NXP
  *
  */
 
@@ -8,6 +8,7 @@
 #include <dirent.h>
 #include <stdalign.h>
 #include <stdbool.h>
+#include <sys/mman.h>
 
 #include <eal_export.h>
 #include <rte_log.h>
@@ -35,6 +36,93 @@ struct rte_fslmc_bus_info fslmc_bus_info;
 RTE_EXPORT_INTERNAL_SYMBOL(dpaa2_seqn_dynfield_offset)
 int dpaa2_seqn_dynfield_offset = -1;
 
+/** For LX2160A, LS2088A and LS1088A*/
+#define WRIOP_CCSR_BASE 0x8b80000
+#define WRIOP_CCSR_CTLU_OFFSET 0
+#define WRIOP_CCSR_CTLU_PARSER_OFFSET 0
+#define WRIOP_CCSR_CTLU_PARSER_INGRESS_OFFSET 0
+
+#define WRIOP_INGRESS_PARSER_PHY \
+       (WRIOP_CCSR_BASE + WRIOP_CCSR_CTLU_OFFSET + \
+       WRIOP_CCSR_CTLU_PARSER_OFFSET + \
+       WRIOP_CCSR_CTLU_PARSER_INGRESS_OFFSET)
+
+struct __rte_packed_begin dpaa2_parser_ccsr {
+       uint32_t psr_cfg;
+       uint32_t psr_idle;
+       uint32_t psr_pclm;
+       uint8_t psr_ver_min;
+       uint8_t psr_ver_maj;
+       uint8_t psr_id1_l;
+       uint8_t psr_id1_h;
+       uint32_t psr_rev2;
+       uint8_t rsv[0x2c];
+       uint8_t sp_ins[4032];
+} __rte_packed_end;
+
+#define SP_PROTOCOL_MAGIC_DATA 0xabcd
+#define SP_PROTOCOL_MAGIC_OFFSET 0x4
+
+/** Number of soft parser firmware bytes reported for debugging. */
+#define SP_PRINT_LEN 128
+/** Firmware bytes logged per debug line. */
+#define SP_DUMP_BYTES_PER_LINE 16
+
+static void
+fslmc_soft_parser_protocol_supported(void)
+{
+       int fd, i, pos = 0;
+       void *map_addr = NULL;
+       const struct dpaa2_parser_ccsr *parser_ccsr = NULL;
+       const uint16_t *magic_num;
+       char line[SP_DUMP_BYTES_PER_LINE * 3 + 1];
+
+       fd = open("/dev/mem", O_RDWR | O_SYNC);
+       if (fd < 0) {
+               DPAA2_BUS_ERR("open \"/dev/mem\" ERROR(%d)", fd);
+               goto exit;
+       }
+
+       map_addr = mmap(NULL, sizeof(struct dpaa2_parser_ccsr),
+               PROT_READ | PROT_WRITE, MAP_SHARED, fd,
+               WRIOP_INGRESS_PARSER_PHY);
+       parser_ccsr = map_addr;
+       if (!parser_ccsr) {
+               DPAA2_BUS_ERR("Map 0x%" PRIx64 "(size=0x%zx) failed",
+                       (uint64_t)WRIOP_INGRESS_PARSER_PHY,
+                       sizeof(struct dpaa2_parser_ccsr));
+               goto exit;
+       }
+
+       DPAA2_BUS_DEBUG("Soft ParserID:0x%02x%02x, Rev:maj(%02x), min(%02x)",
+               parser_ccsr->psr_id1_h, parser_ccsr->psr_id1_l,
+               parser_ccsr->psr_ver_maj, parser_ccsr->psr_ver_min);
+
+       magic_num = (const void 
*)&parser_ccsr->sp_ins[SP_PROTOCOL_MAGIC_OFFSET];
+       if (*magic_num == SP_PROTOCOL_MAGIC_DATA) {
+               fslmc_bus_info.sp_protocol = true;
+               DPAA2_BUS_INFO("Soft parser protocol support.");
+               DPAA2_BUS_DEBUG("First %d bytes of sp protocol firmware:",
+                       SP_PRINT_LEN);
+               for (i = 0; i < SP_PRINT_LEN; i++) {
+                       pos += snprintf(&line[pos], sizeof(line) - pos,
+                               "%02x ", parser_ccsr->sp_ins[i]);
+                       if ((i + 1) % SP_DUMP_BYTES_PER_LINE == 0) {
+                               DPAA2_BUS_DEBUG("%s", line);
+                               pos = 0;
+                       }
+               }
+               if (pos)
+                       DPAA2_BUS_DEBUG("%s", line);
+       }
+
+exit:
+       if (map_addr)
+               munmap(map_addr, sizeof(struct dpaa2_parser_ccsr));
+       if (fd >= 0)
+               close(fd);
+}
+
 RTE_EXPORT_INTERNAL_SYMBOL(rte_fslmc_get_device_count)
 uint32_t
 rte_fslmc_get_device_count(enum rte_dpaa2_dev_type device_type)
@@ -345,6 +433,7 @@ rte_fslmc_scan(void)
                DPAA2_BUS_ERR("Unable to open VFIO group directory");
                goto scan_fail;
        }
+       fslmc_soft_parser_protocol_supported();
 
        /* Scan the DPRC container object */
        ret = scan_one_fslmc_device(group_name);
diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c
index e6ce29b2ea..fb1d01e209 100644
--- a/drivers/net/dpaa2/dpaa2_ethdev.c
+++ b/drivers/net/dpaa2/dpaa2_ethdev.c
@@ -3735,6 +3735,8 @@ dpaa2_dev_init(struct rte_eth_dev *eth_dev)
        }
        eth_dev->data->mtu = RTE_ETHER_MTU;
 
+       priv->sp_protocol = dpaa2_dev->bus_info->sp_protocol;
+
        DPAA2_PMD_INFO("%s: netdev created, connected to %s",
                eth_dev->data->name, dpaa2_dev->ep_name);
 
diff --git a/drivers/net/dpaa2/dpaa2_flow.c b/drivers/net/dpaa2/dpaa2_flow.c
index 2662c358e4..cde2f5a9d3 100644
--- a/drivers/net/dpaa2/dpaa2_flow.c
+++ b/drivers/net/dpaa2/dpaa2_flow.c
@@ -9,7 +9,6 @@
 #include <string.h>
 #include <unistd.h>
 #include <stdarg.h>
-#include <sys/mman.h>
 
 #include <rte_ethdev.h>
 #include <rte_log.h>
@@ -22,9 +21,9 @@
 
 #include <dpaa2_ethdev.h>
 #include <dpaa2_pmd_logs.h>
+#include "dpaa2_parser_decode.h"
 
 static char *dpaa2_flow_control_log;
-static int dpaa2_sp_loaded = -1;
 
 /* Default size of a key */
 #define DPNI_DEFAULT_KEY_SIZE 24
@@ -434,92 +433,6 @@ dpaa2_flow_fs_entry_log(const char *log_info,
        DPAA2_FLOW_DUMP("\r\n");
 }
 
-/** For LX2160A, LS2088A and LS1088A*/
-#define WRIOP_CCSR_BASE 0x8b80000
-#define WRIOP_CCSR_CTLU_OFFSET 0
-#define WRIOP_CCSR_CTLU_PARSER_OFFSET 0
-#define WRIOP_CCSR_CTLU_PARSER_INGRESS_OFFSET 0
-
-#define WRIOP_INGRESS_PARSER_PHY \
-       (WRIOP_CCSR_BASE + WRIOP_CCSR_CTLU_OFFSET + \
-       WRIOP_CCSR_CTLU_PARSER_OFFSET + \
-       WRIOP_CCSR_CTLU_PARSER_INGRESS_OFFSET)
-
-struct dpaa2_parser_ccsr {
-       uint32_t psr_cfg;
-       uint32_t psr_idle;
-       uint32_t psr_pclm;
-       uint8_t psr_ver_min;
-       uint8_t psr_ver_maj;
-       uint8_t psr_id1_l;
-       uint8_t psr_id1_h;
-       uint32_t psr_rev2;
-       uint8_t rsv[0x2c];
-       uint8_t sp_ins[4032];
-};
-
-int
-dpaa2_soft_parser_loaded(void)
-{
-       int fd, i, ret = 0;
-       struct dpaa2_parser_ccsr *parser_ccsr = NULL;
-
-       dpaa2_flow_control_log = getenv("DPAA2_FLOW_CONTROL_LOG");
-
-       if (dpaa2_sp_loaded >= 0)
-               return dpaa2_sp_loaded;
-
-       fd = open("/dev/mem", O_RDWR | O_SYNC);
-       if (fd < 0) {
-               DPAA2_PMD_ERR("open \"/dev/mem\" ERROR(%d)", fd);
-               ret = fd;
-               goto exit;
-       }
-
-       parser_ccsr = mmap(NULL, sizeof(struct dpaa2_parser_ccsr),
-               PROT_READ | PROT_WRITE, MAP_SHARED, fd,
-               WRIOP_INGRESS_PARSER_PHY);
-       if (!parser_ccsr) {
-               DPAA2_PMD_ERR("Map 0x%" PRIx64 "(size=0x%x) failed",
-                       (uint64_t)WRIOP_INGRESS_PARSER_PHY,
-                       (uint32_t)sizeof(struct dpaa2_parser_ccsr));
-               ret = -ENOBUFS;
-               goto exit;
-       }
-
-       DPAA2_PMD_INFO("Parser ID:0x%02x%02x, Rev:major(%02x), minor(%02x)",
-               parser_ccsr->psr_id1_h, parser_ccsr->psr_id1_l,
-               parser_ccsr->psr_ver_maj, parser_ccsr->psr_ver_min);
-
-       if (dpaa2_flow_control_log) {
-               for (i = 0; i < 64; i++) {
-                       DPAA2_FLOW_DUMP("%02x ",
-                               parser_ccsr->sp_ins[i]);
-                       if (!((i + 1) % 16))
-                               DPAA2_FLOW_DUMP("\r\n");
-               }
-       }
-
-       for (i = 0; i < 16; i++) {
-               if (parser_ccsr->sp_ins[i]) {
-                       dpaa2_sp_loaded = 1;
-                       break;
-               }
-       }
-       if (dpaa2_sp_loaded < 0)
-               dpaa2_sp_loaded = 0;
-
-       ret = dpaa2_sp_loaded;
-
-exit:
-       if (parser_ccsr)
-               munmap(parser_ccsr, sizeof(struct dpaa2_parser_ccsr));
-       if (fd >= 0)
-               close(fd);
-
-       return ret;
-}
-
 static int
 dpaa2_flow_ip_address_extract(enum net_prot prot,
        uint32_t field)
@@ -3538,6 +3451,11 @@ dpaa2_configure_flow_gre(struct dpaa2_dev_flow *flow,
                return 0;
        }
 
+       if (!priv->sp_protocol) {
+               DPAA2_PMD_ERR("vXLAN flow with spec is not supported without 
SP.");
+               return -ENOTSUP;
+       }
+
        ret = dpaa2_flow_extract_support((const uint8_t *)mask,
                RTE_FLOW_ITEM_TYPE_GRE);
        if (ret) {
@@ -3583,6 +3501,11 @@ dpaa2_configure_flow_vxlan(struct dpaa2_dev_flow *flow,
        struct dpaa2_dev_priv *priv = dev->data->dev_private;
        const struct rte_flow_item *pattern = &dpaa2_pattern->generic_item;
 
+       if (!priv->sp_protocol) {
+               DPAA2_PMD_ERR("eCPRI flow is not supported without SP.");
+               return -ENOTSUP;
+       }
+
        group = attr->group;
 
        /* Parse pattern list to get the matching parameters */
@@ -3681,6 +3604,11 @@ dpaa2_configure_flow_ecpri(struct dpaa2_dev_flow *flow,
        uint8_t extract_size[DPAA2_ECPRI_MAX_EXTRACT_NB];
        uint8_t extract_off[DPAA2_ECPRI_MAX_EXTRACT_NB];
 
+       if (!priv->sp_protocol) {
+               DPAA2_PMD_ERR("ROCEV2 flow is not supported without SP.");
+               return -ENOTSUP;
+       }
+
        group = attr->group;
 
        /* Parse pattern list to get the matching parameters */
@@ -4000,6 +3928,11 @@ dpaa2_configure_flow_gtp(struct dpaa2_dev_flow *flow,
        const struct rte_flow_item *pattern =
                &dpaa2_pattern->generic_item;
 
+       if (!priv->sp_protocol) {
+               DPAA2_PMD_ERR("GENEVE flow is not supported without SP.");
+               return -ENOTSUP;
+       }
+
        group = attr->group;
 
        /* Parse pattern list to get the matching parameters */
@@ -4725,7 +4658,7 @@ dpaa2_configure_qos_table(struct dpaa2_dev_priv *priv,
 
 static int
 dpaa2_flow_item_convert(const struct rte_flow_item pattern[],
-                       struct rte_dpaa2_flow_item **dpaa2_pattern)
+       struct rte_dpaa2_flow_item **dpaa2_pattern, int sp_protocol)
 {
        struct rte_dpaa2_flow_item *new_pattern;
        int num = 0, tunnel_start = 0;
@@ -4737,7 +4670,7 @@ dpaa2_flow_item_convert(const struct rte_flow_item 
pattern[],
        }
 
        new_pattern = rte_malloc(NULL, sizeof(struct rte_dpaa2_flow_item) * num,
-                                RTE_CACHE_LINE_SIZE);
+                       RTE_CACHE_LINE_SIZE);
        if (!new_pattern) {
                DPAA2_PMD_ERR("Failed to alloc %d flow items", num);
                return -ENOMEM;
@@ -4745,13 +4678,13 @@ dpaa2_flow_item_convert(const struct rte_flow_item 
pattern[],
 
        num = 0;
        while (pattern[num].type != RTE_FLOW_ITEM_TYPE_END) {
-               memcpy(&new_pattern[num].generic_item, &pattern[num],
-                      sizeof(struct rte_flow_item));
+               rte_memcpy(&new_pattern[num].generic_item, &pattern[num],
+                       sizeof(struct rte_flow_item));
                new_pattern[num].in_tunnel = 0;
 
                if (pattern[num].type == RTE_FLOW_ITEM_TYPE_VXLAN)
                        tunnel_start = 1;
-               else if (tunnel_start)
+               else if (tunnel_start && sp_protocol)
                        new_pattern[num].in_tunnel = 1;
                num++;
        }
@@ -4788,7 +4721,8 @@ dpaa2_generic_flow_set(struct dpaa2_dev_flow *flow,
        if (ret)
                return ret;
 
-       ret = dpaa2_flow_item_convert(pattern, &dpaa2_pattern);
+       ret = dpaa2_flow_item_convert(pattern, &dpaa2_pattern,
+               priv->sp_protocol);
        if (ret)
                return ret;
 
@@ -5129,7 +5063,8 @@ dpaa2_dev_verify_attr(struct dpni_attr *dpni_attr,
 }
 
 static inline int
-dpaa2_dev_verify_patterns(const struct rte_flow_item pattern[])
+dpaa2_dev_verify_patterns(const struct rte_flow_item pattern[],
+       int sp_support)
 {
        unsigned int i, j, is_found = 0;
        int ret = 0;
@@ -5153,7 +5088,7 @@ dpaa2_dev_verify_patterns(const struct rte_flow_item 
pattern[])
                }
                if (is_found)
                        continue;
-               if (dpaa2_sp_loaded > 0) {
+               if (sp_support) {
                        for (i = 0; i < sp_supported_num; i++) {
                                if (sp_supported[i] == pattern[j].type) {
                                        is_found = 1;
@@ -5232,7 +5167,7 @@ dpaa2_flow_validate(struct rte_eth_dev *dev,
                goto not_valid_params;
        }
        /* Verify input pattern list */
-       ret = dpaa2_dev_verify_patterns(pattern);
+       ret = dpaa2_dev_verify_patterns(pattern, priv->sp_protocol);
        if (ret < 0) {
                DPAA2_PMD_ERR("Invalid pattern list is given");
                rte_flow_error_set(error, EPERM,
diff --git a/drivers/net/dpaa2/dpaa2_rxtx.c b/drivers/net/dpaa2/dpaa2_rxtx.c
index f417edf52b..ccb4bbe7dc 100644
--- a/drivers/net/dpaa2/dpaa2_rxtx.c
+++ b/drivers/net/dpaa2/dpaa2_rxtx.c
@@ -128,6 +128,16 @@ dpaa2_dev_rx_parse_new(struct dpaa2_dev_priv *priv,
                        ext_packet_type |= RTE_PTYPE_INNER_L3_IPV4;
                }
        }
+       if (priv->sp_protocol) {
+               if (frc_parse->fafe2) {
+                       frc_parse->fafe2 = 0;
+                       ext_packet_type |= RTE_PTYPE_TUNNEL_GENEVE;
+               }
+               if (frc_parse->sum_l.l4.fafe3) {
+                       frc_parse->sum_l.l4.fafe3 = 0;
+                       ext_packet_type |= RTE_PTYPE_INNER_L3_IPV4;
+               }
+       }
        switch (frc) {
        case DPAA2_PKT_TYPE_IPV4_UDP:
                m->packet_type = RTE_PTYPE_L2_ETHER |
-- 
2.43.0

Reply via email to