LCOV - code coverage report
Current view: top level - drivers/net/sxe2 - sxe2_txrx_poll.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 815 0.0 %
Date: 2026-08-01 17:54:00 Functions: 0 17 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 352 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <rte_common.h>
       6                 :            : #include <rte_net.h>
       7                 :            : #include <rte_vect.h>
       8                 :            : #include <rte_malloc.h>
       9                 :            : #include <rte_memzone.h>
      10                 :            : #include <ethdev_driver.h>
      11                 :            : #include "sxe2_osal.h"
      12                 :            : #include "sxe2_txrx_common.h"
      13                 :            : #include "sxe2_txrx_vec_common.h"
      14                 :            : #include "sxe2_txrx_poll.h"
      15                 :            : #include "sxe2_txrx.h"
      16                 :            : #include "sxe2_txrx_vec.h"
      17                 :            : #include "sxe2_queue.h"
      18                 :            : #include "sxe2_ethdev.h"
      19                 :            : #include "sxe2_common_log.h"
      20                 :            : #include "sxe2_cmd_chnl.h"
      21                 :            : 
      22                 :            : static __rte_always_inline int32_t
      23                 :          0 : sxe2_tx_bufs_free(struct sxe2_tx_queue *txq)
      24                 :            : {
      25                 :          0 :         struct sxe2_tx_buffer *buffer;
      26                 :          0 :         struct rte_mbuf *mbuf;
      27                 :          0 :         struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX];
      28                 :          0 :         int32_t ret;
      29                 :          0 :         uint32_t i;
      30                 :          0 :         uint16_t rs_thresh;
      31                 :          0 :         uint16_t free_num;
      32                 :          0 :         if ((txq->desc_ring[txq->next_dd].wb.dd &
      33                 :            :                      rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_MASK)) !=
      34                 :            :                      rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE)) {
      35                 :          0 :                 ret = 0;
      36                 :          0 :                 goto l_end;
      37                 :            :         }
      38                 :          0 :         rs_thresh = txq->rs_thresh;
      39                 :          0 :         buffer = &txq->buffer_ring[txq->next_dd - rs_thresh + 1];
      40   [ #  #  #  # ]:          0 :         if (txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) {
      41   [ #  #  #  # ]:          0 :                 if (likely(rs_thresh <= SXE2_TX_FREE_BUFFER_SIZE_MAX)) {
      42                 :          0 :                         mbuf = buffer[0].mbuf;
      43                 :          0 :                         mbuf_free_arr[0] = mbuf;
      44                 :          0 :                         free_num = 1;
      45   [ #  #  #  # ]:          0 :                         for (i = 1; i < rs_thresh; ++i) {
      46                 :          0 :                                 mbuf = buffer[i].mbuf;
      47   [ #  #  #  # ]:          0 :                                 if (likely(mbuf->pool == mbuf_free_arr[0]->pool)) {
      48                 :          0 :                                         mbuf_free_arr[free_num] = mbuf;
      49                 :          0 :                                         free_num++;
      50                 :            :                                 } else {
      51   [ #  #  #  # ]:          0 :                                         rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
      52                 :            :                                                                 (void *)mbuf_free_arr, free_num);
      53                 :          0 :                                         mbuf_free_arr[0] = mbuf;
      54                 :          0 :                                         free_num = 1;
      55                 :            :                                 }
      56                 :            :                         }
      57   [ #  #  #  # ]:          0 :                         rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
      58                 :            :                                                 (void *)mbuf_free_arr, free_num);
      59                 :            :                 } else {
      60   [ #  #  #  # ]:          0 :                         for (i = 0; i < rs_thresh; ++i, ++buffer) {
      61   [ #  #  #  # ]:          0 :                                 rte_mempool_put(buffer->mbuf->pool, buffer->mbuf);
      62                 :          0 :                                 buffer->mbuf = NULL;
      63                 :            :                         }
      64                 :            :                 }
      65                 :            :         } else {
      66   [ #  #  #  # ]:          0 :                 for (i = 0; i < rs_thresh; ++i, ++buffer) {
      67                 :          0 :                         mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
      68                 :          0 :                                 if (mbuf != NULL)
      69   [ #  #  #  # ]:          0 :                                         rte_mempool_put(mbuf->pool, mbuf);
      70                 :          0 :                         buffer->mbuf = NULL;
      71                 :            :                 }
      72                 :            :         }
      73                 :          0 :         txq->desc_free_num += rs_thresh;
      74                 :          0 :         txq->next_dd       += rs_thresh;
      75   [ #  #  #  # ]:          0 :         if (txq->next_dd >= txq->ring_depth)
      76                 :          0 :                 txq->next_dd = rs_thresh - 1;
      77                 :            :         ret = rs_thresh;
      78                 :          0 : l_end:
      79                 :          0 :         return ret;
      80                 :            : }
      81                 :            : 
      82                 :          0 : static inline int32_t sxe2_tx_cleanup(struct sxe2_tx_queue *txq)
      83                 :            : {
      84                 :          0 :         int32_t ret = 0;
      85                 :          0 :         volatile union sxe2_tx_data_desc *desc_ring = txq->desc_ring;
      86                 :          0 :         struct sxe2_tx_buffer *buffer_ring = txq->buffer_ring;
      87                 :          0 :         uint16_t ring_depth = txq->ring_depth;
      88                 :          0 :         uint16_t next_clean = txq->next_clean;
      89                 :          0 :         uint16_t clean_last;
      90                 :          0 :         uint16_t clean_num;
      91                 :            : 
      92                 :          0 :         clean_last = next_clean + txq->rs_thresh;
      93         [ #  # ]:          0 :         if (clean_last >= ring_depth)
      94                 :          0 :                 clean_last = clean_last - ring_depth;
      95                 :            : 
      96                 :          0 :         clean_last = buffer_ring[clean_last].last_id;
      97                 :          0 :         if (rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE) !=
      98         [ #  # ]:          0 :                 (txq->desc_ring[clean_last].wb.dd & rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_MASK))) {
      99                 :          0 :                 PMD_LOG_DEBUG(TX, "desc[%u] is not done.port_id=%u queue_id=%u val=0x%" PRIx64,
     100                 :            :                                                  clean_last, txq->port_id,
     101                 :            :                         txq->queue_id, txq->desc_ring[clean_last].wb.dd);
     102                 :          0 :                 ret = -1;
     103                 :          0 :                 goto l_end;
     104                 :            :         }
     105                 :            : 
     106         [ #  # ]:          0 :         if (clean_last > next_clean)
     107                 :          0 :                 clean_num = clean_last - next_clean;
     108                 :            :         else
     109                 :          0 :                 clean_num = ring_depth - next_clean + clean_last;
     110                 :            : 
     111                 :          0 :         desc_ring[clean_last].wb.dd = 0;
     112                 :            : 
     113                 :          0 :         txq->next_clean = clean_last;
     114                 :          0 :         txq->desc_free_num += clean_num;
     115                 :            : 
     116                 :          0 :         ret = 0;
     117                 :            : 
     118                 :          0 : l_end:
     119                 :          0 :         return ret;
     120                 :            : }
     121                 :            : 
     122                 :          0 : static int32_t sxe2_tx_done_cleanup_simple(struct sxe2_tx_queue *txq, uint32_t free_cnt)
     123                 :            : {
     124                 :          0 :         uint32_t free_cnt_align;
     125                 :          0 :         uint32_t free_cnt_once;
     126                 :          0 :         uint32_t i;
     127                 :            : 
     128   [ #  #  #  # ]:          0 :         if (free_cnt == 0 || free_cnt > txq->ring_depth)
     129                 :          0 :                 free_cnt = txq->ring_depth;
     130                 :            : 
     131                 :          0 :         free_cnt_align = free_cnt - (free_cnt % txq->rs_thresh);
     132         [ #  # ]:          0 :         for (i = 0; i < free_cnt_align; i += free_cnt_once) {
     133         [ #  # ]:          0 :                 if ((txq->ring_depth - txq->desc_free_num) < txq->rs_thresh)
     134                 :            :                         break;
     135                 :            : 
     136         [ #  # ]:          0 :                 free_cnt_once = sxe2_tx_bufs_free(txq);
     137         [ #  # ]:          0 :                 if (free_cnt_once == 0)
     138                 :            :                         break;
     139                 :            :         }
     140                 :            : 
     141                 :          0 :         return i;
     142                 :            : }
     143                 :            : 
     144                 :          0 : static int32_t sxe2_tx_done_cleanup_normal(struct sxe2_tx_queue *txq, uint32_t free_cnt)
     145                 :            : {
     146                 :          0 :         struct sxe2_tx_buffer *buffer_ring = txq->buffer_ring;
     147                 :          0 :         int32_t ret;
     148                 :          0 :         uint16_t clean_last_idx, clean_idx;
     149                 :          0 :         uint16_t clean_last, clean_once;
     150                 :          0 :         uint16_t pkt_cnt, i;
     151                 :            : 
     152   [ #  #  #  # ]:          0 :         if (txq->desc_free_num == 0 && sxe2_tx_cleanup(txq) != 0) {
     153                 :          0 :                 ret = 0;
     154                 :          0 :                 goto l_end;
     155                 :            :         }
     156                 :            : 
     157         [ #  # ]:          0 :         if (free_cnt == 0)
     158                 :          0 :                 free_cnt = txq->ring_depth;
     159                 :            : 
     160                 :          0 :         clean_last_idx = txq->next_use;
     161                 :          0 :         clean_idx = buffer_ring[clean_last_idx].next_id;
     162                 :          0 :         clean_once = txq->desc_free_num;
     163                 :          0 :         clean_last = txq->desc_free_num;
     164                 :            : 
     165         [ #  # ]:          0 :         for (pkt_cnt = 0; pkt_cnt < free_cnt;) {
     166                 :          0 :                 for (i = 0; ((i < clean_once) &&
     167   [ #  #  #  #  :          0 :                              (pkt_cnt < free_cnt) &&
                   #  # ]
     168                 :          0 :                              clean_idx != clean_last_idx); ++i) {
     169         [ #  # ]:          0 :                         if (buffer_ring[clean_idx].mbuf != NULL) {
     170                 :          0 :                                 rte_pktmbuf_free_seg(buffer_ring[clean_idx].mbuf);
     171                 :          0 :                                 buffer_ring[clean_idx].mbuf = NULL;
     172         [ #  # ]:          0 :                                 if (buffer_ring[clean_idx].last_id == clean_idx)
     173                 :          0 :                                         pkt_cnt++;
     174                 :            :                         }
     175                 :          0 :                         clean_idx = buffer_ring[clean_idx].next_id;
     176                 :            :                 }
     177                 :            : 
     178   [ #  #  #  # ]:          0 :                 if ((txq->rs_thresh > (txq->ring_depth - txq->desc_free_num)) ||
     179                 :            :                     clean_idx == clean_last_idx)
     180                 :            :                         break;
     181                 :            : 
     182         [ #  # ]:          0 :                 if (pkt_cnt < free_cnt) {
     183         [ #  # ]:          0 :                         if (sxe2_tx_cleanup(txq) != 0)
     184                 :            :                                 break;
     185                 :            : 
     186                 :          0 :                         clean_once = txq->desc_free_num - clean_last;
     187                 :          0 :                         clean_last = txq->desc_free_num;
     188                 :            :                 }
     189                 :            :         }
     190                 :            : 
     191                 :          0 :         ret = pkt_cnt;
     192                 :          0 : l_end:
     193                 :          0 :         return ret;
     194                 :            : }
     195                 :            : 
     196                 :          0 : int32_t sxe2_tx_done_cleanup(void *tx_queue, uint32_t free_cnt)
     197                 :            : {
     198                 :          0 :         struct sxe2_tx_queue *txq = (struct sxe2_tx_queue *)tx_queue;
     199                 :          0 :         struct sxe2_adapter *adapter;
     200                 :          0 :         int32_t ret;
     201                 :            : 
     202         [ #  # ]:          0 :         if (txq == NULL) {
     203                 :          0 :                 ret = 0;
     204                 :          0 :                 goto l_end;
     205                 :            :         }
     206                 :            : 
     207                 :          0 :         adapter = txq->vsi->adapter;
     208         [ #  # ]:          0 :         if (adapter->q_ctxt.tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK)
     209                 :            :                 ret = -ENOTSUP;
     210         [ #  # ]:          0 :         else if (adapter->q_ctxt.tx_mode_flags & SXE2_TX_MODE_SIMPLE_BATCH)
     211                 :          0 :                 ret = sxe2_tx_done_cleanup_simple(txq, free_cnt);
     212                 :            :         else
     213                 :          0 :                 ret = sxe2_tx_done_cleanup_normal(txq, free_cnt);
     214                 :            : 
     215                 :          0 :         PMD_LOG_DEBUG(TX, "TX cleanup done desc queue_id=%u free_cnt=%d.",
     216                 :            :                                 txq->queue_id, ret);
     217                 :            : 
     218                 :          0 : l_end:
     219                 :          0 :         return ret;
     220                 :            : }
     221                 :            : 
     222                 :            : static __rte_always_inline uint32_t
     223                 :            : sxe2_tx_pkt_data_desc_count(struct rte_mbuf *tx_pkt)
     224                 :            : {
     225                 :            :         struct rte_mbuf *m_seg = tx_pkt;
     226                 :            :         uint32_t count = 0;
     227                 :            : 
     228         [ #  # ]:          0 :         while (m_seg != NULL) {
     229                 :          0 :                 count += SXE2_DIV_ROUND_UP(m_seg->data_len,
     230                 :            :                                 SXE2_TX_MAX_DATA_NUM_PER_DESC);
     231                 :          0 :                 m_seg = m_seg->next;
     232                 :            :         }
     233                 :            : 
     234                 :          0 :         return count;
     235                 :            : }
     236                 :            : 
     237                 :          0 : static __rte_always_inline void sxe2_tx_desc_tunneling_params_fill(uint64_t offloads,
     238                 :            :                                         union sxe2_tx_offload_info ol_info,
     239                 :            :                                         uint32_t *desc_tunneling_params)
     240                 :            : {
     241                 :          0 :         if (offloads & RTE_MBUF_F_TX_OUTER_IP_CKSUM)
     242                 :            :                 *desc_tunneling_params |= SXE2_TX_CTXT_DESC_EIPT_IPV4;
     243         [ #  # ]:          0 :         else if (offloads & RTE_MBUF_F_TX_OUTER_IPV4)
     244                 :            :                 *desc_tunneling_params |= SXE2_TX_CTXT_DESC_EIPT_IPV4_NO_CSUM;
     245         [ #  # ]:          0 :         else if (offloads & RTE_MBUF_F_TX_OUTER_IPV6)
     246                 :          0 :                 *desc_tunneling_params |= SXE2_TX_CTXT_DESC_EIPT_IPV6;
     247                 :            : 
     248                 :          0 :         *desc_tunneling_params |=
     249                 :          0 :                         SXE2_TX_CTXT_DESC_EIPLEN_VAL(ol_info.outer_l3_len);
     250   [ #  #  #  # ]:          0 :         switch (offloads & RTE_MBUF_F_TX_TUNNEL_MASK) {
     251                 :            :         case RTE_MBUF_F_TX_TUNNEL_IPIP:
     252                 :            :                 break;
     253                 :          0 :         case RTE_MBUF_F_TX_TUNNEL_VXLAN:
     254                 :            :         case RTE_MBUF_F_TX_TUNNEL_VXLAN_GPE:
     255                 :            :         case RTE_MBUF_F_TX_TUNNEL_GTP:
     256                 :            :         case RTE_MBUF_F_TX_TUNNEL_GENEVE:
     257                 :          0 :                 *desc_tunneling_params |= SXE2_TX_CTXT_DESC_UDP_TUNNE;
     258                 :          0 :                 break;
     259                 :          0 :         case RTE_MBUF_F_TX_TUNNEL_GRE:
     260                 :          0 :                 *desc_tunneling_params |= SXE2_TX_CTXT_DESC_GRE_TUNNE;
     261                 :          0 :                 break;
     262                 :          0 :         default:
     263                 :          0 :                 PMD_LOG_ERR(TX, "Tunnel type [0x%" PRIx64 "] is not supported.",
     264                 :            :                             (uint64_t)(offloads & RTE_MBUF_F_TX_TUNNEL_MASK));
     265                 :          0 :                 return;
     266                 :            :         }
     267                 :          0 :         *desc_tunneling_params |= SXE2_TX_CTXT_DESC_NATLEN_VAL(ol_info.l2_len);
     268                 :          0 :         if (!(*desc_tunneling_params & SXE2_TX_CTXT_DESC_EIPT_NONE) &&
     269         [ #  # ]:          0 :                         (*desc_tunneling_params & SXE2_TX_CTXT_DESC_UDP_TUNNE) &&
     270         [ #  # ]:          0 :                         (offloads & RTE_MBUF_F_TX_OUTER_UDP_CKSUM)) {
     271                 :          0 :                 *desc_tunneling_params |= SXE2_TX_CTXT_DESC_L4T_CS_MASK;
     272                 :            :         }
     273                 :            : }
     274                 :            : 
     275                 :            : static __rte_always_inline void
     276                 :          0 : sxe2_tx_desc_checksum_fill(uint64_t offloads, uint32_t *desc_cmd, uint32_t *desc_offset,
     277                 :            :                 union sxe2_tx_offload_info ol_info)
     278                 :            : {
     279                 :          0 :         if (offloads & RTE_MBUF_F_TX_IP_CKSUM) {
     280                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_IIPT_IPV4_CSUM;
     281                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_IPLEN_VAL(ol_info.l3_len);
     282         [ #  # ]:          0 :         } else if (offloads & RTE_MBUF_F_TX_IPV4) {
     283                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_IIPT_IPV4;
     284                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_IPLEN_VAL(ol_info.l3_len);
     285         [ #  # ]:          0 :         } else if (offloads & RTE_MBUF_F_TX_IPV6) {
     286                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_IIPT_IPV6;
     287                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_IPLEN_VAL(ol_info.l3_len);
     288                 :            :         }
     289                 :            : 
     290         [ #  # ]:          0 :         if (offloads & RTE_MBUF_F_TX_TCP_SEG) {
     291                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_TCP;
     292                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
     293                 :          0 :                 goto l_end;
     294                 :            :         }
     295                 :            : 
     296         [ #  # ]:          0 :         if (offloads & RTE_MBUF_F_TX_UDP_SEG) {
     297                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_UDP;
     298                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
     299                 :          0 :                 goto l_end;
     300                 :            :         }
     301                 :            : 
     302   [ #  #  #  # ]:          0 :         switch (offloads & RTE_MBUF_F_TX_L4_MASK) {
     303                 :          0 :         case RTE_MBUF_F_TX_TCP_CKSUM:
     304                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_TCP;
     305                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
     306                 :          0 :                 break;
     307                 :          0 :         case RTE_MBUF_F_TX_SCTP_CKSUM:
     308                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_SCTP;
     309                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
     310                 :          0 :                 break;
     311                 :          0 :         case RTE_MBUF_F_TX_UDP_CKSUM:
     312                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_UDP;
     313                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
     314                 :          0 :                 break;
     315                 :            :         default:
     316                 :            : 
     317                 :            :                 break;
     318                 :            :         }
     319                 :            : 
     320                 :          0 : l_end:
     321                 :          0 :         return;
     322                 :            : }
     323                 :            : 
     324                 :          0 : static __rte_always_inline void sxe2_desc_tso_fill(struct rte_mbuf *tx_pkt,
     325                 :            :                                                    uint64_t *desc_type_cmd_tso_mss,
     326                 :            :                                                    union sxe2_tx_offload_info ol_info)
     327                 :            : {
     328                 :          0 :         uint32_t hdr_len;
     329                 :          0 :         uint32_t tso_len;
     330                 :            : 
     331                 :          0 :         if (!ol_info.l4_len) {
     332                 :          0 :                 PMD_LOG_DEBUG(TX, "TSO ERROR: L4 length is 0");
     333                 :          0 :                 goto l_end;
     334                 :            :         }
     335                 :          0 :         hdr_len = ol_info.l2_len + ol_info.l3_len + ol_info.l4_len;
     336         [ #  # ]:          0 :         if (tx_pkt->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK)
     337                 :          0 :                 hdr_len += ol_info.outer_l2_len + ol_info.outer_l3_len;
     338                 :            : 
     339                 :          0 :         tso_len = tx_pkt->pkt_len - hdr_len;
     340                 :          0 :         *desc_type_cmd_tso_mss |=
     341                 :            :                         ((uint64_t)SXE2_TX_CTXT_DESC_CMD_TSO << SXE2_TX_CTXT_DESC_CMD_SHIFT) |
     342                 :          0 :                         ((uint64_t)tso_len << SXE2_TX_CTXT_DESC_TSO_LEN_SHIFT) |
     343                 :          0 :                         ((uint64_t)tx_pkt->tso_segsz << SXE2_TX_CTXT_DESC_MSS_SHIFT);
     344                 :          0 : l_end:
     345                 :          0 :         return;
     346                 :            : }
     347                 :            : 
     348                 :          0 : static __rte_always_inline void sxe2_desc_ipsec_fill(struct rte_mbuf *tx_pkt,
     349                 :            :                         struct sxe2_tx_queue *txq, uint16_t *ipsec_offset,
     350                 :            :                         uint64_t *desc_type_cmd_tso_mss)
     351                 :            : {
     352                 :          0 :         struct sxe2_ipsec_pkt_metadata *md = NULL;
     353                 :          0 :         uint16_t ipsec_pkt_md_offset = txq->ipsec_pkt_md_offset;
     354                 :            : 
     355                 :          0 :         md = RTE_MBUF_DYNFIELD(tx_pkt, ipsec_pkt_md_offset, struct sxe2_ipsec_pkt_metadata *);
     356                 :          0 :         *ipsec_offset = md->esp_head_offset;
     357                 :          0 :         *desc_type_cmd_tso_mss |= SXE2_TX_CTXT_DESC_IPSEC_EN;
     358                 :          0 :         if (md->mode == SXE2_IPSEC_MODE_ONLY_ENCRYPT)
     359                 :          0 :                 *desc_type_cmd_tso_mss |= SXE2_TX_CTXT_DESC_IPSEC_MODE;
     360                 :            : 
     361         [ #  # ]:          0 :         if (md->algo == SXE2_IPSEC_ALGO_SM4_CBC_AND_SM3_96_HMAC)
     362                 :          0 :                 *desc_type_cmd_tso_mss |= SXE2_TX_CTXT_DESC_IPSEC_ENGINE;
     363                 :            : 
     364                 :          0 :         *desc_type_cmd_tso_mss |= (uint64_t)(md->sa_idx) << SXE2_TX_CTXT_DESC_IPSEC_SA_SHIFT;
     365                 :          0 : }
     366                 :            : 
     367                 :            : static __rte_always_inline uint64_t
     368                 :          0 : sxe2_tx_data_desc_build_cobt(uint32_t cmd, uint32_t offset, uint16_t buf_size, uint16_t l2tag)
     369                 :            : {
     370                 :          0 :         return rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DATA |
     371                 :            :                         (((uint64_t)cmd)      << SXE2_TX_DATA_DESC_CMD_SHIFT) |
     372                 :            :                         (((uint64_t)offset)   << SXE2_TX_DATA_DESC_OFFSET_SHIFT) |
     373                 :            :                         (((uint64_t)buf_size) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT) |
     374                 :            :                         (((uint64_t)l2tag)    << SXE2_TX_DATA_DESC_L2TAG1_SHIFT));
     375                 :            : }
     376                 :            : 
     377                 :          0 : uint16_t sxe2_tx_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
     378                 :            : {
     379                 :          0 :         struct sxe2_tx_queue *txq = tx_queue;
     380                 :          0 :         struct sxe2_tx_buffer *buffer_ring;
     381                 :          0 :         struct sxe2_tx_buffer *buffer;
     382                 :          0 :         struct sxe2_tx_buffer *next_buffer;
     383                 :          0 :         struct rte_mbuf *tx_pkt;
     384                 :          0 :         struct rte_mbuf *m_seg;
     385                 :          0 :         volatile union sxe2_tx_data_desc *desc_ring;
     386                 :          0 :         volatile union sxe2_tx_data_desc *desc;
     387                 :          0 :         volatile struct sxe2_tx_context_desc *ctxt_desc;
     388                 :          0 :         union sxe2_tx_offload_info ol_info;
     389                 :          0 :         struct sxe2_vsi *vsi = txq->vsi;
     390                 :          0 :         rte_iova_t buf_dma_addr;
     391                 :          0 :         uint64_t offloads;
     392                 :          0 :         uint64_t desc_type_cmd_tso_mss;
     393                 :          0 :         uint32_t desc_cmd;
     394                 :          0 :         uint32_t desc_offset;
     395                 :          0 :         uint32_t desc_tag;
     396                 :          0 :         uint32_t desc_tunneling_params;
     397                 :          0 :         uint16_t ipsec_offset;
     398                 :          0 :         uint16_t ctxt_desc_num;
     399                 :          0 :         uint32_t desc_sum_num;
     400                 :          0 :         uint16_t tx_num;
     401                 :          0 :         uint16_t seg_len;
     402                 :          0 :         uint16_t next_use;
     403                 :          0 :         uint16_t last_use;
     404                 :          0 :         uint16_t desc_l2tag2;
     405                 :            : 
     406                 :          0 :         buffer_ring = txq->buffer_ring;
     407                 :          0 :         desc_ring   = txq->desc_ring;
     408                 :          0 :         next_use    = txq->next_use;
     409                 :          0 :         buffer      = &buffer_ring[next_use];
     410                 :            : 
     411         [ #  # ]:          0 :         if (txq->desc_free_num < txq->free_thresh)
     412                 :          0 :                 (void)sxe2_tx_cleanup(txq);
     413                 :            : 
     414         [ #  # ]:          0 :         for (tx_num = 0; tx_num < nb_pkts; tx_num++) {
     415                 :          0 :                 tx_pkt = *tx_pkts++;
     416                 :          0 :                 desc_cmd              = 0;
     417                 :          0 :                 desc_offset           = 0;
     418                 :          0 :                 desc_tag              = 0;
     419                 :          0 :                 desc_tunneling_params = 0;
     420                 :          0 :                 ipsec_offset          = 0;
     421                 :          0 :                 offloads              = tx_pkt->ol_flags;
     422                 :          0 :                 ol_info.l2_len        = tx_pkt->l2_len;
     423                 :          0 :                 ol_info.l3_len        = tx_pkt->l3_len;
     424                 :          0 :                 ol_info.l4_len        = tx_pkt->l4_len;
     425                 :          0 :                 ol_info.tso_segsz     = tx_pkt->tso_segsz;
     426                 :          0 :                 ol_info.outer_l2_len  = tx_pkt->outer_l2_len;
     427                 :          0 :                 ol_info.outer_l3_len  = tx_pkt->outer_l3_len;
     428                 :            : 
     429                 :          0 :                 ctxt_desc_num = (offloads &
     430                 :          0 :                                 SXE2_TX_OFFLOAD_CTXT_NEEDCK_MASK) ? 1 : 0;
     431         [ #  # ]:          0 :                 if (unlikely(vsi->vsi_type == SXE2_VSI_T_DPDK_ESW))
     432                 :          0 :                         ctxt_desc_num = 1;
     433                 :            : 
     434         [ #  # ]:          0 :                 if (offloads & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG))
     435                 :          0 :                         desc_sum_num = sxe2_tx_pkt_data_desc_count(tx_pkt) + ctxt_desc_num;
     436                 :            :                 else
     437                 :          0 :                         desc_sum_num = tx_pkt->nb_segs + ctxt_desc_num;
     438                 :            : 
     439                 :          0 :                 last_use = next_use + desc_sum_num - 1;
     440         [ #  # ]:          0 :                 if (last_use >= txq->ring_depth)
     441                 :          0 :                         last_use = last_use - txq->ring_depth;
     442                 :            : 
     443         [ #  # ]:          0 :                 if (desc_sum_num > txq->desc_free_num) {
     444         [ #  # ]:          0 :                         if (unlikely(sxe2_tx_cleanup(txq) != 0))
     445                 :          0 :                                 goto l_cleanup_exit;
     446                 :            : 
     447         [ #  # ]:          0 :                         if (unlikely(desc_sum_num > txq->rs_thresh)) {
     448         [ #  # ]:          0 :                                 while (desc_sum_num > txq->desc_free_num) {
     449         [ #  # ]:          0 :                                         if (unlikely(sxe2_tx_cleanup(txq) != 0))
     450                 :          0 :                                                 goto l_cleanup_exit;
     451                 :            :                                 }
     452                 :            :                         }
     453                 :            :                 }
     454                 :            : 
     455   [ #  #  #  # ]:          0 :                 if ((offloads & RTE_MBUF_F_TX_TUNNEL_MASK) && ctxt_desc_num) {
     456                 :          0 :                         desc_offset |= SXE2_TX_DATA_DESC_MACLEN_VAL(ol_info.outer_l2_len);
     457         [ #  # ]:          0 :                         sxe2_tx_desc_tunneling_params_fill(offloads, ol_info,
     458                 :            :                                                 &desc_tunneling_params);
     459                 :            :                 } else {
     460                 :          0 :                         desc_offset |= SXE2_TX_DATA_DESC_MACLEN_VAL(ol_info.l2_len);
     461                 :            :                 }
     462                 :            : 
     463         [ #  # ]:          0 :                 if (offloads & SXE2_TX_OFFLOAD_CKSUM_MASK) {
     464         [ #  # ]:          0 :                         sxe2_tx_desc_checksum_fill(offloads, &desc_cmd,
     465                 :            :                                         &desc_offset, ol_info);
     466                 :            :                 }
     467                 :            : 
     468         [ #  # ]:          0 :                 if (offloads & (RTE_MBUF_F_TX_VLAN | RTE_MBUF_F_TX_QINQ)) {
     469                 :          0 :                         desc_cmd |= SXE2_TX_DATA_DESC_CMD_IL2TAG1;
     470                 :          0 :                         desc_tag = tx_pkt->vlan_tci;
     471                 :            :                 }
     472                 :            : 
     473         [ #  # ]:          0 :                 if (ctxt_desc_num) {
     474                 :          0 :                         ctxt_desc = (volatile struct sxe2_tx_context_desc *)
     475                 :          0 :                                                         &desc_ring[next_use];
     476                 :          0 :                         desc_l2tag2 = 0;
     477                 :          0 :                         desc_type_cmd_tso_mss = SXE2_TX_DESC_DTYPE_CTXT;
     478                 :            : 
     479                 :          0 :                         next_buffer = &buffer_ring[buffer->next_id];
     480         [ #  # ]:          0 :                         RTE_MBUF_PREFETCH_TO_FREE(next_buffer->mbuf);
     481                 :            : 
     482         [ #  # ]:          0 :                         if (buffer->mbuf) {
     483         [ #  # ]:          0 :                                 rte_pktmbuf_free_seg(buffer->mbuf);
     484                 :          0 :                                 buffer->mbuf = NULL;
     485                 :            :                         }
     486         [ #  # ]:          0 :                         if (offloads & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG))
     487         [ #  # ]:          0 :                                 sxe2_desc_tso_fill(tx_pkt,
     488                 :            :                                         &desc_type_cmd_tso_mss, ol_info);
     489         [ #  # ]:          0 :                         else if (offloads & RTE_MBUF_F_TX_IEEE1588_TMST)
     490                 :          0 :                                 desc_type_cmd_tso_mss |= SXE2_TX_CTXT_DESC_CMD_TSYN_MASK;
     491                 :            : 
     492         [ #  # ]:          0 :                         if (offloads & RTE_MBUF_F_TX_SEC_OFFLOAD) {
     493         [ #  # ]:          0 :                                 sxe2_desc_ipsec_fill(tx_pkt, txq, &ipsec_offset,
     494                 :            :                                                      &desc_type_cmd_tso_mss);
     495                 :            :                         }
     496                 :            : 
     497         [ #  # ]:          0 :                         if (offloads & RTE_MBUF_F_TX_QINQ) {
     498                 :          0 :                                 desc_l2tag2 = tx_pkt->vlan_tci_outer;
     499                 :          0 :                                 desc_type_cmd_tso_mss |= SXE2_TX_CTXT_DESC_CMD_IL2TAG2_MASK;
     500                 :            :                         }
     501         [ #  # ]:          0 :                         if (unlikely(vsi->vsi_type == SXE2_VSI_T_DPDK_ESW)) {
     502                 :          0 :                                 desc_type_cmd_tso_mss |=
     503                 :            :                                         (SXE2_TX_CTXT_DESC_CMD_SWTCH_VSI <<
     504                 :            :                                         SXE2_TX_CTXT_DESC_CMD_SHIFT);
     505                 :          0 :                                 desc_type_cmd_tso_mss |=
     506                 :          0 :                                         ((vsi->adapter->repr_priv_data->repr_vf_vsi_id & 0x3FFULL)
     507                 :          0 :                                         << SXE2_TX_CTXT_DESC_VSI_SHIFT);
     508                 :            :                         }
     509                 :            : 
     510                 :          0 :                         ctxt_desc->tunneling_params =
     511                 :            :                                 rte_cpu_to_le_32(desc_tunneling_params);
     512                 :          0 :                         ctxt_desc->l2tag2 = rte_cpu_to_le_16(desc_l2tag2);
     513                 :          0 :                         ctxt_desc->type_cmd_tso_mss = rte_cpu_to_le_64(desc_type_cmd_tso_mss);
     514                 :          0 :                         ctxt_desc->ipsec_offset = rte_cpu_to_le_16(ipsec_offset);
     515                 :            : 
     516                 :          0 :                         buffer->last_id = last_use;
     517                 :          0 :                         next_use        = buffer->next_id;
     518                 :          0 :                         buffer          = next_buffer;
     519                 :            :                 }
     520                 :            : 
     521                 :            :                 m_seg = tx_pkt;
     522                 :            : 
     523                 :          0 :                 do {
     524                 :          0 :                         desc = &desc_ring[next_use];
     525                 :          0 :                         next_buffer = &buffer_ring[buffer->next_id];
     526         [ #  # ]:          0 :                         RTE_MBUF_PREFETCH_TO_FREE(next_buffer->mbuf);
     527         [ #  # ]:          0 :                         if (buffer->mbuf) {
     528         [ #  # ]:          0 :                                 rte_pktmbuf_free_seg(buffer->mbuf);
     529                 :          0 :                                 buffer->mbuf = NULL;
     530                 :            :                         }
     531                 :            : 
     532                 :          0 :                         buffer->mbuf = m_seg;
     533                 :          0 :                         seg_len = m_seg->data_len;
     534                 :          0 :                         buf_dma_addr = rte_mbuf_data_iova(m_seg);
     535                 :          0 :                         while ((offloads & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG)) &&
     536         [ #  # ]:          0 :                                         unlikely(seg_len > SXE2_TX_MAX_DATA_NUM_PER_DESC)) {
     537                 :          0 :                                 desc->read.buf_addr = rte_cpu_to_le_64(buf_dma_addr);
     538                 :          0 :                                 desc->read.type_cmd_off_bsz_l2t =
     539                 :          0 :                                         sxe2_tx_data_desc_build_cobt(desc_cmd, desc_offset,
     540                 :            :                                                 SXE2_TX_MAX_DATA_NUM_PER_DESC,
     541                 :            :                                                 desc_tag);
     542                 :          0 :                                 buf_dma_addr += SXE2_TX_MAX_DATA_NUM_PER_DESC;
     543                 :          0 :                                 seg_len      -= SXE2_TX_MAX_DATA_NUM_PER_DESC;
     544                 :          0 :                                 buffer->last_id = last_use;
     545                 :          0 :                                 next_use        = buffer->next_id;
     546                 :          0 :                                 buffer          = next_buffer;
     547                 :          0 :                                 desc            = &desc_ring[next_use];
     548                 :          0 :                                 next_buffer     = &buffer_ring[buffer->next_id];
     549   [ #  #  #  # ]:          0 :                                 RTE_MBUF_PREFETCH_TO_FREE(next_buffer->mbuf);
     550                 :            :                         }
     551                 :            : 
     552                 :          0 :                         desc->read.buf_addr = rte_cpu_to_le_64(buf_dma_addr);
     553                 :          0 :                         desc->read.type_cmd_off_bsz_l2t =
     554                 :          0 :                                 sxe2_tx_data_desc_build_cobt(desc_cmd,
     555                 :            :                                         desc_offset, seg_len, desc_tag);
     556                 :            : 
     557                 :          0 :                         buffer->last_id = last_use;
     558                 :          0 :                         next_use        = buffer->next_id;
     559                 :          0 :                         buffer          = next_buffer;
     560                 :            : 
     561                 :          0 :                         m_seg = m_seg->next;
     562         [ #  # ]:          0 :                 } while (m_seg);
     563                 :            : 
     564                 :          0 :                 desc_cmd |= SXE2_TX_DATA_DESC_CMD_EOP;
     565                 :          0 :                 txq->desc_used_num += desc_sum_num;
     566                 :          0 :                 txq->desc_free_num -= desc_sum_num;
     567                 :            : 
     568         [ #  # ]:          0 :                 if (txq->desc_used_num >= txq->rs_thresh) {
     569                 :          0 :                         PMD_LOG_DEBUG(TX, "Tx pkts set RS bit."
     570                 :            :                                         "last_use=%u port_id=%u, queue_id=%u",
     571                 :            :                                         last_use, txq->port_id, txq->queue_id);
     572                 :          0 :                         desc_cmd |= SXE2_TX_DATA_DESC_CMD_RS;
     573                 :          0 :                         txq->desc_used_num = 0;
     574                 :            :                 }
     575                 :            : 
     576                 :          0 :                 desc->read.type_cmd_off_bsz_l2t |=
     577                 :          0 :                         rte_cpu_to_le_64(((uint64_t)desc_cmd) << SXE2_TX_DATA_DESC_CMD_SHIFT);
     578                 :            :         }
     579                 :          0 :         goto l_end_of_tx;
     580                 :            : 
     581                 :          0 : l_cleanup_exit:
     582         [ #  # ]:          0 :         if (tx_num == 0)
     583                 :            :                 return 0;
     584                 :          0 : l_end_of_tx:
     585                 :          0 :         SXE2_PCI_REG_WRITE_WC(txq->tdt_reg_addr, next_use);
     586                 :          0 :         PMD_LOG_DEBUG(TX, "port_id=%u queue_id=%u next_use=%u send_pkts=%u",
     587                 :            :                         txq->port_id, txq->queue_id, next_use, tx_num);
     588                 :            : 
     589                 :          0 :         txq->next_use = next_use;
     590                 :          0 :         return tx_num;
     591                 :            : }
     592                 :            : 
     593                 :            : static __rte_always_inline void
     594                 :          0 : sxe2_tx_data_desc_fill(volatile union sxe2_tx_data_desc *desc,
     595                 :            :                 struct rte_mbuf **tx_pkts)
     596                 :            : {
     597                 :          0 :         rte_iova_t buf_dma_addr;
     598                 :          0 :         uint32_t desc_offset;
     599                 :          0 :         buf_dma_addr = rte_mbuf_data_iova(*tx_pkts);
     600                 :          0 :         desc->read.buf_addr = rte_cpu_to_le_64(buf_dma_addr);
     601                 :          0 :         desc_offset = SXE2_TX_DATA_DESC_MACLEN_VAL((*tx_pkts)->l2_len);
     602                 :          0 :         desc->read.type_cmd_off_bsz_l2t =
     603                 :          0 :                                 sxe2_tx_data_desc_build_cobt(SXE2_TX_DATA_DESC_CMD_EOP,
     604                 :          0 :                                         desc_offset, (*tx_pkts)->data_len, 0);
     605                 :            : }
     606                 :            : static __rte_always_inline void
     607                 :          0 : sxe2_tx_data_desc_fill_batch(volatile union sxe2_tx_data_desc *desc,
     608                 :            :                 struct rte_mbuf **tx_pkts)
     609                 :            : {
     610                 :          0 :         rte_iova_t buf_dma_addr;
     611                 :          0 :         uint32_t i;
     612                 :          0 :         uint32_t desc_offset;
     613         [ #  # ]:          0 :         for (i = 0; i < SXE2_TX_FILL_PER_LOOP; ++i, ++desc, ++tx_pkts) {
     614                 :          0 :                 buf_dma_addr = rte_mbuf_data_iova(*tx_pkts);
     615                 :          0 :                 desc->read.buf_addr = rte_cpu_to_le_64(buf_dma_addr);
     616                 :          0 :                 desc_offset = SXE2_TX_DATA_DESC_MACLEN_VAL((*tx_pkts)->l2_len);
     617                 :          0 :                 desc->read.type_cmd_off_bsz_l2t =
     618                 :          0 :                         sxe2_tx_data_desc_build_cobt(SXE2_TX_DATA_DESC_CMD_EOP,
     619                 :            :                                         desc_offset,
     620                 :          0 :                                         (*tx_pkts)->data_len,
     621                 :            :                                         0);
     622                 :            :         }
     623                 :            : }
     624                 :            : 
     625                 :          0 : static inline void sxe2_tx_ring_fill(struct sxe2_tx_queue *txq,
     626                 :            :                                 struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
     627                 :            : {
     628                 :          0 :         struct sxe2_tx_buffer *buffer = &txq->buffer_ring[txq->next_use];
     629                 :          0 :         volatile union sxe2_tx_data_desc *desc = &txq->desc_ring[txq->next_use];
     630                 :          0 :         uint32_t i, j;
     631                 :          0 :         uint32_t        mainpart;
     632                 :          0 :         uint32_t leftover;
     633                 :          0 :         mainpart = nb_pkts & ((uint32_t)~SXE2_TX_FILL_PER_LOOP_MASK);
     634                 :          0 :         leftover = nb_pkts & ((uint32_t)SXE2_TX_FILL_PER_LOOP_MASK);
     635         [ #  # ]:          0 :         for (i = 0; i < mainpart; i += SXE2_TX_FILL_PER_LOOP) {
     636         [ #  # ]:          0 :                 for (j = 0; j < SXE2_TX_FILL_PER_LOOP; ++j)
     637                 :          0 :                         (buffer + i + j)->mbuf = *(tx_pkts + i + j);
     638                 :          0 :                 sxe2_tx_data_desc_fill_batch(desc + i, tx_pkts + i);
     639                 :            :         }
     640         [ #  # ]:          0 :         if (unlikely(leftover > 0)) {
     641         [ #  # ]:          0 :                 for (i = 0; i < leftover; ++i) {
     642                 :          0 :                         (buffer + mainpart + i)->mbuf = *(tx_pkts + mainpart + i);
     643                 :          0 :                         sxe2_tx_data_desc_fill(desc + mainpart + i,
     644                 :            :                                         tx_pkts + mainpart + i);
     645                 :            :                 }
     646                 :            :         }
     647                 :          0 : }
     648                 :            : 
     649                 :          0 : static inline uint16_t sxe2_tx_pkts_batch(void *tx_queue,
     650                 :            :                         struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
     651                 :            : {
     652                 :          0 :         struct sxe2_tx_queue *txq = (struct sxe2_tx_queue *)tx_queue;
     653                 :          0 :         volatile union sxe2_tx_data_desc *desc_ring = txq->desc_ring;
     654                 :          0 :         uint16_t res_num = 0;
     655         [ #  # ]:          0 :         if (txq->desc_free_num < txq->free_thresh)
     656         [ #  # ]:          0 :                 (void)sxe2_tx_bufs_free(txq);
     657                 :          0 :         nb_pkts = RTE_MIN(txq->desc_free_num, nb_pkts);
     658         [ #  # ]:          0 :         if (unlikely(nb_pkts == 0)) {
     659                 :          0 :                 PMD_LOG_DEBUG(TX, "Tx batch: may not enough free desc, "
     660                 :            :                                 "free_desc=%u, need_tx_pkts=%u",
     661                 :            :                                 txq->desc_free_num, nb_pkts);
     662                 :          0 :                 goto l_end;
     663                 :            :         }
     664                 :          0 :         txq->desc_free_num -= nb_pkts;
     665         [ #  # ]:          0 :         if ((txq->next_use + nb_pkts) > txq->ring_depth) {
     666                 :          0 :                 res_num = txq->ring_depth - txq->next_use;
     667                 :          0 :                 sxe2_tx_ring_fill(txq, tx_pkts, res_num);
     668                 :          0 :                 desc_ring[txq->next_rs].read.type_cmd_off_bsz_l2t |=
     669                 :            :                                 rte_cpu_to_le_64(SXE2_TX_DATA_DESC_CMD_RS_MASK);
     670                 :          0 :                 txq->next_rs = txq->rs_thresh - 1;
     671                 :          0 :                 txq->next_use = 0;
     672                 :            :         }
     673                 :          0 :         sxe2_tx_ring_fill(txq, tx_pkts + res_num, nb_pkts - res_num);
     674                 :          0 :         txq->next_use = txq->next_use + (nb_pkts - res_num);
     675         [ #  # ]:          0 :         if (txq->next_use > txq->next_rs) {
     676                 :          0 :                 desc_ring[txq->next_rs].read.type_cmd_off_bsz_l2t |=
     677                 :            :                                 rte_cpu_to_le_64(SXE2_TX_DATA_DESC_CMD_RS_MASK);
     678                 :          0 :                 txq->next_rs += txq->rs_thresh;
     679         [ #  # ]:          0 :                 if (txq->next_rs >= txq->ring_depth)
     680                 :          0 :                         txq->next_rs = txq->rs_thresh - 1;
     681                 :            :         }
     682         [ #  # ]:          0 :         if (txq->next_use >= txq->ring_depth)
     683                 :          0 :                 txq->next_use = 0;
     684                 :          0 :         PMD_LOG_DEBUG(TX, "port_id=%u queue_id=%u next_use=%u send_pkts=%u",
     685                 :            :                         txq->port_id, txq->queue_id, txq->next_use, nb_pkts);
     686                 :          0 :         SXE2_PCI_REG_WRITE_WC(txq->tdt_reg_addr, txq->next_use);
     687                 :          0 : l_end:
     688                 :          0 :         return nb_pkts;
     689                 :            : }
     690                 :            : 
     691                 :          0 : uint16_t sxe2_tx_pkts_simple(void *tx_queue,
     692                 :            :                         struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
     693                 :            : {
     694                 :          0 :         uint16_t tx_done_num;
     695                 :          0 :         uint16_t tx_once_num;
     696                 :          0 :         uint16_t tx_need_num;
     697         [ #  # ]:          0 :         if (likely(nb_pkts <= SXE2_TX_PKTS_BURST_BATCH_NUM)) {
     698                 :          0 :                 tx_done_num = sxe2_tx_pkts_batch(tx_queue,
     699                 :            :                                 tx_pkts, nb_pkts);
     700                 :          0 :                 goto l_end;
     701                 :            :         }
     702                 :            :         tx_done_num = 0;
     703         [ #  # ]:          0 :         while (nb_pkts) {
     704                 :          0 :                 tx_need_num = RTE_MIN(nb_pkts, SXE2_TX_PKTS_BURST_BATCH_NUM);
     705                 :          0 :                 tx_once_num = sxe2_tx_pkts_batch(tx_queue,
     706                 :          0 :                                                  &tx_pkts[tx_done_num],
     707                 :            :                                                  tx_need_num);
     708                 :          0 :                 nb_pkts -= tx_once_num;
     709                 :          0 :                 tx_done_num += tx_once_num;
     710         [ #  # ]:          0 :                 if (tx_once_num < tx_need_num)
     711                 :            :                         break;
     712                 :            :         }
     713                 :          0 : l_end:
     714                 :          0 :         return tx_done_num;
     715                 :            : }
     716                 :            : 
     717                 :            : static inline void
     718                 :          0 : sxe2_update_rx_tail(struct sxe2_rx_queue *rxq, uint16_t hold_num, uint16_t rx_id)
     719                 :            : {
     720                 :          0 :         hold_num += rxq->hold_num;
     721                 :            : 
     722         [ #  # ]:          0 :         if (hold_num > rxq->rx_free_thresh) {
     723         [ #  # ]:          0 :                 rx_id = (uint16_t)((rx_id == 0) ? (rxq->ring_depth - 1) : (rx_id - 1));
     724                 :          0 :                 SXE2_PCI_REG_WRITE_WC(rxq->rdt_reg_addr, rx_id);
     725                 :            :                 hold_num = 0;
     726                 :            :         }
     727                 :          0 :         rxq->hold_num = hold_num;
     728                 :          0 : }
     729                 :            : 
     730                 :            : static inline uint64_t
     731                 :          0 : sxe2_rx_desc_error_para(__rte_unused struct sxe2_rx_queue *rxq,
     732                 :            :                 union sxe2_rx_desc *desc)
     733                 :            : {
     734                 :          0 :         uint64_t flags = 0;
     735                 :          0 :         uint64_t desc_qw1 = rte_le_to_cpu_64(desc->wb.status_err_ptype_len);
     736                 :            : 
     737         [ #  # ]:          0 :         if (unlikely(0 == (desc_qw1 & SXE2_RX_DESC_STATUS_L3L4_P_MASK)))
     738                 :          0 :                 goto l_end;
     739                 :            : 
     740         [ #  # ]:          0 :         if (likely(0 == (desc->wb.rxdid_src & SXE2_RX_DESC_EUDPE_MASK)))
     741                 :            :                 flags = RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD;
     742                 :            :         else
     743                 :          0 :                 flags = RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD;
     744                 :            : 
     745         [ #  # ]:          0 :         if (likely(0 == (desc_qw1 & SXE2_RX_DESC_QW1_ERRORS_MASK))) {
     746                 :          0 :                 flags |= (RTE_MBUF_F_RX_IP_CKSUM_GOOD |
     747                 :            :                                 RTE_MBUF_F_RX_L4_CKSUM_GOOD |
     748                 :            :                                 RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD);
     749                 :          0 :                 goto l_end;
     750                 :            :         }
     751                 :            : 
     752         [ #  # ]:          0 :         if (likely(0 == (desc_qw1 & SXE2_RX_DESC_ERROR_CSUM_IPE_MASK)))
     753                 :          0 :                 flags |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
     754                 :            :         else
     755                 :          0 :                 flags |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
     756                 :            : 
     757         [ #  # ]:          0 :         if (likely(0 == (desc_qw1 & SXE2_RX_DESC_ERROR_CSUM_L4_MASK)))
     758                 :          0 :                 flags |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
     759                 :            :         else
     760                 :          0 :                 flags |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
     761                 :            : 
     762         [ #  # ]:          0 :         if (unlikely(0 != (desc_qw1 & SXE2_RX_DESC_ERROR_CSUM_EIP_MASK)))
     763                 :          0 :                 flags |= RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD;
     764                 :            : 
     765                 :          0 : l_end:
     766                 :          0 :         return flags;
     767                 :            : }
     768                 :            : 
     769                 :          0 : static inline void sxe2_rx_desc_vlan_para_fill(struct rte_mbuf *mbuf,
     770                 :            :                         union sxe2_rx_desc *desc)
     771                 :            : {
     772         [ #  # ]:          0 :         if (0 == (rte_le_to_cpu_64(desc->wb.status_err_ptype_len) &
     773                 :            :                   SXE2_RX_DESC_STATUS_L2TAG1_P_MASK)) {
     774                 :          0 :                 mbuf->vlan_tci = 0;
     775                 :            :         } else {
     776                 :          0 :                 mbuf->ol_flags |= (RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED);
     777                 :          0 :                 mbuf->vlan_tci = rte_le_to_cpu_16(desc->wb.l2tag1);
     778                 :          0 :                 PMD_LOG_DEBUG(RX, "Rx desc mbuf vlan, vlan_tci:%u",
     779                 :            :                         mbuf->vlan_tci);
     780                 :            :         }
     781                 :            : #ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
     782         [ #  # ]:          0 :         if (0 == (rte_le_to_cpu_32(desc->wb.status_lrocnt_fdpf_id) &
     783                 :            :                                 SXE2_RX_DESC_EXT_STATUS_L2TAG2P_MASK)) {
     784                 :          0 :                 mbuf->vlan_tci_outer = 0;
     785                 :            :         } else {
     786                 :          0 :                 mbuf->ol_flags |= RTE_MBUF_F_RX_QINQ_STRIPPED | RTE_MBUF_F_RX_QINQ |
     787                 :            :                                 RTE_MBUF_F_RX_VLAN_STRIPPED | RTE_MBUF_F_RX_VLAN;
     788                 :          0 :                 mbuf->vlan_tci_outer = mbuf->vlan_tci;
     789                 :          0 :                 mbuf->vlan_tci = rte_le_to_cpu_16(desc->wb.l2tag2_2nd);
     790                 :          0 :                 PMD_LOG_DEBUG(RX, "Rx desc out vlan, l2tag2_1st:%u l2tag2_2nd:%u.",
     791                 :            :                                 rte_le_to_cpu_16(desc->wb.l2tag2_1st),
     792                 :            :                                 rte_le_to_cpu_16(desc->wb.l2tag2_2nd));
     793                 :            :         }
     794                 :            : #endif
     795                 :          0 : }
     796                 :            : 
     797                 :            : static inline void
     798                 :          0 : sxe2_rx_desc_filter_para_fill(struct sxe2_rx_queue *rxq __rte_unused,
     799                 :            :                 struct rte_mbuf *mbuf, union sxe2_rx_desc *desc)
     800                 :            : {
     801                 :          0 :         if (SXE2_RX_DESC_STATUS_RSS_VLD_MASK &
     802         [ #  # ]:          0 :                                 rte_le_to_cpu_64(desc->wb.status_err_ptype_len)) {
     803                 :          0 :                 mbuf->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
     804                 :          0 :                 mbuf->hash.rss = rte_le_to_cpu_32(desc->wb.filter_status);
     805                 :          0 :                 PMD_LOG_DEBUG(RX, "rss id:%u", mbuf->hash.rss);
     806                 :            :         }
     807                 :            : #ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
     808         [ #  # ]:          0 :         if (SXE2_RX_DESC_FD_VLD_MASK & desc->wb.rxdid_src) {
     809                 :          0 :                 mbuf->ol_flags |= (RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID);
     810                 :          0 :                 mbuf->hash.fdir.hi = rte_le_to_cpu_32(desc->wb.fd_filter_id);
     811                 :          0 :                 PMD_LOG_DEBUG(RX, "fdir id:%u", mbuf->hash.fdir.hi);
     812                 :            :         }
     813                 :            : #endif
     814                 :          0 : }
     815                 :            : 
     816                 :            : #ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
     817                 :          0 : int32_t sxe2_rx_update_ptp_time(struct sxe2_rx_queue *rxq)
     818                 :            : {
     819                 :          0 :         struct sxe2_adapter *adapter;
     820                 :          0 :         uint64_t cur_time_ms;
     821                 :          0 :         int32_t ret = 0;
     822                 :          0 :         cur_time_ms = rte_get_timer_cycles() / (rte_get_timer_hz() / 1000);
     823                 :            : 
     824         [ #  # ]:          0 :         if (likely((cur_time_ms - rxq->update_time) < SXE2_RX_PKTS_TS_TIMEOUT_VAL))
     825                 :          0 :                 goto l_end;
     826                 :          0 :         rxq->update_time = cur_time_ms;
     827                 :          0 :         adapter = rxq->vsi->adapter;
     828                 :          0 :         rxq->ts_need_update = true;
     829                 :          0 :         ret = sxe2_drv_ptp_gettime(adapter, rxq);
     830         [ #  # ]:          0 :         if (rxq->desc_ts < rxq->ts_low)
     831                 :          0 :                 rxq->ts_need_update = false;
     832                 :            : 
     833                 :          0 :         PMD_LOG_INFO(RX, "rxq update time ret=%d, cur time=%" PRIu64 ", rxqh=%" PRIu64 ", rxql=%d",
     834                 :            :                      ret, cur_time_ms, rxq->ts_high, rxq->ts_low);
     835                 :          0 : l_end:
     836                 :          0 :         return ret;
     837                 :            : }
     838                 :            : 
     839                 :          0 : static inline void sxe2_rx_desc_ptp_para_fill(struct sxe2_rx_queue *rxq,
     840                 :            :                                               struct rte_mbuf *mbuf,
     841                 :            :                                               union sxe2_rx_desc *desc)
     842                 :            : {
     843                 :          0 :         struct sxe2_adapter *adapter = rxq->vsi->adapter;
     844                 :          0 :         uint64_t ts_ns;
     845                 :            : 
     846         [ #  # ]:          0 :         if (adapter->ptp_ctxt.mbuf_rx_ts_flag != 0 &&
     847         [ #  # ]:          0 :             (rxq->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) &&
     848         [ #  # ]:          0 :             SXE2_RX_DESC_RXDID_VAL_GET(desc->wb.rxdid_src) == SXE2_RX_DESC_RXDID_1588) {
     849                 :          0 :                 rxq->desc_ts = rte_le_to_cpu_32(desc->wb_ts.ts_h);
     850                 :          0 :                 (void)sxe2_rx_update_ptp_time(rxq);
     851   [ #  #  #  # ]:          0 :                 if (rxq->ts_need_update && rxq->desc_ts < rxq->ts_low)
     852                 :          0 :                         rxq->ts_high += 1;
     853                 :            : 
     854                 :          0 :                 rxq->ts_need_update = true;
     855                 :          0 :                 rxq->ts_low = rxq->desc_ts;
     856                 :          0 :                 rxq->update_time = rte_get_timer_cycles() /
     857                 :          0 :                         (rte_get_timer_hz() / 1000);
     858                 :          0 :                 ts_ns = rxq->ts_high * NSEC_PER_SEC + rxq->ts_low;
     859                 :          0 :                 *RTE_MBUF_DYNFIELD(mbuf, adapter->ptp_ctxt.mbuf_rx_ts_offset, uint64_t *) = ts_ns;
     860                 :          0 :                 mbuf->ol_flags |= adapter->ptp_ctxt.mbuf_rx_ts_flag;
     861                 :          0 :                 PMD_LOG_INFO(RX, "receive ptp pkt,ts_s=%" PRIu64 ", ts_ns=%d", rxq->ts_high,
     862                 :            :                              rxq->ts_low);
     863                 :            :         }
     864                 :          0 : }
     865                 :            : 
     866                 :          0 : static inline void sxe2_rx_desc_ipsec_para_fill(struct sxe2_rx_queue *rxq __rte_unused,
     867                 :            :                 struct rte_mbuf *mbuf, union sxe2_rx_desc *desc)
     868                 :            : {
     869                 :          0 :         uint32_t status_lrocnt_fdpf_id = rte_le_to_cpu_32(desc->wb.status_lrocnt_fdpf_id);
     870                 :          0 :         enum sxe2_rx_desc_ipsec_status ipsec_status;
     871                 :            : 
     872         [ #  # ]:          0 :         if (status_lrocnt_fdpf_id & SXE2_RX_DESC_IPSEC_PKT_MASK) {
     873                 :          0 :                 mbuf->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD;
     874                 :          0 :                 ipsec_status = SXE2_RX_DESC_IPSEC_STATUS_VAL_GET(status_lrocnt_fdpf_id);
     875         [ #  # ]:          0 :                 switch (ipsec_status) {
     876                 :            :                 case SXE2_RX_DESC_IPSEC_STATUS_SUCCESS:
     877                 :            :                         break;
     878                 :          0 :                 case SXE2_RX_DESC_IPSEC_STATUS_PKG_OVER_2K:
     879                 :            :                 case SXE2_RX_DESC_IPSEC_STATUS_SPI_IP_INVALID:
     880                 :            :                 case SXE2_RX_DESC_IPSEC_STATUS_SA_INVALID:
     881                 :            :                 case SXE2_RX_DESC_IPSEC_STATUS_NOT_ALIGN:
     882                 :            :                 case SXE2_RX_DESC_IPSEC_STATUS_ICV_ERROR:
     883                 :            :                 case SXE2_RX_DESC_IPSEC_STATUS_BY_PASSH:
     884                 :            :                 case SXE2_RX_DESC_IPSEC_STATUS_MAC_BY_PASSH:
     885                 :          0 :                         PMD_LOG_INFO(RX, "IPsec status error:%d", ipsec_status);
     886                 :          0 :                         mbuf->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
     887                 :          0 :                         break;
     888                 :            :                 default:
     889                 :            :                         PMD_LOG_INFO(RX, "Invalid ipsec status:%d", ipsec_status);
     890                 :            :                         mbuf->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
     891                 :            :                         break;
     892                 :            :                 }
     893                 :            :         }
     894                 :          0 : }
     895                 :            : #endif
     896                 :            : 
     897                 :            : static __rte_always_inline void
     898                 :          0 : sxe2_rx_mbuf_common_fields_fill(struct sxe2_rx_queue *rxq, struct rte_mbuf *mbuf,
     899                 :            :                 union sxe2_rx_desc *rxd)
     900                 :            : {
     901                 :          0 :         uint64_t qword1;
     902                 :          0 :         uint64_t pkt_flags;
     903                 :          0 :         qword1 = rte_le_to_cpu_64(rxd->wb.status_err_ptype_len);
     904                 :            : 
     905                 :          0 :         mbuf->ol_flags = 0;
     906                 :          0 :         mbuf->packet_type = sxe2_ptype_tbl[SXE2_RX_DESC_PTYPE_VAL_GET(qword1)];
     907                 :          0 :         pkt_flags = sxe2_rx_desc_error_para(rxq, rxd);
     908                 :          0 :         sxe2_rx_desc_vlan_para_fill(mbuf, rxd);
     909                 :          0 :         sxe2_rx_desc_filter_para_fill(rxq, mbuf, rxd);
     910                 :            : #ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
     911                 :          0 :         sxe2_rx_desc_ipsec_para_fill(rxq, mbuf, rxd);
     912                 :          0 :         sxe2_rx_desc_ptp_para_fill(rxq, mbuf, rxd);
     913                 :            : #endif
     914                 :            : 
     915                 :          0 :         mbuf->ol_flags |= pkt_flags;
     916                 :            : }
     917                 :            : 
     918                 :            : static __rte_always_inline void
     919                 :          0 : sxe2_rx_sw_stats_update(struct sxe2_rx_queue *rxq, struct rte_mbuf *mbuf,
     920                 :            :                 union sxe2_rx_desc *rxd)
     921                 :            : {
     922                 :          0 :         uint64_t qword1 = rte_le_to_cpu_64(rxd->wb.status_err_ptype_len);
     923                 :          0 :         rxq->sw_stats.pkts += 1;
     924                 :          0 :         rxq->sw_stats.bytes += mbuf->pkt_len + RTE_ETHER_CRC_LEN;
     925                 :          0 :         switch (SXE2_RX_DESC_STATUS_UMBCAST_VAL_GET(qword1)) {
     926                 :          0 :         case SXE2_RX_DESC_STATUS_UNICAST:
     927                 :          0 :                 rxq->sw_stats.unicast_pkts += 1;
     928                 :          0 :                 break;
     929                 :          0 :         case SXE2_RX_DESC_STATUS_MULTICAST:
     930                 :          0 :                 rxq->sw_stats.multicast_pkts += 1;
     931                 :          0 :                 break;
     932                 :          0 :         case SXE2_RX_DESC_STATUS_BROADCAST:
     933                 :          0 :                 rxq->sw_stats.broadcast_pkts += 1;
     934                 :          0 :                 break;
     935                 :            :         default:
     936                 :            :                 break;
     937                 :            :         }
     938                 :            : }
     939                 :            : 
     940                 :          0 : uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
     941                 :            : {
     942                 :          0 :         struct sxe2_rx_queue *rxq = (struct sxe2_rx_queue *)rx_queue;
     943                 :          0 :         volatile union sxe2_rx_desc *desc_ring;
     944                 :          0 :         volatile union sxe2_rx_desc *desc;
     945                 :          0 :         union sxe2_rx_desc desc_tmp;
     946                 :          0 :         struct rte_mbuf **buffer_ring;
     947                 :          0 :         struct rte_mbuf **cur_buffer;
     948                 :          0 :         struct rte_mbuf *cur_mbuf;
     949                 :          0 :         struct rte_mbuf *new_mbuf;
     950                 :          0 :         struct rte_mbuf *first_seg;
     951                 :          0 :         struct rte_mbuf *last_seg;
     952                 :          0 :         uint64_t qword1;
     953                 :          0 :         uint16_t done_num;
     954                 :          0 :         uint16_t hold_num;
     955                 :          0 :         uint16_t cur_idx;
     956                 :          0 :         uint16_t pkt_len;
     957                 :            : 
     958                 :          0 :         desc_ring   = rxq->desc_ring;
     959                 :          0 :         buffer_ring = rxq->buffer_ring;
     960                 :          0 :         cur_idx     = rxq->processing_idx;
     961                 :          0 :         first_seg   = rxq->pkt_first_seg;
     962                 :          0 :         last_seg    = rxq->pkt_last_seg;
     963                 :          0 :         done_num    = 0;
     964                 :          0 :         hold_num    = 0;
     965         [ #  # ]:          0 :         while (done_num < nb_pkts) {
     966                 :          0 :                 desc = &desc_ring[cur_idx];
     967                 :          0 :                 qword1 = rte_le_to_cpu_64(desc->wb.status_err_ptype_len);
     968         [ #  # ]:          0 :                 if (0 == (SXE2_RX_DESC_STATUS_DD_MASK & qword1))
     969                 :            :                         break;
     970                 :            : 
     971                 :          0 :                 new_mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
     972         [ #  # ]:          0 :                 if (unlikely(new_mbuf == NULL)) {
     973                 :          0 :                         rxq->vsi->adapter->dev_info.dev_data->rx_mbuf_alloc_failed++;
     974                 :          0 :                         PMD_LOG_INFO(RX, "Rx new_mbuf alloc failed port_id:%u "
     975                 :            :                                         "queue_id:%u", rxq->port_id, rxq->queue_id);
     976                 :          0 :                         break;
     977                 :            :                 }
     978                 :            : 
     979                 :          0 :                 hold_num++;
     980                 :          0 :                 desc_tmp = *desc;
     981                 :          0 :                 cur_buffer = &buffer_ring[cur_idx];
     982                 :          0 :                 cur_idx++;
     983         [ #  # ]:          0 :                 if (unlikely(cur_idx == rxq->ring_depth))
     984                 :          0 :                         cur_idx = 0;
     985                 :            : 
     986                 :          0 :                 rte_prefetch0(buffer_ring[cur_idx]);
     987                 :            : 
     988         [ #  # ]:          0 :                 if (0 == (cur_idx & 0x3)) {
     989                 :          0 :                         rte_prefetch0(&desc_ring[cur_idx]);
     990                 :          0 :                         rte_prefetch0(&buffer_ring[cur_idx]);
     991                 :            :                 }
     992                 :            : 
     993                 :          0 :                 cur_mbuf = *cur_buffer;
     994                 :            : 
     995                 :          0 :                 *cur_buffer = new_mbuf;
     996                 :            : 
     997                 :          0 :                 desc->read.hdr_addr = 0;
     998         [ #  # ]:          0 :                 desc->read.pkt_addr =
     999                 :          0 :                         rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf));
    1000                 :            : 
    1001                 :          0 :                 pkt_len = SXE2_RX_DESC_PKT_LEN_VAL_GET(qword1);
    1002                 :          0 :                 cur_mbuf->data_len = pkt_len;
    1003                 :          0 :                 cur_mbuf->data_off = RTE_PKTMBUF_HEADROOM;
    1004                 :            : 
    1005         [ #  # ]:          0 :                 if (first_seg == NULL) {
    1006                 :          0 :                         first_seg = cur_mbuf;
    1007                 :          0 :                         first_seg->nb_segs = 1;
    1008                 :          0 :                         first_seg->pkt_len = pkt_len;
    1009                 :            :                 } else {
    1010                 :          0 :                         first_seg->pkt_len += pkt_len;
    1011                 :          0 :                         first_seg->nb_segs++;
    1012                 :          0 :                         last_seg->next = cur_mbuf;
    1013                 :            :                 }
    1014                 :            : 
    1015         [ #  # ]:          0 :                 if (0 == (qword1 & SXE2_RX_DESC_STATUS_EOP_MASK)) {
    1016                 :          0 :                         last_seg = cur_mbuf;
    1017                 :          0 :                         continue;
    1018                 :            :                 }
    1019                 :            : 
    1020         [ #  # ]:          0 :                 if (unlikely(qword1 & SXE2_RX_DESC_ERROR_RXE_MASK) ||
    1021         [ #  # ]:          0 :                         unlikely(qword1 & SXE2_RX_DESC_ERROR_OVERSIZE_MASK)) {
    1022                 :          0 :                         rxq->sw_stats.drop_pkts += 1;
    1023                 :          0 :                         rxq->sw_stats.drop_bytes +=
    1024                 :          0 :                                 first_seg->pkt_len - rxq->crc_len + RTE_ETHER_CRC_LEN;
    1025                 :          0 :                         rte_pktmbuf_free(first_seg);
    1026                 :          0 :                         first_seg = NULL;
    1027                 :          0 :                         continue;
    1028                 :            :                 }
    1029                 :            : 
    1030                 :          0 :                 cur_mbuf->next = NULL;
    1031         [ #  # ]:          0 :                 if (unlikely(rxq->crc_len > 0)) {
    1032                 :          0 :                         first_seg->pkt_len -= RTE_ETHER_CRC_LEN;
    1033                 :            : 
    1034         [ #  # ]:          0 :                         if (pkt_len <= RTE_ETHER_CRC_LEN) {
    1035         [ #  # ]:          0 :                                 rte_pktmbuf_free_seg(cur_mbuf);
    1036                 :          0 :                                 first_seg->nb_segs--;
    1037                 :          0 :                                 last_seg->data_len = last_seg->data_len + pkt_len -
    1038                 :            :                                         RTE_ETHER_CRC_LEN;
    1039                 :          0 :                                 last_seg->next = NULL;
    1040                 :            :                         } else {
    1041                 :          0 :                                 cur_mbuf->data_len = pkt_len - RTE_ETHER_CRC_LEN;
    1042                 :            :                         }
    1043                 :            : 
    1044         [ #  # ]:          0 :                 } else if (pkt_len == 0) {
    1045         [ #  # ]:          0 :                         rte_pktmbuf_free_seg(cur_mbuf);
    1046                 :          0 :                         first_seg->nb_segs--;
    1047                 :          0 :                         last_seg->next = NULL;
    1048                 :            :                 }
    1049                 :            : 
    1050                 :          0 :                 rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr, first_seg->data_off));
    1051                 :          0 :                 first_seg->port     = rxq->port_id;
    1052                 :            : 
    1053                 :          0 :                 sxe2_rx_mbuf_common_fields_fill(rxq, first_seg, &desc_tmp);
    1054                 :            : 
    1055   [ #  #  #  # ]:          0 :                 sxe2_rx_sw_stats_update(rxq, first_seg, &desc_tmp);
    1056                 :            : 
    1057                 :          0 :                 rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr, first_seg->data_off));
    1058                 :            : 
    1059                 :          0 :                 rx_pkts[done_num] = first_seg;
    1060                 :          0 :                 done_num++;
    1061                 :            : 
    1062                 :          0 :                 first_seg = NULL;
    1063                 :            :         }
    1064                 :            : 
    1065                 :          0 :         rxq->processing_idx = cur_idx;
    1066                 :          0 :         rxq->pkt_first_seg  = first_seg;
    1067                 :          0 :         rxq->pkt_last_seg   = last_seg;
    1068                 :            : 
    1069                 :          0 :         sxe2_update_rx_tail(rxq, hold_num, cur_idx);
    1070                 :            : 
    1071                 :          0 :         return done_num;
    1072                 :            : }
    1073                 :            : 
    1074                 :          0 : uint16_t sxe2_rx_pkts_scattered_split(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
    1075                 :            : {
    1076                 :          0 :         struct sxe2_rx_queue *rxq = (struct sxe2_rx_queue *)rx_queue;
    1077                 :          0 :         volatile union sxe2_rx_desc *desc_ring;
    1078                 :          0 :         volatile union sxe2_rx_desc *desc;
    1079                 :          0 :         union sxe2_rx_desc desc_tmp;
    1080                 :          0 :         struct rte_mbuf **buffer_ring;
    1081                 :          0 :         struct rte_mbuf **cur_buffer;
    1082                 :          0 :         struct rte_mbuf *cur_mbuf;
    1083                 :          0 :         struct rte_mbuf *cur_mbuf_pay;
    1084                 :          0 :         struct rte_mbuf *new_mbuf;
    1085                 :          0 :         struct rte_mbuf *new_mbuf_pay = NULL;
    1086                 :          0 :         struct rte_mbuf *first_seg;
    1087                 :          0 :         struct rte_mbuf *last_seg;
    1088                 :          0 :         uint64_t qword1;
    1089                 :          0 :         uint16_t done_num;
    1090                 :          0 :         uint16_t hold_num;
    1091                 :          0 :         uint16_t cur_idx;
    1092                 :          0 :         uint16_t pkt_len;
    1093                 :          0 :         uint16_t hdr_len;
    1094                 :            : 
    1095                 :          0 :         desc_ring = rxq->desc_ring;
    1096                 :          0 :         buffer_ring = rxq->buffer_ring;
    1097                 :          0 :         cur_idx = rxq->processing_idx;
    1098                 :          0 :         first_seg = rxq->pkt_first_seg;
    1099                 :          0 :         last_seg = rxq->pkt_last_seg;
    1100                 :          0 :         done_num = 0;
    1101                 :          0 :         hold_num = 0;
    1102                 :          0 :         new_mbuf = NULL;
    1103                 :            : 
    1104         [ #  # ]:          0 :         while (done_num < nb_pkts) {
    1105                 :          0 :                 desc = &desc_ring[cur_idx];
    1106                 :          0 :                 qword1 = rte_le_to_cpu_64(desc->wb.status_err_ptype_len);
    1107                 :            : 
    1108         [ #  # ]:          0 :                 if (0 == (SXE2_RX_DESC_STATUS_DD_MASK & qword1))
    1109                 :            :                         break;
    1110                 :            : 
    1111   [ #  #  #  # ]:          0 :                 if ((rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) == 0 ||
    1112                 :            :                         first_seg == NULL) {
    1113                 :          0 :                         new_mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
    1114         [ #  # ]:          0 :                         if (unlikely(new_mbuf == NULL)) {
    1115                 :          0 :                                 rxq->vsi->adapter->dev_info.dev_data->rx_mbuf_alloc_failed++;
    1116                 :          0 :                                 break;
    1117                 :            :                         }
    1118                 :            :                 }
    1119                 :            : 
    1120         [ #  # ]:          0 :                 if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
    1121                 :          0 :                         new_mbuf_pay = rte_mbuf_raw_alloc(rxq->rx_seg[1].mp);
    1122         [ #  # ]:          0 :                         if (unlikely(new_mbuf_pay == NULL)) {
    1123                 :          0 :                                 rxq->vsi->adapter->dev_info.dev_data->rx_mbuf_alloc_failed++;
    1124         [ #  # ]:          0 :                                 if (new_mbuf != NULL)
    1125                 :          0 :                                         rte_pktmbuf_free(new_mbuf);
    1126                 :          0 :                                 new_mbuf = NULL;
    1127                 :            :                                 break;
    1128                 :            :                         }
    1129                 :            :                 }
    1130                 :            : 
    1131                 :          0 :                 hold_num++;
    1132                 :          0 :                 desc_tmp = *desc;
    1133                 :          0 :                 cur_buffer = &buffer_ring[cur_idx];
    1134                 :          0 :                 cur_idx++;
    1135         [ #  # ]:          0 :                 if (unlikely(cur_idx == rxq->ring_depth))
    1136                 :          0 :                         cur_idx = 0;
    1137                 :          0 :                 rte_prefetch0(buffer_ring[cur_idx]);
    1138         [ #  # ]:          0 :                 if (0 == (cur_idx & 0x3)) {
    1139                 :          0 :                         rte_prefetch0(&desc_ring[cur_idx]);
    1140                 :          0 :                         rte_prefetch0(&buffer_ring[cur_idx]);
    1141                 :            :                 }
    1142                 :          0 :                 cur_mbuf = *cur_buffer;
    1143         [ #  # ]:          0 :                 if (0 == (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT)) {
    1144                 :          0 :                         *cur_buffer = new_mbuf;
    1145                 :          0 :                         desc->read.hdr_addr = 0;
    1146                 :          0 :                         desc->read.pkt_addr =
    1147                 :          0 :                                 rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf));
    1148                 :            :                 } else {
    1149         [ #  # ]:          0 :                         if (first_seg == NULL) {
    1150                 :          0 :                                 *cur_buffer = new_mbuf;
    1151                 :          0 :                                 new_mbuf->next = new_mbuf_pay;
    1152                 :          0 :                                 new_mbuf->data_off = RTE_PKTMBUF_HEADROOM;
    1153                 :          0 :                                 new_mbuf_pay->next = NULL;
    1154                 :          0 :                                 new_mbuf_pay->data_off = RTE_PKTMBUF_HEADROOM;
    1155                 :          0 :                                 desc->read.hdr_addr =
    1156                 :          0 :                                         rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf));
    1157                 :          0 :                                 desc->read.pkt_addr =
    1158                 :          0 :                                         rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf_pay));
    1159                 :            :                         } else {
    1160                 :          0 :                                 cur_mbuf_pay = cur_mbuf->next;
    1161                 :          0 :                                 new_mbuf_pay->next = NULL;
    1162                 :          0 :                                 new_mbuf_pay->data_off = RTE_PKTMBUF_HEADROOM;
    1163                 :          0 :                                 cur_mbuf->next = new_mbuf_pay;
    1164                 :          0 :                                 desc->read.hdr_addr =
    1165                 :          0 :                                         rte_cpu_to_le_64(rte_mbuf_data_iova_default(cur_mbuf));
    1166                 :          0 :                                 desc->read.pkt_addr =
    1167                 :          0 :                                         rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf_pay));
    1168                 :          0 :                                 cur_mbuf = cur_mbuf_pay;
    1169                 :            :                         }
    1170                 :            :                 }
    1171                 :          0 :                 new_mbuf = NULL;
    1172         [ #  # ]:          0 :                 if (0 == (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT)) {
    1173                 :          0 :                         pkt_len = SXE2_RX_DESC_PKT_LEN_VAL_GET(qword1);
    1174                 :          0 :                         cur_mbuf->data_len = pkt_len;
    1175                 :          0 :                         cur_mbuf->data_off = RTE_PKTMBUF_HEADROOM;
    1176         [ #  # ]:          0 :                         if (first_seg == NULL) {
    1177                 :          0 :                                 first_seg = cur_mbuf;
    1178                 :          0 :                                 first_seg->nb_segs = 1;
    1179                 :          0 :                                 first_seg->pkt_len = pkt_len;
    1180                 :            :                         } else {
    1181                 :          0 :                                 first_seg->pkt_len += pkt_len;
    1182                 :          0 :                                 first_seg->nb_segs++;
    1183                 :          0 :                                 last_seg->next = cur_mbuf;
    1184                 :            :                         }
    1185                 :            :                 } else {
    1186         [ #  # ]:          0 :                         if (first_seg == NULL) {
    1187                 :          0 :                                 cur_mbuf->nb_segs = 2;
    1188                 :          0 :                                 cur_mbuf->next->next = NULL;
    1189                 :          0 :                                 pkt_len = SXE2_RX_DESC_PKT_LEN_VAL_GET(qword1);
    1190                 :          0 :                                 hdr_len = SXE2_RX_DESC_HDR_LEN_VAL_GET(qword1);
    1191                 :          0 :                                 cur_mbuf->data_len = hdr_len;
    1192                 :          0 :                                 cur_mbuf->pkt_len = hdr_len + pkt_len;
    1193                 :          0 :                                 cur_mbuf->next->data_len = pkt_len;
    1194                 :          0 :                                 first_seg = cur_mbuf;
    1195                 :          0 :                                 cur_mbuf = cur_mbuf->next;
    1196                 :          0 :                                 last_seg = cur_mbuf;
    1197                 :            :                         } else {
    1198                 :          0 :                                 cur_mbuf->nb_segs = 1;
    1199                 :          0 :                                 cur_mbuf->next = NULL;
    1200                 :          0 :                                 pkt_len = SXE2_RX_DESC_PKT_LEN_VAL_GET(qword1);
    1201                 :          0 :                                 cur_mbuf->data_len = pkt_len;
    1202                 :            : 
    1203                 :          0 :                                 first_seg->pkt_len += pkt_len;
    1204                 :          0 :                                 first_seg->nb_segs++;
    1205                 :          0 :                                 last_seg->next = cur_mbuf;
    1206                 :            :                         }
    1207                 :            :                 }
    1208                 :            : 
    1209                 :            : #ifdef RTE_ETHDEV_DEBUG_RX
    1210                 :            : 
    1211                 :            :                 rte_pktmbuf_dump(stdout, first_seg, rte_pktmbuf_pkt_len(first_seg));
    1212                 :            : #endif
    1213                 :            : 
    1214         [ #  # ]:          0 :                 if (0 == (rte_le_to_cpu_64(desc_tmp.wb.status_err_ptype_len) &
    1215                 :            :                                         SXE2_RX_DESC_STATUS_EOP_MASK)) {
    1216                 :          0 :                         last_seg = cur_mbuf;
    1217                 :          0 :                         continue;
    1218                 :            :                 }
    1219                 :            : 
    1220         [ #  # ]:          0 :                 if (unlikely(qword1 & SXE2_RX_DESC_ERROR_RXE_MASK) ||
    1221         [ #  # ]:          0 :                         unlikely(qword1 & SXE2_RX_DESC_ERROR_OVERSIZE_MASK)) {
    1222                 :          0 :                         rxq->sw_stats.drop_pkts += 1;
    1223                 :          0 :                         rxq->sw_stats.drop_bytes +=
    1224                 :          0 :                                 first_seg->pkt_len - rxq->crc_len + RTE_ETHER_CRC_LEN;
    1225                 :          0 :                         rte_pktmbuf_free(first_seg);
    1226                 :          0 :                         first_seg = NULL;
    1227                 :          0 :                         continue;
    1228                 :            :                 }
    1229                 :            : 
    1230                 :          0 :                 cur_mbuf->next = NULL;
    1231         [ #  # ]:          0 :                 if (unlikely(rxq->crc_len > 0)) {
    1232                 :          0 :                         first_seg->pkt_len -= RTE_ETHER_CRC_LEN;
    1233         [ #  # ]:          0 :                         if (pkt_len <= RTE_ETHER_CRC_LEN) {
    1234         [ #  # ]:          0 :                                 rte_pktmbuf_free_seg(cur_mbuf);
    1235                 :          0 :                                 cur_mbuf = NULL;
    1236                 :          0 :                                 first_seg->nb_segs--;
    1237                 :          0 :                                 last_seg->data_len = last_seg->data_len +
    1238                 :          0 :                                         pkt_len - RTE_ETHER_CRC_LEN;
    1239                 :          0 :                                 last_seg->next = NULL;
    1240                 :            :                         } else {
    1241                 :          0 :                                 cur_mbuf->data_len = pkt_len - RTE_ETHER_CRC_LEN;
    1242                 :            :                         }
    1243         [ #  # ]:          0 :                 } else if (pkt_len == 0) {
    1244         [ #  # ]:          0 :                         rte_pktmbuf_free_seg(cur_mbuf);
    1245                 :          0 :                         cur_mbuf = NULL;
    1246                 :          0 :                         first_seg->nb_segs--;
    1247                 :          0 :                         last_seg->next = NULL;
    1248                 :            :                 }
    1249                 :            : 
    1250                 :          0 :                 first_seg->port = rxq->port_id;
    1251                 :          0 :                 sxe2_rx_mbuf_common_fields_fill(rxq, first_seg, &desc_tmp);
    1252                 :            : 
    1253   [ #  #  #  # ]:          0 :                 sxe2_rx_sw_stats_update(rxq, first_seg, &desc_tmp);
    1254                 :            : 
    1255                 :          0 :                 rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr, first_seg->data_off));
    1256                 :            : 
    1257                 :          0 :                 rx_pkts[done_num] = first_seg;
    1258                 :          0 :                 done_num++;
    1259                 :            : 
    1260                 :          0 :                 first_seg = NULL;
    1261                 :            :         }
    1262                 :            : 
    1263                 :          0 :         rxq->processing_idx = cur_idx;
    1264                 :          0 :         rxq->pkt_first_seg = first_seg;
    1265                 :          0 :         rxq->pkt_last_seg = last_seg;
    1266                 :            : 
    1267                 :          0 :         sxe2_update_rx_tail(rxq, hold_num, cur_idx);
    1268                 :            : 
    1269                 :          0 :         return done_num;
    1270                 :            : }

Generated by: LCOV version 1.14