LCOV - code coverage report
Current view: top level - drivers/net/sxe2 - sxe2_rx.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 356 0.0 %
Date: 2026-08-01 17:54:00 Functions: 0 16 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 118 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 <ethdev_driver.h>
       6                 :            : #include <rte_net.h>
       7                 :            : #include <rte_vect.h>
       8                 :            : #include <rte_malloc.h>
       9                 :            : #include <rte_memzone.h>
      10                 :            : 
      11                 :            : #include "sxe2_ethdev.h"
      12                 :            : #include "sxe2_queue.h"
      13                 :            : #include "sxe2_rx.h"
      14                 :            : #include "sxe2_cmd_chnl.h"
      15                 :            : 
      16                 :            : #include "sxe2_osal.h"
      17                 :            : #include "sxe2_common_log.h"
      18                 :            : 
      19                 :          0 : static void *sxe2_rx_doorbell_tail_addr_get(struct sxe2_adapter *adapter, uint16_t queue_id)
      20                 :            : {
      21                 :          0 :         return sxe2_pci_map_addr_get(adapter, SXE2_PCI_MAP_RES_DOORBELL_RX_TAIL,
      22                 :            :                                      queue_id);
      23                 :            : }
      24                 :            : 
      25                 :          0 : static void sxe2_rx_head_tail_init(struct sxe2_adapter *adapter, struct sxe2_rx_queue *rxq)
      26                 :            : {
      27                 :          0 :         rxq->rdt_reg_addr = sxe2_rx_doorbell_tail_addr_get(adapter, rxq->queue_id);
      28                 :          0 :         SXE2_PCI_REG_WRITE_WC(rxq->rdt_reg_addr, 0);
      29                 :          0 : }
      30                 :            : 
      31                 :          0 : static void __rte_cold sxe2_rx_queue_reset(struct sxe2_rx_queue *rxq)
      32                 :            : {
      33                 :          0 :         uint16_t i = 0;
      34                 :          0 :         uint16_t len = 0;
      35                 :          0 :         static const union sxe2_rx_desc zeroed_desc = {{0}};
      36                 :            : 
      37                 :          0 :         len = rxq->ring_depth + SXE2_RX_PKTS_BURST_BATCH_NUM;
      38         [ #  # ]:          0 :         for (i = 0; i < len; ++i)
      39                 :          0 :                 rxq->desc_ring[i] = zeroed_desc;
      40                 :            : 
      41                 :          0 :         memset(&rxq->fake_mbuf, 0, sizeof(rxq->fake_mbuf));
      42         [ #  # ]:          0 :         for (i = rxq->ring_depth; i < len; i++)
      43                 :          0 :                 rxq->buffer_ring[i] = &rxq->fake_mbuf;
      44                 :            : 
      45                 :          0 :         rxq->hold_num            = 0;
      46                 :          0 :         rxq->next_ret_pkt        = 0;
      47                 :          0 :         rxq->processing_idx      = 0;
      48                 :          0 :         rxq->completed_pkts_num  = 0;
      49                 :          0 :         rxq->batch_alloc_trigger = rxq->rx_free_thresh - 1;
      50                 :            : 
      51                 :          0 :         rxq->pkt_first_seg = NULL;
      52                 :          0 :         rxq->pkt_last_seg  = NULL;
      53                 :            : 
      54                 :          0 :         rxq->realloc_num   = 0;
      55                 :          0 :         rxq->realloc_start = 0;
      56                 :          0 : }
      57                 :            : 
      58                 :          0 : void __rte_cold sxe2_rx_queue_mbufs_release(struct sxe2_rx_queue *rxq)
      59                 :            : {
      60                 :          0 :         uint16_t i;
      61                 :            : 
      62         [ #  # ]:          0 :         if (rxq->buffer_ring != NULL) {
      63         [ #  # ]:          0 :                 for (i = 0; i < rxq->ring_depth; i++) {
      64         [ #  # ]:          0 :                         if (rxq->buffer_ring[i] != NULL) {
      65                 :          0 :                                 rte_pktmbuf_free(rxq->buffer_ring[i]);
      66                 :          0 :                                 rxq->buffer_ring[i] = NULL;
      67                 :            :                         }
      68                 :            :                 }
      69                 :            :         }
      70                 :            : 
      71         [ #  # ]:          0 :         if (rxq->completed_pkts_num) {
      72         [ #  # ]:          0 :                 for (i = 0; i < rxq->completed_pkts_num; ++i) {
      73         [ #  # ]:          0 :                         if (rxq->completed_buf[rxq->next_ret_pkt + i] != NULL) {
      74                 :          0 :                                 rte_pktmbuf_free(rxq->completed_buf[rxq->next_ret_pkt + i]);
      75                 :          0 :                                 rxq->completed_buf[rxq->next_ret_pkt + i] = NULL;
      76                 :            :                         }
      77                 :            :                 }
      78                 :          0 :                 rxq->completed_pkts_num = 0;
      79                 :            :         }
      80                 :          0 : }
      81                 :            : 
      82                 :            : const struct sxe2_rxq_ops sxe2_default_rxq_ops = {
      83                 :            :         .queue_reset      = sxe2_rx_queue_reset,
      84                 :            :         .mbufs_release    = sxe2_rx_queue_mbufs_release,
      85                 :            : };
      86                 :            : 
      87                 :          0 : static struct sxe2_rxq_ops sxe2_rx_default_ops_get(void)
      88                 :            : {
      89                 :          0 :         return sxe2_default_rxq_ops;
      90                 :            : }
      91                 :            : 
      92                 :          0 : void __rte_cold sxe2_rx_queue_info_get(struct rte_eth_dev *dev,
      93                 :            :                 uint16_t queue_id, struct rte_eth_rxq_info *qinfo)
      94                 :            : {
      95                 :          0 :         struct sxe2_rx_queue *rxq = NULL;
      96                 :            : 
      97         [ #  # ]:          0 :         if (queue_id >= dev->data->nb_rx_queues) {
      98                 :          0 :                 PMD_LOG_ERR(RX, "rx queue:%u is out of range:%u",
      99                 :            :                         queue_id, dev->data->nb_rx_queues);
     100                 :          0 :                 goto end;
     101                 :            :         }
     102                 :            : 
     103                 :          0 :         rxq = dev->data->rx_queues[queue_id];
     104         [ #  # ]:          0 :         if (rxq == NULL) {
     105                 :          0 :                 PMD_LOG_ERR(RX, "rx queue:%u is NULL", queue_id);
     106                 :          0 :                 goto end;
     107                 :            :         }
     108                 :            : 
     109                 :          0 :         qinfo->mp           = rxq->mb_pool;
     110                 :          0 :         qinfo->nb_desc      = rxq->ring_depth;
     111                 :          0 :         qinfo->scattered_rx = dev->data->scattered_rx;
     112                 :          0 :         qinfo->conf.rx_free_thresh    = rxq->rx_free_thresh;
     113                 :          0 :         qinfo->conf.rx_drop_en        = rxq->drop_en;
     114                 :          0 :         qinfo->conf.rx_deferred_start = rxq->rx_deferred_start;
     115                 :            : 
     116                 :          0 : end:
     117                 :          0 :         return;
     118                 :            : }
     119                 :            : 
     120                 :          0 : int32_t __rte_cold sxe2_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
     121                 :            : {
     122                 :          0 :         struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
     123                 :          0 :         struct sxe2_rx_queue *rxq;
     124                 :          0 :         int32_t ret;
     125                 :          0 :         PMD_INIT_FUNC_TRACE();
     126                 :            : 
     127         [ #  # ]:          0 :         if (dev->data->rx_queue_state[rx_queue_id] ==
     128                 :            :                         RTE_ETH_QUEUE_STATE_STOPPED) {
     129                 :          0 :                 ret = 0;
     130                 :          0 :                 goto l_end;
     131                 :            :         }
     132                 :            : 
     133                 :          0 :         rxq = dev->data->rx_queues[rx_queue_id];
     134         [ #  # ]:          0 :         if (rxq == NULL) {
     135                 :          0 :                 ret = 0;
     136                 :          0 :                 goto l_end;
     137                 :            :         }
     138                 :          0 :         ret = sxe2_drv_rxq_switch(adapter, rxq, false);
     139         [ #  # ]:          0 :         if (ret) {
     140                 :          0 :                 PMD_LOG_ERR(RX, "Failed to switch rx queue %u off, ret = %d",
     141                 :            :                                 rx_queue_id, ret);
     142         [ #  # ]:          0 :                 if (ret == -EPERM)
     143                 :          0 :                         goto l_free;
     144                 :          0 :                 goto l_end;
     145                 :            :         }
     146                 :            : 
     147                 :          0 : l_free:
     148                 :          0 :         rxq->ops.mbufs_release(rxq);
     149                 :          0 :         rxq->ops.queue_reset(rxq);
     150                 :          0 :         dev->data->rx_queue_state[rx_queue_id] =
     151                 :            :                 RTE_ETH_QUEUE_STATE_STOPPED;
     152                 :          0 : l_end:
     153                 :          0 :         return ret;
     154                 :            : }
     155                 :            : 
     156                 :          0 : static void __rte_cold sxe2_rx_queue_free(struct sxe2_rx_queue *rxq)
     157                 :            : {
     158         [ #  # ]:          0 :         if (rxq != NULL) {
     159                 :          0 :                 rxq->ops.mbufs_release(rxq);
     160         [ #  # ]:          0 :                 if (rxq->buffer_ring != NULL) {
     161                 :          0 :                         rte_free(rxq->buffer_ring);
     162                 :          0 :                         rxq->buffer_ring = NULL;
     163                 :            :                 }
     164                 :          0 :                 rte_memzone_free(rxq->mz);
     165                 :          0 :                 rte_free(rxq);
     166                 :            :         }
     167                 :          0 : }
     168                 :            : 
     169                 :          0 : void __rte_cold sxe2_rx_queue_release(struct rte_eth_dev *dev,
     170                 :            :                                         uint16_t queue_idx)
     171                 :            : {
     172                 :          0 :         (void)sxe2_rx_queue_stop(dev, queue_idx);
     173                 :          0 :         sxe2_rx_queue_free(dev->data->rx_queues[queue_idx]);
     174                 :          0 :         dev->data->rx_queues[queue_idx] = NULL;
     175                 :          0 : }
     176                 :            : 
     177                 :          0 : void __rte_cold sxe2_all_rxqs_release(struct rte_eth_dev *dev)
     178                 :            : {
     179                 :          0 :         struct rte_eth_dev_data *data = dev->data;
     180                 :          0 :         uint16_t nb_rxq;
     181                 :            : 
     182         [ #  # ]:          0 :         for (nb_rxq = 0; nb_rxq < data->nb_rx_queues; nb_rxq++) {
     183         [ #  # ]:          0 :                 if (data->rx_queues[nb_rxq] == NULL)
     184                 :          0 :                         continue;
     185                 :          0 :                 sxe2_rx_queue_release(dev, nb_rxq);
     186                 :          0 :                 data->rx_queues[nb_rxq] = NULL;
     187                 :            :         }
     188                 :          0 :         data->nb_rx_queues = 0;
     189                 :          0 : }
     190                 :            : 
     191                 :          0 : static struct sxe2_rx_queue *sxe2_rx_queue_alloc(struct rte_eth_dev *dev, uint16_t queue_idx,
     192                 :            :                 uint16_t ring_depth, uint32_t socket_id)
     193                 :            : {
     194                 :          0 :         struct sxe2_rx_queue *rxq;
     195                 :          0 :         const struct rte_memzone *tz;
     196                 :          0 :         uint16_t len;
     197                 :            : 
     198         [ #  # ]:          0 :         if (dev->data->rx_queues[queue_idx] != NULL) {
     199                 :          0 :                 sxe2_rx_queue_release(dev, queue_idx);
     200                 :          0 :                 dev->data->rx_queues[queue_idx] = NULL;
     201                 :            :         }
     202                 :            : 
     203                 :          0 :         rxq = rte_zmalloc_socket("rx_queue", sizeof(*rxq),
     204                 :            :                                  RTE_CACHE_LINE_SIZE, socket_id);
     205                 :            : 
     206         [ #  # ]:          0 :         if (rxq == NULL) {
     207                 :          0 :                 PMD_LOG_ERR(RX, "rx queue[%d] alloc failed", queue_idx);
     208                 :          0 :                 goto l_end;
     209                 :            :         }
     210                 :            : 
     211                 :          0 :         rxq->ring_depth = ring_depth;
     212                 :          0 :         len = rxq->ring_depth + SXE2_RX_PKTS_BURST_BATCH_NUM;
     213                 :            : 
     214                 :          0 :         rxq->buffer_ring = rte_zmalloc_socket("rx_buffer_ring",
     215                 :            :                                           sizeof(struct rte_mbuf *) * len,
     216                 :            :                                           RTE_CACHE_LINE_SIZE, socket_id);
     217                 :            : 
     218         [ #  # ]:          0 :         if (!rxq->buffer_ring) {
     219                 :          0 :                 PMD_LOG_ERR(RX, "Rxq malloc mbuf mem failed");
     220                 :          0 :                 rte_free(rxq);
     221                 :          0 :                 rxq = NULL;
     222                 :          0 :                 goto l_end;
     223                 :            :         }
     224                 :            : 
     225                 :          0 :         tz = rte_eth_dma_zone_reserve(dev, "rx_dma", queue_idx,
     226                 :            :                                         SXE2_RX_RING_SIZE, SXE2_DESC_ADDR_ALIGN, socket_id);
     227         [ #  # ]:          0 :         if (tz == NULL) {
     228                 :          0 :                 PMD_LOG_ERR(RX, "Rxq malloc desc mem failed");
     229                 :          0 :                 rte_free(rxq->buffer_ring);
     230                 :          0 :                 rxq->buffer_ring = NULL;
     231                 :          0 :                 rte_free(rxq);
     232                 :          0 :                 rxq = NULL;
     233                 :          0 :                 goto l_end;
     234                 :            :         }
     235                 :            : 
     236                 :          0 :         rxq->mz = tz;
     237                 :          0 :         memset(tz->addr, 0, SXE2_RX_RING_SIZE);
     238                 :          0 :         rxq->base_addr = tz->iova;
     239                 :          0 :         rxq->desc_ring = (union sxe2_rx_desc *)tz->addr;
     240                 :            : 
     241                 :          0 : l_end:
     242                 :          0 :         return rxq;
     243                 :            : }
     244                 :            : 
     245                 :          0 : int32_t __rte_cold sxe2_rx_queue_setup(struct rte_eth_dev *dev,
     246                 :            :                         uint16_t queue_idx, uint16_t nb_desc, uint32_t socket_id,
     247                 :            :                         const struct rte_eth_rxconf *rx_conf,
     248                 :            :                         struct rte_mempool *mp)
     249                 :            : {
     250                 :          0 :         struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
     251                 :          0 :         struct sxe2_vsi *vsi = adapter->vsi_ctxt.main_vsi;
     252                 :          0 :         struct sxe2_rx_queue *rxq;
     253                 :          0 :         uint64_t offloads;
     254                 :          0 :         int32_t ret;
     255                 :          0 :         uint16_t rx_nseg;
     256                 :          0 :         uint16_t i;
     257                 :            : 
     258                 :          0 :         PMD_INIT_FUNC_TRACE();
     259                 :            : 
     260                 :          0 :         if (nb_desc % SXE2_RX_DESC_RING_ALIGN != 0 ||
     261         [ #  # ]:          0 :                 nb_desc > SXE2_MAX_RING_DESC ||
     262                 :            :                 nb_desc < SXE2_MIN_RING_DESC) {
     263                 :          0 :                 PMD_LOG_ERR(RX, "param desc num:%u is invalid", nb_desc);
     264                 :          0 :                 ret = -EINVAL;
     265                 :          0 :                 goto l_end;
     266                 :            :         }
     267                 :            : 
     268         [ #  # ]:          0 :         if (mp != NULL)
     269                 :            :                 rx_nseg = 1;
     270                 :            :         else
     271                 :          0 :                 rx_nseg = rx_conf->rx_nseg;
     272                 :            : 
     273                 :          0 :         offloads = rx_conf->offloads | dev->data->dev_conf.rxmode.offloads;
     274                 :            : 
     275   [ #  #  #  # ]:          0 :         if (rx_nseg > 1 && !(offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT)) {
     276                 :          0 :                 PMD_LOG_ERR(RX, "Port %u queue %u Buffer split offload not configured, but rx_nseg is %u",
     277                 :            :                                         dev->data->port_id, queue_idx, rx_nseg);
     278                 :          0 :                 ret = -EINVAL;
     279                 :          0 :                 goto l_end;
     280                 :            :         }
     281                 :            : 
     282   [ #  #  #  # ]:          0 :         if ((offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) && !(rx_nseg > 1)) {
     283                 :          0 :                 PMD_LOG_ERR(RX, "Port %u queue %u Buffer split offload configured, but rx_nseg is %u",
     284                 :            :                                         dev->data->port_id, queue_idx, rx_nseg);
     285                 :          0 :                 ret = -EINVAL;
     286                 :          0 :                 goto l_end;
     287                 :            :         }
     288                 :            : 
     289         [ #  # ]:          0 :         if ((offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) &&
     290                 :            :                 (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)) {
     291                 :          0 :                 PMD_LOG_ERR(RX, "port_id %u queue %u, LRO can't be configure with Keep crc.",
     292                 :            :                                         dev->data->port_id, queue_idx);
     293                 :          0 :                 ret = -EINVAL;
     294                 :          0 :                 goto l_end;
     295                 :            :         }
     296                 :            : 
     297         [ #  # ]:          0 :         if (!sxe2_ipsec_valid_rx_offloads(offloads)) {
     298                 :          0 :                 ret = -EINVAL;
     299                 :          0 :                 goto l_end;
     300                 :            :         }
     301                 :            : 
     302                 :          0 :         rxq = sxe2_rx_queue_alloc(dev, queue_idx, nb_desc, socket_id);
     303         [ #  # ]:          0 :         if (rxq == NULL) {
     304                 :          0 :                 PMD_LOG_ERR(RX, "rx queue[%d] resource alloc failed", queue_idx);
     305                 :          0 :                 ret = -ENOMEM;
     306                 :          0 :                 goto l_end;
     307                 :            :         }
     308                 :            : 
     309         [ #  # ]:          0 :         if (offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO)
     310                 :          0 :                 dev->data->lro = 1;
     311                 :            : 
     312         [ #  # ]:          0 :         if (rx_nseg > 1) {
     313         [ #  # ]:          0 :                 for (i = 0; i < rx_nseg; i++) {
     314                 :          0 :                         rte_memcpy(&rxq->rx_seg[i], &rx_conf->rx_seg[i].split,
     315                 :            :                                         sizeof(struct rte_eth_rxseg_split));
     316                 :            :                 }
     317                 :          0 :                 rxq->mb_pool = rxq->rx_seg[0].mp;
     318                 :            :         } else {
     319                 :          0 :                 rxq->mb_pool = mp;
     320                 :            :         }
     321                 :            : 
     322                 :          0 :         rxq->rx_free_thresh = rx_conf->rx_free_thresh;
     323                 :          0 :         rxq->port_id = dev->data->port_id;
     324                 :          0 :         rxq->offloads = offloads;
     325         [ #  # ]:          0 :         if (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
     326                 :          0 :                 rxq->crc_len = RTE_ETHER_CRC_LEN;
     327                 :            :         else
     328                 :          0 :                 rxq->crc_len = 0;
     329                 :            : 
     330                 :          0 :         rxq->queue_id = queue_idx;
     331                 :          0 :         rxq->idx_in_func = vsi->rxqs.base_idx_in_func + queue_idx;
     332                 :          0 :         rxq->drop_en = rx_conf->rx_drop_en;
     333                 :          0 :         rxq->rx_deferred_start = rx_conf->rx_deferred_start;
     334                 :          0 :         rxq->vsi = vsi;
     335                 :          0 :         rxq->ops = sxe2_rx_default_ops_get();
     336                 :          0 :         rxq->ops.queue_reset(rxq);
     337                 :          0 :         dev->data->rx_queues[queue_idx] = rxq;
     338                 :            : 
     339                 :          0 :         ret = 0;
     340                 :          0 : l_end:
     341                 :          0 :         return ret;
     342                 :            : }
     343                 :            : 
     344                 :          0 : static int32_t __rte_cold sxe2_rx_queue_mbufs_alloc(struct sxe2_rx_queue *rxq)
     345                 :            : {
     346                 :          0 :         struct rte_mbuf **buf_ring = rxq->buffer_ring;
     347                 :          0 :         struct rte_mbuf *mbuf = NULL;
     348                 :          0 :         struct rte_mbuf *mbuf_pay;
     349                 :          0 :         volatile union sxe2_rx_desc *desc;
     350                 :          0 :         uint64_t dma_addr;
     351                 :          0 :         int32_t ret;
     352                 :          0 :         uint16_t i, j;
     353                 :            : 
     354         [ #  # ]:          0 :         for (i = 0; i < rxq->ring_depth; i++) {
     355                 :          0 :                 mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
     356         [ #  # ]:          0 :                 if (mbuf == NULL) {
     357                 :          0 :                         PMD_LOG_ERR(RX, "Rx queue is not available or setup");
     358                 :          0 :                         ret = -ENOMEM;
     359                 :          0 :                         goto l_err_free_mbuf;
     360                 :            :                 }
     361                 :            : 
     362                 :          0 :                 buf_ring[i] = mbuf;
     363                 :          0 :                 mbuf->data_off = RTE_PKTMBUF_HEADROOM;
     364                 :          0 :                 mbuf->nb_segs = 1;
     365                 :          0 :                 mbuf->port = rxq->port_id;
     366                 :            : 
     367         [ #  # ]:          0 :                 dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf));
     368                 :          0 :                 desc = &rxq->desc_ring[i];
     369         [ #  # ]:          0 :                 if (!(rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT)) {
     370                 :          0 :                         mbuf->next = NULL;
     371                 :          0 :                         desc->read.hdr_addr = 0;
     372                 :          0 :                         desc->read.pkt_addr = dma_addr;
     373                 :            :                 } else {
     374                 :          0 :                         mbuf_pay = rte_mbuf_raw_alloc(rxq->rx_seg[1].mp);
     375         [ #  # ]:          0 :                         if (unlikely(!mbuf_pay)) {
     376                 :          0 :                                 PMD_LOG_ERR(RX, "Failed to allocate payload mbuf for RX");
     377                 :          0 :                                 ret = -ENOMEM;
     378                 :          0 :                                 goto l_err_free_mbuf;
     379                 :            :                         }
     380                 :            : 
     381                 :          0 :                         mbuf_pay->next = NULL;
     382                 :          0 :                         mbuf_pay->data_off = RTE_PKTMBUF_HEADROOM;
     383                 :          0 :                         mbuf_pay->nb_segs = 1;
     384                 :          0 :                         mbuf_pay->port = rxq->port_id;
     385                 :          0 :                         mbuf->next = mbuf_pay;
     386                 :            : 
     387                 :          0 :                         desc->read.hdr_addr = dma_addr;
     388                 :          0 :                         desc->read.pkt_addr =
     389                 :          0 :                                 rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf_pay));
     390                 :            :                 }
     391                 :            : 
     392                 :            : #ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
     393                 :          0 :                 desc->read.rsvd1 = 0;
     394                 :          0 :                 desc->read.rsvd2 = 0;
     395                 :            : #endif
     396                 :            :         }
     397                 :            : 
     398                 :          0 :         ret = 0;
     399                 :          0 :         goto l_end;
     400                 :            : 
     401                 :          0 : l_err_free_mbuf:
     402         [ #  # ]:          0 :         for (j = 0; j <= i; j++) {
     403   [ #  #  #  # ]:          0 :                 if (buf_ring[j] != NULL && buf_ring[j]->next != NULL) {
     404                 :          0 :                         rte_pktmbuf_free(buf_ring[j]->next);
     405                 :          0 :                         buf_ring[j]->next = NULL;
     406                 :            :                 }
     407                 :            : 
     408         [ #  # ]:          0 :                 if (buf_ring[j] != NULL) {
     409                 :          0 :                         rte_pktmbuf_free(buf_ring[j]);
     410                 :          0 :                         buf_ring[j] = NULL;
     411                 :            :                 }
     412                 :            :         }
     413                 :            : 
     414                 :          0 : l_end:
     415                 :          0 :         return ret;
     416                 :            : }
     417                 :            : 
     418                 :          0 : int32_t __rte_cold sxe2_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
     419                 :            : {
     420                 :          0 :         struct sxe2_rx_queue *rxq;
     421                 :          0 :         struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
     422                 :          0 :         int32_t ret;
     423                 :          0 :         PMD_INIT_FUNC_TRACE();
     424                 :            : 
     425                 :          0 :         rxq = dev->data->rx_queues[rx_queue_id];
     426         [ #  # ]:          0 :         if (rxq == NULL) {
     427                 :          0 :                 PMD_LOG_ERR(RX, "Rx queue %u is not available or setup",
     428                 :            :                                 rx_queue_id);
     429                 :          0 :                 ret = -EINVAL;
     430                 :          0 :                 goto l_end;
     431                 :            :         }
     432                 :            : 
     433         [ #  # ]:          0 :         if (dev->data->rx_queue_state[rx_queue_id] ==
     434                 :            :                         RTE_ETH_QUEUE_STATE_STARTED) {
     435                 :          0 :                 ret = 0;
     436                 :          0 :                 goto l_end;
     437                 :            :         }
     438                 :            : 
     439                 :          0 :         ret = sxe2_rx_queue_mbufs_alloc(rxq);
     440         [ #  # ]:          0 :         if (ret) {
     441                 :          0 :                 PMD_LOG_ERR(RX, "Rx queue %u apply desc ring fail",
     442                 :            :                         rx_queue_id);
     443                 :          0 :                 ret =  -ENOMEM;
     444                 :          0 :                 goto l_end;
     445                 :            :         }
     446                 :            : 
     447                 :          0 :         sxe2_rx_head_tail_init(adapter, rxq);
     448                 :            : 
     449                 :          0 :         ret = sxe2_drv_rxq_ctxt_cfg(adapter, rxq, 1);
     450         [ #  # ]:          0 :         if (ret) {
     451                 :          0 :                 PMD_LOG_ERR(RX, "Rx queue %u config ctxt fail, ret=%d",
     452                 :            :                         rx_queue_id, ret);
     453                 :            : 
     454                 :          0 :                 (void)sxe2_drv_rxq_switch(adapter, rxq, false);
     455                 :          0 :                 rxq->ops.mbufs_release(rxq);
     456                 :          0 :                 rxq->ops.queue_reset(rxq);
     457                 :          0 :                 goto l_end;
     458                 :            :         }
     459                 :            : 
     460                 :          0 :         SXE2_PCI_REG_WRITE_WC(rxq->rdt_reg_addr, rxq->ring_depth - 1);
     461                 :          0 :         dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
     462                 :            : 
     463                 :          0 : l_end:
     464                 :          0 :         return  ret;
     465                 :            : }
     466                 :            : 
     467                 :          0 : int32_t __rte_cold sxe2_rxqs_all_start(struct rte_eth_dev *dev)
     468                 :            : {
     469                 :          0 :         struct rte_eth_dev_data *data = dev->data;
     470                 :          0 :         struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
     471                 :          0 :         struct sxe2_drv_vsi_fc_get_resp fc_resp = {0};
     472                 :          0 :         struct sxe2_rx_queue *rxq;
     473                 :          0 :         uint16_t nb_rxq;
     474                 :          0 :         uint16_t nb_started_rxq;
     475                 :          0 :         int32_t ret;
     476                 :          0 :         PMD_INIT_FUNC_TRACE();
     477                 :            : 
     478         [ #  # ]:          0 :         if (adapter->cap_flags & SXE2_DEV_CAPS_OFFLOAD_FC_STATE) {
     479                 :          0 :                 ret = sxe2_drv_fc_state_get(adapter, &fc_resp);
     480         [ #  # ]:          0 :                 if (ret) {
     481                 :          0 :                         PMD_LOG_ERR(RX, "Failed to get fc state, ret=[%d]", ret);
     482                 :          0 :                         goto l_end;
     483                 :            :                 }
     484                 :          0 :                 adapter->fc_state_ctx.cfg_state = fc_resp.fc_enable;
     485                 :          0 :                 adapter->fc_state_ctx.curr_state = adapter->fc_state_ctx.cfg_state;
     486                 :            :         }
     487                 :            : 
     488         [ #  # ]:          0 :         for (nb_rxq = 0; nb_rxq < data->nb_rx_queues; nb_rxq++) {
     489                 :          0 :                 rxq = dev->data->rx_queues[nb_rxq];
     490   [ #  #  #  # ]:          0 :                 if (!rxq || rxq->rx_deferred_start)
     491                 :          0 :                         continue;
     492                 :            : 
     493                 :          0 :                 ret = sxe2_rx_queue_start(dev, nb_rxq);
     494         [ #  # ]:          0 :                 if (ret) {
     495                 :          0 :                         PMD_LOG_ERR(RX, "Fail to start rx queue %u", nb_rxq);
     496                 :          0 :                         goto l_free_started_queue;
     497                 :            :                 }
     498                 :            : 
     499                 :          0 :                 rxq->sw_stats.pkts = 0;
     500                 :          0 :                 rxq->sw_stats.bytes = 0;
     501                 :          0 :                 rxq->sw_stats.drop_pkts = 0;
     502                 :          0 :                 rxq->sw_stats.drop_bytes = 0;
     503                 :          0 :                 rxq->sw_stats.unicast_pkts = 0;
     504                 :          0 :                 rxq->sw_stats.broadcast_pkts = 0;
     505                 :          0 :                 rxq->sw_stats.multicast_pkts = 0;
     506                 :            :         }
     507                 :          0 :         ret = 0;
     508                 :          0 :         goto l_end;
     509                 :            : 
     510                 :          0 : l_free_started_queue:
     511         [ #  # ]:          0 :         for (nb_started_rxq = 0; nb_started_rxq <= nb_rxq; nb_started_rxq++)
     512                 :          0 :                 (void)sxe2_rx_queue_stop(dev, nb_started_rxq);
     513                 :          0 : l_end:
     514                 :          0 :         return ret;
     515                 :            : }
     516                 :            : 
     517                 :          0 : void __rte_cold sxe2_rxqs_all_stop(struct rte_eth_dev *dev)
     518                 :            : {
     519                 :          0 :         struct rte_eth_dev_data *data = dev->data;
     520                 :          0 :         struct sxe2_adapter *adapter  = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
     521                 :          0 :         struct sxe2_vsi     *vsi      = adapter->vsi_ctxt.main_vsi;
     522                 :          0 :         struct sxe2_stats   *sw_stats_prev = &vsi->vsi_stats.vsi_sw_stats_prev;
     523                 :          0 :         struct sxe2_rx_queue *rxq = NULL;
     524                 :          0 :         int32_t ret;
     525                 :          0 :         uint16_t nb_rxq;
     526                 :          0 :         PMD_INIT_FUNC_TRACE();
     527                 :            : 
     528         [ #  # ]:          0 :         for (nb_rxq = 0; nb_rxq < data->nb_rx_queues; nb_rxq++) {
     529                 :          0 :                 ret = sxe2_rx_queue_stop(dev, nb_rxq);
     530         [ #  # ]:          0 :                 if (ret) {
     531                 :          0 :                         PMD_LOG_ERR(RX, "Fail to stop rx queue %u", nb_rxq);
     532                 :          0 :                         continue;
     533                 :            :                 }
     534                 :            : 
     535                 :          0 :                 rxq = dev->data->rx_queues[nb_rxq];
     536         [ #  # ]:          0 :                 if (rxq) {
     537                 :          0 :                         sw_stats_prev->ipackets += rxq->sw_stats.pkts;
     538                 :          0 :                         sw_stats_prev->ierrors += rxq->sw_stats.drop_pkts;
     539                 :          0 :                         sw_stats_prev->ibytes += rxq->sw_stats.bytes;
     540                 :            : 
     541                 :          0 :                         sw_stats_prev->rx_sw_unicast_packets += rxq->sw_stats.unicast_pkts;
     542                 :          0 :                         sw_stats_prev->rx_sw_broadcast_packets += rxq->sw_stats.broadcast_pkts;
     543                 :          0 :                         sw_stats_prev->rx_sw_multicast_packets += rxq->sw_stats.multicast_pkts;
     544                 :          0 :                         sw_stats_prev->rx_sw_drop_packets += rxq->sw_stats.drop_pkts;
     545                 :          0 :                         sw_stats_prev->rx_sw_drop_bytes += rxq->sw_stats.drop_bytes;
     546                 :            :                 }
     547                 :            :         }
     548                 :          0 : }
     549                 :            : 
     550                 :          0 : static int32_t sxe2_monitor_callback(const uint64_t value,
     551                 :            :                                  const uint64_t arg[RTE_POWER_MONITOR_OPAQUE_SZ] __rte_unused)
     552                 :            : {
     553                 :          0 :         const uint64_t dd_state = rte_cpu_to_le_64(SXE2_RX_DESC_STATUS_DD_MASK);
     554         [ #  # ]:          0 :         return (value & dd_state) == dd_state ? -1 : 0;
     555                 :            : }
     556                 :            : 
     557                 :          0 : int32_t sxe2_get_monitor_addr(void *rx_queue, struct rte_power_monitor_cond *pmc)
     558                 :            : {
     559                 :          0 :         volatile union sxe2_rx_desc *rxdp;
     560                 :          0 :         struct sxe2_rx_queue *rxq = (struct sxe2_rx_queue *)rx_queue;
     561                 :            : 
     562                 :          0 :         rxdp = &rxq->desc_ring[rxq->processing_idx];
     563                 :            : 
     564                 :          0 :         pmc->addr = &rxdp->wb.status_err_ptype_len;
     565                 :          0 :         pmc->fn   = sxe2_monitor_callback;
     566                 :          0 :         pmc->size = sizeof(uint16_t);
     567                 :            : 
     568                 :          0 :         return 0;
     569                 :            : }

Generated by: LCOV version 1.14