LCOV - code coverage report
Current view: top level - drivers/net/ark - ark_ethdev_rx.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 205 0.0 %
Date: 2025-11-01 17:50:34 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 88 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright (c) 2015-2018 Atomic Rules LLC
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <unistd.h>
       6                 :            : 
       7                 :            : #include "ark_ethdev_rx.h"
       8                 :            : #include "ark_global.h"
       9                 :            : #include "ark_logs.h"
      10                 :            : #include "ark_mpu.h"
      11                 :            : #include "ark_udm.h"
      12                 :            : #include "ark_ext.h"
      13                 :            : 
      14                 :            : #define ARK_RX_META_SIZE 32
      15                 :            : #define ARK_RX_META_OFFSET (RTE_PKTMBUF_HEADROOM - ARK_RX_META_SIZE)
      16                 :            : #define ARK_RX_MPU_CHUNK (64U)
      17                 :            : #define ARK_PCIE_BOUNDARY 4096
      18                 :            : 
      19                 :            : /* Forward declarations */
      20                 :            : struct ark_rx_queue;
      21                 :            : struct ark_rx_meta;
      22                 :            : 
      23                 :            : static void dump_mbuf_data(struct rte_mbuf *mbuf, uint16_t lo, uint16_t hi);
      24                 :            : static void ark_ethdev_rx_dump(const char *name, struct ark_rx_queue *queue);
      25                 :            : static uint32_t ark_rx_jumbo(struct ark_rx_queue *queue,
      26                 :            :                                  struct ark_rx_meta *meta,
      27                 :            :                                  struct rte_mbuf *mbuf0,
      28                 :            :                                  uint32_t cons_index);
      29                 :            : static inline int ark_rx_seed_mbufs(struct ark_rx_queue *queue);
      30                 :            : 
      31                 :            : /* ************************************************************************* */
      32                 :            : struct __rte_cache_aligned ark_rx_queue {
      33                 :            :         /* array of mbufs to populate */
      34                 :            :         struct rte_mbuf **reserve_q;
      35                 :            :         /* array of physical addresses of the mbuf data pointer */
      36                 :            :         /* This point is a virtual address */
      37                 :            :         rte_iova_t *paddress_q;
      38                 :            :         struct rte_mempool *mb_pool;
      39                 :            : 
      40                 :            :         struct ark_udm_t *udm;
      41                 :            :         struct ark_mpu_t *mpu;
      42                 :            : 
      43                 :            :         rx_user_meta_hook_fn rx_user_meta_hook;
      44                 :            :         void *ext_user_data;
      45                 :            : 
      46                 :            :         uint32_t starvation;
      47                 :            :         uint32_t dataroom;
      48                 :            :         uint32_t headroom;
      49                 :            : 
      50                 :            :         uint32_t queue_size;
      51                 :            :         uint32_t queue_mask;
      52                 :            : 
      53                 :            :         uint32_t seed_index;            /* step 1 set with empty mbuf */
      54                 :            :         uint32_t cons_index;            /* step 3 consumed by driver */
      55                 :            : 
      56                 :            :         /* The queue Id is used to identify the HW Q */
      57                 :            :         uint16_t phys_qid;
      58                 :            : 
      59                 :            :         /* The queue Index is used within the dpdk device structures */
      60                 :            :         uint16_t queue_index;
      61                 :            : 
      62                 :            :         /* next cache line - fields written by device */
      63                 :            :         alignas(RTE_CACHE_LINE_MIN_SIZE) RTE_MARKER cacheline1;
      64                 :            : 
      65                 :            :         volatile uint32_t prod_index;   /* step 2 filled by FPGA */
      66                 :            : };
      67                 :            : 
      68                 :            : /* ************************************************************************* */
      69                 :            : static int
      70                 :          0 : ark_rx_hw_setup(struct rte_eth_dev *dev,
      71                 :            :                     struct ark_rx_queue *queue,
      72                 :            :                     uint16_t rx_queue_idx)
      73                 :            : {
      74                 :            :         rte_iova_t queue_base;
      75                 :            :         rte_iova_t phys_addr_q_base;
      76                 :            :         rte_iova_t phys_addr_prod_index;
      77                 :            : 
      78                 :          0 :         queue_base = rte_malloc_virt2iova(queue);
      79                 :          0 :         phys_addr_prod_index = queue_base +
      80                 :            :                 offsetof(struct ark_rx_queue, prod_index);
      81                 :            : 
      82                 :          0 :         phys_addr_q_base = rte_malloc_virt2iova(queue->paddress_q);
      83                 :            : 
      84                 :            :         /* Verify HW */
      85         [ #  # ]:          0 :         if (ark_mpu_verify(queue->mpu, sizeof(rte_iova_t))) {
      86                 :          0 :                 ARK_PMD_LOG(ERR, "Illegal configuration rx queue\n");
      87                 :          0 :                 return -1;
      88                 :            :         }
      89                 :            : 
      90                 :            :         /* Stop and Reset and configure MPU */
      91                 :          0 :         ark_mpu_configure(queue->mpu, phys_addr_q_base, queue->queue_size, 0);
      92                 :            : 
      93                 :          0 :         ark_udm_write_addr(queue->udm, phys_addr_prod_index);
      94                 :            : 
      95                 :            :         /* The seed is the producer index for the HW */
      96                 :          0 :         ark_mpu_set_producer(queue->mpu, queue->seed_index);
      97                 :          0 :         dev->data->rx_queue_state[rx_queue_idx] = RTE_ETH_QUEUE_STATE_STOPPED;
      98                 :            : 
      99                 :          0 :         return 0;
     100                 :            : }
     101                 :            : 
     102                 :            : static inline void
     103                 :            : ark_rx_update_cons_index(struct ark_rx_queue *queue, uint32_t cons_index)
     104                 :            : {
     105                 :          0 :         queue->cons_index = cons_index;
     106         [ #  # ]:          0 :         if ((cons_index + queue->queue_size - queue->seed_index) >= ARK_RX_MPU_CHUNK) {
     107                 :          0 :                 ark_rx_seed_mbufs(queue);
     108                 :          0 :                 ark_mpu_set_producer(queue->mpu, queue->seed_index);
     109                 :            :         }
     110                 :            : }
     111                 :            : 
     112                 :            : /* ************************************************************************* */
     113                 :            : int
     114                 :          0 : ark_dev_rx_queue_setup(struct rte_eth_dev *dev,
     115                 :            :                            uint16_t queue_idx,
     116                 :            :                            uint16_t nb_desc,
     117                 :            :                            unsigned int socket_id,
     118                 :            :                            const struct rte_eth_rxconf *rx_conf,
     119                 :            :                            struct rte_mempool *mb_pool)
     120                 :            : {
     121                 :            :         static int warning1;            /* = 0 */
     122                 :          0 :         struct ark_adapter *ark = dev->data->dev_private;
     123                 :            : 
     124                 :            :         struct ark_rx_queue *queue;
     125                 :            :         uint32_t i;
     126                 :            :         int status;
     127                 :            : 
     128                 :          0 :         int qidx = ark->qbase + queue_idx;
     129                 :            : 
     130                 :            :         /* We may already be setup, free memory prior to re-allocation */
     131         [ #  # ]:          0 :         if (dev->data->rx_queues[queue_idx] != NULL) {
     132                 :          0 :                 ark_dev_rx_queue_release(dev->data->rx_queues[queue_idx]);
     133                 :          0 :                 dev->data->rx_queues[queue_idx] = NULL;
     134                 :            :         }
     135                 :            : 
     136   [ #  #  #  # ]:          0 :         if (rx_conf != NULL && warning1 == 0) {
     137                 :          0 :                 warning1 = 1;
     138                 :          0 :                 ARK_PMD_LOG(NOTICE,
     139                 :            :                             "Arkville ignores rte_eth_rxconf argument.\n");
     140                 :            :         }
     141                 :            : 
     142                 :            :         if (RTE_PKTMBUF_HEADROOM < ARK_RX_META_SIZE) {
     143                 :            :                 ARK_PMD_LOG(ERR,
     144                 :            :                             "Error: DPDK Arkville requires head room > %d bytes (%s)\n",
     145                 :            :                             ARK_RX_META_SIZE, __func__);
     146                 :            :                 return -1;              /* ERROR CODE */
     147                 :            :         }
     148                 :            : 
     149         [ #  # ]:          0 :         if (!rte_is_power_of_2(nb_desc)) {
     150                 :          0 :                 ARK_PMD_LOG(ERR,
     151                 :            :                             "DPDK Arkville configuration queue size must be power of two %u (%s)\n",
     152                 :            :                             nb_desc, __func__);
     153                 :          0 :                 return -1;              /* ERROR CODE */
     154                 :            :         }
     155                 :            : 
     156                 :            :         /* Allocate queue struct */
     157                 :          0 :         queue = rte_zmalloc_socket("Ark_rxqueue",
     158                 :            :                                    sizeof(struct ark_rx_queue),
     159                 :            :                                    64,
     160                 :            :                                    socket_id);
     161         [ #  # ]:          0 :         if (queue == 0) {
     162                 :          0 :                 ARK_PMD_LOG(ERR, "Failed to allocate memory in %s\n", __func__);
     163                 :          0 :                 return -ENOMEM;
     164                 :            :         }
     165                 :            : 
     166                 :            :         /* NOTE zmalloc is used, no need to 0 indexes, etc. */
     167         [ #  # ]:          0 :         queue->mb_pool = mb_pool;
     168                 :          0 :         queue->dataroom = rte_pktmbuf_data_room_size(mb_pool) -
     169                 :            :                 RTE_PKTMBUF_HEADROOM;
     170                 :            : 
     171                 :            :         /* Check pool's private data to confirm pool structure */
     172         [ #  # ]:          0 :         if (mb_pool->private_data_size != 0) {
     173                 :            :                 struct rte_pmd_ark_lmbuf_mempool_priv *pool_priv = rte_mempool_get_priv(mb_pool);
     174         [ #  # ]:          0 :                 if (strncmp(pool_priv->cookie, ARK_MEMPOOL_COOKIE, sizeof(pool_priv->cookie)) == 0)
     175                 :          0 :                         queue->dataroom = pool_priv->dataroom;
     176                 :            :         }
     177                 :          0 :         queue->headroom = RTE_PKTMBUF_HEADROOM;
     178                 :          0 :         queue->phys_qid = qidx;
     179                 :          0 :         queue->queue_index = queue_idx;
     180                 :          0 :         queue->queue_size = nb_desc;
     181                 :          0 :         queue->queue_mask = nb_desc - 1;
     182                 :          0 :         queue->rx_user_meta_hook = ark->user_ext.rx_user_meta_hook;
     183                 :          0 :         queue->ext_user_data = ark->user_data[dev->data->port_id];
     184                 :            : 
     185                 :          0 :         queue->reserve_q =
     186                 :          0 :                 rte_zmalloc_socket("Ark_rx_queue mbuf",
     187                 :            :                                    nb_desc * sizeof(struct rte_mbuf *),
     188                 :            :                                    512,
     189                 :            :                                    socket_id);
     190                 :            :         /* Align buffer to PCIe's boundary size to reduce upstream read request TLPs from FPGA */
     191                 :          0 :         queue->paddress_q =
     192                 :          0 :                 rte_zmalloc_socket("Ark_rx_queue paddr",
     193                 :            :                                    nb_desc * sizeof(rte_iova_t),
     194                 :            :                                    ARK_PCIE_BOUNDARY,
     195                 :            :                                    socket_id);
     196                 :            : 
     197   [ #  #  #  # ]:          0 :         if (queue->reserve_q == 0 || queue->paddress_q == 0) {
     198                 :          0 :                 ARK_PMD_LOG(ERR,
     199                 :            :                             "Failed to allocate queue memory in %s\n",
     200                 :            :                             __func__);
     201                 :          0 :                 rte_free(queue->reserve_q);
     202                 :          0 :                 rte_free(queue->paddress_q);
     203                 :          0 :                 rte_free(queue);
     204                 :          0 :                 return -ENOMEM;
     205                 :            :         }
     206                 :            : 
     207                 :          0 :         dev->data->rx_queues[queue_idx] = queue;
     208                 :          0 :         queue->udm = RTE_PTR_ADD(ark->udm.v, qidx * ARK_UDM_QOFFSET);
     209                 :          0 :         queue->mpu = RTE_PTR_ADD(ark->mpurx.v, qidx * ARK_MPU_QOFFSET);
     210                 :            : 
     211                 :            :         /* Configure UDM per queue */
     212                 :          0 :         ark_udm_configure(queue->udm,
     213                 :            :                           RTE_PKTMBUF_HEADROOM,
     214                 :            :                           queue->dataroom);
     215                 :          0 :         ark_udm_queue_stats_reset(queue->udm);
     216                 :            : 
     217                 :            :         /* populate mbuf reserve */
     218                 :          0 :         status = ark_rx_seed_mbufs(queue);
     219                 :            : 
     220         [ #  # ]:          0 :         if (queue->seed_index != nb_desc) {
     221                 :          0 :                 ARK_PMD_LOG(ERR, "Failed to allocate %u mbufs for RX queue %d\n",
     222                 :            :                             nb_desc, qidx);
     223                 :            :                 status = -1;
     224                 :            :         }
     225                 :            :         /* MPU Setup */
     226         [ #  # ]:          0 :         if (status == 0)
     227                 :          0 :                 status = ark_rx_hw_setup(dev, queue, queue_idx);
     228                 :            : 
     229         [ #  # ]:          0 :         if (unlikely(status != 0)) {
     230                 :            :                 struct rte_mbuf **mbuf;
     231                 :            : 
     232                 :          0 :                 ARK_PMD_LOG(ERR, "Failed to initialize RX queue %d %s\n",
     233                 :            :                             qidx,
     234                 :            :                             __func__);
     235                 :            :                 /* Free the mbufs allocated */
     236                 :          0 :                 for (i = 0, mbuf = queue->reserve_q;
     237         [ #  # ]:          0 :                      i < queue->seed_index; ++i, mbuf++) {
     238                 :          0 :                         rte_pktmbuf_free(*mbuf);
     239                 :            :                 }
     240                 :          0 :                 rte_free(queue->reserve_q);
     241                 :          0 :                 rte_free(queue->paddress_q);
     242                 :          0 :                 rte_free(queue);
     243                 :          0 :                 return -1;              /* ERROR CODE */
     244                 :            :         }
     245                 :            : 
     246                 :            :         return 0;
     247                 :            : }
     248                 :            : 
     249                 :            : /* ************************************************************************* */
     250                 :            : uint16_t
     251                 :          0 : ark_recv_pkts(void *rx_queue,
     252                 :            :                   struct rte_mbuf **rx_pkts,
     253                 :            :                   uint16_t nb_pkts)
     254                 :            : {
     255                 :            :         struct ark_rx_queue *queue;
     256                 :            :         register uint32_t cons_index, prod_index;
     257                 :            :         uint16_t nb;
     258                 :            :         uint16_t i;
     259                 :            :         struct rte_mbuf *mbuf;
     260                 :            :         struct rte_mbuf **pmbuf;
     261                 :            :         struct ark_rx_meta *meta;
     262                 :            :         rx_user_meta_hook_fn rx_user_meta_hook;
     263                 :            : 
     264                 :            :         queue = (struct ark_rx_queue *)rx_queue;
     265         [ #  # ]:          0 :         if (unlikely(queue == 0))
     266                 :            :                 return 0;
     267         [ #  # ]:          0 :         if (unlikely(nb_pkts == 0))
     268                 :            :                 return 0;
     269         [ #  # ]:          0 :         if (unlikely(queue->starvation))
     270                 :          0 :                 ark_rx_seed_mbufs(queue);
     271                 :            : 
     272                 :          0 :         prod_index = queue->prod_index;
     273                 :          0 :         cons_index = queue->cons_index;
     274         [ #  # ]:          0 :         if (prod_index == cons_index)
     275                 :            :                 return 0;
     276                 :            :         nb = 0;
     277                 :            : 
     278         [ #  # ]:          0 :         while (prod_index != cons_index) {
     279                 :          0 :                 mbuf = queue->reserve_q[cons_index & queue->queue_mask];
     280                 :            :                 /* prefetch mbuf */
     281                 :            :                 rte_mbuf_prefetch_part1(mbuf);
     282                 :            :                 rte_mbuf_prefetch_part2(mbuf);
     283                 :            : 
     284                 :            :                 /* META DATA embedded in headroom */
     285                 :          0 :                 meta = RTE_PTR_ADD(mbuf->buf_addr, ARK_RX_META_OFFSET);
     286                 :            : 
     287                 :          0 :                 mbuf->pkt_len = meta->pkt_len;
     288                 :          0 :                 mbuf->data_len = meta->pkt_len;
     289                 :            : 
     290                 :            :                 if (ARK_DEBUG_CORE) {   /* debug sanity checks */
     291                 :            : 
     292                 :            :                         if ((meta->pkt_len > (1024 * 16)) ||
     293                 :            :                             (meta->pkt_len == 0)) {
     294                 :            :                                 ARK_PMD_LOG(DEBUG, "RX: Bad Meta Q: %u"
     295                 :            :                                            " cons: %" PRIU32
     296                 :            :                                            " prod: %" PRIU32
     297                 :            :                                            " seed_index %" PRIU32
     298                 :            :                                            "\n",
     299                 :            :                                            queue->phys_qid,
     300                 :            :                                            cons_index,
     301                 :            :                                            queue->prod_index,
     302                 :            :                                            queue->seed_index);
     303                 :            : 
     304                 :            : 
     305                 :            :                                 ARK_PMD_LOG(DEBUG, "       :  UDM"
     306                 :            :                                            " prod: %" PRIU32
     307                 :            :                                            " len: %u\n",
     308                 :            :                                            queue->udm->rt_cfg.prod_idx,
     309                 :            :                                            meta->pkt_len);
     310                 :            :                                 ark_mpu_dump(queue->mpu,
     311                 :            :                                              "    ",
     312                 :            :                                              queue->phys_qid);
     313                 :            :                                 dump_mbuf_data(mbuf, 0, 256);
     314                 :            :                                 /* its FUBAR so fix it */
     315                 :            :                                 mbuf->pkt_len = 63;
     316                 :            :                                 meta->pkt_len = 63;
     317                 :            :                         }
     318                 :            :                 }
     319                 :            : 
     320         [ #  # ]:          0 :                 if (unlikely(meta->pkt_len > queue->dataroom)) {
     321                 :          0 :                         uint32_t tcons = ark_rx_jumbo(queue, meta, mbuf, cons_index + 1);
     322                 :          0 :                         if ((int32_t)(prod_index - tcons) >= 0)
     323                 :            :                                 cons_index = tcons; /* nominal condition */
     324                 :            :                         else
     325                 :            :                                 break;
     326                 :            :                 } else {
     327                 :          0 :                         cons_index += 1;
     328                 :            :                 }
     329                 :            : 
     330                 :          0 :                 rx_pkts[nb] = mbuf;
     331                 :          0 :                 nb++;
     332         [ #  # ]:          0 :                 if (nb >= nb_pkts)
     333                 :            :                         break;
     334                 :            :         }
     335                 :            : 
     336                 :          0 :         rx_user_meta_hook = queue->rx_user_meta_hook;
     337         [ #  # ]:          0 :         for (pmbuf = rx_pkts, i = 0; rx_user_meta_hook && i < nb; i++) {
     338                 :          0 :                 mbuf = *pmbuf++;
     339                 :          0 :                 meta = RTE_PTR_ADD(mbuf->buf_addr, ARK_RX_META_OFFSET);
     340                 :          0 :                 rx_user_meta_hook(mbuf, meta->user_meta, queue->ext_user_data);
     341                 :            :         }
     342                 :            : 
     343                 :            :         ark_rx_update_cons_index(queue, cons_index);
     344                 :            : 
     345                 :            :         return nb;
     346                 :            : }
     347                 :            : 
     348                 :            : /* ************************************************************************* */
     349                 :            : static uint32_t
     350                 :            : ark_rx_jumbo(struct ark_rx_queue *queue,
     351                 :            :                  struct ark_rx_meta *meta,
     352                 :            :                  struct rte_mbuf *mbuf0,
     353                 :            :                  uint32_t cons_index)
     354                 :            : {
     355                 :            :         struct rte_mbuf *mbuf_prev;
     356                 :            :         struct rte_mbuf *mbuf;
     357                 :            : 
     358                 :            :         uint16_t remaining;
     359                 :            :         uint16_t data_len;
     360                 :            :         uint16_t segments;
     361                 :            : 
     362                 :            :         /* first buf populated by called */
     363                 :            :         mbuf_prev = mbuf0;
     364                 :            :         segments = 1;
     365                 :          0 :         data_len = RTE_MIN(meta->pkt_len, queue->dataroom);
     366                 :          0 :         remaining = meta->pkt_len - data_len;
     367                 :          0 :         mbuf0->data_len = data_len;
     368                 :            : 
     369                 :            :         /* HW guarantees that the data does not exceed prod_index! */
     370         [ #  # ]:          0 :         while (remaining != 0) {
     371                 :          0 :                 data_len = RTE_MIN(remaining,
     372                 :            :                                    queue->dataroom);
     373                 :            : 
     374                 :          0 :                 remaining -= data_len;
     375                 :          0 :                 segments += 1;
     376                 :            : 
     377                 :          0 :                 mbuf = queue->reserve_q[cons_index & queue->queue_mask];
     378                 :          0 :                 mbuf_prev->next = mbuf;
     379                 :            :                 mbuf_prev = mbuf;
     380                 :          0 :                 mbuf->data_len = data_len;
     381                 :            : 
     382                 :          0 :                 cons_index += 1;
     383                 :            :         }
     384                 :            : 
     385         [ #  # ]:          0 :         mbuf0->nb_segs = segments;
     386                 :            :         return cons_index;
     387                 :            : }
     388                 :            : 
     389                 :            : /* Drain the internal queue allowing hw to clear out. */
     390                 :            : static void
     391                 :          0 : ark_rx_queue_drain(struct ark_rx_queue *queue)
     392                 :            : {
     393                 :            :         register uint32_t cons_index;
     394                 :            :         struct rte_mbuf *mbuf;
     395                 :            : 
     396                 :          0 :         cons_index = queue->cons_index;
     397                 :            : 
     398                 :            :         /* NOT performance optimized, since this is a one-shot call */
     399         [ #  # ]:          0 :         while ((cons_index ^ queue->prod_index) & queue->queue_mask) {
     400                 :          0 :                 mbuf = queue->reserve_q[cons_index & queue->queue_mask];
     401                 :          0 :                 rte_pktmbuf_free(mbuf);
     402         [ #  # ]:          0 :                 cons_index++;
     403                 :            :                 ark_rx_update_cons_index(queue, cons_index);
     404                 :            :         }
     405                 :          0 : }
     406                 :            : 
     407                 :            : int
     408                 :          0 : ark_dev_rx_queue_count(void *rx_queue)
     409                 :            : {
     410                 :            :         struct ark_rx_queue *queue;
     411                 :            : 
     412                 :            :         queue = rx_queue;
     413                 :          0 :         return (queue->prod_index - queue->cons_index);   /* mod arith */
     414                 :            : }
     415                 :            : 
     416                 :            : /* ************************************************************************* */
     417                 :            : int
     418                 :          0 : ark_rx_start_queue(struct rte_eth_dev *dev, uint16_t queue_id)
     419                 :            : {
     420                 :            :         struct ark_rx_queue *queue;
     421                 :            : 
     422                 :          0 :         queue = dev->data->rx_queues[queue_id];
     423         [ #  # ]:          0 :         if (queue == 0)
     424                 :            :                 return -1;
     425                 :            : 
     426                 :          0 :         dev->data->rx_queue_state[queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
     427                 :            : 
     428                 :          0 :         ark_mpu_set_producer(queue->mpu, queue->seed_index);
     429                 :          0 :         ark_mpu_start(queue->mpu);
     430                 :            : 
     431                 :          0 :         ark_udm_queue_enable(queue->udm, 1);
     432                 :            : 
     433                 :          0 :         return 0;
     434                 :            : }
     435                 :            : 
     436                 :            : /* ************************************************************************* */
     437                 :            : 
     438                 :            : /* Queue can be restarted.   data remains
     439                 :            :  */
     440                 :            : int
     441                 :          0 : ark_rx_stop_queue(struct rte_eth_dev *dev, uint16_t queue_id)
     442                 :            : {
     443                 :            :         struct ark_rx_queue *queue;
     444                 :            : 
     445                 :          0 :         queue = dev->data->rx_queues[queue_id];
     446         [ #  # ]:          0 :         if (queue == 0)
     447                 :            :                 return -1;
     448                 :            : 
     449                 :          0 :         ark_udm_queue_enable(queue->udm, 0);
     450                 :            : 
     451                 :          0 :         dev->data->rx_queue_state[queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
     452                 :            : 
     453                 :          0 :         return 0;
     454                 :            : }
     455                 :            : 
     456                 :            : /* ************************************************************************* */
     457                 :            : static inline int
     458                 :          0 : ark_rx_seed_mbufs(struct ark_rx_queue *queue)
     459                 :            : {
     460                 :          0 :         uint32_t limit = RTE_ALIGN_FLOOR(queue->cons_index, ARK_RX_MPU_CHUNK) +
     461                 :          0 :                 queue->queue_size;
     462                 :          0 :         uint32_t seed_index = queue->seed_index;
     463                 :            : 
     464                 :            :         uint32_t count = 0;
     465                 :          0 :         uint32_t seed_m = queue->seed_index & queue->queue_mask;
     466                 :            : 
     467                 :          0 :         uint32_t nb = limit - seed_index;
     468                 :            :         int status;
     469                 :            : 
     470                 :            :         /* Handle wrap around -- remainder is filled on the next call */
     471         [ #  # ]:          0 :         if (unlikely(seed_m + nb > queue->queue_size))
     472                 :          0 :                 nb = queue->queue_size - seed_m;
     473                 :            : 
     474                 :          0 :         struct rte_mbuf **mbufs = &queue->reserve_q[seed_m];
     475                 :            :         do {
     476                 :          0 :                 status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, nb);
     477         [ #  # ]:          0 :                 if (status == 0)
     478                 :            :                         break;
     479                 :            :                 /* Try again with a smaller request, keeping aligned with chunk size */
     480                 :          0 :                 nb = RTE_ALIGN_FLOOR(nb / 2, ARK_RX_MPU_CHUNK);
     481         [ #  # ]:          0 :         } while (nb >= ARK_RX_MPU_CHUNK);
     482                 :            : 
     483         [ #  # ]:          0 :         if (unlikely(status != 0)) {
     484         [ #  # ]:          0 :                 if (queue->starvation == 0) {
     485                 :          0 :                         ARK_PMD_LOG(NOTICE,
     486                 :            :                                     "Could not allocate %u mbufs from pool for RX queue %u; %u free buffers remaining\n",
     487                 :            :                                     ARK_RX_MPU_CHUNK, queue->queue_index,
     488                 :            :                                     queue->seed_index - queue->cons_index);
     489                 :          0 :                         queue->starvation = 1;
     490                 :            :                 }
     491                 :          0 :                 return -1;
     492                 :            :         }
     493                 :          0 :         queue->starvation = 0;
     494                 :            : 
     495                 :            :         if (ARK_DEBUG_CORE) {           /* DEBUG */
     496                 :            :                 while (count != nb) {
     497                 :            :                         struct rte_mbuf *mbuf_init =
     498                 :            :                                 queue->reserve_q[seed_m + count];
     499                 :            : 
     500                 :            :                         memset(mbuf_init->buf_addr, -1, 512);
     501                 :            :                         *((uint32_t *)mbuf_init->buf_addr) =
     502                 :            :                                 seed_index + count;
     503                 :            :                         *(uint16_t *)RTE_PTR_ADD(mbuf_init->buf_addr, 4) =
     504                 :            :                                 queue->phys_qid;
     505                 :            :                         count++;
     506                 :            :                 }
     507                 :            :                 count = 0;
     508                 :            :         } /* DEBUG */
     509                 :          0 :         queue->seed_index += nb;
     510                 :            : 
     511                 :            :         /* Duff's device https://en.wikipedia.org/wiki/Duff's_device */
     512   [ #  #  #  # ]:          0 :         switch (nb % 4) {
     513                 :            :         case 0:
     514         [ #  # ]:          0 :                 while (count != nb) {
     515                 :          0 :                         queue->paddress_q[seed_m++] =
     516                 :          0 :                                 (*mbufs++)->buf_iova;
     517                 :          0 :                         count++;
     518                 :            :                 /* FALLTHROUGH */
     519                 :          0 :         case 3:
     520                 :          0 :                 queue->paddress_q[seed_m++] =
     521                 :          0 :                         (*mbufs++)->buf_iova;
     522                 :          0 :                 count++;
     523                 :            :                 /* FALLTHROUGH */
     524                 :          0 :         case 2:
     525                 :          0 :                 queue->paddress_q[seed_m++] =
     526                 :          0 :                         (*mbufs++)->buf_iova;
     527                 :          0 :                 count++;
     528                 :            :                 /* FALLTHROUGH */
     529                 :          0 :         case 1:
     530                 :          0 :                 queue->paddress_q[seed_m++] =
     531                 :          0 :                         (*mbufs++)->buf_iova;
     532                 :          0 :                 count++;
     533                 :            :                 /* FALLTHROUGH */
     534                 :            : 
     535                 :            :                 } /* while (count != nb) */
     536                 :            :         } /* switch */
     537                 :            : 
     538                 :            :         return 0;
     539                 :            : }
     540                 :            : 
     541                 :            : void
     542                 :          0 : ark_rx_dump_queue(struct rte_eth_dev *dev, uint16_t queue_id,
     543                 :            :                       const char *msg)
     544                 :            : {
     545                 :            :         struct ark_rx_queue *queue;
     546                 :            : 
     547                 :          0 :         queue = dev->data->rx_queues[queue_id];
     548                 :            : 
     549                 :          0 :         ark_ethdev_rx_dump(msg, queue);
     550                 :          0 : }
     551                 :            : 
     552                 :            : /* ************************************************************************* */
     553                 :            : /* Call on device closed no user API, queue is stopped */
     554                 :            : void
     555                 :          0 : ark_dev_rx_queue_release(void *vqueue)
     556                 :            : {
     557                 :            :         struct ark_rx_queue *queue;
     558                 :            : 
     559                 :            :         queue = (struct ark_rx_queue *)vqueue;
     560         [ #  # ]:          0 :         if (queue == 0)
     561                 :            :                 return;
     562                 :            : 
     563                 :          0 :         ark_udm_queue_enable(queue->udm, 0);
     564                 :            :         /* Stop the MPU since pointer are going away */
     565                 :          0 :         ark_mpu_stop(queue->mpu);
     566                 :            : 
     567                 :            :         /* Need to clear out mbufs here, dropping packets along the way */
     568                 :          0 :         ark_rx_queue_drain(queue);
     569                 :            : 
     570                 :          0 :         rte_free(queue->reserve_q);
     571                 :          0 :         rte_free(queue->paddress_q);
     572                 :          0 :         rte_free(queue);
     573                 :            : }
     574                 :            : 
     575                 :            : void
     576                 :          0 : ark_rx_queue_stats_get(void *vqueue, struct rte_eth_stats *stats,
     577                 :            :                        struct eth_queue_stats *qstats)
     578                 :            : {
     579                 :            :         struct ark_rx_queue *queue;
     580                 :            :         struct ark_udm_t *udm;
     581                 :            : 
     582                 :            :         queue = vqueue;
     583         [ #  # ]:          0 :         if (queue == NULL)
     584                 :            :                 return;
     585                 :          0 :         udm = queue->udm;
     586                 :            : 
     587                 :          0 :         uint64_t ibytes = ark_udm_bytes(udm);
     588                 :          0 :         uint64_t ipackets = ark_udm_packets(udm);
     589                 :          0 :         uint64_t idropped = ark_udm_dropped(queue->udm);
     590                 :            : 
     591                 :          0 :         stats->ipackets += ipackets;
     592                 :          0 :         stats->ibytes += ibytes;
     593                 :          0 :         stats->imissed += idropped;
     594                 :            : 
     595   [ #  #  #  # ]:          0 :         if (qstats && queue->queue_index < RTE_ETHDEV_QUEUE_STAT_CNTRS) {
     596                 :          0 :                 qstats->q_ipackets[queue->queue_index] = ipackets;
     597                 :          0 :                 qstats->q_ibytes[queue->queue_index] = ibytes;
     598                 :          0 :                 qstats->q_errors[queue->queue_index] = idropped;
     599                 :            :         }
     600                 :            : }
     601                 :            : 
     602                 :            : void
     603                 :          0 : ark_rx_queue_stats_reset(void *vqueue)
     604                 :            : {
     605                 :            :         struct ark_rx_queue *queue;
     606                 :            : 
     607                 :            :         queue = vqueue;
     608         [ #  # ]:          0 :         if (queue == 0)
     609                 :            :                 return;
     610                 :            : 
     611                 :          0 :         ark_udm_queue_stats_reset(queue->udm);
     612                 :            : }
     613                 :            : 
     614                 :            : static void
     615                 :          0 : ark_ethdev_rx_dump(const char *name, struct ark_rx_queue *queue)
     616                 :            : {
     617         [ #  # ]:          0 :         if (queue == NULL)
     618                 :            :                 return;
     619                 :          0 :         ARK_PMD_LOG(DEBUG, "RX QUEUE %d -- %s", queue->phys_qid, name);
     620                 :          0 :         ARK_PMD_LOG(DEBUG, ARK_SU32 ARK_SU32 ARK_SU32 ARK_SU32 "\n",
     621                 :            :                         "queue_size", queue->queue_size,
     622                 :            :                         "seed_index", queue->seed_index,
     623                 :            :                         "prod_index", queue->prod_index,
     624                 :            :                         "cons_index", queue->cons_index);
     625                 :            : 
     626                 :          0 :         ark_mpu_dump(queue->mpu, name, queue->phys_qid);
     627                 :          0 :         ark_mpu_dump_setup(queue->mpu, queue->phys_qid);
     628                 :          0 :         ark_udm_dump_setup(queue->udm, queue->phys_qid);
     629                 :            : }
     630                 :            : 
     631                 :            : /* Only used in debug.
     632                 :            :  * This function is a raw memory dump of a portion of an mbuf's memory
     633                 :            :  * region.  The usual function, rte_pktmbuf_dump() only shows data
     634                 :            :  * with respect to the data_off field.  This function show data
     635                 :            :  * anywhere in the mbuf's buffer.  This is useful for examining
     636                 :            :  * data in the headroom or tailroom portion of an mbuf.
     637                 :            :  */
     638                 :            : static void
     639                 :            : dump_mbuf_data(struct rte_mbuf *mbuf, uint16_t lo, uint16_t hi)
     640                 :            : {
     641                 :            :         uint16_t i, j;
     642                 :            : 
     643                 :            :         ARK_PMD_LOG(DEBUG, " MBUF: %p len %d, off: %d\n",
     644                 :            :                     mbuf, mbuf->pkt_len, mbuf->data_off);
     645                 :            :         for (i = lo; i < hi; i += 16) {
     646                 :            :                 uint8_t *dp = RTE_PTR_ADD(mbuf->buf_addr, i);
     647                 :            : 
     648                 :            :                 ARK_PMD_LOG(DEBUG, "  %6d:  ", i);
     649                 :            :                 for (j = 0; j < 16; j++)
     650                 :            :                         ARK_PMD_LOG(DEBUG, " %02x", dp[j]);
     651                 :            : 
     652                 :            :                 ARK_PMD_LOG(DEBUG, "\n");
     653                 :            :         }
     654                 :            : }

Generated by: LCOV version 1.14