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

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

Generated by: LCOV version 1.14