LCOV - code coverage report
Current view: top level - drivers/net/sxe2 - sxe2_txrx.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 195 0.0 %
Date: 2026-06-01 18:36:17 Functions: 0 10 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 100 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 <unistd.h>
      12                 :            : #include "sxe2_txrx.h"
      13                 :            : #include "sxe2_txrx_common.h"
      14                 :            : #include "sxe2_txrx_vec.h"
      15                 :            : #include "sxe2_txrx_poll.h"
      16                 :            : #include "sxe2_ethdev.h"
      17                 :            : #include "sxe2_common_log.h"
      18                 :            : #include "sxe2_osal.h"
      19                 :            : #include "sxe2_cmd_chnl.h"
      20                 :            : #if defined(RTE_ARCH_ARM64)
      21                 :            : #include <rte_cpuflags.h>
      22                 :            : #endif
      23                 :            : 
      24                 :            : int32_t __rte_cold
      25                 :          0 : sxe2_tx_simple_batch_support_check(struct rte_eth_dev *dev,
      26                 :            :                 uint32_t *batch_flags)
      27                 :            : {
      28                 :          0 :         struct sxe2_tx_queue *txq;
      29                 :          0 :         int32_t ret = 0;
      30                 :          0 :         uint16_t i;
      31                 :            : 
      32         [ #  # ]:          0 :         for (i = 0; i < dev->data->nb_tx_queues; ++i) {
      33                 :          0 :                 txq = (struct sxe2_tx_queue *)dev->data->tx_queues[i];
      34         [ #  # ]:          0 :                 if (txq == NULL) {
      35                 :          0 :                         ret = -EINVAL;
      36                 :          0 :                         goto l_end;
      37                 :            :                 }
      38         [ #  # ]:          0 :                 if (txq->offloads != (txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) ||
      39         [ #  # ]:          0 :                      txq->rs_thresh < SXE2_TX_PKTS_BURST_BATCH_NUM) {
      40                 :          0 :                         ret = -ENOTSUP;
      41                 :          0 :                         goto l_end;
      42                 :            :                 }
      43                 :            :         }
      44                 :          0 :         *batch_flags = SXE2_TX_MODE_SIMPLE_BATCH;
      45                 :          0 : l_end:
      46                 :          0 :         return ret;
      47                 :            : }
      48                 :            : 
      49                 :          0 : static int32_t sxe2_tx_descriptor_status(void *tx_queue, uint16_t offset)
      50                 :            : {
      51                 :          0 :         struct sxe2_tx_queue *txq = (struct sxe2_tx_queue *)tx_queue;
      52                 :          0 :         int32_t ret;
      53                 :          0 :         uint16_t desc_idx;
      54                 :            : 
      55         [ #  # ]:          0 :         if (unlikely(offset >= txq->ring_depth)) {
      56                 :          0 :                 ret = -EINVAL;
      57                 :          0 :                 goto l_end;
      58                 :            :         }
      59                 :          0 :         desc_idx = txq->next_use + offset;
      60                 :          0 :         desc_idx = SXE2_DIV_ROUND_UP(desc_idx, txq->rs_thresh) * (txq->rs_thresh);
      61         [ #  # ]:          0 :         if (desc_idx >= txq->ring_depth) {
      62                 :          0 :                 desc_idx -= txq->ring_depth;
      63         [ #  # ]:          0 :                 if (desc_idx >= txq->ring_depth)
      64                 :          0 :                         desc_idx -= txq->ring_depth;
      65                 :            :         }
      66         [ #  # ]:          0 :         if (desc_idx == 0)
      67                 :          0 :                 desc_idx = txq->rs_thresh - 1;
      68                 :            :         else
      69                 :          0 :                 desc_idx -= 1;
      70                 :          0 :         if (rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE) ==
      71         [ #  # ]:          0 :                 (txq->desc_ring[desc_idx].wb.dd &
      72                 :            :                 rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_MASK)))
      73                 :            :                 ret = RTE_ETH_TX_DESC_DONE;
      74                 :            :         else
      75                 :          0 :                 ret = RTE_ETH_TX_DESC_FULL;
      76                 :          0 : l_end:
      77                 :          0 :         return ret;
      78                 :            : }
      79                 :            : 
      80                 :            : static inline int32_t sxe2_tx_mbuf_empty_check(struct rte_mbuf *mbuf)
      81                 :            : {
      82                 :            :         struct rte_mbuf *m_seg = mbuf;
      83         [ #  # ]:          0 :         while (m_seg != NULL) {
      84         [ #  # ]:          0 :                 if (m_seg->data_len == 0)
      85                 :            :                         return -EINVAL;
      86                 :          0 :                 m_seg = m_seg->next;
      87                 :            :         }
      88                 :            : 
      89                 :            :         return 0;
      90                 :            : }
      91                 :            : 
      92                 :          0 : uint16_t sxe2_tx_pkts_prepare(void *tx_queue,
      93                 :            :                 struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
      94                 :            : {
      95                 :          0 :         struct sxe2_tx_queue *txq = tx_queue;
      96                 :          0 :         struct rte_mbuf *mbuf;
      97                 :          0 :         uint64_t ol_flags = 0;
      98                 :          0 :         int32_t ret = 0;
      99                 :          0 :         int32_t i = 0;
     100                 :            : 
     101         [ #  # ]:          0 :         for (i = 0; i < nb_pkts; i++) {
     102                 :          0 :                 mbuf = tx_pkts[i];
     103         [ #  # ]:          0 :                 if (!mbuf)
     104                 :          0 :                         continue;
     105                 :          0 :                 ol_flags = mbuf->ol_flags;
     106         [ #  # ]:          0 :                 if (!(ol_flags & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG))) {
     107         [ #  # ]:          0 :                         if (mbuf->nb_segs > SXE2_TX_MTU_SEG_MAX ||
     108         [ #  # ]:          0 :                                         mbuf->pkt_len > SXE2_FRAME_SIZE_MAX) {
     109                 :          0 :                                 rte_errno = -EINVAL;
     110                 :          0 :                                 goto l_end;
     111                 :            :                         }
     112         [ #  # ]:          0 :                 } else if ((mbuf->tso_segsz < SXE2_MIN_TSO_MSS) ||
     113                 :          0 :                         (mbuf->tso_segsz > SXE2_MAX_TSO_MSS) ||
     114         [ #  # ]:          0 :                         (mbuf->nb_segs   > txq->ring_depth) ||
     115         [ #  # ]:          0 :                         (mbuf->pkt_len > SXE2_TX_TSO_PKTLEN_MAX)) {
     116                 :          0 :                         rte_errno = -EINVAL;
     117                 :          0 :                         goto l_end;
     118                 :            :                 }
     119         [ #  # ]:          0 :                 if (mbuf->pkt_len < SXE2_TX_MIN_PKT_LEN) {
     120                 :          0 :                         rte_errno = -EINVAL;
     121                 :          0 :                         goto l_end;
     122                 :            :                 }
     123                 :            : #ifdef RTE_ETHDEV_DEBUG_TX
     124                 :            :                 ret = rte_validate_tx_offload(mbuf);
     125                 :            :                 if (ret != 0) {
     126                 :            :                         rte_errno = -ret;
     127                 :            :                         goto l_end;
     128                 :            :                 }
     129                 :            : #endif
     130                 :          0 :                 ret = rte_net_intel_cksum_prepare(mbuf);
     131         [ #  # ]:          0 :                 if (ret != 0) {
     132                 :          0 :                         rte_errno = -ret;
     133                 :          0 :                         goto l_end;
     134                 :            :                 }
     135                 :          0 :                 ret = sxe2_tx_mbuf_empty_check(mbuf);
     136         [ #  # ]:          0 :                 if (ret != 0) {
     137                 :          0 :                         rte_errno = -ret;
     138                 :          0 :                         goto l_end;
     139                 :            :                 }
     140                 :            :         }
     141                 :          0 : l_end:
     142                 :          0 :         return i;
     143                 :            : }
     144                 :            : 
     145                 :          0 : void sxe2_tx_mode_func_set(struct rte_eth_dev *dev)
     146                 :            : {
     147                 :          0 :         struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
     148                 :          0 :         uint32_t tx_mode_flags;
     149                 :          0 :         int32_t ret;
     150                 :          0 :         uint32_t vec_flags = 0;
     151                 :          0 :         uint32_t batch_flags = 0;
     152                 :            : 
     153                 :          0 :         PMD_INIT_FUNC_TRACE();
     154         [ #  # ]:          0 :         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
     155                 :          0 :                 tx_mode_flags = 0;
     156                 :          0 :                 ret = sxe2_tx_vec_support_check(dev, &vec_flags);
     157   [ #  #  #  # ]:          0 :                 if (ret == 0 &&
     158                 :          0 :                     rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
     159                 :          0 :                         tx_mode_flags = vec_flags;
     160         [ #  # ]:          0 :                         if (tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK) {
     161                 :          0 :                                 ret = sxe2_tx_queues_vec_prepare(dev);
     162         [ #  # ]:          0 :                                 if (ret != 0)
     163                 :          0 :                                         tx_mode_flags &= ~SXE2_TX_MODE_VEC_SET_MASK;
     164                 :            :                         }
     165                 :            :                 }
     166                 :          0 :                 ret = sxe2_tx_simple_batch_support_check(dev, &batch_flags);
     167   [ #  #  #  # ]:          0 :                 if (ret == 0 && batch_flags == SXE2_TX_MODE_SIMPLE_BATCH)
     168                 :          0 :                         tx_mode_flags |= SXE2_TX_MODE_SIMPLE_BATCH;
     169                 :            : 
     170                 :          0 :                 adapter->q_ctxt.tx_mode_flags = tx_mode_flags;
     171                 :            :         } else {
     172                 :          0 :                 tx_mode_flags = adapter->q_ctxt.tx_mode_flags;
     173                 :            :         }
     174                 :            : 
     175                 :            : #ifdef RTE_ARCH_X86
     176         [ #  # ]:          0 :         if (tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK) {
     177         [ #  # ]:          0 :                 if (tx_mode_flags & SXE2_TX_MODE_VEC_OFFLOAD) {
     178                 :          0 :                         dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
     179                 :          0 :                         dev->tx_pkt_burst = sxe2_tx_pkts_vec_sse;
     180                 :            :                 } else {
     181                 :          0 :                         dev->tx_pkt_prepare = NULL;
     182                 :          0 :                         dev->tx_pkt_burst = sxe2_tx_pkts_vec_sse_simple;
     183                 :            :                 }
     184                 :            :         } else {
     185                 :            : #endif
     186         [ #  # ]:          0 :                 if (tx_mode_flags & SXE2_TX_MODE_SIMPLE_BATCH) {
     187                 :          0 :                         dev->tx_pkt_prepare = NULL;
     188                 :          0 :                         dev->tx_pkt_burst = sxe2_tx_pkts_simple;
     189                 :            :                 } else {
     190                 :          0 :                         dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
     191                 :          0 :                         dev->tx_pkt_burst = sxe2_tx_pkts;
     192                 :            :                 }
     193                 :            : #ifdef RTE_ARCH_X86
     194                 :            :         }
     195                 :            : #endif
     196                 :          0 : }
     197                 :            : 
     198                 :            : static const struct {
     199                 :            :         eth_tx_burst_t tx_burst;
     200                 :            :         const char *info;
     201                 :            : } sxe2_tx_burst_infos[] = {
     202                 :            :         { sxe2_tx_pkts,   "Scalar" },
     203                 :            : #ifdef RTE_ARCH_X86
     204                 :            :         { sxe2_tx_pkts_vec_sse,        "Vector SSE" },
     205                 :            :         { sxe2_tx_pkts_vec_sse_simple, "Vector SSE Simple" },
     206                 :            : #endif
     207                 :            : };
     208                 :            : 
     209                 :          0 : int32_t sxe2_tx_burst_mode_get(struct rte_eth_dev *dev,
     210                 :            :                 __rte_unused uint16_t queue_id, struct rte_eth_burst_mode *mode)
     211                 :            : {
     212                 :          0 :         eth_tx_burst_t pkt_burst = dev->tx_pkt_burst;
     213                 :          0 :         int32_t ret = -EINVAL;
     214                 :          0 :         uint32_t i;
     215                 :          0 :         uint32_t size;
     216                 :            : 
     217                 :          0 :         size = RTE_DIM(sxe2_tx_burst_infos);
     218         [ #  # ]:          0 :         for (i = 0; i < size; ++i) {
     219         [ #  # ]:          0 :                 if (pkt_burst == sxe2_tx_burst_infos[i].tx_burst) {
     220                 :          0 :                         snprintf(mode->info, sizeof(mode->info), "%s",
     221                 :          0 :                                         sxe2_tx_burst_infos[i].info);
     222                 :          0 :                         ret = 0;
     223                 :          0 :                         break;
     224                 :            :                 }
     225                 :            :         }
     226                 :          0 :         return ret;
     227                 :            : }
     228                 :            : 
     229                 :          0 : static int32_t sxe2_rx_descriptor_status(void *rx_queue, uint16_t offset)
     230                 :            : {
     231                 :          0 :         struct sxe2_rx_queue *rxq = (struct sxe2_rx_queue *)rx_queue;
     232                 :          0 :         volatile union sxe2_rx_desc *desc;
     233                 :          0 :         int32_t ret;
     234                 :            : 
     235         [ #  # ]:          0 :         if (unlikely(offset >= rxq->ring_depth)) {
     236                 :          0 :                 ret = -EINVAL;
     237                 :          0 :                 goto l_end;
     238                 :            :         }
     239         [ #  # ]:          0 :         if (offset >= rxq->ring_depth - rxq->hold_num) {
     240                 :          0 :                 ret = RTE_ETH_RX_DESC_UNAVAIL;
     241                 :          0 :                 goto l_end;
     242                 :            :         }
     243         [ #  # ]:          0 :         if (rxq->processing_idx + offset >= rxq->ring_depth)
     244                 :          0 :                 desc = &rxq->desc_ring[rxq->processing_idx + offset - rxq->ring_depth];
     245                 :            :         else
     246                 :          0 :                 desc = &rxq->desc_ring[rxq->processing_idx + offset];
     247         [ #  # ]:          0 :         if (rte_le_to_cpu_64(desc->wb.status_err_ptype_len) & SXE2_RX_DESC_STATUS_DD_MASK)
     248                 :            :                 ret = RTE_ETH_RX_DESC_DONE;
     249                 :            :         else
     250                 :          0 :                 ret = RTE_ETH_RX_DESC_AVAIL;
     251                 :          0 : l_end:
     252                 :          0 :         PMD_LOG_DEBUG(RX, "Rx queue desc[%u] status:%d queue_id:%u port_id:%u",
     253                 :            :                                 offset, ret, rxq->queue_id, rxq->port_id);
     254                 :          0 :         return ret;
     255                 :            : }
     256                 :            : 
     257                 :          0 : static int32_t sxe2_rx_queue_count(void *rx_queue)
     258                 :            : {
     259                 :          0 :         struct sxe2_rx_queue *rxq = (struct sxe2_rx_queue *)rx_queue;
     260                 :          0 :         volatile union sxe2_rx_desc *desc;
     261                 :          0 :         uint16_t done_num = 0;
     262                 :            : 
     263                 :          0 :         desc = &rxq->desc_ring[rxq->processing_idx];
     264         [ #  # ]:          0 :         while ((done_num < rxq->ring_depth) &&
     265         [ #  # ]:          0 :                 (rte_le_to_cpu_64(desc->wb.status_err_ptype_len) &
     266                 :            :                 SXE2_RX_DESC_STATUS_DD_MASK)) {
     267                 :          0 :                 done_num += SXE2_RX_QUEUE_CHECK_INTERVAL_NUM;
     268         [ #  # ]:          0 :                 if (rxq->processing_idx + done_num >= rxq->ring_depth)
     269                 :          0 :                         desc = &rxq->desc_ring[rxq->processing_idx + done_num - rxq->ring_depth];
     270                 :            :                 else
     271                 :          0 :                         desc += SXE2_RX_QUEUE_CHECK_INTERVAL_NUM;
     272                 :            :         }
     273                 :          0 :         PMD_LOG_DEBUG(RX, "Rx queue done desc count:%u queue_id:%u port_id:%u",
     274                 :            :                                 done_num, rxq->queue_id, rxq->port_id);
     275                 :          0 :         return done_num;
     276                 :            : }
     277                 :            : 
     278                 :          0 : void sxe2_rx_mode_func_set(struct rte_eth_dev *dev)
     279                 :            : {
     280                 :          0 :         struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
     281                 :          0 :         uint32_t rx_mode_flags = 0;
     282                 :          0 :         int32_t ret;
     283                 :          0 :         uint32_t vec_flags = 0;
     284                 :          0 :         PMD_INIT_FUNC_TRACE();
     285                 :            : 
     286         [ #  # ]:          0 :         if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
     287                 :          0 :                 ret = sxe2_rx_vec_support_check(dev, &vec_flags);
     288   [ #  #  #  # ]:          0 :                 if (ret == 0 &&
     289                 :          0 :                     rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
     290                 :          0 :                         rx_mode_flags = vec_flags;
     291         [ #  # ]:          0 :                         if ((rx_mode_flags & SXE2_RX_MODE_VEC_SET_MASK) != 0) {
     292                 :          0 :                                 ret = sxe2_rx_queues_vec_prepare(dev);
     293         [ #  # ]:          0 :                                 if (ret != 0)
     294                 :          0 :                                         rx_mode_flags &= ~SXE2_RX_MODE_VEC_SET_MASK;
     295                 :            :                         }
     296                 :            :                 }
     297                 :          0 :                 adapter->q_ctxt.rx_mode_flags = rx_mode_flags;
     298                 :            :         } else {
     299                 :          0 :                 rx_mode_flags = adapter->q_ctxt.rx_mode_flags;
     300                 :            :         }
     301                 :            : 
     302                 :            : #ifdef RTE_ARCH_X86
     303         [ #  # ]:          0 :         if (rx_mode_flags & SXE2_RX_MODE_VEC_SET_MASK) {
     304                 :          0 :                 dev->rx_pkt_burst = sxe2_rx_pkts_scattered_vec_sse_offload;
     305                 :          0 :                 return;
     306                 :            :         }
     307                 :            : #endif
     308         [ #  # ]:          0 :         if (sxe2_rx_offload_en_check(dev, RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT))
     309                 :          0 :                 dev->rx_pkt_burst = sxe2_rx_pkts_scattered_split;
     310                 :            :         else
     311                 :          0 :                 dev->rx_pkt_burst = sxe2_rx_pkts_scattered;
     312                 :            : }
     313                 :            : 
     314                 :            : static const struct {
     315                 :            :         eth_rx_burst_t rx_burst;
     316                 :            :         const char *info;
     317                 :            : } sxe2_rx_burst_infos[] = {
     318                 :            :         { sxe2_rx_pkts_scattered,          "Scalar Scattered" },
     319                 :            :         { sxe2_rx_pkts_scattered_split,          "Scalar Scattered split" },
     320                 :            : #ifdef RTE_ARCH_X86
     321                 :            :         { sxe2_rx_pkts_scattered_vec_sse_offload,      "Vector SSE Scattered" },
     322                 :            : #endif
     323                 :            : };
     324                 :            : 
     325                 :          0 : int32_t sxe2_rx_burst_mode_get(struct rte_eth_dev *dev,
     326                 :            :                         __rte_unused uint16_t queue_id, struct rte_eth_burst_mode *mode)
     327                 :            : {
     328                 :          0 :         eth_rx_burst_t pkt_burst = dev->rx_pkt_burst;
     329                 :          0 :         int32_t ret = -EINVAL;
     330                 :          0 :         uint32_t i, size;
     331                 :          0 :         size = RTE_DIM(sxe2_rx_burst_infos);
     332         [ #  # ]:          0 :         for (i = 0; i < size; ++i) {
     333         [ #  # ]:          0 :                 if (pkt_burst == sxe2_rx_burst_infos[i].rx_burst) {
     334                 :          0 :                         snprintf(mode->info, sizeof(mode->info), "%s",
     335                 :          0 :                                  sxe2_rx_burst_infos[i].info);
     336                 :          0 :                         ret = 0;
     337                 :          0 :                         break;
     338                 :            :                 }
     339                 :            :         }
     340                 :          0 :         return ret;
     341                 :            : }
     342                 :            : 
     343                 :          0 : void sxe2_set_common_function(struct rte_eth_dev *dev)
     344                 :            : {
     345                 :          0 :         PMD_INIT_FUNC_TRACE();
     346                 :          0 :         dev->rx_queue_count = sxe2_rx_queue_count;
     347                 :          0 :         dev->rx_descriptor_status = sxe2_rx_descriptor_status;
     348                 :            : 
     349                 :          0 :         dev->tx_descriptor_status = sxe2_tx_descriptor_status;
     350                 :          0 :         dev->tx_pkt_prepare = sxe2_tx_pkts_prepare;
     351                 :          0 : }

Generated by: LCOV version 1.14