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 678 0.0 %
Date: 2026-06-01 18:36:17 Functions: 0 12 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 296 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                 :            : 
      21                 :            : static __rte_always_inline int32_t
      22                 :          0 : sxe2_tx_bufs_free(struct sxe2_tx_queue *txq)
      23                 :            : {
      24                 :          0 :         struct sxe2_tx_buffer *buffer;
      25                 :          0 :         struct rte_mbuf *mbuf;
      26                 :          0 :         struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX];
      27                 :          0 :         int32_t ret;
      28                 :          0 :         uint32_t i;
      29                 :          0 :         uint16_t rs_thresh;
      30                 :          0 :         uint16_t free_num;
      31                 :          0 :         if ((txq->desc_ring[txq->next_dd].wb.dd &
      32                 :            :                      rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_MASK)) !=
      33                 :            :                      rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE)) {
      34                 :          0 :                 ret = 0;
      35                 :          0 :                 goto l_end;
      36                 :            :         }
      37                 :          0 :         rs_thresh = txq->rs_thresh;
      38                 :          0 :         buffer = &txq->buffer_ring[txq->next_dd - rs_thresh + 1];
      39   [ #  #  #  # ]:          0 :         if (txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) {
      40   [ #  #  #  # ]:          0 :                 if (likely(rs_thresh <= SXE2_TX_FREE_BUFFER_SIZE_MAX)) {
      41                 :          0 :                         mbuf = buffer[0].mbuf;
      42                 :          0 :                         mbuf_free_arr[0] = mbuf;
      43                 :          0 :                         free_num = 1;
      44   [ #  #  #  # ]:          0 :                         for (i = 1; i < rs_thresh; ++i) {
      45                 :          0 :                                 mbuf = buffer[i].mbuf;
      46   [ #  #  #  # ]:          0 :                                 if (likely(mbuf->pool == mbuf_free_arr[0]->pool)) {
      47                 :          0 :                                         mbuf_free_arr[free_num] = mbuf;
      48                 :          0 :                                         free_num++;
      49                 :            :                                 } else {
      50   [ #  #  #  # ]:          0 :                                         rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
      51                 :            :                                                                 (void *)mbuf_free_arr, free_num);
      52                 :          0 :                                         mbuf_free_arr[0] = mbuf;
      53                 :          0 :                                         free_num = 1;
      54                 :            :                                 }
      55                 :            :                         }
      56   [ #  #  #  # ]:          0 :                         rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
      57                 :            :                                                 (void *)mbuf_free_arr, free_num);
      58                 :            :                 } else {
      59   [ #  #  #  # ]:          0 :                         for (i = 0; i < rs_thresh; ++i, ++buffer) {
      60   [ #  #  #  # ]:          0 :                                 rte_mempool_put(buffer->mbuf->pool, buffer->mbuf);
      61                 :          0 :                                 buffer->mbuf = NULL;
      62                 :            :                         }
      63                 :            :                 }
      64                 :            :         } else {
      65   [ #  #  #  # ]:          0 :                 for (i = 0; i < rs_thresh; ++i, ++buffer) {
      66                 :          0 :                         mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
      67                 :          0 :                                 if (mbuf != NULL)
      68   [ #  #  #  # ]:          0 :                                         rte_mempool_put(mbuf->pool, mbuf);
      69                 :          0 :                         buffer->mbuf = NULL;
      70                 :            :                 }
      71                 :            :         }
      72                 :          0 :         txq->desc_free_num += rs_thresh;
      73                 :          0 :         txq->next_dd       += rs_thresh;
      74   [ #  #  #  # ]:          0 :         if (txq->next_dd >= txq->ring_depth)
      75                 :          0 :                 txq->next_dd = rs_thresh - 1;
      76                 :            :         ret = rs_thresh;
      77                 :          0 : l_end:
      78                 :          0 :         return ret;
      79                 :            : }
      80                 :            : 
      81                 :          0 : static inline int32_t sxe2_tx_cleanup(struct sxe2_tx_queue *txq)
      82                 :            : {
      83                 :          0 :         int32_t ret = 0;
      84                 :          0 :         volatile union sxe2_tx_data_desc *desc_ring = txq->desc_ring;
      85                 :          0 :         struct sxe2_tx_buffer *buffer_ring = txq->buffer_ring;
      86                 :          0 :         uint16_t ring_depth = txq->ring_depth;
      87                 :          0 :         uint16_t next_clean = txq->next_clean;
      88                 :          0 :         uint16_t clean_last;
      89                 :          0 :         uint16_t clean_num;
      90                 :            : 
      91                 :          0 :         clean_last = next_clean + txq->rs_thresh;
      92         [ #  # ]:          0 :         if (clean_last >= ring_depth)
      93                 :          0 :                 clean_last = clean_last - ring_depth;
      94                 :            : 
      95                 :          0 :         clean_last = buffer_ring[clean_last].last_id;
      96                 :          0 :         if (rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE) !=
      97         [ #  # ]:          0 :                 (txq->desc_ring[clean_last].wb.dd & rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_MASK))) {
      98                 :          0 :                 PMD_LOG_DEBUG(TX, "desc[%u] is not done.port_id=%u queue_id=%u val=0x%" PRIx64,
      99                 :            :                                                  clean_last, txq->port_id,
     100                 :            :                         txq->queue_id, txq->desc_ring[clean_last].wb.dd);
     101                 :          0 :                 ret = -1;
     102                 :          0 :                 goto l_end;
     103                 :            :         }
     104                 :            : 
     105         [ #  # ]:          0 :         if (clean_last > next_clean)
     106                 :          0 :                 clean_num = clean_last - next_clean;
     107                 :            :         else
     108                 :          0 :                 clean_num = ring_depth - next_clean + clean_last;
     109                 :            : 
     110                 :          0 :         desc_ring[clean_last].wb.dd = 0;
     111                 :            : 
     112                 :          0 :         txq->next_clean = clean_last;
     113                 :          0 :         txq->desc_free_num += clean_num;
     114                 :            : 
     115                 :          0 :         ret = 0;
     116                 :            : 
     117                 :          0 : l_end:
     118                 :          0 :         return ret;
     119                 :            : }
     120                 :            : 
     121                 :          0 : static int32_t sxe2_tx_done_cleanup_simple(struct sxe2_tx_queue *txq, uint32_t free_cnt)
     122                 :            : {
     123                 :          0 :         uint32_t free_cnt_align;
     124                 :          0 :         uint32_t free_cnt_once;
     125                 :          0 :         uint32_t i;
     126                 :            : 
     127   [ #  #  #  # ]:          0 :         if (free_cnt == 0 || free_cnt > txq->ring_depth)
     128                 :          0 :                 free_cnt = txq->ring_depth;
     129                 :            : 
     130                 :          0 :         free_cnt_align = free_cnt - (free_cnt % txq->rs_thresh);
     131         [ #  # ]:          0 :         for (i = 0; i < free_cnt_align; i += free_cnt_once) {
     132         [ #  # ]:          0 :                 if ((txq->ring_depth - txq->desc_free_num) < txq->rs_thresh)
     133                 :            :                         break;
     134                 :            : 
     135         [ #  # ]:          0 :                 free_cnt_once = sxe2_tx_bufs_free(txq);
     136         [ #  # ]:          0 :                 if (free_cnt_once == 0)
     137                 :            :                         break;
     138                 :            :         }
     139                 :            : 
     140                 :          0 :         return i;
     141                 :            : }
     142                 :            : 
     143                 :          0 : static int32_t sxe2_tx_done_cleanup_normal(struct sxe2_tx_queue *txq, uint32_t free_cnt)
     144                 :            : {
     145                 :          0 :         struct sxe2_tx_buffer *buffer_ring = txq->buffer_ring;
     146                 :          0 :         int32_t ret;
     147                 :          0 :         uint16_t clean_last_idx, clean_idx;
     148                 :          0 :         uint16_t clean_last, clean_once;
     149                 :          0 :         uint16_t pkt_cnt, i;
     150                 :            : 
     151   [ #  #  #  # ]:          0 :         if (txq->desc_free_num == 0 && sxe2_tx_cleanup(txq) != 0) {
     152                 :          0 :                 ret = 0;
     153                 :          0 :                 goto l_end;
     154                 :            :         }
     155                 :            : 
     156         [ #  # ]:          0 :         if (free_cnt == 0)
     157                 :          0 :                 free_cnt = txq->ring_depth;
     158                 :            : 
     159                 :          0 :         clean_last_idx = txq->next_use;
     160                 :          0 :         clean_idx = buffer_ring[clean_last_idx].next_id;
     161                 :          0 :         clean_once = txq->desc_free_num;
     162                 :          0 :         clean_last = txq->desc_free_num;
     163                 :            : 
     164         [ #  # ]:          0 :         for (pkt_cnt = 0; pkt_cnt < free_cnt;) {
     165                 :          0 :                 for (i = 0; ((i < clean_once) &&
     166   [ #  #  #  #  :          0 :                              (pkt_cnt < free_cnt) &&
                   #  # ]
     167                 :          0 :                              clean_idx != clean_last_idx); ++i) {
     168         [ #  # ]:          0 :                         if (buffer_ring[clean_idx].mbuf != NULL) {
     169                 :          0 :                                 rte_pktmbuf_free_seg(buffer_ring[clean_idx].mbuf);
     170                 :          0 :                                 buffer_ring[clean_idx].mbuf = NULL;
     171         [ #  # ]:          0 :                                 if (buffer_ring[clean_idx].last_id == clean_idx)
     172                 :          0 :                                         pkt_cnt++;
     173                 :            :                         }
     174                 :          0 :                         clean_idx = buffer_ring[clean_idx].next_id;
     175                 :            :                 }
     176                 :            : 
     177   [ #  #  #  # ]:          0 :                 if ((txq->rs_thresh > (txq->ring_depth - txq->desc_free_num)) ||
     178                 :            :                     clean_idx == clean_last_idx)
     179                 :            :                         break;
     180                 :            : 
     181         [ #  # ]:          0 :                 if (pkt_cnt < free_cnt) {
     182         [ #  # ]:          0 :                         if (sxe2_tx_cleanup(txq) != 0)
     183                 :            :                                 break;
     184                 :            : 
     185                 :          0 :                         clean_once = txq->desc_free_num - clean_last;
     186                 :          0 :                         clean_last = txq->desc_free_num;
     187                 :            :                 }
     188                 :            :         }
     189                 :            : 
     190                 :          0 :         ret = pkt_cnt;
     191                 :          0 : l_end:
     192                 :          0 :         return ret;
     193                 :            : }
     194                 :            : 
     195                 :          0 : int32_t sxe2_tx_done_cleanup(void *tx_queue, uint32_t free_cnt)
     196                 :            : {
     197                 :          0 :         struct sxe2_tx_queue *txq = (struct sxe2_tx_queue *)tx_queue;
     198                 :          0 :         struct sxe2_adapter *adapter;
     199                 :          0 :         int32_t ret;
     200                 :            : 
     201         [ #  # ]:          0 :         if (txq == NULL) {
     202                 :          0 :                 ret = 0;
     203                 :          0 :                 goto l_end;
     204                 :            :         }
     205                 :            : 
     206                 :          0 :         adapter = txq->vsi->adapter;
     207         [ #  # ]:          0 :         if (adapter->q_ctxt.tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK)
     208                 :            :                 ret = -ENOTSUP;
     209         [ #  # ]:          0 :         else if (adapter->q_ctxt.tx_mode_flags & SXE2_TX_MODE_SIMPLE_BATCH)
     210                 :          0 :                 ret = sxe2_tx_done_cleanup_simple(txq, free_cnt);
     211                 :            :         else
     212                 :          0 :                 ret = sxe2_tx_done_cleanup_normal(txq, free_cnt);
     213                 :            : 
     214                 :          0 :         PMD_LOG_DEBUG(TX, "TX cleanup done desc queue_id=%u free_cnt=%d.",
     215                 :            :                                 txq->queue_id, ret);
     216                 :            : 
     217                 :          0 : l_end:
     218                 :          0 :         return ret;
     219                 :            : }
     220                 :            : 
     221                 :            : static __rte_always_inline uint32_t
     222                 :            : sxe2_tx_pkt_data_desc_count(struct rte_mbuf *tx_pkt)
     223                 :            : {
     224                 :            :         struct rte_mbuf *m_seg = tx_pkt;
     225                 :            :         uint32_t count = 0;
     226                 :            : 
     227         [ #  # ]:          0 :         while (m_seg != NULL) {
     228                 :          0 :                 count += SXE2_DIV_ROUND_UP(m_seg->data_len,
     229                 :            :                                 SXE2_TX_MAX_DATA_NUM_PER_DESC);
     230                 :          0 :                 m_seg = m_seg->next;
     231                 :            :         }
     232                 :            : 
     233                 :          0 :         return count;
     234                 :            : }
     235                 :            : 
     236                 :            : static __rte_always_inline void
     237                 :          0 : sxe2_tx_desc_checksum_fill(uint64_t offloads, uint32_t *desc_cmd, uint32_t *desc_offset,
     238                 :            :                 union sxe2_tx_offload_info ol_info)
     239                 :            : {
     240                 :          0 :         if (offloads & RTE_MBUF_F_TX_IP_CKSUM) {
     241                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_IIPT_IPV4_CSUM;
     242                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_IPLEN_VAL(ol_info.l3_len);
     243         [ #  # ]:          0 :         } else if (offloads & RTE_MBUF_F_TX_IPV4) {
     244                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_IIPT_IPV4;
     245                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_IPLEN_VAL(ol_info.l3_len);
     246         [ #  # ]:          0 :         } else if (offloads & RTE_MBUF_F_TX_IPV6) {
     247                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_IIPT_IPV6;
     248                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_IPLEN_VAL(ol_info.l3_len);
     249                 :            :         }
     250                 :            : 
     251         [ #  # ]:          0 :         if (offloads & RTE_MBUF_F_TX_TCP_SEG) {
     252                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_TCP;
     253                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
     254                 :          0 :                 goto l_end;
     255                 :            :         }
     256                 :            : 
     257         [ #  # ]:          0 :         if (offloads & RTE_MBUF_F_TX_UDP_SEG) {
     258                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_UDP;
     259                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
     260                 :          0 :                 goto l_end;
     261                 :            :         }
     262                 :            : 
     263   [ #  #  #  # ]:          0 :         switch (offloads & RTE_MBUF_F_TX_L4_MASK) {
     264                 :          0 :         case RTE_MBUF_F_TX_TCP_CKSUM:
     265                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_TCP;
     266                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
     267                 :          0 :                 break;
     268                 :          0 :         case RTE_MBUF_F_TX_SCTP_CKSUM:
     269                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_SCTP;
     270                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
     271                 :          0 :                 break;
     272                 :          0 :         case RTE_MBUF_F_TX_UDP_CKSUM:
     273                 :          0 :                 *desc_cmd    |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_UDP;
     274                 :          0 :                 *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
     275                 :          0 :                 break;
     276                 :            :         default:
     277                 :            : 
     278                 :            :                 break;
     279                 :            :         }
     280                 :            : 
     281                 :          0 : l_end:
     282                 :          0 :         return;
     283                 :            : }
     284                 :            : 
     285                 :            : static __rte_always_inline uint64_t
     286                 :          0 : sxe2_tx_data_desc_build_cobt(uint32_t cmd, uint32_t offset, uint16_t buf_size, uint16_t l2tag)
     287                 :            : {
     288                 :          0 :         return rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DATA |
     289                 :            :                         (((uint64_t)cmd)      << SXE2_TX_DATA_DESC_CMD_SHIFT) |
     290                 :            :                         (((uint64_t)offset)   << SXE2_TX_DATA_DESC_OFFSET_SHIFT) |
     291                 :            :                         (((uint64_t)buf_size) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT) |
     292                 :            :                         (((uint64_t)l2tag)    << SXE2_TX_DATA_DESC_L2TAG1_SHIFT));
     293                 :            : }
     294                 :            : 
     295                 :          0 : uint16_t sxe2_tx_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
     296                 :            : {
     297                 :          0 :         struct sxe2_tx_queue *txq = tx_queue;
     298                 :          0 :         struct sxe2_tx_buffer *buffer_ring;
     299                 :          0 :         struct sxe2_tx_buffer *buffer;
     300                 :          0 :         struct sxe2_tx_buffer *next_buffer;
     301                 :          0 :         struct rte_mbuf *tx_pkt;
     302                 :          0 :         struct rte_mbuf *m_seg;
     303                 :          0 :         volatile union sxe2_tx_data_desc *desc_ring;
     304                 :          0 :         volatile union sxe2_tx_data_desc *desc;
     305                 :          0 :         volatile struct sxe2_tx_context_desc *ctxt_desc;
     306                 :          0 :         union sxe2_tx_offload_info ol_info;
     307                 :          0 :         struct sxe2_vsi *vsi = txq->vsi;
     308                 :          0 :         rte_iova_t buf_dma_addr;
     309                 :          0 :         uint64_t offloads;
     310                 :          0 :         uint64_t desc_type_cmd_tso_mss;
     311                 :          0 :         uint32_t desc_cmd;
     312                 :          0 :         uint32_t desc_offset;
     313                 :          0 :         uint32_t desc_tag;
     314                 :          0 :         uint32_t desc_tunneling_params;
     315                 :          0 :         uint16_t ipsec_offset;
     316                 :          0 :         uint16_t ctxt_desc_num;
     317                 :          0 :         uint32_t desc_sum_num;
     318                 :          0 :         uint16_t tx_num;
     319                 :          0 :         uint16_t seg_len;
     320                 :          0 :         uint16_t next_use;
     321                 :          0 :         uint16_t last_use;
     322                 :          0 :         uint16_t desc_l2tag2;
     323                 :            : 
     324                 :          0 :         buffer_ring = txq->buffer_ring;
     325                 :          0 :         desc_ring   = txq->desc_ring;
     326                 :          0 :         next_use    = txq->next_use;
     327                 :          0 :         buffer      = &buffer_ring[next_use];
     328                 :            : 
     329         [ #  # ]:          0 :         if (txq->desc_free_num < txq->free_thresh)
     330                 :          0 :                 (void)sxe2_tx_cleanup(txq);
     331                 :            : 
     332         [ #  # ]:          0 :         for (tx_num = 0; tx_num < nb_pkts; tx_num++) {
     333                 :          0 :                 tx_pkt = *tx_pkts++;
     334                 :          0 :                 desc_cmd              = 0;
     335                 :          0 :                 desc_offset           = 0;
     336                 :          0 :                 desc_tag              = 0;
     337                 :          0 :                 desc_tunneling_params = 0;
     338                 :          0 :                 ipsec_offset          = 0;
     339                 :          0 :                 offloads              = tx_pkt->ol_flags;
     340                 :          0 :                 ol_info.l2_len        = tx_pkt->l2_len;
     341                 :          0 :                 ol_info.l3_len        = tx_pkt->l3_len;
     342                 :          0 :                 ol_info.l4_len        = tx_pkt->l4_len;
     343                 :          0 :                 ol_info.tso_segsz     = tx_pkt->tso_segsz;
     344                 :          0 :                 ol_info.outer_l2_len  = tx_pkt->outer_l2_len;
     345                 :          0 :                 ol_info.outer_l3_len  = tx_pkt->outer_l3_len;
     346                 :            : 
     347                 :          0 :                 ctxt_desc_num = (offloads &
     348                 :          0 :                                 SXE2_TX_OFFLOAD_CTXT_NEEDCK_MASK) ? 1 : 0;
     349         [ #  # ]:          0 :                 if (unlikely(vsi->vsi_type == SXE2_VSI_T_DPDK_ESW))
     350                 :          0 :                         ctxt_desc_num = 1;
     351                 :            : 
     352         [ #  # ]:          0 :                 if (offloads & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG))
     353                 :          0 :                         desc_sum_num = sxe2_tx_pkt_data_desc_count(tx_pkt) + ctxt_desc_num;
     354                 :            :                 else
     355                 :          0 :                         desc_sum_num = tx_pkt->nb_segs + ctxt_desc_num;
     356                 :            : 
     357                 :          0 :                 last_use = next_use + desc_sum_num - 1;
     358         [ #  # ]:          0 :                 if (last_use >= txq->ring_depth)
     359                 :          0 :                         last_use = last_use - txq->ring_depth;
     360                 :            : 
     361         [ #  # ]:          0 :                 if (desc_sum_num > txq->desc_free_num) {
     362         [ #  # ]:          0 :                         if (unlikely(sxe2_tx_cleanup(txq) != 0))
     363                 :          0 :                                 goto l_cleanup_exit;
     364                 :            : 
     365         [ #  # ]:          0 :                         if (unlikely(desc_sum_num > txq->rs_thresh)) {
     366         [ #  # ]:          0 :                                 while (desc_sum_num > txq->desc_free_num) {
     367         [ #  # ]:          0 :                                         if (unlikely(sxe2_tx_cleanup(txq) != 0))
     368                 :          0 :                                                 goto l_cleanup_exit;
     369                 :            :                                 }
     370                 :            :                         }
     371                 :            :                 }
     372                 :            : 
     373                 :          0 :                 desc_offset |= SXE2_TX_DATA_DESC_MACLEN_VAL(ol_info.l2_len);
     374                 :            : 
     375         [ #  # ]:          0 :                 if (offloads & SXE2_TX_OFFLOAD_CKSUM_MASK) {
     376         [ #  # ]:          0 :                         sxe2_tx_desc_checksum_fill(offloads, &desc_cmd,
     377                 :            :                                         &desc_offset, ol_info);
     378                 :            :                 }
     379                 :            : 
     380         [ #  # ]:          0 :                 if (offloads & (RTE_MBUF_F_TX_VLAN | RTE_MBUF_F_TX_QINQ)) {
     381                 :          0 :                         desc_cmd |= SXE2_TX_DATA_DESC_CMD_IL2TAG1;
     382                 :          0 :                         desc_tag = tx_pkt->vlan_tci;
     383                 :            :                 }
     384                 :            : 
     385         [ #  # ]:          0 :                 if (ctxt_desc_num) {
     386                 :          0 :                         ctxt_desc = (volatile struct sxe2_tx_context_desc *)
     387                 :          0 :                                                         &desc_ring[next_use];
     388                 :          0 :                         desc_l2tag2 = 0;
     389                 :          0 :                         desc_type_cmd_tso_mss = SXE2_TX_DESC_DTYPE_CTXT;
     390                 :            : 
     391                 :          0 :                         next_buffer = &buffer_ring[buffer->next_id];
     392         [ #  # ]:          0 :                         RTE_MBUF_PREFETCH_TO_FREE(next_buffer->mbuf);
     393                 :            : 
     394         [ #  # ]:          0 :                         if (buffer->mbuf) {
     395         [ #  # ]:          0 :                                 rte_pktmbuf_free_seg(buffer->mbuf);
     396                 :          0 :                                 buffer->mbuf = NULL;
     397                 :            :                         }
     398                 :            : 
     399         [ #  # ]:          0 :                         if (offloads & RTE_MBUF_F_TX_QINQ) {
     400                 :          0 :                                 desc_l2tag2 = tx_pkt->vlan_tci_outer;
     401                 :          0 :                                 desc_type_cmd_tso_mss |= SXE2_TX_CTXT_DESC_CMD_IL2TAG2_MASK;
     402                 :            :                         }
     403                 :            : 
     404                 :          0 :                         ctxt_desc->tunneling_params =
     405                 :            :                                 rte_cpu_to_le_32(desc_tunneling_params);
     406                 :          0 :                         ctxt_desc->l2tag2 = rte_cpu_to_le_16(desc_l2tag2);
     407                 :          0 :                         ctxt_desc->type_cmd_tso_mss = rte_cpu_to_le_64(desc_type_cmd_tso_mss);
     408                 :          0 :                         ctxt_desc->ipsec_offset = rte_cpu_to_le_16(ipsec_offset);
     409                 :            : 
     410                 :          0 :                         buffer->last_id = last_use;
     411                 :          0 :                         next_use        = buffer->next_id;
     412                 :          0 :                         buffer          = next_buffer;
     413                 :            :                 }
     414                 :            : 
     415                 :            :                 m_seg = tx_pkt;
     416                 :            : 
     417                 :          0 :                 do {
     418                 :          0 :                         desc = &desc_ring[next_use];
     419                 :          0 :                         next_buffer = &buffer_ring[buffer->next_id];
     420         [ #  # ]:          0 :                         RTE_MBUF_PREFETCH_TO_FREE(next_buffer->mbuf);
     421         [ #  # ]:          0 :                         if (buffer->mbuf) {
     422         [ #  # ]:          0 :                                 rte_pktmbuf_free_seg(buffer->mbuf);
     423                 :          0 :                                 buffer->mbuf = NULL;
     424                 :            :                         }
     425                 :            : 
     426                 :          0 :                         buffer->mbuf = m_seg;
     427                 :          0 :                         seg_len = m_seg->data_len;
     428                 :          0 :                         buf_dma_addr = rte_mbuf_data_iova(m_seg);
     429                 :          0 :                         while ((offloads & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG)) &&
     430         [ #  # ]:          0 :                                         unlikely(seg_len > SXE2_TX_MAX_DATA_NUM_PER_DESC)) {
     431                 :          0 :                                 desc->read.buf_addr = rte_cpu_to_le_64(buf_dma_addr);
     432                 :          0 :                                 desc->read.type_cmd_off_bsz_l2t =
     433                 :          0 :                                         sxe2_tx_data_desc_build_cobt(desc_cmd, desc_offset,
     434                 :            :                                                 SXE2_TX_MAX_DATA_NUM_PER_DESC,
     435                 :            :                                                 desc_tag);
     436                 :          0 :                                 buf_dma_addr += SXE2_TX_MAX_DATA_NUM_PER_DESC;
     437                 :          0 :                                 seg_len      -= SXE2_TX_MAX_DATA_NUM_PER_DESC;
     438                 :          0 :                                 buffer->last_id = last_use;
     439                 :          0 :                                 next_use        = buffer->next_id;
     440                 :          0 :                                 buffer          = next_buffer;
     441                 :          0 :                                 desc            = &desc_ring[next_use];
     442                 :          0 :                                 next_buffer     = &buffer_ring[buffer->next_id];
     443   [ #  #  #  # ]:          0 :                                 RTE_MBUF_PREFETCH_TO_FREE(next_buffer->mbuf);
     444                 :            :                         }
     445                 :            : 
     446                 :          0 :                         desc->read.buf_addr = rte_cpu_to_le_64(buf_dma_addr);
     447                 :          0 :                         desc->read.type_cmd_off_bsz_l2t =
     448                 :          0 :                                 sxe2_tx_data_desc_build_cobt(desc_cmd,
     449                 :            :                                         desc_offset, seg_len, desc_tag);
     450                 :            : 
     451                 :          0 :                         buffer->last_id = last_use;
     452                 :          0 :                         next_use        = buffer->next_id;
     453                 :          0 :                         buffer          = next_buffer;
     454                 :            : 
     455                 :          0 :                         m_seg = m_seg->next;
     456         [ #  # ]:          0 :                 } while (m_seg);
     457                 :            : 
     458                 :          0 :                 desc_cmd |= SXE2_TX_DATA_DESC_CMD_EOP;
     459                 :          0 :                 txq->desc_used_num += desc_sum_num;
     460                 :          0 :                 txq->desc_free_num -= desc_sum_num;
     461                 :            : 
     462         [ #  # ]:          0 :                 if (txq->desc_used_num >= txq->rs_thresh) {
     463                 :          0 :                         PMD_LOG_DEBUG(TX, "Tx pkts set RS bit."
     464                 :            :                                         "last_use=%u port_id=%u, queue_id=%u",
     465                 :            :                                         last_use, txq->port_id, txq->queue_id);
     466                 :          0 :                         desc_cmd |= SXE2_TX_DATA_DESC_CMD_RS;
     467                 :          0 :                         txq->desc_used_num = 0;
     468                 :            :                 }
     469                 :            : 
     470                 :          0 :                 desc->read.type_cmd_off_bsz_l2t |=
     471                 :          0 :                         rte_cpu_to_le_64(((uint64_t)desc_cmd) << SXE2_TX_DATA_DESC_CMD_SHIFT);
     472                 :            :         }
     473                 :          0 :         goto l_end_of_tx;
     474                 :            : 
     475                 :          0 : l_cleanup_exit:
     476         [ #  # ]:          0 :         if (tx_num == 0)
     477                 :            :                 return 0;
     478                 :          0 : l_end_of_tx:
     479                 :          0 :         SXE2_PCI_REG_WRITE_WC(txq->tdt_reg_addr, next_use);
     480                 :          0 :         PMD_LOG_DEBUG(TX, "port_id=%u queue_id=%u next_use=%u send_pkts=%u",
     481                 :            :                         txq->port_id, txq->queue_id, next_use, tx_num);
     482                 :            : 
     483                 :          0 :         txq->next_use = next_use;
     484                 :          0 :         return tx_num;
     485                 :            : }
     486                 :            : 
     487                 :            : static __rte_always_inline void
     488                 :          0 : sxe2_tx_data_desc_fill(volatile union sxe2_tx_data_desc *desc,
     489                 :            :                 struct rte_mbuf **tx_pkts)
     490                 :            : {
     491                 :          0 :         rte_iova_t buf_dma_addr;
     492                 :          0 :         uint32_t desc_offset;
     493                 :          0 :         buf_dma_addr = rte_mbuf_data_iova(*tx_pkts);
     494                 :          0 :         desc->read.buf_addr = rte_cpu_to_le_64(buf_dma_addr);
     495                 :          0 :         desc_offset = SXE2_TX_DATA_DESC_MACLEN_VAL((*tx_pkts)->l2_len);
     496                 :          0 :         desc->read.type_cmd_off_bsz_l2t =
     497                 :          0 :                                 sxe2_tx_data_desc_build_cobt(SXE2_TX_DATA_DESC_CMD_EOP,
     498                 :          0 :                                         desc_offset, (*tx_pkts)->data_len, 0);
     499                 :            : }
     500                 :            : static __rte_always_inline void
     501                 :          0 : sxe2_tx_data_desc_fill_batch(volatile union sxe2_tx_data_desc *desc,
     502                 :            :                 struct rte_mbuf **tx_pkts)
     503                 :            : {
     504                 :          0 :         rte_iova_t buf_dma_addr;
     505                 :          0 :         uint32_t i;
     506                 :          0 :         uint32_t desc_offset;
     507         [ #  # ]:          0 :         for (i = 0; i < SXE2_TX_FILL_PER_LOOP; ++i, ++desc, ++tx_pkts) {
     508                 :          0 :                 buf_dma_addr = rte_mbuf_data_iova(*tx_pkts);
     509                 :          0 :                 desc->read.buf_addr = rte_cpu_to_le_64(buf_dma_addr);
     510                 :          0 :                 desc_offset = SXE2_TX_DATA_DESC_MACLEN_VAL((*tx_pkts)->l2_len);
     511                 :          0 :                 desc->read.type_cmd_off_bsz_l2t =
     512                 :          0 :                         sxe2_tx_data_desc_build_cobt(SXE2_TX_DATA_DESC_CMD_EOP,
     513                 :            :                                         desc_offset,
     514                 :          0 :                                         (*tx_pkts)->data_len,
     515                 :            :                                         0);
     516                 :            :         }
     517                 :            : }
     518                 :            : 
     519                 :          0 : static inline void sxe2_tx_ring_fill(struct sxe2_tx_queue *txq,
     520                 :            :                                 struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
     521                 :            : {
     522                 :          0 :         struct sxe2_tx_buffer *buffer = &txq->buffer_ring[txq->next_use];
     523                 :          0 :         volatile union sxe2_tx_data_desc *desc = &txq->desc_ring[txq->next_use];
     524                 :          0 :         uint32_t i, j;
     525                 :          0 :         uint32_t        mainpart;
     526                 :          0 :         uint32_t leftover;
     527                 :          0 :         mainpart = nb_pkts & ((uint32_t)~SXE2_TX_FILL_PER_LOOP_MASK);
     528                 :          0 :         leftover = nb_pkts & ((uint32_t)SXE2_TX_FILL_PER_LOOP_MASK);
     529         [ #  # ]:          0 :         for (i = 0; i < mainpart; i += SXE2_TX_FILL_PER_LOOP) {
     530         [ #  # ]:          0 :                 for (j = 0; j < SXE2_TX_FILL_PER_LOOP; ++j)
     531                 :          0 :                         (buffer + i + j)->mbuf = *(tx_pkts + i + j);
     532                 :          0 :                 sxe2_tx_data_desc_fill_batch(desc + i, tx_pkts + i);
     533                 :            :         }
     534         [ #  # ]:          0 :         if (unlikely(leftover > 0)) {
     535         [ #  # ]:          0 :                 for (i = 0; i < leftover; ++i) {
     536                 :          0 :                         (buffer + mainpart + i)->mbuf = *(tx_pkts + mainpart + i);
     537                 :          0 :                         sxe2_tx_data_desc_fill(desc + mainpart + i,
     538                 :            :                                         tx_pkts + mainpart + i);
     539                 :            :                 }
     540                 :            :         }
     541                 :          0 : }
     542                 :            : 
     543                 :          0 : static inline uint16_t sxe2_tx_pkts_batch(void *tx_queue,
     544                 :            :                         struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
     545                 :            : {
     546                 :          0 :         struct sxe2_tx_queue *txq = (struct sxe2_tx_queue *)tx_queue;
     547                 :          0 :         volatile union sxe2_tx_data_desc *desc_ring = txq->desc_ring;
     548                 :          0 :         uint16_t res_num = 0;
     549         [ #  # ]:          0 :         if (txq->desc_free_num < txq->free_thresh)
     550         [ #  # ]:          0 :                 (void)sxe2_tx_bufs_free(txq);
     551                 :          0 :         nb_pkts = RTE_MIN(txq->desc_free_num, nb_pkts);
     552         [ #  # ]:          0 :         if (unlikely(nb_pkts == 0)) {
     553                 :          0 :                 PMD_LOG_DEBUG(TX, "Tx batch: may not enough free desc, "
     554                 :            :                                 "free_desc=%u, need_tx_pkts=%u",
     555                 :            :                                 txq->desc_free_num, nb_pkts);
     556                 :          0 :                 goto l_end;
     557                 :            :         }
     558                 :          0 :         txq->desc_free_num -= nb_pkts;
     559         [ #  # ]:          0 :         if ((txq->next_use + nb_pkts) > txq->ring_depth) {
     560                 :          0 :                 res_num = txq->ring_depth - txq->next_use;
     561                 :          0 :                 sxe2_tx_ring_fill(txq, tx_pkts, res_num);
     562                 :          0 :                 desc_ring[txq->next_rs].read.type_cmd_off_bsz_l2t |=
     563                 :            :                                 rte_cpu_to_le_64(SXE2_TX_DATA_DESC_CMD_RS_MASK);
     564                 :          0 :                 txq->next_rs = txq->rs_thresh - 1;
     565                 :          0 :                 txq->next_use = 0;
     566                 :            :         }
     567                 :          0 :         sxe2_tx_ring_fill(txq, tx_pkts + res_num, nb_pkts - res_num);
     568                 :          0 :         txq->next_use = txq->next_use + (nb_pkts - res_num);
     569         [ #  # ]:          0 :         if (txq->next_use > txq->next_rs) {
     570                 :          0 :                 desc_ring[txq->next_rs].read.type_cmd_off_bsz_l2t |=
     571                 :            :                                 rte_cpu_to_le_64(SXE2_TX_DATA_DESC_CMD_RS_MASK);
     572                 :          0 :                 txq->next_rs += txq->rs_thresh;
     573         [ #  # ]:          0 :                 if (txq->next_rs >= txq->ring_depth)
     574                 :          0 :                         txq->next_rs = txq->rs_thresh - 1;
     575                 :            :         }
     576         [ #  # ]:          0 :         if (txq->next_use >= txq->ring_depth)
     577                 :          0 :                 txq->next_use = 0;
     578                 :          0 :         PMD_LOG_DEBUG(TX, "port_id=%u queue_id=%u next_use=%u send_pkts=%u",
     579                 :            :                         txq->port_id, txq->queue_id, txq->next_use, nb_pkts);
     580                 :          0 :         SXE2_PCI_REG_WRITE_WC(txq->tdt_reg_addr, txq->next_use);
     581                 :          0 : l_end:
     582                 :          0 :         return nb_pkts;
     583                 :            : }
     584                 :            : 
     585                 :          0 : uint16_t sxe2_tx_pkts_simple(void *tx_queue,
     586                 :            :                         struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
     587                 :            : {
     588                 :          0 :         uint16_t tx_done_num;
     589                 :          0 :         uint16_t tx_once_num;
     590                 :          0 :         uint16_t tx_need_num;
     591         [ #  # ]:          0 :         if (likely(nb_pkts <= SXE2_TX_PKTS_BURST_BATCH_NUM)) {
     592                 :          0 :                 tx_done_num = sxe2_tx_pkts_batch(tx_queue,
     593                 :            :                                 tx_pkts, nb_pkts);
     594                 :          0 :                 goto l_end;
     595                 :            :         }
     596                 :            :         tx_done_num = 0;
     597         [ #  # ]:          0 :         while (nb_pkts) {
     598                 :          0 :                 tx_need_num = RTE_MIN(nb_pkts, SXE2_TX_PKTS_BURST_BATCH_NUM);
     599                 :          0 :                 tx_once_num = sxe2_tx_pkts_batch(tx_queue,
     600                 :          0 :                                                  &tx_pkts[tx_done_num],
     601                 :            :                                                  tx_need_num);
     602                 :          0 :                 nb_pkts -= tx_once_num;
     603                 :          0 :                 tx_done_num += tx_once_num;
     604         [ #  # ]:          0 :                 if (tx_once_num < tx_need_num)
     605                 :            :                         break;
     606                 :            :         }
     607                 :          0 : l_end:
     608                 :          0 :         return tx_done_num;
     609                 :            : }
     610                 :            : 
     611                 :            : static inline void
     612                 :          0 : sxe2_update_rx_tail(struct sxe2_rx_queue *rxq, uint16_t hold_num, uint16_t rx_id)
     613                 :            : {
     614                 :          0 :         hold_num += rxq->hold_num;
     615                 :            : 
     616         [ #  # ]:          0 :         if (hold_num > rxq->rx_free_thresh) {
     617         [ #  # ]:          0 :                 rx_id = (uint16_t)((rx_id == 0) ? (rxq->ring_depth - 1) : (rx_id - 1));
     618                 :          0 :                 SXE2_PCI_REG_WRITE_WC(rxq->rdt_reg_addr, rx_id);
     619                 :            :                 hold_num = 0;
     620                 :            :         }
     621                 :          0 :         rxq->hold_num = hold_num;
     622                 :          0 : }
     623                 :            : 
     624                 :            : static inline uint64_t
     625                 :          0 : sxe2_rx_desc_error_para(__rte_unused struct sxe2_rx_queue *rxq,
     626                 :            :                 union sxe2_rx_desc *desc)
     627                 :            : {
     628                 :          0 :         uint64_t flags = 0;
     629                 :          0 :         uint64_t desc_qw1 = rte_le_to_cpu_64(desc->wb.status_err_ptype_len);
     630                 :            : 
     631         [ #  # ]:          0 :         if (unlikely(0 == (desc_qw1 & SXE2_RX_DESC_STATUS_L3L4_P_MASK)))
     632                 :          0 :                 goto l_end;
     633                 :            : 
     634         [ #  # ]:          0 :         if (likely(0 == (desc->wb.rxdid_src & SXE2_RX_DESC_EUDPE_MASK)))
     635                 :            :                 flags = RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD;
     636                 :            :         else
     637                 :          0 :                 flags = RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD;
     638                 :            : 
     639         [ #  # ]:          0 :         if (likely(0 == (desc_qw1 & SXE2_RX_DESC_QW1_ERRORS_MASK))) {
     640                 :          0 :                 flags |= (RTE_MBUF_F_RX_IP_CKSUM_GOOD |
     641                 :            :                                 RTE_MBUF_F_RX_L4_CKSUM_GOOD |
     642                 :            :                                 RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD);
     643                 :          0 :                 goto l_end;
     644                 :            :         }
     645                 :            : 
     646         [ #  # ]:          0 :         if (likely(0 == (desc_qw1 & SXE2_RX_DESC_ERROR_CSUM_IPE_MASK)))
     647                 :          0 :                 flags |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
     648                 :            :         else
     649                 :          0 :                 flags |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
     650                 :            : 
     651         [ #  # ]:          0 :         if (likely(0 == (desc_qw1 & SXE2_RX_DESC_ERROR_CSUM_L4_MASK)))
     652                 :          0 :                 flags |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
     653                 :            :         else
     654                 :          0 :                 flags |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
     655                 :            : 
     656         [ #  # ]:          0 :         if (unlikely(0 != (desc_qw1 & SXE2_RX_DESC_ERROR_CSUM_EIP_MASK)))
     657                 :          0 :                 flags |= RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD;
     658                 :            : 
     659                 :          0 : l_end:
     660                 :          0 :         return flags;
     661                 :            : }
     662                 :            : 
     663                 :            : static __rte_always_inline void
     664                 :          0 : sxe2_rx_mbuf_common_fields_fill(struct sxe2_rx_queue *rxq, struct rte_mbuf *mbuf,
     665                 :            :                 union sxe2_rx_desc *rxd)
     666                 :            : {
     667                 :          0 :         uint32_t *ptype_tbl = rxq->vsi->adapter->ptype_tbl;
     668                 :          0 :         uint64_t qword1;
     669                 :          0 :         uint64_t pkt_flags;
     670                 :          0 :         qword1 = rte_le_to_cpu_64(rxd->wb.status_err_ptype_len);
     671                 :            : 
     672                 :          0 :         mbuf->ol_flags = 0;
     673                 :          0 :         mbuf->packet_type = ptype_tbl[SXE2_RX_DESC_PTYPE_VAL_GET(qword1)];
     674                 :            : 
     675                 :          0 :         pkt_flags = sxe2_rx_desc_error_para(rxq, rxd);
     676                 :            : 
     677                 :          0 :         mbuf->ol_flags |= pkt_flags;
     678                 :            : }
     679                 :            : 
     680                 :            : static __rte_always_inline void
     681                 :          0 : sxe2_rx_sw_stats_update(struct sxe2_rx_queue *rxq, struct rte_mbuf *mbuf,
     682                 :            :                 union sxe2_rx_desc *rxd)
     683                 :            : {
     684                 :          0 :         uint64_t qword1 = rte_le_to_cpu_64(rxd->wb.status_err_ptype_len);
     685                 :          0 :         rte_atomic_fetch_add_explicit(&rxq->sw_stats.pkts, 1,
     686                 :            :                 rte_memory_order_relaxed);
     687                 :          0 :         rte_atomic_fetch_add_explicit(&rxq->sw_stats.bytes,
     688                 :            :                         mbuf->pkt_len + RTE_ETHER_CRC_LEN,
     689                 :            :                         rte_memory_order_relaxed);
     690                 :          0 :         switch (SXE2_RX_DESC_STATUS_UMBCAST_VAL_GET(qword1)) {
     691                 :          0 :         case SXE2_RX_DESC_STATUS_UNICAST:
     692                 :          0 :                 rte_atomic_fetch_add_explicit(&rxq->sw_stats.unicast_pkts, 1,
     693                 :            :                         rte_memory_order_relaxed);
     694                 :          0 :                 break;
     695                 :          0 :         case SXE2_RX_DESC_STATUS_MULTICAST:
     696                 :          0 :                 rte_atomic_fetch_add_explicit(&rxq->sw_stats.multicast_pkts, 1,
     697                 :            :                         rte_memory_order_relaxed);
     698                 :          0 :                 break;
     699                 :          0 :         case SXE2_RX_DESC_STATUS_BROADCAST:
     700                 :          0 :                 rte_atomic_fetch_add_explicit(&rxq->sw_stats.broadcast_pkts, 1,
     701                 :            :                         rte_memory_order_relaxed);
     702                 :          0 :                 break;
     703                 :            :         default:
     704                 :            :                 break;
     705                 :            :         }
     706                 :            : }
     707                 :            : 
     708                 :          0 : uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
     709                 :            : {
     710                 :          0 :         struct sxe2_rx_queue *rxq = (struct sxe2_rx_queue *)rx_queue;
     711                 :          0 :         volatile union sxe2_rx_desc *desc_ring;
     712                 :          0 :         volatile union sxe2_rx_desc *desc;
     713                 :          0 :         union sxe2_rx_desc desc_tmp;
     714                 :          0 :         struct rte_mbuf **buffer_ring;
     715                 :          0 :         struct rte_mbuf **cur_buffer;
     716                 :          0 :         struct rte_mbuf *cur_mbuf;
     717                 :          0 :         struct rte_mbuf *new_mbuf;
     718                 :          0 :         struct rte_mbuf *first_seg;
     719                 :          0 :         struct rte_mbuf *last_seg;
     720                 :          0 :         uint64_t qword1;
     721                 :          0 :         uint16_t done_num;
     722                 :          0 :         uint16_t hold_num;
     723                 :          0 :         uint16_t cur_idx;
     724                 :          0 :         uint16_t pkt_len;
     725                 :            : 
     726                 :          0 :         desc_ring   = rxq->desc_ring;
     727                 :          0 :         buffer_ring = rxq->buffer_ring;
     728                 :          0 :         cur_idx     = rxq->processing_idx;
     729                 :          0 :         first_seg   = rxq->pkt_first_seg;
     730                 :          0 :         last_seg    = rxq->pkt_last_seg;
     731                 :          0 :         done_num    = 0;
     732                 :          0 :         hold_num    = 0;
     733         [ #  # ]:          0 :         while (done_num < nb_pkts) {
     734                 :          0 :                 desc = &desc_ring[cur_idx];
     735                 :          0 :                 qword1 = rte_le_to_cpu_64(desc->wb.status_err_ptype_len);
     736         [ #  # ]:          0 :                 if (0 == (SXE2_RX_DESC_STATUS_DD_MASK & qword1))
     737                 :            :                         break;
     738                 :            : 
     739                 :          0 :                 new_mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
     740         [ #  # ]:          0 :                 if (unlikely(new_mbuf == NULL)) {
     741                 :          0 :                         rxq->vsi->adapter->dev_info.dev_data->rx_mbuf_alloc_failed++;
     742                 :          0 :                         PMD_LOG_INFO(RX, "Rx new_mbuf alloc failed port_id:%u "
     743                 :            :                                         "queue_id:%u", rxq->port_id, rxq->queue_id);
     744                 :          0 :                         break;
     745                 :            :                 }
     746                 :            : 
     747                 :          0 :                 hold_num++;
     748                 :          0 :                 desc_tmp = *desc;
     749                 :          0 :                 cur_buffer = &buffer_ring[cur_idx];
     750                 :          0 :                 cur_idx++;
     751         [ #  # ]:          0 :                 if (unlikely(cur_idx == rxq->ring_depth))
     752                 :          0 :                         cur_idx = 0;
     753                 :            : 
     754                 :          0 :                 rte_prefetch0(buffer_ring[cur_idx]);
     755                 :            : 
     756         [ #  # ]:          0 :                 if (0 == (cur_idx & 0x3)) {
     757                 :          0 :                         rte_prefetch0(&desc_ring[cur_idx]);
     758                 :          0 :                         rte_prefetch0(&buffer_ring[cur_idx]);
     759                 :            :                 }
     760                 :            : 
     761                 :          0 :                 cur_mbuf = *cur_buffer;
     762                 :            : 
     763                 :          0 :                 *cur_buffer = new_mbuf;
     764                 :            : 
     765                 :          0 :                 desc->read.hdr_addr = 0;
     766         [ #  # ]:          0 :                 desc->read.pkt_addr =
     767                 :          0 :                         rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf));
     768                 :            : 
     769                 :          0 :                 pkt_len = SXE2_RX_DESC_PKT_LEN_VAL_GET(qword1);
     770                 :          0 :                 cur_mbuf->data_len = pkt_len;
     771                 :          0 :                 cur_mbuf->data_off = RTE_PKTMBUF_HEADROOM;
     772                 :            : 
     773         [ #  # ]:          0 :                 if (first_seg == NULL) {
     774                 :          0 :                         first_seg = cur_mbuf;
     775                 :          0 :                         first_seg->nb_segs = 1;
     776                 :          0 :                         first_seg->pkt_len = pkt_len;
     777                 :            :                 } else {
     778                 :          0 :                         first_seg->pkt_len += pkt_len;
     779                 :          0 :                         first_seg->nb_segs++;
     780                 :          0 :                         last_seg->next = cur_mbuf;
     781                 :            :                 }
     782                 :            : 
     783         [ #  # ]:          0 :                 if (0 == (qword1 & SXE2_RX_DESC_STATUS_EOP_MASK)) {
     784                 :          0 :                         last_seg = cur_mbuf;
     785                 :          0 :                         continue;
     786                 :            :                 }
     787                 :            : 
     788         [ #  # ]:          0 :                 if (unlikely(qword1 & SXE2_RX_DESC_ERROR_RXE_MASK) ||
     789         [ #  # ]:          0 :                         unlikely(qword1 & SXE2_RX_DESC_ERROR_OVERSIZE_MASK)) {
     790                 :          0 :                         rte_atomic_fetch_add_explicit(&rxq->sw_stats.drop_pkts, 1,
     791                 :            :                                 rte_memory_order_relaxed);
     792                 :          0 :                         rte_atomic_fetch_add_explicit(&rxq->sw_stats.drop_bytes,
     793                 :            :                                 first_seg->pkt_len - rxq->crc_len + RTE_ETHER_CRC_LEN,
     794                 :            :                                 rte_memory_order_relaxed);
     795                 :          0 :                         rte_pktmbuf_free(first_seg);
     796                 :          0 :                         first_seg = NULL;
     797                 :          0 :                         continue;
     798                 :            :                 }
     799                 :            : 
     800                 :          0 :                 cur_mbuf->next = NULL;
     801         [ #  # ]:          0 :                 if (unlikely(rxq->crc_len > 0)) {
     802                 :          0 :                         first_seg->pkt_len -= RTE_ETHER_CRC_LEN;
     803                 :            : 
     804         [ #  # ]:          0 :                         if (pkt_len <= RTE_ETHER_CRC_LEN) {
     805         [ #  # ]:          0 :                                 rte_pktmbuf_free_seg(cur_mbuf);
     806                 :          0 :                                 first_seg->nb_segs--;
     807                 :          0 :                                 last_seg->data_len = last_seg->data_len + pkt_len -
     808                 :            :                                         RTE_ETHER_CRC_LEN;
     809                 :          0 :                                 last_seg->next = NULL;
     810                 :            :                         } else {
     811                 :          0 :                                 cur_mbuf->data_len = pkt_len - RTE_ETHER_CRC_LEN;
     812                 :            :                         }
     813                 :            : 
     814         [ #  # ]:          0 :                 } else if (pkt_len == 0) {
     815         [ #  # ]:          0 :                         rte_pktmbuf_free_seg(cur_mbuf);
     816                 :          0 :                         first_seg->nb_segs--;
     817                 :          0 :                         last_seg->next = NULL;
     818                 :            :                 }
     819                 :            : 
     820                 :          0 :                 rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr, first_seg->data_off));
     821                 :          0 :                 first_seg->port     = rxq->port_id;
     822                 :            : 
     823                 :          0 :                 sxe2_rx_mbuf_common_fields_fill(rxq, first_seg, &desc_tmp);
     824                 :            : 
     825         [ #  # ]:          0 :                 if (rxq->vsi->adapter->devargs.sw_stats_en)
     826   [ #  #  #  # ]:          0 :                         sxe2_rx_sw_stats_update(rxq, first_seg, &desc_tmp);
     827                 :            : 
     828                 :          0 :                 rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr, first_seg->data_off));
     829                 :            : 
     830                 :          0 :                 rx_pkts[done_num] = first_seg;
     831                 :          0 :                 done_num++;
     832                 :            : 
     833                 :          0 :                 first_seg = NULL;
     834                 :            :         }
     835                 :            : 
     836                 :          0 :         rxq->processing_idx = cur_idx;
     837                 :          0 :         rxq->pkt_first_seg  = first_seg;
     838                 :          0 :         rxq->pkt_last_seg   = last_seg;
     839                 :            : 
     840                 :          0 :         sxe2_update_rx_tail(rxq, hold_num, cur_idx);
     841                 :            : 
     842                 :          0 :         return done_num;
     843                 :            : }
     844                 :            : 
     845                 :          0 : uint16_t sxe2_rx_pkts_scattered_split(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
     846                 :            : {
     847                 :          0 :         struct sxe2_rx_queue *rxq = (struct sxe2_rx_queue *)rx_queue;
     848                 :          0 :         volatile union sxe2_rx_desc *desc_ring;
     849                 :          0 :         volatile union sxe2_rx_desc *desc;
     850                 :          0 :         union sxe2_rx_desc desc_tmp;
     851                 :          0 :         struct rte_mbuf **buffer_ring;
     852                 :          0 :         struct rte_mbuf **cur_buffer;
     853                 :          0 :         struct rte_mbuf *cur_mbuf;
     854                 :          0 :         struct rte_mbuf *cur_mbuf_pay;
     855                 :          0 :         struct rte_mbuf *new_mbuf;
     856                 :          0 :         struct rte_mbuf *new_mbuf_pay = NULL;
     857                 :          0 :         struct rte_mbuf *first_seg;
     858                 :          0 :         struct rte_mbuf *last_seg;
     859                 :          0 :         uint64_t qword1;
     860                 :          0 :         uint16_t done_num;
     861                 :          0 :         uint16_t hold_num;
     862                 :          0 :         uint16_t cur_idx;
     863                 :          0 :         uint16_t pkt_len;
     864                 :          0 :         uint16_t hdr_len;
     865                 :            : 
     866                 :          0 :         desc_ring = rxq->desc_ring;
     867                 :          0 :         buffer_ring = rxq->buffer_ring;
     868                 :          0 :         cur_idx = rxq->processing_idx;
     869                 :          0 :         first_seg = rxq->pkt_first_seg;
     870                 :          0 :         last_seg = rxq->pkt_last_seg;
     871                 :          0 :         done_num = 0;
     872                 :          0 :         hold_num = 0;
     873                 :          0 :         new_mbuf = NULL;
     874                 :            : 
     875         [ #  # ]:          0 :         while (done_num < nb_pkts) {
     876                 :          0 :                 desc = &desc_ring[cur_idx];
     877                 :          0 :                 qword1 = rte_le_to_cpu_64(desc->wb.status_err_ptype_len);
     878                 :            : 
     879         [ #  # ]:          0 :                 if (0 == (SXE2_RX_DESC_STATUS_DD_MASK & qword1))
     880                 :            :                         break;
     881                 :            : 
     882   [ #  #  #  # ]:          0 :                 if ((rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) == 0 ||
     883                 :            :                         first_seg == NULL) {
     884                 :          0 :                         new_mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
     885         [ #  # ]:          0 :                         if (unlikely(new_mbuf == NULL)) {
     886                 :          0 :                                 rxq->vsi->adapter->dev_info.dev_data->rx_mbuf_alloc_failed++;
     887                 :          0 :                                 break;
     888                 :            :                         }
     889                 :            :                 }
     890                 :            : 
     891         [ #  # ]:          0 :                 if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
     892                 :          0 :                         new_mbuf_pay = rte_mbuf_raw_alloc(rxq->rx_seg[1].mp);
     893         [ #  # ]:          0 :                         if (unlikely(new_mbuf_pay == NULL)) {
     894                 :          0 :                                 rxq->vsi->adapter->dev_info.dev_data->rx_mbuf_alloc_failed++;
     895         [ #  # ]:          0 :                                 if (new_mbuf != NULL)
     896                 :          0 :                                         rte_pktmbuf_free(new_mbuf);
     897                 :          0 :                                 new_mbuf = NULL;
     898                 :            :                                 break;
     899                 :            :                         }
     900                 :            :                 }
     901                 :            : 
     902                 :          0 :                 hold_num++;
     903                 :          0 :                 desc_tmp = *desc;
     904                 :          0 :                 cur_buffer = &buffer_ring[cur_idx];
     905                 :          0 :                 cur_idx++;
     906         [ #  # ]:          0 :                 if (unlikely(cur_idx == rxq->ring_depth))
     907                 :          0 :                         cur_idx = 0;
     908                 :          0 :                 rte_prefetch0(buffer_ring[cur_idx]);
     909         [ #  # ]:          0 :                 if (0 == (cur_idx & 0x3)) {
     910                 :          0 :                         rte_prefetch0(&desc_ring[cur_idx]);
     911                 :          0 :                         rte_prefetch0(&buffer_ring[cur_idx]);
     912                 :            :                 }
     913                 :          0 :                 cur_mbuf = *cur_buffer;
     914         [ #  # ]:          0 :                 if (0 == (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT)) {
     915                 :          0 :                         *cur_buffer = new_mbuf;
     916                 :          0 :                         desc->read.hdr_addr = 0;
     917                 :          0 :                         desc->read.pkt_addr =
     918                 :          0 :                                 rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf));
     919                 :            :                 } else {
     920         [ #  # ]:          0 :                         if (first_seg == NULL) {
     921                 :          0 :                                 *cur_buffer = new_mbuf;
     922                 :          0 :                                 new_mbuf->next = new_mbuf_pay;
     923                 :          0 :                                 new_mbuf->data_off = RTE_PKTMBUF_HEADROOM;
     924                 :          0 :                                 new_mbuf_pay->next = NULL;
     925                 :          0 :                                 new_mbuf_pay->data_off = RTE_PKTMBUF_HEADROOM;
     926                 :          0 :                                 desc->read.hdr_addr =
     927                 :          0 :                                         rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf));
     928                 :          0 :                                 desc->read.pkt_addr =
     929                 :          0 :                                         rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf_pay));
     930                 :            :                         } else {
     931                 :          0 :                                 cur_mbuf_pay = cur_mbuf->next;
     932                 :          0 :                                 new_mbuf_pay->next = NULL;
     933                 :          0 :                                 new_mbuf_pay->data_off = RTE_PKTMBUF_HEADROOM;
     934                 :          0 :                                 cur_mbuf->next = new_mbuf_pay;
     935                 :          0 :                                 desc->read.hdr_addr =
     936                 :          0 :                                         rte_cpu_to_le_64(rte_mbuf_data_iova_default(cur_mbuf));
     937                 :          0 :                                 desc->read.pkt_addr =
     938                 :          0 :                                         rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf_pay));
     939                 :          0 :                                 cur_mbuf = cur_mbuf_pay;
     940                 :            :                         }
     941                 :            :                 }
     942                 :          0 :                 new_mbuf = NULL;
     943         [ #  # ]:          0 :                 if (0 == (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT)) {
     944                 :          0 :                         pkt_len = SXE2_RX_DESC_PKT_LEN_VAL_GET(qword1);
     945                 :          0 :                         cur_mbuf->data_len = pkt_len;
     946                 :          0 :                         cur_mbuf->data_off = RTE_PKTMBUF_HEADROOM;
     947         [ #  # ]:          0 :                         if (first_seg == NULL) {
     948                 :          0 :                                 first_seg = cur_mbuf;
     949                 :          0 :                                 first_seg->nb_segs = 1;
     950                 :          0 :                                 first_seg->pkt_len = pkt_len;
     951                 :            :                         } else {
     952                 :          0 :                                 first_seg->pkt_len += pkt_len;
     953                 :          0 :                                 first_seg->nb_segs++;
     954                 :          0 :                                 last_seg->next = cur_mbuf;
     955                 :            :                         }
     956                 :            :                 } else {
     957         [ #  # ]:          0 :                         if (first_seg == NULL) {
     958                 :          0 :                                 cur_mbuf->nb_segs = 2;
     959                 :          0 :                                 cur_mbuf->next->next = NULL;
     960                 :          0 :                                 pkt_len = SXE2_RX_DESC_PKT_LEN_VAL_GET(qword1);
     961                 :          0 :                                 hdr_len = SXE2_RX_DESC_HDR_LEN_VAL_GET(qword1);
     962                 :          0 :                                 cur_mbuf->data_len = hdr_len;
     963                 :          0 :                                 cur_mbuf->pkt_len = hdr_len + pkt_len;
     964                 :          0 :                                 cur_mbuf->next->data_len = pkt_len;
     965                 :          0 :                                 first_seg = cur_mbuf;
     966                 :          0 :                                 cur_mbuf = cur_mbuf->next;
     967                 :          0 :                                 last_seg = cur_mbuf;
     968                 :            :                         } else {
     969                 :          0 :                                 cur_mbuf->nb_segs = 1;
     970                 :          0 :                                 cur_mbuf->next = NULL;
     971                 :          0 :                                 pkt_len = SXE2_RX_DESC_PKT_LEN_VAL_GET(qword1);
     972                 :          0 :                                 cur_mbuf->data_len = pkt_len;
     973                 :            : 
     974                 :          0 :                                 first_seg->pkt_len += pkt_len;
     975                 :          0 :                                 first_seg->nb_segs++;
     976                 :          0 :                                 last_seg->next = cur_mbuf;
     977                 :            :                         }
     978                 :            :                 }
     979                 :            : 
     980                 :            : #ifdef RTE_ETHDEV_DEBUG_RX
     981                 :            : 
     982                 :            :                 rte_pktmbuf_dump(stdout, first_seg, rte_pktmbuf_pkt_len(first_seg));
     983                 :            : #endif
     984                 :            : 
     985         [ #  # ]:          0 :                 if (0 == (rte_le_to_cpu_64(desc_tmp.wb.status_err_ptype_len) &
     986                 :            :                                         SXE2_RX_DESC_STATUS_EOP_MASK)) {
     987                 :          0 :                         last_seg = cur_mbuf;
     988                 :          0 :                         continue;
     989                 :            :                 }
     990                 :            : 
     991         [ #  # ]:          0 :                 if (unlikely(qword1 & SXE2_RX_DESC_ERROR_RXE_MASK) ||
     992         [ #  # ]:          0 :                         unlikely(qword1 & SXE2_RX_DESC_ERROR_OVERSIZE_MASK)) {
     993                 :          0 :                         rte_atomic_fetch_add_explicit(&rxq->sw_stats.drop_pkts, 1,
     994                 :            :                                 rte_memory_order_relaxed);
     995                 :          0 :                         rte_atomic_fetch_add_explicit(&rxq->sw_stats.drop_bytes,
     996                 :            :                                 first_seg->pkt_len - rxq->crc_len + RTE_ETHER_CRC_LEN,
     997                 :            :                                 rte_memory_order_relaxed);
     998                 :          0 :                         rte_pktmbuf_free(first_seg);
     999                 :          0 :                         first_seg = NULL;
    1000                 :          0 :                         continue;
    1001                 :            :                 }
    1002                 :            : 
    1003                 :          0 :                 cur_mbuf->next = NULL;
    1004         [ #  # ]:          0 :                 if (unlikely(rxq->crc_len > 0)) {
    1005                 :          0 :                         first_seg->pkt_len -= RTE_ETHER_CRC_LEN;
    1006         [ #  # ]:          0 :                         if (pkt_len <= RTE_ETHER_CRC_LEN) {
    1007         [ #  # ]:          0 :                                 rte_pktmbuf_free_seg(cur_mbuf);
    1008                 :          0 :                                 cur_mbuf = NULL;
    1009                 :          0 :                                 first_seg->nb_segs--;
    1010                 :          0 :                                 last_seg->data_len = last_seg->data_len +
    1011                 :          0 :                                         pkt_len - RTE_ETHER_CRC_LEN;
    1012                 :          0 :                                 last_seg->next = NULL;
    1013                 :            :                         } else {
    1014                 :          0 :                                 cur_mbuf->data_len = pkt_len - RTE_ETHER_CRC_LEN;
    1015                 :            :                         }
    1016         [ #  # ]:          0 :                 } else if (pkt_len == 0) {
    1017         [ #  # ]:          0 :                         rte_pktmbuf_free_seg(cur_mbuf);
    1018                 :          0 :                         cur_mbuf = NULL;
    1019                 :          0 :                         first_seg->nb_segs--;
    1020                 :          0 :                         last_seg->next = NULL;
    1021                 :            :                 }
    1022                 :            : 
    1023                 :          0 :                 first_seg->port = rxq->port_id;
    1024                 :          0 :                 sxe2_rx_mbuf_common_fields_fill(rxq, first_seg, &desc_tmp);
    1025                 :            : 
    1026         [ #  # ]:          0 :                 if (rxq->vsi->adapter->devargs.sw_stats_en)
    1027   [ #  #  #  # ]:          0 :                         sxe2_rx_sw_stats_update(rxq, first_seg, &desc_tmp);
    1028                 :            : 
    1029                 :          0 :                 rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr, first_seg->data_off));
    1030                 :            : 
    1031                 :          0 :                 rx_pkts[done_num] = first_seg;
    1032                 :          0 :                 done_num++;
    1033                 :            : 
    1034                 :          0 :                 first_seg = NULL;
    1035                 :            :         }
    1036                 :            : 
    1037                 :          0 :         rxq->processing_idx = cur_idx;
    1038                 :          0 :         rxq->pkt_first_seg = first_seg;
    1039                 :          0 :         rxq->pkt_last_seg = last_seg;
    1040                 :            : 
    1041                 :          0 :         sxe2_update_rx_tail(rxq, hold_num, cur_idx);
    1042                 :            : 
    1043                 :          0 :         return done_num;
    1044                 :            : }

Generated by: LCOV version 1.14