From: Ivan Malov Date: Tue, 12 Oct 2021 19:46:17 +0000 (+0300) Subject: net/sfc: support API to negotiate delivery of Rx metadata X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=9b14dc746141bcd3ed2769ea745cc0cca85a9bb0;p=dpdk.git net/sfc: support API to negotiate delivery of Rx metadata 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 Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- 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,