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

Generated by: LCOV version 1.14