From 53a80512644c8a12cb8efc903f77dd7b42263565 Mon Sep 17 00:00:00 2001 From: Ivan Malov Date: Wed, 13 Oct 2021 16:15:04 +0300 Subject: [PATCH] net/sfc: fence off 8 bits in Rx mark for tunnel offload Later patches add support for tunnel offload on Riverhead (EF100). A board can host at most 254 tunnels. Partially offloaded (missed) tunnel packets are identified by virtue of 8 high bits in Rx mark. Add basic definitions of the upcoming tunnel offload support and take care of the dedicated bits in Rx mark across the driver. Signed-off-by: Ivan Malov Reviewed-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- drivers/net/sfc/meson.build | 1 + drivers/net/sfc/sfc_dp_rx.h | 3 +++ drivers/net/sfc/sfc_ef100_rx.c | 14 ++++++++++-- drivers/net/sfc/sfc_ethdev.c | 4 ++++ drivers/net/sfc/sfc_flow.c | 8 ++++++- drivers/net/sfc/sfc_flow_tunnel.c | 30 ++++++++++++++++++++++++ drivers/net/sfc/sfc_flow_tunnel.h | 38 +++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_mae.c | 6 +++++ drivers/net/sfc/sfc_rx.c | 10 +++++++- 9 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 drivers/net/sfc/sfc_flow_tunnel.c create mode 100644 drivers/net/sfc/sfc_flow_tunnel.h diff --git a/drivers/net/sfc/meson.build b/drivers/net/sfc/meson.build index 98365e9e73..33087330f9 100644 --- a/drivers/net/sfc/meson.build +++ b/drivers/net/sfc/meson.build @@ -90,6 +90,7 @@ sources = files( 'sfc_mae.c', 'sfc_mae_counter.c', 'sfc_flow.c', + 'sfc_flow_tunnel.c', 'sfc_dp.c', 'sfc_ef10_rx.c', 'sfc_ef10_essb_rx.c', diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h index d037acaa56..099f026a15 100644 --- a/drivers/net/sfc/sfc_dp_rx.h +++ b/drivers/net/sfc/sfc_dp_rx.h @@ -92,6 +92,9 @@ struct sfc_dp_rx_qcreate_info { efsys_dma_addr_t fcw_offset; /** VI window size shift */ unsigned int vi_window_shift; + + /** Mask to extract user bits from Rx prefix mark field */ + uint32_t user_mark_mask; }; /** diff --git a/drivers/net/sfc/sfc_ef100_rx.c b/drivers/net/sfc/sfc_ef100_rx.c index d6308dc70d..2b88de1fee 100644 --- a/drivers/net/sfc/sfc_ef100_rx.c +++ b/drivers/net/sfc/sfc_ef100_rx.c @@ -20,7 +20,9 @@ #include "efx_regs_ef100.h" #include "efx.h" +#include "sfc.h" #include "sfc_debug.h" +#include "sfc_flow_tunnel.h" #include "sfc_tweak.h" #include "sfc_dp_rx.h" #include "sfc_kvargs.h" @@ -75,6 +77,7 @@ struct sfc_ef100_rxq { uint64_t rearm_data; uint16_t buf_size; uint16_t prefix_size; + uint32_t user_mark_mask; unsigned int evq_hw_index; volatile void *evq_prime; @@ -423,10 +426,13 @@ sfc_ef100_rx_prefix_to_offloads(const struct sfc_ef100_rxq *rxq, if (rxq->flags & SFC_EF100_RXQ_USER_MARK) { uint32_t user_mark; + uint32_t mark; /* EFX_XWORD_FIELD converts little-endian to CPU */ - user_mark = EFX_XWORD_FIELD(rx_prefix[0], - ESF_GZ_RX_PREFIX_USER_MARK); + mark = EFX_XWORD_FIELD(rx_prefix[0], + ESF_GZ_RX_PREFIX_USER_MARK); + + user_mark = mark & rxq->user_mark_mask; if (user_mark != SFC_EF100_USER_MARK_INVALID) { ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID; m->hash.fdir.hi = user_mark; @@ -760,6 +766,10 @@ sfc_ef100_rx_qcreate(uint16_t port_id, uint16_t queue_id, rxq->max_fill_level = info->max_fill_level; rxq->refill_threshold = info->refill_threshold; rxq->prefix_size = info->prefix_size; + + SFC_ASSERT(info->user_mark_mask != 0); + rxq->user_mark_mask = info->user_mark_mask; + rxq->buf_size = info->buf_size; rxq->refill_mb_pool = info->refill_mb_pool; rxq->rxq_hw_ring = info->rxq_hw_ring; diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index c0d9810fbb..e127b18c1f 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -26,6 +26,7 @@ #include "sfc_rx.h" #include "sfc_tx.h" #include "sfc_flow.h" +#include "sfc_flow_tunnel.h" #include "sfc_dp.h" #include "sfc_dp_rx.h" #include "sfc_repr.h" @@ -2332,6 +2333,9 @@ sfc_rx_metadata_negotiate(struct rte_eth_dev *dev, uint64_t *features) if ((sa->priv.dp_rx->features & SFC_DP_RX_FEAT_FLOW_MARK) != 0) supported |= RTE_ETH_RX_METADATA_USER_MARK; + if (sfc_flow_tunnel_is_supported(sa)) + supported |= RTE_ETH_RX_METADATA_TUNNEL_ID; + sa->negotiated_rx_metadata = supported & *features; *features = sa->negotiated_rx_metadata; diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index 9e6d8109c7..251072483b 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -22,6 +22,7 @@ #include "sfc_rx.h" #include "sfc_filter.h" #include "sfc_flow.h" +#include "sfc_flow_tunnel.h" #include "sfc_log.h" #include "sfc_dp_rx.h" #include "sfc_mae_counter.h" @@ -1740,8 +1741,13 @@ sfc_flow_parse_mark(struct sfc_adapter *sa, struct sfc_flow_spec *spec = &flow->spec; struct sfc_flow_spec_filter *spec_filter = &spec->filter; const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic); + uint32_t mark_max; - if (mark == NULL || mark->id > encp->enc_filter_action_mark_max) + mark_max = encp->enc_filter_action_mark_max; + if (sfc_flow_tunnel_is_active(sa)) + mark_max = RTE_MIN(mark_max, SFC_FT_USER_MARK_MASK); + + if (mark == NULL || mark->id > mark_max) return EINVAL; spec_filter->template.efs_flags |= EFX_FILTER_FLAG_ACTION_MARK; diff --git a/drivers/net/sfc/sfc_flow_tunnel.c b/drivers/net/sfc/sfc_flow_tunnel.c new file mode 100644 index 0000000000..2a0cf299d1 --- /dev/null +++ b/drivers/net/sfc/sfc_flow_tunnel.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2021 Xilinx, Inc. + */ + +#include +#include + +#include "sfc.h" +#include "sfc_dp_rx.h" +#include "sfc_flow_tunnel.h" +#include "sfc_mae.h" + +bool +sfc_flow_tunnel_is_supported(struct sfc_adapter *sa) +{ + SFC_ASSERT(sfc_adapter_is_locked(sa)); + + return ((sa->priv.dp_rx->features & SFC_DP_RX_FEAT_FLOW_MARK) != 0 && + sa->mae.status == SFC_MAE_STATUS_SUPPORTED); +} + +bool +sfc_flow_tunnel_is_active(struct sfc_adapter *sa) +{ + SFC_ASSERT(sfc_adapter_is_locked(sa)); + + return ((sa->negotiated_rx_metadata & + RTE_ETH_RX_METADATA_TUNNEL_ID) != 0); +} diff --git a/drivers/net/sfc/sfc_flow_tunnel.h b/drivers/net/sfc/sfc_flow_tunnel.h new file mode 100644 index 0000000000..fec891fdad --- /dev/null +++ b/drivers/net/sfc/sfc_flow_tunnel.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright(c) 2021 Xilinx, Inc. + */ + +#ifndef _SFC_FLOW_TUNNEL_H +#define _SFC_FLOW_TUNNEL_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Flow Tunnel (FT) SW entry ID */ +typedef uint8_t sfc_ft_id_t; + +#define SFC_FT_TUNNEL_MARK_BITS \ + (sizeof(sfc_ft_id_t) * CHAR_BIT) + +#define SFC_FT_USER_MARK_BITS \ + (sizeof(uint32_t) * CHAR_BIT - SFC_FT_TUNNEL_MARK_BITS) + +#define SFC_FT_USER_MARK_MASK \ + RTE_LEN2MASK(SFC_FT_USER_MARK_BITS, uint32_t) + +struct sfc_adapter; + +bool sfc_flow_tunnel_is_supported(struct sfc_adapter *sa); + +bool sfc_flow_tunnel_is_active(struct sfc_adapter *sa); + +#ifdef __cplusplus +} +#endif +#endif /* _SFC_FLOW_TUNNEL_H */ diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index 571673a723..9c1e6f1991 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -16,6 +16,7 @@ #include "efx.h" #include "sfc.h" +#include "sfc_flow_tunnel.h" #include "sfc_mae_counter.h" #include "sfc_log.h" #include "sfc_switch.h" @@ -2923,6 +2924,11 @@ sfc_mae_rule_parse_action_mark(struct sfc_adapter *sa, { int rc; + if (conf->id > SFC_FT_USER_MARK_MASK) { + sfc_err(sa, "the mark value is too large"); + return EINVAL; + } + rc = efx_mae_action_set_populate_mark(spec, conf->id); if (rc != 0) sfc_err(sa, "failed to request action MARK: %s", strerror(rc)); diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c index 5e120f5851..2c779c4fbc 100644 --- a/drivers/net/sfc/sfc_rx.c +++ b/drivers/net/sfc/sfc_rx.c @@ -13,6 +13,7 @@ #include "sfc.h" #include "sfc_debug.h" +#include "sfc_flow_tunnel.h" #include "sfc_log.h" #include "sfc_ev.h" #include "sfc_rx.h" @@ -1181,7 +1182,8 @@ sfc_rx_qinit(struct sfc_adapter *sa, sfc_sw_index_t sw_index, if ((sa->negotiated_rx_metadata & RTE_ETH_RX_METADATA_USER_FLAG) != 0) rxq_info->type_flags |= EFX_RXQ_FLAG_USER_FLAG; - if ((sa->negotiated_rx_metadata & RTE_ETH_RX_METADATA_USER_MARK) != 0) + if ((sa->negotiated_rx_metadata & RTE_ETH_RX_METADATA_USER_MARK) != 0 || + sfc_flow_tunnel_is_active(sa)) rxq_info->type_flags |= EFX_RXQ_FLAG_USER_MARK; rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_RX, sw_index, @@ -1231,6 +1233,12 @@ sfc_rx_qinit(struct sfc_adapter *sa, sfc_sw_index_t sw_index, info.buf_size = buf_size; info.batch_max = encp->enc_rx_batch_max; info.prefix_size = encp->enc_rx_prefix_size; + + if (sfc_flow_tunnel_is_active(sa)) + info.user_mark_mask = SFC_FT_USER_MARK_MASK; + else + info.user_mark_mask = UINT32_MAX; + info.flags = rxq_info->rxq_flags; info.rxq_entries = rxq_info->entries; info.rxq_hw_ring = rxq->mem.esm_base; -- 2.20.1