From: Long Wu <long...@corigine.com>

If dma_len is larger than NFDK_DESC_TX_DMA_LEN_HEAD, the value of
dma_len bitwise and NFDK_DESC_TX_DMA_LEN_HEAD maybe less than packet
head length and the packet will be dropped. Fill maximum dma_len in
first tx descriptor to make sure the whole head is included in the
first descriptor. In addition, add comments to better explain the
code flow.

Fixes: c73dced48c8c ("net/nfp: add NFDk Tx")
Cc: jin....@corigine.com
Cc: sta...@dpdk.org

Signed-off-by: Long Wu <long...@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderl...@corigine.com>
---

v2:
* Rewrite the commit message.
* Revise some logic according to the advice.

---
 drivers/net/nfp/nfp_rxtx.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c
index 01cffdfde0..990007c03d 100644
--- a/drivers/net/nfp/nfp_rxtx.c
+++ b/drivers/net/nfp/nfp_rxtx.c
@@ -1063,6 +1063,7 @@ nfp_net_nfdk_tx_maybe_close_block(struct nfp_net_txq 
*txq, struct rte_mbuf *pkt)
        if (unlikely(n_descs > NFDK_TX_DESC_GATHER_MAX))
                return -EINVAL;
 
+       /* Under count by 1 (don't count meta) for the round down to work out */
        n_descs += !!(pkt->ol_flags & RTE_MBUF_F_TX_TCP_SEG);
 
        if (round_down(txq->wr_p, NFDK_TX_DESC_BLOCK_CNT) !=
@@ -1219,8 +1220,19 @@ nfp_net_nfdk_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts, uint16_t nb_pk
                } else {
                        type = NFDK_DESC_TX_TYPE_GATHER;
                }
+
+               /* Implicitly truncates to chunk in below logic */
                dma_len -= 1;
-               dlen_type = (NFDK_DESC_TX_DMA_LEN_HEAD & dma_len) |
+
+               /*
+                * We will do our best to pass as much data as we can in 
descriptor
+                * and we need to make sure the first descriptor includes whole
+                * head since there is limitation in firmware side. Sometimes 
the
+                * value of dma_len bitwise & NFDK_DESC_TX_DMA_LEN_HEAD will 
less
+                * than packet head len.
+                */
+               dlen_type = (dma_len > NFDK_DESC_TX_DMA_LEN_HEAD ?
+                       NFDK_DESC_TX_DMA_LEN_HEAD : dma_len) |
                        (NFDK_DESC_TX_TYPE_HEAD & (type << 12));
                ktxds->dma_len_type = rte_cpu_to_le_16(dlen_type);
                dma_addr = rte_mbuf_data_iova(pkt);
@@ -1230,10 +1242,18 @@ nfp_net_nfdk_xmit_pkts(void *tx_queue, struct rte_mbuf 
**tx_pkts, uint16_t nb_pk
                ktxds->dma_addr_lo = rte_cpu_to_le_32(dma_addr & 0xffffffff);
                ktxds++;
 
+               /*
+                * Preserve the original dlen_type, this way below the EOP logic
+                * can use dlen_type.
+                */
                tmp_dlen = dlen_type & NFDK_DESC_TX_DMA_LEN_HEAD;
                dma_len -= tmp_dlen;
                dma_addr += tmp_dlen + 1;
 
+               /*
+                * The rest of the data (if any) will be in larger dma 
descritors
+                * and is handled with the dma_len loop.
+                */
                while (pkt) {
                        if (*lmbuf)
                                rte_pktmbuf_free_seg(*lmbuf);
-- 
2.29.3

Reply via email to