net/sfc: support EF100 Tx override prefix
Add internal mbuf dynamic flag and field to request EF100 native Tx datapath to use Tx prefix descriptor to override egress m-port. Overriding egress m-port is necessary on representor Tx burst so that the packet will reach corresponding VF. Signed-off-by: Igor Romanov <igor.romanov@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru> Reviewed-by: Andy Moreton <amoreton@xilinx.com> Reviewed-by: Ivan Malov <ivan.malov@oktetlabs.ru>
This commit is contained in:
parent
4ea8bb7809
commit
3f95dfb9c4
@ -12,6 +12,9 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <rte_log.h>
|
||||
#include <rte_mbuf_dyn.h>
|
||||
|
||||
#include "efx.h"
|
||||
|
||||
#include "sfc_dp.h"
|
||||
#include "sfc_log.h"
|
||||
@ -77,3 +80,46 @@ sfc_dp_register(struct sfc_dp_list *head, struct sfc_dp *entry)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t sfc_dp_mport_override;
|
||||
int sfc_dp_mport_offset = -1;
|
||||
|
||||
int
|
||||
sfc_dp_mport_register(void)
|
||||
{
|
||||
static const struct rte_mbuf_dynfield mport = {
|
||||
.name = "rte_net_sfc_dynfield_mport",
|
||||
.size = sizeof(efx_mport_id_t),
|
||||
.align = __alignof__(efx_mport_id_t),
|
||||
};
|
||||
static const struct rte_mbuf_dynflag mport_override = {
|
||||
.name = "rte_net_sfc_dynflag_mport_override",
|
||||
};
|
||||
|
||||
int field_offset;
|
||||
int flag;
|
||||
|
||||
if (sfc_dp_mport_override != 0) {
|
||||
SFC_GENERIC_LOG(INFO, "%s() already registered", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
field_offset = rte_mbuf_dynfield_register(&mport);
|
||||
if (field_offset < 0) {
|
||||
SFC_GENERIC_LOG(ERR, "%s() failed to register mport dynfield",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
flag = rte_mbuf_dynflag_register(&mport_override);
|
||||
if (flag < 0) {
|
||||
SFC_GENERIC_LOG(ERR, "%s() failed to register mport dynflag",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sfc_dp_mport_offset = field_offset;
|
||||
sfc_dp_mport_override = UINT64_C(1) << flag;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -128,6 +128,31 @@ struct sfc_dp *sfc_dp_find_by_caps(struct sfc_dp_list *head,
|
||||
unsigned int avail_caps);
|
||||
int sfc_dp_register(struct sfc_dp_list *head, struct sfc_dp *entry);
|
||||
|
||||
/**
|
||||
* Dynamically registered mbuf flag "mport_override" (as a bitmask).
|
||||
*
|
||||
* If this flag is set in an mbuf then the dynamically registered
|
||||
* mbuf field "mport" holds a valid value. This is used to direct
|
||||
* port representor transmit traffic to the correct target port.
|
||||
*/
|
||||
extern uint64_t sfc_dp_mport_override;
|
||||
|
||||
/**
|
||||
* Dynamically registered mbuf field "mport" (mbuf byte offset).
|
||||
*
|
||||
* If the dynamically registered "mport_override" flag is set in
|
||||
* an mbuf then the mbuf "mport" field holds a valid value. This
|
||||
* is used to direct port representor transmit traffic to the
|
||||
* correct target port.
|
||||
*/
|
||||
extern int sfc_dp_mport_offset;
|
||||
|
||||
/**
|
||||
* Register dynamic mbuf flag and field which can be used to require Tx override
|
||||
* prefix descriptor with egress mport set.
|
||||
*/
|
||||
int sfc_dp_mport_register(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <rte_mbuf.h>
|
||||
#include <rte_mbuf_dyn.h>
|
||||
#include <rte_io.h>
|
||||
#include <rte_net.h>
|
||||
|
||||
@ -309,6 +310,19 @@ sfc_ef100_tx_reap(struct sfc_ef100_txq *txq)
|
||||
sfc_ef100_tx_reap_num_descs(txq, sfc_ef100_tx_process_events(txq));
|
||||
}
|
||||
|
||||
static void
|
||||
sfc_ef100_tx_qdesc_prefix_create(const struct rte_mbuf *m, efx_oword_t *tx_desc)
|
||||
{
|
||||
efx_mport_id_t *mport_id =
|
||||
RTE_MBUF_DYNFIELD(m, sfc_dp_mport_offset, efx_mport_id_t *);
|
||||
|
||||
EFX_POPULATE_OWORD_3(*tx_desc,
|
||||
ESF_GZ_TX_PREFIX_EGRESS_MPORT,
|
||||
mport_id->id,
|
||||
ESF_GZ_TX_PREFIX_EGRESS_MPORT_EN, 1,
|
||||
ESF_GZ_TX_DESC_TYPE, ESE_GZ_TX_DESC_TYPE_PREFIX);
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
sfc_ef100_tx_qdesc_cso_inner_l3(uint64_t tx_tunnel)
|
||||
{
|
||||
@ -525,6 +539,11 @@ sfc_ef100_tx_pkt_descs_max(const struct rte_mbuf *m)
|
||||
SFC_MBUF_SEG_LEN_MAX));
|
||||
}
|
||||
|
||||
if (m->ol_flags & sfc_dp_mport_override) {
|
||||
/* Tx override prefix descriptor will be used */
|
||||
extra_descs++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Any segment of scattered packet cannot be bigger than maximum
|
||||
* segment length. Make sure that subsequent segments do not need
|
||||
@ -671,6 +690,12 @@ sfc_ef100_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_seg->ol_flags & sfc_dp_mport_override) {
|
||||
id = added++ & txq->ptr_mask;
|
||||
sfc_ef100_tx_qdesc_prefix_create(m_seg,
|
||||
&txq->txq_hw_ring[id]);
|
||||
}
|
||||
|
||||
if (m_seg->ol_flags & PKT_TX_TCP_SEG) {
|
||||
m_seg = sfc_ef100_xmit_tso_pkt(txq, m_seg, &added);
|
||||
} else {
|
||||
|
@ -2301,6 +2301,10 @@ sfc_eth_dev_init(struct rte_eth_dev *dev)
|
||||
return 1;
|
||||
}
|
||||
|
||||
rc = sfc_dp_mport_register();
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
sfc_register_dp();
|
||||
|
||||
logtype_main = sfc_register_logtype(&pci_dev->addr,
|
||||
|
Loading…
x
Reference in New Issue
Block a user