LCOV - code coverage report
Current view: top level - drivers/net/octeon_ep - otx_ep_rxtx.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 387 0.0 %
Date: 2024-01-22 16:26:08 Functions: 0 20 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 140 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(C) 2021 Marvell.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <unistd.h>
       6                 :            : #include <assert.h>
       7                 :            : #include <rte_eal.h>
       8                 :            : #include <rte_mempool.h>
       9                 :            : #include <rte_mbuf.h>
      10                 :            : #include <rte_io.h>
      11                 :            : #include <rte_net.h>
      12                 :            : #include <ethdev_pci.h>
      13                 :            : 
      14                 :            : #include "otx_ep_common.h"
      15                 :            : #include "otx_ep_vf.h"
      16                 :            : #include "otx_ep_rxtx.h"
      17                 :            : 
      18                 :            : static void
      19                 :          0 : otx_ep_dmazone_free(const struct rte_memzone *mz)
      20                 :            : {
      21                 :            :         const struct rte_memzone *mz_tmp;
      22                 :            :         int ret = 0;
      23                 :            : 
      24         [ #  # ]:          0 :         if (mz == NULL) {
      25                 :          0 :                 otx_ep_err("Memzone: NULL\n");
      26                 :          0 :                 return;
      27                 :            :         }
      28                 :            : 
      29                 :          0 :         mz_tmp = rte_memzone_lookup(mz->name);
      30         [ #  # ]:          0 :         if (mz_tmp == NULL) {
      31                 :          0 :                 otx_ep_err("Memzone %s Not Found\n", mz->name);
      32                 :          0 :                 return;
      33                 :            :         }
      34                 :            : 
      35                 :          0 :         ret = rte_memzone_free(mz);
      36         [ #  # ]:          0 :         if (ret)
      37                 :          0 :                 otx_ep_err("Memzone free failed : ret = %d\n", ret);
      38                 :            : }
      39                 :            : 
      40                 :            : /* Free IQ resources */
      41                 :            : int
      42                 :          0 : otx_ep_delete_iqs(struct otx_ep_device *otx_ep, uint32_t iq_no)
      43                 :            : {
      44                 :            :         struct otx_ep_instr_queue *iq;
      45                 :            :         uint32_t i;
      46                 :            : 
      47                 :          0 :         iq = otx_ep->instr_queue[iq_no];
      48         [ #  # ]:          0 :         if (iq == NULL) {
      49                 :          0 :                 otx_ep_err("Invalid IQ[%d]\n", iq_no);
      50                 :          0 :                 return -EINVAL;
      51                 :            :         }
      52                 :            : 
      53         [ #  # ]:          0 :         if (iq->req_list) {
      54         [ #  # ]:          0 :                 for (i = 0; i < iq->nb_desc; i++)
      55                 :          0 :                         rte_free(iq->req_list[i].finfo.g.sg);
      56                 :          0 :                 rte_free(iq->req_list);
      57                 :            :         }
      58                 :            : 
      59                 :          0 :         iq->req_list = NULL;
      60                 :            : 
      61         [ #  # ]:          0 :         if (iq->iq_mz) {
      62                 :          0 :                 otx_ep_dmazone_free(iq->iq_mz);
      63                 :          0 :                 iq->iq_mz = NULL;
      64                 :            :         }
      65                 :            : 
      66                 :          0 :         rte_free(otx_ep->instr_queue[iq_no]);
      67                 :          0 :         otx_ep->instr_queue[iq_no] = NULL;
      68                 :            : 
      69                 :          0 :         otx_ep->nb_tx_queues--;
      70                 :            : 
      71                 :          0 :         otx_ep_info("IQ[%d] is deleted\n", iq_no);
      72                 :            : 
      73                 :          0 :         return 0;
      74                 :            : }
      75                 :            : 
      76                 :            : /* IQ initialization */
      77                 :            : static int
      78                 :          0 : otx_ep_init_instr_queue(struct otx_ep_device *otx_ep, int iq_no, int num_descs,
      79                 :            :                      unsigned int socket_id)
      80                 :            : {
      81                 :            :         const struct otx_ep_config *conf;
      82                 :            :         struct otx_ep_instr_queue *iq;
      83                 :            :         struct otx_ep_sg_entry *sg;
      84                 :            :         uint32_t i, q_size;
      85                 :            :         int ret;
      86                 :            : 
      87                 :          0 :         conf = otx_ep->conf;
      88                 :          0 :         iq = otx_ep->instr_queue[iq_no];
      89                 :          0 :         q_size = conf->iq.instr_type * num_descs;
      90                 :            : 
      91                 :            :         /* IQ memory creation for Instruction submission to OCTEON 9 */
      92                 :          0 :         iq->iq_mz = rte_eth_dma_zone_reserve(otx_ep->eth_dev,
      93                 :            :                                              "instr_queue", iq_no, q_size,
      94                 :            :                                              OTX_EP_PCI_RING_ALIGN,
      95                 :            :                                              socket_id);
      96         [ #  # ]:          0 :         if (iq->iq_mz == NULL) {
      97                 :          0 :                 otx_ep_err("IQ[%d] memzone alloc failed\n", iq_no);
      98                 :          0 :                 goto iq_init_fail;
      99                 :            :         }
     100                 :            : 
     101                 :          0 :         iq->base_addr_dma = iq->iq_mz->iova;
     102                 :          0 :         iq->base_addr = (uint8_t *)iq->iq_mz->addr;
     103                 :            : 
     104         [ #  # ]:          0 :         if (num_descs & (num_descs - 1)) {
     105                 :          0 :                 otx_ep_err("IQ[%d] descs not in power of 2\n", iq_no);
     106                 :          0 :                 goto iq_init_fail;
     107                 :            :         }
     108                 :            : 
     109                 :          0 :         iq->nb_desc = num_descs;
     110                 :            : 
     111                 :            :         /* Create a IQ request list to hold requests that have been
     112                 :            :          * posted to OCTEON 9. This list will be used for freeing the IQ
     113                 :            :          * data buffer(s) later once the OCTEON 9 fetched the requests.
     114                 :            :          */
     115                 :          0 :         iq->req_list = rte_zmalloc_socket("request_list",
     116                 :          0 :                         (iq->nb_desc * OTX_EP_IQREQ_LIST_SIZE),
     117                 :            :                         RTE_CACHE_LINE_SIZE,
     118                 :          0 :                         rte_socket_id());
     119         [ #  # ]:          0 :         if (iq->req_list == NULL) {
     120                 :          0 :                 otx_ep_err("IQ[%d] req_list alloc failed\n", iq_no);
     121                 :          0 :                 goto iq_init_fail;
     122                 :            :         }
     123                 :            : 
     124         [ #  # ]:          0 :         for (i = 0; i < iq->nb_desc; i++) {
     125                 :          0 :                 sg = rte_zmalloc_socket("sg_entry", (OTX_EP_MAX_SG_LISTS * OTX_EP_SG_ENTRY_SIZE),
     126                 :          0 :                         OTX_EP_SG_ALIGN, rte_socket_id());
     127         [ #  # ]:          0 :                 if (sg == NULL) {
     128                 :          0 :                         otx_ep_err("IQ[%d] sg_entries alloc failed\n", iq_no);
     129                 :          0 :                         goto iq_init_fail;
     130                 :            :                 }
     131                 :            : 
     132                 :          0 :                 iq->req_list[i].finfo.g.num_sg = OTX_EP_MAX_SG_LISTS;
     133                 :          0 :                 iq->req_list[i].finfo.g.sg = sg;
     134                 :            :         }
     135                 :            : 
     136                 :          0 :         otx_ep_info("IQ[%d]: base: %p basedma: %lx count: %d\n",
     137                 :            :                      iq_no, iq->base_addr, (unsigned long)iq->base_addr_dma,
     138                 :            :                      iq->nb_desc);
     139                 :            : 
     140                 :          0 :         iq->mbuf_list = rte_zmalloc_socket("mbuf_list",    (iq->nb_desc * sizeof(struct rte_mbuf *)),
     141                 :          0 :                                            RTE_CACHE_LINE_SIZE, rte_socket_id());
     142         [ #  # ]:          0 :         if (!iq->mbuf_list) {
     143                 :          0 :                 otx_ep_err("IQ[%d] mbuf_list alloc failed\n", iq_no);
     144                 :          0 :                 goto iq_init_fail;
     145                 :            :         }
     146                 :            : 
     147                 :          0 :         iq->otx_ep_dev = otx_ep;
     148                 :          0 :         iq->q_no = iq_no;
     149                 :          0 :         iq->fill_cnt = 0;
     150                 :          0 :         iq->host_write_index = 0;
     151                 :          0 :         iq->otx_read_index = 0;
     152                 :          0 :         iq->flush_index = 0;
     153                 :          0 :         iq->instr_pending = 0;
     154                 :            : 
     155                 :          0 :         otx_ep->io_qmask.iq |= (1ull << iq_no);
     156                 :            : 
     157                 :            :         /* Set 32B/64B mode for each input queue */
     158         [ #  # ]:          0 :         if (conf->iq.instr_type == 64)
     159                 :          0 :                 otx_ep->io_qmask.iq64B |= (1ull << iq_no);
     160                 :            : 
     161                 :          0 :         iq->iqcmd_64B = (conf->iq.instr_type == 64);
     162                 :            : 
     163                 :            :         /* Set up IQ registers */
     164                 :          0 :         ret = otx_ep->fn_list.setup_iq_regs(otx_ep, iq_no);
     165         [ #  # ]:          0 :         if (ret)
     166                 :          0 :                 return ret;
     167                 :            : 
     168                 :            :         return 0;
     169                 :            : 
     170                 :            : iq_init_fail:
     171                 :            :         return -ENOMEM;
     172                 :            : }
     173                 :            : 
     174                 :            : int
     175                 :          0 : otx_ep_setup_iqs(struct otx_ep_device *otx_ep, uint32_t iq_no, int num_descs,
     176                 :            :                  unsigned int socket_id)
     177                 :            : {
     178                 :            :         struct otx_ep_instr_queue *iq;
     179                 :            : 
     180                 :          0 :         iq = (struct otx_ep_instr_queue *)rte_zmalloc("otx_ep_IQ", sizeof(*iq),
     181                 :            :                                                 RTE_CACHE_LINE_SIZE);
     182         [ #  # ]:          0 :         if (iq == NULL)
     183                 :            :                 return -ENOMEM;
     184                 :            : 
     185                 :          0 :         otx_ep->instr_queue[iq_no] = iq;
     186                 :            : 
     187         [ #  # ]:          0 :         if (otx_ep_init_instr_queue(otx_ep, iq_no, num_descs, socket_id)) {
     188                 :          0 :                 otx_ep_err("IQ init is failed\n");
     189                 :          0 :                 goto delete_IQ;
     190                 :            :         }
     191                 :          0 :         otx_ep->nb_tx_queues++;
     192                 :            : 
     193                 :          0 :         otx_ep_info("IQ[%d] is created.\n", iq_no);
     194                 :            : 
     195                 :          0 :         return 0;
     196                 :            : 
     197                 :            : delete_IQ:
     198                 :          0 :         otx_ep_delete_iqs(otx_ep, iq_no);
     199                 :          0 :         return -ENOMEM;
     200                 :            : }
     201                 :            : 
     202                 :            : static void
     203                 :            : otx_ep_droq_reset_indices(struct otx_ep_droq *droq)
     204                 :            : {
     205                 :          0 :         droq->read_idx  = 0;
     206                 :          0 :         droq->write_idx = 0;
     207                 :          0 :         droq->refill_idx = 0;
     208                 :          0 :         droq->refill_count = 0;
     209                 :          0 :         droq->last_pkt_count = 0;
     210                 :          0 :         droq->pkts_pending = 0;
     211                 :            : }
     212                 :            : 
     213                 :            : static void
     214                 :          0 : otx_ep_droq_destroy_ring_buffers(struct otx_ep_droq *droq)
     215                 :            : {
     216                 :            :         uint32_t idx;
     217                 :            : 
     218         [ #  # ]:          0 :         for (idx = 0; idx < droq->nb_desc; idx++) {
     219         [ #  # ]:          0 :                 if (droq->recv_buf_list[idx]) {
     220                 :          0 :                         rte_pktmbuf_free(droq->recv_buf_list[idx]);
     221                 :          0 :                         droq->recv_buf_list[idx] = NULL;
     222                 :            :                 }
     223                 :            :         }
     224                 :            : 
     225                 :            :         otx_ep_droq_reset_indices(droq);
     226                 :          0 : }
     227                 :            : 
     228                 :            : /* Free OQs resources */
     229                 :            : int
     230                 :          0 : otx_ep_delete_oqs(struct otx_ep_device *otx_ep, uint32_t oq_no)
     231                 :            : {
     232                 :            :         struct otx_ep_droq *droq;
     233                 :            : 
     234                 :          0 :         droq = otx_ep->droq[oq_no];
     235         [ #  # ]:          0 :         if (droq == NULL) {
     236                 :          0 :                 otx_ep_err("Invalid droq[%d]\n", oq_no);
     237                 :          0 :                 return -EINVAL;
     238                 :            :         }
     239                 :            : 
     240                 :          0 :         otx_ep_droq_destroy_ring_buffers(droq);
     241                 :          0 :         rte_free(droq->recv_buf_list);
     242                 :          0 :         droq->recv_buf_list = NULL;
     243                 :            : 
     244         [ #  # ]:          0 :         if (droq->desc_ring_mz) {
     245                 :          0 :                 otx_ep_dmazone_free(droq->desc_ring_mz);
     246                 :            :                 droq->desc_ring_mz = NULL;
     247                 :            :         }
     248                 :            : 
     249                 :            :         memset(droq, 0, OTX_EP_DROQ_SIZE);
     250                 :            : 
     251                 :          0 :         rte_free(otx_ep->droq[oq_no]);
     252                 :          0 :         otx_ep->droq[oq_no] = NULL;
     253                 :            : 
     254                 :          0 :         otx_ep->nb_rx_queues--;
     255                 :            : 
     256                 :          0 :         otx_ep_info("OQ[%d] is deleted\n", oq_no);
     257                 :          0 :         return 0;
     258                 :            : }
     259                 :            : 
     260                 :            : static int
     261                 :          0 : otx_ep_droq_setup_ring_buffers(struct otx_ep_droq *droq)
     262                 :            : {
     263                 :          0 :         struct otx_ep_droq_desc *desc_ring = droq->desc_ring;
     264                 :            :         struct otx_ep_droq_info *info;
     265                 :            :         struct rte_mbuf *buf;
     266                 :            :         uint32_t idx;
     267                 :            : 
     268         [ #  # ]:          0 :         for (idx = 0; idx < droq->nb_desc; idx++) {
     269                 :          0 :                 buf = rte_pktmbuf_alloc(droq->mpool);
     270         [ #  # ]:          0 :                 if (buf == NULL) {
     271                 :          0 :                         otx_ep_err("OQ buffer alloc failed\n");
     272                 :          0 :                         droq->stats.rx_alloc_failure++;
     273                 :          0 :                         return -ENOMEM;
     274                 :            :                 }
     275                 :            : 
     276                 :          0 :                 droq->recv_buf_list[idx] = buf;
     277                 :          0 :                 info = rte_pktmbuf_mtod(buf, struct otx_ep_droq_info *);
     278                 :            :                 memset(info, 0, sizeof(*info));
     279                 :          0 :                 desc_ring[idx].buffer_ptr = rte_mbuf_data_iova_default(buf);
     280                 :            :         }
     281                 :            : 
     282                 :            :         otx_ep_droq_reset_indices(droq);
     283                 :            : 
     284                 :          0 :         return 0;
     285                 :            : }
     286                 :            : 
     287                 :            : /* OQ initialization */
     288                 :            : static int
     289                 :          0 : otx_ep_init_droq(struct otx_ep_device *otx_ep, uint32_t q_no,
     290                 :            :               uint32_t num_descs, uint32_t desc_size,
     291                 :            :               struct rte_mempool *mpool, unsigned int socket_id)
     292                 :            : {
     293                 :          0 :         const struct otx_ep_config *conf = otx_ep->conf;
     294                 :            :         uint32_t c_refill_threshold;
     295                 :            :         struct otx_ep_droq *droq;
     296                 :            :         uint32_t desc_ring_size;
     297                 :            :         int ret;
     298                 :            : 
     299                 :          0 :         otx_ep_info("OQ[%d] Init start\n", q_no);
     300                 :            : 
     301                 :          0 :         droq = otx_ep->droq[q_no];
     302                 :          0 :         droq->otx_ep_dev = otx_ep;
     303                 :          0 :         droq->q_no = q_no;
     304                 :          0 :         droq->mpool = mpool;
     305                 :            : 
     306                 :          0 :         droq->nb_desc      = num_descs;
     307                 :          0 :         droq->buffer_size  = desc_size;
     308                 :          0 :         c_refill_threshold = RTE_MAX(conf->oq.refill_threshold,
     309                 :            :                                      droq->nb_desc / 2);
     310                 :            : 
     311                 :            :         /* OQ desc_ring set up */
     312                 :          0 :         desc_ring_size = droq->nb_desc * OTX_EP_DROQ_DESC_SIZE;
     313                 :          0 :         droq->desc_ring_mz = rte_eth_dma_zone_reserve(otx_ep->eth_dev, "droq",
     314                 :            :                                                       q_no, desc_ring_size,
     315                 :            :                                                       OTX_EP_PCI_RING_ALIGN,
     316                 :            :                                                       socket_id);
     317                 :            : 
     318         [ #  # ]:          0 :         if (droq->desc_ring_mz == NULL) {
     319                 :          0 :                 otx_ep_err("OQ:%d desc_ring allocation failed\n", q_no);
     320                 :          0 :                 goto init_droq_fail;
     321                 :            :         }
     322                 :            : 
     323                 :          0 :         droq->desc_ring_dma = droq->desc_ring_mz->iova;
     324                 :          0 :         droq->desc_ring = (struct otx_ep_droq_desc *)droq->desc_ring_mz->addr;
     325                 :            : 
     326                 :          0 :         otx_ep_dbg("OQ[%d]: desc_ring: virt: 0x%p, dma: %lx\n",
     327                 :            :                     q_no, droq->desc_ring, (unsigned long)droq->desc_ring_dma);
     328                 :          0 :         otx_ep_dbg("OQ[%d]: num_desc: %d\n", q_no, droq->nb_desc);
     329                 :            : 
     330                 :            :         /* OQ buf_list set up */
     331                 :          0 :         droq->recv_buf_list = rte_zmalloc_socket("recv_buf_list",
     332                 :          0 :                                 (droq->nb_desc * sizeof(struct rte_mbuf *)),
     333                 :            :                                  RTE_CACHE_LINE_SIZE, socket_id);
     334         [ #  # ]:          0 :         if (droq->recv_buf_list == NULL) {
     335                 :          0 :                 otx_ep_err("OQ recv_buf_list alloc failed\n");
     336                 :          0 :                 goto init_droq_fail;
     337                 :            :         }
     338                 :            : 
     339         [ #  # ]:          0 :         if (otx_ep_droq_setup_ring_buffers(droq))
     340                 :          0 :                 goto init_droq_fail;
     341                 :            : 
     342                 :          0 :         droq->refill_threshold = c_refill_threshold;
     343                 :            : 
     344                 :            :         /* Set up OQ registers */
     345                 :          0 :         ret = otx_ep->fn_list.setup_oq_regs(otx_ep, q_no);
     346         [ #  # ]:          0 :         if (ret)
     347                 :            :                 return ret;
     348                 :            : 
     349                 :          0 :         otx_ep->io_qmask.oq |= (1ull << q_no);
     350                 :            : 
     351                 :          0 :         return 0;
     352                 :            : 
     353                 :            : init_droq_fail:
     354                 :            :         return -ENOMEM;
     355                 :            : }
     356                 :            : 
     357                 :            : /* OQ configuration and setup */
     358                 :            : int
     359                 :          0 : otx_ep_setup_oqs(struct otx_ep_device *otx_ep, int oq_no, int num_descs,
     360                 :            :                  int desc_size, struct rte_mempool *mpool,
     361                 :            :                  unsigned int socket_id)
     362                 :            : {
     363                 :            :         struct otx_ep_droq *droq;
     364                 :            : 
     365                 :            :         /* Allocate new droq. */
     366                 :          0 :         droq = (struct otx_ep_droq *)rte_zmalloc("otx_ep_OQ",
     367                 :            :                                 sizeof(*droq), RTE_CACHE_LINE_SIZE);
     368         [ #  # ]:          0 :         if (droq == NULL) {
     369                 :          0 :                 otx_ep_err("Droq[%d] Creation Failed\n", oq_no);
     370                 :          0 :                 return -ENOMEM;
     371                 :            :         }
     372                 :          0 :         otx_ep->droq[oq_no] = droq;
     373                 :            : 
     374         [ #  # ]:          0 :         if (otx_ep_init_droq(otx_ep, oq_no, num_descs, desc_size, mpool,
     375                 :            :                              socket_id)) {
     376                 :          0 :                 otx_ep_err("Droq[%d] Initialization failed\n", oq_no);
     377                 :          0 :                 goto delete_OQ;
     378                 :            :         }
     379                 :          0 :         otx_ep_info("OQ[%d] is created.\n", oq_no);
     380                 :            : 
     381                 :          0 :         otx_ep->nb_rx_queues++;
     382                 :            : 
     383                 :          0 :         return 0;
     384                 :            : 
     385                 :            : delete_OQ:
     386                 :          0 :         otx_ep_delete_oqs(otx_ep, oq_no);
     387                 :          0 :         return -ENOMEM;
     388                 :            : }
     389                 :            : 
     390                 :            : static inline void
     391                 :          0 : otx_ep_iqreq_delete(struct otx_ep_instr_queue *iq, uint32_t idx)
     392                 :            : {
     393                 :            :         struct rte_mbuf *mbuf;
     394                 :            :         uint32_t reqtype;
     395                 :            : 
     396                 :          0 :         mbuf    = iq->req_list[idx].finfo.mbuf;
     397                 :          0 :         reqtype = iq->req_list[idx].reqtype;
     398                 :            : 
     399         [ #  # ]:          0 :         switch (reqtype) {
     400                 :          0 :         case OTX_EP_REQTYPE_NORESP_NET:
     401                 :            :         case OTX_EP_REQTYPE_NORESP_GATHER:
     402                 :            :                 /* This will take care of multiple segments also */
     403                 :          0 :                 rte_pktmbuf_free(mbuf);
     404                 :          0 :                 otx_ep_dbg("IQ buffer freed at idx[%d]\n", idx);
     405                 :          0 :                 break;
     406                 :            : 
     407                 :          0 :         case OTX_EP_REQTYPE_NONE:
     408                 :            :         default:
     409                 :          0 :                 otx_ep_info("This iqreq mode is not supported:%d\n", reqtype);
     410                 :            :         }
     411                 :            : 
     412                 :            :         /* Reset the request list at this index */
     413                 :          0 :         iq->req_list[idx].finfo.mbuf = NULL;
     414                 :          0 :         iq->req_list[idx].reqtype = 0;
     415                 :          0 : }
     416                 :            : 
     417                 :            : static inline void
     418                 :            : otx_ep_iqreq_add(struct otx_ep_instr_queue *iq, struct rte_mbuf *mbuf,
     419                 :            :                 uint32_t reqtype, int index)
     420                 :            : {
     421                 :          0 :         iq->req_list[index].finfo.mbuf = mbuf;
     422                 :          0 :         iq->req_list[index].reqtype = reqtype;
     423                 :            : }
     424                 :            : 
     425                 :            : static uint32_t
     426                 :          0 : otx_vf_update_read_index(struct otx_ep_instr_queue *iq)
     427                 :            : {
     428                 :            :         uint32_t val;
     429                 :            : 
     430                 :            :         /*
     431                 :            :          * Batch subtractions from the HW counter to reduce PCIe traffic
     432                 :            :          * This adds an extra local variable, but almost halves the
     433                 :            :          * number of PCIe writes.
     434                 :            :          */
     435                 :          0 :         val = *iq->inst_cnt_ism;
     436                 :          0 :         iq->inst_cnt += val - iq->inst_cnt_ism_prev;
     437                 :          0 :         iq->inst_cnt_ism_prev = val;
     438                 :            : 
     439         [ #  # ]:          0 :         if (val > (uint32_t)(1 << 31)) {
     440                 :            :                 /*
     441                 :            :                  * Only subtract the packet count in the HW counter
     442                 :            :                  * when count above halfway to saturation.
     443                 :            :                  */
     444                 :          0 :                 rte_write32(val, iq->inst_cnt_reg);
     445                 :            :                 rte_mb();
     446                 :            : 
     447                 :          0 :                 rte_write64(OTX2_SDP_REQUEST_ISM, iq->inst_cnt_reg);
     448         [ #  # ]:          0 :                 while (__atomic_load_n(iq->inst_cnt_ism, __ATOMIC_RELAXED) >= val) {
     449                 :          0 :                         rte_write64(OTX2_SDP_REQUEST_ISM, iq->inst_cnt_reg);
     450                 :            :                         rte_mb();
     451                 :            :                 }
     452                 :            : 
     453                 :          0 :                 iq->inst_cnt_ism_prev = 0;
     454                 :            :         }
     455                 :          0 :         rte_write64(OTX2_SDP_REQUEST_ISM, iq->inst_cnt_reg);
     456                 :            : 
     457                 :            :         /* Modulo of the new index with the IQ size will give us
     458                 :            :          * the new index.
     459                 :            :          */
     460                 :          0 :         return iq->inst_cnt & (iq->nb_desc - 1);
     461                 :            : }
     462                 :            : 
     463                 :            : static void
     464                 :          0 : otx_ep_flush_iq(struct otx_ep_instr_queue *iq)
     465                 :            : {
     466                 :            :         uint32_t instr_processed = 0;
     467                 :            : 
     468                 :          0 :         iq->otx_read_index = otx_vf_update_read_index(iq);
     469         [ #  # ]:          0 :         while (iq->flush_index != iq->otx_read_index) {
     470                 :            :                 /* Free the IQ data buffer to the pool */
     471                 :          0 :                 otx_ep_iqreq_delete(iq, iq->flush_index);
     472                 :          0 :                 iq->flush_index =
     473                 :          0 :                         otx_ep_incr_index(iq->flush_index, 1, iq->nb_desc);
     474                 :            : 
     475                 :          0 :                 instr_processed++;
     476                 :            :         }
     477                 :            : 
     478                 :          0 :         iq->stats.instr_processed = instr_processed;
     479                 :          0 :         iq->instr_pending -= instr_processed;
     480                 :          0 : }
     481                 :            : 
     482                 :            : static inline void
     483                 :            : otx_ep_ring_doorbell(struct otx_ep_device *otx_ep __rte_unused,
     484                 :            :                 struct otx_ep_instr_queue *iq)
     485                 :            : {
     486                 :            :         rte_wmb();
     487                 :          0 :         rte_write64(iq->fill_cnt, iq->doorbell_reg);
     488                 :          0 :         iq->fill_cnt = 0;
     489                 :          0 : }
     490                 :            : 
     491                 :            : static inline int
     492                 :          0 : post_iqcmd(struct otx_ep_instr_queue *iq, uint8_t *iqcmd)
     493                 :            : {
     494                 :            :         uint8_t *iqptr, cmdsize;
     495                 :            : 
     496                 :            :         /* This ensures that the read index does not wrap around to
     497                 :            :          * the same position if queue gets full before OCTEON 9 could
     498                 :            :          * fetch any instr.
     499                 :            :          */
     500         [ #  # ]:          0 :         if (iq->instr_pending > (iq->nb_desc - 1))
     501                 :            :                 return OTX_EP_IQ_SEND_FAILED;
     502                 :            : 
     503                 :            :         /* Copy cmd into iq */
     504                 :            :         cmdsize = 64;
     505         [ #  # ]:          0 :         iqptr   = iq->base_addr + (iq->host_write_index << 6);
     506                 :            : 
     507                 :            :         rte_memcpy(iqptr, iqcmd, cmdsize);
     508                 :            : 
     509                 :            :         /* Increment the host write index */
     510                 :          0 :         iq->host_write_index =
     511                 :          0 :                 otx_ep_incr_index(iq->host_write_index, 1, iq->nb_desc);
     512                 :            : 
     513                 :          0 :         iq->fill_cnt++;
     514                 :            : 
     515                 :            :         /* Flush the command into memory. We need to be sure the data
     516                 :            :          * is in memory before indicating that the instruction is
     517                 :            :          * pending.
     518                 :            :          */
     519                 :          0 :         iq->instr_pending++;
     520                 :            :         /* OTX_EP_IQ_SEND_SUCCESS */
     521                 :          0 :         return 0;
     522                 :            : }
     523                 :            : 
     524                 :            : 
     525                 :            : static int
     526                 :          0 : otx_ep_send_data(struct otx_ep_device *otx_ep, struct otx_ep_instr_queue *iq,
     527                 :            :                  void *cmd, int dbell)
     528                 :            : {
     529                 :            :         uint32_t ret;
     530                 :            : 
     531                 :            :         /* Submit IQ command */
     532                 :          0 :         ret = post_iqcmd(iq, cmd);
     533                 :            : 
     534         [ #  # ]:          0 :         if (ret == OTX_EP_IQ_SEND_SUCCESS) {
     535         [ #  # ]:          0 :                 if (dbell)
     536                 :            :                         otx_ep_ring_doorbell(otx_ep, iq);
     537                 :          0 :                 iq->stats.instr_posted++;
     538                 :            : 
     539                 :            :         } else {
     540                 :          0 :                 iq->stats.instr_dropped++;
     541         [ #  # ]:          0 :                 if (iq->fill_cnt)
     542                 :            :                         otx_ep_ring_doorbell(otx_ep, iq);
     543                 :            :         }
     544                 :          0 :         return ret;
     545                 :            : }
     546                 :            : 
     547                 :            : static inline void
     548                 :            : set_sg_size(struct otx_ep_sg_entry *sg_entry, uint16_t size, uint32_t pos)
     549                 :            : {
     550                 :            : #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
     551                 :            :         sg_entry->u.size[pos] = size;
     552                 :            : #elif RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
     553                 :          0 :         sg_entry->u.size[(OTX_EP_NUM_SG_PTRS - 1) - pos] = size;
     554                 :            : #endif
     555                 :            : }
     556                 :            : 
     557                 :            : static inline int
     558                 :          0 : prepare_xmit_gather_list(struct otx_ep_instr_queue *iq, struct rte_mbuf *m, uint64_t *dptr,
     559                 :            :                          union otx_ep_instr_ih *ih)
     560                 :            : {
     561                 :            :         uint16_t j = 0, frags, num_sg, mask = OTX_EP_NUM_SG_PTRS - 1;
     562                 :            :         struct otx_ep_buf_free_info *finfo;
     563                 :            :         uint32_t pkt_len;
     564                 :            :         int rc = -1;
     565                 :            : 
     566                 :          0 :         pkt_len = rte_pktmbuf_pkt_len(m);
     567                 :          0 :         frags = m->nb_segs;
     568                 :          0 :         num_sg = (frags + mask) / OTX_EP_NUM_SG_PTRS;
     569                 :            : 
     570         [ #  # ]:          0 :         if (unlikely(pkt_len > OTX_EP_MAX_PKT_SZ && num_sg > OTX_EP_MAX_SG_LISTS)) {
     571                 :          0 :                 otx_ep_err("Failed to xmit the pkt, pkt_len is higher or pkt has more segments\n");
     572                 :          0 :                 goto exit;
     573                 :            :         }
     574                 :            : 
     575                 :          0 :         finfo = &iq->req_list[iq->host_write_index].finfo;
     576                 :          0 :         *dptr = rte_mem_virt2iova(finfo->g.sg);
     577                 :          0 :         ih->u64 |= ((1ULL << 62) | ((uint64_t)frags << 48) | (pkt_len + ih->s.fsz));
     578                 :            : 
     579         [ #  # ]:          0 :         while (frags--) {
     580                 :          0 :                 finfo->g.sg[(j >> 2)].ptr[(j & mask)] = rte_mbuf_data_iova(m);
     581                 :          0 :                 set_sg_size(&finfo->g.sg[(j >> 2)], m->data_len, (j & mask));
     582                 :          0 :                 j++;
     583                 :          0 :                 m = m->next;
     584                 :            :         }
     585                 :            : 
     586                 :            :         return 0;
     587                 :            : 
     588                 :            : exit:
     589                 :          0 :         return rc;
     590                 :            : }
     591                 :            : 
     592                 :            : /* Enqueue requests/packets to OTX_EP IQ queue.
     593                 :            :  * returns number of requests enqueued successfully
     594                 :            :  */
     595                 :            : uint16_t
     596                 :          0 : otx_ep_xmit_pkts(void *tx_queue, struct rte_mbuf **pkts, uint16_t nb_pkts)
     597                 :            : {
     598                 :            :         struct otx_ep_instr_queue *iq = (struct otx_ep_instr_queue *)tx_queue;
     599                 :          0 :         struct otx_ep_device *otx_ep = iq->otx_ep_dev;
     600                 :            :         struct otx_ep_instr_64B iqcmd;
     601                 :            :         int dbell, index, count = 0;
     602                 :            :         uint32_t iqreq_type;
     603                 :            :         uint32_t pkt_len, i;
     604                 :            :         struct rte_mbuf *m;
     605                 :            : 
     606                 :          0 :         iqcmd.ih.u64 = 0;
     607                 :          0 :         iqcmd.pki_ih3.u64 = 0;
     608                 :          0 :         iqcmd.irh.u64 = 0;
     609                 :            : 
     610                 :            :         /* ih invars */
     611                 :          0 :         iqcmd.ih.s.fsz = OTX_EP_FSZ;
     612                 :          0 :         iqcmd.ih.s.pkind = otx_ep->pkind; /* The SDK decided PKIND value */
     613                 :            : 
     614                 :            :         /* pki ih3 invars */
     615                 :          0 :         iqcmd.pki_ih3.s.w = 1;
     616                 :          0 :         iqcmd.pki_ih3.s.utt = 1;
     617                 :            :         iqcmd.pki_ih3.s.tagtype = ORDERED_TAG;
     618                 :            :         /* sl will be sizeof(pki_ih3) */
     619                 :          0 :         iqcmd.pki_ih3.s.sl = OTX_EP_FSZ + OTX_CUST_DATA_LEN;
     620                 :            : 
     621                 :            :         /* irh invars */
     622                 :          0 :         iqcmd.irh.s.opcode = OTX_EP_NW_PKT_OP;
     623                 :            : 
     624         [ #  # ]:          0 :         for (i = 0; i < nb_pkts; i++) {
     625                 :          0 :                 m = pkts[i];
     626         [ #  # ]:          0 :                 if (m->nb_segs == 1) {
     627                 :          0 :                         pkt_len = rte_pktmbuf_data_len(m);
     628                 :          0 :                         iqcmd.ih.s.tlen = pkt_len + iqcmd.ih.s.fsz;
     629                 :          0 :                         iqcmd.dptr = rte_mbuf_data_iova(m); /*dptr*/
     630                 :          0 :                         iqcmd.ih.s.gather = 0;
     631                 :          0 :                         iqcmd.ih.s.gsz = 0;
     632                 :            :                         iqreq_type = OTX_EP_REQTYPE_NORESP_NET;
     633                 :            :                 } else {
     634         [ #  # ]:          0 :                         if (!(otx_ep->tx_offloads & RTE_ETH_TX_OFFLOAD_MULTI_SEGS))
     635                 :          0 :                                 goto xmit_fail;
     636                 :            : 
     637         [ #  # ]:          0 :                         if (unlikely(prepare_xmit_gather_list(iq, m, &iqcmd.dptr, &iqcmd.ih) < 0))
     638                 :          0 :                                 goto xmit_fail;
     639                 :            : 
     640                 :          0 :                         pkt_len = rte_pktmbuf_pkt_len(m);
     641                 :            :                         iqreq_type = OTX_EP_REQTYPE_NORESP_GATHER;
     642                 :            :                 }
     643                 :            : 
     644         [ #  # ]:          0 :                 iqcmd.irh.u64 = rte_bswap64(iqcmd.irh.u64);
     645                 :            : 
     646                 :            : #ifdef OTX_EP_IO_DEBUG
     647                 :            :                 otx_ep_dbg("After swapping\n");
     648                 :            :                 otx_ep_dbg("Word0 [dptr]: 0x%016lx\n",
     649                 :            :                            (unsigned long)iqcmd.dptr);
     650                 :            :                 otx_ep_dbg("Word1 [ihtx]: 0x%016lx\n", (unsigned long)iqcmd.ih);
     651                 :            :                 otx_ep_dbg("Word2 [pki_ih3]: 0x%016lx\n",
     652                 :            :                            (unsigned long)iqcmd.pki_ih3);
     653                 :            :                 otx_ep_dbg("Word3 [rptr]: 0x%016lx\n",
     654                 :            :                            (unsigned long)iqcmd.rptr);
     655                 :            :                 otx_ep_dbg("Word4 [irh]: 0x%016lx\n", (unsigned long)iqcmd.irh);
     656                 :            :                 otx_ep_dbg("Word5 [exhdr[0]]: 0x%016lx\n",
     657                 :            :                                 (unsigned long)iqcmd.exhdr[0]);
     658                 :            :                 rte_pktmbuf_dump(stdout, m, rte_pktmbuf_pkt_len(m));
     659                 :            : #endif
     660                 :          0 :                 dbell = (i == (unsigned int)(nb_pkts - 1)) ? 1 : 0;
     661                 :          0 :                 index = iq->host_write_index;
     662         [ #  # ]:          0 :                 if (otx_ep_send_data(otx_ep, iq, &iqcmd, dbell))
     663                 :          0 :                         goto xmit_fail;
     664                 :            :                 otx_ep_iqreq_add(iq, m, iqreq_type, index);
     665                 :          0 :                 iq->stats.tx_pkts++;
     666                 :          0 :                 iq->stats.tx_bytes += pkt_len;
     667                 :          0 :                 count++;
     668                 :            :         }
     669                 :            : 
     670                 :          0 : xmit_fail:
     671         [ #  # ]:          0 :         if (iq->instr_pending >= OTX_EP_MAX_INSTR)
     672                 :          0 :                 otx_ep_flush_iq(iq);
     673                 :            : 
     674                 :            :         /* Return no# of instructions posted successfully. */
     675                 :          0 :         return count;
     676                 :            : }
     677                 :            : 
     678                 :            : static uint32_t
     679                 :          0 : otx_ep_droq_refill(struct otx_ep_droq *droq)
     680                 :            : {
     681                 :          0 :         struct otx_ep_droq_desc *desc_ring = droq->desc_ring;
     682                 :            :         struct otx_ep_droq_info *info;
     683                 :            :         struct rte_mbuf *buf = NULL;
     684                 :            :         uint32_t desc_refilled = 0;
     685                 :            : 
     686   [ #  #  #  # ]:          0 :         while (droq->refill_count && (desc_refilled < droq->nb_desc)) {
     687                 :          0 :                 buf = rte_pktmbuf_alloc(droq->mpool);
     688                 :            :                 /* If a buffer could not be allocated, no point in
     689                 :            :                  * continuing
     690                 :            :                  */
     691         [ #  # ]:          0 :                 if (unlikely(!buf)) {
     692                 :          0 :                         droq->stats.rx_alloc_failure++;
     693                 :          0 :                         break;
     694                 :            :                 }
     695                 :          0 :                 info = rte_pktmbuf_mtod(buf, struct otx_ep_droq_info *);
     696                 :          0 :                 info->length = 0;
     697                 :            : 
     698                 :          0 :                 droq->recv_buf_list[droq->refill_idx] = buf;
     699                 :          0 :                 desc_ring[droq->refill_idx].buffer_ptr =
     700                 :            :                                         rte_mbuf_data_iova_default(buf);
     701                 :          0 :                 droq->refill_idx = otx_ep_incr_index(droq->refill_idx, 1,
     702                 :            :                                 droq->nb_desc);
     703                 :            : 
     704                 :          0 :                 desc_refilled++;
     705                 :          0 :                 droq->refill_count--;
     706                 :            :         }
     707                 :            : 
     708                 :          0 :         return desc_refilled;
     709                 :            : }
     710                 :            : 
     711                 :            : static struct rte_mbuf *
     712                 :          0 : otx_ep_droq_read_packet(struct otx_ep_device *otx_ep, struct otx_ep_droq *droq, int next_fetch)
     713                 :            : {
     714                 :            :         volatile struct otx_ep_droq_info *info;
     715                 :            :         struct rte_mbuf *mbuf_next = NULL;
     716                 :            :         struct rte_mbuf *mbuf = NULL;
     717                 :            :         uint64_t total_pkt_len;
     718                 :            :         uint32_t pkt_len = 0;
     719                 :            :         int next_idx;
     720                 :            : 
     721                 :          0 :         mbuf = droq->recv_buf_list[droq->read_idx];
     722                 :          0 :         info = rte_pktmbuf_mtod(mbuf, struct otx_ep_droq_info *);
     723                 :            : 
     724                 :            :         /* make sure info is available */
     725                 :            :         rte_rmb();
     726         [ #  # ]:          0 :         if (unlikely(!info->length)) {
     727                 :            :                 int retry = OTX_EP_MAX_DELAYED_PKT_RETRIES;
     728                 :            :                 /* otx_ep_dbg("OCTEON DROQ[%d]: read_idx: %d; Data not ready "
     729                 :            :                  * "yet, Retry; pending=%lu\n", droq->q_no, droq->read_idx,
     730                 :            :                  * droq->pkts_pending);
     731                 :            :                  */
     732                 :          0 :                 droq->stats.pkts_delayed_data++;
     733   [ #  #  #  # ]:          0 :                 while (retry && !info->length) {
     734                 :          0 :                         retry--;
     735                 :          0 :                         rte_delay_us_block(50);
     736                 :            :                 }
     737   [ #  #  #  # ]:          0 :                 if (!retry && !info->length) {
     738                 :          0 :                         otx_ep_err("OCTEON DROQ[%d]: read_idx: %d; Retry failed !!\n",
     739                 :            :                                    droq->q_no, droq->read_idx);
     740                 :            :                         /* May be zero length packet; drop it */
     741                 :          0 :                         assert(0);
     742                 :            :                 }
     743                 :            :         }
     744                 :            : 
     745         [ #  # ]:          0 :         if (next_fetch) {
     746                 :          0 :                 next_idx = otx_ep_incr_index(droq->read_idx, 1, droq->nb_desc);
     747                 :          0 :                 mbuf_next = droq->recv_buf_list[next_idx];
     748                 :          0 :                 rte_prefetch0(rte_pktmbuf_mtod(mbuf_next, void *));
     749                 :            :         }
     750                 :            : 
     751                 :          0 :         info->length = rte_bswap16(info->length >> 48);
     752                 :            :         /* Deduce the actual data size */
     753                 :          0 :         total_pkt_len = info->length + OTX_EP_INFO_SIZE;
     754         [ #  # ]:          0 :         if (total_pkt_len <= droq->buffer_size) {
     755                 :          0 :                 mbuf->data_off += OTX_EP_INFO_SIZE;
     756                 :          0 :                 pkt_len = (uint32_t)info->length;
     757                 :          0 :                 mbuf->pkt_len  = pkt_len;
     758                 :          0 :                 mbuf->data_len  = pkt_len;
     759                 :          0 :                 mbuf->port = otx_ep->port_id;
     760                 :          0 :                 droq->recv_buf_list[droq->read_idx] = NULL;
     761                 :          0 :                 droq->read_idx = otx_ep_incr_index(droq->read_idx, 1, droq->nb_desc);
     762                 :          0 :                 droq->refill_count++;
     763                 :            :         } else {
     764                 :            :                 struct rte_mbuf *first_buf = NULL;
     765                 :            :                 struct rte_mbuf *last_buf = NULL;
     766                 :            : 
     767                 :            :                 /* csr read helps to flush pending dma */
     768                 :          0 :                 droq->sent_reg_val = rte_read32(droq->pkts_sent_reg);
     769                 :            :                 rte_rmb();
     770                 :            : 
     771         [ #  # ]:          0 :                 while (pkt_len < total_pkt_len) {
     772                 :            :                         int cpy_len = 0;
     773                 :            : 
     774                 :          0 :                         cpy_len = ((pkt_len + droq->buffer_size) > total_pkt_len)
     775                 :          0 :                                         ? ((uint32_t)total_pkt_len - pkt_len)
     776         [ #  # ]:          0 :                                         : droq->buffer_size;
     777                 :            : 
     778                 :          0 :                         mbuf = droq->recv_buf_list[droq->read_idx];
     779                 :          0 :                         droq->recv_buf_list[droq->read_idx] = NULL;
     780                 :            : 
     781         [ #  # ]:          0 :                         if (likely(mbuf)) {
     782                 :            :                                 /* Note the first seg */
     783         [ #  # ]:          0 :                                 if (!pkt_len)
     784                 :            :                                         first_buf = mbuf;
     785                 :            : 
     786                 :          0 :                                 mbuf->port = otx_ep->port_id;
     787         [ #  # ]:          0 :                                 if (!pkt_len) {
     788                 :          0 :                                         mbuf->data_off += OTX_EP_INFO_SIZE;
     789                 :          0 :                                         mbuf->pkt_len = cpy_len - OTX_EP_INFO_SIZE;
     790                 :          0 :                                         mbuf->data_len = cpy_len - OTX_EP_INFO_SIZE;
     791                 :            :                                 } else {
     792                 :          0 :                                         mbuf->pkt_len = cpy_len;
     793                 :          0 :                                         mbuf->data_len = cpy_len;
     794                 :            :                                 }
     795                 :            : 
     796         [ #  # ]:          0 :                                 if (pkt_len) {
     797                 :          0 :                                         first_buf->nb_segs++;
     798                 :          0 :                                         first_buf->pkt_len += mbuf->pkt_len;
     799                 :            :                                 }
     800                 :            : 
     801         [ #  # ]:          0 :                                 if (last_buf)
     802                 :          0 :                                         last_buf->next = mbuf;
     803                 :            : 
     804                 :            :                                 last_buf = mbuf;
     805                 :            :                         } else {
     806                 :          0 :                                 otx_ep_err("no buf\n");
     807                 :          0 :                                 assert(0);
     808                 :            :                         }
     809                 :            : 
     810                 :          0 :                         pkt_len += cpy_len;
     811                 :          0 :                         droq->read_idx = otx_ep_incr_index(droq->read_idx, 1, droq->nb_desc);
     812                 :          0 :                         droq->refill_count++;
     813                 :            :                 }
     814                 :            :                 mbuf = first_buf;
     815                 :            :         }
     816                 :            : 
     817                 :          0 :         return mbuf;
     818                 :            : }
     819                 :            : 
     820                 :            : static inline uint32_t
     821                 :          0 : otx_ep_check_droq_pkts(struct otx_ep_droq *droq)
     822                 :            : {
     823                 :            :         uint32_t new_pkts;
     824                 :            :         uint32_t val;
     825                 :            : 
     826                 :            :         /*
     827                 :            :          * Batch subtractions from the HW counter to reduce PCIe traffic
     828                 :            :          * This adds an extra local variable, but almost halves the
     829                 :            :          * number of PCIe writes.
     830                 :            :          */
     831                 :          0 :         val = *droq->pkts_sent_ism;
     832                 :          0 :         new_pkts = val - droq->pkts_sent_ism_prev;
     833                 :          0 :         droq->pkts_sent_ism_prev = val;
     834                 :            : 
     835         [ #  # ]:          0 :         if (val > (uint32_t)(1 << 31)) {
     836                 :            :                 /*
     837                 :            :                  * Only subtract the packet count in the HW counter
     838                 :            :                  * when count above halfway to saturation.
     839                 :            :                  */
     840                 :          0 :                 rte_write32(val, droq->pkts_sent_reg);
     841                 :            :                 rte_mb();
     842                 :            : 
     843                 :          0 :                 rte_write64(OTX2_SDP_REQUEST_ISM, droq->pkts_sent_reg);
     844         [ #  # ]:          0 :                 while (__atomic_load_n(droq->pkts_sent_ism, __ATOMIC_RELAXED) >= val) {
     845                 :          0 :                         rte_write64(OTX2_SDP_REQUEST_ISM, droq->pkts_sent_reg);
     846                 :            :                         rte_mb();
     847                 :            :                 }
     848                 :            : 
     849                 :          0 :                 droq->pkts_sent_ism_prev = 0;
     850                 :            :         }
     851                 :          0 :         rte_write64(OTX2_SDP_REQUEST_ISM, droq->pkts_sent_reg);
     852                 :          0 :         droq->pkts_pending += new_pkts;
     853                 :            : 
     854                 :          0 :         return new_pkts;
     855                 :            : }
     856                 :            : 
     857                 :            : static inline int32_t __rte_hot
     858                 :            : otx_ep_rx_pkts_to_process(struct otx_ep_droq *droq, uint16_t nb_pkts)
     859                 :            : {
     860                 :          0 :         if (unlikely(droq->pkts_pending < nb_pkts))
     861                 :          0 :                 otx_ep_check_droq_pkts(droq);
     862                 :            : 
     863                 :          0 :         return RTE_MIN(nb_pkts, droq->pkts_pending);
     864                 :            : }
     865                 :            : 
     866                 :            : /* Check for response arrival from OCTEON 9
     867                 :            :  * returns number of requests completed
     868                 :            :  */
     869                 :            : uint16_t
     870                 :          0 : otx_ep_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
     871                 :            : {
     872                 :            :         struct otx_ep_droq *droq = rx_queue;
     873                 :            :         struct otx_ep_device *otx_ep;
     874                 :            :         struct rte_mbuf *oq_pkt;
     875                 :            :         uint16_t pkts, new_pkts;
     876                 :            :         uint32_t valid_pkts = 0;
     877                 :            :         int next_fetch;
     878                 :            : 
     879         [ #  # ]:          0 :         otx_ep = droq->otx_ep_dev;
     880                 :          0 :         new_pkts = otx_ep_rx_pkts_to_process(droq, nb_pkts);
     881                 :            : 
     882         [ #  # ]:          0 :         for (pkts = 0; pkts < new_pkts; pkts++) {
     883                 :            :                 /* Push the received pkt to application */
     884                 :          0 :                 next_fetch = (pkts == new_pkts - 1) ? 0 : 1;
     885                 :          0 :                 oq_pkt = otx_ep_droq_read_packet(otx_ep, droq, next_fetch);
     886         [ #  # ]:          0 :                 if (!oq_pkt) {
     887                 :          0 :                         RTE_LOG_DP(ERR, PMD,
     888                 :            :                                    "DROQ read pkt failed pending %" PRIu64
     889                 :            :                                     "last_pkt_count %" PRIu64 "new_pkts %d.\n",
     890                 :            :                                    droq->pkts_pending, droq->last_pkt_count,
     891                 :            :                                    new_pkts);
     892                 :          0 :                         droq->stats.rx_err++;
     893                 :          0 :                         continue;
     894                 :            :                 } else {
     895                 :          0 :                         rx_pkts[valid_pkts] = oq_pkt;
     896                 :          0 :                         valid_pkts++;
     897                 :            :                         /* Stats */
     898                 :          0 :                         droq->stats.pkts_received++;
     899                 :          0 :                         droq->stats.bytes_received += oq_pkt->pkt_len;
     900                 :            :                 }
     901                 :            :         }
     902                 :          0 :         droq->pkts_pending -= pkts;
     903                 :            : 
     904                 :            :         /* Refill DROQ buffers */
     905         [ #  # ]:          0 :         if (droq->refill_count >= DROQ_REFILL_THRESHOLD) {
     906                 :          0 :                 int desc_refilled = otx_ep_droq_refill(droq);
     907                 :            : 
     908                 :            :                 /* Flush the droq descriptor data to memory to be sure
     909                 :            :                  * that when we update the credits the data in memory is
     910                 :            :                  * accurate.
     911                 :            :                  */
     912                 :          0 :                 rte_io_wmb();
     913                 :          0 :                 rte_write32(desc_refilled, droq->pkts_credit_reg);
     914                 :            :         } else {
     915                 :            :                 /*
     916                 :            :                  * SDP output goes into DROP state when output doorbell count
     917                 :            :                  * goes below drop count. When door bell count is written with
     918                 :            :                  * a value greater than drop count SDP output should come out
     919                 :            :                  * of DROP state. Due to a race condition this is not happening.
     920                 :            :                  * Writing doorbell register with 0 again may make SDP output
     921                 :            :                  * come out of this state.
     922                 :            :                  */
     923                 :            : 
     924                 :          0 :                 rte_write32(0, droq->pkts_credit_reg);
     925                 :            :         }
     926                 :          0 :         return valid_pkts;
     927                 :            : }

Generated by: LCOV version 1.14