From: Harman Kalra <hkalra@marvell.com>
To: Nithin Dabilpuram <ndabilpuram@marvell.com>,
Kiran Kumar K <kirankumark@marvell.com>,
Sunil Kumar Kori <skori@marvell.com>,
Satha Rao <skoteshwar@marvell.com>,
Harman Kalra <hkalra@marvell.com>
Cc: <dev@dpdk.org>, <jerinj@marvell.com>,
Ankur Dwivedi <adwivedi@marvell.com>
Subject: [PATCH 3/6] net/cnxk: add multi seg support in eswitch
Date: Mon, 24 Jun 2024 13:18:18 +0530 [thread overview]
Message-ID: <20240624074822.88955-3-hkalra@marvell.com> (raw)
In-Reply-To: <20240624074822.88955-1-hkalra@marvell.com>
From: Ankur Dwivedi <adwivedi@marvell.com>
Introducing multi segment support in eswitch driver to handle
packets of varying sizes.
Signed-off-by: Ankur Dwivedi <adwivedi@marvell.com>
---
drivers/net/cnxk/cnxk_eswitch.c | 2 +-
drivers/net/cnxk/cnxk_eswitch_rxtx.c | 167 ++++++++++++++++++++++++---
2 files changed, 149 insertions(+), 20 deletions(-)
diff --git a/drivers/net/cnxk/cnxk_eswitch.c b/drivers/net/cnxk/cnxk_eswitch.c
index f420d01ef8..6b1bfdd476 100644
--- a/drivers/net/cnxk/cnxk_eswitch.c
+++ b/drivers/net/cnxk/cnxk_eswitch.c
@@ -455,7 +455,7 @@ cnxk_eswitch_txq_setup(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid, uint1
memset(sq, 0, sizeof(struct roc_nix_sq));
sq->qid = qid;
sq->nb_desc = nb_desc;
- sq->max_sqe_sz = NIX_MAXSQESZ_W8;
+ sq->max_sqe_sz = NIX_MAXSQESZ_W16;
if (sq->nb_desc >= CNXK_NIX_DEF_SQ_COUNT)
sq->fc_hyst_bits = 0x1;
diff --git a/drivers/net/cnxk/cnxk_eswitch_rxtx.c b/drivers/net/cnxk/cnxk_eswitch_rxtx.c
index 0200392f2d..83a9c68a34 100644
--- a/drivers/net/cnxk/cnxk_eswitch_rxtx.c
+++ b/drivers/net/cnxk/cnxk_eswitch_rxtx.c
@@ -39,31 +39,105 @@ eswitch_nix_rx_nb_pkts(struct roc_nix_cq *cq, const uint64_t wdata, const uint32
}
static inline void
-nix_cn9k_xmit_one(uint64_t *cmd, void *lmt_addr, const plt_iova_t io_addr)
+nix_cn9k_xmit_one(uint64_t *cmd, void *lmt_addr, const plt_iova_t io_addr, uint16_t segdw)
{
uint64_t lmt_status;
do {
- roc_lmt_mov(lmt_addr, cmd, 0);
+ roc_lmt_mov_seg(lmt_addr, (const void *)cmd, segdw);
lmt_status = roc_lmt_submit_ldeor(io_addr);
} while (lmt_status == 0);
}
+static __rte_always_inline uint16_t
+cnxk_eswitch_prepare_mseg(struct rte_mbuf *m, union nix_send_sg_s *sg, uint64_t *cmd, uint64_t len,
+ uint8_t off)
+{
+ union nix_send_sg_s l_sg;
+ struct rte_mbuf *m_next;
+ uint64_t nb_segs;
+ uint64_t *slist;
+ uint16_t segdw;
+ uint64_t dlen;
+
+ l_sg.u = 0;
+ l_sg.ld_type = NIX_SENDLDTYPE_LDD;
+ l_sg.subdc = NIX_SUBDC_SG;
+
+ dlen = m->data_len;
+ l_sg.u |= dlen;
+ len -= dlen;
+ nb_segs = m->nb_segs - 1;
+ m_next = m->next;
+ m->next = NULL;
+ slist = &cmd[off + 1];
+ l_sg.segs = 1;
+ *slist = rte_mbuf_data_iova(m);
+ slist++;
+ m = m_next;
+ if (!m)
+ goto done;
+
+ do {
+ uint64_t iova;
+
+ m_next = m->next;
+ iova = rte_mbuf_data_iova(m);
+ dlen = m->data_len;
+ len -= dlen;
+
+ nb_segs--;
+ m->next = NULL;
+
+ *slist = iova;
+ /* Set the segment length */
+ l_sg.u |= ((uint64_t)dlen << (l_sg.segs << 4));
+ l_sg.segs += 1;
+ slist++;
+ if (l_sg.segs > 2 && nb_segs) {
+ sg->u = l_sg.u;
+ /* Next SG subdesc */
+ sg = (union nix_send_sg_s *)slist;
+ l_sg.u = 0;
+ l_sg.ld_type = NIX_SENDLDTYPE_LDD;
+ l_sg.subdc = NIX_SUBDC_SG;
+ slist++;
+ }
+ m = m_next;
+ } while (nb_segs);
+done:
+ /* Write the last subdc out */
+ sg->u = l_sg.u;
+ segdw = (uint64_t *)slist - (uint64_t *)&cmd[off];
+ /* Roundup extra dwords to multiple of 2 */
+ segdw = (segdw >> 1) + (segdw & 0x1);
+ /* Default dwords */
+ segdw += (off >> 1);
+
+ return segdw;
+}
+
uint16_t
cnxk_eswitch_dev_tx_burst(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid,
struct rte_mbuf **pkts, uint16_t nb_xmit, const uint16_t flags)
{
struct roc_nix_sq *sq = &eswitch_dev->txq[qid].sqs;
struct roc_nix_rq *rq = &eswitch_dev->rxq[qid].rqs;
- uint64_t aura_handle, cmd[6], data = 0;
uint16_t lmt_id, pkt = 0, nb_tx = 0;
struct nix_send_ext_s *send_hdr_ext;
struct nix_send_hdr_s *send_hdr;
+ uint64_t aura_handle, data = 0;
uint16_t vlan_tci = qid;
union nix_send_sg_s *sg;
uintptr_t lmt_base, pa;
int64_t fc_pkts, dw_m1;
+ uint64_t cmd_cn9k[16];
+ struct rte_mbuf *m;
rte_iova_t io_addr;
+ uint16_t segdw;
+ uint64_t *cmd;
+ uint64_t len;
+ uint8_t off;
if (unlikely(eswitch_dev->txq[qid].state != CNXK_ESWITCH_QUEUE_STATE_STARTED))
return 0;
@@ -78,9 +152,14 @@ cnxk_eswitch_dev_tx_burst(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid,
/* 2(HDR) + 2(EXT_HDR) + 1(SG) + 1(IOVA) = 6/2 - 1 = 2 */
dw_m1 = cn10k_nix_tx_ext_subs(flags) + 1;
- memset(cmd, 0, sizeof(cmd));
+ if (roc_model_is_cn9k()) {
+ memset(cmd_cn9k, 0, sizeof(cmd_cn9k));
+ cmd = &cmd_cn9k[0];
+ } else {
+ cmd = (uint64_t *)lmt_base;
+ }
+
send_hdr = (struct nix_send_hdr_s *)&cmd[0];
- send_hdr->w0.sizem1 = dw_m1;
send_hdr->w0.sq = sq->qid;
if (dw_m1 >= 2) {
@@ -90,15 +169,15 @@ cnxk_eswitch_dev_tx_burst(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid,
send_hdr_ext->w1.vlan0_ins_ena = true;
/* 2B before end of l2 header */
send_hdr_ext->w1.vlan0_ins_ptr = 12;
- send_hdr_ext->w1.vlan0_ins_tci = 0;
+ send_hdr_ext->w1.vlan0_ins_tci = vlan_tci;
}
- sg = (union nix_send_sg_s *)&cmd[4];
+ off = 4;
} else {
- sg = (union nix_send_sg_s *)&cmd[2];
+ off = 2;
}
+ sg = (union nix_send_sg_s *)&cmd[off];
sg->subdc = NIX_SUBDC_SG;
- sg->segs = 1;
sg->ld_type = NIX_SENDLDTYPE_LDD;
/* Tx */
@@ -110,28 +189,28 @@ cnxk_eswitch_dev_tx_burst(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid,
nb_tx = PLT_MIN(nb_xmit, (uint64_t)fc_pkts);
for (pkt = 0; pkt < nb_tx; pkt++) {
- send_hdr->w0.total = pkts[pkt]->pkt_len;
- if (pkts[pkt]->pool) {
- aura_handle = pkts[pkt]->pool->pool_id;
+ m = pkts[pkt];
+ len = m->pkt_len;
+ send_hdr->w0.total = len;
+ if (m->pool) {
+ aura_handle = m->pool->pool_id;
send_hdr->w0.aura = roc_npa_aura_handle_to_aura(aura_handle);
} else {
send_hdr->w0.df = 1;
}
- if (dw_m1 >= 2 && flags & NIX_TX_OFFLOAD_VLAN_QINQ_F)
- send_hdr_ext->w1.vlan0_ins_tci = vlan_tci;
- sg->seg1_size = pkts[pkt]->pkt_len;
- *(plt_iova_t *)(sg + 1) = rte_mbuf_data_iova(pkts[pkt]);
+
+ segdw = cnxk_eswitch_prepare_mseg(m, sg, cmd, len, off);
+ send_hdr->w0.sizem1 = segdw - 1;
plt_esw_dbg("Transmitting pkt %d (%p) vlan tci %x on sq %d esw qid %d", pkt,
pkts[pkt], vlan_tci, sq->qid, qid);
if (roc_model_is_cn9k()) {
- nix_cn9k_xmit_one(cmd, sq->lmt_addr, sq->io_addr);
+ nix_cn9k_xmit_one(cmd, sq->lmt_addr, sq->io_addr, segdw);
} else {
- cn10k_nix_xmit_mv_lmt_base(lmt_base, cmd, flags);
/* PA<6:4> = LMTST size-1 in units of 128 bits. Size of the first LMTST in
* burst.
*/
- pa = io_addr | (dw_m1 << 4);
+ pa = io_addr | ((segdw - 1) << 4);
data &= ~0x7ULL;
/*<15:12> = CNTM1: Count minus one of LMTSTs in the burst */
data = (0ULL << 12);
@@ -148,6 +227,54 @@ cnxk_eswitch_dev_tx_burst(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid,
return nb_tx;
}
+static __rte_always_inline void
+cnxk_eswitch_xtract_mseg(struct rte_mbuf *mbuf, const union nix_rx_parse_u *rx)
+{
+ const rte_iova_t *iova_list;
+ uint16_t later_skip = 0;
+ const rte_iova_t *eol;
+ struct rte_mbuf *head;
+ uint8_t nb_segs;
+ uint16_t sg_len;
+ uint64_t sg;
+
+ sg = *(const uint64_t *)(rx + 1);
+ nb_segs = (sg >> 48) & 0x3;
+ if (nb_segs == 1)
+ return;
+
+ mbuf->nb_segs = nb_segs;
+ mbuf->data_len = sg & 0xFFFF;
+ head = mbuf;
+ eol = ((const rte_iova_t *)(rx + 1) + ((rx->desc_sizem1 + 1) << 1));
+ sg = sg >> 16;
+ /* Skip SG_S and first IOVA*/
+ iova_list = ((const rte_iova_t *)(rx + 1)) + 2;
+ nb_segs--;
+ later_skip = (uintptr_t)mbuf->buf_addr - (uintptr_t)mbuf;
+
+ while (nb_segs) {
+ mbuf->next = (struct rte_mbuf *)(*iova_list - later_skip);
+ mbuf = mbuf->next;
+
+ RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
+
+ sg_len = sg & 0XFFFF;
+
+ mbuf->data_len = sg_len;
+ sg = sg >> 16;
+ nb_segs--;
+ iova_list++;
+
+ if (!nb_segs && (iova_list + 1 < eol)) {
+ sg = *(const uint64_t *)(iova_list);
+ nb_segs = (sg >> 48) & 0x3;
+ head->nb_segs += nb_segs;
+ iova_list = (const rte_iova_t *)(iova_list + 1);
+ }
+ }
+}
+
uint16_t
cnxk_eswitch_dev_rx_burst(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid,
struct rte_mbuf **pkts, uint16_t nb_pkts)
@@ -195,6 +322,8 @@ cnxk_eswitch_dev_rx_burst(struct cnxk_eswitch_dev *eswitch_dev, uint16_t qid,
/* Populate RSS hash */
mbuf->hash.rss = cqe->tag;
mbuf->ol_flags = RTE_MBUF_F_RX_RSS_HASH;
+
+ cnxk_eswitch_xtract_mseg(mbuf, rx);
pkts[pkt] = mbuf;
roc_prefetch_store_keep(mbuf);
plt_esw_dbg("Packet %d rec on queue %d esw qid %d hash %x mbuf %p vlan tci %d",
--
2.18.0
next prev parent reply other threads:[~2024-06-24 7:49 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-24 7:48 [PATCH 1/6] net/cnxk: stale offload flag reset Harman Kalra
2024-06-24 7:48 ` [PATCH 2/6] net/cnxk: add MTU set ops Harman Kalra
2024-06-24 7:48 ` Harman Kalra [this message]
2024-06-24 7:48 ` [PATCH 4/6] net/cnxk: increment number of flow pattern Harman Kalra
2024-06-24 9:14 ` Jerin Jacob
2024-06-24 7:48 ` [PATCH 5/6] net/cnxk: update processing ready message Harman Kalra
2024-06-24 7:48 ` [PATCH 6/6] common/cnxk: flow aginig delaying app shutdown Harman Kalra
2024-06-24 9:13 ` [PATCH 1/6] net/cnxk: stale offload flag reset Jerin Jacob
2024-06-24 11:57 ` [PATCH v2 1/5] net/cnxk: fix " Harman Kalra
2024-06-24 11:57 ` [PATCH v2 2/5] net/cnxk: add MTU set ops Harman Kalra
2024-06-24 11:57 ` [PATCH v2 3/5] net/cnxk: add multi seg support in eswitch Harman Kalra
2024-06-24 11:57 ` [PATCH v2 4/5] net/cnxk: fix invalid pattern count Harman Kalra
2024-06-24 11:57 ` [PATCH v2 5/5] net/cnxk: fix representor port mapping Harman Kalra
2024-06-24 13:24 ` [PATCH v3 1/5] net/cnxk: fix stale offload flag reset Harman Kalra
2024-06-24 13:24 ` [PATCH v3 2/5] net/cnxk: add MTU set ops Harman Kalra
2024-06-24 13:24 ` [PATCH v3 3/5] net/cnxk: add multi seg support in eswitch Harman Kalra
2024-06-24 13:24 ` [PATCH v3 4/5] net/cnxk: fix invalid pattern count Harman Kalra
2024-06-24 13:24 ` [PATCH v3 5/5] net/cnxk: fix representor port mapping Harman Kalra
2024-06-25 9:46 ` Jerin Jacob
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240624074822.88955-3-hkalra@marvell.com \
--to=hkalra@marvell.com \
--cc=adwivedi@marvell.com \
--cc=dev@dpdk.org \
--cc=jerinj@marvell.com \
--cc=kirankumark@marvell.com \
--cc=ndabilpuram@marvell.com \
--cc=skori@marvell.com \
--cc=skoteshwar@marvell.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).