From: Ivan Malov <ivan.ma...@oktetlabs.ru>

Define the corresponding specification structure and
make the code identify MAE rules by testing transfer
attribute presence. Also, add a priority level check.

Signed-off-by: Ivan Malov <ivan.ma...@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybche...@solarflare.com>
Reviewed-by: Andy Moreton <amore...@xilinx.com>
---
 doc/guides/nics/sfc_efx.rst |  5 +++--
 drivers/net/sfc/sfc_flow.c  | 26 ++++++++++++++++++++------
 drivers/net/sfc/sfc_flow.h  |  9 +++++++++
 drivers/net/sfc/sfc_mae.c   | 11 +++++++++++
 drivers/net/sfc/sfc_mae.h   |  2 ++
 5 files changed, 45 insertions(+), 8 deletions(-)

diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 959b52c1c3..7a5aff79f9 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -144,8 +144,9 @@ Flow API support
 Supported attributes:
 
 - Ingress
+- Transfer
 
-Supported pattern items:
+Supported pattern items (***non-transfer*** rules):
 
 - VOID
 
@@ -173,7 +174,7 @@ Supported pattern items:
 
 - NVGRE (exact match of virtual subnet ID)
 
-Supported actions:
+Supported actions (***non-transfer*** rules):
 
 - VOID
 
diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
index cb802d7991..86082208d0 100644
--- a/drivers/net/sfc/sfc_flow.c
+++ b/drivers/net/sfc/sfc_flow.c
@@ -1124,12 +1124,15 @@ static const struct sfc_flow_item sfc_flow_items[] = {
  * Protocol-independent flow API support
  */
 static int
-sfc_flow_parse_attr(const struct rte_flow_attr *attr,
+sfc_flow_parse_attr(struct sfc_adapter *sa,
+                   const struct rte_flow_attr *attr,
                    struct rte_flow *flow,
                    struct rte_flow_error *error)
 {
        struct sfc_flow_spec *spec = &flow->spec;
        struct sfc_flow_spec_filter *spec_filter = &spec->filter;
+       struct sfc_flow_spec_mae *spec_mae = &spec->mae;
+       struct sfc_mae *mae = &sa->mae;
 
        if (attr == NULL) {
                rte_flow_error_set(error, EINVAL,
@@ -1167,10 +1170,20 @@ sfc_flow_parse_attr(const struct rte_flow_attr *attr,
                spec_filter->template.efs_rss_context = EFX_RSS_CONTEXT_DEFAULT;
                spec_filter->template.efs_priority = EFX_FILTER_PRI_MANUAL;
        } else {
-               rte_flow_error_set(error, ENOTSUP,
-                                  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, attr,
-                                  "Transfer is not supported");
-               return -rte_errno;
+               if (mae->status != SFC_MAE_STATUS_SUPPORTED) {
+                       rte_flow_error_set(error, ENOTSUP,
+                                          RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                                          attr, "Transfer is not supported");
+                       return -rte_errno;
+               }
+               if (attr->priority > mae->nb_action_rule_prios_max) {
+                       rte_flow_error_set(error, ENOTSUP,
+                                          RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
+                                          attr, "Unsupported priority level");
+                       return -rte_errno;
+               }
+               spec->type = SFC_FLOW_SPEC_MAE;
+               spec_mae->priority = attr->priority;
        }
 
        return 0;
@@ -2403,10 +2416,11 @@ sfc_flow_parse(struct rte_eth_dev *dev,
               struct rte_flow *flow,
               struct rte_flow_error *error)
 {
+       struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
        const struct sfc_flow_ops_by_spec *ops;
        int rc;
 
-       rc = sfc_flow_parse_attr(attr, flow, error);
+       rc = sfc_flow_parse_attr(sa, attr, flow, error);
        if (rc != 0)
                return rc;
 
diff --git a/drivers/net/sfc/sfc_flow.h b/drivers/net/sfc/sfc_flow.h
index 433c7a31e9..1fbcb878d1 100644
--- a/drivers/net/sfc/sfc_flow.h
+++ b/drivers/net/sfc/sfc_flow.h
@@ -38,6 +38,7 @@ struct sfc_flow_rss {
 /* Flow engines supported by the implementation */
 enum sfc_flow_spec_type {
        SFC_FLOW_SPEC_FILTER = 0,
+       SFC_FLOW_SPEC_MAE,
 
        SFC_FLOW_SPEC_NTYPES
 };
@@ -58,6 +59,12 @@ struct sfc_flow_spec_filter {
        struct sfc_flow_rss rss_conf;
 };
 
+/* MAE-specific flow specification */
+struct sfc_flow_spec_mae {
+       /* Desired priority level */
+       unsigned int                    priority;
+};
+
 /* Flow specification */
 struct sfc_flow_spec {
        /* Flow specification type (engine-based) */
@@ -67,6 +74,8 @@ struct sfc_flow_spec {
        union {
                /* Filter-based (VNIC level flows) specification */
                struct sfc_flow_spec_filter filter;
+               /* MAE-based (lower-level HW switch flows) specification */
+               struct sfc_flow_spec_mae mae;
        };
 };
 
diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index 2a7ed6377a..487bd61f76 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -21,6 +21,7 @@ sfc_mae_attach(struct sfc_adapter *sa)
 {
        const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
        struct sfc_mae *mae = &sa->mae;
+       efx_mae_limits_t limits;
        int rc;
 
        sfc_log_init(sa, "entry");
@@ -35,12 +36,21 @@ sfc_mae_attach(struct sfc_adapter *sa)
        if (rc != 0)
                goto fail_mae_init;
 
+       sfc_log_init(sa, "get MAE limits");
+       rc = efx_mae_get_limits(sa->nic, &limits);
+       if (rc != 0)
+               goto fail_mae_get_limits;
+
        mae->status = SFC_MAE_STATUS_SUPPORTED;
+       mae->nb_action_rule_prios_max = limits.eml_max_n_action_prios;
 
        sfc_log_init(sa, "done");
 
        return 0;
 
+fail_mae_get_limits:
+       efx_mae_fini(sa->nic);
+
 fail_mae_init:
        sfc_log_init(sa, "failed %d", rc);
 
@@ -55,6 +65,7 @@ sfc_mae_detach(struct sfc_adapter *sa)
 
        sfc_log_init(sa, "entry");
 
+       mae->nb_action_rule_prios_max = 0;
        mae->status = SFC_MAE_STATUS_UNKNOWN;
 
        if (status_prev != SFC_MAE_STATUS_SUPPORTED)
diff --git a/drivers/net/sfc/sfc_mae.h b/drivers/net/sfc/sfc_mae.h
index d7821e71cc..dd9ca07d15 100644
--- a/drivers/net/sfc/sfc_mae.h
+++ b/drivers/net/sfc/sfc_mae.h
@@ -28,6 +28,8 @@ enum sfc_mae_status {
 struct sfc_mae {
        /** NIC support for MAE status */
        enum sfc_mae_status             status;
+       /** Priority level limit for MAE action rules */
+       unsigned int                    nb_action_rule_prios_max;
 };
 
 struct sfc_adapter;
-- 
2.17.1

Reply via email to