LCOV - code coverage report
Current view: top level - drivers/net/hinic3 - hinic3_rx.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 476 0.0 %
Date: 2026-04-01 20:02:27 Functions: 0 28 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 200 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2025 Huawei Technologies Co., Ltd
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "base/hinic3_compat.h"
       6                 :            : #include "base/hinic3_hwif.h"
       7                 :            : #include "base/hinic3_hwdev.h"
       8                 :            : #include "base/hinic3_wq.h"
       9                 :            : #include "base/hinic3_nic_cfg.h"
      10                 :            : #include "hinic3_nic_io.h"
      11                 :            : #include "hinic3_ethdev.h"
      12                 :            : #include "hinic3_rx.h"
      13                 :            : 
      14                 :            : /**
      15                 :            :  * Get wqe from receive queue.
      16                 :            :  *
      17                 :            :  * @param[in] rxq
      18                 :            :  * Receive queue.
      19                 :            :  * @param[out] rq_wqe
      20                 :            :  * Receive queue wqe.
      21                 :            :  * @param[out] pi
      22                 :            :  * Current pi.
      23                 :            :  */
      24                 :            : static inline void
      25                 :            : hinic3_get_rq_wqe(struct hinic3_rxq *rxq, struct hinic3_rq_wqe **rq_wqe, uint16_t *pi)
      26                 :            : {
      27                 :          0 :         *pi = MASKED_QUEUE_IDX(rxq, rxq->prod_idx);
      28                 :            : 
      29                 :            :         /* Get only one rxq wqe. */
      30                 :          0 :         rxq->prod_idx++;
      31                 :          0 :         rxq->delta--;
      32                 :            : 
      33                 :          0 :         *rq_wqe = NIC_WQE_ADDR(rxq, *pi);
      34                 :            : }
      35                 :            : 
      36                 :            : /**
      37                 :            :  * Put wqe into receive queue.
      38                 :            :  *
      39                 :            :  * @param[in] rxq
      40                 :            :  * Receive queue.
      41                 :            :  * @param[in] wqe_cnt
      42                 :            :  * Wqebb counters.
      43                 :            :  */
      44                 :            : static inline void
      45                 :            : hinic3_put_rq_wqe(struct hinic3_rxq *rxq, uint16_t wqe_cnt)
      46                 :            : {
      47                 :          0 :         rxq->delta += wqe_cnt;
      48                 :          0 :         rxq->prod_idx -= wqe_cnt;
      49                 :            : }
      50                 :            : 
      51                 :            : /**
      52                 :            :  * Get receive queue local pi.
      53                 :            :  *
      54                 :            :  * @param[in] rxq
      55                 :            :  * Receive queue.
      56                 :            :  * @return
      57                 :            :  * Receive queue local pi.
      58                 :            :  */
      59                 :            : static inline uint16_t
      60                 :            : hinic3_get_rq_local_pi(struct hinic3_rxq *rxq)
      61                 :            : {
      62                 :          0 :         return MASKED_QUEUE_IDX(rxq, rxq->prod_idx);
      63                 :            : }
      64                 :            : 
      65                 :            : uint16_t
      66                 :          0 : hinic3_rx_fill_wqe(struct hinic3_rxq *rxq)
      67                 :            : {
      68                 :            :         struct hinic3_rq_wqe *rq_wqe = NULL;
      69                 :          0 :         struct hinic3_nic_dev *nic_dev = rxq->nic_dev;
      70                 :            :         rte_iova_t cqe_dma;
      71                 :            :         uint16_t pi = 0;
      72                 :            :         uint16_t i;
      73                 :            : 
      74                 :          0 :         cqe_dma = rxq->cqe_start_paddr;
      75         [ #  # ]:          0 :         for (i = 0; i < rxq->q_depth; i++) {
      76                 :            :                 hinic3_get_rq_wqe(rxq, &rq_wqe, &pi);
      77         [ #  # ]:          0 :                 if (!rq_wqe) {
      78                 :          0 :                         PMD_DRV_LOG(ERR,
      79                 :            :                                     "Get rq wqe failed, rxq id: %d, wqe id: %d",
      80                 :            :                                     rxq->q_id, i);
      81                 :          0 :                         break;
      82                 :            :                 }
      83                 :            : 
      84         [ #  # ]:          0 :                 if (rxq->wqe_type == HINIC3_EXTEND_RQ_WQE) {
      85                 :            :                         /* Unit of cqe length is 16B. */
      86                 :          0 :                         hinic3_set_sge(&rq_wqe->extend_wqe.cqe_sect.sge, cqe_dma,
      87                 :            :                                        HINIC3_CQE_LEN >> HINIC3_CQE_SIZE_SHIFT);
      88                 :            :                         /* Use fixed len. */
      89                 :          0 :                         rq_wqe->extend_wqe.buf_desc.sge.len = nic_dev->rx_buff_len;
      90                 :            :                 } else {
      91                 :          0 :                         rq_wqe->normal_wqe.cqe_hi_addr = upper_32_bits(cqe_dma);
      92                 :          0 :                         rq_wqe->normal_wqe.cqe_lo_addr = lower_32_bits(cqe_dma);
      93                 :            :                 }
      94                 :            : 
      95                 :          0 :                 cqe_dma += sizeof(struct hinic3_rq_cqe);
      96                 :            : 
      97                 :            :                 hinic3_cpu_to_hw(rq_wqe, rxq->wqebb_size);
      98                 :            :         }
      99                 :            : 
     100                 :            :         hinic3_put_rq_wqe(rxq, i);
     101                 :            : 
     102                 :          0 :         return i;
     103                 :            : }
     104                 :            : 
     105                 :            : static struct rte_mbuf *
     106                 :          0 : hinic3_rx_alloc_mbuf(struct hinic3_rxq *rxq, rte_iova_t *dma_addr)
     107                 :            : {
     108                 :          0 :         struct rte_mbuf *mbuf = NULL;
     109                 :            : 
     110         [ #  # ]:          0 :         if (unlikely(rte_pktmbuf_alloc_bulk(rxq->mb_pool, &mbuf, 1) != 0))
     111                 :            :                 return NULL;
     112                 :            : 
     113                 :          0 :         *dma_addr = rte_mbuf_data_iova_default(mbuf);
     114                 :            : #ifdef HINIC3_XSTAT_MBUF_USE
     115                 :            :         rxq->rxq_stats.rx_alloc_mbuf_bytes++;
     116                 :            : #endif
     117                 :          0 :         return mbuf;
     118                 :            : }
     119                 :            : 
     120                 :            : #ifdef HINIC3_XSTAT_RXBUF_INFO
     121                 :            : static void
     122                 :            : hinic3_rxq_buffer_done_count(struct hinic3_rxq *rxq)
     123                 :            : {
     124                 :            :         uint16_t sw_ci, avail_pkts = 0, hit_done = 0, cqe_hole = 0;
     125                 :            :         RTE_ATOMIC(uint32_t)status;
     126                 :            :         volatile struct hinic3_rq_cqe *rx_cqe;
     127                 :            : 
     128                 :            :         for (sw_ci = 0; sw_ci < rxq->q_depth; sw_ci++) {
     129                 :            :                 rx_cqe = &rxq->rx_cqe[sw_ci];
     130                 :            : 
     131                 :            :                 /* Check current ci is done. */
     132                 :            :                 status = rx_cqe->status;
     133                 :            :                 if (!HINIC3_GET_RX_DONE(status)) {
     134                 :            :                         if (hit_done) {
     135                 :            :                                 cqe_hole++;
     136                 :            :                                 hit_done = 0;
     137                 :            :                         }
     138                 :            :                         continue;
     139                 :            :                 }
     140                 :            : 
     141                 :            :                 avail_pkts++;
     142                 :            :                 hit_done = 1;
     143                 :            :         }
     144                 :            : 
     145                 :            :         rxq->rxq_stats.rx_avail = avail_pkts;
     146                 :            :         rxq->rxq_stats.rx_hole = cqe_hole;
     147                 :            : }
     148                 :            : 
     149                 :            : void
     150                 :            : hinic3_get_stats(struct hinic3_rxq *rxq)
     151                 :            : {
     152                 :            :         rxq->rxq_stats.rx_mbuf = rxq->q_depth - hinic3_get_rq_free_wqebb(rxq);
     153                 :            : 
     154                 :            :         hinic3_rxq_buffer_done_count(rxq);
     155                 :            : }
     156                 :            : #endif
     157                 :            : 
     158                 :            : uint16_t
     159                 :          0 : hinic3_rx_fill_buffers(struct hinic3_rxq *rxq)
     160                 :            : {
     161                 :            :         struct hinic3_rq_wqe *rq_wqe = NULL;
     162                 :            :         struct hinic3_rx_info *rx_info = NULL;
     163                 :            :         struct rte_mbuf *mb = NULL;
     164                 :            :         rte_iova_t dma_addr;
     165                 :            :         uint16_t i, free_wqebbs;
     166                 :            : 
     167                 :          0 :         free_wqebbs = rxq->delta - 1;
     168         [ #  # ]:          0 :         for (i = 0; i < free_wqebbs; i++) {
     169                 :          0 :                 rx_info = &rxq->rx_info[rxq->next_to_update];
     170                 :            : 
     171                 :          0 :                 mb = hinic3_rx_alloc_mbuf(rxq, &dma_addr);
     172         [ #  # ]:          0 :                 if (!mb) {
     173                 :          0 :                         PMD_DRV_LOG(ERR, "Alloc mbuf failed");
     174                 :          0 :                         break;
     175                 :            :                 }
     176                 :            : 
     177                 :          0 :                 rx_info->mbuf = mb;
     178                 :            : 
     179                 :          0 :                 rq_wqe = NIC_WQE_ADDR(rxq, rxq->next_to_update);
     180                 :            : 
     181                 :            :                 /* Fill buffer address only. */
     182         [ #  # ]:          0 :                 if (rxq->wqe_type == HINIC3_EXTEND_RQ_WQE) {
     183                 :          0 :                         rq_wqe->extend_wqe.buf_desc.sge.hi_addr =
     184                 :          0 :                                 hinic3_hw_be32(upper_32_bits(dma_addr));
     185                 :          0 :                         rq_wqe->extend_wqe.buf_desc.sge.lo_addr =
     186                 :          0 :                                 hinic3_hw_be32(lower_32_bits(dma_addr));
     187                 :            :                 } else {
     188                 :          0 :                         rq_wqe->normal_wqe.buf_hi_addr =
     189                 :          0 :                                 hinic3_hw_be32(upper_32_bits(dma_addr));
     190                 :          0 :                         rq_wqe->normal_wqe.buf_lo_addr =
     191                 :          0 :                                 hinic3_hw_be32(lower_32_bits(dma_addr));
     192                 :            :                 }
     193                 :            : 
     194                 :          0 :                 rxq->next_to_update = (rxq->next_to_update + 1) & rxq->q_mask;
     195                 :            :         }
     196                 :            : 
     197         [ #  # ]:          0 :         if (likely(i > 0)) {
     198                 :          0 :                 hinic3_write_db(rxq->db_addr, rxq->q_id, 0, RQ_CFLAG_DP,
     199                 :          0 :                                 (rxq->next_to_update << rxq->wqe_type));
     200                 :            :                 /* Init rxq contxet used, need to optimization. */
     201                 :          0 :                 rxq->prod_idx = rxq->next_to_update;
     202                 :          0 :                 rxq->delta -= i;
     203                 :            :         } else {
     204                 :          0 :                 PMD_DRV_LOG(ERR, "Alloc rx buffers failed, rxq_id: %d", rxq->q_id);
     205                 :            :         }
     206                 :            : 
     207                 :          0 :         return i;
     208                 :            : }
     209                 :            : 
     210                 :            : void
     211                 :          0 : hinic3_free_rxq_mbufs(struct hinic3_rxq *rxq)
     212                 :            : {
     213                 :            :         struct hinic3_rx_info *rx_info = NULL;
     214                 :          0 :         int free_wqebbs = hinic3_get_rq_free_wqebb(rxq) + 1;
     215                 :            :         volatile struct hinic3_rq_cqe *rx_cqe = NULL;
     216                 :            :         uint16_t ci;
     217                 :            : 
     218         [ #  # ]:          0 :         while (free_wqebbs++ < rxq->q_depth) {
     219                 :            :                 ci = hinic3_get_rq_local_ci(rxq);
     220         [ #  # ]:          0 :                 if (rxq->wqe_type != HINIC3_COMPACT_RQ_WQE) {
     221                 :          0 :                         rx_cqe = &rxq->rx_cqe[ci];
     222                 :            :                         /* Clear done bit. */
     223                 :          0 :                         rx_cqe->status = 0;
     224                 :            :                 }
     225                 :            : 
     226                 :          0 :                 rx_info = &rxq->rx_info[ci];
     227                 :          0 :                 rte_pktmbuf_free(rx_info->mbuf);
     228                 :          0 :                 rx_info->mbuf = NULL;
     229                 :            : 
     230                 :            :                 hinic3_update_rq_local_ci(rxq, 1);
     231                 :            : #ifdef HINIC3_XSTAT_MBUF_USE
     232                 :            :                 rxq->rxq_stats.rx_free_mbuf_bytes++;
     233                 :            : #endif
     234                 :            :         }
     235                 :          0 : }
     236                 :            : 
     237                 :            : void
     238                 :          0 : hinic3_free_all_rxq_mbufs(struct hinic3_nic_dev *nic_dev)
     239                 :            : {
     240                 :            :         uint16_t qid;
     241                 :            : 
     242         [ #  # ]:          0 :         for (qid = 0; qid < nic_dev->num_rqs; qid++)
     243                 :          0 :                 hinic3_free_rxq_mbufs(nic_dev->rxqs[qid]);
     244                 :          0 : }
     245                 :            : 
     246                 :            : static uint32_t
     247                 :            : hinic3_rx_alloc_mbuf_bulk(struct hinic3_rxq *rxq, struct rte_mbuf **mbufs,
     248                 :            :                           uint32_t exp_mbuf_cnt)
     249                 :            : {
     250                 :            :         uint32_t avail_cnt;
     251                 :            :         int err;
     252                 :            : 
     253                 :          0 :         err = rte_pktmbuf_alloc_bulk(rxq->mb_pool, mbufs, exp_mbuf_cnt);
     254         [ #  # ]:          0 :         if (likely(err == 0)) {
     255                 :            :                 avail_cnt = exp_mbuf_cnt;
     256                 :            :         } else {
     257                 :            :                 avail_cnt = 0;
     258                 :          0 :                 rxq->rxq_stats.rx_nombuf += exp_mbuf_cnt;
     259                 :            :         }
     260                 :            : #ifdef HINIC3_XSTAT_MBUF_USE
     261                 :            :         rxq->rxq_stats.rx_alloc_mbuf_bytes += avail_cnt;
     262                 :            : #endif
     263                 :            :         return avail_cnt;
     264                 :            : }
     265                 :            : 
     266                 :            : static int
     267                 :          0 : hinic3_rearm_rxq_mbuf(struct hinic3_rxq *rxq)
     268                 :            : {
     269                 :            :         struct hinic3_rq_wqe *rq_wqe = NULL;
     270                 :            :         struct rte_mbuf **rearm_mbufs;
     271                 :            :         uint32_t i, free_wqebbs, rearm_wqebbs, exp_wqebbs;
     272                 :            :         rte_iova_t dma_addr;
     273                 :            :         uint16_t pi;
     274         [ #  # ]:          0 :         struct hinic3_nic_dev *nic_dev = rxq->nic_dev;
     275                 :            : 
     276                 :            :         /* Check free wqebb cnt fo rearm. */
     277                 :          0 :         free_wqebbs = hinic3_get_rq_free_wqebb(rxq);
     278         [ #  # ]:          0 :         if (unlikely(free_wqebbs < rxq->rx_free_thresh))
     279                 :            :                 return -ENOMEM;
     280                 :            : 
     281                 :            :         /* Get rearm mbuf array. */
     282                 :            :         pi = hinic3_get_rq_local_pi(rxq);
     283                 :          0 :         rearm_mbufs = (struct rte_mbuf **)(&rxq->rx_info[pi]);
     284                 :            : 
     285                 :            :         /* Check rxq free wqebbs turn around. */
     286                 :          0 :         exp_wqebbs = rxq->q_depth - pi;
     287                 :            :         if (free_wqebbs < exp_wqebbs)
     288                 :            :                 exp_wqebbs = free_wqebbs;
     289                 :            : 
     290                 :            :         /* Alloc mbuf in bulk. */
     291                 :            :         rearm_wqebbs = hinic3_rx_alloc_mbuf_bulk(rxq, rearm_mbufs, exp_wqebbs);
     292         [ #  # ]:          0 :         if (unlikely(rearm_wqebbs == 0))
     293                 :            :                 return -ENOMEM;
     294                 :            : 
     295                 :            :         /* Rearm rxq mbuf. */
     296                 :          0 :         rq_wqe = NIC_WQE_ADDR(rxq, pi);
     297         [ #  # ]:          0 :         for (i = 0; i < rearm_wqebbs; i++) {
     298         [ #  # ]:          0 :                 dma_addr = rte_mbuf_data_iova_default(rearm_mbufs[i]);
     299                 :            : 
     300                 :            :                 /* Fill packet dma address into wqe. */
     301         [ #  # ]:          0 :                 if (rxq->wqe_type == HINIC3_EXTEND_RQ_WQE) {
     302                 :          0 :                         rq_wqe->extend_wqe.buf_desc.sge.hi_addr =
     303                 :          0 :                                 hinic3_hw_be32(upper_32_bits(dma_addr));
     304                 :          0 :                         rq_wqe->extend_wqe.buf_desc.sge.lo_addr =
     305                 :          0 :                                 hinic3_hw_be32(lower_32_bits(dma_addr));
     306                 :          0 :                         rq_wqe->extend_wqe.buf_desc.sge.len =
     307                 :          0 :                                 nic_dev->rx_buff_len;
     308         [ #  # ]:          0 :                 } else if (rxq->wqe_type == HINIC3_NORMAL_RQ_WQE) {
     309                 :          0 :                         rq_wqe->normal_wqe.buf_hi_addr =
     310                 :          0 :                                 hinic3_hw_be32(upper_32_bits(dma_addr));
     311                 :          0 :                         rq_wqe->normal_wqe.buf_lo_addr =
     312                 :          0 :                                 hinic3_hw_be32(lower_32_bits(dma_addr));
     313                 :            :                 } else {
     314                 :          0 :                         rq_wqe->compact_wqe.buf_hi_addr =
     315                 :          0 :                                 hinic3_hw_be32(upper_32_bits(dma_addr));
     316                 :          0 :                         rq_wqe->compact_wqe.buf_lo_addr =
     317                 :          0 :                                 hinic3_hw_be32(lower_32_bits(dma_addr));
     318                 :            :                 }
     319                 :            : 
     320                 :          0 :                 rq_wqe =
     321                 :          0 :                         (struct hinic3_rq_wqe *)((uint64_t)rq_wqe + rxq->wqebb_size);
     322                 :            :         }
     323                 :          0 :         rxq->prod_idx += rearm_wqebbs;
     324                 :          0 :         rxq->delta -= rearm_wqebbs;
     325                 :            : 
     326                 :          0 :         hinic3_write_db(rxq->db_addr, rxq->q_id, 0, RQ_CFLAG_DP,
     327                 :          0 :                         ((pi + rearm_wqebbs) & rxq->q_mask) << rxq->wqe_type);
     328                 :          0 :         return 0;
     329                 :            : }
     330                 :            : 
     331                 :            : static int
     332                 :          0 : hinic3_init_rss_key(struct hinic3_nic_dev *nic_dev,
     333                 :            :                     struct rte_eth_rss_conf *rss_conf)
     334                 :            : {
     335                 :          0 :         uint8_t default_rss_key[HINIC3_RSS_KEY_SIZE] = {
     336                 :            :                          0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
     337                 :            :                          0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
     338                 :            :                          0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
     339                 :            :                          0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
     340                 :            :                          0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa};
     341                 :          0 :         uint8_t hashkey[HINIC3_RSS_KEY_SIZE] = {0};
     342                 :            :         int err;
     343                 :            : 
     344         [ #  # ]:          0 :         if (rss_conf->rss_key == NULL ||
     345         [ #  # ]:          0 :             rss_conf->rss_key_len > HINIC3_RSS_KEY_SIZE)
     346                 :            :                 memcpy(hashkey, default_rss_key, HINIC3_RSS_KEY_SIZE);
     347                 :            :         else
     348                 :          0 :                 memcpy(hashkey, rss_conf->rss_key, rss_conf->rss_key_len);
     349                 :            : 
     350                 :          0 :         err = hinic3_rss_set_hash_key(nic_dev->hwdev, hashkey, HINIC3_RSS_KEY_SIZE);
     351         [ #  # ]:          0 :         if (err)
     352                 :            :                 return err;
     353                 :            : 
     354                 :          0 :         memcpy(nic_dev->rss_key, hashkey, HINIC3_RSS_KEY_SIZE);
     355                 :          0 :         return 0;
     356                 :            : }
     357                 :            : 
     358                 :            : void
     359                 :          0 : hinic3_add_rq_to_rx_queue_list(struct hinic3_nic_dev *nic_dev, uint16_t queue_id)
     360                 :            : {
     361                 :          0 :         uint16_t rss_queue_count = nic_dev->num_rss;
     362                 :            : 
     363                 :            :         RTE_ASSERT(rss_queue_count <= (RTE_DIM(nic_dev->rx_queue_list) - 1));
     364                 :            : 
     365                 :          0 :         nic_dev->rx_queue_list[rss_queue_count] = (uint8_t)queue_id;
     366                 :          0 :         nic_dev->num_rss++;
     367                 :          0 : }
     368                 :            : 
     369                 :            : void
     370                 :          0 : hinic3_init_rx_queue_list(struct hinic3_nic_dev *nic_dev)
     371                 :            : {
     372                 :          0 :         nic_dev->num_rss = 0;
     373                 :          0 : }
     374                 :            : 
     375                 :            : static void
     376                 :          0 : hinic3_fill_indir_tbl(struct hinic3_nic_dev *nic_dev, uint32_t *indir_tbl)
     377                 :            : {
     378                 :          0 :         uint16_t rss_queue_count = nic_dev->num_rss;
     379                 :            :         int i = 0;
     380                 :            :         int j;
     381                 :            : 
     382         [ #  # ]:          0 :         if (rss_queue_count == 0) {
     383                 :            :                 /* Delete q_id from indir tbl. */
     384         [ #  # ]:          0 :                 for (i = 0; i < HINIC3_RSS_INDIR_SIZE; i++)
     385                 :            :                         /* Invalid value in indir tbl. */
     386                 :          0 :                         indir_tbl[i] = 0xFFFF;
     387                 :            :         } else {
     388         [ #  # ]:          0 :                 while (i < HINIC3_RSS_INDIR_SIZE)
     389   [ #  #  #  # ]:          0 :                         for (j = 0; (j < rss_queue_count) &&
     390                 :          0 :                                     (i < HINIC3_RSS_INDIR_SIZE); j++)
     391                 :          0 :                                 indir_tbl[i++] = nic_dev->rx_queue_list[j];
     392                 :            :         }
     393                 :          0 : }
     394                 :            : 
     395                 :            : int
     396                 :          0 : hinic3_refill_indir_rqid(struct hinic3_rxq *rxq)
     397                 :            : {
     398                 :          0 :         struct hinic3_nic_dev *nic_dev = rxq->nic_dev;
     399                 :            :         uint32_t *indir_tbl;
     400                 :            :         int err;
     401                 :            : 
     402                 :          0 :         indir_tbl = rte_zmalloc(NULL, HINIC3_RSS_INDIR_SIZE * sizeof(uint32_t), 0);
     403         [ #  # ]:          0 :         if (!indir_tbl) {
     404                 :          0 :                 PMD_DRV_LOG(ERR,
     405                 :            :                             "Alloc indir_tbl mem failed, eth_dev:%s, queue_idx:%d",
     406                 :            :                             nic_dev->dev_name, rxq->q_id);
     407                 :          0 :                 return -ENOMEM;
     408                 :            :         }
     409                 :            : 
     410                 :            :         /* Build indir tbl according to the number of rss queue. */
     411                 :          0 :         hinic3_fill_indir_tbl(nic_dev, indir_tbl);
     412                 :            : 
     413                 :          0 :         err = hinic3_rss_set_indir_tbl(nic_dev->hwdev, indir_tbl);
     414         [ #  # ]:          0 :         if (err) {
     415                 :          0 :                 PMD_DRV_LOG(ERR,
     416                 :            :                         "Set indirect table failed, eth_dev:%s, queue_idx:%d",
     417                 :            :                         nic_dev->dev_name, rxq->q_id);
     418                 :          0 :                 goto out;
     419                 :            :         }
     420                 :            : 
     421                 :          0 : out:
     422                 :          0 :         rte_free(indir_tbl);
     423                 :          0 :         return err;
     424                 :            : }
     425                 :            : 
     426                 :            : static int
     427                 :          0 : hinic3_init_rss_type(struct hinic3_nic_dev *nic_dev,
     428                 :            :                      struct rte_eth_rss_conf *rss_conf)
     429                 :            : {
     430                 :          0 :         struct hinic3_rss_type rss_type = {0};
     431                 :          0 :         uint64_t rss_hf = rss_conf->rss_hf;
     432                 :            :         int err;
     433                 :            : 
     434                 :          0 :         rss_type.ipv4 = (rss_hf & (RTE_ETH_RSS_IPV4 | RTE_ETH_RSS_FRAG_IPV4)) ? 1 : 0;
     435                 :          0 :         rss_type.tcp_ipv4 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_TCP) ? 1 : 0;
     436                 :          0 :         rss_type.ipv6 = (rss_hf & (RTE_ETH_RSS_IPV6 | RTE_ETH_RSS_FRAG_IPV6)) ? 1 : 0;
     437                 :          0 :         rss_type.tcp_ipv6 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_TCP) ? 1 : 0;
     438                 :          0 :         rss_type.udp_ipv4 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV4_UDP) ? 1 : 0;
     439                 :          0 :         rss_type.udp_ipv6 = (rss_hf & RTE_ETH_RSS_NONFRAG_IPV6_UDP) ? 1 : 0;
     440                 :            : 
     441         [ #  # ]:          0 :         if (nic_dev->feature_cap & NIC_F_HTN_CMDQ) {
     442                 :          0 :                 rss_type.ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_EX) ? 1 : 0;
     443                 :          0 :                 rss_type.tcp_ipv6_ext = (rss_hf & RTE_ETH_RSS_IPV6_TCP_EX) ? 1 : 0;
     444                 :            :         } else {
     445                 :            :                 rss_type.ipv6_ext = 0;
     446                 :            :                 rss_type.tcp_ipv6_ext = 0;
     447                 :            :         }
     448                 :            : 
     449                 :          0 :         err = hinic3_set_rss_type(nic_dev->hwdev, rss_type);
     450                 :          0 :         return err;
     451                 :            : }
     452                 :            : 
     453                 :            : int
     454                 :          0 : hinic3_update_rss_config(struct rte_eth_dev *dev,
     455                 :            :                          struct rte_eth_rss_conf *rss_conf)
     456                 :            : {
     457                 :          0 :         struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev);
     458                 :          0 :         uint8_t prio_tc[HINIC3_DCB_UP_MAX] = {0};
     459                 :            :         uint8_t num_tc = 0;
     460                 :            :         int err;
     461                 :            : 
     462         [ #  # ]:          0 :         if (rss_conf->rss_hf == 0) {
     463                 :          0 :                 rss_conf->rss_hf = HINIC3_RSS_OFFLOAD_ALL;
     464         [ #  # ]:          0 :         } else if ((rss_conf->rss_hf & HINIC3_RSS_OFFLOAD_ALL) == 0) {
     465                 :          0 :                 PMD_DRV_LOG(ERR, "Doesn't support rss hash type: %" PRIu64,
     466                 :            :                             rss_conf->rss_hf);
     467                 :          0 :                 return -EINVAL;
     468                 :            :         }
     469                 :            : 
     470                 :          0 :         err = hinic3_rss_template_alloc(nic_dev->hwdev);
     471         [ #  # ]:          0 :         if (err) {
     472                 :          0 :                 PMD_DRV_LOG(ERR, "Alloc rss template failed, err: %d", err);
     473                 :          0 :                 return err;
     474                 :            :         }
     475                 :            : 
     476                 :          0 :         err = hinic3_init_rss_key(nic_dev, rss_conf);
     477         [ #  # ]:          0 :         if (err) {
     478                 :          0 :                 PMD_DRV_LOG(ERR, "Init rss hash key failed, err: %d", err);
     479                 :          0 :                 goto init_rss_fail;
     480                 :            :         }
     481                 :            : 
     482                 :          0 :         err = hinic3_init_rss_type(nic_dev, rss_conf);
     483         [ #  # ]:          0 :         if (err) {
     484                 :          0 :                 PMD_DRV_LOG(ERR, "Init rss hash type failed, err: %d", err);
     485                 :          0 :                 goto init_rss_fail;
     486                 :            :         }
     487                 :            : 
     488                 :          0 :         err = hinic3_rss_set_hash_engine(nic_dev->hwdev,
     489                 :            :                                          HINIC3_RSS_HASH_ENGINE_TYPE_TOEP);
     490         [ #  # ]:          0 :         if (err) {
     491                 :          0 :                 PMD_DRV_LOG(ERR, "Init rss hash function failed, err: %d", err);
     492                 :          0 :                 goto init_rss_fail;
     493                 :            :         }
     494                 :            : 
     495                 :          0 :         err = hinic3_rss_cfg(nic_dev->hwdev, HINIC3_RSS_ENABLE, num_tc, prio_tc);
     496         [ #  # ]:          0 :         if (err) {
     497                 :          0 :                 PMD_DRV_LOG(ERR, "Enable rss failed, err: %d", err);
     498                 :          0 :                 goto init_rss_fail;
     499                 :            :         }
     500                 :            : 
     501                 :          0 :         nic_dev->rss_state = HINIC3_RSS_ENABLE;
     502                 :          0 :         return 0;
     503                 :            : 
     504                 :          0 : init_rss_fail:
     505         [ #  # ]:          0 :         if (hinic3_rss_template_free(nic_dev->hwdev))
     506                 :          0 :                 PMD_DRV_LOG(WARNING, "Free rss template failed");
     507                 :            : 
     508                 :            :         return err;
     509                 :            : }
     510                 :            : 
     511                 :            : /**
     512                 :            :  * Search given queue array to find position of given id.
     513                 :            :  * Return queue pos or queue_count if not found.
     514                 :            :  */
     515                 :            : static uint8_t
     516                 :            : hinic3_find_queue_pos_by_rq_id(uint8_t *queues, uint8_t queues_count, uint8_t queue_id)
     517                 :            : {
     518                 :            :         uint8_t pos;
     519                 :            : 
     520         [ #  # ]:          0 :         for (pos = 0; pos < queues_count; pos++) {
     521         [ #  # ]:          0 :                 if (queue_id == queues[pos])
     522                 :            :                         break;
     523                 :            :         }
     524                 :            : 
     525                 :            :         return pos;
     526                 :            : }
     527                 :            : 
     528                 :            : void
     529                 :          0 : hinic3_remove_rq_from_rx_queue_list(struct hinic3_nic_dev *nic_dev,
     530                 :            :                                     uint16_t queue_id)
     531                 :            : {
     532                 :            :         uint8_t queue_pos;
     533                 :          0 :         uint16_t rss_queue_count = nic_dev->num_rss;
     534                 :            : 
     535                 :          0 :         queue_pos = hinic3_find_queue_pos_by_rq_id(nic_dev->rx_queue_list,
     536                 :            :                                                    rss_queue_count, queue_id);
     537                 :            :         /*
     538                 :            :          * If queue was not at the end of the list,
     539                 :            :          * shift started queues up queue array list.
     540                 :            :          */
     541         [ #  # ]:          0 :         if (queue_pos < rss_queue_count) {
     542                 :          0 :                 rss_queue_count--;
     543                 :          0 :                 memmove(nic_dev->rx_queue_list + queue_pos,
     544                 :          0 :                         nic_dev->rx_queue_list + queue_pos + 1,
     545                 :          0 :                         (rss_queue_count - queue_pos) * sizeof(nic_dev->rx_queue_list[0]));
     546                 :            :         }
     547                 :            : 
     548                 :            :         RTE_ASSERT(rss_queue_count < RTE_DIM(nic_dev->rx_queue_list));
     549                 :          0 :         nic_dev->num_rss = rss_queue_count;
     550                 :          0 : }
     551                 :            : 
     552                 :            : static void
     553                 :          0 : hinic3_rx_queue_release_mbufs(struct hinic3_rxq *rxq)
     554                 :            : {
     555                 :            :         uint16_t sw_ci, ci_mask, free_wqebbs;
     556                 :            :         uint16_t rx_buf_len;
     557                 :            :         uint32_t vlan_len, pkt_len;
     558                 :            :         RTE_ATOMIC(uint32_t)status;
     559                 :            :         uint32_t pkt_left_len = 0;
     560                 :            :         uint32_t nr_released = 0;
     561                 :            :         struct hinic3_rx_info *rx_info;
     562                 :            :         volatile struct hinic3_rq_cqe *rx_cqe;
     563                 :            : 
     564                 :            :         sw_ci = hinic3_get_rq_local_ci(rxq);
     565                 :          0 :         rx_info = &rxq->rx_info[sw_ci];
     566                 :          0 :         rx_cqe = &rxq->rx_cqe[sw_ci];
     567                 :            :         free_wqebbs = hinic3_get_rq_free_wqebb(rxq) + 1;
     568                 :          0 :         status = rx_cqe->status;
     569                 :            :         ci_mask = rxq->q_mask;
     570                 :            : 
     571         [ #  # ]:          0 :         while (free_wqebbs < rxq->q_depth) {
     572                 :          0 :                 rx_buf_len = rxq->buf_len;
     573         [ #  # ]:          0 :                 if (pkt_left_len != 0) {
     574                 :            :                         /* Flush continues jumbo rqe. */
     575                 :          0 :                         pkt_left_len = (pkt_left_len <= rx_buf_len)
     576         [ #  # ]:          0 :                                                ? 0 : (pkt_left_len - rx_buf_len);
     577         [ #  # ]:          0 :                 } else if (HINIC3_GET_RX_FLUSH(status)) {
     578                 :            :                         /* Flush one released rqe. */
     579                 :            :                         pkt_left_len = 0;
     580         [ #  # ]:          0 :                 } else if (HINIC3_GET_RX_DONE(status)) {
     581                 :            :                         /* Flush single packet or first jumbo rqe. */
     582                 :          0 :                         vlan_len = hinic3_hw_cpu32(rx_cqe->vlan_len);
     583                 :          0 :                         pkt_len = HINIC3_GET_RX_PKT_LEN(vlan_len);
     584                 :          0 :                         pkt_left_len = (pkt_len <= rx_buf_len)
     585         [ #  # ]:          0 :                                                ? 0 : (pkt_len - rx_buf_len);
     586                 :            :                 } else {
     587                 :            :                         break;
     588                 :            :                 }
     589                 :          0 :                 rte_pktmbuf_free(rx_info->mbuf);
     590                 :            : 
     591                 :          0 :                 rx_info->mbuf = NULL;
     592                 :          0 :                 rx_cqe->status = 0;
     593                 :          0 :                 nr_released++;
     594                 :          0 :                 free_wqebbs++;
     595                 :            : 
     596                 :            :                 /* Update ci to next cqe. */
     597                 :          0 :                 sw_ci++;
     598                 :          0 :                 sw_ci &= ci_mask;
     599                 :          0 :                 rx_info = &rxq->rx_info[sw_ci];
     600                 :          0 :                 rx_cqe = &rxq->rx_cqe[sw_ci];
     601                 :          0 :                 status = rx_cqe->status;
     602                 :            :         }
     603                 :            : 
     604                 :          0 :         hinic3_update_rq_local_ci(rxq, nr_released);
     605                 :          0 : }
     606                 :            : 
     607                 :            : int
     608                 :          0 : hinic3_poll_rq_empty(struct hinic3_rxq *rxq)
     609                 :            : {
     610                 :            :         uint64_t end;
     611                 :            :         int free_wqebb;
     612                 :            :         int err = -EFAULT;
     613                 :            : 
     614                 :          0 :         end = msecs_to_cycles(HINIC3_FLUSH_QUEUE_TIMEOUT) + cycles;
     615                 :            :         do {
     616                 :          0 :                 free_wqebb = hinic3_get_rq_free_wqebb(rxq) + 1;
     617         [ #  # ]:          0 :                 if (free_wqebb == rxq->q_depth) {
     618                 :            :                         err = 0;
     619                 :            :                         break;
     620                 :            :                 }
     621                 :          0 :                 hinic3_rx_queue_release_mbufs(rxq);
     622                 :          0 :                 rte_delay_us(1);
     623         [ #  # ]:          0 :         } while (time_before(cycles, end));
     624                 :            : 
     625                 :          0 :         return err;
     626                 :            : }
     627                 :            : 
     628                 :            : int
     629                 :          0 : hinic3_poll_integrated_cqe_rq_empty(struct hinic3_rxq *rxq)
     630                 :            : {
     631                 :            :         struct hinic3_rx_info *rx_info;
     632                 :            :         struct hinic3_rq_ci_wb rq_ci;
     633                 :            :         uint16_t sw_ci;
     634                 :            :         uint16_t hw_ci;
     635                 :            :         uint32_t val;
     636                 :            : 
     637                 :            :         sw_ci = hinic3_get_rq_local_ci(rxq);
     638                 :          0 :         val = rte_read32(&rxq->rq_ci->dw1.value);
     639                 :            :         rq_ci.dw1.value = hinic3_hw_cpu32(val);
     640                 :            :         hw_ci = rq_ci.dw1.bs.hw_ci;
     641                 :            : 
     642         [ #  # ]:          0 :         while (sw_ci != hw_ci) {
     643                 :          0 :                 rx_info = &rxq->rx_info[sw_ci];
     644                 :          0 :                 rte_pktmbuf_free(rx_info->mbuf);
     645                 :          0 :                 rx_info->mbuf = NULL;
     646                 :            : 
     647                 :          0 :                 sw_ci++;
     648                 :          0 :                 sw_ci &= rxq->q_mask;
     649                 :            :                 hinic3_update_rq_local_ci(rxq, 1);
     650                 :            :         }
     651                 :            : 
     652                 :          0 :         return 0;
     653                 :            : }
     654                 :            : 
     655                 :            : void
     656                 :          0 : hinic3_dump_cqe_status(struct hinic3_rxq *rxq, uint32_t *cqe_done_cnt,
     657                 :            :                        uint32_t *cqe_hole_cnt, uint32_t *head_ci, uint32_t *head_done)
     658                 :            : {
     659                 :            :         uint16_t sw_ci;
     660                 :            :         uint16_t avail_pkts = 0;
     661                 :            :         uint16_t hit_done = 0;
     662                 :            :         uint16_t cqe_hole = 0;
     663                 :            :         RTE_ATOMIC(uint32_t)status;
     664                 :            :         volatile struct hinic3_rq_cqe *rx_cqe;
     665                 :            : 
     666                 :            :         sw_ci = hinic3_get_rq_local_ci(rxq);
     667                 :          0 :         rx_cqe = &rxq->rx_cqe[sw_ci];
     668                 :          0 :         status = rx_cqe->status;
     669                 :          0 :         *head_done = HINIC3_GET_RX_DONE(status);
     670                 :          0 :         *head_ci = sw_ci;
     671                 :            : 
     672         [ #  # ]:          0 :         for (sw_ci = 0; sw_ci < rxq->q_depth; sw_ci++) {
     673                 :          0 :                 rx_cqe = &rxq->rx_cqe[sw_ci];
     674                 :            : 
     675                 :            :                 /* Check current ci is done. */
     676                 :          0 :                 status = rx_cqe->status;
     677         [ #  # ]:          0 :                 if (!HINIC3_GET_RX_DONE(status) ||
     678         [ #  # ]:          0 :                     !HINIC3_GET_RX_FLUSH(status)) {
     679         [ #  # ]:          0 :                         if (hit_done) {
     680                 :          0 :                                 cqe_hole++;
     681                 :            :                                 hit_done = 0;
     682                 :            :                         }
     683                 :            : 
     684                 :          0 :                         continue;
     685                 :            :                 }
     686                 :            : 
     687                 :          0 :                 avail_pkts++;
     688                 :            :                 hit_done = 1;
     689                 :            :         }
     690                 :            : 
     691                 :          0 :         *cqe_done_cnt = avail_pkts;
     692                 :          0 :         *cqe_hole_cnt = cqe_hole;
     693                 :          0 : }
     694                 :            : 
     695                 :            : int
     696                 :          0 : hinic3_stop_rq(struct rte_eth_dev *eth_dev, struct hinic3_rxq *rxq)
     697                 :            : {
     698                 :          0 :         struct hinic3_nic_dev *nic_dev = rxq->nic_dev;
     699                 :          0 :         uint32_t cqe_done_cnt = 0;
     700                 :          0 :         uint32_t cqe_hole_cnt = 0;
     701                 :            :         uint32_t head_ci, head_done;
     702                 :            :         int err;
     703                 :            : 
     704                 :            :         /* Disable rxq intr. */
     705                 :          0 :         hinic3_dev_rx_queue_intr_disable(eth_dev, rxq->q_id);
     706                 :            : 
     707                 :            :         /* Lock dev queue switch. */
     708                 :          0 :         rte_spinlock_lock(&nic_dev->queue_list_lock);
     709                 :            : 
     710         [ #  # ]:          0 :         if (nic_dev->num_rss == 1) {
     711                 :          0 :                 err = hinic3_set_vport_enable(nic_dev->hwdev, false);
     712         [ #  # ]:          0 :                 if (err) {
     713                 :          0 :                         PMD_DRV_LOG(ERR, "%s Disable vport failed, rc:%d",
     714                 :            :                                     nic_dev->dev_name, err);
     715                 :            :                 }
     716                 :            :         }
     717                 :          0 :         hinic3_remove_rq_from_rx_queue_list(nic_dev, rxq->q_id);
     718                 :            : 
     719                 :            :         /*
     720                 :            :          * If RSS is enable, remove q_id from rss indir table.
     721                 :            :          * If RSS is disable, no mbuf in rq, packet will be dropped.
     722                 :            :          */
     723         [ #  # ]:          0 :         if (nic_dev->rss_state == HINIC3_RSS_ENABLE) {
     724                 :          0 :                 err = hinic3_refill_indir_rqid(rxq);
     725         [ #  # ]:          0 :                 if (err) {
     726                 :          0 :                         PMD_DRV_LOG(ERR,
     727                 :            :                                     "Clear rq in indirect table failed, eth_dev:%s, queue_idx:%d",
     728                 :            :                                     nic_dev->dev_name, rxq->q_id);
     729                 :          0 :                         hinic3_add_rq_to_rx_queue_list(nic_dev, rxq->q_id);
     730                 :          0 :                         goto set_indir_failed;
     731                 :            :                 }
     732                 :            :         }
     733                 :            : 
     734                 :            :         /* Unlock dev queue list switch. */
     735                 :            :         rte_spinlock_unlock(&nic_dev->queue_list_lock);
     736                 :            : 
     737                 :            :         /* Send flush rxq cmd to device. */
     738         [ #  # ]:          0 :         if ((hinic3_get_driver_feature(nic_dev) & NIC_F_HTN_FDIR) == 0)
     739                 :          0 :                 err = hinic3_set_rq_flush(nic_dev->hwdev, rxq->q_id);
     740                 :            :         else
     741                 :          0 :                 err = hinic3_set_rq_enable(nic_dev, rxq->q_id, false);
     742         [ #  # ]:          0 :         if (err) {
     743                 :          0 :                 PMD_DRV_LOG(ERR, "Flush rq failed, eth_dev:%s, queue_idx:%d",
     744                 :            :                             nic_dev->dev_name, rxq->q_id);
     745                 :          0 :                 goto rq_flush_failed;
     746                 :            :         }
     747                 :            : 
     748                 :          0 :         err = nic_dev->rx_ops->nic_rx_poll_rq_empty(rxq);
     749         [ #  # ]:          0 :         if (err) {
     750                 :          0 :                 hinic3_dump_cqe_status(rxq, &cqe_done_cnt, &cqe_hole_cnt,
     751                 :            :                                        &head_ci, &head_done);
     752                 :          0 :                 PMD_DRV_LOG(ERR, "Poll rq empty timeout");
     753                 :          0 :                 PMD_DRV_LOG(ERR,
     754                 :            :                             "eth_dev:%s, queue_idx:%d, mbuf_left:%d, cqe_done:%d, cqe_hole:%d, cqe[%d].done=%d",
     755                 :            :                             nic_dev->dev_name, rxq->q_id,
     756                 :            :                             rxq->q_depth - hinic3_get_rq_free_wqebb(rxq),
     757                 :            :                             cqe_done_cnt, cqe_hole_cnt, head_ci, head_done);
     758                 :          0 :                 goto poll_rq_failed;
     759                 :            :         }
     760                 :            : 
     761                 :            :         return 0;
     762                 :            : 
     763                 :            : poll_rq_failed:
     764                 :          0 :         hinic3_set_rq_enable(nic_dev, rxq->q_id, true);
     765                 :          0 : rq_flush_failed:
     766                 :            :         rte_spinlock_lock(&nic_dev->queue_list_lock);
     767                 :          0 : set_indir_failed:
     768                 :          0 :         hinic3_add_rq_to_rx_queue_list(nic_dev, rxq->q_id);
     769         [ #  # ]:          0 :         if (nic_dev->rss_state == HINIC3_RSS_ENABLE)
     770                 :          0 :                 hinic3_refill_indir_rqid(rxq);
     771                 :            :         rte_spinlock_unlock(&nic_dev->queue_list_lock);
     772                 :          0 :         hinic3_dev_rx_queue_intr_enable(eth_dev, rxq->q_id);
     773                 :          0 :         return err;
     774                 :            : }
     775                 :            : 
     776                 :            : int
     777                 :          0 : hinic3_start_rq(struct rte_eth_dev *eth_dev, struct hinic3_rxq *rxq)
     778                 :            : {
     779                 :          0 :         struct hinic3_nic_dev *nic_dev = rxq->nic_dev;
     780                 :            :         int err = 0;
     781                 :            : 
     782                 :            :         /* Lock dev queue switch.  */
     783                 :          0 :         rte_spinlock_lock(&nic_dev->queue_list_lock);
     784                 :          0 :         hinic3_add_rq_to_rx_queue_list(nic_dev, rxq->q_id);
     785                 :            : 
     786         [ #  # ]:          0 :         if (nic_dev->rss_state == HINIC3_RSS_ENABLE) {
     787         [ #  # ]:          0 :                 if ((hinic3_get_driver_feature(nic_dev) & NIC_F_FDIR) != 0)
     788                 :          0 :                         err = hinic3_set_rq_enable(nic_dev, rxq->q_id, true);
     789         [ #  # ]:          0 :                 if (err) {
     790                 :          0 :                         PMD_DRV_LOG(ERR, "Flush rq failed, eth_dev:%s, queue_idx:%d",
     791                 :            :                                          nic_dev->dev_name, rxq->q_id);
     792                 :            :                 } else {
     793                 :          0 :                         err = hinic3_refill_indir_rqid(rxq);
     794         [ #  # ]:          0 :                         if (err) {
     795                 :          0 :                                 PMD_DRV_LOG(ERR, "Refill rq to indirect table failed,"
     796                 :            :                                                  "eth_dev:%s, queue_idx:%d err:%d",
     797                 :            :                                                  nic_dev->dev_name, rxq->q_id, err);
     798                 :          0 :                                 hinic3_remove_rq_from_rx_queue_list(nic_dev, rxq->q_id);
     799                 :            :                         }
     800                 :            :                 }
     801                 :            :         }
     802                 :            : 
     803                 :          0 :         (void)hinic3_rearm_rxq_mbuf(rxq);
     804         [ #  # ]:          0 :         if (rxq->nic_dev->num_rss == 1) {
     805                 :          0 :                 err = hinic3_set_vport_enable(nic_dev->hwdev, true);
     806         [ #  # ]:          0 :                 if (err)
     807                 :          0 :                         PMD_DRV_LOG(ERR, "%s enable vport failed, err:%d",
     808                 :            :                                     nic_dev->dev_name, err);
     809                 :            :         }
     810                 :            : 
     811                 :            :         /* Unlock dev queue list switch. */
     812                 :            :         rte_spinlock_unlock(&nic_dev->queue_list_lock);
     813                 :            : 
     814                 :          0 :         hinic3_dev_rx_queue_intr_enable(eth_dev, rxq->q_id);
     815                 :            : 
     816                 :          0 :         return err;
     817                 :            : }
     818                 :            : 
     819                 :            : static inline uint64_t
     820                 :            : hinic3_rx_vlan(uint8_t vlan_offload, uint16_t vlan_tag, uint16_t *vlan_tci)
     821                 :            : {
     822                 :          0 :         if (!vlan_offload || vlan_tag == 0) {
     823                 :          0 :                 *vlan_tci = 0;
     824                 :          0 :                 return 0;
     825                 :            :         }
     826                 :            : 
     827                 :          0 :         *vlan_tci = vlan_tag;
     828                 :            : 
     829                 :          0 :         return HINIC3_PKT_RX_VLAN | HINIC3_PKT_RX_VLAN_STRIPPED;
     830                 :            : }
     831                 :            : 
     832                 :            : static inline uint64_t
     833                 :          0 : hinic3_rx_csum(uint16_t csum_err, struct hinic3_rxq *rxq)
     834                 :            : {
     835                 :          0 :         struct hinic3_nic_dev *nic_dev = rxq->nic_dev;
     836                 :            :         uint64_t flags;
     837                 :            : 
     838         [ #  # ]:          0 :         if (unlikely(!(nic_dev->rx_csum_en & HINIC3_DEFAULT_RX_CSUM_OFFLOAD)))
     839                 :            :                 return HINIC3_PKT_RX_IP_CKSUM_UNKNOWN;
     840                 :            : 
     841         [ #  # ]:          0 :         if (likely(csum_err == 0))
     842                 :            :                 return (HINIC3_PKT_RX_IP_CKSUM_GOOD |
     843                 :            :                         HINIC3_PKT_RX_L4_CKSUM_GOOD);
     844                 :            : 
     845                 :            :         /*
     846                 :            :          * If bypass bit is set, all other err status indications should be
     847                 :            :          * ignored.
     848                 :            :          */
     849         [ #  # ]:          0 :         if (unlikely(csum_err & HINIC3_RX_CSUM_HW_CHECK_NONE))
     850                 :            :                 return HINIC3_PKT_RX_IP_CKSUM_UNKNOWN;
     851                 :            : 
     852                 :            :         flags = 0;
     853                 :            : 
     854                 :            :         /* IP checksum error. */
     855         [ #  # ]:          0 :         if (csum_err & HINIC3_RX_CSUM_IP_CSUM_ERR) {
     856                 :            :                 flags |= HINIC3_PKT_RX_IP_CKSUM_BAD;
     857                 :          0 :                 rxq->rxq_stats.csum_errors++;
     858                 :            :         }
     859                 :            : 
     860                 :            :         /* L4 checksum error. */
     861         [ #  # ]:          0 :         if ((csum_err & HINIC3_RX_CSUM_TCP_CSUM_ERR) ||
     862                 :            :             (csum_err & HINIC3_RX_CSUM_UDP_CSUM_ERR) ||
     863                 :            :             (csum_err & HINIC3_RX_CSUM_SCTP_CRC_ERR)) {
     864                 :          0 :                 flags |= HINIC3_PKT_RX_L4_CKSUM_BAD;
     865                 :          0 :                 rxq->rxq_stats.csum_errors++;
     866                 :            :         }
     867                 :            : 
     868         [ #  # ]:          0 :         if (unlikely(csum_err == HINIC3_RX_CSUM_IPSU_OTHER_ERR))
     869                 :          0 :                 rxq->rxq_stats.other_errors++;
     870                 :            : 
     871                 :            :         return flags;
     872                 :            : }
     873                 :            : 
     874                 :            : static inline uint64_t
     875                 :            : hinic3_rx_rss_hash(uint32_t rss_type, uint32_t rss_hash_value, uint32_t *rss_hash)
     876                 :            : {
     877                 :            : 
     878                 :          0 :         if (likely(rss_type != 0)) {
     879                 :          0 :                 *rss_hash = rss_hash_value;
     880                 :          0 :                 return HINIC3_PKT_RX_RSS_HASH;
     881                 :            :         }
     882                 :            : 
     883                 :            :         return 0;
     884                 :            : }
     885                 :            : 
     886                 :            : static void
     887                 :          0 : hinic3_recv_jumbo_pkt(struct hinic3_rxq *rxq, struct rte_mbuf *head_mbuf,
     888                 :            :                       uint32_t remain_pkt_len)
     889                 :            : {
     890                 :            :         struct rte_mbuf *cur_mbuf = NULL;
     891                 :            :         struct rte_mbuf *rxm = NULL;
     892                 :            :         struct hinic3_rx_info *rx_info = NULL;
     893                 :          0 :         uint16_t sw_ci, rx_buf_len = rxq->buf_len;
     894                 :            :         uint32_t pkt_len;
     895                 :            : 
     896         [ #  # ]:          0 :         while (remain_pkt_len > 0) {
     897                 :            :                 sw_ci = hinic3_get_rq_local_ci(rxq);
     898         [ #  # ]:          0 :                 rx_info = &rxq->rx_info[sw_ci];
     899                 :            : 
     900                 :            :                 hinic3_update_rq_local_ci(rxq, 1);
     901                 :            : 
     902                 :          0 :                 pkt_len = remain_pkt_len > rx_buf_len ? rx_buf_len
     903                 :          0 :                                                       : remain_pkt_len;
     904                 :          0 :                 remain_pkt_len -= pkt_len;
     905                 :            : 
     906                 :          0 :                 cur_mbuf = rx_info->mbuf;
     907                 :          0 :                 cur_mbuf->data_len = (uint16_t)pkt_len;
     908                 :          0 :                 cur_mbuf->next = NULL;
     909                 :            : 
     910                 :          0 :                 head_mbuf->pkt_len += cur_mbuf->data_len;
     911                 :          0 :                 head_mbuf->nb_segs++;
     912                 :            : #ifdef HINIC3_XSTAT_MBUF_USE
     913                 :            :                 rxq->rxq_stats.rx_free_mbuf_bytes++;
     914                 :            : #endif
     915         [ #  # ]:          0 :                 if (!rxm)
     916                 :          0 :                         head_mbuf->next = cur_mbuf;
     917                 :            :                 else
     918                 :          0 :                         rxm->next = cur_mbuf;
     919                 :            : 
     920                 :            :                 rxm = cur_mbuf;
     921                 :            :         }
     922                 :          0 : }
     923                 :            : 
     924                 :            : int
     925                 :          0 : hinic3_start_all_rqs(struct rte_eth_dev *eth_dev)
     926                 :            : {
     927                 :            :         struct hinic3_nic_dev *nic_dev = NULL;
     928                 :            :         struct hinic3_rxq *rxq = NULL;
     929                 :            :         int err = 0;
     930                 :            :         int i;
     931                 :            : 
     932                 :          0 :         nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
     933                 :            : 
     934         [ #  # ]:          0 :         for (i = 0; i < nic_dev->num_rqs; i++) {
     935                 :          0 :                 rxq = eth_dev->data->rx_queues[i];
     936                 :          0 :                 hinic3_add_rq_to_rx_queue_list(nic_dev, rxq->q_id);
     937                 :          0 :                 err = hinic3_rearm_rxq_mbuf(rxq);
     938         [ #  # ]:          0 :                 if (err) {
     939                 :          0 :                         PMD_DRV_LOG(ERR,
     940                 :            :                                     "Fail to alloc mbuf for Rx queue %d, qid = %u, need_mbuf: %d",
     941                 :            :                                     i, rxq->q_id, rxq->q_depth);
     942                 :          0 :                         goto out;
     943                 :            :                 }
     944                 :          0 :                 hinic3_dev_rx_queue_intr_enable(eth_dev, rxq->q_id);
     945         [ #  # ]:          0 :                 if (rxq->rx_deferred_start)
     946                 :          0 :                         continue;
     947                 :          0 :                 eth_dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STARTED;
     948                 :            :         }
     949                 :            : 
     950         [ #  # ]:          0 :         if (nic_dev->rss_state == HINIC3_RSS_ENABLE) {
     951                 :          0 :                 err = hinic3_refill_indir_rqid(rxq);
     952         [ #  # ]:          0 :                 if (err) {
     953                 :          0 :                         PMD_DRV_LOG(ERR,
     954                 :            :                                     "Refill rq to indirect table failed, eth_dev:%s, queue_idx:%d, err:%d",
     955                 :            :                                     rxq->nic_dev->dev_name, rxq->q_id, err);
     956                 :          0 :                         goto out;
     957                 :            :                 }
     958                 :            :         }
     959                 :            : 
     960                 :            :         return 0;
     961                 :          0 : out:
     962         [ #  # ]:          0 :         for (i = 0; i < nic_dev->num_rqs; i++) {
     963                 :          0 :                 rxq = eth_dev->data->rx_queues[i];
     964                 :          0 :                 hinic3_remove_rq_from_rx_queue_list(nic_dev, rxq->q_id);
     965                 :          0 :                 hinic3_free_rxq_mbufs(rxq);
     966                 :          0 :                 hinic3_dev_rx_queue_intr_disable(eth_dev, rxq->q_id);
     967                 :          0 :                 eth_dev->data->rx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
     968                 :            :         }
     969                 :            :         return err;
     970                 :            : }
     971                 :            : 
     972                 :            : bool
     973         [ #  # ]:          0 : hinic3_rx_separate_cqe_done(struct hinic3_rxq *rxq, volatile struct hinic3_rq_cqe **rx_cqe)
     974                 :            : {
     975                 :            :         volatile struct hinic3_rq_cqe *cqe = NULL;
     976                 :            :         uint16_t sw_ci;
     977                 :            :         uint32_t status;
     978                 :            : 
     979                 :            :         sw_ci = hinic3_get_rq_local_ci(rxq);
     980                 :          0 :         *rx_cqe = &rxq->rx_cqe[sw_ci];
     981                 :            :         cqe = *rx_cqe;
     982                 :            : 
     983                 :          0 :         status = hinic3_hw_cpu32((uint32_t)(rte_atomic_load_explicit(&cqe->status,
     984                 :            :                                                                      rte_memory_order_acquire)));
     985         [ #  # ]:          0 :         if (!HINIC3_GET_RX_DONE(status))
     986                 :          0 :                 return false;
     987                 :            : 
     988                 :            :         return true;
     989                 :            : }
     990                 :            : 
     991                 :            : bool
     992                 :          0 : hinic3_rx_integrated_cqe_done(struct hinic3_rxq *rxq, volatile struct hinic3_rq_cqe **rx_cqe)
     993                 :            : {
     994                 :            :         struct hinic3_rq_ci_wb rq_ci;
     995                 :            :         struct rte_mbuf *rxm = NULL;
     996                 :            :         uint16_t sw_ci, hw_ci;
     997                 :            :         uint32_t val;
     998                 :            : 
     999                 :            :         sw_ci = hinic3_get_rq_local_ci(rxq);
    1000                 :          0 :         val = rte_read32(&rxq->rq_ci->dw1.value);
    1001                 :            :         rq_ci.dw1.value = hinic3_hw_cpu32(val);
    1002                 :            :         hw_ci = rq_ci.dw1.bs.hw_ci;
    1003                 :            : 
    1004         [ #  # ]:          0 :         if (hw_ci == sw_ci)
    1005                 :            :                 return false;
    1006                 :            : 
    1007         [ #  # ]:          0 :         rxm = rxq->rx_info[sw_ci].mbuf;
    1008                 :            : 
    1009                 :          0 :         *rx_cqe = (volatile struct hinic3_rq_cqe *)rte_mbuf_data_addr_default(rxm);
    1010                 :            : 
    1011                 :          0 :         return true;
    1012                 :            : }
    1013                 :            : 
    1014                 :            : void
    1015                 :          0 : hinic3_rx_get_cqe_info(struct hinic3_rxq *rxq __rte_unused, volatile struct hinic3_rq_cqe *rx_cqe,
    1016                 :            :                        struct hinic3_cqe_info *cqe_info)
    1017                 :            : {
    1018                 :          0 :         uint32_t dw0 = hinic3_hw_cpu32(rx_cqe->status);
    1019                 :          0 :         uint32_t dw1 = hinic3_hw_cpu32(rx_cqe->vlan_len);
    1020                 :          0 :         uint32_t dw2 = hinic3_hw_cpu32(rx_cqe->offload_type);
    1021                 :          0 :         uint32_t dw3 = hinic3_hw_cpu32(rx_cqe->hash_val);
    1022                 :            : 
    1023                 :          0 :         cqe_info->lro_num = RQ_CQE_STATUS_GET(dw0, NUM_LRO);
    1024                 :          0 :         cqe_info->csum_err = RQ_CQE_STATUS_GET(dw0, CSUM_ERR);
    1025                 :            : 
    1026                 :          0 :         cqe_info->pkt_len = RQ_CQE_SGE_GET(dw1, LEN);
    1027                 :          0 :         cqe_info->vlan_tag = RQ_CQE_SGE_GET(dw1, VLAN);
    1028                 :            : 
    1029                 :          0 :         cqe_info->ptype = HINIC3_GET_RX_PTYPE_OFFLOAD(dw0);
    1030                 :          0 :         cqe_info->vlan_offload = RQ_CQE_OFFOLAD_TYPE_GET(dw2, VLAN_EN);
    1031                 :          0 :         cqe_info->rss_type = RQ_CQE_OFFOLAD_TYPE_GET(dw2, RSS_TYPE);
    1032                 :          0 :         cqe_info->rss_hash_value = dw3;
    1033                 :          0 : }
    1034                 :            : 
    1035                 :            : void
    1036                 :          0 : hinic3_rx_get_compact_cqe_info(struct hinic3_rxq *rxq, volatile struct hinic3_rq_cqe *rx_cqe,
    1037                 :            :                                struct hinic3_cqe_info *cqe_info)
    1038                 :            : {
    1039                 :            :         uint32_t dw0, dw1, dw2;
    1040                 :            : 
    1041         [ #  # ]:          0 :         if (rxq->wqe_type != HINIC3_COMPACT_RQ_WQE) {
    1042                 :          0 :                 dw0 = hinic3_hw_cpu32(rx_cqe->status);
    1043                 :          0 :                 dw1 = hinic3_hw_cpu32(rx_cqe->vlan_len);
    1044                 :          0 :                 dw2 = hinic3_hw_cpu32(rx_cqe->offload_type);
    1045                 :            :         } else {
    1046                 :            :                 /* Compact Rx CQE mode integrates cqe with packet in big endian way. */
    1047                 :          0 :                 dw0 = rte_be_to_cpu_32(rx_cqe->status);
    1048                 :          0 :                 dw1 = rte_be_to_cpu_32(rx_cqe->vlan_len);
    1049                 :          0 :                 dw2 = rte_be_to_cpu_32(rx_cqe->offload_type);
    1050                 :            :         }
    1051                 :            : 
    1052                 :          0 :         cqe_info->cqe_type = HINIC3_RQ_COMPACT_CQE_STATUS_GET(dw0, CQE_TYPE);
    1053                 :          0 :         cqe_info->csum_err = HINIC3_RQ_COMPACT_CQE_STATUS_GET(dw0, CSUM_ERR);
    1054                 :          0 :         cqe_info->vlan_offload = HINIC3_RQ_COMPACT_CQE_STATUS_GET(dw0, VLAN_EN);
    1055                 :          0 :         cqe_info->cqe_len = HINIC3_RQ_COMPACT_CQE_STATUS_GET(dw0, CQE_LEN);
    1056                 :          0 :         cqe_info->pkt_len = HINIC3_RQ_COMPACT_CQE_STATUS_GET(dw0, PKT_LEN);
    1057                 :          0 :         cqe_info->ts_flag = HINIC3_RQ_COMPACT_CQE_STATUS_GET(dw0, TS_FLAG);
    1058                 :          0 :         cqe_info->ptype = HINIC3_RQ_COMPACT_CQE_STATUS_GET(dw0, PTYPE);
    1059                 :          0 :         cqe_info->rss_hash_value = dw1;
    1060                 :            : 
    1061         [ #  # ]:          0 :         if (cqe_info->cqe_len == HINIC3_RQ_COMPACT_CQE_16BYTE) {
    1062                 :          0 :                 cqe_info->lro_num = HINIC3_RQ_COMPACT_CQE_OFFLOAD_GET(dw2, NUM_LRO);
    1063                 :          0 :                 cqe_info->vlan_tag = HINIC3_RQ_COMPACT_CQE_OFFLOAD_GET(dw2, VLAN);
    1064                 :            :         }
    1065                 :            : 
    1066         [ #  # ]:          0 :         if (cqe_info->cqe_type == HINIC3_RQ_CQE_INTEGRATE)
    1067         [ #  # ]:          0 :                 cqe_info->data_offset =
    1068                 :            :                                 (cqe_info->cqe_len == HINIC3_RQ_COMPACT_CQE_16BYTE) ? 16 : 8;
    1069                 :          0 : }
    1070                 :            : 
    1071                 :            : #define HINIC3_RX_EMPTY_THRESHOLD 3
    1072                 :            : uint16_t
    1073                 :          0 : hinic3_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
    1074                 :            : {
    1075                 :            :         struct hinic3_rxq *rxq = rx_queue;
    1076                 :          0 :         struct hinic3_nic_dev *nic_dev = rxq->nic_dev;
    1077                 :            :         struct hinic3_rx_info *rx_info = NULL;
    1078                 :          0 :         volatile struct hinic3_rq_cqe *rx_cqe = NULL;
    1079                 :          0 :         struct hinic3_cqe_info cqe_info = {0};
    1080                 :            :         struct rte_mbuf *rxm = NULL;
    1081                 :            :         uint16_t sw_ci, rx_buf_len, pkts = 0;
    1082                 :            :         uint32_t pkt_len;
    1083                 :            :         uint64_t rx_bytes = 0;
    1084                 :            : 
    1085                 :            : #ifdef HINIC3_XSTAT_PROF_RX
    1086                 :            :         uint64_t t1 = rte_get_tsc_cycles();
    1087                 :            :         uint64_t t2;
    1088                 :            : #endif
    1089         [ #  # ]:          0 :         if (((rte_get_timer_cycles() - rxq->rxq_stats.tsc) < rxq->wait_time_cycle) &&
    1090         [ #  # ]:          0 :             rxq->rxq_stats.empty >= HINIC3_RX_EMPTY_THRESHOLD)
    1091                 :          0 :                 goto out;
    1092                 :            : 
    1093                 :            :         sw_ci = hinic3_get_rq_local_ci(rxq);
    1094                 :            : 
    1095         [ #  # ]:          0 :         while (pkts < nb_pkts) {
    1096                 :          0 :                 rx_cqe = &rxq->rx_cqe[sw_ci];
    1097         [ #  # ]:          0 :                 if (!nic_dev->rx_ops->nic_rx_cqe_done(rxq, &rx_cqe)) {
    1098                 :          0 :                         rxq->rxq_stats.empty++;
    1099                 :          0 :                         break;
    1100                 :            :                 }
    1101                 :            : 
    1102                 :          0 :                 nic_dev->rx_ops->nic_rx_get_cqe_info(rxq, rx_cqe, &cqe_info);
    1103                 :            : 
    1104                 :          0 :                 pkt_len = cqe_info.pkt_len;
    1105                 :            :                 /*
    1106                 :            :                  * Compact Rx CQE mode integrates cqe with packet,
    1107                 :            :                  * so mbuf length needs to remove the length of cqe.
    1108                 :            :                  */
    1109                 :          0 :                 rx_buf_len = rxq->buf_len - cqe_info.data_offset;
    1110                 :            : 
    1111                 :          0 :                 rx_info = &rxq->rx_info[sw_ci];
    1112                 :          0 :                 rxm = rx_info->mbuf;
    1113                 :            : 
    1114                 :            :                 /* 1. Next ci point and prefetch. */
    1115                 :          0 :                 sw_ci++;
    1116                 :          0 :                 sw_ci &= rxq->q_mask;
    1117                 :            : 
    1118                 :            :                 /* 2. Prefetch next mbuf first 64B. */
    1119                 :          0 :                 rte_prefetch0(rxq->rx_info[sw_ci].mbuf);
    1120                 :            : 
    1121                 :            :                 /* 3. Jumbo frame process. */
    1122         [ #  # ]:          0 :                 if (likely(pkt_len <= rx_buf_len)) {
    1123                 :          0 :                         rxm->data_len = (uint16_t)pkt_len;
    1124                 :          0 :                         rxm->pkt_len = pkt_len;
    1125                 :            :                         hinic3_update_rq_local_ci(rxq, 1);
    1126                 :            :                 } else {
    1127                 :          0 :                         rxm->data_len = rx_buf_len;
    1128                 :          0 :                         rxm->pkt_len = rx_buf_len;
    1129                 :            : 
    1130                 :            :                         /*
    1131                 :            :                          * If receive jumbo, updating ci will be done by
    1132                 :            :                          * hinic3_recv_jumbo_pkt function.
    1133                 :            :                          */
    1134                 :            :                         hinic3_update_rq_local_ci(rxq, 1);
    1135                 :          0 :                         hinic3_recv_jumbo_pkt(rxq, rxm, pkt_len - rx_buf_len);
    1136                 :            :                         sw_ci = hinic3_get_rq_local_ci(rxq);
    1137                 :            :                 }
    1138                 :            : 
    1139                 :          0 :                 rxm->data_off = RTE_PKTMBUF_HEADROOM + cqe_info.data_offset;
    1140                 :          0 :                 rxm->port = rxq->port_id;
    1141                 :            : 
    1142                 :            :                 /* 4. Rx checksum offload. */
    1143                 :          0 :                 rxm->ol_flags |= hinic3_rx_csum(cqe_info.csum_err, rxq);
    1144                 :            : 
    1145                 :            :                 /* 5. Vlan offload. */
    1146         [ #  # ]:          0 :                 rxm->ol_flags |= hinic3_rx_vlan(cqe_info.vlan_offload, cqe_info.vlan_tag,
    1147                 :            :                                                 &rxm->vlan_tci);
    1148                 :            : 
    1149                 :            :                 /* 6. RSS. */
    1150         [ #  # ]:          0 :                 rxm->ol_flags |= hinic3_rx_rss_hash(cqe_info.rss_type, cqe_info.rss_hash_value,
    1151                 :            :                                                     &rxm->hash.rss);
    1152                 :            :                 /* 8. LRO. */
    1153         [ #  # ]:          0 :                 if (unlikely(cqe_info.lro_num != 0)) {
    1154                 :          0 :                         rxm->ol_flags |= HINIC3_PKT_RX_LRO;
    1155                 :          0 :                         rxm->tso_segsz = pkt_len / cqe_info.lro_num;
    1156                 :            :                 }
    1157                 :            : 
    1158                 :          0 :                 rx_cqe->status = 0;
    1159                 :            : 
    1160                 :          0 :                 rx_bytes += pkt_len;
    1161                 :          0 :                 rx_pkts[pkts++] = rxm;
    1162                 :            :         }
    1163                 :            : 
    1164         [ #  # ]:          0 :         if (pkts) {
    1165                 :            :                 /* Update packet stats. */
    1166                 :          0 :                 rxq->rxq_stats.packets += pkts;
    1167                 :          0 :                 rxq->rxq_stats.bytes += rx_bytes;
    1168                 :          0 :                 rxq->rxq_stats.empty = 0;
    1169                 :            : #ifdef HINIC3_XSTAT_MBUF_USE
    1170                 :            :                 rxq->rxq_stats.rx_free_mbuf_bytes += pkts;
    1171                 :            : #endif
    1172                 :            :         }
    1173                 :          0 :         rxq->rxq_stats.burst_pkts = pkts;
    1174                 :          0 :         rxq->rxq_stats.tsc = rte_get_timer_cycles();
    1175                 :          0 : out:
    1176                 :            :         /* 10. Rearm mbuf to rxq. */
    1177                 :          0 :         hinic3_rearm_rxq_mbuf(rxq);
    1178                 :            : 
    1179                 :            : #ifdef HINIC3_XSTAT_PROF_RX
    1180                 :            :         /* Do profiling stats. */
    1181                 :            :         t2 = rte_get_tsc_cycles();
    1182                 :            :         rxq->rxq_stats.app_tsc = t1 - rxq->prof_rx_end_tsc;
    1183                 :            :         rxq->prof_rx_end_tsc = t2;
    1184                 :            :         rxq->rxq_stats.pmd_tsc = t2 - t1;
    1185                 :            : #endif
    1186                 :            : 
    1187                 :          0 :         return pkts;
    1188                 :            : }

Generated by: LCOV version 1.14