[13/13] net/nfp: modify the logic of some NFDk function
Checks
Commit Message
Split one function into two functions and change the data type of
parameter and return value.
Also add some comment message to help understand.
Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
drivers/net/nfp/nfdk/nfp_nfdk.h | 75 ++++++++++++++++++++++++++++--
drivers/net/nfp/nfdk/nfp_nfdk_dp.c | 48 ++++++++++++-------
2 files changed, 101 insertions(+), 22 deletions(-)
@@ -9,22 +9,27 @@
#define NFDK_TX_DESC_PER_SIMPLE_PKT 2
#define NFDK_TX_DESC_GATHER_MAX 17
-#define NFDK_TX_MAX_DATA_PER_HEAD 0x00001000
-#define NFDK_TX_MAX_DATA_PER_DESC 0x00004000
-#define NFDK_TX_MAX_DATA_PER_BLOCK 0x00010000
+#define NFDK_TX_MAX_DATA_PER_HEAD 0x00001000 /* 4K */
+#define NFDK_TX_MAX_DATA_PER_DESC 0x00004000 /* 16K */
+#define NFDK_TX_MAX_DATA_PER_BLOCK 0x00010000 /* 64K */
+/* The mask of 'dma_len_xx' of address descriptor */
#define NFDK_DESC_TX_DMA_LEN_HEAD 0x0FFF /* [0,11] */
#define NFDK_DESC_TX_DMA_LEN 0x3FFF /* [0,13] */
#define NFDK_DESC_TX_TYPE_HEAD 0xF000 /* [12,15] */
+/* The mask of upper 4 bit of first address descriptor */
+#define NFDK_DESC_TX_TYPE_HEAD 0xF000 /* [12,15] */
+
+/* The value of upper 4 bit of first address descriptor */
#define NFDK_DESC_TX_TYPE_GATHER 1
#define NFDK_DESC_TX_TYPE_TSO 2
#define NFDK_DESC_TX_TYPE_SIMPLE 8
-/* TX descriptor format */
+/* The 'end of chain' flag of address descriptor */
#define NFDK_DESC_TX_EOP RTE_BIT32(14)
-/* Flags in the host TX descriptor */
+/* Flags in the host metadata descriptor */
#define NFDK_DESC_TX_CHAIN_META RTE_BIT32(3)
#define NFDK_DESC_TX_ENCAP RTE_BIT32(2)
#define NFDK_DESC_TX_L4_CSUM RTE_BIT32(1)
@@ -40,14 +45,73 @@
/* Convenience macro for wrapping descriptor index on ring size */
#define D_IDX(ring, idx) ((idx) & ((ring)->tx_count - 1))
+/*
+ * A full TX descriptor consists of one or more address descriptors,
+ * followed by a TX metadata descriptor, and finally a TSO descriptor for
+ * TSO packets.
+ *
+ * --> Header address descriptor:
+ * Bit 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word +-+-+---+-----------------------+-------------------------------+
+ * 0 |S|E| TP| dma_len_12 | dma_addr_hi |
+ * +-+-+---+-----------------------+-------------------------------+
+ * 1 | dma_addr_lo |
+ * +---------------------------------------------------------------+
+ *
+ * --> Subsequent address descriptor(s):
+ * Bit 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word +-+-+---------------------------+-------------------------------+
+ * 0 |S|E| dma_len_14 | dma_addr_hi |
+ * +-+-+---------------------------+-------------------------------+
+ * 1 | dma_addr_lo |
+ * +---------------------------------------------------------------+
+ *
+ * S - Simple Packet descriptor
+ * TP - Type of descriptor
+ * E - End of chain
+ * dma_len - length of the host memory in bytes -1
+ * dma_addr_hi - bits [47:32] of host memory address
+ * dma_addr_lo - bits [31:0] of host memory address
+ *
+ * --> metadata descriptor
+ * Bit 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word +-------+-----------------------+---------------------+---+-----+
+ * 0 | ZERO | Rsvd (64b support) | TBD meta | MT| CSUM|
+ * +-------+-----------------------+---------------------+---+-----+
+ * 1 | TBD meta |
+ * +---------------------------------------------------------------+
+ *
+ * --> TSO descriptor
+ * The following is only present if TP above indicates LSO:
+ * Bit 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
+ * -----\ 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ * Word +---------------+---------------+---+---------------------------+
+ * 0 | total_segments| header_len |sp0| mss |
+ * +---------------+---------------+---+---------------------------+
+ * 1 | sp1 | L4 | L3 |
+ * +---------------------------------------------------------------+
+ *
+ * total_segments - LSO: Total number of segments
+ * header_len - LSO: length of the LSO header in bytes
+ * sp0 - Spare Bits (ZERO)
+ * mss - LSO: TCP MSS, maximum segment size of TCP payload
+ * sp1 - Spare Bits (ZERO)
+ * L4 - Layer 4 data
+ * L3 - Layer 3 data
+ */
struct nfp_net_nfdk_tx_desc {
union {
+ /* Address descriptor */
struct {
uint16_t dma_addr_hi; /* High bits of host buf address */
uint16_t dma_len_type; /* Length to DMA for this desc */
uint32_t dma_addr_lo; /* Low 32bit of host buf addr */
};
+ /* TSO descriptor */
struct {
uint16_t mss; /* MSS to be used for LSO */
uint8_t lso_hdrlen; /* LSO, TCP payload offset */
@@ -57,6 +121,7 @@ struct nfp_net_nfdk_tx_desc {
uint16_t lso_meta_res; /* Rsvd bits in TSO metadata */
};
+ /* Metadata descriptor */
struct {
uint8_t flags; /* TX Flags, see @NFDK_DESC_TX_* */
uint8_t reserved[7]; /* meta byte placeholder */
@@ -14,25 +14,46 @@
#include "../nfpcore/nfp_rtsym.h"
#include "nfp_nfdk.h"
-static inline int
-nfp_net_nfdk_headlen_to_segs(unsigned int headlen)
+static inline uint16_t
+nfp_net_nfdk_headlen_to_segs(uint16_t headlen)
{
+ /* First descriptor fits less data, so adjust for that */
return DIV_ROUND_UP(headlen +
NFDK_TX_MAX_DATA_PER_DESC -
NFDK_TX_MAX_DATA_PER_HEAD,
NFDK_TX_MAX_DATA_PER_DESC);
}
+static inline void
+nfp_net_nfdk_tx_close_block(struct nfp_net_txq *txq,
+ uint32_t nop_slots)
+{
+ uint32_t i;
+ uint32_t wr_p;
+
+ wr_p = txq->wr_p;
+ memset(&txq->ktxds[wr_p], 0, nop_slots * sizeof(struct nfp_net_nfdk_tx_desc));
+
+ for (i = wr_p; i < nop_slots + wr_p; i++) {
+ if (txq->txbufs[i].mbuf != NULL) {
+ rte_pktmbuf_free_seg(txq->txbufs[i].mbuf);
+ txq->txbufs[i].mbuf = NULL;
+ }
+ }
+
+ txq->data_pending = 0;
+ txq->wr_p = D_IDX(txq, wr_p + nop_slots);
+}
+
static int
nfp_net_nfdk_tx_maybe_close_block(struct nfp_net_txq *txq,
struct rte_mbuf *pkt)
{
- uint32_t i;
- uint32_t wr_p;
uint16_t n_descs;
uint32_t nop_slots;
struct rte_mbuf *pkt_temp;
+ /* Count address descriptor */
pkt_temp = pkt;
n_descs = nfp_net_nfdk_headlen_to_segs(pkt_temp->data_len);
while (pkt_temp->next != NULL) {
@@ -43,9 +64,12 @@ nfp_net_nfdk_tx_maybe_close_block(struct nfp_net_txq *txq,
if (unlikely(n_descs > NFDK_TX_DESC_GATHER_MAX))
return -EINVAL;
- if ((pkt->ol_flags & RTE_MBUF_F_TX_TCP_SEG) != 0)
+ /* Count TSO descriptor */
+ if ((txq->hw->cap & NFP_NET_CFG_CTRL_LSO_ANY) != 0 &&
+ (pkt->ol_flags & RTE_MBUF_F_TX_TCP_SEG) != 0)
n_descs++;
+ /* Don't count metadata descriptor, for the round down to work out */
if (round_down(txq->wr_p, NFDK_TX_DESC_BLOCK_CNT) !=
round_down(txq->wr_p + n_descs, NFDK_TX_DESC_BLOCK_CNT))
goto close_block;
@@ -56,18 +80,8 @@ nfp_net_nfdk_tx_maybe_close_block(struct nfp_net_txq *txq,
return 0;
close_block:
- wr_p = txq->wr_p;
- nop_slots = D_BLOCK_CPL(wr_p);
-
- memset(&txq->ktxds[wr_p], 0, nop_slots * sizeof(struct nfp_net_nfdk_tx_desc));
- for (i = wr_p; i < nop_slots + wr_p; i++) {
- if (txq->txbufs[i].mbuf) {
- rte_pktmbuf_free_seg(txq->txbufs[i].mbuf);
- txq->txbufs[i].mbuf = NULL;
- }
- }
- txq->data_pending = 0;
- txq->wr_p = D_IDX(txq, txq->wr_p + nop_slots);
+ nop_slots = D_BLOCK_CPL(txq->wr_p);
+ nfp_net_nfdk_tx_close_block(txq, nop_slots);
return nop_slots;
}