LCOV - code coverage report
Current view: top level - drivers/net/rnp - rnp_rxtx.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 887 0.0 %
Date: 2025-07-01 21:32:37 Functions: 0 39 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 511 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(C) 2023 Mucse IC Design Ltd.
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <stdint.h>
       6                 :            : 
       7                 :            : #include <rte_ethdev.h>
       8                 :            : #include <rte_memzone.h>
       9                 :            : #include <rte_mbuf.h>
      10                 :            : #include <rte_malloc.h>
      11                 :            : 
      12                 :            : #include "base/rnp_bdq_if.h"
      13                 :            : #include "base/rnp_dma_regs.h"
      14                 :            : #include "rnp_rxtx.h"
      15                 :            : #include "rnp_logs.h"
      16                 :            : #include "rnp.h"
      17                 :            : 
      18                 :            : static void rnp_tx_queue_release_mbuf(struct rnp_tx_queue *txq);
      19                 :            : static void rnp_tx_queue_sw_reset(struct rnp_tx_queue *txq);
      20                 :            : static void rnp_tx_queue_release(void *_txq);
      21                 :            : 
      22                 :            : static __rte_always_inline phys_addr_t
      23                 :            : rnp_get_dma_addr(struct rnp_queue_attr *attr, struct rte_mbuf *mbuf)
      24                 :            : {
      25                 :            :         phys_addr_t dma_addr;
      26                 :            : 
      27                 :          0 :         dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova(mbuf));
      28   [ #  #  #  #  :          0 :         if (attr->sriov_st)
             #  #  #  # ]
      29                 :          0 :                 dma_addr |= (attr->sriov_st << 56);
      30                 :            : 
      31                 :            :         return dma_addr;
      32                 :            : }
      33                 :            : 
      34                 :          0 : static void rnp_rx_queue_release_mbuf(struct rnp_rx_queue *rxq)
      35                 :            : {
      36                 :            :         uint16_t i;
      37                 :            : 
      38         [ #  # ]:          0 :         if (!rxq)
      39                 :            :                 return;
      40                 :            : 
      41         [ #  # ]:          0 :         if (rxq->sw_ring) {
      42         [ #  # ]:          0 :                 for (i = 0; i < rxq->attr.nb_desc; i++) {
      43         [ #  # ]:          0 :                         if (rxq->sw_ring[i].mbuf)
      44                 :            :                                 rte_pktmbuf_free_seg(rxq->sw_ring[i].mbuf);
      45                 :            :                 }
      46                 :          0 :                 memset(rxq->sw_ring, 0,
      47                 :          0 :                                 sizeof(rxq->sw_ring[0]) * rxq->attr.nb_desc);
      48                 :            :         }
      49                 :            : }
      50                 :            : 
      51                 :          0 : static void rnp_rx_queue_release(void *_rxq)
      52                 :            : {
      53                 :            :         struct rnp_rx_queue *rxq = (struct rnp_rx_queue *)_rxq;
      54                 :            : 
      55                 :          0 :         PMD_INIT_FUNC_TRACE();
      56                 :            : 
      57         [ #  # ]:          0 :         if (rxq) {
      58                 :          0 :                 rnp_rx_queue_release_mbuf(rxq);
      59                 :          0 :                 rte_memzone_free(rxq->rz);
      60                 :          0 :                 rte_free(rxq->sw_ring);
      61                 :          0 :                 rte_free(rxq);
      62                 :            :         }
      63                 :          0 : }
      64                 :            : 
      65                 :            : static int
      66                 :            : rnp_tx_queue_reset(struct rnp_eth_port *port,
      67                 :            :                    struct rnp_tx_queue *txq)
      68                 :            : {
      69                 :          0 :         struct rnp_hw *hw = port->hw;
      70                 :            : 
      71                 :          0 :         rnp_reset_hw_txq_op(hw, txq);
      72                 :            : 
      73                 :            :         return 0;
      74                 :            : }
      75                 :            : 
      76                 :            : static int
      77                 :          0 : rnp_rx_queue_reset(struct rnp_eth_port *port,
      78                 :            :                    struct rnp_rx_queue *rxq)
      79                 :            : {
      80                 :          0 :         struct rte_eth_dev_data *data = port->eth_dev->data;
      81                 :          0 :         struct rnp_eth_adapter *adapter = port->hw->back;
      82                 :            :         struct rte_eth_dev *dev = port->eth_dev;
      83                 :          0 :         struct rnp_rxq_reset_res res = {0};
      84                 :          0 :         uint16_t qidx = rxq->attr.queue_id;
      85                 :            :         struct rnp_tx_queue *txq = NULL;
      86                 :            :         struct rte_eth_txconf def_conf;
      87                 :            :         struct rnp_hw *hw = port->hw;
      88                 :            :         struct rte_mbuf *m_mbuf[2];
      89                 :            :         bool tx_origin_e = false;
      90                 :            :         bool tx_new = false;
      91                 :            :         uint16_t index;
      92                 :            :         int err = 0;
      93                 :            : 
      94                 :          0 :         index = rxq->attr.index;
      95                 :            :         /* disable eth send pkts to this ring */
      96                 :          0 :         rxq->rx_tail = RNP_E_REG_RD(hw, RNP_RXQ_HEAD(index));
      97         [ #  # ]:          0 :         if (!rxq->rx_tail)
      98                 :            :                 return 0;
      99   [ #  #  #  # ]:          0 :         if (qidx < data->nb_tx_queues && data->tx_queues[qidx]) {
     100                 :            :                 txq = (struct rnp_tx_queue *)data->tx_queues[qidx];
     101                 :            :         } else {
     102                 :            :                 /* tx queues has been release or txq num less than rxq num */
     103                 :          0 :                 def_conf.tx_deferred_start = true;
     104                 :          0 :                 def_conf.tx_free_thresh = 32;
     105                 :          0 :                 def_conf.tx_rs_thresh = 32;
     106         [ #  # ]:          0 :                 if (dev->dev_ops->tx_queue_setup)
     107                 :          0 :                         err = dev->dev_ops->tx_queue_setup(dev, qidx,
     108                 :          0 :                                 rxq->attr.nb_desc,
     109                 :          0 :                                 dev->data->numa_node, &def_conf);
     110         [ #  # ]:          0 :                 if (err) {
     111                 :          0 :                         RNP_PMD_ERR("rxq[%u] reset pair txq setup fail", qidx);
     112                 :          0 :                         return err;
     113                 :            :                 }
     114                 :          0 :                 txq = port->tx_queues[qidx];
     115                 :            :                 tx_new = true;
     116                 :            :         }
     117   [ #  #  #  # ]:          0 :         if (unlikely(rte_mempool_get_bulk(adapter->reset_pool, (void *)m_mbuf,
     118                 :            :                                         2) < 0)) {
     119                 :          0 :                 RNP_PMD_LOG(WARNING, "port[%u] reset rx queue[%u] failed "
     120                 :            :                                 "because mbuf alloc failed",
     121                 :            :                                 data->port_id, qidx);
     122                 :          0 :                 return -ENOMEM;
     123                 :            :         }
     124                 :          0 :         rnp_rxq_flow_disable(hw, index);
     125                 :          0 :         tx_origin_e = txq->txq_started;
     126                 :          0 :         rte_io_wmb();
     127                 :          0 :         txq->txq_started = false;
     128         [ #  # ]:          0 :         rte_mbuf_refcnt_set(m_mbuf[0], 1);
     129                 :          0 :         rte_mbuf_refcnt_set(m_mbuf[1], 1);
     130                 :          0 :         m_mbuf[0]->data_off = RTE_PKTMBUF_HEADROOM;
     131                 :          0 :         m_mbuf[1]->data_off = RTE_PKTMBUF_HEADROOM;
     132         [ #  # ]:          0 :         res.eth_hdr = rte_pktmbuf_mtod(m_mbuf[0], uint8_t *);
     133         [ #  # ]:          0 :         res.rx_pkt_addr = rnp_get_dma_addr(&rxq->attr, m_mbuf[1]);
     134                 :          0 :         res.tx_pkt_addr = rnp_get_dma_addr(&txq->attr, m_mbuf[0]);
     135                 :          0 :         rnp_reset_hw_rxq_op(hw, rxq, txq, &res);
     136         [ #  # ]:          0 :         if (tx_new)
     137                 :          0 :                 rnp_tx_queue_release(txq);
     138                 :            :         else
     139                 :          0 :                 txq->tx_tail = RNP_E_REG_RD(hw, RNP_TXQ_HEAD(index));
     140         [ #  # ]:          0 :         if (!tx_new) {
     141         [ #  # ]:          0 :                 if (txq->tx_tail) {
     142                 :          0 :                         rnp_tx_queue_release_mbuf(txq);
     143                 :            :                         rnp_tx_queue_reset(port, txq);
     144                 :          0 :                         rnp_tx_queue_sw_reset(txq);
     145                 :            :                 }
     146                 :          0 :                 txq->txq_started = tx_origin_e;
     147                 :            :         }
     148         [ #  # ]:          0 :         rte_mempool_put_bulk(adapter->reset_pool, (void **)m_mbuf, 2);
     149                 :          0 :         rnp_rxq_flow_enable(hw, index);
     150                 :          0 :         rte_io_wmb();
     151                 :          0 :         RNP_E_REG_WR(hw, RNP_RXQ_LEN(index), rxq->attr.nb_desc);
     152                 :            : 
     153                 :          0 :         return 0;
     154                 :            : }
     155                 :            : 
     156                 :            : static int
     157                 :          0 : rnp_alloc_rxbdr(struct rte_eth_dev *dev,
     158                 :            :                 struct rnp_rx_queue *rxq,
     159                 :            :                 uint16_t nb_rx_desc, int socket_id)
     160                 :            : {
     161                 :            :         const struct rte_memzone *rz = NULL;
     162                 :            :         uint32_t size = 0;
     163                 :            : 
     164                 :          0 :         size = (nb_rx_desc + RNP_RX_MAX_BURST_SIZE) *
     165                 :            :                 sizeof(struct rnp_rxsw_entry);
     166                 :          0 :         rxq->sw_ring = rte_zmalloc_socket("rx_swring", size,
     167                 :            :                         RTE_CACHE_LINE_SIZE, socket_id);
     168         [ #  # ]:          0 :         if (rxq->sw_ring == NULL)
     169                 :            :                 return -ENOMEM;
     170                 :          0 :         rz = rte_eth_dma_zone_reserve(dev, "rx_ring", rxq->attr.queue_id,
     171                 :            :                         RNP_RX_MAX_RING_SZ, RNP_BD_RING_ALIGN, socket_id);
     172         [ #  # ]:          0 :         if (rz == NULL) {
     173                 :          0 :                 rte_free(rxq->sw_ring);
     174                 :          0 :                 rxq->sw_ring = NULL;
     175                 :          0 :                 return -ENOMEM;
     176                 :            :         }
     177                 :          0 :         memset(rz->addr, 0, RNP_RX_MAX_RING_SZ);
     178                 :          0 :         rxq->rx_bdr = (struct rnp_rx_desc *)rz->addr;
     179                 :          0 :         rxq->ring_phys_addr = rz->iova;
     180                 :          0 :         rxq->rz = rz;
     181                 :            : 
     182                 :          0 :         return 0;
     183                 :            : }
     184                 :            : 
     185                 :            : static void
     186                 :            : rnp_rx_queue_sw_reset(struct rnp_rx_queue *rxq)
     187                 :            : {
     188                 :            :         uint32_t size = 0;
     189                 :            :         uint32_t idx = 0;
     190                 :            : 
     191                 :          0 :         rxq->nb_rx_free = rxq->attr.nb_desc - 1;
     192                 :          0 :         rxq->rx_tail = 0;
     193                 :            : 
     194                 :          0 :         size = rxq->attr.nb_desc + RNP_RX_MAX_BURST_SIZE;
     195   [ #  #  #  # ]:          0 :         for (idx = 0; idx < size * sizeof(struct rnp_rx_desc); idx++)
     196                 :          0 :                 ((volatile char *)rxq->rx_bdr)[idx] = 0;
     197                 :            : }
     198                 :            : 
     199                 :            : 
     200                 :          0 : int rnp_rx_queue_setup(struct rte_eth_dev *eth_dev,
     201                 :            :                        uint16_t qidx,
     202                 :            :                        uint16_t nb_rx_desc,
     203                 :            :                        unsigned int socket_id,
     204                 :            :                        const struct rte_eth_rxconf *rx_conf,
     205                 :            :                        struct rte_mempool *mb_pool)
     206                 :            : {
     207                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     208                 :            :         struct rte_eth_dev_data *data = eth_dev->data;
     209                 :          0 :         struct rnp_hw *hw = port->hw;
     210                 :            :         struct rnp_rx_queue *rxq = NULL;
     211                 :            :         uint64_t offloads;
     212                 :            :         int err = 0;
     213                 :            : 
     214                 :          0 :         RNP_PMD_LOG(INFO, "RXQ[%u] setup nb-desc %u", qidx, nb_rx_desc);
     215                 :          0 :         offloads = rx_conf->offloads | data->dev_conf.rxmode.offloads;
     216         [ #  # ]:          0 :         if (rte_is_power_of_2(nb_rx_desc) == 0) {
     217                 :          0 :                 RNP_PMD_ERR("Rxq Desc Num Must power of 2");
     218                 :          0 :                 return -EINVAL;
     219                 :            :         }
     220         [ #  # ]:          0 :         if (nb_rx_desc > RNP_MAX_BD_COUNT)
     221                 :            :                 return -EINVAL;
     222                 :            :         /* check whether queue has been created if so release it */
     223         [ #  # ]:          0 :         if (qidx < data->nb_rx_queues &&
     224         [ #  # ]:          0 :                         data->rx_queues[qidx] != NULL) {
     225                 :          0 :                 rnp_rx_queue_release(data->rx_queues[qidx]);
     226                 :          0 :                 data->rx_queues[qidx] = NULL;
     227                 :            :         }
     228                 :          0 :         rxq = rte_zmalloc_socket("rnp_rxq", sizeof(struct rnp_rx_queue),
     229                 :            :                         RTE_CACHE_LINE_SIZE, socket_id);
     230         [ #  # ]:          0 :         if (rxq == NULL) {
     231                 :          0 :                 RNP_PMD_ERR("Failed to allocate rx ring memory");
     232                 :          0 :                 return -ENOMEM;
     233                 :            :         }
     234                 :          0 :         rxq->rx_offloads = offloads;
     235                 :            :         /* queue hw info */
     236                 :          0 :         rxq->attr.index = rnp_get_dma_ring_index(port, qidx);
     237                 :          0 :         rxq->attr.nb_desc_mask = nb_rx_desc - 1;
     238                 :          0 :         rxq->attr.nb_desc = nb_rx_desc;
     239                 :          0 :         rxq->attr.queue_id = qidx;
     240                 :            :         /* queue map to port hw info */
     241                 :          0 :         rxq->attr.vf_num = hw->mbx.vf_num;
     242                 :          0 :         rxq->attr.sriov_st = hw->mbx.sriov_st;
     243                 :          0 :         rxq->attr.lane_id = port->attr.nr_lane;
     244                 :          0 :         rxq->attr.port_id = data->port_id;
     245                 :            : #define RNP_RXQ_BD_TIMEOUT   (5000000)
     246         [ #  # ]:          0 :         rxq->nodesc_tm_thresh = RNP_RXQ_BD_TIMEOUT;
     247                 :          0 :         rxq->rx_buf_len = (uint16_t)(rte_pktmbuf_data_room_size(mb_pool) -
     248                 :            :                         RTE_PKTMBUF_HEADROOM);
     249                 :          0 :         rxq->mb_pool = mb_pool;
     250                 :          0 :         err = rnp_alloc_rxbdr(eth_dev, rxq, nb_rx_desc, socket_id);
     251         [ #  # ]:          0 :         if (err)
     252                 :          0 :                 goto fail;
     253                 :          0 :         RNP_PMD_LOG(INFO, "PF[%u] dev:[%u] hw-lane[%u] rx_qid[%u] "
     254                 :            :                         "hw_ridx %u socket %u",
     255                 :            :                         hw->mbx.pf_num, rxq->attr.port_id,
     256                 :            :                         rxq->attr.lane_id, qidx,
     257                 :            :                         rxq->attr.index, socket_id);
     258         [ #  # ]:          0 :         rxq->rx_free_thresh = (rx_conf->rx_free_thresh) ?
     259                 :            :                 rx_conf->rx_free_thresh : RNP_DEFAULT_RX_FREE_THRESH;
     260         [ #  # ]:          0 :         rxq->pthresh = (rx_conf->rx_thresh.pthresh) ?
     261                 :            :                 rx_conf->rx_thresh.pthresh : RNP_RX_DESC_FETCH_TH;
     262         [ #  # ]:          0 :         rxq->pburst = (rx_conf->rx_thresh.hthresh) ?
     263                 :            :                 rx_conf->rx_thresh.hthresh : RNP_RX_DESC_FETCH_BURST;
     264                 :          0 :         rnp_setup_rxbdr(hw, rxq);
     265         [ #  # ]:          0 :         if (rxq->rx_tail) {
     266                 :          0 :                 err = rnp_rx_queue_reset(port, rxq);
     267         [ #  # ]:          0 :                 if (err) {
     268                 :          0 :                         RNP_PMD_ERR("PF[%u] dev:[%u] lane[%u] rx_qid[%u] "
     269                 :            :                                     "hw_ridx[%u] bdr setup failed",
     270                 :            :                                     hw->mbx.pf_num, rxq->attr.port_id,
     271                 :            :                                     rxq->attr.lane_id, qidx, rxq->attr.index);
     272                 :          0 :                         goto rxbd_setup_failed;
     273                 :            :                 }
     274                 :            :         }
     275                 :            :         rnp_rx_queue_sw_reset(rxq);
     276                 :          0 :         data->rx_queues[qidx] = rxq;
     277                 :            : 
     278                 :          0 :         return 0;
     279                 :            : rxbd_setup_failed:
     280                 :          0 :         rte_memzone_free(rxq->rz);
     281                 :          0 : fail:
     282                 :          0 :         rte_free(rxq);
     283                 :            : 
     284                 :          0 :         return err;
     285                 :            : }
     286                 :            : 
     287                 :          0 : static void rnp_tx_queue_release_mbuf(struct rnp_tx_queue *txq)
     288                 :            : {
     289                 :            :         uint16_t i;
     290                 :            : 
     291         [ #  # ]:          0 :         if (!txq)
     292                 :            :                 return;
     293         [ #  # ]:          0 :         if (txq->sw_ring) {
     294         [ #  # ]:          0 :                 for (i = 0; i < txq->attr.nb_desc; i++) {
     295         [ #  # ]:          0 :                         if (txq->sw_ring[i].mbuf) {
     296                 :            :                                 rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
     297                 :          0 :                                 txq->sw_ring[i].mbuf = NULL;
     298                 :            :                         }
     299                 :            :                 }
     300                 :            :         }
     301                 :            : }
     302                 :            : 
     303                 :          0 : static void rnp_tx_queue_release(void *_txq)
     304                 :            : {
     305                 :            :         struct rnp_tx_queue *txq = (struct rnp_tx_queue *)_txq;
     306                 :            : 
     307                 :          0 :         PMD_INIT_FUNC_TRACE();
     308                 :            : 
     309         [ #  # ]:          0 :         if (txq) {
     310                 :          0 :                 rnp_tx_queue_release_mbuf(txq);
     311                 :            : 
     312                 :          0 :                 rte_memzone_free(txq->rz);
     313                 :          0 :                 rte_free(txq->sw_ring);
     314                 :          0 :                 rte_free(txq);
     315                 :            :         }
     316                 :          0 : }
     317                 :            : 
     318                 :            : void
     319                 :          0 : rnp_dev_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
     320                 :            : {
     321                 :          0 :         rnp_rx_queue_release(dev->data->rx_queues[qid]);
     322                 :          0 : }
     323                 :            : 
     324                 :            : void
     325                 :          0 : rnp_dev_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid)
     326                 :            : {
     327                 :          0 :         rnp_tx_queue_release(dev->data->tx_queues[qid]);
     328                 :          0 : }
     329                 :            : 
     330                 :          0 : static int rnp_alloc_txbdr(struct rte_eth_dev *dev,
     331                 :            :                            struct rnp_tx_queue *txq,
     332                 :            :                            uint16_t nb_desc, int socket_id)
     333                 :            : {
     334                 :            :         const struct rte_memzone *rz = NULL;
     335                 :            :         int size;
     336                 :            : 
     337                 :          0 :         size = nb_desc * sizeof(struct rnp_txsw_entry);
     338                 :          0 :         txq->sw_ring = rte_zmalloc_socket("tx_swq", size,
     339                 :            :                         RTE_CACHE_LINE_SIZE, socket_id);
     340         [ #  # ]:          0 :         if (txq->sw_ring == NULL)
     341                 :            :                 return -ENOMEM;
     342                 :            : 
     343                 :          0 :         rz = rte_eth_dma_zone_reserve(dev, "tx_ring", txq->attr.queue_id,
     344                 :            :                         RNP_TX_MAX_RING_SZ, RNP_BD_RING_ALIGN, socket_id);
     345         [ #  # ]:          0 :         if (rz == NULL) {
     346                 :          0 :                 rte_free(txq->sw_ring);
     347                 :          0 :                 txq->sw_ring = NULL;
     348                 :          0 :                 return -ENOMEM;
     349                 :            :         }
     350                 :          0 :         memset(rz->addr, 0, RNP_TX_MAX_RING_SZ);
     351                 :          0 :         txq->ring_phys_addr = rz->iova;
     352                 :          0 :         txq->tx_bdr = rz->addr;
     353                 :          0 :         txq->rz = rz;
     354                 :            : 
     355                 :          0 :         return 0;
     356                 :            : }
     357                 :            : 
     358                 :            : static void
     359                 :          0 : rnp_tx_queue_sw_reset(struct rnp_tx_queue *txq)
     360                 :            : {
     361                 :          0 :         struct rnp_txsw_entry *sw_ring = txq->sw_ring;
     362                 :            :         uint32_t idx = 0, prev = 0;
     363                 :            :         uint32_t size = 0;
     364                 :            : 
     365                 :          0 :         prev = (uint16_t)(txq->attr.nb_desc - 1);
     366         [ #  # ]:          0 :         for (idx = 0; idx < txq->attr.nb_desc; idx++) {
     367                 :          0 :                 sw_ring[idx].mbuf = NULL;
     368                 :          0 :                 sw_ring[idx].last_id = idx;
     369                 :          0 :                 sw_ring[prev].next_id = idx;
     370                 :            :                 prev = idx;
     371                 :            :         }
     372                 :          0 :         txq->last_desc_cleaned = txq->attr.nb_desc - 1;
     373                 :          0 :         txq->nb_tx_free = txq->attr.nb_desc - 1;
     374                 :          0 :         txq->tx_next_dd = txq->tx_rs_thresh - 1;
     375                 :          0 :         txq->tx_next_rs = txq->tx_rs_thresh - 1;
     376                 :          0 :         txq->nb_tx_used = 0;
     377                 :          0 :         txq->tx_tail = 0;
     378                 :            : 
     379                 :          0 :         size = (txq->attr.nb_desc + RNP_TX_MAX_BURST_SIZE);
     380         [ #  # ]:          0 :         for (idx = 0; idx < size * sizeof(struct rnp_tx_desc); idx++)
     381                 :          0 :                 ((volatile char *)txq->tx_bdr)[idx] = 0;
     382                 :          0 : }
     383                 :            : 
     384                 :            : int
     385                 :          0 : rnp_tx_queue_setup(struct rte_eth_dev *dev,
     386                 :            :                    uint16_t qidx, uint16_t nb_desc,
     387                 :            :                    unsigned int socket_id,
     388                 :            :                    const struct rte_eth_txconf *tx_conf)
     389                 :            : {
     390                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(dev);
     391                 :            :         struct rte_eth_dev_data *data = dev->data;
     392                 :          0 :         struct rnp_hw *hw = port->hw;
     393                 :            :         struct rnp_tx_queue *txq;
     394                 :            :         uint64_t offloads = 0;
     395                 :            :         int err = 0;
     396                 :            : 
     397                 :          0 :         PMD_INIT_FUNC_TRACE();
     398                 :          0 :         offloads = tx_conf->offloads | dev->data->dev_conf.txmode.offloads;
     399                 :          0 :         RNP_PMD_INFO("TXQ[%u] setup nb-desc %u", qidx, nb_desc);
     400         [ #  # ]:          0 :         if (rte_is_power_of_2(nb_desc) == 0) {
     401                 :          0 :                 RNP_PMD_ERR("txq Desc num must power of 2");
     402                 :          0 :                 return -EINVAL;
     403                 :            :         }
     404         [ #  # ]:          0 :         if (nb_desc > RNP_MAX_BD_COUNT)
     405                 :            :                 return -EINVAL;
     406                 :            :         /* check whether queue Has been create if so release it */
     407   [ #  #  #  # ]:          0 :         if (qidx < data->nb_tx_queues && data->tx_queues[qidx]) {
     408                 :          0 :                 rnp_tx_queue_release(data->tx_queues[qidx]);
     409                 :          0 :                 data->tx_queues[qidx] = NULL;
     410                 :            :         }
     411                 :          0 :         txq = rte_zmalloc_socket("rnp_txq", sizeof(struct rnp_tx_queue),
     412                 :            :                         RTE_CACHE_LINE_SIZE, socket_id);
     413         [ #  # ]:          0 :         if (!txq) {
     414                 :          0 :                 RNP_PMD_ERR("Failed to allocate TX ring memory");
     415                 :          0 :                 return -ENOMEM;
     416                 :            :         }
     417         [ #  # ]:          0 :         txq->tx_rs_thresh = tx_conf->tx_rs_thresh ?
     418                 :            :                 tx_conf->tx_rs_thresh : RNP_DEFAULT_TX_RS_THRESH;
     419         [ #  # ]:          0 :         txq->tx_free_thresh = tx_conf->tx_free_thresh ?
     420                 :            :                 tx_conf->tx_free_thresh : RNP_DEFAULT_TX_FREE_THRESH;
     421         [ #  # ]:          0 :         if (txq->tx_rs_thresh > txq->tx_free_thresh) {
     422                 :          0 :                 RNP_PMD_ERR("tx_rs_thresh must be less than or "
     423                 :            :                              "equal to tx_free_thresh. (tx_free_thresh=%u"
     424                 :            :                              " tx_rs_thresh=%u port=%d queue=%d)",
     425                 :            :                              (unsigned int)tx_conf->tx_free_thresh,
     426                 :            :                              (unsigned int)tx_conf->tx_rs_thresh,
     427                 :            :                              (int)data->port_id,
     428                 :            :                              (int)qidx);
     429                 :            :                 err = -EINVAL;
     430                 :          0 :                 goto txbd_setup_failed;
     431                 :            :         }
     432         [ #  # ]:          0 :         if (txq->tx_rs_thresh + txq->tx_free_thresh >= nb_desc) {
     433                 :          0 :                 RNP_PMD_ERR("tx_rs_thresh + tx_free_thresh >= nb_desc"
     434                 :            :                                 "%d + %d >= %d", txq->tx_rs_thresh,
     435                 :            :                                 txq->tx_free_thresh, nb_desc);
     436                 :            :                 err = -EINVAL;
     437                 :          0 :                 goto txbd_setup_failed;
     438                 :            :         }
     439         [ #  # ]:          0 :         txq->pthresh = (tx_conf->tx_thresh.pthresh) ?
     440                 :            :                 tx_conf->tx_thresh.pthresh : RNP_TX_DESC_FETCH_TH;
     441         [ #  # ]:          0 :         txq->pburst = (tx_conf->tx_thresh.hthresh) ?
     442                 :            :                 tx_conf->tx_thresh.hthresh : RNP_TX_DESC_FETCH_BURST;
     443                 :          0 :         txq->free_mbufs = rte_zmalloc_socket("txq->free_mbufs",
     444                 :          0 :                         sizeof(struct rte_mbuf *) * txq->tx_rs_thresh,
     445                 :            :                         RTE_CACHE_LINE_SIZE, socket_id);
     446                 :          0 :         txq->attr.index = rnp_get_dma_ring_index(port, qidx);
     447                 :          0 :         txq->attr.lane_id = port->attr.nr_lane;
     448                 :          0 :         txq->attr.port_id = dev->data->port_id;
     449                 :          0 :         txq->attr.nb_desc_mask = nb_desc - 1;
     450                 :          0 :         txq->attr.vf_num = hw->mbx.vf_num;
     451                 :          0 :         txq->attr.nb_desc = nb_desc;
     452                 :          0 :         txq->attr.queue_id = qidx;
     453                 :            : 
     454                 :          0 :         err = rnp_alloc_txbdr(dev, txq, nb_desc, socket_id);
     455         [ #  # ]:          0 :         if (err)
     456                 :          0 :                 goto txbd_setup_failed;
     457                 :          0 :         rnp_setup_txbdr(hw, txq);
     458         [ #  # ]:          0 :         if (txq->tx_tail)
     459                 :          0 :                 rnp_reset_hw_txq_op(hw, txq);
     460                 :          0 :         rnp_tx_queue_sw_reset(txq);
     461                 :          0 :         RNP_PMD_LOG(INFO, "PF[%u] dev:[%u] hw-lane[%u] txq queue_id[%u] "
     462                 :            :                         "dma_idx %u socket %u",
     463                 :            :                         hw->mbx.pf_num, txq->attr.port_id,
     464                 :            :                         txq->attr.lane_id, qidx,
     465                 :            :                         txq->attr.index, socket_id);
     466         [ #  # ]:          0 :         if (qidx < dev->data->nb_tx_queues)
     467                 :          0 :                 data->tx_queues[qidx] = txq;
     468                 :          0 :         port->tx_queues[qidx] = txq;
     469                 :            : 
     470                 :          0 :         txq->tx_deferred_start = tx_conf->tx_deferred_start;
     471                 :          0 :         txq->tx_offloads = offloads;
     472                 :            : 
     473                 :          0 :         return 0;
     474                 :          0 : txbd_setup_failed:
     475                 :            : 
     476                 :          0 :         rte_free(txq);
     477                 :            : 
     478                 :          0 :         return err;
     479                 :            : }
     480                 :            : 
     481                 :          0 : int rnp_tx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t qidx)
     482                 :            : {
     483                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     484                 :            :         struct rte_eth_dev_data *data = eth_dev->data;
     485                 :            :         struct rnp_tx_queue *txq;
     486                 :            : 
     487                 :          0 :         PMD_INIT_FUNC_TRACE();
     488                 :          0 :         txq = eth_dev->data->tx_queues[qidx];
     489         [ #  # ]:          0 :         if (!txq) {
     490                 :          0 :                 RNP_PMD_ERR("TX queue %u is null or not setup", qidx);
     491                 :          0 :                 return -EINVAL;
     492                 :            :         }
     493         [ #  # ]:          0 :         if (data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STARTED) {
     494                 :          0 :                 txq->txq_started = 0;
     495                 :            :                 /* wait for tx burst process stop traffic */
     496                 :          0 :                 rte_delay_us(10);
     497                 :          0 :                 rnp_tx_queue_release_mbuf(txq);
     498                 :            :                 rnp_tx_queue_reset(port, txq);
     499                 :          0 :                 rnp_tx_queue_sw_reset(txq);
     500                 :          0 :                 data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
     501                 :            :         }
     502                 :            : 
     503                 :            :         return 0;
     504                 :            : }
     505                 :            : 
     506                 :          0 : int rnp_tx_queue_start(struct rte_eth_dev *eth_dev, uint16_t qidx)
     507                 :            : {
     508                 :          0 :         struct rte_eth_dev_data *data = eth_dev->data;
     509                 :            :         struct rnp_tx_queue *txq;
     510                 :            : 
     511                 :          0 :         PMD_INIT_FUNC_TRACE();
     512                 :            : 
     513                 :          0 :         txq = data->tx_queues[qidx];
     514         [ #  # ]:          0 :         if (!txq) {
     515                 :          0 :                 RNP_PMD_ERR("Can't start tx queue %d it's not setup by "
     516                 :            :                                 "tx_queue_setup API", qidx);
     517                 :          0 :                 return -EINVAL;
     518                 :            :         }
     519         [ #  # ]:          0 :         if (data->tx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STOPPED) {
     520                 :          0 :                 data->tx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STARTED;
     521                 :          0 :                 txq->txq_started = 1;
     522                 :            :         }
     523                 :            : 
     524                 :            :         return 0;
     525                 :            : }
     526                 :            : 
     527                 :          0 : int rnp_rx_queue_stop(struct rte_eth_dev *eth_dev, uint16_t qidx)
     528                 :            : {
     529                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     530                 :            :         struct rte_eth_dev_data *data = eth_dev->data;
     531                 :            :         bool ori_q_state[RNP_MAX_RX_QUEUE_NUM];
     532                 :          0 :         struct rnp_hw *hw = port->hw;
     533                 :            :         struct rnp_rx_queue *rxq;
     534                 :            :         uint16_t hwrid;
     535                 :            :         uint16_t i = 0;
     536                 :            : 
     537                 :          0 :         PMD_INIT_FUNC_TRACE();
     538                 :            :         memset(ori_q_state, 0, sizeof(ori_q_state));
     539         [ #  # ]:          0 :         if (qidx >= data->nb_rx_queues)
     540                 :            :                 return -EINVAL;
     541                 :          0 :         rxq = data->rx_queues[qidx];
     542         [ #  # ]:          0 :         if (!rxq) {
     543                 :          0 :                 RNP_PMD_ERR("rx queue %u is null or not setup", qidx);
     544                 :          0 :                 return -EINVAL;
     545                 :            :         }
     546         [ #  # ]:          0 :         if (data->rx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STARTED) {
     547                 :          0 :                 hwrid = rxq->attr.index;
     548         [ #  # ]:          0 :                 for (i = 0; i < RNP_MAX_RX_QUEUE_NUM; i++) {
     549                 :          0 :                         RNP_E_REG_WR(hw, RNP_RXQ_DROP_TIMEOUT_TH(i), 16);
     550                 :          0 :                         ori_q_state[i] = RNP_E_REG_RD(hw, RNP_RXQ_START(i));
     551                 :          0 :                         RNP_E_REG_WR(hw, RNP_RXQ_START(i), 0);
     552                 :            :                 }
     553                 :          0 :                 rxq->rxq_started = false;
     554                 :          0 :                 rnp_rx_queue_release_mbuf(rxq);
     555                 :          0 :                 RNP_E_REG_WR(hw, RNP_RXQ_START(hwrid), 0);
     556                 :          0 :                 rnp_rx_queue_reset(port, rxq);
     557                 :            :                 rnp_rx_queue_sw_reset(rxq);
     558         [ #  # ]:          0 :                 for (i = 0; i < RNP_MAX_RX_QUEUE_NUM; i++) {
     559                 :          0 :                         RNP_E_REG_WR(hw, RNP_RXQ_DROP_TIMEOUT_TH(i),
     560                 :            :                                         rxq->nodesc_tm_thresh);
     561                 :          0 :                         RNP_E_REG_WR(hw, RNP_RXQ_START(i), ori_q_state[i]);
     562                 :            :                 }
     563                 :          0 :                 RNP_E_REG_WR(hw, RNP_RXQ_START(hwrid), 0);
     564                 :          0 :                 data->rx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STOPPED;
     565                 :            :         }
     566                 :            : 
     567                 :            :         return 0;
     568                 :            : }
     569                 :            : 
     570                 :          0 : static int rnp_alloc_rxq_mbuf(struct rnp_rx_queue *rxq)
     571                 :            : {
     572                 :          0 :         struct rnp_rxsw_entry *rx_swbd = rxq->sw_ring;
     573                 :            :         volatile struct rnp_rx_desc *rxd;
     574                 :            :         struct rte_mbuf *mbuf = NULL;
     575                 :            :         uint64_t dma_addr;
     576                 :            :         uint16_t i;
     577                 :            : 
     578         [ #  # ]:          0 :         for (i = 0; i < rxq->attr.nb_desc; i++) {
     579                 :          0 :                 mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
     580         [ #  # ]:          0 :                 if (!mbuf)
     581                 :          0 :                         goto rx_mb_alloc_failed;
     582         [ #  # ]:          0 :                 rx_swbd[i].mbuf = mbuf;
     583                 :            : 
     584                 :            :                 rte_mbuf_refcnt_set(mbuf, 1);
     585                 :          0 :                 mbuf->next = NULL;
     586                 :          0 :                 mbuf->data_off = RTE_PKTMBUF_HEADROOM;
     587         [ #  # ]:          0 :                 mbuf->port = rxq->attr.port_id;
     588                 :            :                 dma_addr = rnp_get_dma_addr(&rxq->attr, mbuf);
     589                 :            : 
     590                 :          0 :                 rxd = &rxq->rx_bdr[i];
     591                 :          0 :                 *rxd = rxq->zero_desc;
     592                 :          0 :                 rxd->d.pkt_addr = dma_addr;
     593                 :          0 :                 rxd->d.cmd = 0;
     594                 :            :         }
     595                 :          0 :         memset(&rxq->fake_mbuf, 0x0, sizeof(rxq->fake_mbuf));
     596         [ #  # ]:          0 :         for (i = 0; i < RNP_RX_MAX_BURST_SIZE; ++i)
     597                 :          0 :                 rxq->sw_ring[rxq->attr.nb_desc + i].mbuf = &rxq->fake_mbuf;
     598                 :            : 
     599                 :            :         return 0;
     600                 :            : rx_mb_alloc_failed:
     601                 :          0 :         RNP_PMD_ERR("rx queue %u alloc mbuf failed", rxq->attr.queue_id);
     602                 :          0 :         rnp_rx_queue_release_mbuf(rxq);
     603                 :            : 
     604                 :          0 :         return -ENOMEM;
     605                 :            : }
     606                 :            : 
     607                 :          0 : int rnp_rx_queue_start(struct rte_eth_dev *eth_dev, uint16_t qidx)
     608                 :            : {
     609                 :          0 :         struct rnp_eth_port *port = RNP_DEV_TO_PORT(eth_dev);
     610                 :            :         struct rte_eth_dev_data *data = eth_dev->data;
     611                 :          0 :         struct rnp_hw *hw = port->hw;
     612                 :            :         struct rnp_rx_queue *rxq;
     613                 :            :         uint16_t hwrid;
     614                 :            : 
     615                 :          0 :         PMD_INIT_FUNC_TRACE();
     616                 :          0 :         rxq = data->rx_queues[qidx];
     617         [ #  # ]:          0 :         if (!rxq) {
     618                 :          0 :                 RNP_PMD_ERR("RX queue %u is Null or Not setup", qidx);
     619                 :          0 :                 return -EINVAL;
     620                 :            :         }
     621         [ #  # ]:          0 :         if (data->rx_queue_state[qidx] == RTE_ETH_QUEUE_STATE_STOPPED) {
     622                 :          0 :                 hwrid = rxq->attr.index;
     623                 :            :                 /* disable ring */
     624                 :          0 :                 rte_io_wmb();
     625                 :          0 :                 RNP_E_REG_WR(hw, RNP_RXQ_START(hwrid), 0);
     626         [ #  # ]:          0 :                 if (rnp_alloc_rxq_mbuf(rxq) != 0) {
     627                 :          0 :                         RNP_PMD_ERR("Could not alloc mbuf for queue:%d", qidx);
     628                 :          0 :                         return -ENOMEM;
     629                 :            :                 }
     630                 :          0 :                 rte_io_wmb();
     631                 :          0 :                 RNP_REG_WR(rxq->rx_tailreg, 0, rxq->attr.nb_desc - 1);
     632                 :          0 :                 RNP_E_REG_WR(hw, RNP_RXQ_START(hwrid), 1);
     633                 :          0 :                 rxq->nb_rx_free = rxq->attr.nb_desc - 1;
     634                 :          0 :                 rxq->rxq_started = true;
     635                 :            : 
     636                 :          0 :                 data->rx_queue_state[qidx] = RTE_ETH_QUEUE_STATE_STARTED;
     637                 :            :         }
     638                 :            : 
     639                 :            :         return 0;
     640                 :            : }
     641                 :            : 
     642                 :            : struct rnp_rx_cksum_parse {
     643                 :            :         uint64_t offloads;
     644                 :            :         uint64_t packet_type;
     645                 :            :         uint16_t hw_offload;
     646                 :            :         uint64_t good;
     647                 :            :         uint64_t bad;
     648                 :            : };
     649                 :            : 
     650                 :            : #define RNP_RX_OFFLOAD_L4_CKSUM (RTE_ETH_RX_OFFLOAD_TCP_CKSUM | \
     651                 :            :                                  RTE_ETH_RX_OFFLOAD_UDP_CKSUM | \
     652                 :            :                                  RTE_ETH_RX_OFFLOAD_SCTP_CKSUM)
     653                 :            : static const struct rnp_rx_cksum_parse rnp_rx_cksum_tunnel[] = {
     654                 :            :         { RTE_ETH_RX_OFFLOAD_IPV4_CKSUM | RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM,
     655                 :            :           RTE_PTYPE_L3_IPV4 | RTE_PTYPE_TUNNEL_MASK, RNP_RX_L3_ERR,
     656                 :            :           RTE_MBUF_F_RX_IP_CKSUM_GOOD, RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD
     657                 :            :         },
     658                 :            :         { RTE_ETH_RX_OFFLOAD_IPV4_CKSUM,
     659                 :            :           RTE_PTYPE_L3_IPV4, RNP_RX_IN_L3_ERR,
     660                 :            :           RTE_MBUF_F_RX_IP_CKSUM_GOOD, RTE_MBUF_F_RX_IP_CKSUM_BAD
     661                 :            :         },
     662                 :            :         { RNP_RX_OFFLOAD_L4_CKSUM, RTE_PTYPE_L4_MASK,
     663                 :            :           RNP_RX_IN_L4_ERR | RNP_RX_SCTP_ERR,
     664                 :            :           RTE_MBUF_F_RX_L4_CKSUM_GOOD, RTE_MBUF_F_RX_L4_CKSUM_BAD
     665                 :            :         }
     666                 :            : };
     667                 :            : 
     668                 :            : static const struct rnp_rx_cksum_parse rnp_rx_cksum[] = {
     669                 :            :         { RTE_ETH_RX_OFFLOAD_IPV4_CKSUM,
     670                 :            :           RTE_PTYPE_L3_IPV4, RNP_RX_L3_ERR,
     671                 :            :           RTE_MBUF_F_RX_IP_CKSUM_GOOD, RTE_MBUF_F_RX_IP_CKSUM_BAD
     672                 :            :         },
     673                 :            :         { RNP_RX_OFFLOAD_L4_CKSUM,
     674                 :            :           RTE_PTYPE_L4_MASK, RNP_RX_L4_ERR | RNP_RX_SCTP_ERR,
     675                 :            :           RTE_MBUF_F_RX_L4_CKSUM_GOOD, RTE_MBUF_F_RX_L4_CKSUM_BAD
     676                 :            :         }
     677                 :            : };
     678                 :            : 
     679                 :            : static void
     680                 :          0 : rnp_rx_parse_tunnel_cksum(struct rnp_rx_queue *rxq,
     681                 :            :                           struct rte_mbuf *m, uint16_t cksum_cmd)
     682                 :            : {
     683                 :            :         uint16_t idx = 0;
     684                 :            : 
     685         [ #  # ]:          0 :         for (idx = 0; idx < RTE_DIM(rnp_rx_cksum_tunnel); idx++) {
     686         [ #  # ]:          0 :                 if (rxq->rx_offloads & rnp_rx_cksum_tunnel[idx].offloads &&
     687         [ #  # ]:          0 :                     m->packet_type & rnp_rx_cksum_tunnel[idx].packet_type) {
     688         [ #  # ]:          0 :                         if (cksum_cmd & rnp_rx_cksum_tunnel[idx].hw_offload)
     689                 :          0 :                                 m->ol_flags |= rnp_rx_cksum_tunnel[idx].bad;
     690                 :            :                         else
     691                 :          0 :                                 m->ol_flags |= rnp_rx_cksum_tunnel[idx].good;
     692                 :            :                 }
     693                 :            :         }
     694                 :          0 : }
     695                 :            : 
     696                 :            : static void
     697                 :          0 : rnp_rx_parse_cksum(struct rnp_rx_queue *rxq,
     698                 :            :                    struct rte_mbuf *m, uint16_t cksum_cmd)
     699                 :            : {
     700                 :            :         uint16_t idx = 0;
     701                 :            : 
     702         [ #  # ]:          0 :         for (idx = 0; idx < RTE_DIM(rnp_rx_cksum); idx++) {
     703         [ #  # ]:          0 :                 if (rxq->rx_offloads & rnp_rx_cksum[idx].offloads &&
     704         [ #  # ]:          0 :                     m->packet_type & rnp_rx_cksum[idx].packet_type) {
     705         [ #  # ]:          0 :                         if (cksum_cmd & rnp_rx_cksum[idx].hw_offload)
     706                 :          0 :                                 m->ol_flags |= rnp_rx_cksum[idx].bad;
     707                 :            :                         else
     708                 :          0 :                                 m->ol_flags |= rnp_rx_cksum[idx].good;
     709                 :            :                 }
     710                 :            :         }
     711                 :          0 : }
     712                 :            : 
     713                 :            : static __rte_always_inline void
     714                 :            : rnp_dev_rx_offload(struct rnp_rx_queue *rxq,
     715                 :            :                    struct rte_mbuf *m,
     716                 :            :                    volatile struct rnp_rx_desc rxbd)
     717                 :            : {
     718                 :          0 :         uint32_t rss = rte_le_to_cpu_32(rxbd.wb.qword0.rss_hash);
     719                 :          0 :         uint16_t vlan_tci = rxbd.wb.qword1.vlan_tci;
     720                 :          0 :         uint16_t cmd = rxbd.wb.qword1.cmd;
     721                 :            : 
     722   [ #  #  #  # ]:          0 :         if (rxq->rx_offloads & RNP_RX_CHECKSUM_SUPPORT) {
     723   [ #  #  #  # ]:          0 :                 if (m->packet_type & RTE_PTYPE_TUNNEL_MASK) {
     724                 :          0 :                         rnp_rx_parse_tunnel_cksum(rxq, m, cmd);
     725                 :            :                 } else {
     726   [ #  #  #  # ]:          0 :                         if (m->packet_type & RTE_PTYPE_L3_MASK ||
     727                 :            :                             m->packet_type & RTE_PTYPE_L4_MASK)
     728                 :          0 :                                 rnp_rx_parse_cksum(rxq, m, cmd);
     729                 :            :                 }
     730                 :            :         }
     731   [ #  #  #  #  :          0 :         if (rxq->rx_offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH && rss) {
             #  #  #  # ]
     732                 :          0 :                 m->hash.rss = rss;
     733                 :          0 :                 m->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
     734                 :            :         }
     735   [ #  #  #  # ]:          0 :         if (rxq->rx_offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
     736   [ #  #  #  # ]:          0 :                 if (vlan_tci && cmd & RNP_RX_STRIP_VLAN) {
     737                 :          0 :                         m->ol_flags |= RTE_MBUF_F_RX_VLAN |
     738                 :            :                                 RTE_MBUF_F_RX_VLAN_STRIPPED;
     739                 :          0 :                         m->vlan_tci = vlan_tci;
     740                 :            :                 }
     741                 :            :         }
     742                 :            : }
     743                 :            : 
     744                 :            : static __rte_always_inline void
     745                 :            : rnp_dev_rx_parse(struct rnp_rx_queue *rxq,
     746                 :            :                  struct rte_mbuf *m,
     747                 :            :                  volatile struct rnp_rx_desc rxbd)
     748                 :            : {
     749                 :          0 :         uint32_t mark_data = rxbd.wb.qword0.mark_data;
     750                 :          0 :         uint16_t vlan_tci = rxbd.wb.qword1.vlan_tci;
     751                 :          0 :         uint32_t cmd = rxbd.wb.qword1.cmd;
     752                 :            : 
     753                 :            :         /* clear mbuf packet_type and ol_flags */
     754                 :          0 :         m->packet_type = 0;
     755                 :          0 :         m->ol_flags = 0;
     756                 :          0 :         if (mark_data & RNP_RX_L3TYPE_VALID) {
     757   [ #  #  #  # ]:          0 :                 if (cmd & RNP_RX_L3TYPE_IPV6)
     758                 :          0 :                         m->packet_type |= RTE_PTYPE_L3_IPV6;
     759                 :            :                 else
     760                 :          0 :                         m->packet_type |= RTE_PTYPE_L3_IPV4;
     761                 :            :         }
     762   [ #  #  #  # ]:          0 :         if (vlan_tci)
     763                 :          0 :                 m->packet_type |= RTE_PTYPE_L2_ETHER_VLAN;
     764   [ #  #  #  #  :          0 :         switch (cmd & RNP_RX_L4TYPE_MASK) {
             #  #  #  # ]
     765                 :          0 :         case RNP_RX_L4TYPE_UDP:
     766                 :          0 :                 m->packet_type |= RTE_PTYPE_L4_UDP;
     767                 :          0 :                 break;
     768                 :          0 :         case RNP_RX_L4TYPE_TCP:
     769                 :          0 :                 m->packet_type |= RTE_PTYPE_L4_TCP;
     770                 :          0 :                 break;
     771                 :          0 :         case RNP_RX_L4TYPE_SCTP:
     772                 :          0 :                 m->packet_type |= RTE_PTYPE_L4_SCTP;
     773                 :          0 :                 break;
     774                 :            :         }
     775   [ #  #  #  #  :          0 :         switch (cmd & RNP_RX_TUNNEL_MASK) {
                   #  # ]
     776                 :          0 :         case RNP_RX_PTYPE_VXLAN:
     777                 :          0 :                 m->packet_type |= RTE_PTYPE_TUNNEL_VXLAN;
     778                 :          0 :                 break;
     779                 :          0 :         case RNP_RX_PTYPE_NVGRE:
     780                 :          0 :                 m->packet_type |= RTE_PTYPE_TUNNEL_NVGRE;
     781                 :          0 :                 break;
     782                 :            :         }
     783   [ #  #  #  # ]:          0 :         if (!(m->packet_type & RTE_PTYPE_L2_MASK))
     784                 :          0 :                 m->packet_type |= RTE_PTYPE_L2_ETHER;
     785                 :            :         rnp_dev_rx_offload(rxq, m, rxbd);
     786                 :            : }
     787                 :            : 
     788                 :            : #define RNP_CACHE_FETCH_RX (4)
     789                 :            : static __rte_always_inline int
     790                 :            : rnp_refill_rx_ring(struct rnp_rx_queue *rxq)
     791                 :            : {
     792                 :            :         volatile struct rnp_rx_desc *rxbd;
     793                 :            :         struct rnp_rxsw_entry *rx_swbd;
     794                 :            :         struct rte_eth_dev_data *data;
     795                 :            :         struct rte_mbuf *mb;
     796                 :            :         uint16_t j, i;
     797                 :            :         uint16_t rx_id;
     798                 :            :         int ret;
     799                 :            : 
     800                 :          0 :         rxbd = rxq->rx_bdr + rxq->rxrearm_start;
     801                 :          0 :         rx_swbd = &rxq->sw_ring[rxq->rxrearm_start];
     802         [ #  # ]:          0 :         ret = rte_mempool_get_bulk(rxq->mb_pool, (void *)rx_swbd,
     803                 :            :                         rxq->rx_free_thresh);
     804                 :          0 :         data = rte_eth_devices[rxq->attr.port_id].data;
     805         [ #  # ]:          0 :         if (unlikely(ret != 0)) {
     806         [ #  # ]:          0 :                 if (rxq->rxrearm_nb + rxq->rx_free_thresh >= rxq->attr.nb_desc) {
     807         [ #  # ]:          0 :                         for (i = 0; i < RNP_CACHE_FETCH_RX; i++) {
     808                 :          0 :                                 rx_swbd[i].mbuf = &rxq->fake_mbuf;
     809                 :          0 :                                 rxbd[i].d.pkt_addr = 0;
     810                 :          0 :                                 rxbd[i].d.cmd = 0;
     811                 :            :                         }
     812                 :            :                 }
     813                 :          0 :                 data->rx_mbuf_alloc_failed += rxq->rx_free_thresh;
     814                 :          0 :                 return 0;
     815                 :            :         }
     816         [ #  # ]:          0 :         for (j = 0; j < rxq->rx_free_thresh; ++j) {
     817                 :          0 :                 mb = rx_swbd[j].mbuf;
     818                 :          0 :                 rte_mbuf_refcnt_set(mb, 1);
     819                 :          0 :                 mb->data_off = RTE_PKTMBUF_HEADROOM;
     820                 :          0 :                 mb->port = rxq->attr.port_id;
     821                 :            : 
     822         [ #  # ]:          0 :                 rxbd[j].d.pkt_addr = rnp_get_dma_addr(&rxq->attr, mb);
     823                 :          0 :                 rxbd[j].d.cmd = 0;
     824                 :            :         }
     825                 :          0 :         rxq->rxrearm_start += rxq->rx_free_thresh;
     826         [ #  # ]:          0 :         if (rxq->rxrearm_start >= rxq->attr.nb_desc - 1)
     827                 :          0 :                 rxq->rxrearm_start = 0;
     828                 :          0 :         rxq->rxrearm_nb -= rxq->rx_free_thresh;
     829                 :            : 
     830         [ #  # ]:          0 :         rx_id = (uint16_t)((rxq->rxrearm_start == 0) ?
     831                 :            :                         (rxq->attr.nb_desc - 1) : (rxq->rxrearm_start - 1));
     832                 :            :         rte_wmb();
     833                 :          0 :         RNP_REG_WR(rxq->rx_tailreg, 0, rx_id);
     834                 :            : 
     835                 :          0 :         return j;
     836                 :            : }
     837                 :            : 
     838                 :            : static __rte_always_inline uint16_t
     839                 :          0 : rnp_recv_pkts(void *_rxq, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
     840                 :            : {
     841                 :            :         struct rnp_rx_queue *rxq = (struct rnp_rx_queue *)_rxq;
     842                 :            :         struct rnp_rxsw_entry *rx_swbd;
     843                 :            :         uint32_t state_cmd[RNP_CACHE_FETCH_RX];
     844                 :          0 :         uint32_t pkt_len[RNP_CACHE_FETCH_RX] = {0};
     845                 :            :         volatile struct rnp_rx_desc *rxbd;
     846                 :            :         struct rte_mbuf *nmb;
     847                 :            :         int nb_dd, nb_rx = 0;
     848                 :            :         int i, j;
     849                 :            : 
     850   [ #  #  #  # ]:          0 :         if (unlikely(!rxq->rxq_started || !rxq->rx_link))
     851                 :            :                 return 0;
     852                 :          0 :         nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, RNP_CACHE_FETCH_RX);
     853                 :          0 :         rxbd = &rxq->rx_bdr[rxq->rx_tail];
     854                 :          0 :         rte_prefetch0(rxbd);
     855         [ #  # ]:          0 :         if (rxq->rxrearm_nb > rxq->rx_free_thresh)
     856                 :            :                 rnp_refill_rx_ring(rxq);
     857                 :            : 
     858         [ #  # ]:          0 :         if (!(rxbd->wb.qword1.cmd & RNP_CMD_DD))
     859                 :            :                 return 0;
     860                 :            : 
     861                 :          0 :         rx_swbd = &rxq->sw_ring[rxq->rx_tail];
     862         [ #  # ]:          0 :         for (i = 0; i < nb_pkts;
     863                 :          0 :                         i += RNP_CACHE_FETCH_RX, rxbd += RNP_CACHE_FETCH_RX,
     864                 :          0 :                         rx_swbd += RNP_CACHE_FETCH_RX) {
     865         [ #  # ]:          0 :                 for (j = 0; j < RNP_CACHE_FETCH_RX; j++)
     866                 :          0 :                         state_cmd[j] = rxbd[j].wb.qword1.cmd;
     867                 :            :                 rte_atomic_thread_fence(rte_memory_order_acquire);
     868                 :            : 
     869         [ #  # ]:          0 :                 for (nb_dd = 0; nb_dd < RNP_CACHE_FETCH_RX &&
     870         [ #  # ]:          0 :                                 (state_cmd[nb_dd] & rte_cpu_to_le_16(RNP_CMD_DD));
     871                 :          0 :                                 nb_dd++)
     872                 :            :                         ;
     873         [ #  # ]:          0 :                 for (j = 0; j < nb_dd; j++)
     874                 :          0 :                         pkt_len[j] = rxbd[j].wb.qword1.lens;
     875                 :            : 
     876         [ #  # ]:          0 :                 for (j = 0; j < nb_dd; ++j) {
     877                 :          0 :                         nmb = rx_swbd[j].mbuf;
     878                 :            : 
     879                 :          0 :                         nmb->data_off = RTE_PKTMBUF_HEADROOM;
     880                 :          0 :                         nmb->port = rxq->attr.port_id;
     881                 :          0 :                         nmb->data_len = pkt_len[j];
     882                 :          0 :                         nmb->pkt_len = pkt_len[j];
     883                 :          0 :                         nmb->packet_type = 0;
     884                 :          0 :                         nmb->ol_flags = 0;
     885                 :          0 :                         nmb->nb_segs = 1;
     886                 :            : 
     887         [ #  # ]:          0 :                         rnp_dev_rx_parse(rxq, nmb, rxbd[j]);
     888                 :          0 :                         rxq->stats.ibytes += nmb->data_len;
     889                 :            :                 }
     890         [ #  # ]:          0 :                 for (j = 0; j < nb_dd; ++j) {
     891                 :          0 :                         rx_pkts[i + j] = rx_swbd[j].mbuf;
     892                 :          0 :                         rx_swbd[j].mbuf = NULL;
     893                 :            :                 }
     894                 :            : 
     895                 :          0 :                 nb_rx += nb_dd;
     896                 :          0 :                 rxq->nb_rx_free -= nb_dd;
     897         [ #  # ]:          0 :                 if (nb_dd != RNP_CACHE_FETCH_RX)
     898                 :            :                         break;
     899                 :            :         }
     900                 :          0 :         rxq->stats.ipackets += nb_rx;
     901                 :          0 :         rxq->rx_tail = (rxq->rx_tail + nb_rx) & rxq->attr.nb_desc_mask;
     902                 :          0 :         rxq->rxrearm_nb = rxq->rxrearm_nb + nb_rx;
     903                 :            : 
     904                 :          0 :         return nb_rx;
     905                 :            : }
     906                 :            : 
     907                 :            : static  __rte_always_inline int
     908                 :            : rnp_clean_tx_ring(struct rnp_tx_queue *txq)
     909                 :            : {
     910                 :            :         volatile struct rnp_tx_desc *txbd;
     911                 :            :         struct rnp_txsw_entry *tx_swbd;
     912                 :            :         struct rte_mbuf *m;
     913                 :            :         uint16_t next_dd;
     914                 :            :         uint16_t i;
     915                 :            : 
     916                 :          0 :         txbd = &txq->tx_bdr[txq->tx_next_dd];
     917         [ #  # ]:          0 :         if (!(txbd->d.cmd & RNP_CMD_DD))
     918                 :            :                 return 0;
     919                 :          0 :         *txbd = txq->zero_desc;
     920                 :          0 :         next_dd = txq->tx_next_dd - (txq->tx_free_thresh - 1);
     921                 :          0 :         tx_swbd = &txq->sw_ring[next_dd];
     922                 :            : 
     923         [ #  # ]:          0 :         for (i = 0; i < txq->tx_rs_thresh; ++i, ++tx_swbd) {
     924         [ #  # ]:          0 :                 if (tx_swbd->mbuf) {
     925                 :            :                         m = tx_swbd->mbuf;
     926                 :            :                         rte_pktmbuf_free_seg(m);
     927                 :          0 :                         tx_swbd->mbuf = NULL;
     928                 :            :                 }
     929                 :            :         }
     930                 :          0 :         txq->nb_tx_free = (txq->nb_tx_free + txq->tx_rs_thresh);
     931                 :          0 :         txq->tx_next_dd = (txq->tx_next_dd + txq->tx_rs_thresh) &
     932                 :          0 :                 txq->attr.nb_desc_mask;
     933                 :            : 
     934                 :          0 :         return 0;
     935                 :            : }
     936                 :            : 
     937                 :            : static __rte_always_inline uint16_t
     938                 :          0 : rnp_xmit_simple(void *_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
     939                 :            : {
     940                 :            :         struct rnp_tx_queue *txq = (struct rnp_tx_queue *)_txq;
     941                 :            :         volatile struct rnp_tx_desc *txbd;
     942                 :            :         struct rnp_txsw_entry *tx_swbd;
     943                 :            :         uint64_t phy;
     944                 :            :         uint16_t start;
     945                 :            :         uint16_t i;
     946                 :            : 
     947   [ #  #  #  # ]:          0 :         if (unlikely(!txq->txq_started || !txq->tx_link))
     948                 :            :                 return 0;
     949                 :            : 
     950         [ #  # ]:          0 :         if (txq->nb_tx_free < txq->tx_free_thresh)
     951                 :            :                 rnp_clean_tx_ring(txq);
     952                 :            : 
     953                 :          0 :         nb_pkts = RTE_MIN(txq->nb_tx_free, nb_pkts);
     954         [ #  # ]:          0 :         if (!nb_pkts)
     955                 :            :                 return 0;
     956                 :            :         start = nb_pkts;
     957                 :          0 :         i = txq->tx_tail;
     958                 :            : 
     959         [ #  # ]:          0 :         while (nb_pkts--) {
     960                 :          0 :                 txbd = &txq->tx_bdr[i];
     961                 :          0 :                 tx_swbd = &txq->sw_ring[i];
     962         [ #  # ]:          0 :                 tx_swbd->mbuf = *tx_pkts++;
     963                 :            :                 phy = rnp_get_dma_addr(&txq->attr, tx_swbd->mbuf);
     964                 :          0 :                 txbd->d.addr = phy;
     965         [ #  # ]:          0 :                 if (unlikely(tx_swbd->mbuf->data_len > RNP_MAC_MAXFRM_SIZE))
     966                 :          0 :                         tx_swbd->mbuf->data_len = 0;
     967                 :          0 :                 txbd->d.blen = tx_swbd->mbuf->data_len;
     968                 :          0 :                 txbd->d.cmd = RNP_CMD_EOP;
     969                 :            : 
     970                 :          0 :                 txq->stats.obytes += txbd->d.blen;
     971                 :          0 :                 i = (i + 1) & txq->attr.nb_desc_mask;
     972                 :            :         }
     973                 :          0 :         txq->nb_tx_free -= start;
     974         [ #  # ]:          0 :         if (txq->tx_tail + start > txq->tx_next_rs) {
     975                 :          0 :                 txbd = &txq->tx_bdr[txq->tx_next_rs];
     976                 :          0 :                 txbd->d.cmd |= RNP_CMD_RS;
     977                 :          0 :                 txq->tx_next_rs = (txq->tx_next_rs + txq->tx_rs_thresh);
     978                 :            : 
     979         [ #  # ]:          0 :                 if (txq->tx_next_rs > txq->attr.nb_desc)
     980                 :          0 :                         txq->tx_next_rs = txq->tx_rs_thresh - 1;
     981                 :            :         }
     982                 :          0 :         txq->stats.opackets += start;
     983                 :          0 :         txq->tx_tail = i;
     984                 :            : 
     985                 :            :         rte_wmb();
     986                 :          0 :         RNP_REG_WR(txq->tx_tailreg, 0, i);
     987                 :            : 
     988                 :          0 :         return start;
     989                 :            : }
     990                 :            : 
     991                 :            : static int
     992                 :          0 : rnp_rxq_bulk_alloc(struct rnp_rx_queue *rxq,
     993                 :            :                    volatile struct rnp_rx_desc *rxbd,
     994                 :            :                    struct rnp_rxsw_entry *rxe,
     995                 :            :                    bool bulk_alloc)
     996                 :            : {
     997                 :            :         struct rte_eth_dev_data *data;
     998                 :            :         struct rte_mbuf *nmb = NULL;
     999                 :            :         uint16_t update_tail;
    1000                 :            : 
    1001         [ #  # ]:          0 :         if (!bulk_alloc) {
    1002                 :          0 :                 data = rte_eth_devices[rxq->attr.port_id].data;
    1003                 :          0 :                 nmb = rte_mbuf_raw_alloc(rxq->mb_pool);
    1004         [ #  # ]:          0 :                 if (unlikely(!nmb)) {
    1005                 :          0 :                         data->rx_mbuf_alloc_failed++;
    1006                 :          0 :                         return -ENOMEM;
    1007                 :            :                 }
    1008                 :          0 :                 rxbd->d.pkt_addr = 0;
    1009                 :          0 :                 rxbd->d.cmd = 0;
    1010                 :            :                 rxe->mbuf = NULL;
    1011         [ #  # ]:          0 :                 rxe->mbuf = nmb;
    1012                 :          0 :                 rxbd->d.pkt_addr = rnp_get_dma_addr(&rxq->attr, nmb);
    1013                 :            :         }
    1014                 :          0 :         rxq->rxrearm_nb++;
    1015         [ #  # ]:          0 :         if (rxq->rxrearm_nb > rxq->rx_free_thresh) {
    1016                 :          0 :                 rxq->rxrearm_nb -= rxq->rx_free_thresh;
    1017                 :          0 :                 rxq->rxrearm_start += rxq->rx_free_thresh;
    1018         [ #  # ]:          0 :                 if (rxq->rxrearm_start >= rxq->attr.nb_desc)
    1019                 :          0 :                         rxq->rxrearm_start = 0;
    1020         [ #  # ]:          0 :                 update_tail = (uint16_t)((rxq->rxrearm_start == 0) ?
    1021                 :            :                                 (rxq->attr.nb_desc - 1) : (rxq->rxrearm_start - 1));
    1022                 :          0 :                 rte_io_wmb();
    1023                 :          0 :                 RNP_REG_WR(rxq->rx_tailreg, 0, update_tail);
    1024                 :            :         }
    1025                 :            : 
    1026                 :            :         return 0;
    1027                 :            : }
    1028                 :            : 
    1029                 :            : static __rte_always_inline uint16_t
    1030                 :          0 : rnp_scattered_rx(void *rx_queue, struct rte_mbuf **rx_pkts,
    1031                 :            :                  uint16_t nb_pkts)
    1032                 :            : {
    1033                 :            :         struct rnp_rx_queue *rxq = (struct rnp_rx_queue *)rx_queue;
    1034                 :          0 :         volatile struct rnp_rx_desc *bd_ring = rxq->rx_bdr;
    1035                 :          0 :         struct rte_mbuf *first_seg = rxq->pkt_first_seg;
    1036                 :          0 :         struct rte_mbuf *last_seg = rxq->pkt_last_seg;
    1037                 :          0 :         struct rnp_rxsw_entry *sw_ring = rxq->sw_ring;
    1038                 :            :         volatile struct rnp_rx_desc *rxbd;
    1039                 :            :         volatile struct rnp_rx_desc rxd;
    1040                 :            :         struct rnp_rxsw_entry *rxe;
    1041                 :            :         struct rte_mbuf *rxm;
    1042                 :            :         uint16_t rx_pkt_len;
    1043                 :            :         uint16_t nb_rx = 0;
    1044                 :            :         uint16_t rx_status;
    1045                 :            :         uint16_t rx_id;
    1046                 :            : 
    1047   [ #  #  #  # ]:          0 :         if (unlikely(!rxq->rxq_started || !rxq->rx_link))
    1048                 :            :                 return 0;
    1049                 :          0 :         rx_id = rxq->rx_tail;
    1050         [ #  # ]:          0 :         while (nb_rx < nb_pkts) {
    1051                 :          0 :                 rxbd = &bd_ring[rx_id];
    1052                 :          0 :                 rx_status = rxbd->wb.qword1.cmd;
    1053         [ #  # ]:          0 :                 if (!(rx_status & rte_cpu_to_le_16(RNP_CMD_DD)))
    1054                 :            :                         break;
    1055                 :            :                 rte_atomic_thread_fence(rte_memory_order_acquire);
    1056                 :          0 :                 rxd = *rxbd;
    1057                 :          0 :                 rxe = &sw_ring[rx_id];
    1058                 :          0 :                 rxm = rxe->mbuf;
    1059         [ #  # ]:          0 :                 if (rnp_rxq_bulk_alloc(rxq, rxbd, rxe, false))
    1060                 :            :                         break;
    1061                 :          0 :                 rx_id = (rx_id + 1) & rxq->attr.nb_desc_mask;
    1062                 :          0 :                 rte_prefetch0(sw_ring[rx_id].mbuf);
    1063         [ #  # ]:          0 :                 if ((rx_id & 0x3) == 0) {
    1064                 :          0 :                         rte_prefetch0(&bd_ring[rx_id]);
    1065                 :          0 :                         rte_prefetch0(&sw_ring[rx_id]);
    1066                 :            :                 }
    1067                 :          0 :                 rx_pkt_len = rxd.wb.qword1.lens;
    1068                 :          0 :                 rxm->data_len = rx_pkt_len;
    1069                 :          0 :                 rxm->data_off = RTE_PKTMBUF_HEADROOM;
    1070         [ #  # ]:          0 :                 if (!first_seg) {
    1071                 :            :                         /* first segment pkt */
    1072                 :            :                         first_seg = rxm;
    1073                 :          0 :                         first_seg->nb_segs = 1;
    1074                 :          0 :                         first_seg->pkt_len = rx_pkt_len;
    1075                 :            :                 } else {
    1076                 :            :                         /* follow-up segment pkt */
    1077                 :          0 :                         first_seg->pkt_len =
    1078                 :          0 :                                 (uint16_t)(first_seg->pkt_len + rx_pkt_len);
    1079                 :          0 :                         first_seg->nb_segs++;
    1080                 :          0 :                         last_seg->next = rxm;
    1081                 :            :                 }
    1082         [ #  # ]:          0 :                 if (!(rx_status & rte_cpu_to_le_16(RNP_CMD_EOP))) {
    1083                 :            :                         last_seg = rxm;
    1084                 :          0 :                         continue;
    1085                 :            :                 }
    1086                 :          0 :                 rxm->next = NULL;
    1087         [ #  # ]:          0 :                 first_seg->port = rxq->attr.port_id;
    1088                 :            :                 rnp_dev_rx_parse(rxq, first_seg, rxd);
    1089                 :          0 :                 rxq->stats.ibytes += first_seg->pkt_len;
    1090                 :            :                 /* this the end of packet the large pkt has been recv finish */
    1091                 :          0 :                 rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr,
    1092                 :            :                                         first_seg->data_off));
    1093                 :          0 :                 rx_pkts[nb_rx++] = first_seg;
    1094                 :            :                 first_seg = NULL;
    1095                 :            :         }
    1096                 :            :         /* update sw record point */
    1097                 :          0 :         rxq->stats.ipackets += nb_rx;
    1098                 :          0 :         rxq->rx_tail = rx_id;
    1099                 :          0 :         rxq->pkt_first_seg = first_seg;
    1100                 :          0 :         rxq->pkt_last_seg = last_seg;
    1101                 :            : 
    1102                 :          0 :         return nb_rx;
    1103                 :            : }
    1104                 :            : 
    1105                 :            : static __rte_always_inline uint16_t
    1106                 :            : rnp_multiseg_clean_txq(struct rnp_tx_queue *txq)
    1107                 :            : {
    1108                 :          0 :         uint16_t last_desc_cleaned = txq->last_desc_cleaned;
    1109                 :          0 :         struct rnp_txsw_entry *sw_ring = txq->sw_ring;
    1110                 :            :         volatile struct rnp_tx_desc *txbd;
    1111                 :            :         uint16_t desc_to_clean_to;
    1112                 :            :         uint16_t nb_tx_to_clean;
    1113                 :            : 
    1114                 :          0 :         desc_to_clean_to = (uint16_t)(last_desc_cleaned + txq->tx_rs_thresh);
    1115                 :          0 :         desc_to_clean_to = desc_to_clean_to & (txq->attr.nb_desc - 1);
    1116                 :            : 
    1117                 :          0 :         desc_to_clean_to = sw_ring[desc_to_clean_to].last_id;
    1118                 :          0 :         txbd = &txq->tx_bdr[desc_to_clean_to];
    1119   [ #  #  #  # ]:          0 :         if (!(txbd->d.cmd & RNP_CMD_DD))
    1120                 :            :                 return txq->nb_tx_free;
    1121                 :            : 
    1122   [ #  #  #  # ]:          0 :         if (last_desc_cleaned > desc_to_clean_to)
    1123                 :          0 :                 nb_tx_to_clean = (uint16_t)((txq->attr.nb_desc -
    1124                 :            :                                         last_desc_cleaned) + desc_to_clean_to);
    1125                 :            :         else
    1126                 :          0 :                 nb_tx_to_clean = (uint16_t)(desc_to_clean_to -
    1127                 :            :                                 last_desc_cleaned);
    1128                 :            : 
    1129                 :          0 :         txbd->d.cmd = 0;
    1130                 :            : 
    1131                 :          0 :         txq->last_desc_cleaned = desc_to_clean_to;
    1132                 :          0 :         txq->nb_tx_free = (uint16_t)(txq->nb_tx_free + nb_tx_to_clean);
    1133                 :            : 
    1134                 :          0 :         return txq->nb_tx_free;
    1135                 :            : }
    1136                 :            : static inline uint32_t
    1137                 :            : rnp_cal_tso_seg(struct rte_mbuf *mbuf)
    1138                 :            : {
    1139                 :            :         uint32_t hdr_len;
    1140                 :            : 
    1141                 :          0 :         hdr_len = mbuf->l2_len + mbuf->l3_len + mbuf->l4_len;
    1142                 :            : 
    1143                 :          0 :         hdr_len += (mbuf->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) ?
    1144   [ #  #  #  # ]:          0 :                 mbuf->outer_l2_len + mbuf->outer_l3_len : 0;
    1145                 :            : 
    1146   [ #  #  #  # ]:          0 :         return (mbuf->tso_segsz) ? mbuf->tso_segsz : hdr_len;
    1147                 :            : }
    1148                 :            : 
    1149                 :            : static inline bool
    1150                 :          0 : rnp_need_ctrl_desc(uint64_t flags)
    1151                 :            : {
    1152                 :            :         static uint64_t mask = RTE_MBUF_F_TX_OUTER_IP_CKSUM |
    1153                 :            :                                RTE_MBUF_F_TX_TCP_SEG |
    1154                 :            :                                RTE_MBUF_F_TX_TUNNEL_VXLAN |
    1155                 :            :                                RTE_MBUF_F_TX_TUNNEL_GRE |
    1156                 :            :                                RTE_MBUF_F_TX_QINQ;
    1157                 :          0 :         return (flags & mask) ? 1 : 0;
    1158                 :            : }
    1159                 :            : 
    1160                 :            : static void
    1161                 :          0 : rnp_build_tx_control_desc(struct rnp_tx_queue *txq,
    1162                 :            :                           volatile struct rnp_tx_desc *txbd,
    1163                 :            :                           struct rte_mbuf *mbuf)
    1164                 :            : {
    1165                 :            :         struct rte_gre_hdr *gre_hdr;
    1166                 :            :         uint16_t tunnel_len = 0;
    1167                 :            :         uint64_t flags;
    1168                 :            : 
    1169                 :          0 :         *txbd = txq->zero_desc;
    1170                 :            :         /* For outer checksum offload l2_len is
    1171                 :            :          * l2 (MAC) Header Length for non-tunneling pkt.
    1172                 :            :          * For Inner checksum offload l2_len is
    1173                 :            :          * Outer_L4_len + ... + Inner_L2_len(Inner L2 Header Len)
    1174                 :            :          * for tunneling pkt.
    1175                 :            :          */
    1176         [ #  # ]:          0 :         if (!mbuf)
    1177                 :            :                 return;
    1178                 :          0 :         flags = mbuf->ol_flags;
    1179         [ #  # ]:          0 :         if (flags & RTE_MBUF_F_TX_TCP_SEG) {
    1180                 :          0 :                 txbd->c.qword0.mss = rnp_cal_tso_seg(mbuf);
    1181                 :          0 :                 txbd->c.qword0.l4_len = mbuf->l4_len;
    1182                 :            :         }
    1183         [ #  # ]:          0 :         if (flags & RTE_MBUF_F_TX_QINQ) {
    1184                 :          0 :                 txbd->c.qword0.vlan_tci = mbuf->vlan_tci;
    1185                 :          0 :                 txbd->c.qword1.cmd |= RNP_TX_QINQ_INSERT;
    1186                 :            :         }
    1187                 :            : #define GRE_TUNNEL_KEY (4)
    1188                 :            : #define GRE_TUNNEL_SEQ (4)
    1189      [ #  #  # ]:          0 :         switch (flags & RTE_MBUF_F_TX_TUNNEL_MASK) {
    1190                 :          0 :         case RTE_MBUF_F_TX_TUNNEL_VXLAN:
    1191                 :          0 :                 tunnel_len = mbuf->outer_l2_len + mbuf->outer_l3_len +
    1192                 :            :                         sizeof(struct rte_udp_hdr) +
    1193                 :            :                         sizeof(struct rte_vxlan_hdr);
    1194                 :          0 :                 break;
    1195                 :          0 :         case RTE_MBUF_F_TX_TUNNEL_GRE:
    1196                 :          0 :                 gre_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_gre_hdr *,
    1197                 :            :                                 mbuf->outer_l2_len + mbuf->outer_l3_len);
    1198                 :          0 :                 tunnel_len = mbuf->outer_l2_len + mbuf->outer_l3_len +
    1199                 :            :                                   sizeof(struct rte_gre_hdr);
    1200         [ #  # ]:          0 :                 if (gre_hdr->k)
    1201                 :          0 :                         tunnel_len += GRE_TUNNEL_KEY;
    1202         [ #  # ]:          0 :                 if (gre_hdr->s)
    1203                 :          0 :                         tunnel_len += GRE_TUNNEL_SEQ;
    1204                 :            :                 break;
    1205                 :            :         }
    1206                 :          0 :         txbd->c.qword0.tunnel_len = tunnel_len;
    1207                 :          0 :         txbd->c.qword1.cmd |= RNP_CTRL_DESC;
    1208                 :            : }
    1209                 :            : 
    1210                 :            : static void
    1211                 :          0 : rnp_padding_hdr_len(volatile struct rnp_tx_desc *txbd,
    1212                 :            :                     struct rte_mbuf *m)
    1213                 :            : {
    1214                 :            :         struct rte_ether_hdr *eth_hdr = NULL;
    1215                 :            :         struct rte_vlan_hdr *vlan_hdr = NULL;
    1216                 :            :         int ethertype, l2_len;
    1217                 :            :         uint16_t l3_len = 0;
    1218                 :            : 
    1219         [ #  # ]:          0 :         if (m->l2_len == 0) {
    1220                 :          0 :                 eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
    1221                 :            :                 l2_len = RTE_ETHER_HDR_LEN;
    1222                 :          0 :                 ethertype = rte_le_to_cpu_32(eth_hdr->ether_type);
    1223         [ #  # ]:          0 :                 if (ethertype == RTE_ETHER_TYPE_VLAN) {
    1224                 :          0 :                         vlan_hdr = rte_pktmbuf_mtod_offset(m, struct rte_vlan_hdr *,
    1225                 :            :                                         sizeof(struct rte_ether_hdr));
    1226                 :            :                         l2_len += RTE_VLAN_HLEN;
    1227                 :          0 :                         ethertype = vlan_hdr->eth_proto;
    1228                 :            :                 }
    1229      [ #  #  # ]:          0 :                 switch (ethertype) {
    1230                 :          0 :                 case RTE_ETHER_TYPE_IPV4:
    1231                 :            :                         l3_len = sizeof(struct rte_ipv4_hdr);
    1232                 :          0 :                         break;
    1233                 :          0 :                 case RTE_ETHER_TYPE_IPV6:
    1234                 :            :                         l3_len = sizeof(struct rte_ipv6_hdr);
    1235                 :          0 :                         break;
    1236                 :            :                 }
    1237                 :            :         } else {
    1238                 :          0 :                 l2_len = m->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK ?
    1239         [ #  # ]:          0 :                                   m->outer_l2_len : m->l2_len;
    1240                 :          0 :                 l3_len = m->l3_len;
    1241                 :            :         }
    1242                 :          0 :         txbd->d.mac_ip_len = l2_len << RNP_TX_MAC_LEN_S;
    1243                 :          0 :         txbd->d.mac_ip_len |= l3_len;
    1244                 :          0 : }
    1245                 :            : 
    1246                 :            : static void
    1247                 :          0 : rnp_check_inner_eth_hdr(struct rte_mbuf *mbuf,
    1248                 :            :                         volatile struct rnp_tx_desc *txbd)
    1249                 :            : {
    1250                 :            :         struct rte_ether_hdr *eth_hdr;
    1251                 :            :         uint16_t inner_l2_offset = 0;
    1252                 :            :         struct rte_vlan_hdr *vlan_hdr;
    1253                 :            :         uint16_t ext_l2_len = 0;
    1254                 :            :         uint16_t l2_offset = 0;
    1255                 :            :         uint16_t l2_type;
    1256                 :            : 
    1257                 :          0 :         inner_l2_offset = mbuf->outer_l2_len + mbuf->outer_l3_len +
    1258                 :            :                 sizeof(struct rte_udp_hdr) +
    1259                 :            :                 sizeof(struct rte_vxlan_hdr);
    1260                 :          0 :         eth_hdr = rte_pktmbuf_mtod_offset(mbuf,
    1261                 :            :                         struct rte_ether_hdr *, inner_l2_offset);
    1262                 :          0 :         l2_type = eth_hdr->ether_type;
    1263                 :          0 :         l2_offset = txbd->d.mac_ip_len >> RNP_TX_MAC_LEN_S;
    1264   [ #  #  #  # ]:          0 :         while (l2_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN) ||
    1265                 :            :                         l2_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_QINQ)) {
    1266                 :          0 :                 vlan_hdr = (struct rte_vlan_hdr *)
    1267                 :            :                         ((char *)eth_hdr + l2_offset);
    1268                 :          0 :                 l2_offset += RTE_VLAN_HLEN;
    1269                 :          0 :                 ext_l2_len += RTE_VLAN_HLEN;
    1270                 :          0 :                 l2_type = vlan_hdr->eth_proto;
    1271                 :            :         }
    1272                 :          0 :         txbd->d.mac_ip_len += (ext_l2_len << RNP_TX_MAC_LEN_S);
    1273                 :          0 : }
    1274                 :            : 
    1275                 :            : #define RNP_TX_L4_OFFLOAD_ALL   (RTE_MBUF_F_TX_SCTP_CKSUM | \
    1276                 :            :                                  RTE_MBUF_F_TX_TCP_CKSUM | \
    1277                 :            :                                  RTE_MBUF_F_TX_UDP_CKSUM)
    1278                 :            : static inline void
    1279                 :          0 : rnp_setup_csum_offload(struct rte_mbuf *mbuf,
    1280                 :            :                        volatile struct rnp_tx_desc *tx_desc)
    1281                 :            : {
    1282                 :          0 :         tx_desc->d.cmd |= (mbuf->ol_flags & RTE_MBUF_F_TX_IP_CKSUM) ?
    1283                 :          0 :                 RNP_TX_IP_CKSUM_EN : 0;
    1284                 :          0 :         tx_desc->d.cmd |= (mbuf->ol_flags & RTE_MBUF_F_TX_IPV6) ?
    1285                 :          0 :                 RNP_TX_L3TYPE_IPV6 : 0;
    1286         [ #  # ]:          0 :         tx_desc->d.cmd |= (mbuf->ol_flags & RNP_TX_L4_OFFLOAD_ALL) ?
    1287                 :            :                 RNP_TX_L4CKSUM_EN : 0;
    1288   [ #  #  #  # ]:          0 :         switch ((mbuf->ol_flags & RTE_MBUF_F_TX_L4_MASK)) {
    1289                 :          0 :         case RTE_MBUF_F_TX_TCP_CKSUM:
    1290                 :          0 :                 tx_desc->d.cmd |= RNP_TX_L4TYPE_TCP;
    1291                 :          0 :                 break;
    1292                 :          0 :         case RTE_MBUF_F_TX_UDP_CKSUM:
    1293                 :          0 :                 tx_desc->d.cmd |= RNP_TX_L4TYPE_UDP;
    1294                 :          0 :                 break;
    1295                 :          0 :         case RTE_MBUF_F_TX_SCTP_CKSUM:
    1296                 :          0 :                 tx_desc->d.cmd |= RNP_TX_L4TYPE_SCTP;
    1297                 :          0 :                 break;
    1298                 :            :         }
    1299                 :          0 :         tx_desc->d.mac_ip_len = mbuf->l2_len << RNP_TX_MAC_LEN_S;
    1300                 :          0 :         tx_desc->d.mac_ip_len |= mbuf->l3_len;
    1301         [ #  # ]:          0 :         if (mbuf->ol_flags & RTE_MBUF_F_TX_TCP_SEG) {
    1302                 :          0 :                 tx_desc->d.cmd |= RNP_TX_IP_CKSUM_EN;
    1303                 :          0 :                 tx_desc->d.cmd |= RNP_TX_L4CKSUM_EN;
    1304                 :          0 :                 tx_desc->d.cmd |= RNP_TX_L4TYPE_TCP;
    1305                 :          0 :                 tx_desc->d.cmd |= RNP_TX_TSO_EN;
    1306                 :            :         }
    1307         [ #  # ]:          0 :         if (mbuf->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) {
    1308                 :            :                 /* need inner l2 l3 lens for inner checksum offload */
    1309                 :          0 :                 tx_desc->d.mac_ip_len &= ~RNP_TX_MAC_LEN_MASK;
    1310                 :          0 :                 tx_desc->d.mac_ip_len |= RTE_ETHER_HDR_LEN << RNP_TX_MAC_LEN_S;
    1311                 :          0 :                 rnp_check_inner_eth_hdr(mbuf, tx_desc);
    1312      [ #  #  # ]:          0 :                 switch (mbuf->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) {
    1313                 :          0 :                 case RTE_MBUF_F_TX_TUNNEL_VXLAN:
    1314                 :          0 :                         tx_desc->d.cmd |= RNP_TX_VXLAN_TUNNEL;
    1315                 :          0 :                         break;
    1316                 :          0 :                 case RTE_MBUF_F_TX_TUNNEL_GRE:
    1317                 :          0 :                         tx_desc->d.cmd |= RNP_TX_NVGRE_TUNNEL;
    1318                 :          0 :                         break;
    1319                 :            :                 }
    1320                 :            :         }
    1321                 :          0 : }
    1322                 :            : 
    1323                 :            : static void
    1324                 :          0 : rnp_setup_tx_offload(struct rnp_tx_queue *txq,
    1325                 :            :                      volatile struct rnp_tx_desc *txbd,
    1326                 :            :                      uint64_t flags, struct rte_mbuf *tx_pkt)
    1327                 :            : {
    1328                 :          0 :         *txbd = txq->zero_desc;
    1329                 :          0 :         if (flags & RTE_MBUF_F_TX_L4_MASK ||
    1330         [ #  # ]:          0 :             flags & RTE_MBUF_F_TX_TCP_SEG ||
    1331                 :            :             flags & RTE_MBUF_F_TX_IP_CKSUM)
    1332                 :          0 :                 rnp_setup_csum_offload(tx_pkt, txbd);
    1333         [ #  # ]:          0 :         if (flags & (RTE_MBUF_F_TX_VLAN |
    1334                 :            :                      RTE_MBUF_F_TX_QINQ)) {
    1335                 :          0 :                 txbd->d.cmd |= RNP_TX_VLAN_VALID;
    1336         [ #  # ]:          0 :                 txbd->d.vlan_tci = (flags & RTE_MBUF_F_TX_QINQ) ?
    1337                 :            :                         tx_pkt->vlan_tci_outer : tx_pkt->vlan_tci;
    1338                 :          0 :                 txbd->d.cmd |= RNP_TX_VLAN_INSERT;
    1339                 :            :         }
    1340                 :          0 : }
    1341                 :            : 
    1342                 :            : static __rte_always_inline uint16_t
    1343                 :          0 : rnp_multiseg_xmit_pkts(void *_txq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
    1344                 :            : {
    1345                 :            :         struct rnp_tx_queue *txq = (struct rnp_tx_queue *)_txq;
    1346                 :            :         volatile struct rnp_tx_desc *txbd;
    1347                 :            :         struct rnp_txsw_entry *txe, *txn;
    1348                 :            :         struct rte_mbuf *tx_pkt, *m_seg;
    1349                 :            :         uint16_t send_pkts = 0;
    1350                 :            :         uint16_t nb_used_bd;
    1351                 :            :         uint8_t ctx_desc_use;
    1352                 :            :         uint8_t first_seg;
    1353                 :            :         uint16_t tx_last;
    1354                 :            :         uint16_t nb_tx;
    1355                 :            :         uint16_t tx_id;
    1356                 :            : 
    1357   [ #  #  #  # ]:          0 :         if (unlikely(!txq->txq_started || !txq->tx_link))
    1358                 :            :                 return 0;
    1359         [ #  # ]:          0 :         if (txq->nb_tx_free < txq->tx_free_thresh)
    1360                 :            :                 rnp_multiseg_clean_txq(txq);
    1361         [ #  # ]:          0 :         if (unlikely(txq->nb_tx_free == 0))
    1362                 :            :                 return 0;
    1363                 :          0 :         tx_id = txq->tx_tail;
    1364                 :          0 :         txbd = &txq->tx_bdr[tx_id];
    1365                 :          0 :         txe = &txq->sw_ring[tx_id];
    1366         [ #  # ]:          0 :         for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
    1367                 :          0 :                 tx_pkt = tx_pkts[nb_tx];
    1368                 :          0 :                 ctx_desc_use = rnp_need_ctrl_desc(tx_pkt->ol_flags);
    1369                 :          0 :                 nb_used_bd = tx_pkt->nb_segs + ctx_desc_use;
    1370                 :          0 :                 tx_last = (uint16_t)(tx_id + nb_used_bd - 1);
    1371         [ #  # ]:          0 :                 if (tx_last >= txq->attr.nb_desc)
    1372                 :          0 :                         tx_last = (uint16_t)(tx_last - txq->attr.nb_desc);
    1373         [ #  # ]:          0 :                 if (nb_used_bd > txq->nb_tx_free)
    1374         [ #  # ]:          0 :                         if (nb_used_bd > rnp_multiseg_clean_txq(txq))
    1375                 :            :                                 break;
    1376         [ #  # ]:          0 :                 if (ctx_desc_use) {
    1377                 :          0 :                         txbd = &txq->tx_bdr[tx_id];
    1378                 :          0 :                         txn = &txq->sw_ring[txe->next_id];
    1379         [ #  # ]:          0 :                         RTE_MBUF_PREFETCH_TO_FREE(txn->mbuf);
    1380         [ #  # ]:          0 :                         if (txe->mbuf) {
    1381                 :            :                                 rte_pktmbuf_free_seg(txe->mbuf);
    1382                 :          0 :                                 txe->mbuf = NULL;
    1383                 :            :                         }
    1384                 :          0 :                         rnp_build_tx_control_desc(txq, txbd, tx_pkt);
    1385                 :          0 :                         txe->last_id = tx_last;
    1386                 :          0 :                         tx_id = txe->next_id;
    1387                 :            :                         txe = txn;
    1388                 :            :                 }
    1389                 :            :                 m_seg = tx_pkt;
    1390                 :            :                 first_seg = 1;
    1391                 :            :                 do {
    1392                 :          0 :                         txbd = &txq->tx_bdr[tx_id];
    1393                 :          0 :                         txbd->d.cmd = 0;
    1394                 :          0 :                         txn = &txq->sw_ring[txe->next_id];
    1395   [ #  #  #  # ]:          0 :                         if ((first_seg && m_seg->ol_flags)) {
    1396                 :          0 :                                 rnp_setup_tx_offload(txq, txbd,
    1397                 :            :                                                 m_seg->ol_flags, m_seg);
    1398         [ #  # ]:          0 :                                 if (!txbd->d.mac_ip_len)
    1399                 :          0 :                                         rnp_padding_hdr_len(txbd, m_seg);
    1400                 :            :                                 first_seg = 0;
    1401                 :            :                         }
    1402         [ #  # ]:          0 :                         if (txe->mbuf) {
    1403                 :            :                                 rte_pktmbuf_free_seg(txe->mbuf);
    1404                 :            :                                 txe->mbuf = NULL;
    1405                 :            :                         }
    1406                 :          0 :                         txe->mbuf = m_seg;
    1407         [ #  # ]:          0 :                         txe->last_id = tx_last;
    1408                 :          0 :                         txbd->d.addr = rnp_get_dma_addr(&txq->attr, m_seg);
    1409                 :          0 :                         txbd->d.blen = rte_cpu_to_le_32(m_seg->data_len);
    1410                 :          0 :                         txbd->d.cmd &= ~RNP_CMD_EOP;
    1411                 :          0 :                         m_seg = m_seg->next;
    1412                 :          0 :                         tx_id = txe->next_id;
    1413                 :            :                         txe = txn;
    1414         [ #  # ]:          0 :                 } while (m_seg != NULL);
    1415                 :          0 :                 txq->stats.obytes += tx_pkt->pkt_len;
    1416                 :          0 :                 txbd->d.cmd |= RNP_CMD_EOP;
    1417                 :          0 :                 txq->nb_tx_used = (uint16_t)txq->nb_tx_used + nb_used_bd;
    1418                 :          0 :                 txq->nb_tx_free = (uint16_t)txq->nb_tx_free - nb_used_bd;
    1419         [ #  # ]:          0 :                 if (txq->nb_tx_used >= txq->tx_rs_thresh) {
    1420                 :          0 :                         txq->nb_tx_used = 0;
    1421                 :          0 :                         txbd->d.cmd |= RNP_CMD_RS;
    1422                 :            :                 }
    1423                 :          0 :                 send_pkts++;
    1424                 :            :         }
    1425         [ #  # ]:          0 :         if (!send_pkts)
    1426                 :            :                 return 0;
    1427                 :          0 :         txq->stats.opackets += send_pkts;
    1428                 :          0 :         txq->tx_tail = tx_id;
    1429                 :            : 
    1430                 :            :         rte_wmb();
    1431                 :          0 :         RNP_REG_WR(txq->tx_tailreg, 0, tx_id);
    1432                 :            : 
    1433                 :          0 :         return send_pkts;
    1434                 :            : }
    1435                 :            : 
    1436                 :            : #define RNP_TX_TUNNEL_NOSUP_TSO_MASK (RTE_MBUF_F_TX_TUNNEL_MASK ^ \
    1437                 :            :                                      (RTE_MBUF_F_TX_TUNNEL_VXLAN | \
    1438                 :            :                                       RTE_MBUF_F_TX_TUNNEL_GRE))
    1439                 :            : static inline bool
    1440                 :          0 : rnp_check_tx_tso_valid(struct rte_mbuf *m)
    1441                 :            : {
    1442                 :          0 :         uint16_t max_seg = m->nb_segs;
    1443                 :            :         uint32_t remain_len = 0;
    1444                 :            :         struct rte_mbuf *m_seg;
    1445                 :            :         uint32_t total_len = 0;
    1446                 :            :         uint32_t limit_len = 0;
    1447                 :            :         uint32_t tso = 0;
    1448                 :            : 
    1449         [ #  # ]:          0 :         if (likely(!(m->ol_flags & RTE_MBUF_F_TX_TCP_SEG))) {
    1450                 :            :                 /* non tso mode */
    1451         [ #  # ]:          0 :                 if (unlikely(m->pkt_len > RNP_MAC_MAXFRM_SIZE)) {
    1452                 :            :                         return false;
    1453         [ #  # ]:          0 :                 } else if (max_seg <= RNP_TX_MAX_MTU_SEG) {
    1454                 :            :                         m_seg = m;
    1455                 :            :                         do {
    1456                 :          0 :                                 total_len += m_seg->data_len;
    1457                 :          0 :                                 m_seg = m_seg->next;
    1458         [ #  # ]:          0 :                         } while (m_seg != NULL);
    1459         [ #  # ]:          0 :                         if (total_len > RNP_MAC_MAXFRM_SIZE)
    1460                 :            :                                 return false;
    1461                 :          0 :                         return true;
    1462                 :            :                 }
    1463                 :            :         } else {
    1464         [ #  # ]:          0 :                 if (unlikely(m->ol_flags & RNP_TX_TUNNEL_NOSUP_TSO_MASK))
    1465                 :            :                         return false;
    1466         [ #  # ]:          0 :                 if (max_seg > RNP_TX_MAX_MTU_SEG)
    1467                 :            :                         return false;
    1468                 :            :                 tso = rnp_cal_tso_seg(m);
    1469                 :            :                 m_seg = m;
    1470                 :            :                 do {
    1471                 :          0 :                         remain_len = RTE_MAX(remain_len, m_seg->data_len % tso);
    1472                 :          0 :                         m_seg = m_seg->next;
    1473         [ #  # ]:          0 :                 } while (m_seg != NULL);
    1474                 :            :                 /* TSO will remain bytes because of tso
    1475                 :            :                  * in this situation must refer the worst condition
    1476                 :            :                  */
    1477                 :          0 :                 limit_len = remain_len * max_seg + tso;
    1478                 :            : 
    1479         [ #  # ]:          0 :                 if (limit_len > RNP_MAX_TSO_PKT)
    1480                 :          0 :                         return false;
    1481                 :            :         }
    1482                 :            : 
    1483                 :            :         return true;
    1484                 :            : }
    1485                 :            : 
    1486                 :            : static inline int
    1487                 :          0 : rnp_net_cksum_flags_prepare(struct rte_mbuf *m, uint64_t ol_flags)
    1488                 :            : {
    1489                 :            :         struct rte_ipv4_hdr *ipv4_hdr = NULL;
    1490                 :          0 :         uint64_t inner_l3_offset = m->l2_len;
    1491                 :            :         struct rte_ipv6_hdr *ipv6_hdr;
    1492                 :            :         struct rte_sctp_hdr *sctp_hdr;
    1493                 :            :         struct rte_tcp_hdr *tcp_hdr;
    1494                 :            :         struct rte_udp_hdr *udp_hdr;
    1495                 :            : 
    1496         [ #  # ]:          0 :         if (!(ol_flags & (RTE_MBUF_F_TX_IP_CKSUM |
    1497                 :            :                           RTE_MBUF_F_TX_L4_MASK |
    1498                 :            :                           RTE_MBUF_F_TX_TCP_SEG)))
    1499                 :            :                 return 0;
    1500         [ #  # ]:          0 :         if (ol_flags & (RTE_MBUF_F_TX_OUTER_IPV4 | RTE_MBUF_F_TX_OUTER_IPV6)) {
    1501         [ #  # ]:          0 :                 if ((ol_flags & RTE_MBUF_F_TX_L4_MASK) ==
    1502                 :          0 :                                 RTE_MBUF_F_TX_TCP_CKSUM ||
    1503         [ #  # ]:          0 :                                 (ol_flags & RTE_MBUF_F_TX_TCP_SEG)) {
    1504                 :            :                         /* hardware must require out-ip cksum is zero
    1505                 :            :                          * when vxlan-tso enable
    1506                 :            :                          */
    1507                 :          0 :                         ipv4_hdr = rte_pktmbuf_mtod_offset(m,
    1508                 :            :                                         struct rte_ipv4_hdr *, m->outer_l2_len);
    1509                 :          0 :                         ipv4_hdr->hdr_checksum = 0;
    1510                 :            :                 }
    1511                 :          0 :                 inner_l3_offset += m->outer_l2_len + m->outer_l3_len;
    1512                 :            :         }
    1513         [ #  # ]:          0 :         if (unlikely(rte_pktmbuf_data_len(m) <
    1514                 :            :                                 inner_l3_offset + m->l3_len + m->l4_len))
    1515                 :            :                 return -ENOTSUP;
    1516         [ #  # ]:          0 :         if (ol_flags & RTE_MBUF_F_TX_IPV4) {
    1517                 :          0 :                 ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *,
    1518                 :            :                                 inner_l3_offset);
    1519         [ #  # ]:          0 :                 if (ol_flags & RTE_MBUF_F_TX_IP_CKSUM)
    1520                 :          0 :                         ipv4_hdr->hdr_checksum = 0;
    1521                 :            :         }
    1522         [ #  # ]:          0 :         if ((ol_flags & RTE_MBUF_F_TX_L4_MASK) == RTE_MBUF_F_TX_UDP_CKSUM) {
    1523         [ #  # ]:          0 :                 if (ol_flags & RTE_MBUF_F_TX_IPV4) {
    1524                 :          0 :                         ipv4_hdr = rte_pktmbuf_mtod_offset(m,
    1525                 :            :                                         struct rte_ipv4_hdr *, inner_l3_offset);
    1526                 :          0 :                         udp_hdr = (struct rte_udp_hdr *)((char *)ipv4_hdr +
    1527                 :            :                                         m->l3_len);
    1528                 :          0 :                         udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(ipv4_hdr,
    1529                 :            :                                         ol_flags);
    1530                 :            :                 } else {
    1531                 :          0 :                         ipv6_hdr = rte_pktmbuf_mtod_offset(m,
    1532                 :            :                                         struct rte_ipv6_hdr *, inner_l3_offset);
    1533                 :            :                         /* non-TSO udp */
    1534                 :          0 :                         udp_hdr = rte_pktmbuf_mtod_offset(m,
    1535                 :            :                                         struct rte_udp_hdr *,
    1536                 :            :                                         inner_l3_offset + m->l3_len);
    1537                 :          0 :                         udp_hdr->dgram_cksum = rte_ipv6_phdr_cksum(ipv6_hdr,
    1538                 :            :                                         ol_flags);
    1539                 :            :                 }
    1540         [ #  # ]:          0 :         } else if ((ol_flags & RTE_MBUF_F_TX_L4_MASK) == RTE_MBUF_F_TX_TCP_CKSUM ||
    1541         [ #  # ]:          0 :                         (ol_flags & RTE_MBUF_F_TX_TCP_SEG)) {
    1542         [ #  # ]:          0 :                 if (ol_flags & RTE_MBUF_F_TX_IPV4) {
    1543                 :            :                         /* non-TSO tcp or TSO */
    1544                 :          0 :                         ipv4_hdr = rte_pktmbuf_mtod_offset(m,
    1545                 :            :                                         struct rte_ipv4_hdr *, inner_l3_offset);
    1546                 :          0 :                         tcp_hdr = (struct rte_tcp_hdr *)((char *)ipv4_hdr + m->l3_len);
    1547                 :          0 :                         tcp_hdr->cksum = rte_ipv4_phdr_cksum(ipv4_hdr,
    1548                 :            :                                         ol_flags);
    1549                 :            :                 } else {
    1550                 :          0 :                         ipv6_hdr = rte_pktmbuf_mtod_offset(m,
    1551                 :            :                                         struct rte_ipv6_hdr *, inner_l3_offset);
    1552                 :            :                         /* non-TSO tcp or TSO */
    1553                 :          0 :                         tcp_hdr = rte_pktmbuf_mtod_offset(m,
    1554                 :            :                                         struct rte_tcp_hdr *,
    1555                 :            :                                         inner_l3_offset + m->l3_len);
    1556                 :          0 :                         tcp_hdr->cksum = rte_ipv6_phdr_cksum(ipv6_hdr,
    1557                 :            :                                         ol_flags);
    1558                 :            :                 }
    1559         [ #  # ]:          0 :         } else if ((ol_flags & RTE_MBUF_F_TX_L4_MASK) == RTE_MBUF_F_TX_SCTP_CKSUM) {
    1560         [ #  # ]:          0 :                 if (ol_flags & RTE_MBUF_F_TX_IPV4) {
    1561                 :          0 :                         ipv4_hdr = rte_pktmbuf_mtod_offset(m,
    1562                 :            :                                         struct rte_ipv4_hdr *, inner_l3_offset);
    1563                 :          0 :                         sctp_hdr = (struct rte_sctp_hdr *)((char *)ipv4_hdr +
    1564                 :            :                                         m->l3_len);
    1565                 :            :                         /* SCTP-cksm implement CRC32 */
    1566                 :          0 :                         sctp_hdr->cksum = 0;
    1567                 :            :                 } else {
    1568                 :          0 :                         ipv6_hdr = rte_pktmbuf_mtod_offset(m,
    1569                 :            :                                         struct rte_ipv6_hdr *, inner_l3_offset);
    1570                 :            :                         /* NON-TSO SCTP */
    1571                 :          0 :                         sctp_hdr = rte_pktmbuf_mtod_offset(m,
    1572                 :            :                                         struct rte_sctp_hdr *,
    1573                 :            :                                         inner_l3_offset + m->l3_len);
    1574                 :          0 :                         sctp_hdr->cksum = 0;
    1575                 :            :                 }
    1576                 :            :         }
    1577         [ #  # ]:          0 :         if (ol_flags & RTE_MBUF_F_TX_IP_CKSUM && !(ol_flags &
    1578                 :            :                                 (RTE_MBUF_F_TX_L4_MASK | RTE_MBUF_F_TX_TCP_SEG))) {
    1579                 :            :                 /* the hardware L4 is follow on l3 checksum.
    1580                 :            :                  * when ol_flags set hw L3, sw l4 checksum offload,
    1581                 :            :                  * we must prepare pseudo header to avoid
    1582                 :            :                  * the l4 Checksum error
    1583                 :            :                  */
    1584         [ #  # ]:          0 :                 if (ol_flags & RTE_MBUF_F_TX_IPV4) {
    1585                 :          0 :                         ipv4_hdr = rte_pktmbuf_mtod_offset(m,
    1586                 :            :                                         struct rte_ipv4_hdr *, inner_l3_offset);
    1587      [ #  #  # ]:          0 :                         switch (ipv4_hdr->next_proto_id) {
    1588                 :          0 :                         case IPPROTO_UDP:
    1589                 :          0 :                                 udp_hdr = (struct rte_udp_hdr *)((char *)ipv4_hdr +
    1590                 :            :                                                 m->l3_len);
    1591                 :          0 :                                 udp_hdr->dgram_cksum =
    1592                 :          0 :                                         rte_ipv4_phdr_cksum(ipv4_hdr, ol_flags);
    1593                 :          0 :                                 break;
    1594                 :          0 :                         case IPPROTO_TCP:
    1595                 :          0 :                                 tcp_hdr = (struct rte_tcp_hdr *)((char *)ipv4_hdr +
    1596                 :            :                                                 m->l3_len);
    1597                 :          0 :                                 tcp_hdr->cksum = rte_ipv4_phdr_cksum(ipv4_hdr,
    1598                 :            :                                                 ol_flags);
    1599                 :          0 :                                 break;
    1600                 :            :                         default:
    1601                 :            :                                 break;
    1602                 :            :                         }
    1603                 :            :                 } else {
    1604                 :          0 :                         ipv6_hdr = rte_pktmbuf_mtod_offset(m,
    1605                 :            :                                         struct rte_ipv6_hdr *, inner_l3_offset);
    1606      [ #  #  # ]:          0 :                         switch (ipv6_hdr->proto) {
    1607                 :          0 :                         case IPPROTO_UDP:
    1608                 :          0 :                                 udp_hdr = (struct rte_udp_hdr *)((char *)ipv6_hdr +
    1609                 :            :                                                 m->l3_len);
    1610                 :          0 :                                 udp_hdr->dgram_cksum =
    1611                 :          0 :                                         rte_ipv6_phdr_cksum(ipv6_hdr, ol_flags);
    1612                 :          0 :                                 break;
    1613                 :          0 :                         case IPPROTO_TCP:
    1614                 :          0 :                                 tcp_hdr = (struct rte_tcp_hdr *)((char *)ipv6_hdr +
    1615                 :            :                                                 m->l3_len);
    1616                 :          0 :                                 tcp_hdr->cksum = rte_ipv6_phdr_cksum(ipv6_hdr,
    1617                 :            :                                                 ol_flags);
    1618                 :          0 :                                 break;
    1619                 :            :                         default:
    1620                 :            :                                 break;
    1621                 :            :                         }
    1622                 :            :                 }
    1623                 :            :         }
    1624                 :            : 
    1625                 :            :         return 0;
    1626                 :            : }
    1627                 :            : 
    1628                 :            : static uint16_t
    1629                 :          0 : rnp_tx_pkt_prepare(void *tx_queue,
    1630                 :            :                    struct rte_mbuf **tx_pkts,
    1631                 :            :                    uint16_t nb_pkts)
    1632                 :            : {
    1633                 :            :         struct rnp_tx_queue *txq = (struct rnp_tx_queue *)tx_queue;
    1634                 :            :         struct rte_mbuf *m;
    1635                 :            :         int i, ret;
    1636                 :            : 
    1637                 :          0 :         PMD_INIT_FUNC_TRACE();
    1638         [ #  # ]:          0 :         for (i = 0; i < nb_pkts; i++) {
    1639                 :          0 :                 m = tx_pkts[i];
    1640         [ #  # ]:          0 :                 if (unlikely(!rnp_check_tx_tso_valid(m))) {
    1641                 :          0 :                         txq->stats.errors++;
    1642                 :          0 :                         rte_errno = EINVAL;
    1643                 :          0 :                         return i;
    1644                 :            :                 }
    1645         [ #  # ]:          0 :                 if (m->nb_segs > 10) {
    1646                 :          0 :                         txq->stats.errors++;
    1647                 :          0 :                         rte_errno = EINVAL;
    1648                 :          0 :                         return i;
    1649                 :            :                 }
    1650                 :            : #ifdef RTE_ETHDEV_DEBUG_TX
    1651                 :            :                 ret = rte_validate_tx_offload(m);
    1652                 :            :                 if (ret != 0) {
    1653                 :            :                         rte_errno = -ret;
    1654                 :            :                         return i;
    1655                 :            :                 }
    1656                 :            : #endif
    1657                 :          0 :                 ret = rnp_net_cksum_flags_prepare(m, m->ol_flags);
    1658         [ #  # ]:          0 :                 if (ret != 0) {
    1659                 :          0 :                         rte_errno = -ret;
    1660                 :          0 :                         return i;
    1661                 :            :                 }
    1662                 :            :         }
    1663                 :            : 
    1664                 :          0 :         return i;
    1665                 :            : }
    1666                 :            : 
    1667                 :            : static int
    1668                 :            : rnp_check_rx_simple_valid(struct rte_eth_dev *dev)
    1669                 :            : {
    1670                 :          0 :         uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
    1671                 :            : 
    1672         [ #  # ]:          0 :         if (dev->data->scattered_rx || rx_offloads & RTE_ETH_RX_OFFLOAD_SCATTER)
    1673                 :            :                 return -ENOTSUP;
    1674                 :            :         return 0;
    1675                 :            : }
    1676                 :            : 
    1677         [ #  # ]:          0 : int rnp_rx_func_select(struct rte_eth_dev *dev)
    1678                 :            : {
    1679                 :            :         bool simple_allowed = false;
    1680                 :            : 
    1681                 :            :         simple_allowed = rnp_check_rx_simple_valid(dev) == 0;
    1682                 :            :         if (simple_allowed)
    1683                 :          0 :                 dev->rx_pkt_burst = rnp_recv_pkts;
    1684                 :            :         else
    1685                 :          0 :                 dev->rx_pkt_burst = rnp_scattered_rx;
    1686                 :            : 
    1687                 :          0 :         return 0;
    1688                 :            : }
    1689                 :            : 
    1690                 :            : static int
    1691                 :            : rnp_check_tx_simple_valid(struct rte_eth_dev *dev, struct rnp_tx_queue *txq)
    1692                 :            : {
    1693                 :          0 :         uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
    1694                 :            : 
    1695                 :          0 :         tx_offloads |= txq->tx_offloads;
    1696                 :          0 :         if (tx_offloads != RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE)
    1697                 :            :                 return -ENOTSUP;
    1698         [ #  # ]:          0 :         if (dev->data->scattered_rx)
    1699                 :          0 :                 return -ENOTSUP;
    1700                 :            : 
    1701                 :            :         return 0;
    1702                 :            : }
    1703                 :            : 
    1704                 :          0 : int rnp_tx_func_select(struct rte_eth_dev *dev)
    1705                 :            : {
    1706                 :            :         bool simple_allowed = false;
    1707                 :            :         struct rnp_tx_queue *txq;
    1708                 :            :         int idx = 0;
    1709                 :            : 
    1710         [ #  # ]:          0 :         for (idx = 0; idx < dev->data->nb_tx_queues; idx++) {
    1711         [ #  # ]:          0 :                 txq = dev->data->tx_queues[idx];
    1712                 :          0 :                 simple_allowed = rnp_check_tx_simple_valid(dev, txq) == 0;
    1713                 :            :         }
    1714         [ #  # ]:          0 :         if (simple_allowed) {
    1715                 :          0 :                 dev->tx_pkt_burst = rnp_xmit_simple;
    1716                 :            :         } else {
    1717                 :          0 :                 dev->tx_pkt_burst = rnp_multiseg_xmit_pkts;
    1718                 :          0 :                 dev->tx_pkt_prepare = rnp_tx_pkt_prepare;
    1719                 :            :         }
    1720                 :            : 
    1721                 :          0 :         return 0;
    1722                 :            : }
    1723                 :            : 
    1724                 :            : void
    1725                 :          0 : rnp_rx_queue_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
    1726                 :            :                       struct rte_eth_rxq_info *qinfo)
    1727                 :            : {
    1728                 :            :         struct rnp_rx_queue *rxq;
    1729                 :            : 
    1730                 :          0 :         rxq = dev->data->rx_queues[queue_id];
    1731         [ #  # ]:          0 :         if (!rxq)
    1732                 :            :                 return;
    1733                 :          0 :         qinfo->mp = rxq->mb_pool;
    1734                 :          0 :         qinfo->scattered_rx = dev->data->scattered_rx;
    1735                 :          0 :         qinfo->queue_state = rxq->rxq_started;
    1736                 :          0 :         qinfo->nb_desc = rxq->attr.nb_desc;
    1737                 :          0 :         qinfo->rx_buf_size = rxq->rx_buf_len;
    1738                 :            : 
    1739                 :          0 :         qinfo->conf.rx_deferred_start = rxq->rx_deferred_start;
    1740                 :          0 :         qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
    1741                 :          0 :         qinfo->conf.rx_thresh.pthresh = rxq->pthresh;
    1742                 :          0 :         qinfo->conf.rx_thresh.hthresh = rxq->pburst;
    1743                 :          0 :         qinfo->conf.offloads = rxq->rx_offloads;
    1744                 :            : }
    1745                 :            : 
    1746                 :            : void
    1747                 :          0 : rnp_tx_queue_info_get(struct rte_eth_dev *dev, uint16_t queue_id,
    1748                 :            :                       struct rte_eth_txq_info *qinfo)
    1749                 :            : {
    1750                 :            :         struct rnp_tx_queue *txq;
    1751                 :            : 
    1752                 :          0 :         txq = dev->data->tx_queues[queue_id];
    1753         [ #  # ]:          0 :         if (!txq)
    1754                 :            :                 return;
    1755                 :          0 :         qinfo->queue_state = txq->txq_started;
    1756                 :          0 :         qinfo->nb_desc = txq->attr.nb_desc;
    1757                 :            : 
    1758                 :          0 :         qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
    1759                 :          0 :         qinfo->conf.tx_free_thresh = txq->tx_free_thresh;
    1760                 :          0 :         qinfo->conf.tx_rs_thresh = txq->tx_rs_thresh;
    1761                 :          0 :         qinfo->conf.tx_thresh.pthresh = txq->pthresh;
    1762                 :          0 :         qinfo->conf.tx_thresh.hthresh = txq->pburst;
    1763                 :          0 :         qinfo->conf.offloads = txq->tx_offloads;
    1764                 :            : }
    1765                 :            : 
    1766                 :            : static const struct {
    1767                 :            :         eth_rx_burst_t pkt_burst;
    1768                 :            :         const char *info;
    1769                 :            : } rnp_rx_burst_infos[] = {
    1770                 :            :         { rnp_scattered_rx,             "Scalar Scattered" },
    1771                 :            :         { rnp_recv_pkts,                "Scalar" },
    1772                 :            : };
    1773                 :            : 
    1774                 :            : static const struct {
    1775                 :            :         eth_tx_burst_t pkt_burst;
    1776                 :            :         const char *info;
    1777                 :            : } rnp_tx_burst_infos[] = {
    1778                 :            :         { rnp_xmit_simple,              "Scalar Simple" },
    1779                 :            :         { rnp_multiseg_xmit_pkts,       "Scalar" },
    1780                 :            : };
    1781                 :            : 
    1782                 :            : int
    1783                 :          0 : rnp_rx_burst_mode_get(struct rte_eth_dev *dev,
    1784                 :            :                       __rte_unused uint16_t queue_id,
    1785                 :            :                       struct rte_eth_burst_mode *mode)
    1786                 :            : {
    1787                 :          0 :         eth_rx_burst_t pkt_burst = dev->rx_pkt_burst;
    1788                 :            :         int ret = -EINVAL;
    1789                 :            :         unsigned int i;
    1790                 :            : 
    1791         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(rnp_rx_burst_infos); ++i) {
    1792         [ #  # ]:          0 :                 if (pkt_burst == rnp_rx_burst_infos[i].pkt_burst) {
    1793                 :          0 :                         snprintf(mode->info, sizeof(mode->info), "%s",
    1794                 :          0 :                                         rnp_rx_burst_infos[i].info);
    1795                 :            :                         ret = 0;
    1796                 :          0 :                         break;
    1797                 :            :                 }
    1798                 :            :         }
    1799                 :            : 
    1800                 :          0 :         return ret;
    1801                 :            : }
    1802                 :            : 
    1803                 :            : int
    1804                 :          0 : rnp_tx_burst_mode_get(struct rte_eth_dev *dev,
    1805                 :            :                       __rte_unused uint16_t queue_id,
    1806                 :            :                       struct rte_eth_burst_mode *mode)
    1807                 :            : {
    1808                 :          0 :         eth_tx_burst_t pkt_burst = dev->tx_pkt_burst;
    1809                 :            :         int ret = -EINVAL;
    1810                 :            :         unsigned int i;
    1811                 :            : 
    1812         [ #  # ]:          0 :         for (i = 0; i < RTE_DIM(rnp_tx_burst_infos); ++i) {
    1813         [ #  # ]:          0 :                 if (pkt_burst == rnp_tx_burst_infos[i].pkt_burst) {
    1814                 :          0 :                         snprintf(mode->info, sizeof(mode->info), "%s",
    1815                 :          0 :                                         rnp_tx_burst_infos[i].info);
    1816                 :            :                         ret = 0;
    1817                 :          0 :                         break;
    1818                 :            :                 }
    1819                 :            :         }
    1820                 :            : 
    1821                 :          0 :         return ret;
    1822                 :            : }

Generated by: LCOV version 1.14