Initial support for the method. Later patches will extend it to
make FLAG and MARK delivery available on EF100 native datapath.

Signed-off-by: Ivan Malov <ivan.ma...@oktetlabs.ru>
Reviewed-by: Andrew Rybchenko <andrew.rybche...@oktetlabs.ru>
Reviewed-by: Andy Moreton <amore...@xilinx.com>
---
 drivers/net/sfc/sfc.h        |  2 ++
 drivers/net/sfc/sfc_ethdev.c | 29 +++++++++++++++++++++++++++++
 drivers/net/sfc/sfc_flow.c   | 11 +++++++++++
 drivers/net/sfc/sfc_mae.c    | 22 ++++++++++++++++++++--
 4 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 331e06bac6..2812d76cbb 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -312,6 +312,8 @@ struct sfc_adapter {
        boolean_t                       tso;
        boolean_t                       tso_encap;
 
+       uint64_t                        negotiated_rx_meta;
+
        uint32_t                        rxd_wait_timeout_ns;
 };
 
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 2db0d000c3..75c3da2e52 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -1859,6 +1859,28 @@ sfc_rx_queue_intr_disable(struct rte_eth_dev *dev, 
uint16_t ethdev_qid)
        return sap->dp_rx->intr_disable(rxq_info->dp);
 }
 
+static int
+sfc_rx_meta_negotiate(struct rte_eth_dev *dev, uint64_t *features)
+{
+       struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+       uint64_t supported = 0;
+
+       sfc_adapter_lock(sa);
+
+       if ((sa->priv.dp_rx->features & SFC_DP_RX_FEAT_FLOW_FLAG) != 0)
+               supported |= RTE_ETH_RX_META_USER_FLAG;
+
+       if ((sa->priv.dp_rx->features & SFC_DP_RX_FEAT_FLOW_MARK) != 0)
+               supported |= RTE_ETH_RX_META_USER_MARK;
+
+       sa->negotiated_rx_meta = supported & *features;
+       *features = sa->negotiated_rx_meta;
+
+       sfc_adapter_unlock(sa);
+
+       return 0;
+}
+
 static const struct eth_dev_ops sfc_eth_dev_ops = {
        .dev_configure                  = sfc_dev_configure,
        .dev_start                      = sfc_dev_start,
@@ -1906,6 +1928,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
        .xstats_get_by_id               = sfc_xstats_get_by_id,
        .xstats_get_names_by_id         = sfc_xstats_get_names_by_id,
        .pool_ops_supported             = sfc_pool_ops_supported,
+       .rx_meta_negotiate              = sfc_rx_meta_negotiate,
 };
 
 /**
@@ -1998,6 +2021,12 @@ sfc_eth_dev_set_ops(struct rte_eth_dev *dev)
                goto fail_dp_rx_name;
        }
 
+       if (strcmp(dp_rx->dp.name, SFC_KVARG_DATAPATH_EF10_ESSB) == 0) {
+               /* FLAG and MARK are always available from Rx prefix. */
+               sa->negotiated_rx_meta |= RTE_ETH_RX_META_USER_FLAG;
+               sa->negotiated_rx_meta |= RTE_ETH_RX_META_USER_MARK;
+       }
+
        sfc_notice(sa, "use %s Rx datapath", sas->dp_rx_name);
 
        rc = sfc_kvargs_process(sa, SFC_KVARG_TX_DATAPATH,
diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
index 4f5993a68d..57cf1ad02b 100644
--- a/drivers/net/sfc/sfc_flow.c
+++ b/drivers/net/sfc/sfc_flow.c
@@ -1760,6 +1760,7 @@ sfc_flow_parse_actions(struct sfc_adapter *sa,
        struct sfc_flow_spec *spec = &flow->spec;
        struct sfc_flow_spec_filter *spec_filter = &spec->filter;
        const unsigned int dp_rx_features = sa->priv.dp_rx->features;
+       const uint64_t rx_meta = sa->negotiated_rx_meta;
        uint32_t actions_set = 0;
        const uint32_t fate_actions_mask = (1UL << RTE_FLOW_ACTION_TYPE_QUEUE) |
                                           (1UL << RTE_FLOW_ACTION_TYPE_RSS) |
@@ -1832,6 +1833,11 @@ sfc_flow_parse_actions(struct sfc_adapter *sa,
                                        RTE_FLOW_ERROR_TYPE_ACTION, NULL,
                                        "FLAG action is not supported on the 
current Rx datapath");
                                return -rte_errno;
+                       } else if ((rx_meta & RTE_ETH_RX_META_USER_FLAG) == 0) {
+                               rte_flow_error_set(error, ENOTSUP,
+                                       RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+                                       "flag delivery has not been 
negotiated");
+                               return -rte_errno;
                        }
 
                        spec_filter->template.efs_flags |=
@@ -1849,6 +1855,11 @@ sfc_flow_parse_actions(struct sfc_adapter *sa,
                                        RTE_FLOW_ERROR_TYPE_ACTION, NULL,
                                        "MARK action is not supported on the 
current Rx datapath");
                                return -rte_errno;
+                       } else if ((rx_meta & RTE_ETH_RX_META_USER_MARK) == 0) {
+                               rte_flow_error_set(error, ENOTSUP,
+                                       RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+                                       "mark delivery has not been 
negotiated");
+                               return -rte_errno;
                        }
 
                        rc = sfc_flow_parse_mark(sa, actions->conf, flow);
diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c
index 4b520bc619..5ecad7347a 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c
@@ -2963,6 +2963,7 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa,
                          efx_mae_actions_t *spec,
                          struct rte_flow_error *error)
 {
+       const uint64_t rx_meta = sa->negotiated_rx_meta;
        bool custom_error = B_FALSE;
        int rc = 0;
 
@@ -3012,12 +3013,29 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa,
        case RTE_FLOW_ACTION_TYPE_FLAG:
                SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_FLAG,
                                       bundle->actions_mask);
-               rc = efx_mae_action_set_populate_flag(spec);
+               if ((rx_meta & RTE_ETH_RX_META_USER_FLAG) != 0) {
+                       rc = efx_mae_action_set_populate_flag(spec);
+               } else {
+                       rc = rte_flow_error_set(error, ENOTSUP,
+                                               RTE_FLOW_ERROR_TYPE_ACTION,
+                                               action,
+                                               "flag delivery has not been 
negotiated");
+                       custom_error = B_TRUE;
+               }
                break;
        case RTE_FLOW_ACTION_TYPE_MARK:
                SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_MARK,
                                       bundle->actions_mask);
-               rc = sfc_mae_rule_parse_action_mark(sa, action->conf, spec);
+               if ((rx_meta & RTE_ETH_RX_META_USER_MARK) != 0) {
+                       rc = sfc_mae_rule_parse_action_mark(sa, action->conf,
+                                                           spec);
+               } else {
+                       rc = rte_flow_error_set(error, ENOTSUP,
+                                               RTE_FLOW_ERROR_TYPE_ACTION,
+                                               action,
+                                               "mark delivery has not been 
negotiated");
+                       custom_error = B_TRUE;
+               }
                break;
        case RTE_FLOW_ACTION_TYPE_PHY_PORT:
                SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_PHY_PORT,
-- 
2.20.1

Reply via email to