LCOV - code coverage report
Current view: top level - drivers/net/nfp/nfd3 - nfp_nfd3_dp.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 186 0.0 %
Date: 2024-01-22 16:26:08 Functions: 0 7 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 104 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright (c) 2023 Corigine, Inc.
       3                 :            :  * All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "nfp_nfd3.h"
       7                 :            : 
       8                 :            : #include <bus_pci_driver.h>
       9                 :            : #include <rte_malloc.h>
      10                 :            : 
      11                 :            : #include "../flower/nfp_flower.h"
      12                 :            : #include "../nfp_logs.h"
      13                 :            : 
      14                 :            : /* Flags in the host TX descriptor */
      15                 :            : #define NFD3_DESC_TX_CSUM               RTE_BIT32(7)
      16                 :            : #define NFD3_DESC_TX_IP4_CSUM           RTE_BIT32(6)
      17                 :            : #define NFD3_DESC_TX_TCP_CSUM           RTE_BIT32(5)
      18                 :            : #define NFD3_DESC_TX_UDP_CSUM           RTE_BIT32(4)
      19                 :            : #define NFD3_DESC_TX_VLAN               RTE_BIT32(3)
      20                 :            : #define NFD3_DESC_TX_LSO                RTE_BIT32(2)
      21                 :            : #define NFD3_DESC_TX_ENCAP              RTE_BIT32(1)
      22                 :            : #define NFD3_DESC_TX_O_IP4_CSUM         RTE_BIT32(0)
      23                 :            : 
      24                 :            : /* Set NFD3 TX descriptor for TSO */
      25                 :            : static void
      26                 :          0 : nfp_net_nfd3_tx_tso(struct nfp_net_txq *txq,
      27                 :            :                 struct nfp_net_nfd3_tx_desc *txd,
      28                 :            :                 struct rte_mbuf *mb)
      29                 :            : {
      30                 :            :         uint64_t ol_flags;
      31                 :          0 :         struct nfp_net_hw *hw = txq->hw;
      32                 :            : 
      33         [ #  # ]:          0 :         if ((hw->super.cap & NFP_NET_CFG_CTRL_LSO_ANY) == 0)
      34                 :          0 :                 goto clean_txd;
      35                 :            : 
      36                 :          0 :         ol_flags = mb->ol_flags;
      37         [ #  # ]:          0 :         if ((ol_flags & RTE_MBUF_F_TX_TCP_SEG) == 0)
      38                 :          0 :                 goto clean_txd;
      39                 :            : 
      40                 :          0 :         txd->l3_offset = mb->l2_len;
      41                 :          0 :         txd->l4_offset = mb->l2_len + mb->l3_len;
      42                 :          0 :         txd->lso_hdrlen = mb->l2_len + mb->l3_len + mb->l4_len;
      43                 :            : 
      44         [ #  # ]:          0 :         if ((ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) != 0) {
      45                 :          0 :                 txd->l3_offset += mb->outer_l2_len + mb->outer_l3_len;
      46                 :          0 :                 txd->l4_offset += mb->outer_l2_len + mb->outer_l3_len;
      47                 :          0 :                 txd->lso_hdrlen += mb->outer_l2_len + mb->outer_l3_len;
      48                 :            :         }
      49                 :            : 
      50                 :          0 :         txd->mss = rte_cpu_to_le_16(mb->tso_segsz);
      51                 :          0 :         txd->flags = NFD3_DESC_TX_LSO;
      52                 :            : 
      53                 :          0 :         return;
      54                 :            : 
      55                 :          0 : clean_txd:
      56                 :          0 :         txd->flags = 0;
      57                 :          0 :         txd->l3_offset = 0;
      58                 :          0 :         txd->l4_offset = 0;
      59                 :          0 :         txd->lso_hdrlen = 0;
      60                 :          0 :         txd->mss = 0;
      61                 :            : }
      62                 :            : 
      63                 :            : /* Set TX CSUM offload flags in NFD3 TX descriptor */
      64                 :            : static void
      65                 :          0 : nfp_net_nfd3_tx_cksum(struct nfp_net_txq *txq,
      66                 :            :                 struct nfp_net_nfd3_tx_desc *txd,
      67                 :            :                 struct rte_mbuf *mb)
      68                 :            : {
      69                 :            :         uint64_t ol_flags;
      70                 :          0 :         struct nfp_net_hw *hw = txq->hw;
      71                 :            : 
      72         [ #  # ]:          0 :         if ((hw->super.cap & NFP_NET_CFG_CTRL_TXCSUM) == 0)
      73                 :            :                 return;
      74                 :            : 
      75                 :          0 :         ol_flags = mb->ol_flags;
      76                 :            : 
      77                 :            :         /* Set TCP csum offload if TSO enabled. */
      78         [ #  # ]:          0 :         if ((ol_flags & RTE_MBUF_F_TX_TCP_SEG) != 0)
      79                 :          0 :                 txd->flags |= NFD3_DESC_TX_TCP_CSUM;
      80                 :            : 
      81                 :            :         /* IPv6 does not need checksum */
      82         [ #  # ]:          0 :         if ((ol_flags & RTE_MBUF_F_TX_IP_CKSUM) != 0)
      83                 :          0 :                 txd->flags |= NFD3_DESC_TX_IP4_CSUM;
      84                 :            : 
      85         [ #  # ]:          0 :         if ((ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) != 0)
      86                 :          0 :                 txd->flags |= NFD3_DESC_TX_ENCAP;
      87                 :            : 
      88      [ #  #  # ]:          0 :         switch (ol_flags & RTE_MBUF_F_TX_L4_MASK) {
      89                 :          0 :         case RTE_MBUF_F_TX_UDP_CKSUM:
      90                 :          0 :                 txd->flags |= NFD3_DESC_TX_UDP_CSUM;
      91                 :          0 :                 break;
      92                 :          0 :         case RTE_MBUF_F_TX_TCP_CKSUM:
      93                 :          0 :                 txd->flags |= NFD3_DESC_TX_TCP_CSUM;
      94                 :          0 :                 break;
      95                 :            :         }
      96                 :            : 
      97         [ #  # ]:          0 :         if ((ol_flags & (RTE_MBUF_F_TX_IP_CKSUM | RTE_MBUF_F_TX_L4_MASK)) != 0)
      98                 :          0 :                 txd->flags |= NFD3_DESC_TX_CSUM;
      99                 :            : }
     100                 :            : 
     101                 :            : uint32_t
     102         [ #  # ]:          0 : nfp_flower_nfd3_pkt_add_metadata(struct rte_mbuf *mbuf,
     103                 :            :                 uint32_t port_id)
     104                 :            : {
     105                 :            :         char *meta_offset;
     106                 :            : 
     107                 :            :         meta_offset = rte_pktmbuf_prepend(mbuf, FLOWER_PKT_DATA_OFFSET);
     108                 :          0 :         *(rte_be32_t *)meta_offset = rte_cpu_to_be_32(NFP_NET_META_PORTID);
     109                 :            :         meta_offset += NFP_NET_META_HEADER_SIZE;
     110         [ #  # ]:          0 :         *(rte_be32_t *)meta_offset = rte_cpu_to_be_32(port_id);
     111                 :            : 
     112                 :          0 :         return FLOWER_PKT_DATA_OFFSET;
     113                 :            : }
     114                 :            : 
     115                 :            : /*
     116                 :            :  * Set vlan info in the nfd3 tx desc
     117                 :            :  *
     118                 :            :  * If enable NFP_NET_CFG_CTRL_TXVLAN_V2
     119                 :            :  *   Vlan_info is stored in the meta and is handled in the @nfp_net_nfd3_set_meta_vlan()
     120                 :            :  * else if enable NFP_NET_CFG_CTRL_TXVLAN
     121                 :            :  *   Vlan_info is stored in the tx_desc and is handled in the @nfp_net_nfd3_tx_vlan()
     122                 :            :  */
     123                 :            : static inline void
     124                 :            : nfp_net_nfd3_tx_vlan(struct nfp_net_txq *txq,
     125                 :            :                 struct nfp_net_nfd3_tx_desc *txd,
     126                 :            :                 struct rte_mbuf *mb)
     127                 :            : {
     128                 :          0 :         struct nfp_net_hw *hw = txq->hw;
     129                 :            : 
     130         [ #  # ]:          0 :         if ((hw->super.cap & NFP_NET_CFG_CTRL_TXVLAN_V2) != 0 ||
     131                 :            :                         (hw->super.cap & NFP_NET_CFG_CTRL_TXVLAN) == 0)
     132                 :            :                 return;
     133                 :            : 
     134         [ #  # ]:          0 :         if ((mb->ol_flags & RTE_MBUF_F_TX_VLAN) != 0) {
     135                 :          0 :                 txd->flags |= NFD3_DESC_TX_VLAN;
     136                 :          0 :                 txd->vlan = mb->vlan_tci;
     137                 :            :         }
     138                 :            : }
     139                 :            : 
     140                 :            : static inline void
     141                 :          0 : nfp_net_nfd3_set_meta_data(struct nfp_net_meta_raw *meta_data,
     142                 :            :                 struct nfp_net_txq *txq,
     143                 :            :                 struct rte_mbuf *pkt)
     144                 :            : {
     145                 :            :         char *meta;
     146                 :            :         uint8_t layer = 0;
     147                 :            :         uint32_t meta_info;
     148                 :            :         uint32_t cap_extend;
     149                 :            :         struct nfp_net_hw *hw;
     150                 :            :         uint8_t vlan_layer = 0;
     151                 :            :         uint8_t ipsec_layer = 0;
     152                 :            : 
     153                 :          0 :         hw = txq->hw;
     154                 :          0 :         cap_extend = hw->super.cap_ext;
     155                 :            : 
     156         [ #  # ]:          0 :         if ((pkt->ol_flags & RTE_MBUF_F_TX_VLAN) != 0 &&
     157         [ #  # ]:          0 :                         (hw->super.ctrl & NFP_NET_CFG_CTRL_TXVLAN_V2) != 0) {
     158         [ #  # ]:          0 :                 if (meta_data->length == 0)
     159                 :          0 :                         meta_data->length = NFP_NET_META_HEADER_SIZE;
     160                 :          0 :                 meta_data->length += NFP_NET_META_FIELD_SIZE;
     161                 :          0 :                 meta_data->header |= NFP_NET_META_VLAN;
     162                 :            :         }
     163                 :            : 
     164         [ #  # ]:          0 :         if ((pkt->ol_flags & RTE_MBUF_F_TX_SEC_OFFLOAD) != 0 &&
     165         [ #  # ]:          0 :                         (cap_extend & NFP_NET_CFG_CTRL_IPSEC) != 0) {
     166                 :            :                 uint32_t ipsec_type = NFP_NET_META_IPSEC |
     167                 :            :                                 NFP_NET_META_IPSEC << NFP_NET_META_FIELD_SIZE |
     168                 :            :                                 NFP_NET_META_IPSEC << (2 * NFP_NET_META_FIELD_SIZE);
     169         [ #  # ]:          0 :                 if (meta_data->length == 0)
     170                 :          0 :                         meta_data->length = NFP_NET_META_FIELD_SIZE;
     171                 :          0 :                 uint8_t ipsec_offset = meta_data->length - NFP_NET_META_FIELD_SIZE;
     172                 :          0 :                 meta_data->header |= (ipsec_type << ipsec_offset);
     173                 :          0 :                 meta_data->length += 3 * NFP_NET_META_FIELD_SIZE;
     174                 :            :         }
     175                 :            : 
     176         [ #  # ]:          0 :         if (meta_data->length == 0)
     177                 :            :                 return;
     178                 :            : 
     179                 :          0 :         meta_info = meta_data->header;
     180   [ #  #  #  # ]:          0 :         meta_data->header = rte_cpu_to_be_32(meta_data->header);
     181                 :            :         meta = rte_pktmbuf_prepend(pkt, meta_data->length);
     182                 :          0 :         memcpy(meta, &meta_data->header, sizeof(meta_data->header));
     183                 :          0 :         meta += NFP_NET_META_HEADER_SIZE;
     184                 :            : 
     185         [ #  # ]:          0 :         for (; meta_info != 0; meta_info >>= NFP_NET_META_FIELD_SIZE, layer++,
     186                 :          0 :                         meta += NFP_NET_META_FIELD_SIZE) {
     187      [ #  #  # ]:          0 :                 switch (meta_info & NFP_NET_META_FIELD_MASK) {
     188                 :          0 :                 case NFP_NET_META_VLAN:
     189         [ #  # ]:          0 :                         if (vlan_layer > 0) {
     190                 :          0 :                                 PMD_DRV_LOG(ERR, "At most 1 layers of vlan is supported");
     191                 :          0 :                                 return;
     192                 :            :                         }
     193                 :          0 :                         nfp_net_set_meta_vlan(meta_data, pkt, layer);
     194                 :            :                         vlan_layer++;
     195                 :          0 :                         break;
     196                 :          0 :                 case NFP_NET_META_IPSEC:
     197         [ #  # ]:          0 :                         if (ipsec_layer > 2) {
     198                 :          0 :                                 PMD_DRV_LOG(ERR, "At most 3 layers of ipsec is supported for now.");
     199                 :          0 :                                 return;
     200                 :            :                         }
     201                 :            : 
     202                 :          0 :                         nfp_net_set_meta_ipsec(meta_data, txq, pkt, layer, ipsec_layer);
     203                 :          0 :                         ipsec_layer++;
     204                 :          0 :                         break;
     205                 :          0 :                 default:
     206                 :          0 :                         PMD_DRV_LOG(ERR, "The metadata type not supported");
     207                 :          0 :                         return;
     208                 :            :                 }
     209                 :            : 
     210                 :          0 :                 memcpy(meta, &meta_data->data[layer], sizeof(meta_data->data[layer]));
     211                 :            :         }
     212                 :            : }
     213                 :            : 
     214                 :            : uint16_t
     215                 :          0 : nfp_net_nfd3_xmit_pkts(void *tx_queue,
     216                 :            :                 struct rte_mbuf **tx_pkts,
     217                 :            :                 uint16_t nb_pkts)
     218                 :            : {
     219                 :          0 :         return nfp_net_nfd3_xmit_pkts_common(tx_queue, tx_pkts, nb_pkts, false);
     220                 :            : }
     221                 :            : 
     222                 :            : uint16_t
     223                 :          0 : nfp_net_nfd3_xmit_pkts_common(void *tx_queue,
     224                 :            :                 struct rte_mbuf **tx_pkts,
     225                 :            :                 uint16_t nb_pkts,
     226                 :            :                 bool repr_flag)
     227                 :            : {
     228                 :            :         uint16_t i;
     229                 :            :         uint8_t offset;
     230                 :            :         uint32_t pkt_size;
     231                 :            :         uint16_t dma_size;
     232                 :            :         uint64_t dma_addr;
     233                 :            :         uint16_t free_descs;
     234                 :            :         struct rte_mbuf *pkt;
     235                 :            :         uint16_t issued_descs;
     236                 :            :         struct nfp_net_hw *hw;
     237                 :            :         struct rte_mbuf **lmbuf;
     238                 :            :         struct nfp_net_txq *txq;
     239                 :            :         struct nfp_net_nfd3_tx_desc txd;
     240                 :            :         struct nfp_net_nfd3_tx_desc *txds;
     241                 :            : 
     242                 :            :         txq = tx_queue;
     243                 :          0 :         hw = txq->hw;
     244         [ #  # ]:          0 :         txds = &txq->txds[txq->wr_p];
     245                 :            : 
     246                 :            :         PMD_TX_LOG(DEBUG, "working for queue %hu at pos %d and %hu packets",
     247                 :            :                         txq->qidx, txq->wr_p, nb_pkts);
     248                 :            : 
     249   [ #  #  #  # ]:          0 :         if (nfp_net_nfd3_free_tx_desc(txq) < NFD3_TX_DESC_PER_PKT * nb_pkts ||
     250                 :            :                         nfp_net_nfd3_txq_full(txq))
     251                 :          0 :                 nfp_net_tx_free_bufs(txq);
     252                 :            : 
     253                 :          0 :         free_descs = nfp_net_nfd3_free_tx_desc(txq);
     254         [ #  # ]:          0 :         if (unlikely(free_descs == 0))
     255                 :            :                 return 0;
     256                 :            : 
     257                 :            :         pkt = *tx_pkts;
     258                 :            : 
     259                 :            :         issued_descs = 0;
     260                 :            :         PMD_TX_LOG(DEBUG, "queue: %hu. Sending %hu packets", txq->qidx, nb_pkts);
     261                 :            : 
     262                 :            :         /* Sending packets */
     263         [ #  # ]:          0 :         for (i = 0; i < nb_pkts && free_descs > 0; i++) {
     264                 :            :                 /* Grabbing the mbuf linked to the current descriptor */
     265                 :          0 :                 lmbuf = &txq->txbufs[txq->wr_p].mbuf;
     266                 :            :                 /* Warming the cache for releasing the mbuf later on */
     267         [ #  # ]:          0 :                 RTE_MBUF_PREFETCH_TO_FREE(*lmbuf);
     268                 :            : 
     269                 :          0 :                 pkt = *(tx_pkts + i);
     270                 :            : 
     271         [ #  # ]:          0 :                 if (!repr_flag) {
     272                 :            :                         struct nfp_net_meta_raw meta_data;
     273                 :            :                         memset(&meta_data, 0, sizeof(meta_data));
     274                 :          0 :                         nfp_net_nfd3_set_meta_data(&meta_data, txq, pkt);
     275                 :          0 :                         offset = meta_data.length;
     276                 :            :                 } else {
     277                 :            :                         offset = FLOWER_PKT_DATA_OFFSET;
     278                 :            :                 }
     279                 :            : 
     280   [ #  #  #  # ]:          0 :                 if (unlikely(pkt->nb_segs > 1 &&
     281                 :            :                                 (hw->super.cap & NFP_NET_CFG_CTRL_GATHER) == 0)) {
     282                 :            :                         PMD_TX_LOG(ERR, "Multisegment packet not supported");
     283                 :          0 :                         goto xmit_end;
     284                 :            :                 }
     285                 :            : 
     286                 :            :                 /* Checking if we have enough descriptors */
     287         [ #  # ]:          0 :                 if (unlikely(pkt->nb_segs > free_descs))
     288                 :          0 :                         goto xmit_end;
     289                 :            : 
     290                 :            :                 /*
     291                 :            :                  * Checksum and VLAN flags just in the first descriptor for a
     292                 :            :                  * multisegment packet, but TSO info needs to be in all of them.
     293                 :            :                  */
     294                 :          0 :                 txd.data_len = pkt->pkt_len;
     295                 :          0 :                 nfp_net_nfd3_tx_tso(txq, &txd, pkt);
     296                 :          0 :                 nfp_net_nfd3_tx_cksum(txq, &txd, pkt);
     297                 :            :                 nfp_net_nfd3_tx_vlan(txq, &txd, pkt);
     298                 :            : 
     299                 :            :                 /*
     300                 :            :                  * Mbuf data_len is the data in one segment and pkt_len data
     301                 :            :                  * in the whole packet. When the packet is just one segment,
     302                 :            :                  * then data_len = pkt_len.
     303                 :            :                  */
     304                 :            :                 pkt_size = pkt->pkt_len;
     305                 :            : 
     306         [ #  # ]:          0 :                 while (pkt != NULL && free_descs > 0) {
     307                 :            :                         /* Copying TSO, VLAN and cksum info */
     308                 :          0 :                         *txds = txd;
     309                 :            : 
     310                 :            :                         /* Releasing mbuf used by this descriptor previously */
     311         [ #  # ]:          0 :                         if (*lmbuf != NULL)
     312                 :            :                                 rte_pktmbuf_free_seg(*lmbuf);
     313                 :            : 
     314                 :            :                         /*
     315                 :            :                          * Linking mbuf with descriptor for being released
     316                 :            :                          * next time descriptor is used.
     317                 :            :                          */
     318                 :          0 :                         *lmbuf = pkt;
     319                 :            : 
     320         [ #  # ]:          0 :                         dma_size = pkt->data_len;
     321                 :            :                         dma_addr = rte_mbuf_data_iova(pkt);
     322                 :            : 
     323                 :            :                         /* Filling descriptors fields */
     324                 :          0 :                         txds->dma_len = dma_size;
     325                 :          0 :                         txds->data_len = txd.data_len;
     326                 :          0 :                         txds->dma_addr_hi = (dma_addr >> 32) & 0xff;
     327                 :          0 :                         txds->dma_addr_lo = (dma_addr & 0xffffffff);
     328                 :          0 :                         free_descs--;
     329                 :            : 
     330                 :          0 :                         txq->wr_p++;
     331         [ #  # ]:          0 :                         if (unlikely(txq->wr_p == txq->tx_count)) /* Wrapping */
     332                 :          0 :                                 txq->wr_p = 0;
     333                 :            : 
     334                 :          0 :                         pkt_size -= dma_size;
     335                 :            : 
     336                 :            :                         /*
     337                 :            :                          * Making the EOP, packets with just one segment
     338                 :            :                          * the priority.
     339                 :            :                          */
     340         [ #  # ]:          0 :                         if (likely(pkt_size == 0))
     341                 :          0 :                                 txds->offset_eop = NFD3_DESC_TX_EOP;
     342                 :            :                         else
     343                 :          0 :                                 txds->offset_eop = 0;
     344                 :            : 
     345                 :            :                         /* Set the meta_len */
     346                 :          0 :                         txds->offset_eop |= offset;
     347                 :            : 
     348                 :          0 :                         pkt = pkt->next;
     349                 :            :                         /* Referencing next free TX descriptor */
     350                 :          0 :                         txds = &txq->txds[txq->wr_p];
     351                 :          0 :                         lmbuf = &txq->txbufs[txq->wr_p].mbuf;
     352                 :          0 :                         issued_descs++;
     353                 :            :                 }
     354                 :            :         }
     355                 :            : 
     356                 :          0 : xmit_end:
     357                 :            :         /* Increment write pointers. Force memory write before we let HW know */
     358                 :            :         rte_wmb();
     359                 :          0 :         nfp_qcp_ptr_add(txq->qcp_q, NFP_QCP_WRITE_PTR, issued_descs);
     360                 :            : 
     361                 :          0 :         return i;
     362                 :            : }
     363                 :            : 
     364                 :            : int
     365                 :          0 : nfp_net_nfd3_tx_queue_setup(struct rte_eth_dev *dev,
     366                 :            :                 uint16_t queue_idx,
     367                 :            :                 uint16_t nb_desc,
     368                 :            :                 unsigned int socket_id,
     369                 :            :                 const struct rte_eth_txconf *tx_conf)
     370                 :            : {
     371                 :            :         size_t size;
     372                 :            :         uint32_t tx_desc_sz;
     373                 :            :         uint16_t min_tx_desc;
     374                 :            :         uint16_t max_tx_desc;
     375                 :            :         struct nfp_net_hw *hw;
     376                 :            :         struct nfp_net_txq *txq;
     377                 :            :         uint16_t tx_free_thresh;
     378                 :            :         const struct rte_memzone *tz;
     379                 :            : 
     380                 :          0 :         hw = nfp_net_get_hw(dev);
     381                 :            : 
     382                 :          0 :         nfp_net_tx_desc_limits(hw, &min_tx_desc, &max_tx_desc);
     383                 :            : 
     384                 :            :         /* Validating number of descriptors */
     385                 :          0 :         tx_desc_sz = nb_desc * sizeof(struct nfp_net_nfd3_tx_desc);
     386         [ #  # ]:          0 :         if ((NFD3_TX_DESC_PER_PKT * tx_desc_sz) % NFP_ALIGN_RING_DESC != 0 ||
     387   [ #  #  #  # ]:          0 :                         nb_desc > max_tx_desc || nb_desc < min_tx_desc) {
     388                 :          0 :                 PMD_DRV_LOG(ERR, "Wrong nb_desc value");
     389                 :          0 :                 return -EINVAL;
     390                 :            :         }
     391                 :            : 
     392         [ #  # ]:          0 :         tx_free_thresh = (tx_conf->tx_free_thresh != 0) ?
     393                 :            :                         tx_conf->tx_free_thresh : DEFAULT_TX_FREE_THRESH;
     394         [ #  # ]:          0 :         if (tx_free_thresh > nb_desc) {
     395                 :          0 :                 PMD_DRV_LOG(ERR, "tx_free_thresh must be less than the number of TX "
     396                 :            :                                 "descriptors. (tx_free_thresh=%u port=%d queue=%d)",
     397                 :            :                                 tx_free_thresh, dev->data->port_id, queue_idx);
     398                 :          0 :                 return -EINVAL;
     399                 :            :         }
     400                 :            : 
     401                 :            :         /*
     402                 :            :          * Free memory prior to re-allocation if needed. This is the case after
     403                 :            :          * calling nfp_net_stop().
     404                 :            :          */
     405         [ #  # ]:          0 :         if (dev->data->tx_queues[queue_idx] != NULL) {
     406                 :            :                 PMD_TX_LOG(DEBUG, "Freeing memory prior to re-allocation %d",
     407                 :            :                                 queue_idx);
     408                 :          0 :                 nfp_net_tx_queue_release(dev, queue_idx);
     409                 :          0 :                 dev->data->tx_queues[queue_idx] = NULL;
     410                 :            :         }
     411                 :            : 
     412                 :            :         /* Allocating tx queue data structure */
     413                 :          0 :         txq = rte_zmalloc_socket("ethdev TX queue", sizeof(struct nfp_net_txq),
     414                 :            :                         RTE_CACHE_LINE_SIZE, socket_id);
     415         [ #  # ]:          0 :         if (txq == NULL) {
     416                 :          0 :                 PMD_DRV_LOG(ERR, "Error allocating tx dma");
     417                 :          0 :                 return -ENOMEM;
     418                 :            :         }
     419                 :            : 
     420                 :          0 :         dev->data->tx_queues[queue_idx] = txq;
     421                 :            : 
     422                 :            :         /*
     423                 :            :          * Allocate TX ring hardware descriptors. A memzone large enough to
     424                 :            :          * handle the maximum ring size is allocated in order to allow for
     425                 :            :          * resizing in later calls to the queue setup function.
     426                 :            :          */
     427                 :          0 :         size = sizeof(struct nfp_net_nfd3_tx_desc) * NFD3_TX_DESC_PER_PKT * max_tx_desc;
     428                 :          0 :         tz = rte_eth_dma_zone_reserve(dev, "tx_ring", queue_idx, size,
     429                 :            :                         NFP_MEMZONE_ALIGN, socket_id);
     430         [ #  # ]:          0 :         if (tz == NULL) {
     431                 :          0 :                 PMD_DRV_LOG(ERR, "Error allocating tx dma");
     432                 :          0 :                 nfp_net_tx_queue_release(dev, queue_idx);
     433                 :          0 :                 dev->data->tx_queues[queue_idx] = NULL;
     434                 :          0 :                 return -ENOMEM;
     435                 :            :         }
     436                 :            : 
     437                 :          0 :         txq->tx_count = nb_desc * NFD3_TX_DESC_PER_PKT;
     438                 :          0 :         txq->tx_free_thresh = tx_free_thresh;
     439                 :            : 
     440                 :            :         /* Queue mapping based on firmware configuration */
     441                 :          0 :         txq->qidx = queue_idx;
     442                 :          0 :         txq->tx_qcidx = queue_idx * hw->stride_tx;
     443                 :          0 :         txq->qcp_q = hw->tx_bar + NFP_QCP_QUEUE_OFF(txq->tx_qcidx);
     444                 :          0 :         txq->port_id = dev->data->port_id;
     445                 :            : 
     446                 :            :         /* Saving physical and virtual addresses for the TX ring */
     447                 :          0 :         txq->dma = tz->iova;
     448                 :          0 :         txq->txds = tz->addr;
     449                 :            : 
     450                 :            :         /* Mbuf pointers array for referencing mbufs linked to TX descriptors */
     451                 :          0 :         txq->txbufs = rte_zmalloc_socket("txq->txbufs",
     452                 :          0 :                         sizeof(*txq->txbufs) * txq->tx_count,
     453                 :            :                         RTE_CACHE_LINE_SIZE, socket_id);
     454         [ #  # ]:          0 :         if (txq->txbufs == NULL) {
     455                 :          0 :                 nfp_net_tx_queue_release(dev, queue_idx);
     456                 :          0 :                 dev->data->tx_queues[queue_idx] = NULL;
     457                 :          0 :                 return -ENOMEM;
     458                 :            :         }
     459                 :            : 
     460                 :          0 :         nfp_net_reset_tx_queue(txq);
     461                 :            : 
     462                 :          0 :         txq->hw = hw;
     463                 :            : 
     464                 :            :         /*
     465                 :            :          * Telling the HW about the physical address of the TX ring and number
     466                 :            :          * of descriptors in log2 format.
     467                 :            :          */
     468                 :          0 :         nn_cfg_writeq(&hw->super, NFP_NET_CFG_TXR_ADDR(queue_idx), txq->dma);
     469         [ #  # ]:          0 :         nn_cfg_writeb(&hw->super, NFP_NET_CFG_TXR_SZ(queue_idx), rte_log2_u32(txq->tx_count));
     470                 :            : 
     471                 :          0 :         return 0;
     472                 :            : }

Generated by: LCOV version 1.14