[dpdk-dev] [PATCH v6 2/5] net/sfc: support API to negotiate delivery of Rx metadata
From: Ivan Malov <hidden>
Date: 2021-10-12 19:38:49
Subsystem:
networking drivers, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
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 <redacted> Reviewed-by: Andrew Rybchenko <redacted> Reviewed-by: Andy Moreton <redacted> --- drivers/net/sfc/sfc.h | 2 ++ drivers/net/sfc/sfc_ethdev.c | 29 +++++++++++++++++++++++++++++ drivers/net/sfc/sfc_flow.c | 13 +++++++++++++ drivers/net/sfc/sfc_mae.c | 22 ++++++++++++++++++++-- 4 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 2b459a72db..bba9adc424 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h@@ -289,6 +289,8 @@ struct sfc_adapter { boolean_t tso; boolean_t tso_encap; + uint64_t negotiated_rx_metadata; + uint32_t rxd_wait_timeout_ns; bool switchdev;
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 200961cfc8..c0d9810fbb 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c@@ -2318,6 +2318,28 @@ sfc_representor_info_get(struct rte_eth_dev *dev, return nb_repr; } +static int +sfc_rx_metadata_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_METADATA_USER_FLAG; + + if ((sa->priv.dp_rx->features & SFC_DP_RX_FEAT_FLOW_MARK) != 0) + supported |= RTE_ETH_RX_METADATA_USER_MARK; + + sa->negotiated_rx_metadata = supported & *features; + *features = sa->negotiated_rx_metadata; + + 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,
@@ -2366,6 +2388,7 @@ static const struct eth_dev_ops sfc_eth_dev_ops = { .xstats_get_names_by_id = sfc_xstats_get_names_by_id, .pool_ops_supported = sfc_pool_ops_supported, .representor_info_get = sfc_representor_info_get, + .rx_metadata_negotiate = sfc_rx_metadata_negotiate, }; struct sfc_ethdev_init_data {
@@ -2462,6 +2485,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_metadata |= RTE_ETH_RX_METADATA_USER_FLAG; + sa->negotiated_rx_metadata |= RTE_ETH_RX_METADATA_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 36ee79f331..9e6d8109c7 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_metadata = sa->negotiated_rx_metadata; 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,12 @@ 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_metadata & + RTE_ETH_RX_METADATA_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 +1856,12 @@ 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_metadata & + RTE_ETH_RX_METADATA_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 053a729a77..571673a723 100644
--- a/drivers/net/sfc/sfc_mae.c
+++ b/drivers/net/sfc/sfc_mae.c@@ -3088,6 +3088,7 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa, efx_mae_actions_t *spec, struct rte_flow_error *error) { + const uint64_t rx_metadata = sa->negotiated_rx_metadata; bool custom_error = B_FALSE; int rc = 0;
@@ -3137,12 +3138,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_metadata & RTE_ETH_RX_METADATA_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_metadata & RTE_ETH_RX_METADATA_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