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 197 0.0 %
Date: 2025-01-02 22:41:34 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 76 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                 :            : 
      18                 :            : /* Forward declarations */
      19                 :            : struct ark_rx_queue;
      20                 :            : struct ark_rx_meta;
      21                 :            : 
      22                 :            : static void dump_mbuf_data(struct rte_mbuf *mbuf, uint16_t lo, uint16_t hi);
      23                 :            : static void ark_ethdev_rx_dump(const char *name, struct ark_rx_queue *queue);
      24                 :            : static uint32_t eth_ark_rx_jumbo(struct ark_rx_queue *queue,
      25                 :            :                                  struct ark_rx_meta *meta,
      26                 :            :                                  struct rte_mbuf *mbuf0,
      27                 :            :                                  uint32_t cons_index);
      28                 :            : static inline int eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue);
      29                 :            : 
      30                 :            : /* ************************************************************************* */
      31                 :            : struct __rte_cache_aligned ark_rx_queue {
      32                 :            :         /* array of mbufs to populate */
      33                 :            :         struct rte_mbuf **reserve_q;
      34                 :            :         /* array of physical addresses of the mbuf data pointer */
      35                 :            :         /* This point is a virtual address */
      36                 :            :         rte_iova_t *paddress_q;
      37                 :            :         struct rte_mempool *mb_pool;
      38                 :            : 
      39                 :            :         struct ark_udm_t *udm;
      40                 :            :         struct ark_mpu_t *mpu;
      41                 :            : 
      42                 :            :         rx_user_meta_hook_fn rx_user_meta_hook;
      43                 :            :         void *ext_user_data;
      44                 :            : 
      45                 :            :         uint32_t dataroom;
      46                 :            :         uint32_t headroom;
      47                 :            : 
      48                 :            :         uint32_t queue_size;
      49                 :            :         uint32_t queue_mask;
      50                 :            : 
      51                 :            :         uint32_t seed_index;            /* step 1 set with empty mbuf */
      52                 :            :         uint32_t cons_index;            /* step 3 consumed by driver */
      53                 :            : 
      54                 :            :         /* The queue Id is used to identify the HW Q */
      55                 :            :         uint16_t phys_qid;
      56                 :            : 
      57                 :            :         /* The queue Index is used within the dpdk device structures */
      58                 :            :         uint16_t queue_index;
      59                 :            : 
      60                 :            :         uint32_t unused;
      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 : eth_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                 :            : eth_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 :                 eth_ark_rx_seed_mbufs(queue);
     108                 :          0 :                 ark_mpu_set_producer(queue->mpu, queue->seed_index);
     109                 :            :         }
     110                 :            : }
     111                 :            : 
     112                 :            : /* ************************************************************************* */
     113                 :            : int
     114                 :          0 : eth_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 :                 eth_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                 :          0 :         queue->paddress_q =
     191                 :          0 :                 rte_zmalloc_socket("Ark_rx_queue paddr",
     192                 :            :                                    nb_desc * sizeof(rte_iova_t),
     193                 :            :                                    512,
     194                 :            :                                    socket_id);
     195                 :            : 
     196   [ #  #  #  # ]:          0 :         if (queue->reserve_q == 0 || queue->paddress_q == 0) {
     197                 :          0 :                 ARK_PMD_LOG(ERR,
     198                 :            :                             "Failed to allocate queue memory in %s\n",
     199                 :            :                             __func__);
     200                 :          0 :                 rte_free(queue->reserve_q);
     201                 :          0 :                 rte_free(queue->paddress_q);
     202                 :          0 :                 rte_free(queue);
     203                 :          0 :                 return -ENOMEM;
     204                 :            :         }
     205                 :            : 
     206                 :          0 :         dev->data->rx_queues[queue_idx] = queue;
     207                 :          0 :         queue->udm = RTE_PTR_ADD(ark->udm.v, qidx * ARK_UDM_QOFFSET);
     208                 :          0 :         queue->mpu = RTE_PTR_ADD(ark->mpurx.v, qidx * ARK_MPU_QOFFSET);
     209                 :            : 
     210                 :            :         /* Configure UDM per queue */
     211                 :          0 :         ark_udm_configure(queue->udm,
     212                 :            :                           RTE_PKTMBUF_HEADROOM,
     213                 :            :                           queue->dataroom);
     214                 :          0 :         ark_udm_queue_stats_reset(queue->udm);
     215                 :            : 
     216                 :            :         /* populate mbuf reserve */
     217                 :          0 :         status = eth_ark_rx_seed_mbufs(queue);
     218                 :            : 
     219         [ #  # ]:          0 :         if (queue->seed_index != nb_desc) {
     220                 :          0 :                 ARK_PMD_LOG(ERR, "Failed to allocate %u mbufs for RX queue %d\n",
     221                 :            :                             nb_desc, qidx);
     222                 :            :                 status = -1;
     223                 :            :         }
     224                 :            :         /* MPU Setup */
     225         [ #  # ]:          0 :         if (status == 0)
     226                 :          0 :                 status = eth_ark_rx_hw_setup(dev, queue, queue_idx);
     227                 :            : 
     228         [ #  # ]:          0 :         if (unlikely(status != 0)) {
     229                 :            :                 struct rte_mbuf **mbuf;
     230                 :            : 
     231                 :          0 :                 ARK_PMD_LOG(ERR, "Failed to initialize RX queue %d %s\n",
     232                 :            :                             qidx,
     233                 :            :                             __func__);
     234                 :            :                 /* Free the mbufs allocated */
     235                 :          0 :                 for (i = 0, mbuf = queue->reserve_q;
     236         [ #  # ]:          0 :                      i < queue->seed_index; ++i, mbuf++) {
     237                 :          0 :                         rte_pktmbuf_free(*mbuf);
     238                 :            :                 }
     239                 :          0 :                 rte_free(queue->reserve_q);
     240                 :          0 :                 rte_free(queue->paddress_q);
     241                 :          0 :                 rte_free(queue);
     242                 :          0 :                 return -1;              /* ERROR CODE */
     243                 :            :         }
     244                 :            : 
     245                 :            :         return 0;
     246                 :            : }
     247                 :            : 
     248                 :            : /* ************************************************************************* */
     249                 :            : uint16_t
     250                 :          0 : eth_ark_recv_pkts(void *rx_queue,
     251                 :            :                   struct rte_mbuf **rx_pkts,
     252                 :            :                   uint16_t nb_pkts)
     253                 :            : {
     254                 :            :         struct ark_rx_queue *queue;
     255                 :            :         register uint32_t cons_index, prod_index;
     256                 :            :         uint16_t nb;
     257                 :            :         uint16_t i;
     258                 :            :         struct rte_mbuf *mbuf;
     259                 :            :         struct rte_mbuf **pmbuf;
     260                 :            :         struct ark_rx_meta *meta;
     261                 :            :         rx_user_meta_hook_fn rx_user_meta_hook;
     262                 :            : 
     263                 :            :         queue = (struct ark_rx_queue *)rx_queue;
     264         [ #  # ]:          0 :         if (unlikely(queue == 0))
     265                 :            :                 return 0;
     266         [ #  # ]:          0 :         if (unlikely(nb_pkts == 0))
     267                 :            :                 return 0;
     268                 :          0 :         prod_index = queue->prod_index;
     269                 :          0 :         cons_index = queue->cons_index;
     270         [ #  # ]:          0 :         if (prod_index == cons_index)
     271                 :            :                 return 0;
     272                 :            :         nb = 0;
     273                 :            : 
     274         [ #  # ]:          0 :         while (prod_index != cons_index) {
     275                 :          0 :                 mbuf = queue->reserve_q[cons_index & queue->queue_mask];
     276                 :            :                 /* prefetch mbuf */
     277                 :            :                 rte_mbuf_prefetch_part1(mbuf);
     278                 :            :                 rte_mbuf_prefetch_part2(mbuf);
     279                 :            : 
     280                 :            :                 /* META DATA embedded in headroom */
     281                 :          0 :                 meta = RTE_PTR_ADD(mbuf->buf_addr, ARK_RX_META_OFFSET);
     282                 :            : 
     283                 :          0 :                 mbuf->pkt_len = meta->pkt_len;
     284                 :          0 :                 mbuf->data_len = meta->pkt_len;
     285                 :            : 
     286                 :            :                 if (ARK_DEBUG_CORE) {   /* debug sanity checks */
     287                 :            : 
     288                 :            :                         if ((meta->pkt_len > (1024 * 16)) ||
     289                 :            :                             (meta->pkt_len == 0)) {
     290                 :            :                                 ARK_PMD_LOG(DEBUG, "RX: Bad Meta Q: %u"
     291                 :            :                                            " cons: %" PRIU32
     292                 :            :                                            " prod: %" PRIU32
     293                 :            :                                            " seed_index %" PRIU32
     294                 :            :                                            "\n",
     295                 :            :                                            queue->phys_qid,
     296                 :            :                                            cons_index,
     297                 :            :                                            queue->prod_index,
     298                 :            :                                            queue->seed_index);
     299                 :            : 
     300                 :            : 
     301                 :            :                                 ARK_PMD_LOG(DEBUG, "       :  UDM"
     302                 :            :                                            " prod: %" PRIU32
     303                 :            :                                            " len: %u\n",
     304                 :            :                                            queue->udm->rt_cfg.prod_idx,
     305                 :            :                                            meta->pkt_len);
     306                 :            :                                 ark_mpu_dump(queue->mpu,
     307                 :            :                                              "    ",
     308                 :            :                                              queue->phys_qid);
     309                 :            :                                 dump_mbuf_data(mbuf, 0, 256);
     310                 :            :                                 /* its FUBAR so fix it */
     311                 :            :                                 mbuf->pkt_len = 63;
     312                 :            :                                 meta->pkt_len = 63;
     313                 :            :                         }
     314                 :            :                 }
     315                 :            : 
     316         [ #  # ]:          0 :                 if (unlikely(meta->pkt_len > queue->dataroom))
     317                 :          0 :                         cons_index = eth_ark_rx_jumbo
     318                 :            :                                 (queue, meta, mbuf, cons_index + 1);
     319                 :            :                 else
     320                 :          0 :                         cons_index += 1;
     321                 :            : 
     322                 :          0 :                 rx_pkts[nb] = mbuf;
     323                 :          0 :                 nb++;
     324         [ #  # ]:          0 :                 if (nb >= nb_pkts)
     325                 :            :                         break;
     326                 :            :         }
     327                 :            : 
     328                 :          0 :         rx_user_meta_hook = queue->rx_user_meta_hook;
     329         [ #  # ]:          0 :         for (pmbuf = rx_pkts, i = 0; rx_user_meta_hook && i < nb; i++) {
     330                 :          0 :                 mbuf = *pmbuf++;
     331                 :          0 :                 meta = RTE_PTR_ADD(mbuf->buf_addr, ARK_RX_META_OFFSET);
     332                 :          0 :                 rx_user_meta_hook(mbuf, meta->user_meta, queue->ext_user_data);
     333                 :            :         }
     334                 :            : 
     335                 :            :         eth_ark_rx_update_cons_index(queue, cons_index);
     336                 :            : 
     337                 :            :         return nb;
     338                 :            : }
     339                 :            : 
     340                 :            : /* ************************************************************************* */
     341                 :            : static uint32_t
     342                 :            : eth_ark_rx_jumbo(struct ark_rx_queue *queue,
     343                 :            :                  struct ark_rx_meta *meta,
     344                 :            :                  struct rte_mbuf *mbuf0,
     345                 :            :                  uint32_t cons_index)
     346                 :            : {
     347                 :            :         struct rte_mbuf *mbuf_prev;
     348                 :            :         struct rte_mbuf *mbuf;
     349                 :            : 
     350                 :            :         uint16_t remaining;
     351                 :            :         uint16_t data_len;
     352                 :            :         uint16_t segments;
     353                 :            : 
     354                 :            :         /* first buf populated by called */
     355                 :            :         mbuf_prev = mbuf0;
     356                 :            :         segments = 1;
     357                 :          0 :         data_len = RTE_MIN(meta->pkt_len, queue->dataroom);
     358                 :          0 :         remaining = meta->pkt_len - data_len;
     359                 :          0 :         mbuf0->data_len = data_len;
     360                 :            : 
     361                 :            :         /* HW guarantees that the data does not exceed prod_index! */
     362         [ #  # ]:          0 :         while (remaining != 0) {
     363                 :          0 :                 data_len = RTE_MIN(remaining,
     364                 :            :                                    queue->dataroom);
     365                 :            : 
     366                 :          0 :                 remaining -= data_len;
     367                 :          0 :                 segments += 1;
     368                 :            : 
     369                 :          0 :                 mbuf = queue->reserve_q[cons_index & queue->queue_mask];
     370                 :          0 :                 mbuf_prev->next = mbuf;
     371                 :            :                 mbuf_prev = mbuf;
     372                 :          0 :                 mbuf->data_len = data_len;
     373                 :            : 
     374                 :          0 :                 cons_index += 1;
     375                 :            :         }
     376                 :            : 
     377                 :          0 :         mbuf0->nb_segs = segments;
     378                 :            :         return cons_index;
     379                 :            : }
     380                 :            : 
     381                 :            : /* Drain the internal queue allowing hw to clear out. */
     382                 :            : static void
     383                 :          0 : eth_ark_rx_queue_drain(struct ark_rx_queue *queue)
     384                 :            : {
     385                 :            :         register uint32_t cons_index;
     386                 :            :         struct rte_mbuf *mbuf;
     387                 :            : 
     388                 :          0 :         cons_index = queue->cons_index;
     389                 :            : 
     390                 :            :         /* NOT performance optimized, since this is a one-shot call */
     391         [ #  # ]:          0 :         while ((cons_index ^ queue->prod_index) & queue->queue_mask) {
     392                 :          0 :                 mbuf = queue->reserve_q[cons_index & queue->queue_mask];
     393                 :          0 :                 rte_pktmbuf_free(mbuf);
     394         [ #  # ]:          0 :                 cons_index++;
     395                 :            :                 eth_ark_rx_update_cons_index(queue, cons_index);
     396                 :            :         }
     397                 :          0 : }
     398                 :            : 
     399                 :            : uint32_t
     400                 :          0 : eth_ark_dev_rx_queue_count(void *rx_queue)
     401                 :            : {
     402                 :            :         struct ark_rx_queue *queue;
     403                 :            : 
     404                 :            :         queue = rx_queue;
     405                 :          0 :         return (queue->prod_index - queue->cons_index);   /* mod arith */
     406                 :            : }
     407                 :            : 
     408                 :            : /* ************************************************************************* */
     409                 :            : int
     410                 :          0 : eth_ark_rx_start_queue(struct rte_eth_dev *dev, uint16_t queue_id)
     411                 :            : {
     412                 :            :         struct ark_rx_queue *queue;
     413                 :            : 
     414                 :          0 :         queue = dev->data->rx_queues[queue_id];
     415         [ #  # ]:          0 :         if (queue == 0)
     416                 :            :                 return -1;
     417                 :            : 
     418                 :          0 :         dev->data->rx_queue_state[queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
     419                 :            : 
     420                 :          0 :         ark_mpu_set_producer(queue->mpu, queue->seed_index);
     421                 :          0 :         ark_mpu_start(queue->mpu);
     422                 :            : 
     423                 :          0 :         ark_udm_queue_enable(queue->udm, 1);
     424                 :            : 
     425                 :          0 :         return 0;
     426                 :            : }
     427                 :            : 
     428                 :            : /* ************************************************************************* */
     429                 :            : 
     430                 :            : /* Queue can be restarted.   data remains
     431                 :            :  */
     432                 :            : int
     433                 :          0 : eth_ark_rx_stop_queue(struct rte_eth_dev *dev, uint16_t queue_id)
     434                 :            : {
     435                 :            :         struct ark_rx_queue *queue;
     436                 :            : 
     437                 :          0 :         queue = dev->data->rx_queues[queue_id];
     438         [ #  # ]:          0 :         if (queue == 0)
     439                 :            :                 return -1;
     440                 :            : 
     441                 :          0 :         ark_udm_queue_enable(queue->udm, 0);
     442                 :            : 
     443                 :          0 :         dev->data->rx_queue_state[queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
     444                 :            : 
     445                 :          0 :         return 0;
     446                 :            : }
     447                 :            : 
     448                 :            : /* ************************************************************************* */
     449                 :            : static inline int
     450                 :          0 : eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
     451                 :            : {
     452                 :          0 :         uint32_t limit = (queue->cons_index & ~(ARK_RX_MPU_CHUNK - 1)) +
     453                 :          0 :                 queue->queue_size;
     454                 :          0 :         uint32_t seed_index = queue->seed_index;
     455                 :            : 
     456                 :            :         uint32_t count = 0;
     457                 :          0 :         uint32_t seed_m = queue->seed_index & queue->queue_mask;
     458                 :            : 
     459                 :          0 :         uint32_t nb = limit - seed_index;
     460                 :            : 
     461                 :            :         /* Handle wrap around -- remainder is filled on the next call */
     462         [ #  # ]:          0 :         if (unlikely(seed_m + nb > queue->queue_size))
     463                 :          0 :                 nb = queue->queue_size - seed_m;
     464                 :            : 
     465                 :          0 :         struct rte_mbuf **mbufs = &queue->reserve_q[seed_m];
     466                 :          0 :         int status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, nb);
     467                 :            : 
     468         [ #  # ]:          0 :         if (unlikely(status != 0)) {
     469                 :          0 :                 ARK_PMD_LOG(NOTICE,
     470                 :            :                             "Could not allocate %u mbufs from pool"
     471                 :            :                             " for RX queue %u;"
     472                 :            :                             " %u free buffers remaining in queue\n",
     473                 :            :                             nb, queue->queue_index,
     474                 :            :                             queue->seed_index - queue->cons_index);
     475                 :          0 :                 return -1;
     476                 :            :         }
     477                 :            : 
     478                 :            :         if (ARK_DEBUG_CORE) {           /* DEBUG */
     479                 :            :                 while (count != nb) {
     480                 :            :                         struct rte_mbuf *mbuf_init =
     481                 :            :                                 queue->reserve_q[seed_m + count];
     482                 :            : 
     483                 :            :                         memset(mbuf_init->buf_addr, -1, 512);
     484                 :            :                         *((uint32_t *)mbuf_init->buf_addr) =
     485                 :            :                                 seed_index + count;
     486                 :            :                         *(uint16_t *)RTE_PTR_ADD(mbuf_init->buf_addr, 4) =
     487                 :            :                                 queue->phys_qid;
     488                 :            :                         count++;
     489                 :            :                 }
     490                 :            :                 count = 0;
     491                 :            :         } /* DEBUG */
     492                 :          0 :         queue->seed_index += nb;
     493                 :            : 
     494                 :            :         /* Duff's device https://en.wikipedia.org/wiki/Duff's_device */
     495   [ #  #  #  # ]:          0 :         switch (nb % 4) {
     496                 :            :         case 0:
     497         [ #  # ]:          0 :                 while (count != nb) {
     498                 :          0 :                         queue->paddress_q[seed_m++] =
     499                 :          0 :                                 (*mbufs++)->buf_iova;
     500                 :          0 :                         count++;
     501                 :            :                 /* FALLTHROUGH */
     502                 :          0 :         case 3:
     503                 :          0 :                 queue->paddress_q[seed_m++] =
     504                 :          0 :                         (*mbufs++)->buf_iova;
     505                 :          0 :                 count++;
     506                 :            :                 /* FALLTHROUGH */
     507                 :          0 :         case 2:
     508                 :          0 :                 queue->paddress_q[seed_m++] =
     509                 :          0 :                         (*mbufs++)->buf_iova;
     510                 :          0 :                 count++;
     511                 :            :                 /* FALLTHROUGH */
     512                 :          0 :         case 1:
     513                 :          0 :                 queue->paddress_q[seed_m++] =
     514                 :          0 :                         (*mbufs++)->buf_iova;
     515                 :          0 :                 count++;
     516                 :            :                 /* FALLTHROUGH */
     517                 :            : 
     518                 :            :                 } /* while (count != nb) */
     519                 :            :         } /* switch */
     520                 :            : 
     521                 :            :         return 0;
     522                 :            : }
     523                 :            : 
     524                 :            : void
     525                 :          0 : eth_ark_rx_dump_queue(struct rte_eth_dev *dev, uint16_t queue_id,
     526                 :            :                       const char *msg)
     527                 :            : {
     528                 :            :         struct ark_rx_queue *queue;
     529                 :            : 
     530                 :          0 :         queue = dev->data->rx_queues[queue_id];
     531                 :            : 
     532                 :          0 :         ark_ethdev_rx_dump(msg, queue);
     533                 :          0 : }
     534                 :            : 
     535                 :            : /* ************************************************************************* */
     536                 :            : /* Call on device closed no user API, queue is stopped */
     537                 :            : void
     538                 :          0 : eth_ark_dev_rx_queue_release(void *vqueue)
     539                 :            : {
     540                 :            :         struct ark_rx_queue *queue;
     541                 :            :         uint32_t i;
     542                 :            : 
     543                 :            :         queue = (struct ark_rx_queue *)vqueue;
     544         [ #  # ]:          0 :         if (queue == 0)
     545                 :            :                 return;
     546                 :            : 
     547                 :          0 :         ark_udm_queue_enable(queue->udm, 0);
     548                 :            :         /* Stop the MPU since pointer are going away */
     549                 :          0 :         ark_mpu_stop(queue->mpu);
     550                 :            : 
     551                 :            :         /* Need to clear out mbufs here, dropping packets along the way */
     552                 :          0 :         eth_ark_rx_queue_drain(queue);
     553                 :            : 
     554         [ #  # ]:          0 :         for (i = 0; i < queue->queue_size; ++i)
     555                 :          0 :                 rte_pktmbuf_free(queue->reserve_q[i]);
     556                 :            : 
     557                 :          0 :         rte_free(queue->reserve_q);
     558                 :          0 :         rte_free(queue->paddress_q);
     559                 :          0 :         rte_free(queue);
     560                 :            : }
     561                 :            : 
     562                 :            : void
     563                 :          0 : eth_rx_queue_stats_get(void *vqueue, struct rte_eth_stats *stats)
     564                 :            : {
     565                 :            :         struct ark_rx_queue *queue;
     566                 :            :         struct ark_udm_t *udm;
     567                 :            : 
     568                 :            :         queue = vqueue;
     569         [ #  # ]:          0 :         if (queue == 0)
     570                 :            :                 return;
     571                 :          0 :         udm = queue->udm;
     572                 :            : 
     573                 :          0 :         uint64_t ibytes = ark_udm_bytes(udm);
     574                 :          0 :         uint64_t ipackets = ark_udm_packets(udm);
     575                 :          0 :         uint64_t idropped = ark_udm_dropped(queue->udm);
     576                 :            : 
     577                 :          0 :         stats->q_ipackets[queue->queue_index] = ipackets;
     578                 :          0 :         stats->q_ibytes[queue->queue_index] = ibytes;
     579                 :          0 :         stats->q_errors[queue->queue_index] = idropped;
     580                 :          0 :         stats->ipackets += ipackets;
     581                 :          0 :         stats->ibytes += ibytes;
     582                 :          0 :         stats->imissed += idropped;
     583                 :            : }
     584                 :            : 
     585                 :            : void
     586                 :          0 : eth_rx_queue_stats_reset(void *vqueue)
     587                 :            : {
     588                 :            :         struct ark_rx_queue *queue;
     589                 :            : 
     590                 :            :         queue = vqueue;
     591         [ #  # ]:          0 :         if (queue == 0)
     592                 :            :                 return;
     593                 :            : 
     594                 :          0 :         ark_udm_queue_stats_reset(queue->udm);
     595                 :            : }
     596                 :            : 
     597                 :            : static void
     598                 :          0 : ark_ethdev_rx_dump(const char *name, struct ark_rx_queue *queue)
     599                 :            : {
     600         [ #  # ]:          0 :         if (queue == NULL)
     601                 :            :                 return;
     602                 :          0 :         ARK_PMD_LOG(DEBUG, "RX QUEUE %d -- %s", queue->phys_qid, name);
     603                 :          0 :         ARK_PMD_LOG(DEBUG, ARK_SU32 ARK_SU32 ARK_SU32 ARK_SU32 "\n",
     604                 :            :                         "queue_size", queue->queue_size,
     605                 :            :                         "seed_index", queue->seed_index,
     606                 :            :                         "prod_index", queue->prod_index,
     607                 :            :                         "cons_index", queue->cons_index);
     608                 :            : 
     609                 :          0 :         ark_mpu_dump(queue->mpu, name, queue->phys_qid);
     610                 :          0 :         ark_mpu_dump_setup(queue->mpu, queue->phys_qid);
     611                 :          0 :         ark_udm_dump_setup(queue->udm, queue->phys_qid);
     612                 :            : }
     613                 :            : 
     614                 :            : /* Only used in debug.
     615                 :            :  * This function is a raw memory dump of a portion of an mbuf's memory
     616                 :            :  * region.  The usual function, rte_pktmbuf_dump() only shows data
     617                 :            :  * with respect to the data_off field.  This function show data
     618                 :            :  * anywhere in the mbuf's buffer.  This is useful for examining
     619                 :            :  * data in the headroom or tailroom portion of an mbuf.
     620                 :            :  */
     621                 :            : static void
     622                 :            : dump_mbuf_data(struct rte_mbuf *mbuf, uint16_t lo, uint16_t hi)
     623                 :            : {
     624                 :            :         uint16_t i, j;
     625                 :            : 
     626                 :            :         ARK_PMD_LOG(DEBUG, " MBUF: %p len %d, off: %d\n",
     627                 :            :                     mbuf, mbuf->pkt_len, mbuf->data_off);
     628                 :            :         for (i = lo; i < hi; i += 16) {
     629                 :            :                 uint8_t *dp = RTE_PTR_ADD(mbuf->buf_addr, i);
     630                 :            : 
     631                 :            :                 ARK_PMD_LOG(DEBUG, "  %6d:  ", i);
     632                 :            :                 for (j = 0; j < 16; j++)
     633                 :            :                         ARK_PMD_LOG(DEBUG, " %02x", dp[j]);
     634                 :            : 
     635                 :            :                 ARK_PMD_LOG(DEBUG, "\n");
     636                 :            :         }
     637                 :            : }

Generated by: LCOV version 1.14