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

Generated by: LCOV version 1.14