LCOV - code coverage report
Current view: top level - drivers/net/bnxt - bnxt_rxq.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 329 0.0 %
Date: 2026-10-01 18:19:24 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 209 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2014-2023 Broadcom
       3                 :            :  * All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <inttypes.h>
       7                 :            : 
       8                 :            : #include <rte_malloc.h>
       9                 :            : 
      10                 :            : #include "bnxt.h"
      11                 :            : #include "bnxt_filter.h"
      12                 :            : #include "bnxt_hwrm.h"
      13                 :            : #include "bnxt_ring.h"
      14                 :            : #include "bnxt_rxq.h"
      15                 :            : #include "bnxt_rxr.h"
      16                 :            : #include "bnxt_vnic.h"
      17                 :            : #include "hsi_struct_def_dpdk.h"
      18                 :            : 
      19                 :            : /*
      20                 :            :  * RX Queues
      21                 :            :  */
      22                 :            : 
      23                 :          0 : uint64_t bnxt_get_rx_port_offloads(struct bnxt *bp)
      24                 :            : {
      25                 :            :         uint64_t rx_offload_capa;
      26                 :            : 
      27                 :            :         rx_offload_capa = RTE_ETH_RX_OFFLOAD_IPV4_CKSUM  |
      28                 :            :                           RTE_ETH_RX_OFFLOAD_UDP_CKSUM   |
      29                 :            :                           RTE_ETH_RX_OFFLOAD_TCP_CKSUM   |
      30                 :            :                           RTE_ETH_RX_OFFLOAD_KEEP_CRC    |
      31                 :            :                           RTE_ETH_RX_OFFLOAD_SCATTER |
      32                 :            :                           RTE_ETH_RX_OFFLOAD_RSS_HASH |
      33                 :            :                           RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT;
      34                 :            : 
      35                 :            :         /* In P7 platform if truflow is enabled then vlan offload is disabled*/
      36   [ #  #  #  #  :          0 :         if (!(BNXT_TRUFLOW_EN(bp) && BNXT_CHIP_P7(bp)))
                   #  # ]
      37                 :            :                 rx_offload_capa |= (RTE_ETH_RX_OFFLOAD_VLAN_FILTER |
      38                 :            :                                     RTE_ETH_RX_OFFLOAD_VLAN_EXTEND);
      39                 :            : 
      40                 :            : 
      41                 :          0 :         if (!bnxt_compressed_rx_cqe_mode_enabled(bp) &&
      42   [ #  #  #  # ]:          0 :             BNXT_SUPPORTS_TPA(bp))
      43                 :          0 :                 rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TCP_LRO;
      44         [ #  # ]:          0 :         if (bp->flags & BNXT_FLAG_PTP_SUPPORTED)
      45                 :          0 :                 rx_offload_capa |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
      46         [ #  # ]:          0 :         if (bp->vnic_cap_flags & BNXT_VNIC_CAP_VLAN_RX_STRIP) {
      47   [ #  #  #  #  :          0 :                 if (!(BNXT_TRUFLOW_EN(bp) && BNXT_CHIP_P7(bp)))
                   #  # ]
      48                 :          0 :                         rx_offload_capa |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
      49                 :            :         }
      50                 :            : 
      51         [ #  # ]:          0 :         if (BNXT_TUNNELED_OFFLOADS_CAP_ALL_EN(bp))
      52                 :          0 :                 rx_offload_capa |= RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
      53                 :            :                                         RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM;
      54                 :            : 
      55                 :          0 :         return rx_offload_capa;
      56                 :            : }
      57                 :            : 
      58                 :            : /* Determine whether the current configuration needs aggregation ring in HW. */
      59                 :          0 : int bnxt_need_agg_ring(struct rte_eth_dev *eth_dev)
      60                 :            : {
      61                 :            :         /* scattered_rx will be true if OFFLOAD_SCATTER is enabled,
      62                 :            :          * if LRO is enabled, or if the max packet len is greater than the
      63                 :            :          * mbuf data size. So AGG ring will be needed whenever scattered_rx
      64                 :            :          * is set.
      65                 :            :          */
      66                 :          0 :         return eth_dev->data->scattered_rx ? 1 : 0;
      67                 :            : }
      68                 :            : 
      69                 :          0 : void bnxt_free_rxq_stats(struct bnxt_rx_queue *rxq)
      70                 :            : {
      71   [ #  #  #  #  :          0 :         if (rxq && rxq->cp_ring && rxq->cp_ring->hw_stats)
                   #  # ]
      72                 :          0 :                 rxq->cp_ring->hw_stats = NULL;
      73                 :          0 : }
      74                 :            : 
      75                 :          0 : int bnxt_mq_rx_configure(struct bnxt *bp)
      76                 :            : {
      77                 :          0 :         struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
      78                 :            :         struct rte_eth_rss_conf *rss = &bp->rss_conf;
      79                 :            :         const struct rte_eth_vmdq_rx_conf *conf =
      80                 :            :                     &dev_conf->rx_adv_conf.vmdq_rx_conf;
      81                 :            :         unsigned int i, j, nb_q_per_grp = 1, ring_idx = 0;
      82                 :            :         int start_grp_id, end_grp_id = 1, rc = 0;
      83                 :            :         struct bnxt_vnic_info *vnic;
      84                 :            :         struct bnxt_filter_info *filter;
      85                 :            :         enum rte_eth_nb_pools pools = 1, max_pools = 0;
      86                 :            :         struct bnxt_rx_queue *rxq;
      87                 :            : 
      88                 :          0 :         bp->nr_vnics = 0;
      89                 :            : 
      90                 :            :         /* Multi-queue mode */
      91         [ #  # ]:          0 :         if (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_DCB_RSS) {
      92                 :            :                 /* VMDq ONLY, VMDq+RSS, VMDq+DCB, VMDq+DCB+RSS */
      93                 :            : 
      94      [ #  #  # ]:          0 :                 switch (dev_conf->rxmode.mq_mode) {
      95                 :          0 :                 case RTE_ETH_MQ_RX_VMDQ_RSS:
      96                 :            :                 case RTE_ETH_MQ_RX_VMDQ_ONLY:
      97                 :            :                 case RTE_ETH_MQ_RX_VMDQ_DCB_RSS:
      98                 :            :                         /* FALLTHROUGH */
      99                 :            :                         /* ETH_8/64_POOLs */
     100                 :          0 :                         pools = conf->nb_queue_pools;
     101                 :            :                         /* For each pool, allocate MACVLAN CFA rule & VNIC */
     102                 :          0 :                         max_pools = RTE_MIN(bp->max_vnics,
     103                 :            :                                             RTE_MIN(bp->max_l2_ctx,
     104                 :            :                                             RTE_MIN(bp->max_rsscos_ctx,
     105                 :            :                                                     RTE_ETH_64_POOLS)));
     106                 :          0 :                         PMD_DRV_LOG_LINE(DEBUG,
     107                 :            :                                     "pools = %u max_pools = %u",
     108                 :            :                                     pools, max_pools);
     109                 :            :                         if (pools > max_pools)
     110                 :            :                                 pools = max_pools;
     111                 :            :                         break;
     112                 :          0 :                 case RTE_ETH_MQ_RX_RSS:
     113         [ #  # ]:          0 :                         pools = bp->rx_cosq_cnt ? bp->rx_cosq_cnt : 1;
     114                 :            :                         break;
     115                 :          0 :                 default:
     116                 :          0 :                         PMD_DRV_LOG_LINE(ERR, "Unsupported mq_mod %d",
     117                 :            :                                 dev_conf->rxmode.mq_mode);
     118                 :            :                         rc = -EINVAL;
     119                 :          0 :                         goto err_out;
     120                 :            :                 }
     121         [ #  # ]:          0 :         } else if (!dev_conf->rxmode.mq_mode) {
     122         [ #  # ]:          0 :                 pools = bp->rx_cosq_cnt ? bp->rx_cosq_cnt : pools;
     123                 :            :         }
     124                 :            : 
     125                 :          0 :         pools = RTE_MIN(pools, bp->rx_cp_nr_rings);
     126                 :          0 :         nb_q_per_grp = bp->rx_cp_nr_rings / pools;
     127                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "pools = %u nb_q_per_grp = %u",
     128                 :            :                     pools, nb_q_per_grp);
     129                 :            :         start_grp_id = 0;
     130                 :          0 :         end_grp_id = nb_q_per_grp;
     131                 :            : 
     132         [ #  # ]:          0 :         for (i = 0; i < pools; i++) {
     133                 :          0 :                 vnic = &bp->vnic_info[i];
     134                 :          0 :                 vnic->flags |= BNXT_VNIC_INFO_BCAST;
     135                 :          0 :                 bp->nr_vnics++;
     136                 :            : 
     137         [ #  # ]:          0 :                 for (j = 0; j < nb_q_per_grp; j++, ring_idx++) {
     138                 :          0 :                         rxq = bp->eth_dev->data->rx_queues[ring_idx];
     139                 :          0 :                         rxq->vnic = vnic;
     140                 :          0 :                         PMD_DRV_LOG_LINE(DEBUG,
     141                 :            :                                     "rxq[%d] = %p vnic[%d] = %p",
     142                 :            :                                     ring_idx, rxq, i, vnic);
     143                 :            :                 }
     144         [ #  # ]:          0 :                 if (i == 0) {
     145         [ #  # ]:          0 :                         if (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_DCB) {
     146                 :          0 :                                 bp->eth_dev->data->promiscuous = 1;
     147                 :          0 :                                 vnic->flags |= BNXT_VNIC_INFO_PROMISC;
     148                 :            :                         }
     149                 :          0 :                         vnic->func_default = true;
     150                 :            :                 }
     151                 :          0 :                 vnic->start_grp_id = start_grp_id;
     152                 :          0 :                 vnic->end_grp_id = end_grp_id;
     153                 :            : 
     154         [ #  # ]:          0 :                 if (i) {
     155         [ #  # ]:          0 :                         if (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_VMDQ_DCB ||
     156                 :            :                             !(dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS))
     157                 :          0 :                                 vnic->rss_dflt_cr = true;
     158                 :          0 :                         goto skip_filter_allocation;
     159                 :            :                 }
     160                 :          0 :                 filter = bnxt_alloc_filter(bp);
     161         [ #  # ]:          0 :                 if (!filter) {
     162                 :          0 :                         PMD_DRV_LOG_LINE(ERR, "L2 filter alloc failed");
     163                 :            :                         rc = -ENOMEM;
     164                 :          0 :                         goto err_out;
     165                 :            :                 }
     166                 :          0 :                 filter->mac_index = 0;
     167                 :          0 :                 filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST;
     168                 :            :                 /*
     169                 :            :                  * TODO: Configure & associate CFA rule for
     170                 :            :                  * each VNIC for each VMDq with MACVLAN, MACVLAN+TC
     171                 :            :                  */
     172                 :          0 :                 STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
     173                 :            : 
     174                 :          0 : skip_filter_allocation:
     175                 :            :                 start_grp_id = end_grp_id;
     176                 :          0 :                 end_grp_id += nb_q_per_grp;
     177                 :            :         }
     178                 :            : 
     179                 :          0 :         bp->rx_num_qs_per_vnic = nb_q_per_grp;
     180                 :            : 
     181         [ #  # ]:          0 :         for (i = 0; i < bp->nr_vnics; i++) {
     182                 :          0 :                 uint32_t lvl = RTE_ETH_RSS_LEVEL(rss->rss_hf);
     183                 :            : 
     184                 :          0 :                 vnic = &bp->vnic_info[i];
     185                 :          0 :                 vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss->rss_hf);
     186                 :          0 :                 vnic->hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss->rss_hf, lvl);
     187                 :            : 
     188                 :            :                 /*
     189                 :            :                  * Use the supplied key if the key length is
     190                 :            :                  * acceptable and the rss_key is not NULL
     191                 :            :                  */
     192   [ #  #  #  # ]:          0 :                 if (rss->rss_key && rss->rss_key_len <= HW_HASH_KEY_SIZE)
     193                 :          0 :                         memcpy(vnic->rss_hash_key, rss->rss_key, rss->rss_key_len);
     194                 :            :         }
     195                 :            : 
     196                 :            :         return rc;
     197                 :            : 
     198                 :            : err_out:
     199                 :            :         /* Free allocated vnic/filters */
     200                 :            : 
     201                 :            :         return rc;
     202                 :            : }
     203                 :            : 
     204                 :          0 : void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq)
     205                 :            : {
     206                 :            :         struct rte_mbuf **sw_ring;
     207                 :            :         struct bnxt_tpa_info *tpa_info;
     208                 :            :         uint16_t i;
     209                 :            : 
     210   [ #  #  #  # ]:          0 :         if (!rxq || !rxq->rx_ring)
     211                 :            :                 return;
     212                 :            : 
     213                 :          0 :         sw_ring = rxq->rx_ring->rx_buf_ring;
     214         [ #  # ]:          0 :         if (sw_ring) {
     215                 :            : #if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
     216                 :            :                 /*
     217                 :            :                  * The vector receive burst function does not set used
     218                 :            :                  * mbuf pointers to NULL, do that here to simplify
     219                 :            :                  * cleanup logic.
     220                 :            :                  */
     221         [ #  # ]:          0 :                 for (i = 0; i < rxq->rxrearm_nb; i++)
     222                 :          0 :                         sw_ring[rxq->rxrearm_start + i] = NULL;
     223                 :          0 :                 rxq->rxrearm_nb = 0;
     224                 :            : #endif
     225                 :          0 :                 for (i = 0;
     226         [ #  # ]:          0 :                      i < rxq->rx_ring->rx_ring_struct->ring_size; i++) {
     227         [ #  # ]:          0 :                         if (sw_ring[i]) {
     228         [ #  # ]:          0 :                                 if (sw_ring[i] != &rxq->fake_mbuf)
     229                 :            :                                         rte_pktmbuf_free_seg(sw_ring[i]);
     230                 :          0 :                                 sw_ring[i] = NULL;
     231                 :            :                         }
     232                 :            :                 }
     233                 :            :         }
     234                 :            :         /* Free up mbufs in Agg ring */
     235         [ #  # ]:          0 :         if (rxq->bp == NULL ||
     236   [ #  #  #  # ]:          0 :             rxq->bp->eth_dev == NULL ||
     237                 :          0 :             !bnxt_need_agg_ring(rxq->bp->eth_dev))
     238                 :          0 :                 return;
     239                 :            : 
     240                 :          0 :         sw_ring = rxq->rx_ring->ag_buf_ring;
     241         [ #  # ]:          0 :         if (sw_ring) {
     242                 :            :                 for (i = 0;
     243         [ #  # ]:          0 :                      i < rxq->rx_ring->ag_ring_struct->ring_size; i++) {
     244         [ #  # ]:          0 :                         if (sw_ring[i]) {
     245                 :            :                                 rte_pktmbuf_free_seg(sw_ring[i]);
     246                 :          0 :                                 sw_ring[i] = NULL;
     247                 :            :                         }
     248                 :            :                 }
     249                 :            :         }
     250                 :            : 
     251         [ #  # ]:          0 :         if (bnxt_compressed_rx_cqe_mode_enabled(rxq->bp))
     252                 :            :                 return;
     253                 :            : 
     254                 :            :         /* Free up mbufs in TPA */
     255                 :          0 :         tpa_info = rxq->rx_ring->tpa_info;
     256         [ #  # ]:          0 :         if (tpa_info) {
     257         [ #  # ]:          0 :                 int max_aggs = BNXT_TPA_MAX_AGGS(rxq->bp);
     258                 :            : 
     259         [ #  # ]:          0 :                 for (i = 0; i < max_aggs; i++) {
     260         [ #  # ]:          0 :                         if (tpa_info[i].mbuf) {
     261                 :            :                                 rte_pktmbuf_free_seg(tpa_info[i].mbuf);
     262                 :          0 :                                 tpa_info[i].mbuf = NULL;
     263                 :            :                         }
     264                 :            :                 }
     265                 :            :         }
     266                 :            : 
     267                 :            : }
     268                 :            : 
     269                 :          0 : void bnxt_free_rx_mbufs(struct bnxt *bp)
     270                 :            : {
     271                 :            :         struct bnxt_rx_queue *rxq;
     272                 :            :         int i;
     273                 :            : 
     274         [ #  # ]:          0 :         for (i = 0; i < (int)bp->rx_nr_rings; i++) {
     275                 :          0 :                 rxq = bp->rx_queues[i];
     276                 :          0 :                 bnxt_rx_queue_release_mbufs(rxq);
     277                 :            :         }
     278                 :          0 : }
     279                 :            : 
     280                 :          0 : void bnxt_free_rxq_mem(struct bnxt_rx_queue *rxq)
     281                 :            : {
     282                 :          0 :         bnxt_rx_queue_release_mbufs(rxq);
     283                 :            : 
     284                 :            :         /* Free RX, AGG ring hardware descriptors */
     285         [ #  # ]:          0 :         if (rxq->rx_ring) {
     286                 :          0 :                 bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
     287                 :          0 :                 rte_free(rxq->rx_ring->rx_ring_struct);
     288                 :          0 :                 rxq->rx_ring->rx_ring_struct = NULL;
     289                 :            :                 /* Free RX Agg ring hardware descriptors */
     290                 :          0 :                 bnxt_free_ring(rxq->rx_ring->ag_ring_struct);
     291                 :          0 :                 rte_free(rxq->rx_ring->ag_ring_struct);
     292                 :          0 :                 rxq->rx_ring->ag_ring_struct = NULL;
     293                 :            : 
     294                 :          0 :                 rte_free(rxq->rx_ring);
     295                 :          0 :                 rxq->rx_ring = NULL;
     296                 :            :         }
     297                 :            :         /* Free RX completion ring hardware descriptors */
     298         [ #  # ]:          0 :         if (rxq->cp_ring) {
     299                 :          0 :                 bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
     300                 :          0 :                 rte_free(rxq->cp_ring->cp_ring_struct);
     301                 :          0 :                 rxq->cp_ring->cp_ring_struct = NULL;
     302                 :          0 :                 rte_free(rxq->cp_ring);
     303                 :          0 :                 rxq->cp_ring = NULL;
     304                 :            :         }
     305                 :            : 
     306                 :          0 :         bnxt_free_rxq_stats(rxq);
     307                 :          0 :         rte_memzone_free(rxq->mz);
     308                 :          0 :         rxq->mz = NULL;
     309                 :          0 : }
     310                 :            : 
     311                 :          0 : void bnxt_rx_queue_release_op(struct rte_eth_dev *dev, uint16_t queue_idx)
     312                 :            : {
     313                 :          0 :         struct bnxt_rx_queue *rxq = dev->data->rx_queues[queue_idx];
     314                 :            : 
     315         [ #  # ]:          0 :         if (rxq != NULL) {
     316         [ #  # ]:          0 :                 if (is_bnxt_in_error(rxq->bp))
     317                 :            :                         return;
     318                 :            : 
     319                 :          0 :                 bnxt_free_hwrm_rx_ring(rxq->bp, rxq->queue_id);
     320                 :          0 :                 bnxt_free_rxq_mem(rxq);
     321                 :          0 :                 rte_free(rxq);
     322                 :            :         }
     323                 :            : }
     324                 :            : 
     325                 :          0 : int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
     326                 :            :                                uint16_t queue_idx,
     327                 :            :                                uint16_t nb_desc,
     328                 :            :                                unsigned int socket_id,
     329                 :            :                                const struct rte_eth_rxconf *rx_conf,
     330                 :            :                                struct rte_mempool *mp)
     331                 :            : {
     332                 :          0 :         uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads;
     333                 :          0 :         uint8_t rs = !!(rx_offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT);
     334                 :          0 :         struct bnxt *bp = eth_dev->data->dev_private;
     335                 :          0 :         struct rte_eth_rxseg_split *rx_seg =
     336                 :            :                         (struct rte_eth_rxseg_split *)rx_conf->rx_seg;
     337                 :          0 :         uint16_t n_seg = rx_conf->rx_nseg;
     338                 :            :         struct bnxt_rx_queue *rxq;
     339                 :            :         int rc = 0;
     340                 :            : 
     341                 :          0 :         rc = is_bnxt_in_error(bp);
     342         [ #  # ]:          0 :         if (rc)
     343                 :            :                 return rc;
     344                 :            : 
     345         [ #  # ]:          0 :         if (n_seg > 1 && !rs) {
     346                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "n_seg %d does not match buffer split %d setting",
     347                 :            :                                 n_seg, rs);
     348                 :          0 :                 return -EINVAL;
     349                 :            :         }
     350                 :            : 
     351         [ #  # ]:          0 :         if (n_seg > BNXT_MAX_BUFFER_SPLIT_SEGS) {
     352                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "n_seg %d not supported", n_seg);
     353                 :          0 :                 return -EINVAL;
     354                 :            :         }
     355                 :            : 
     356         [ #  # ]:          0 :         if (queue_idx >= bnxt_max_rings(bp)) {
     357                 :          0 :                 PMD_DRV_LOG_LINE(ERR,
     358                 :            :                         "Cannot create Rx ring %d. Only %d rings available",
     359                 :            :                         queue_idx, bp->max_rx_rings);
     360                 :          0 :                 return -EINVAL;
     361                 :            :         }
     362                 :            : 
     363         [ #  # ]:          0 :         if (nb_desc < BNXT_MIN_RING_DESC || nb_desc > MAX_RX_DESC_CNT) {
     364                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "nb_desc %d is invalid", nb_desc);
     365                 :          0 :                 return -EINVAL;
     366                 :            :         }
     367                 :            : 
     368                 :          0 :         rxq = eth_dev->data->rx_queues[queue_idx];
     369         [ #  # ]:          0 :         if (rxq)
     370                 :          0 :                 bnxt_rx_queue_release_op(eth_dev, queue_idx);
     371                 :          0 :         rxq = rte_zmalloc_socket("bnxt_rx_queue", sizeof(struct bnxt_rx_queue),
     372                 :            :                                  RTE_CACHE_LINE_SIZE, socket_id);
     373         [ #  # ]:          0 :         if (!rxq) {
     374                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "bnxt_rx_queue allocation failed!");
     375                 :          0 :                 return -ENOMEM;
     376                 :            :         }
     377                 :          0 :         rxq->bp = bp;
     378         [ #  # ]:          0 :         if (n_seg > 1) {
     379                 :          0 :                 rxq->mb_pool = rx_seg[BNXT_MEM_POOL_IDX_0].mp;
     380                 :          0 :                 rxq->agg_mb_pool = rx_seg[BNXT_MEM_POOL_IDX_1].mp;
     381                 :            :         } else {
     382                 :          0 :                 rxq->mb_pool = mp;
     383                 :          0 :                 rxq->agg_mb_pool = mp;
     384                 :            :         }
     385                 :            : 
     386                 :          0 :         rxq->nb_rx_desc = nb_desc;
     387                 :          0 :         rxq->rx_free_thresh =
     388                 :          0 :                 RTE_MIN(rte_align32pow2(nb_desc) / 4, RTE_BNXT_MAX_RX_BURST);
     389                 :            : 
     390                 :          0 :         PMD_DRV_LOG_LINE(DEBUG,
     391                 :            :                     "App supplied RXQ drop_en status : %d", rx_conf->rx_drop_en);
     392                 :          0 :         rxq->drop_en = BNXT_DEFAULT_RX_DROP_EN;
     393                 :            : 
     394                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "RX Buf MTU %d", eth_dev->data->mtu);
     395                 :            : 
     396                 :          0 :         eth_dev->data->rx_queues[queue_idx] = rxq;
     397                 :            : 
     398                 :          0 :         rc = bnxt_init_rx_ring_struct(rxq, socket_id);
     399         [ #  # ]:          0 :         if (rc) {
     400                 :          0 :                 PMD_DRV_LOG_LINE(ERR,
     401                 :            :                             "init_rx_ring_struct failed!");
     402                 :          0 :                 goto err;
     403                 :            :         }
     404                 :            : 
     405                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "RX Buf size is %d", rxq->rx_buf_size);
     406                 :          0 :         rxq->queue_id = queue_idx;
     407                 :          0 :         rxq->port_id = eth_dev->data->port_id;
     408         [ #  # ]:          0 :         if (rx_offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
     409                 :          0 :                 rxq->crc_len = RTE_ETHER_CRC_LEN;
     410                 :            :         else
     411                 :          0 :                 rxq->crc_len = 0;
     412                 :            : 
     413                 :            :         /* Allocate RX ring hardware descriptors */
     414                 :          0 :         rc = bnxt_alloc_rings(bp, socket_id, queue_idx, NULL, rxq, rxq->cp_ring,
     415                 :            :                               NULL, "rxr");
     416         [ #  # ]:          0 :         if (rc) {
     417                 :          0 :                 PMD_DRV_LOG_LINE(ERR,
     418                 :            :                             "ring_dma_zone_reserve for rx_ring failed!");
     419                 :          0 :                 goto err;
     420                 :            :         }
     421                 :          0 :         rxq->rx_mbuf_alloc_fail = 0;
     422                 :          0 :         rxq->epoch = 0;
     423                 :            : 
     424                 :            :         /* rxq 0 must not be stopped when used as async CPR */
     425                 :            :         if (!BNXT_NUM_ASYNC_CPR(bp) && queue_idx == 0)
     426                 :            :                 rxq->rx_deferred_start = false;
     427                 :            :         else
     428                 :          0 :                 rxq->rx_deferred_start = rx_conf->rx_deferred_start;
     429                 :            : 
     430                 :          0 :         rxq->rx_started = rxq->rx_deferred_start ? false : true;
     431                 :          0 :         rxq->vnic = bnxt_get_default_vnic(bp);
     432         [ #  # ]:          0 :         rxq->vnic->hds_threshold = n_seg ? rxq->vnic->hds_threshold : 0;
     433                 :            : 
     434                 :          0 :         return 0;
     435                 :          0 : err:
     436                 :          0 :         bnxt_rx_queue_release_op(eth_dev, queue_idx);
     437                 :          0 :         return rc;
     438                 :            : }
     439                 :            : 
     440                 :            : int
     441                 :          0 : bnxt_rx_queue_intr_enable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id)
     442                 :            : {
     443                 :          0 :         struct bnxt *bp = eth_dev->data->dev_private;
     444                 :            :         struct bnxt_rx_queue *rxq;
     445                 :            :         struct bnxt_cp_ring_info *cpr;
     446                 :            :         int rc = 0;
     447                 :            : 
     448                 :          0 :         rc = is_bnxt_in_error(bp);
     449         [ #  # ]:          0 :         if (rc)
     450                 :            :                 return rc;
     451                 :            : 
     452         [ #  # ]:          0 :         if (eth_dev->data->rx_queues) {
     453                 :          0 :                 rxq = eth_dev->data->rx_queues[queue_id];
     454         [ #  # ]:          0 :                 if (!rxq)
     455                 :            :                         return -EINVAL;
     456                 :            : 
     457                 :          0 :                 cpr = rxq->cp_ring;
     458         [ #  # ]:          0 :                 if (BNXT_CHIP_P5_P7(bp)) {
     459                 :          0 :                         struct bnxt_cp_ring_info *nqr = bp->rxtx_nq_ring;
     460                 :            : 
     461                 :          0 :                         bnxt_arm_nq_p5p(nqr, 1);
     462                 :          0 :                         bnxt_arm_rx_cq_p5p(rxq->cp_ring, 1);
     463                 :            :                 } else {
     464                 :          0 :                         B_CP_DB_ARM(cpr);
     465                 :            :                 }
     466                 :            :         }
     467                 :            :         return rc;
     468                 :            : }
     469                 :            : 
     470                 :            : int
     471                 :          0 : bnxt_rx_queue_intr_disable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id)
     472                 :            : {
     473                 :          0 :         struct bnxt *bp = eth_dev->data->dev_private;
     474                 :            :         struct bnxt_rx_queue *rxq;
     475                 :            :         struct bnxt_cp_ring_info *cpr;
     476                 :            :         int rc = 0;
     477                 :            : 
     478                 :          0 :         rc = is_bnxt_in_error(bp);
     479         [ #  # ]:          0 :         if (rc)
     480                 :            :                 return rc;
     481                 :            : 
     482         [ #  # ]:          0 :         if (eth_dev->data->rx_queues) {
     483                 :          0 :                 rxq = eth_dev->data->rx_queues[queue_id];
     484         [ #  # ]:          0 :                 if (!rxq)
     485                 :            :                         return -EINVAL;
     486                 :            : 
     487                 :          0 :                 cpr = rxq->cp_ring;
     488         [ #  # ]:          0 :                 if (BNXT_CHIP_P5_P7(bp)) {
     489                 :          0 :                         struct bnxt_cp_ring_info *nqr = bp->rxtx_nq_ring;
     490                 :            :                         struct bnxt_cp_ring_info *rx_cpr;
     491                 :            : 
     492                 :          0 :                         bnxt_arm_nq_p5p(nqr, 0);
     493                 :            :                         /* Loops through all RXQs and finds the one that
     494                 :            :                          * received a packet if any
     495                 :            :                          */
     496                 :          0 :                         uint32_t cons = RING_CMPL(nqr->cp_ring_struct->ring_mask,
     497                 :            :                                         nqr->cp_raw_cons);
     498                 :          0 :                         struct cmpl_base *cmpl = &((nqr->cp_desc_ring)[cons]);
     499                 :            : 
     500         [ #  # ]:          0 :                         if (CMPL_VALID(cmpl, nqr->valid)) {
     501                 :            :                                 unsigned int rxid = 0;
     502                 :            : 
     503                 :          0 :                                 rx_cpr = rxq->cp_ring;
     504         [ #  # ]:          0 :                                 for (; rxid < bp->rx_nr_rings; rxid++) {
     505                 :          0 :                                         rxq = bp->rx_queues[rxid];
     506                 :          0 :                                         rx_cpr = rxq->cp_ring;
     507                 :          0 :                                         cons = RING_CMPL(rx_cpr->cp_ring_struct->ring_mask,
     508                 :            :                                                          rx_cpr->cp_raw_cons);
     509                 :          0 :                                         cmpl = &((rx_cpr->cp_desc_ring)[cons]);
     510                 :            :                                         /* Because the valid bit in the rx
     511                 :            :                                          * completion queue is not updated the
     512                 :            :                                          * cmp valid using raw cons is used
     513                 :            :                                          */
     514         [ #  # ]:          0 :                                         if (bnxt_cpr_cmp_valid(cmpl,
     515                 :            :                                                                rx_cpr->cp_raw_cons,
     516                 :            :                                                                rx_cpr->cp_ring_struct->ring_size)) {
     517                 :            :                                                 break;
     518                 :            :                                         }
     519                 :            :                                 }
     520                 :          0 :                                 bnxt_process_nq(bp, nqr, rx_cpr);
     521                 :            :                         }
     522                 :            :                 } else {
     523                 :          0 :                         B_CP_DB_DISARM(cpr);
     524                 :            :                 }
     525                 :            :         }
     526                 :            :         return rc;
     527                 :            : }
     528                 :            : 
     529                 :          0 : int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
     530                 :            : {
     531                 :          0 :         struct bnxt *bp = dev->data->dev_private;
     532                 :          0 :         struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
     533                 :          0 :         struct bnxt_rx_queue *rxq = bp->rx_queues[rx_queue_id];
     534                 :            :         struct bnxt_vnic_info *vnic = NULL;
     535                 :          0 :         uint16_t vnic_idx = 0;
     536                 :            :         uint16_t fw_grp_id = 0;
     537                 :            :         int rc = 0;
     538                 :            : 
     539                 :          0 :         rc = is_bnxt_in_error(bp);
     540         [ #  # ]:          0 :         if (rc)
     541                 :            :                 return rc;
     542                 :            : 
     543         [ #  # ]:          0 :         if (rxq == NULL) {
     544                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "Invalid Rx queue %d", rx_queue_id);
     545                 :          0 :                 return -EINVAL;
     546                 :            :         }
     547                 :            : 
     548                 :          0 :         vnic = bnxt_vnic_queue_id_get_next(bp, rx_queue_id, &vnic_idx);
     549         [ #  # ]:          0 :         if (vnic == NULL) {
     550                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "VNIC not initialized for RxQ %d",
     551                 :            :                             rx_queue_id);
     552                 :          0 :                 return -EINVAL;
     553                 :            :         }
     554                 :            : 
     555                 :            :         /* reset the previous stats for the rx_queue since the counters
     556                 :            :          * will be cleared when the queue is started.
     557                 :            :          */
     558   [ #  #  #  # ]:          0 :         if (BNXT_TPA_V2_P7(bp))
     559                 :          0 :                 memset(&bp->prev_rx_ring_stats_ext[rx_queue_id], 0,
     560                 :            :                        sizeof(struct bnxt_ring_stats_ext));
     561                 :            :         else
     562                 :          0 :                 memset(&bp->prev_rx_ring_stats[rx_queue_id], 0,
     563                 :            :                        sizeof(struct bnxt_ring_stats));
     564                 :            : 
     565                 :            :         /* Set the queue state to started here.
     566                 :            :          * We check the status of the queue while posting buffer.
     567                 :            :          * If queue is it started, we do not post buffers for Rx.
     568                 :            :          */
     569                 :          0 :         rxq->rx_started = true;
     570                 :          0 :         dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
     571                 :            : 
     572                 :          0 :         bnxt_free_hwrm_rx_ring(bp, rx_queue_id);
     573                 :          0 :         rc = bnxt_alloc_hwrm_rx_ring(bp, rx_queue_id);
     574         [ #  # ]:          0 :         if (rc)
     575                 :            :                 return rc;
     576                 :            : 
     577         [ #  # ]:          0 :         if (BNXT_HAS_RING_GRPS(bp))
     578                 :          0 :                 fw_grp_id = bp->grp_info[rx_queue_id].fw_grp_id;
     579                 :            : 
     580                 :            :         do {
     581         [ #  # ]:          0 :                 if (BNXT_HAS_RING_GRPS(bp))
     582                 :          0 :                         vnic->dflt_ring_grp = fw_grp_id;
     583                 :            :                 /* Reconfigure default receive ring and MRU. */
     584                 :          0 :                 bnxt_hwrm_vnic_cfg(bp, vnic);
     585                 :            : 
     586                 :          0 :                 PMD_DRV_LOG_LINE(INFO, "Rx queue started %d", rx_queue_id);
     587                 :            : 
     588         [ #  # ]:          0 :                 if (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) {
     589         [ #  # ]:          0 :                         if (BNXT_HAS_RING_GRPS(bp)) {
     590         [ #  # ]:          0 :                                 if (vnic->fw_grp_ids[rx_queue_id] !=
     591                 :            :                                     INVALID_HW_RING_ID) {
     592                 :          0 :                                         PMD_DRV_LOG_LINE(ERR, "invalid ring id %d",
     593                 :            :                                                     rx_queue_id);
     594                 :          0 :                                         return 0;
     595                 :            :                                 }
     596                 :            : 
     597                 :          0 :                                 vnic->fw_grp_ids[rx_queue_id] = fw_grp_id;
     598                 :          0 :                                 PMD_DRV_LOG_LINE(DEBUG, "vnic = %p fw_grp_id = %d",
     599                 :            :                                             vnic, fw_grp_id);
     600                 :            :                         }
     601                 :            : 
     602                 :          0 :                         PMD_DRV_LOG_LINE(DEBUG, "Rx Queue Count %d",
     603                 :            :                                     vnic->rx_queue_cnt);
     604                 :          0 :                         rc += bnxt_vnic_rss_queue_status_update(bp, vnic);
     605                 :            :                 }
     606                 :          0 :                 vnic_idx++;
     607                 :          0 :         } while ((vnic = bnxt_vnic_queue_id_get_next(bp, rx_queue_id,
     608         [ #  # ]:          0 :                                                      &vnic_idx)) != NULL);
     609                 :            : 
     610         [ #  # ]:          0 :         if (rc != 0) {
     611                 :          0 :                 dev->data->rx_queue_state[rx_queue_id] =
     612                 :            :                                 RTE_ETH_QUEUE_STATE_STOPPED;
     613                 :          0 :                 rxq->rx_started = false;
     614                 :            :         }
     615                 :            : 
     616                 :          0 :         PMD_DRV_LOG_LINE(INFO,
     617                 :            :                     "queue %d, rx_deferred_start %d, state %d!",
     618                 :            :                     rx_queue_id, rxq->rx_deferred_start,
     619                 :            :                     bp->eth_dev->data->rx_queue_state[rx_queue_id]);
     620                 :            : 
     621                 :          0 :         return rc;
     622                 :            : }
     623                 :            : 
     624                 :          0 : int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
     625                 :            : {
     626                 :          0 :         struct bnxt *bp = dev->data->dev_private;
     627                 :          0 :         struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
     628                 :            :         struct bnxt_vnic_info *vnic = NULL;
     629                 :            :         struct bnxt_rx_queue *rxq = NULL;
     630                 :            :         int active_queue_cnt = 0;
     631                 :          0 :         uint16_t vnic_idx = 0, q_id = rx_queue_id;
     632                 :            :         int i, rc = 0;
     633                 :            : 
     634                 :          0 :         rc = is_bnxt_in_error(bp);
     635         [ #  # ]:          0 :         if (rc)
     636                 :            :                 return rc;
     637                 :            : 
     638                 :            :         /* For the stingray platform and other platforms needing tighter
     639                 :            :          * control of resource utilization, Rx CQ 0 also works as
     640                 :            :          * Default CQ for async notifications
     641                 :            :          */
     642                 :            :         if (!BNXT_NUM_ASYNC_CPR(bp) && !rx_queue_id) {
     643                 :            :                 PMD_DRV_LOG_LINE(ERR, "Cannot stop Rx queue id %d", rx_queue_id);
     644                 :            :                 return -EINVAL;
     645                 :            :         }
     646                 :            : 
     647                 :          0 :         rxq = bp->rx_queues[rx_queue_id];
     648         [ #  # ]:          0 :         if (!rxq) {
     649                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "Invalid Rx queue %d", rx_queue_id);
     650                 :          0 :                 return -EINVAL;
     651                 :            :         }
     652                 :            : 
     653                 :          0 :         vnic = bnxt_vnic_queue_id_get_next(bp, q_id, &vnic_idx);
     654         [ #  # ]:          0 :         if (!vnic) {
     655                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "VNIC not initialized for RxQ %d", q_id);
     656                 :          0 :                 return -EINVAL;
     657                 :            :         }
     658                 :            : 
     659         [ #  # ]:          0 :         __rte_assume(q_id < RTE_MAX_QUEUES_PER_PORT);
     660                 :          0 :         dev->data->rx_queue_state[q_id] = RTE_ETH_QUEUE_STATE_STOPPED;
     661                 :          0 :         rxq->rx_started = false;
     662                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "Rx queue stopped");
     663                 :            : 
     664                 :            :         do {
     665                 :            :                 active_queue_cnt = 0;
     666         [ #  # ]:          0 :                 if (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) {
     667         [ #  # ]:          0 :                         if (BNXT_HAS_RING_GRPS(bp))
     668                 :          0 :                                 vnic->fw_grp_ids[q_id] = INVALID_HW_RING_ID;
     669                 :            : 
     670                 :          0 :                         PMD_DRV_LOG_LINE(DEBUG, "Rx Queue Count %d",
     671                 :            :                                     vnic->rx_queue_cnt);
     672                 :          0 :                         rc = bnxt_vnic_rss_queue_status_update(bp, vnic);
     673                 :            :                 }
     674                 :            : 
     675                 :            :                 /* Compute current number of active receive queues. */
     676         [ #  # ]:          0 :                 for (i = vnic->start_grp_id; i < vnic->end_grp_id; i++)
     677         [ #  # ]:          0 :                         if (bp->rx_queues[i]->rx_started)
     678                 :          0 :                                 active_queue_cnt++;
     679                 :            : 
     680         [ #  # ]:          0 :                 if (BNXT_CHIP_P5_P7(bp)) {
     681                 :            :                         /*
     682                 :            :                          * For P5, we need to ensure that the VNIC default
     683                 :            :                          * receive ring corresponds to an active receive queue.
     684                 :            :                          * When no queue is active, we need to temporarily set
     685                 :            :                          * the MRU to zero so that packets are dropped early in
     686                 :            :                          * the receive pipeline in order to prevent the VNIC
     687                 :            :                          * default receive ring from being accessed.
     688                 :            :                          */
     689         [ #  # ]:          0 :                         if (active_queue_cnt == 0) {
     690                 :          0 :                                 uint16_t saved_mru = vnic->mru;
     691                 :            : 
     692                 :            :                                 /* clear RSS setting on vnic. */
     693                 :          0 :                                 bnxt_vnic_rss_clear_p5(bp, vnic);
     694                 :            : 
     695                 :          0 :                                 vnic->mru = 0;
     696                 :            :                                 /* Reconfigure default receive ring and MRU. */
     697                 :          0 :                                 bnxt_hwrm_vnic_cfg(bp, vnic);
     698                 :          0 :                                 vnic->mru = saved_mru;
     699                 :            :                         } else {
     700                 :            :                                 /* Reconfigure default receive ring. */
     701                 :          0 :                                 bnxt_hwrm_vnic_cfg(bp, vnic);
     702                 :            :                         }
     703         [ #  # ]:          0 :                 } else if (active_queue_cnt && vnic->dflt_ring_grp ==
     704         [ #  # ]:          0 :                            bp->grp_info[q_id].fw_grp_id) {
     705                 :            :                         /*
     706                 :            :                          * If the queue being stopped is the current default
     707                 :            :                          * queue and there are other active queues, pick one of
     708                 :            :                          * them as the default and reconfigure the vnic.
     709                 :            :                          */
     710         [ #  # ]:          0 :                         for (i = vnic->start_grp_id; i < vnic->end_grp_id;
     711                 :          0 :                               i++) {
     712         [ #  # ]:          0 :                                 if (bp->rx_queues[i]->rx_started) {
     713                 :          0 :                                         vnic->dflt_ring_grp =
     714                 :          0 :                                                 bp->grp_info[i].fw_grp_id;
     715                 :          0 :                                         bnxt_hwrm_vnic_cfg(bp, vnic);
     716                 :          0 :                                         break;
     717                 :            :                                 }
     718                 :            :                         }
     719                 :            :                 }
     720                 :          0 :                 vnic_idx++;
     721                 :          0 :         } while ((vnic = bnxt_vnic_queue_id_get_next(bp, q_id,
     722         [ #  # ]:          0 :                                                      &vnic_idx)) != NULL);
     723                 :            : 
     724         [ #  # ]:          0 :         if (rc == 0)
     725                 :          0 :                 bnxt_rx_queue_release_mbufs(rxq);
     726                 :            : 
     727                 :            :         return rc;
     728                 :            : }

Generated by: LCOV version 1.14