Raise the TSO segment limit to 255 so the largest jumbo frames can be sent,
reworking the SGE copy path to build multiple copy mbufs.

Signed-off-by: Jiacheng Ye <[email protected]>
---
 doc/guides/rel_notes/release_26_11.rst |   1 +
 drivers/net/hinic3/hinic3_ethdev.c     |   2 +
 drivers/net/hinic3/hinic3_tx.c         | 287 ++++++++++++++-----------
 drivers/net/hinic3/hinic3_tx.h         |  14 +-
 4 files changed, 175 insertions(+), 129 deletions(-)

diff --git a/doc/guides/rel_notes/release_26_11.rst 
b/doc/guides/rel_notes/release_26_11.rst
index a8a1641d2a..19ecce010f 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -101,6 +101,7 @@ New Features
   * Added support for the SP560 NIC.
   * Added device parameters for runtime configuration.
   * Added a compact CQE receive data path.
+  * Extended TCP segmentation offload (TSO) to 255 segments.
 
 * **Updated Intel iavf driver.**
 
diff --git a/drivers/net/hinic3/hinic3_ethdev.c 
b/drivers/net/hinic3/hinic3_ethdev.c
index b272d42007..c472b8fae1 100644
--- a/drivers/net/hinic3/hinic3_ethdev.c
+++ b/drivers/net/hinic3/hinic3_ethdev.c
@@ -1454,6 +1454,8 @@ hinic3_tx_queue_setup(struct rte_eth_dev *dev, uint16_t 
qid, uint16_t nb_desc,
        txq->wqebb_size = (uint16_t)RTE_BIT32(txq->wqebb_shift);
        txq->tx_free_thresh = tx_free_thresh;
        txq->owner = 1;
+       txq->non_tso_max_pkt_len =
+               HINIC3_IS_SP230_NIC(nic_dev) ? MAX_SINGLE_SGE_SIZE : 
HINIC3_MAX_JUMBO_FRAME_SIZE;
 
        if (!ODD_NUMBER_QUEUE_ID(qid) &&
                hinic3_cmd_vf_lag(nic_dev->hwdev, 
hinic3_global_func_id(nic_dev->hwdev),
diff --git a/drivers/net/hinic3/hinic3_tx.c b/drivers/net/hinic3/hinic3_tx.c
index bbe8c1c085..566e22315d 100644
--- a/drivers/net/hinic3/hinic3_tx.c
+++ b/drivers/net/hinic3/hinic3_tx.c
@@ -474,122 +474,121 @@ hinic3_set_tx_offload(struct hinic3_nic_dev *nic_dev,
  * true as valid, false as invalid.
  */
 static bool
-hinic3_is_tso_sge_valid(struct rte_mbuf *mbuf, struct hinic3_wqe_info 
*wqe_info)
+hinic3_is_tso_sge_valid(struct rte_mbuf *mbuf,
+                       struct hinic3_wqe_info *wqe_info)
 {
-       uint32_t total_len, limit_len, checked_len, left_len, adjust_mss;
-       uint32_t max_sges, left_sges, first_len;
-       uint32_t payload_len, frag_num;
-       uint32_t i;
-       struct rte_mbuf *mbuf_head, *mbuf_first;
-       struct rte_mbuf *mbuf_pre = mbuf;
-
-       left_sges = mbuf->nb_segs;
-       mbuf_head = mbuf;
-       mbuf_first = mbuf;
+       uint32_t payload_len, frag_num, adjust_mss, limit_len, total_used_len;
+       uint32_t i = 0, window_len = 0, no_copy_total_len = 0;
+       uint8_t copy_mbuf_num;
+       struct rte_mbuf *mbuf_pkt;
+
+       if (unlikely(mbuf->data_len < wqe_info->payload_offset &&
+                    mbuf->nb_segs > HINIC3_NONTSO_PKT_MAX_SGE)) {
+               PMD_DRV_LOG(WARNING, "illegal pkt, payload offset (%u) > data 
len (%u).",
+                           wqe_info->payload_offset, mbuf->data_len);
+               return false;
+       }
 
        /* Calculate the number of message payload frag,
         * if it exceeds the hardware limit of 10 bits,
         * packet will be discarded.
         */
-       payload_len = mbuf_head->pkt_len - wqe_info->payload_offset;
-       frag_num = (payload_len + mbuf_head->tso_segsz - 1) / 
mbuf_head->tso_segsz;
+       payload_len = mbuf->pkt_len - wqe_info->payload_offset;
+
+       frag_num = (payload_len + mbuf->tso_segsz - 1) / mbuf->tso_segsz;
        if (frag_num > MAX_TSO_NUM_FRAG) {
-               PMD_DRV_LOG(WARNING, "tso frag num over hw limit, 
frag_num:0x%x.", frag_num);
+               PMD_DRV_LOG(WARNING, "tso frag num over hw limit, frag_num: 
0x%x", frag_num);
                return false;
        }
 
-       /* Tso sge number validation. */
-       if (unlikely(left_sges >= HINIC3_NONTSO_PKT_MAX_SGE)) {
-               checked_len = 0;
-               total_len = 0;
-               first_len = 0;
-               adjust_mss = mbuf->tso_segsz >= TX_MSS_MIN ? mbuf->tso_segsz
-                                                          : TX_MSS_MIN;
-               max_sges = HINIC3_NONTSO_PKT_MAX_SGE - 1;
-               limit_len = adjust_mss + wqe_info->payload_offset;
-
-               for (i = 0; (i < max_sges) && (total_len < limit_len); i++) {
-                       total_len += mbuf->data_len;
-                       mbuf_pre = mbuf;
-                       mbuf = mbuf->next;
-               }
+       /* TSO SGE <= HINIC3_NONTSO_PKT_MAX_SGE: no processing */
+       if (likely(mbuf->nb_segs <= HINIC3_NONTSO_PKT_MAX_SGE))
+               return true;
 
-               /* Each continues 38 mbufs segmust do one check. */
-               while (left_sges >= HINIC3_NONTSO_PKT_MAX_SGE) {
-                       if (total_len >= limit_len) {
-                               /* Update the limit len. */
-                               limit_len = adjust_mss;
-                               /* Update checked len. */
-                               checked_len += first_len;
-                               /* Record the first len. */
-                               first_len = mbuf_first->data_len;
-                               /* First mbuf move to the next. */
-                               mbuf_first = mbuf_first->next;
-                               /* Update total len. */
-                               total_len -= first_len;
-                               left_sges--;
-                               i--;
-                               for (;
-                                    (i < max_sges) && (total_len < limit_len);
-                                    i++) {
-                                       total_len += mbuf->data_len;
-                                       mbuf_pre = mbuf;
-                                       mbuf = mbuf->next;
-                               }
-                       } else {
-                               /* Try to copy if not valid. */
-                               checked_len += (total_len - mbuf_pre->data_len);
+       adjust_mss = mbuf->tso_segsz >= TX_MSS_MIN ? mbuf->tso_segsz : 
TX_MSS_MIN;
 
-                               left_len = mbuf_head->pkt_len - checked_len;
-                               if (left_len > HINIC3_COPY_MBUF_SIZE)
-                                       return false;
-                               wqe_info->sge_cnt = 
(uint16_t)(mbuf_head->nb_segs +
-                                                         i - left_sges);
-                               wqe_info->cpy_mbuf_cnt = 1;
+       /* TSO SGE > HINIC3_TSO_PKT_MAX_SGE: skip MSS check, directly trigger 
copy */
+       if (unlikely(mbuf->nb_segs > HINIC3_TSO_PKT_MAX_SGE))
+               goto copy;
 
-                               return true;
+       /* Check sum of 38 SGEs < MSS (First segment < header + MSS) */
+       limit_len = adjust_mss + wqe_info->payload_offset;
+       mbuf_pkt = mbuf;
+       while (mbuf_pkt) {
+               window_len += mbuf_pkt->data_len;
+               i++;
+               mbuf_pkt = mbuf_pkt->next;
+
+               if (i > HINIC3_NONTSO_PKT_MAX_SGE)
+                       goto copy;
+
+               if (window_len >= limit_len) {
+                       if (limit_len == adjust_mss + wqe_info->payload_offset) 
{
+                               window_len -= limit_len;
+                               limit_len = adjust_mss;
                        }
-               } /**< End of while. */
+                       window_len %= adjust_mss;
+                       i = (window_len == 0) ? 0 : 1;
+               }
+       }
+       return true;
+
+copy:
+       mbuf_pkt = mbuf;
+       for (i = 0; i < HINIC3_NON_COPY_SGE_NUM; i++) {
+               no_copy_total_len += mbuf_pkt->data_len;
+               mbuf_pkt = mbuf_pkt->next;
+       }
+
+       if (unlikely(mbuf->pkt_len - no_copy_total_len >
+                    HINIC3_TSO_MBUF_NUM_MAX * HINIC3_COPY_MBUF_SIZE)) {
+               copy_mbuf_num = HINIC3_TSO_MBUF_NUM_MAX;
+               /* The len of first (HINIC3_TSO_PKT_MAX_SGE - 1) mbufs + last
+                * one (last_cpy_mbuf_usable) = header + N * MSS
+                */
+               total_used_len = no_copy_total_len - wqe_info->payload_offset +
+                       (HINIC3_TSO_MBUF_NUM_MAX - 1) * HINIC3_COPY_MBUF_SIZE;
+               wqe_info->last_cpy_mbuf_usable = adjust_mss - total_used_len % 
adjust_mss;
+       } else {
+               copy_mbuf_num = (mbuf->pkt_len - no_copy_total_len +
+                        HINIC3_COPY_MBUF_SIZE - 1) / HINIC3_COPY_MBUF_SIZE;
        }
 
-       wqe_info->sge_cnt = mbuf_head->nb_segs;
+       /* Total SGE = 28 normal SGEs + copy mbufs */
+       wqe_info->sge_cnt = HINIC3_NON_COPY_SGE_NUM + copy_mbuf_num;
+       wqe_info->cpy_mbuf_cnt = copy_mbuf_num;
 
        return true;
 }
 
 static int
-hinic3_non_tso_pkt_pre_process(struct rte_mbuf *mbuf, struct hinic3_wqe_info 
*wqe_info)
+hinic3_non_tso_pkt_pre_process(struct rte_mbuf *mbuf, struct hinic3_wqe_info 
*wqe_info,
+                              uint32_t non_tso_max_pkt_len)
 {
        struct rte_mbuf *mbuf_pkt = mbuf;
        uint32_t total_len = 0;
-       uint16_t i;
+       uint16_t i, copy_mbuf_num = 0;
 
        if (likely(HINIC3_NONTSO_SEG_NUM_VALID(mbuf->nb_segs)))
                return 0;
 
-       /* Non-tso packet length must less than 64KB. */
-       if (unlikely(mbuf->pkt_len > MAX_SINGLE_SGE_SIZE))
+       /* Non-tso packet length must less than HINIC3_MAX_JUMBO_FRAME_SIZE */
+       if (unlikely(mbuf->pkt_len > non_tso_max_pkt_len))
                return -EINVAL;
-
-       /*
-        * Mbuf number of non-tso packet must less than the sge number
-        * that nic can support. The excess part will be copied to another
-        * mbuf.
-        */
-       for (i = 0; i < (HINIC3_NONTSO_PKT_MAX_SGE - 1); i++) {
+       for (i = 0; i < HINIC3_NON_COPY_SGE_NUM; i++) {
                total_len += mbuf_pkt->data_len;
                mbuf_pkt = mbuf_pkt->next;
        }
 
-       /*
-        * Max copy mbuf size is 4KB, packet will be dropped directly,
-        * if total copy length is more than it.
-        */
-       if ((total_len + HINIC3_COPY_MBUF_SIZE) < mbuf->pkt_len)
+       /* Calculate required mbuf number */
+       copy_mbuf_num = (mbuf->pkt_len - total_len +
+                        HINIC3_COPY_MBUF_SIZE - 1) / HINIC3_COPY_MBUF_SIZE;
+       if (copy_mbuf_num > HINIC3_NONTSO_MBUF_NUM_MAX)
                return -EINVAL;
 
-       wqe_info->sge_cnt = HINIC3_NONTSO_PKT_MAX_SGE;
-       wqe_info->cpy_mbuf_cnt = 1;
+       /* Total SGE = 28 normal SGEs + copy mbufs */
+       wqe_info->sge_cnt = HINIC3_NON_COPY_SGE_NUM + copy_mbuf_num;
+       wqe_info->cpy_mbuf_cnt = copy_mbuf_num;
 
        return 0;
 }
@@ -608,7 +607,7 @@ hinic3_non_tso_pkt_pre_process(struct rte_mbuf *mbuf, 
struct hinic3_wqe_info *wq
  */
 static int
 hinic3_get_tx_offload(struct hinic3_nic_dev *nic_dev, struct rte_mbuf *mbuf,
-                     struct hinic3_wqe_info *wqe_info)
+                     struct hinic3_wqe_info *wqe_info, uint32_t 
non_tso_max_pkt_len)
 {
        uint64_t ol_flags = mbuf->ol_flags;
        uint16_t inner_l3_offset = 0;
@@ -619,7 +618,7 @@ hinic3_get_tx_offload(struct hinic3_nic_dev *nic_dev, 
struct rte_mbuf *mbuf,
        /* Check if the packet set available offload flags. */
        if (!(ol_flags & HINIC3_TX_OFFLOAD_MASK)) {
                wqe_info->offload = 0;
-               return hinic3_non_tso_pkt_pre_process(mbuf, wqe_info);
+               return hinic3_non_tso_pkt_pre_process(mbuf, wqe_info, 
non_tso_max_pkt_len);
        }
 
        wqe_info->offload = 1;
@@ -629,7 +628,7 @@ hinic3_get_tx_offload(struct hinic3_nic_dev *nic_dev, 
struct rte_mbuf *mbuf,
 
        /* Non-tso mbuf only check sge num. */
        if (likely(!(mbuf->ol_flags & HINIC3_PKT_TX_TCP_SEG)))
-               return hinic3_non_tso_pkt_pre_process(mbuf, wqe_info);
+               return hinic3_non_tso_pkt_pre_process(mbuf, wqe_info, 
non_tso_max_pkt_len);
 
        /* Tso mbuf. */
        wqe_info->payload_offset =
@@ -674,33 +673,76 @@ hinic3_alloc_cpy_mbuf(struct hinic3_nic_dev *nic_dev)
  * The address of the copied mbuf.
  */
 static void *
-hinic3_copy_tx_mbuf(struct hinic3_nic_dev *nic_dev, struct rte_mbuf *mbuf,
-                   uint16_t sge_cnt)
+hinic3_copy_tx_mbuf_multi(struct hinic3_nic_dev *nic_dev,
+                         struct rte_mbuf *mbuf, struct hinic3_wqe_info 
*wqe_info)
 {
-       struct rte_mbuf *dst_mbuf;
-       uint32_t offset = 0;
-       uint16_t i;
+       uint8_t i;
+       uint32_t remaining_len, dst_mbuf_space, copy_size, copy_offset = 0;
+       struct rte_mbuf *prev_mbuf = NULL;
+       struct rte_mbuf *head_mbuf = NULL;
+       struct rte_mbuf *cur_mbuf;
 
        if (unlikely(!nic_dev->cpy_mpool))
                return NULL;
 
-       dst_mbuf = hinic3_alloc_cpy_mbuf(nic_dev);
-       if (unlikely(!dst_mbuf))
-               return NULL;
+       /* Allocate all copy mbufs and build linked list */
+       for (i = 0; i < wqe_info->cpy_mbuf_cnt; i++) {
+               cur_mbuf = hinic3_alloc_cpy_mbuf(nic_dev);
+               if (unlikely(!cur_mbuf))
+                       goto err_free;
+
+               cur_mbuf->data_off = 0;
+               cur_mbuf->data_len = 0;
+               cur_mbuf->pkt_len = mbuf->pkt_len;
+               cur_mbuf->next = NULL;
+
+               if (prev_mbuf == NULL)
+                       head_mbuf = cur_mbuf;
+               else
+                       prev_mbuf->next = cur_mbuf;
+               prev_mbuf = cur_mbuf;
+       }
 
-       dst_mbuf->data_off = 0;
-       dst_mbuf->data_len = 0;
-       for (i = 0; i < sge_cnt; i++) {
-               memcpy((uint8_t *)dst_mbuf->buf_addr + offset,
-                          (uint8_t *)mbuf->buf_addr + mbuf->data_off,
-                          mbuf->data_len);
-               dst_mbuf->data_len += mbuf->data_len;
-               offset += mbuf->data_len;
+       /* Copy data to mbufs - mbuf already points to first SGE to copy */
+       cur_mbuf = head_mbuf;
+       while (mbuf != NULL) {
+               remaining_len = mbuf->data_len;
+               while (remaining_len > 0 && cur_mbuf != NULL) {
+                       dst_mbuf_space = HINIC3_COPY_MBUF_SIZE - copy_offset;
+                       copy_size = RTE_MIN(remaining_len, dst_mbuf_space);
+
+                       rte_memcpy((uint8_t *)cur_mbuf->buf_addr + copy_offset,
+                                  (uint8_t *)mbuf->buf_addr + mbuf->data_off,
+                                  copy_size);
+
+                       cur_mbuf->data_len += copy_size;
+                       copy_offset += copy_size;
+                       remaining_len -= copy_size;
+
+                       if (copy_offset >= HINIC3_COPY_MBUF_SIZE) {
+                               copy_offset = 0;
+                               cur_mbuf = cur_mbuf->next;
+                       }
+               }
                mbuf = mbuf->next;
        }
-       dst_mbuf->pkt_len = dst_mbuf->data_len;
 
-       return dst_mbuf;
+       /* all copy_mbuf cann't store packet data, cut off last mbuf, ensure
+        * the len of all mbuf = header + N * MSS
+        */
+       if (unlikely(wqe_info->last_cpy_mbuf_usable != 0)) {
+               cur_mbuf = head_mbuf;
+               for (i = 0; i < wqe_info->cpy_mbuf_cnt - 1; i++)
+                       cur_mbuf = cur_mbuf->next;
+               cur_mbuf->data_len = wqe_info->last_cpy_mbuf_usable;
+       }
+
+       return head_mbuf;
+
+err_free:
+       /* Free all allocated mbufs on error */
+       hinic3_free_cpy_mbuf(nic_dev, head_mbuf);
+       return NULL;
 }
 
 /**
@@ -726,9 +768,9 @@ hinic3_mbuf_dma_map_sge(struct hinic3_txq *txq, struct 
rte_mbuf *mbuf,
        struct hinic3_sq_wqe_desc *wqe_desc = wqe_combo->hdr;
        struct hinic3_sq_bufdesc *buf_desc = wqe_combo->bds_head;
        uint16_t nb_segs = wqe_info->sge_cnt - wqe_info->cpy_mbuf_cnt;
-       uint16_t real_segs = mbuf->nb_segs;
        rte_iova_t dma_addr;
        uint32_t i;
+       uint8_t mbuf_idx;
 
        for (i = 0; i < nb_segs; i++) {
                if (unlikely(mbuf == NULL)) {
@@ -767,40 +809,34 @@ hinic3_mbuf_dma_map_sge(struct hinic3_txq *txq, struct 
rte_mbuf *mbuf,
                mbuf = mbuf->next;
        }
 
-       /* For now: support over 38 sge, copy the last 2 mbuf. */
        if (unlikely(wqe_info->cpy_mbuf_cnt != 0)) {
                /*
                 * Copy invalid mbuf segs to a valid buffer, lost performance.
                 */
                txq->txq_stats.cpy_pkts += 1;
-               mbuf = hinic3_copy_tx_mbuf(txq->nic_dev, mbuf,
-                                          real_segs - nb_segs);
+               mbuf = hinic3_copy_tx_mbuf_multi(txq->nic_dev, mbuf, wqe_info);
                if (unlikely(!mbuf))
                        return -EINVAL;
 
                txq->tx_info[wqe_info->pi].cpy_mbuf = mbuf;
 
-               /* Deal with the last mbuf. */
-               dma_addr = rte_mbuf_data_iova(mbuf);
-               if (unlikely(mbuf->data_len == 0)) {
-                       txq->txq_stats.sge_len0++;
-                       return -EINVAL;
-               }
-               /*
-                * Parts of wqe is in sq bottom while parts
-                * of wqe is in sq head.
-                */
-               if (i == 0) {
-                       wqe_desc->hi_addr =
-                               hinic3_hw_be32(upper_32_bits(dma_addr));
-                       wqe_desc->lo_addr =
-                               hinic3_hw_be32(lower_32_bits(dma_addr));
-                       wqe_desc->ctrl_len = mbuf->data_len;
-               } else {
-                       if (unlikely(((uint64_t)buf_desc == 
txq->sq_bot_sge_addr)))
+               /* Set DMA descriptors for all copy mbufs */
+               for (mbuf_idx = 0; mbuf_idx < wqe_info->cpy_mbuf_cnt; 
mbuf_idx++) {
+                       dma_addr = rte_mbuf_data_iova(mbuf);
+                       if (unlikely(mbuf->data_len == 0)) {
+                               txq->txq_stats.sge_len0++;
+                               hinic3_free_cpy_mbuf(txq->nic_dev,
+                                                   
txq->tx_info[wqe_info->pi].cpy_mbuf);
+                               txq->tx_info[wqe_info->pi].cpy_mbuf = NULL;
+                               return -EINVAL;
+                       }
+
+                       if (unlikely((uint64_t)buf_desc == 
txq->sq_bot_sge_addr))
                                buf_desc = (struct hinic3_sq_bufdesc 
*)txq->sq_head_addr;
 
                        hinic3_set_buf_desc(buf_desc, dma_addr, mbuf->data_len);
+                       buf_desc++;
+                       mbuf = mbuf->next;
                }
        }
 
@@ -901,7 +937,8 @@ hinic3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, 
uint16_t nb_pkts)
        /* Tx loop routine. */
        for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
                mbuf_pkt = *tx_pkts++;
-               if (unlikely(hinic3_get_tx_offload(txq->nic_dev, mbuf_pkt, 
&wqe_info))) {
+               if (unlikely(hinic3_get_tx_offload(txq->nic_dev, mbuf_pkt, 
&wqe_info,
+                                                  txq->non_tso_max_pkt_len))) {
                        txq->txq_stats.offload_errors++;
                        break;
                }
diff --git a/drivers/net/hinic3/hinic3_tx.h b/drivers/net/hinic3/hinic3_tx.h
index e0ed9908ad..5d4101630e 100644
--- a/drivers/net/hinic3/hinic3_tx.h
+++ b/drivers/net/hinic3/hinic3_tx.h
@@ -6,12 +6,18 @@
 #define _HINIC3_TX_H_
 
 #define MAX_SINGLE_SGE_SIZE             65536
-#define HINIC3_NONTSO_PKT_MAX_SGE       32 /**< non-tso max sge 32. */
+#define HINIC3_NONTSO_PKT_MAX_SGE       38 /**< non-tso max sge 38. */
 #define HINIC3_NONTSO_SEG_NUM_VALID(num) ((num) <= HINIC3_NONTSO_PKT_MAX_SGE)
 
-#define HINIC3_TSO_PKT_MAX_SGE         127 /**< tso max sge 127. */
+#define HINIC3_TSO_PKT_MAX_SGE         255 /**< tso max sge 255. */
 #define HINIC3_TSO_SEG_NUM_INVALID(num) ((num) > HINIC3_TSO_PKT_MAX_SGE)
 
+/* Non-copy SGE configuration: 28 SGEs are not copied */
+#define HINIC3_NON_COPY_SGE_NUM        28
+#define HINIC3_NONTSO_MBUF_NUM_MAX \
+       (HINIC3_NONTSO_PKT_MAX_SGE - HINIC3_NON_COPY_SGE_NUM)
+#define HINIC3_TSO_MBUF_NUM_MAX                        (HINIC3_TSO_PKT_MAX_SGE 
- HINIC3_NON_COPY_SGE_NUM)
+
 /* Tx wqe queue info */
 struct hinic3_queue_info {
        uint8_t pri;
@@ -57,7 +63,7 @@ struct hinic3_wqe_info {
        uint16_t pi;
 
        uint16_t wqebb_cnt;
-       uint16_t rsvd2; /**< Reserved field 2. */
+       uint16_t last_cpy_mbuf_usable;
 
        struct hinic3_queue_info queue_info;
        struct hinic3_offload_info offload_info;
@@ -375,7 +381,7 @@ struct __rte_cache_aligned hinic3_txq {
        uint64_t sq_bot_sge_addr;
        uint32_t cos;
        uint8_t tx_wqe_compact_task;
-       uint8_t rsvd[3];
+       uint32_t non_tso_max_pkt_len;
        struct hinic3_txq_stats txq_stats;
 #ifdef HINIC3_XSTAT_PROF_TX
        uint64_t prof_tx_end_tsc;
-- 
2.33.0


Reply via email to