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-01-02 22:41:34 Functions: 0 13 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 203 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 :                 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                 :            : 
     429                 :            :         /* rxq 0 must not be stopped when used as async CPR */
     430                 :            :         if (!BNXT_NUM_ASYNC_CPR(bp) && queue_idx == 0)
     431                 :            :                 rxq->rx_deferred_start = false;
     432                 :            :         else
     433                 :          0 :                 rxq->rx_deferred_start = rx_conf->rx_deferred_start;
     434                 :            : 
     435                 :          0 :         rxq->rx_started = rxq->rx_deferred_start ? false : true;
     436                 :          0 :         rxq->vnic = bnxt_get_default_vnic(bp);
     437         [ #  # ]:          0 :         rxq->vnic->hds_threshold = n_seg ? rxq->vnic->hds_threshold : 0;
     438                 :            : 
     439                 :          0 :         return 0;
     440                 :          0 : err:
     441                 :          0 :         bnxt_rx_queue_release_op(eth_dev, queue_idx);
     442                 :          0 :         return rc;
     443                 :            : }
     444                 :            : 
     445                 :            : int
     446                 :          0 : bnxt_rx_queue_intr_enable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id)
     447                 :            : {
     448                 :          0 :         struct bnxt *bp = eth_dev->data->dev_private;
     449                 :            :         struct bnxt_rx_queue *rxq;
     450                 :            :         struct bnxt_cp_ring_info *cpr;
     451                 :            :         int rc = 0;
     452                 :            : 
     453                 :          0 :         rc = is_bnxt_in_error(bp);
     454         [ #  # ]:          0 :         if (rc)
     455                 :            :                 return rc;
     456                 :            : 
     457         [ #  # ]:          0 :         if (eth_dev->data->rx_queues) {
     458                 :          0 :                 rxq = eth_dev->data->rx_queues[queue_id];
     459         [ #  # ]:          0 :                 if (!rxq)
     460                 :            :                         return -EINVAL;
     461                 :            : 
     462                 :          0 :                 cpr = rxq->cp_ring;
     463         [ #  # ]:          0 :                 B_CP_DB_REARM(cpr, cpr->cp_raw_cons);
     464                 :            :         }
     465                 :            :         return rc;
     466                 :            : }
     467                 :            : 
     468                 :            : int
     469                 :          0 : bnxt_rx_queue_intr_disable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id)
     470                 :            : {
     471                 :          0 :         struct bnxt *bp = eth_dev->data->dev_private;
     472                 :            :         struct bnxt_rx_queue *rxq;
     473                 :            :         struct bnxt_cp_ring_info *cpr;
     474                 :            :         int rc = 0;
     475                 :            : 
     476                 :          0 :         rc = is_bnxt_in_error(bp);
     477         [ #  # ]:          0 :         if (rc)
     478                 :            :                 return rc;
     479                 :            : 
     480         [ #  # ]:          0 :         if (eth_dev->data->rx_queues) {
     481                 :          0 :                 rxq = eth_dev->data->rx_queues[queue_id];
     482         [ #  # ]:          0 :                 if (!rxq)
     483                 :            :                         return -EINVAL;
     484                 :            : 
     485                 :          0 :                 cpr = rxq->cp_ring;
     486                 :          0 :                 B_CP_DB_DISARM(cpr);
     487                 :            :         }
     488                 :            :         return rc;
     489                 :            : }
     490                 :            : 
     491                 :          0 : int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
     492                 :            : {
     493                 :          0 :         struct bnxt *bp = dev->data->dev_private;
     494                 :          0 :         struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
     495                 :          0 :         struct bnxt_rx_queue *rxq = bp->rx_queues[rx_queue_id];
     496                 :            :         struct bnxt_vnic_info *vnic = NULL;
     497                 :          0 :         uint16_t vnic_idx = 0;
     498                 :            :         uint16_t fw_grp_id = 0;
     499                 :            :         int rc = 0;
     500                 :            : 
     501                 :          0 :         rc = is_bnxt_in_error(bp);
     502         [ #  # ]:          0 :         if (rc)
     503                 :            :                 return rc;
     504                 :            : 
     505         [ #  # ]:          0 :         if (rxq == NULL) {
     506                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "Invalid Rx queue %d", rx_queue_id);
     507                 :          0 :                 return -EINVAL;
     508                 :            :         }
     509                 :            : 
     510                 :          0 :         vnic = bnxt_vnic_queue_id_get_next(bp, rx_queue_id, &vnic_idx);
     511         [ #  # ]:          0 :         if (vnic == NULL) {
     512                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "VNIC not initialized for RxQ %d",
     513                 :            :                             rx_queue_id);
     514                 :          0 :                 return -EINVAL;
     515                 :            :         }
     516                 :            : 
     517                 :            :         /* reset the previous stats for the rx_queue since the counters
     518                 :            :          * will be cleared when the queue is started.
     519                 :            :          */
     520   [ #  #  #  # ]:          0 :         if (BNXT_TPA_V2_P7(bp))
     521                 :          0 :                 memset(&bp->prev_rx_ring_stats_ext[rx_queue_id], 0,
     522                 :            :                        sizeof(struct bnxt_ring_stats_ext));
     523                 :            :         else
     524                 :          0 :                 memset(&bp->prev_rx_ring_stats[rx_queue_id], 0,
     525                 :            :                        sizeof(struct bnxt_ring_stats));
     526                 :            : 
     527                 :            :         /* Set the queue state to started here.
     528                 :            :          * We check the status of the queue while posting buffer.
     529                 :            :          * If queue is it started, we do not post buffers for Rx.
     530                 :            :          */
     531                 :          0 :         rxq->rx_started = true;
     532                 :          0 :         dev->data->rx_queue_state[rx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
     533                 :            : 
     534                 :          0 :         bnxt_free_hwrm_rx_ring(bp, rx_queue_id);
     535                 :          0 :         rc = bnxt_alloc_hwrm_rx_ring(bp, rx_queue_id);
     536         [ #  # ]:          0 :         if (rc)
     537                 :            :                 return rc;
     538                 :            : 
     539         [ #  # ]:          0 :         if (BNXT_HAS_RING_GRPS(bp))
     540                 :          0 :                 fw_grp_id = bp->grp_info[rx_queue_id].fw_grp_id;
     541                 :            : 
     542                 :            :         do {
     543         [ #  # ]:          0 :                 if (BNXT_HAS_RING_GRPS(bp))
     544                 :          0 :                         vnic->dflt_ring_grp = fw_grp_id;
     545                 :            :                 /* Reconfigure default receive ring and MRU. */
     546                 :          0 :                 bnxt_hwrm_vnic_cfg(bp, vnic);
     547                 :            : 
     548                 :          0 :                 PMD_DRV_LOG_LINE(INFO, "Rx queue started %d", rx_queue_id);
     549                 :            : 
     550         [ #  # ]:          0 :                 if (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) {
     551         [ #  # ]:          0 :                         if (BNXT_HAS_RING_GRPS(bp)) {
     552         [ #  # ]:          0 :                                 if (vnic->fw_grp_ids[rx_queue_id] !=
     553                 :            :                                     INVALID_HW_RING_ID) {
     554                 :          0 :                                         PMD_DRV_LOG_LINE(ERR, "invalid ring id %d",
     555                 :            :                                                     rx_queue_id);
     556                 :          0 :                                         return 0;
     557                 :            :                                 }
     558                 :            : 
     559                 :          0 :                                 vnic->fw_grp_ids[rx_queue_id] = fw_grp_id;
     560                 :          0 :                                 PMD_DRV_LOG_LINE(DEBUG, "vnic = %p fw_grp_id = %d",
     561                 :            :                                             vnic, fw_grp_id);
     562                 :            :                         }
     563                 :            : 
     564                 :          0 :                         PMD_DRV_LOG_LINE(DEBUG, "Rx Queue Count %d",
     565                 :            :                                     vnic->rx_queue_cnt);
     566                 :          0 :                         rc += bnxt_vnic_rss_queue_status_update(bp, vnic);
     567                 :            :                 }
     568                 :          0 :                 vnic_idx++;
     569                 :          0 :         } while ((vnic = bnxt_vnic_queue_id_get_next(bp, rx_queue_id,
     570         [ #  # ]:          0 :                                                      &vnic_idx)) != NULL);
     571                 :            : 
     572         [ #  # ]:          0 :         if (rc != 0) {
     573                 :          0 :                 dev->data->rx_queue_state[rx_queue_id] =
     574                 :            :                                 RTE_ETH_QUEUE_STATE_STOPPED;
     575                 :          0 :                 rxq->rx_started = false;
     576                 :            :         }
     577                 :            : 
     578                 :          0 :         PMD_DRV_LOG_LINE(INFO,
     579                 :            :                     "queue %d, rx_deferred_start %d, state %d!",
     580                 :            :                     rx_queue_id, rxq->rx_deferred_start,
     581                 :            :                     bp->eth_dev->data->rx_queue_state[rx_queue_id]);
     582                 :            : 
     583                 :          0 :         return rc;
     584                 :            : }
     585                 :            : 
     586                 :          0 : int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id)
     587                 :            : {
     588                 :          0 :         struct bnxt *bp = dev->data->dev_private;
     589                 :          0 :         struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
     590                 :            :         struct bnxt_vnic_info *vnic = NULL;
     591                 :            :         struct bnxt_rx_queue *rxq = NULL;
     592                 :            :         int active_queue_cnt = 0;
     593                 :          0 :         uint16_t vnic_idx = 0, q_id = rx_queue_id;
     594                 :            :         int i, rc = 0;
     595                 :            : 
     596                 :          0 :         rc = is_bnxt_in_error(bp);
     597         [ #  # ]:          0 :         if (rc)
     598                 :            :                 return rc;
     599                 :            : 
     600                 :            :         /* For the stingray platform and other platforms needing tighter
     601                 :            :          * control of resource utilization, Rx CQ 0 also works as
     602                 :            :          * Default CQ for async notifications
     603                 :            :          */
     604                 :            :         if (!BNXT_NUM_ASYNC_CPR(bp) && !rx_queue_id) {
     605                 :            :                 PMD_DRV_LOG_LINE(ERR, "Cannot stop Rx queue id %d", rx_queue_id);
     606                 :            :                 return -EINVAL;
     607                 :            :         }
     608                 :            : 
     609                 :          0 :         rxq = bp->rx_queues[rx_queue_id];
     610         [ #  # ]:          0 :         if (!rxq) {
     611                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "Invalid Rx queue %d", rx_queue_id);
     612                 :          0 :                 return -EINVAL;
     613                 :            :         }
     614                 :            : 
     615                 :          0 :         vnic = bnxt_vnic_queue_id_get_next(bp, q_id, &vnic_idx);
     616         [ #  # ]:          0 :         if (!vnic) {
     617                 :          0 :                 PMD_DRV_LOG_LINE(ERR, "VNIC not initialized for RxQ %d", q_id);
     618                 :          0 :                 return -EINVAL;
     619                 :            :         }
     620                 :            : 
     621         [ #  # ]:          0 :         __rte_assume(q_id < RTE_MAX_QUEUES_PER_PORT);
     622                 :          0 :         dev->data->rx_queue_state[q_id] = RTE_ETH_QUEUE_STATE_STOPPED;
     623                 :          0 :         rxq->rx_started = false;
     624                 :          0 :         PMD_DRV_LOG_LINE(DEBUG, "Rx queue stopped");
     625                 :            : 
     626                 :            :         do {
     627                 :            :                 active_queue_cnt = 0;
     628         [ #  # ]:          0 :                 if (dev_conf->rxmode.mq_mode & RTE_ETH_MQ_RX_RSS_FLAG) {
     629         [ #  # ]:          0 :                         if (BNXT_HAS_RING_GRPS(bp))
     630                 :          0 :                                 vnic->fw_grp_ids[q_id] = INVALID_HW_RING_ID;
     631                 :            : 
     632                 :          0 :                         PMD_DRV_LOG_LINE(DEBUG, "Rx Queue Count %d",
     633                 :            :                                     vnic->rx_queue_cnt);
     634                 :          0 :                         rc = bnxt_vnic_rss_queue_status_update(bp, vnic);
     635                 :            :                 }
     636                 :            : 
     637                 :            :                 /* Compute current number of active receive queues. */
     638         [ #  # ]:          0 :                 for (i = vnic->start_grp_id; i < vnic->end_grp_id; i++)
     639         [ #  # ]:          0 :                         if (bp->rx_queues[i]->rx_started)
     640                 :          0 :                                 active_queue_cnt++;
     641                 :            : 
     642         [ #  # ]:          0 :                 if (BNXT_CHIP_P5_P7(bp)) {
     643                 :            :                         /*
     644                 :            :                          * For P5, we need to ensure that the VNIC default
     645                 :            :                          * receive ring corresponds to an active receive queue.
     646                 :            :                          * When no queue is active, we need to temporarily set
     647                 :            :                          * the MRU to zero so that packets are dropped early in
     648                 :            :                          * the receive pipeline in order to prevent the VNIC
     649                 :            :                          * default receive ring from being accessed.
     650                 :            :                          */
     651         [ #  # ]:          0 :                         if (active_queue_cnt == 0) {
     652                 :          0 :                                 uint16_t saved_mru = vnic->mru;
     653                 :            : 
     654                 :            :                                 /* clear RSS setting on vnic. */
     655                 :          0 :                                 bnxt_vnic_rss_clear_p5(bp, vnic);
     656                 :            : 
     657                 :          0 :                                 vnic->mru = 0;
     658                 :            :                                 /* Reconfigure default receive ring and MRU. */
     659                 :          0 :                                 bnxt_hwrm_vnic_cfg(bp, vnic);
     660                 :          0 :                                 vnic->mru = saved_mru;
     661                 :            :                         } else {
     662                 :            :                                 /* Reconfigure default receive ring. */
     663                 :          0 :                                 bnxt_hwrm_vnic_cfg(bp, vnic);
     664                 :            :                         }
     665         [ #  # ]:          0 :                 } else if (active_queue_cnt && vnic->dflt_ring_grp ==
     666         [ #  # ]:          0 :                            bp->grp_info[q_id].fw_grp_id) {
     667                 :            :                         /*
     668                 :            :                          * If the queue being stopped is the current default
     669                 :            :                          * queue and there are other active queues, pick one of
     670                 :            :                          * them as the default and reconfigure the vnic.
     671                 :            :                          */
     672         [ #  # ]:          0 :                         for (i = vnic->start_grp_id; i < vnic->end_grp_id;
     673                 :          0 :                               i++) {
     674         [ #  # ]:          0 :                                 if (bp->rx_queues[i]->rx_started) {
     675                 :          0 :                                         vnic->dflt_ring_grp =
     676                 :          0 :                                                 bp->grp_info[i].fw_grp_id;
     677                 :          0 :                                         bnxt_hwrm_vnic_cfg(bp, vnic);
     678                 :          0 :                                         break;
     679                 :            :                                 }
     680                 :            :                         }
     681                 :            :                 }
     682                 :          0 :                 vnic_idx++;
     683                 :          0 :         } while ((vnic = bnxt_vnic_queue_id_get_next(bp, q_id,
     684         [ #  # ]:          0 :                                                      &vnic_idx)) != NULL);
     685                 :            : 
     686         [ #  # ]:          0 :         if (rc == 0)
     687                 :          0 :                 bnxt_rx_queue_release_mbufs(rxq);
     688                 :            : 
     689                 :            :         return rc;
     690                 :            : }

Generated by: LCOV version 1.14