net/sfc: add concept of MAE (transfer) rules
authorIvan Malov <ivan.malov@oktetlabs.ru>
Tue, 20 Oct 2020 09:12:47 +0000 (10:12 +0100)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 3 Nov 2020 22:24:24 +0000 (23:24 +0100)
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.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
doc/guides/nics/sfc_efx.rst
drivers/net/sfc/sfc_flow.c
drivers/net/sfc/sfc_flow.h
drivers/net/sfc/sfc_mae.c
drivers/net/sfc/sfc_mae.h

index 3af63c3..5e19e5b 100644 (file)
@@ -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
 
index cb802d7..8608220 100644 (file)
@@ -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;
 
index 433c7a3..1fbcb87 100644 (file)
@@ -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;
        };
 };
 
index 2a7ed63..487bd61 100644 (file)
@@ -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)
index d7821e7..dd9ca07 100644 (file)
@@ -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;