LCOV - code coverage report
Current view: top level - drivers/net/fm10k - fm10k_rxtx_vec.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 242 0.0 %
Date: 2025-01-02 22:41:34 Functions: 0 15 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 128 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2013-2015 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include <inttypes.h>
       6                 :            : 
       7                 :            : #include <ethdev_driver.h>
       8                 :            : #include <rte_common.h>
       9                 :            : #include "fm10k.h"
      10                 :            : #include "base/fm10k_type.h"
      11                 :            : 
      12                 :            : #include <rte_vect.h>
      13                 :            : 
      14                 :            : #ifndef __INTEL_COMPILER
      15                 :            : #pragma GCC diagnostic ignored "-Wcast-qual"
      16                 :            : #endif
      17                 :            : 
      18                 :            : static void
      19                 :            : fm10k_reset_tx_queue(struct fm10k_tx_queue *txq);
      20                 :            : 
      21                 :            : /* Handling the offload flags (olflags) field takes computation
      22                 :            :  * time when receiving packets. Therefore we provide a flag to disable
      23                 :            :  * the processing of the olflags field when they are not needed. This
      24                 :            :  * gives improved performance, at the cost of losing the offload info
      25                 :            :  * in the received packet
      26                 :            :  */
      27                 :            : #ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
      28                 :            : 
      29                 :            : /* Vlan present flag shift */
      30                 :            : #define VP_SHIFT     (2)
      31                 :            : /* L3 type shift */
      32                 :            : #define L3TYPE_SHIFT     (4)
      33                 :            : /* L4 type shift */
      34                 :            : #define L4TYPE_SHIFT     (7)
      35                 :            : /* HBO flag shift */
      36                 :            : #define HBOFLAG_SHIFT     (10)
      37                 :            : /* RXE flag shift */
      38                 :            : #define RXEFLAG_SHIFT     (13)
      39                 :            : /* IPE/L4E flag shift */
      40                 :            : #define L3L4EFLAG_SHIFT     (14)
      41                 :            : /* shift RTE_MBUF_F_RX_L4_CKSUM_GOOD into one byte by 1 bit */
      42                 :            : #define CKSUM_SHIFT     (1)
      43                 :            : 
      44                 :            : static inline void
      45                 :          0 : fm10k_desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
      46                 :            : {
      47                 :            :         __m128i ptype0, ptype1, vtag0, vtag1, eflag0, eflag1, cksumflag;
      48                 :            :         union {
      49                 :            :                 uint16_t e[4];
      50                 :            :                 uint64_t dword;
      51                 :            :         } vol;
      52                 :            : 
      53                 :            :         const __m128i pkttype_msk = _mm_set_epi16(
      54                 :            :                         0x0000, 0x0000, 0x0000, 0x0000,
      55                 :            :                         RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
      56                 :            :                         RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
      57                 :            :                         RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
      58                 :            :                         RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED);
      59                 :            : 
      60                 :            :         /* mask everything except rss type */
      61                 :            :         const __m128i rsstype_msk = _mm_set_epi16(
      62                 :            :                         0x0000, 0x0000, 0x0000, 0x0000,
      63                 :            :                         0x000F, 0x000F, 0x000F, 0x000F);
      64                 :            : 
      65                 :            :         /* mask for HBO and RXE flag flags */
      66                 :            :         const __m128i rxe_msk = _mm_set_epi16(
      67                 :            :                         0x0000, 0x0000, 0x0000, 0x0000,
      68                 :            :                         0x0001, 0x0001, 0x0001, 0x0001);
      69                 :            : 
      70                 :            :         /* mask the lower byte of ol_flags */
      71                 :            :         const __m128i ol_flags_msk = _mm_set_epi16(
      72                 :            :                         0x0000, 0x0000, 0x0000, 0x0000,
      73                 :            :                         0x00FF, 0x00FF, 0x00FF, 0x00FF);
      74                 :            : 
      75                 :            :         const __m128i l3l4cksum_flag = _mm_set_epi8(0, 0, 0, 0,
      76                 :            :                         0, 0, 0, 0,
      77                 :            :                         0, 0, 0, 0,
      78                 :            :                         (RTE_MBUF_F_RX_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD) >> CKSUM_SHIFT,
      79                 :            :                         (RTE_MBUF_F_RX_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> CKSUM_SHIFT,
      80                 :            :                         (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_BAD) >> CKSUM_SHIFT,
      81                 :            :                         (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> CKSUM_SHIFT);
      82                 :            : 
      83                 :            :         const __m128i rxe_flag = _mm_set_epi8(0, 0, 0, 0,
      84                 :            :                         0, 0, 0, 0,
      85                 :            :                         0, 0, 0, 0,
      86                 :            :                         0, 0, 0, 0);
      87                 :            : 
      88                 :            :         /* map rss type to rss hash flag */
      89                 :            :         const __m128i rss_flags = _mm_set_epi8(0, 0, 0, 0,
      90                 :            :                         0, 0, 0, RTE_MBUF_F_RX_RSS_HASH,
      91                 :            :                         RTE_MBUF_F_RX_RSS_HASH, 0, RTE_MBUF_F_RX_RSS_HASH, 0,
      92                 :            :                         RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH,
      93                 :            :                         RTE_MBUF_F_RX_RSS_HASH, 0);
      94                 :            : 
      95                 :            :         /* Calculate RSS_hash and Vlan fields */
      96                 :          0 :         ptype0 = _mm_unpacklo_epi16(descs[0], descs[1]);
      97                 :          0 :         ptype1 = _mm_unpacklo_epi16(descs[2], descs[3]);
      98                 :            :         vtag0 = _mm_unpackhi_epi16(descs[0], descs[1]);
      99                 :            :         vtag1 = _mm_unpackhi_epi16(descs[2], descs[3]);
     100                 :            : 
     101                 :            :         ptype0 = _mm_unpacklo_epi32(ptype0, ptype1);
     102                 :            :         ptype0 = _mm_and_si128(ptype0, rsstype_msk);
     103                 :            :         ptype0 = _mm_shuffle_epi8(rss_flags, ptype0);
     104                 :            : 
     105                 :            :         vtag1 = _mm_unpacklo_epi32(vtag0, vtag1);
     106                 :            :         eflag0 = vtag1;
     107                 :            :         cksumflag = vtag1;
     108                 :            :         vtag1 = _mm_srli_epi16(vtag1, VP_SHIFT);
     109                 :            :         vtag1 = _mm_and_si128(vtag1, pkttype_msk);
     110                 :            : 
     111                 :            :         vtag1 = _mm_or_si128(ptype0, vtag1);
     112                 :            : 
     113                 :            :         /* Process err flags, simply set RECIP_ERR bit if HBO/IXE is set */
     114                 :            :         eflag1 = _mm_srli_epi16(eflag0, RXEFLAG_SHIFT);
     115                 :            :         eflag0 = _mm_srli_epi16(eflag0, HBOFLAG_SHIFT);
     116                 :            :         eflag0 = _mm_or_si128(eflag0, eflag1);
     117                 :            :         eflag0 = _mm_and_si128(eflag0, rxe_msk);
     118                 :            :         eflag0 = _mm_shuffle_epi8(rxe_flag, eflag0);
     119                 :            : 
     120                 :            :         vtag1 = _mm_or_si128(eflag0, vtag1);
     121                 :            : 
     122                 :            :         /* Process L4/L3 checksum error flags */
     123                 :            :         cksumflag = _mm_srli_epi16(cksumflag, L3L4EFLAG_SHIFT);
     124                 :            :         cksumflag = _mm_shuffle_epi8(l3l4cksum_flag, cksumflag);
     125                 :            : 
     126                 :            :         /* clean the higher byte and shift back the flag bits */
     127                 :            :         cksumflag = _mm_and_si128(cksumflag, ol_flags_msk);
     128                 :            :         cksumflag = _mm_slli_epi16(cksumflag, CKSUM_SHIFT);
     129                 :            :         vtag1 = _mm_or_si128(cksumflag, vtag1);
     130                 :            : 
     131                 :          0 :         vol.dword = _mm_cvtsi128_si64(vtag1);
     132                 :            : 
     133                 :          0 :         rx_pkts[0]->ol_flags = vol.e[0];
     134                 :          0 :         rx_pkts[1]->ol_flags = vol.e[1];
     135                 :          0 :         rx_pkts[2]->ol_flags = vol.e[2];
     136                 :          0 :         rx_pkts[3]->ol_flags = vol.e[3];
     137                 :          0 : }
     138                 :            : 
     139                 :            : /* @note: When this function is changed, make corresponding change to
     140                 :            :  * fm10k_dev_supported_ptypes_get().
     141                 :            :  */
     142                 :            : static inline void
     143                 :          0 : fm10k_desc_to_pktype_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
     144                 :            : {
     145                 :            :         __m128i l3l4type0, l3l4type1, l3type, l4type;
     146                 :            :         union {
     147                 :            :                 uint16_t e[4];
     148                 :            :                 uint64_t dword;
     149                 :            :         } vol;
     150                 :            : 
     151                 :            :         /* L3 pkt type mask  Bit4 to Bit6 */
     152                 :            :         const __m128i l3type_msk = _mm_set_epi16(
     153                 :            :                         0x0000, 0x0000, 0x0000, 0x0000,
     154                 :            :                         0x0070, 0x0070, 0x0070, 0x0070);
     155                 :            : 
     156                 :            :         /* L4 pkt type mask  Bit7 to Bit9 */
     157                 :            :         const __m128i l4type_msk = _mm_set_epi16(
     158                 :            :                         0x0000, 0x0000, 0x0000, 0x0000,
     159                 :            :                         0x0380, 0x0380, 0x0380, 0x0380);
     160                 :            : 
     161                 :            :         /* convert RRC l3 type to mbuf format */
     162                 :            :         const __m128i l3type_flags = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0,
     163                 :            :                         0, 0, 0, RTE_PTYPE_L3_IPV6_EXT,
     164                 :            :                         RTE_PTYPE_L3_IPV6, RTE_PTYPE_L3_IPV4_EXT,
     165                 :            :                         RTE_PTYPE_L3_IPV4, 0);
     166                 :            : 
     167                 :            :         /* Convert RRC l4 type to mbuf format l4type_flags shift-left 8 bits
     168                 :            :          * to fill into8 bits length.
     169                 :            :          */
     170                 :            :         const __m128i l4type_flags = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0,
     171                 :            :                         RTE_PTYPE_TUNNEL_GENEVE >> 8,
     172                 :            :                         RTE_PTYPE_TUNNEL_NVGRE >> 8,
     173                 :            :                         RTE_PTYPE_TUNNEL_VXLAN >> 8,
     174                 :            :                         RTE_PTYPE_TUNNEL_GRE >> 8,
     175                 :            :                         RTE_PTYPE_L4_UDP >> 8,
     176                 :            :                         RTE_PTYPE_L4_TCP >> 8,
     177                 :            :                         0);
     178                 :            : 
     179                 :          0 :         l3l4type0 = _mm_unpacklo_epi16(descs[0], descs[1]);
     180                 :          0 :         l3l4type1 = _mm_unpacklo_epi16(descs[2], descs[3]);
     181                 :            :         l3l4type0 = _mm_unpacklo_epi32(l3l4type0, l3l4type1);
     182                 :            : 
     183                 :            :         l3type = _mm_and_si128(l3l4type0, l3type_msk);
     184                 :            :         l4type = _mm_and_si128(l3l4type0, l4type_msk);
     185                 :            : 
     186                 :            :         l3type = _mm_srli_epi16(l3type, L3TYPE_SHIFT);
     187                 :            :         l4type = _mm_srli_epi16(l4type, L4TYPE_SHIFT);
     188                 :            : 
     189                 :            :         l3type = _mm_shuffle_epi8(l3type_flags, l3type);
     190                 :            :         /* l4type_flags shift-left for 8 bits, need shift-right back */
     191                 :            :         l4type = _mm_shuffle_epi8(l4type_flags, l4type);
     192                 :            : 
     193                 :            :         l4type = _mm_slli_epi16(l4type, 8);
     194                 :            :         l3l4type0 = _mm_or_si128(l3type, l4type);
     195                 :          0 :         vol.dword = _mm_cvtsi128_si64(l3l4type0);
     196                 :            : 
     197                 :          0 :         rx_pkts[0]->packet_type = vol.e[0];
     198                 :          0 :         rx_pkts[1]->packet_type = vol.e[1];
     199                 :          0 :         rx_pkts[2]->packet_type = vol.e[2];
     200                 :          0 :         rx_pkts[3]->packet_type = vol.e[3];
     201                 :          0 : }
     202                 :            : #else
     203                 :            : #define fm10k_desc_to_olflags_v(desc, rx_pkts) do {} while (0)
     204                 :            : #define fm10k_desc_to_pktype_v(desc, rx_pkts) do {} while (0)
     205                 :            : #endif
     206                 :            : 
     207                 :            : int __rte_cold
     208                 :          0 : fm10k_rx_vec_condition_check(struct rte_eth_dev *dev)
     209                 :            : {
     210                 :            : #ifndef RTE_LIBRTE_IEEE1588
     211                 :          0 :         struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
     212                 :            : 
     213                 :            : #ifndef RTE_FM10K_RX_OLFLAGS_ENABLE
     214                 :            :         /* without rx ol_flags, no VP flag report */
     215         [ #  # ]:          0 :         if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND)
     216                 :          0 :                 return -1;
     217                 :            : #endif
     218                 :            : 
     219                 :            :         return 0;
     220                 :            : #else
     221                 :            :         RTE_SET_USED(dev);
     222                 :            :         return -1;
     223                 :            : #endif
     224                 :            : }
     225                 :            : 
     226                 :            : int __rte_cold
     227                 :          0 : fm10k_rxq_vec_setup(struct fm10k_rx_queue *rxq)
     228                 :            : {
     229                 :            :         uintptr_t p;
     230                 :          0 :         struct rte_mbuf mb_def = { .buf_addr = 0 }; /* zeroed mbuf */
     231                 :            : 
     232                 :          0 :         mb_def.nb_segs = 1;
     233                 :            :         /* data_off will be adjusted after new mbuf allocated for 512-byte
     234                 :            :          * alignment.
     235                 :            :          */
     236                 :          0 :         mb_def.data_off = RTE_PKTMBUF_HEADROOM;
     237                 :          0 :         mb_def.port = rxq->port_id;
     238                 :            :         rte_mbuf_refcnt_set(&mb_def, 1);
     239                 :            : 
     240                 :            :         /* prevent compiler reordering: rearm_data covers previous fields */
     241                 :          0 :         rte_compiler_barrier();
     242                 :            :         p = (uintptr_t)&mb_def.rearm_data;
     243                 :          0 :         rxq->mbuf_initializer = *(uint64_t *)p;
     244                 :          0 :         return 0;
     245                 :            : }
     246                 :            : 
     247                 :            : static inline void
     248                 :          0 : fm10k_rxq_rearm(struct fm10k_rx_queue *rxq)
     249                 :            : {
     250                 :            :         int i;
     251                 :            :         uint16_t rx_id;
     252                 :            :         volatile union fm10k_rx_desc *rxdp;
     253                 :          0 :         struct rte_mbuf **mb_alloc = &rxq->sw_ring[rxq->rxrearm_start];
     254                 :            :         struct rte_mbuf *mb0, *mb1;
     255                 :            :         __m128i head_off = _mm_set_epi64x(
     256                 :            :                         RTE_PKTMBUF_HEADROOM + FM10K_RX_DATABUF_ALIGN - 1,
     257                 :            :                         RTE_PKTMBUF_HEADROOM + FM10K_RX_DATABUF_ALIGN - 1);
     258                 :            :         __m128i dma_addr0, dma_addr1;
     259                 :            :         /* Rx buffer need to be aligned with 512 byte */
     260                 :            :         const __m128i hba_msk = _mm_set_epi64x(0,
     261                 :            :                                 UINT64_MAX - FM10K_RX_DATABUF_ALIGN + 1);
     262                 :            : 
     263                 :          0 :         rxdp = rxq->hw_ring + rxq->rxrearm_start;
     264                 :            : 
     265                 :            :         /* Pull 'n' more MBUFs into the software ring */
     266   [ #  #  #  # ]:          0 :         if (rte_mempool_get_bulk(rxq->mp,
     267                 :            :                                  (void *)mb_alloc,
     268                 :            :                                  RTE_FM10K_RXQ_REARM_THRESH) < 0) {
     269                 :            :                 dma_addr0 = _mm_setzero_si128();
     270                 :            :                 /* Clean up all the HW/SW ring content */
     271         [ #  # ]:          0 :                 for (i = 0; i < RTE_FM10K_RXQ_REARM_THRESH; i++) {
     272                 :          0 :                         mb_alloc[i] = &rxq->fake_mbuf;
     273                 :          0 :                         _mm_store_si128((__m128i *)&rxdp[i].q,
     274                 :            :                                                 dma_addr0);
     275                 :            :                 }
     276                 :            : 
     277                 :          0 :                 rte_eth_devices[rxq->port_id].data->rx_mbuf_alloc_failed +=
     278                 :            :                         RTE_FM10K_RXQ_REARM_THRESH;
     279                 :          0 :                 return;
     280                 :            :         }
     281                 :            : 
     282                 :            :         /* Initialize the mbufs in vector, process 2 mbufs in one loop */
     283         [ #  # ]:          0 :         for (i = 0; i < RTE_FM10K_RXQ_REARM_THRESH; i += 2, mb_alloc += 2) {
     284                 :            :                 __m128i vaddr0, vaddr1;
     285                 :            :                 uintptr_t p0, p1;
     286                 :            : 
     287                 :          0 :                 mb0 = mb_alloc[0];
     288                 :          0 :                 mb1 = mb_alloc[1];
     289                 :            : 
     290                 :            :                 /* Flush mbuf with pkt template.
     291                 :            :                  * Data to be rearmed is 6 bytes long.
     292                 :            :                  */
     293                 :            :                 p0 = (uintptr_t)&mb0->rearm_data;
     294                 :          0 :                 *(uint64_t *)p0 = rxq->mbuf_initializer;
     295                 :            :                 p1 = (uintptr_t)&mb1->rearm_data;
     296                 :          0 :                 *(uint64_t *)p1 = rxq->mbuf_initializer;
     297                 :            : 
     298                 :            :                 /* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
     299                 :            :                 RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
     300                 :            :                                 offsetof(struct rte_mbuf, buf_addr) + 8);
     301                 :            :                 vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
     302                 :            :                 vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
     303                 :            : 
     304                 :            :                 /* convert pa to dma_addr hdr/data */
     305                 :            :                 dma_addr0 = _mm_unpackhi_epi64(vaddr0, vaddr0);
     306                 :            :                 dma_addr1 = _mm_unpackhi_epi64(vaddr1, vaddr1);
     307                 :            : 
     308                 :            :                 /* add headroom to pa values */
     309                 :            :                 dma_addr0 = _mm_add_epi64(dma_addr0, head_off);
     310                 :            :                 dma_addr1 = _mm_add_epi64(dma_addr1, head_off);
     311                 :            : 
     312                 :            :                 /* Do 512 byte alignment to satisfy HW requirement, in the
     313                 :            :                  * meanwhile, set Header Buffer Address to zero.
     314                 :            :                  */
     315                 :            :                 dma_addr0 = _mm_and_si128(dma_addr0, hba_msk);
     316                 :            :                 dma_addr1 = _mm_and_si128(dma_addr1, hba_msk);
     317                 :            : 
     318                 :            :                 /* flush desc with pa dma_addr */
     319                 :            :                 _mm_store_si128((__m128i *)&rxdp++->q, dma_addr0);
     320                 :          0 :                 _mm_store_si128((__m128i *)&rxdp++->q, dma_addr1);
     321                 :            : 
     322                 :            :                 /* enforce 512B alignment on default Rx virtual addresses */
     323                 :          0 :                 mb0->data_off = (uint16_t)(RTE_PTR_ALIGN((char *)mb0->buf_addr
     324                 :            :                                 + RTE_PKTMBUF_HEADROOM, FM10K_RX_DATABUF_ALIGN)
     325                 :          0 :                                 - (char *)mb0->buf_addr);
     326                 :          0 :                 mb1->data_off = (uint16_t)(RTE_PTR_ALIGN((char *)mb1->buf_addr
     327                 :            :                                 + RTE_PKTMBUF_HEADROOM, FM10K_RX_DATABUF_ALIGN)
     328                 :          0 :                                 - (char *)mb1->buf_addr);
     329                 :            :         }
     330                 :            : 
     331                 :          0 :         rxq->rxrearm_start += RTE_FM10K_RXQ_REARM_THRESH;
     332         [ #  # ]:          0 :         if (rxq->rxrearm_start >= rxq->nb_desc)
     333                 :          0 :                 rxq->rxrearm_start = 0;
     334                 :            : 
     335                 :          0 :         rxq->rxrearm_nb -= RTE_FM10K_RXQ_REARM_THRESH;
     336                 :            : 
     337         [ #  # ]:          0 :         rx_id = (uint16_t)((rxq->rxrearm_start == 0) ?
     338                 :            :                         (rxq->nb_desc - 1) : (rxq->rxrearm_start - 1));
     339                 :            : 
     340                 :            :         /* Update the tail pointer on the NIC */
     341                 :          0 :         FM10K_PCI_REG_WRITE(rxq->tail_ptr, rx_id);
     342                 :            : }
     343                 :            : 
     344                 :            : void __rte_cold
     345                 :          0 : fm10k_rx_queue_release_mbufs_vec(struct fm10k_rx_queue *rxq)
     346                 :            : {
     347                 :          0 :         const unsigned mask = rxq->nb_desc - 1;
     348                 :            :         unsigned i;
     349                 :            : 
     350   [ #  #  #  # ]:          0 :         if (rxq->sw_ring == NULL || rxq->rxrearm_nb >= rxq->nb_desc)
     351                 :            :                 return;
     352                 :            : 
     353                 :            :         /* free all mbufs that are valid in the ring */
     354         [ #  # ]:          0 :         if (rxq->rxrearm_nb == 0) {
     355         [ #  # ]:          0 :                 for (i = 0; i < rxq->nb_desc; i++)
     356         [ #  # ]:          0 :                         if (rxq->sw_ring[i] != NULL)
     357                 :            :                                 rte_pktmbuf_free_seg(rxq->sw_ring[i]);
     358                 :            :         } else {
     359         [ #  # ]:          0 :                 for (i = rxq->next_dd; i != rxq->rxrearm_start;
     360                 :          0 :                                 i = (i + 1) & mask)
     361         [ #  # ]:          0 :                         rte_pktmbuf_free_seg(rxq->sw_ring[i]);
     362                 :            :         }
     363                 :          0 :         rxq->rxrearm_nb = rxq->nb_desc;
     364                 :            : 
     365                 :            :         /* set all entries to NULL */
     366                 :          0 :         memset(rxq->sw_ring, 0, sizeof(rxq->sw_ring[0]) * rxq->nb_desc);
     367                 :            : }
     368                 :            : 
     369                 :            : static inline uint16_t
     370                 :          0 : fm10k_recv_raw_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
     371                 :            :                 uint16_t nb_pkts, uint8_t *split_packet)
     372                 :            : {
     373                 :            :         volatile union fm10k_rx_desc *rxdp;
     374                 :            :         struct rte_mbuf **mbufp;
     375                 :            :         uint16_t nb_pkts_recd;
     376                 :            :         int pos;
     377                 :            :         struct fm10k_rx_queue *rxq = rx_queue;
     378                 :            :         uint64_t var;
     379                 :            :         __m128i shuf_msk;
     380                 :            :         __m128i dd_check, eop_check;
     381                 :            :         uint16_t next_dd;
     382                 :            : 
     383                 :          0 :         next_dd = rxq->next_dd;
     384                 :            : 
     385                 :            :         /* Just the act of getting into the function from the application is
     386                 :            :          * going to cost about 7 cycles
     387                 :            :          */
     388                 :          0 :         rxdp = rxq->hw_ring + next_dd;
     389                 :            : 
     390                 :            :         rte_prefetch0(rxdp);
     391                 :            : 
     392                 :            :         /* See if we need to rearm the RX queue - gives the prefetch a bit
     393                 :            :          * of time to act
     394                 :            :          */
     395         [ #  # ]:          0 :         if (rxq->rxrearm_nb > RTE_FM10K_RXQ_REARM_THRESH)
     396                 :          0 :                 fm10k_rxq_rearm(rxq);
     397                 :            : 
     398                 :            :         /* Before we start moving massive data around, check to see if
     399                 :            :          * there is actually a packet available
     400                 :            :          */
     401         [ #  # ]:          0 :         if (!(rxdp->d.staterr & FM10K_RXD_STATUS_DD))
     402                 :            :                 return 0;
     403                 :            : 
     404                 :            :         /* Vector RX will process 4 packets at a time, strip the unaligned
     405                 :            :          * tails in case it's not multiple of 4.
     406                 :            :          */
     407                 :          0 :         nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, RTE_FM10K_DESCS_PER_LOOP);
     408                 :            : 
     409                 :            :         /* 4 packets DD mask */
     410                 :            :         dd_check = _mm_set_epi64x(0x0000000100000001LL, 0x0000000100000001LL);
     411                 :            : 
     412                 :            :         /* 4 packets EOP mask */
     413                 :            :         eop_check = _mm_set_epi64x(0x0000000200000002LL, 0x0000000200000002LL);
     414                 :            : 
     415                 :            :         /* mask to shuffle from desc. to mbuf */
     416                 :            :         shuf_msk = _mm_set_epi8(
     417                 :            :                 7, 6, 5, 4,  /* octet 4~7, 32bits rss */
     418                 :            :                 15, 14,      /* octet 14~15, low 16 bits vlan_macip */
     419                 :            :                 13, 12,      /* octet 12~13, 16 bits data_len */
     420                 :            :                 0xFF, 0xFF,  /* skip high 16 bits pkt_len, zero out */
     421                 :            :                 13, 12,      /* octet 12~13, low 16 bits pkt_len */
     422                 :            :                 0xFF, 0xFF,  /* skip high 16 bits pkt_type */
     423                 :            :                 0xFF, 0xFF   /* Skip pkt_type field in shuffle operation */
     424                 :            :                 );
     425                 :            :         /*
     426                 :            :          * Compile-time verify the shuffle mask
     427                 :            :          * NOTE: some field positions already verified above, but duplicated
     428                 :            :          * here for completeness in case of future modifications.
     429                 :            :          */
     430                 :            :         RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
     431                 :            :                         offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4);
     432                 :            :         RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) !=
     433                 :            :                         offsetof(struct rte_mbuf, rx_descriptor_fields1) + 8);
     434                 :            :         RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, vlan_tci) !=
     435                 :            :                         offsetof(struct rte_mbuf, rx_descriptor_fields1) + 10);
     436                 :            :         RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, hash) !=
     437                 :            :                         offsetof(struct rte_mbuf, rx_descriptor_fields1) + 12);
     438                 :            : 
     439                 :            :         /* Cache is empty -> need to scan the buffer rings, but first move
     440                 :            :          * the next 'n' mbufs into the cache
     441                 :            :          */
     442                 :          0 :         mbufp = &rxq->sw_ring[next_dd];
     443                 :            : 
     444                 :            :         /* A. load 4 packet in one loop
     445                 :            :          * [A*. mask out 4 unused dirty field in desc]
     446                 :            :          * B. copy 4 mbuf point from swring to rx_pkts
     447                 :            :          * C. calc the number of DD bits among the 4 packets
     448                 :            :          * [C*. extract the end-of-packet bit, if requested]
     449                 :            :          * D. fill info. from desc to mbuf
     450                 :            :          */
     451         [ #  # ]:          0 :         for (pos = 0, nb_pkts_recd = 0; pos < nb_pkts;
     452                 :          0 :                         pos += RTE_FM10K_DESCS_PER_LOOP,
     453                 :          0 :                         rxdp += RTE_FM10K_DESCS_PER_LOOP) {
     454                 :            :                 __m128i descs0[RTE_FM10K_DESCS_PER_LOOP];
     455                 :            :                 __m128i pkt_mb1, pkt_mb2, pkt_mb3, pkt_mb4;
     456                 :            :                 __m128i zero, staterr, sterr_tmp1, sterr_tmp2;
     457                 :            :                 __m128i mbp1;
     458                 :            :                 /* 2 64 bit or 4 32 bit mbuf pointers in one XMM reg. */
     459                 :            : #if defined(RTE_ARCH_X86_64)
     460                 :            :                 __m128i mbp2;
     461                 :            : #endif
     462                 :            : 
     463                 :            :                 /* B.1 load 2 (64 bit) or 4 (32 bit) mbuf points */
     464                 :          0 :                 mbp1 = _mm_loadu_si128((__m128i *)&mbufp[pos]);
     465                 :            : 
     466                 :            :                 /* Read desc statuses backwards to avoid race condition */
     467                 :            :                 /* A.1 load desc[3] */
     468                 :          0 :                 descs0[3] = _mm_loadu_si128((__m128i *)(rxdp + 3));
     469                 :          0 :                 rte_compiler_barrier();
     470                 :            : 
     471                 :            :                 /* B.2 copy 2 64 bit or 4 32 bit mbuf point into rx_pkts */
     472                 :          0 :                 _mm_storeu_si128((__m128i *)&rx_pkts[pos], mbp1);
     473                 :            : 
     474                 :            : #if defined(RTE_ARCH_X86_64)
     475                 :            :                 /* B.1 load 2 64 bit mbuf points */
     476                 :          0 :                 mbp2 = _mm_loadu_si128((__m128i *)&mbufp[pos+2]);
     477                 :            : #endif
     478                 :            : 
     479                 :            :                 /* A.1 load desc[2-0] */
     480                 :          0 :                 descs0[2] = _mm_loadu_si128((__m128i *)(rxdp + 2));
     481                 :          0 :                 rte_compiler_barrier();
     482                 :          0 :                 descs0[1] = _mm_loadu_si128((__m128i *)(rxdp + 1));
     483                 :          0 :                 rte_compiler_barrier();
     484                 :          0 :                 descs0[0] = _mm_loadu_si128((__m128i *)(rxdp));
     485                 :            : 
     486                 :            : #if defined(RTE_ARCH_X86_64)
     487                 :            :                 /* B.2 copy 2 mbuf point into rx_pkts  */
     488                 :          0 :                 _mm_storeu_si128((__m128i *)&rx_pkts[pos+2], mbp2);
     489                 :            : #endif
     490                 :            : 
     491                 :            :                 /* avoid compiler reorder optimization */
     492                 :          0 :                 rte_compiler_barrier();
     493                 :            : 
     494         [ #  # ]:          0 :                 if (split_packet) {
     495                 :          0 :                         rte_mbuf_prefetch_part2(rx_pkts[pos]);
     496                 :          0 :                         rte_mbuf_prefetch_part2(rx_pkts[pos + 1]);
     497                 :          0 :                         rte_mbuf_prefetch_part2(rx_pkts[pos + 2]);
     498                 :          0 :                         rte_mbuf_prefetch_part2(rx_pkts[pos + 3]);
     499                 :            :                 }
     500                 :            : 
     501                 :            :                 /* D.1 pkt 3,4 convert format from desc to pktmbuf */
     502                 :          0 :                 pkt_mb4 = _mm_shuffle_epi8(descs0[3], shuf_msk);
     503                 :          0 :                 pkt_mb3 = _mm_shuffle_epi8(descs0[2], shuf_msk);
     504                 :            : 
     505                 :            :                 /* C.1 4=>2 filter staterr info only */
     506                 :            :                 sterr_tmp2 = _mm_unpackhi_epi32(descs0[3], descs0[2]);
     507                 :            :                 /* C.1 4=>2 filter staterr info only */
     508                 :          0 :                 sterr_tmp1 = _mm_unpackhi_epi32(descs0[1], descs0[0]);
     509                 :            : 
     510                 :            :                 /* set ol_flags with vlan packet type */
     511                 :          0 :                 fm10k_desc_to_olflags_v(descs0, &rx_pkts[pos]);
     512                 :            : 
     513                 :            :                 /* D.1 pkt 1,2 convert format from desc to pktmbuf */
     514                 :            :                 pkt_mb2 = _mm_shuffle_epi8(descs0[1], shuf_msk);
     515                 :            :                 pkt_mb1 = _mm_shuffle_epi8(descs0[0], shuf_msk);
     516                 :            : 
     517                 :            :                 /* C.2 get 4 pkts staterr value  */
     518                 :            :                 zero = _mm_xor_si128(dd_check, dd_check);
     519                 :            :                 staterr = _mm_unpacklo_epi32(sterr_tmp1, sterr_tmp2);
     520                 :            : 
     521                 :            :                 /* D.3 copy final 3,4 data to rx_pkts */
     522         [ #  # ]:          0 :                 _mm_storeu_si128((void *)&rx_pkts[pos+3]->rx_descriptor_fields1,
     523                 :            :                                 pkt_mb4);
     524                 :          0 :                 _mm_storeu_si128((void *)&rx_pkts[pos+2]->rx_descriptor_fields1,
     525                 :            :                                 pkt_mb3);
     526                 :            : 
     527                 :            :                 /* C* extract and record EOP bit */
     528         [ #  # ]:          0 :                 if (split_packet) {
     529                 :            :                         __m128i eop_shuf_mask = _mm_set_epi8(
     530                 :            :                                         0xFF, 0xFF, 0xFF, 0xFF,
     531                 :            :                                         0xFF, 0xFF, 0xFF, 0xFF,
     532                 :            :                                         0xFF, 0xFF, 0xFF, 0xFF,
     533                 :            :                                         0x04, 0x0C, 0x00, 0x08
     534                 :            :                                         );
     535                 :            : 
     536                 :            :                         /* and with mask to extract bits, flipping 1-0 */
     537                 :            :                         __m128i eop_bits = _mm_andnot_si128(staterr, eop_check);
     538                 :            :                         /* the staterr values are not in order, as the count
     539                 :            :                          * of dd bits doesn't care. However, for end of
     540                 :            :                          * packet tracking, we do care, so shuffle. This also
     541                 :            :                          * compresses the 32-bit values to 8-bit
     542                 :            :                          */
     543                 :            :                         eop_bits = _mm_shuffle_epi8(eop_bits, eop_shuf_mask);
     544                 :            :                         /* store the resulting 32-bit value */
     545                 :          0 :                         *(int *)split_packet = _mm_cvtsi128_si32(eop_bits);
     546                 :          0 :                         split_packet += RTE_FM10K_DESCS_PER_LOOP;
     547                 :            : 
     548                 :            :                         /* zero-out next pointers */
     549                 :          0 :                         rx_pkts[pos]->next = NULL;
     550                 :          0 :                         rx_pkts[pos + 1]->next = NULL;
     551                 :          0 :                         rx_pkts[pos + 2]->next = NULL;
     552                 :          0 :                         rx_pkts[pos + 3]->next = NULL;
     553                 :            :                 }
     554                 :            : 
     555                 :            :                 /* C.3 calc available number of desc */
     556                 :            :                 staterr = _mm_and_si128(staterr, dd_check);
     557                 :            :                 staterr = _mm_packs_epi32(staterr, zero);
     558                 :            : 
     559                 :            :                 /* D.3 copy final 1,2 data to rx_pkts */
     560                 :          0 :                 _mm_storeu_si128((void *)&rx_pkts[pos+1]->rx_descriptor_fields1,
     561                 :            :                                 pkt_mb2);
     562                 :          0 :                 _mm_storeu_si128((void *)&rx_pkts[pos]->rx_descriptor_fields1,
     563                 :            :                                 pkt_mb1);
     564                 :            : 
     565                 :          0 :                 fm10k_desc_to_pktype_v(descs0, &rx_pkts[pos]);
     566                 :            : 
     567                 :            :                 /* C.4 calc available number of desc */
     568         [ #  # ]:          0 :                 var = rte_popcount64(_mm_cvtsi128_si64(staterr));
     569                 :          0 :                 nb_pkts_recd += var;
     570         [ #  # ]:          0 :                 if (likely(var != RTE_FM10K_DESCS_PER_LOOP))
     571                 :            :                         break;
     572                 :            :         }
     573                 :            : 
     574                 :            :         /* Update our internal tail pointer */
     575                 :          0 :         rxq->next_dd = (uint16_t)(rxq->next_dd + nb_pkts_recd);
     576                 :          0 :         rxq->next_dd = (uint16_t)(rxq->next_dd & (rxq->nb_desc - 1));
     577                 :          0 :         rxq->rxrearm_nb = (uint16_t)(rxq->rxrearm_nb + nb_pkts_recd);
     578                 :            : 
     579                 :          0 :         return nb_pkts_recd;
     580                 :            : }
     581                 :            : 
     582                 :            : /* vPMD receive routine
     583                 :            :  *
     584                 :            :  * Notice:
     585                 :            :  * - don't support ol_flags for rss and csum err
     586                 :            :  */
     587                 :            : uint16_t
     588                 :          0 : fm10k_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
     589                 :            :                 uint16_t nb_pkts)
     590                 :            : {
     591                 :          0 :         return fm10k_recv_raw_pkts_vec(rx_queue, rx_pkts, nb_pkts, NULL);
     592                 :            : }
     593                 :            : 
     594                 :            : static inline uint16_t
     595                 :          0 : fm10k_reassemble_packets(struct fm10k_rx_queue *rxq,
     596                 :            :                 struct rte_mbuf **rx_bufs,
     597                 :            :                 uint16_t nb_bufs, uint8_t *split_flags)
     598                 :            : {
     599                 :            :         struct rte_mbuf *pkts[RTE_FM10K_MAX_RX_BURST]; /*finished pkts*/
     600                 :          0 :         struct rte_mbuf *start = rxq->pkt_first_seg;
     601                 :          0 :         struct rte_mbuf *end =  rxq->pkt_last_seg;
     602                 :            :         unsigned pkt_idx, buf_idx;
     603                 :            : 
     604         [ #  # ]:          0 :         for (buf_idx = 0, pkt_idx = 0; buf_idx < nb_bufs; buf_idx++) {
     605         [ #  # ]:          0 :                 if (end != NULL) {
     606                 :            :                         /* processing a split packet */
     607                 :          0 :                         end->next = rx_bufs[buf_idx];
     608                 :          0 :                         start->nb_segs++;
     609                 :          0 :                         start->pkt_len += rx_bufs[buf_idx]->data_len;
     610                 :            :                         end = end->next;
     611                 :            : 
     612         [ #  # ]:          0 :                         if (!split_flags[buf_idx]) {
     613                 :            :                                 /* it's the last packet of the set */
     614                 :            : #ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
     615                 :          0 :                                 start->hash = end->hash;
     616                 :          0 :                                 start->ol_flags = end->ol_flags;
     617                 :          0 :                                 start->packet_type = end->packet_type;
     618                 :            : #endif
     619                 :          0 :                                 pkts[pkt_idx++] = start;
     620                 :            :                                 start = end = NULL;
     621                 :            :                         }
     622                 :            :                 } else {
     623                 :            :                         /* not processing a split packet */
     624         [ #  # ]:          0 :                         if (!split_flags[buf_idx]) {
     625                 :            :                                 /* not a split packet, save and skip */
     626                 :          0 :                                 pkts[pkt_idx++] = rx_bufs[buf_idx];
     627                 :          0 :                                 continue;
     628                 :            :                         }
     629                 :          0 :                         end = start = rx_bufs[buf_idx];
     630                 :            :                 }
     631                 :            :         }
     632                 :            : 
     633                 :            :         /* save the partial packet for next time */
     634                 :          0 :         rxq->pkt_first_seg = start;
     635                 :          0 :         rxq->pkt_last_seg = end;
     636                 :          0 :         memcpy(rx_bufs, pkts, pkt_idx * (sizeof(*pkts)));
     637                 :          0 :         return pkt_idx;
     638                 :            : }
     639                 :            : 
     640                 :            : /**
     641                 :            :  * vPMD receive routine that reassembles single burst of 32 scattered packets
     642                 :            :  *
     643                 :            :  * Notice:
     644                 :            :  * - don't support ol_flags for rss and csum err
     645                 :            :  */
     646                 :            : static uint16_t
     647                 :          0 : fm10k_recv_scattered_burst_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
     648                 :            :                                uint16_t nb_pkts)
     649                 :            : {
     650                 :            :         struct fm10k_rx_queue *rxq = rx_queue;
     651                 :          0 :         uint8_t split_flags[RTE_FM10K_MAX_RX_BURST] = {0};
     652                 :            :         unsigned i = 0;
     653                 :            : 
     654                 :            :         /* Split_flags only can support max of RTE_FM10K_MAX_RX_BURST */
     655                 :          0 :         nb_pkts = RTE_MIN(nb_pkts, RTE_FM10K_MAX_RX_BURST);
     656                 :            :         /* get some new buffers */
     657                 :          0 :         uint16_t nb_bufs = fm10k_recv_raw_pkts_vec(rxq, rx_pkts, nb_pkts,
     658                 :            :                         split_flags);
     659         [ #  # ]:          0 :         if (nb_bufs == 0)
     660                 :            :                 return 0;
     661                 :            : 
     662                 :            :         /* happy day case, full burst + no packets to be joined */
     663                 :            :         const uint64_t *split_fl64 = (uint64_t *)split_flags;
     664                 :            : 
     665         [ #  # ]:          0 :         if (rxq->pkt_first_seg == NULL &&
     666   [ #  #  #  # ]:          0 :                         split_fl64[0] == 0 && split_fl64[1] == 0 &&
     667   [ #  #  #  # ]:          0 :                         split_fl64[2] == 0 && split_fl64[3] == 0)
     668                 :            :                 return nb_bufs;
     669                 :            : 
     670                 :            :         /* reassemble any packets that need reassembly*/
     671         [ #  # ]:          0 :         if (rxq->pkt_first_seg == NULL) {
     672                 :            :                 /* find the first split flag, and only reassemble then*/
     673   [ #  #  #  # ]:          0 :                 while (i < nb_bufs && !split_flags[i])
     674                 :          0 :                         i++;
     675         [ #  # ]:          0 :                 if (i == nb_bufs)
     676                 :            :                         return nb_bufs;
     677                 :          0 :                 rxq->pkt_first_seg = rx_pkts[i];
     678                 :            :         }
     679                 :          0 :         return i + fm10k_reassemble_packets(rxq, &rx_pkts[i], nb_bufs - i,
     680                 :            :                 &split_flags[i]);
     681                 :            : }
     682                 :            : 
     683                 :            : /**
     684                 :            :  * vPMD receive routine that reassembles scattered packets.
     685                 :            :  */
     686                 :            : uint16_t
     687                 :          0 : fm10k_recv_scattered_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
     688                 :            :                               uint16_t nb_pkts)
     689                 :            : {
     690                 :            :         uint16_t retval = 0;
     691                 :            : 
     692         [ #  # ]:          0 :         while (nb_pkts > RTE_FM10K_MAX_RX_BURST) {
     693                 :            :                 uint16_t burst;
     694                 :            : 
     695                 :          0 :                 burst = fm10k_recv_scattered_burst_vec(rx_queue,
     696                 :          0 :                                                        rx_pkts + retval,
     697                 :            :                                                        RTE_FM10K_MAX_RX_BURST);
     698                 :          0 :                 retval += burst;
     699                 :          0 :                 nb_pkts -= burst;
     700         [ #  # ]:          0 :                 if (burst < RTE_FM10K_MAX_RX_BURST)
     701                 :          0 :                         return retval;
     702                 :            :         }
     703                 :            : 
     704                 :          0 :         return retval + fm10k_recv_scattered_burst_vec(rx_queue,
     705                 :          0 :                                                        rx_pkts + retval,
     706                 :            :                                                        nb_pkts);
     707                 :            : }
     708                 :            : 
     709                 :            : static const struct fm10k_txq_ops vec_txq_ops = {
     710                 :            :         .reset = fm10k_reset_tx_queue,
     711                 :            : };
     712                 :            : 
     713                 :            : void __rte_cold
     714                 :          0 : fm10k_txq_vec_setup(struct fm10k_tx_queue *txq)
     715                 :            : {
     716                 :          0 :         txq->ops = &vec_txq_ops;
     717                 :          0 : }
     718                 :            : 
     719                 :            : int __rte_cold
     720                 :          0 : fm10k_tx_vec_condition_check(struct fm10k_tx_queue *txq)
     721                 :            : {
     722                 :            :         /* Vector TX can't offload any features yet */
     723         [ #  # ]:          0 :         if (txq->offloads != 0)
     724                 :            :                 return -1;
     725                 :            : 
     726         [ #  # ]:          0 :         if (txq->tx_ftag_en)
     727                 :          0 :                 return -1;
     728                 :            : 
     729                 :            :         return 0;
     730                 :            : }
     731                 :            : 
     732                 :            : static inline void
     733                 :            : vtx1(volatile struct fm10k_tx_desc *txdp,
     734                 :            :                 struct rte_mbuf *pkt, uint64_t flags)
     735                 :            : {
     736                 :          0 :         __m128i descriptor = _mm_set_epi64x(flags << 56 |
     737                 :          0 :                         (uint64_t)pkt->vlan_tci << 16 | (uint64_t)pkt->data_len,
     738                 :          0 :                         MBUF_DMA_ADDR(pkt));
     739                 :            :         _mm_store_si128((__m128i *)txdp, descriptor);
     740                 :            : }
     741                 :            : 
     742                 :            : static inline void
     743                 :            : vtx(volatile struct fm10k_tx_desc *txdp,
     744                 :            :                 struct rte_mbuf **pkt, uint16_t nb_pkts,  uint64_t flags)
     745                 :            : {
     746                 :            :         int i;
     747                 :            : 
     748         [ #  # ]:          0 :         for (i = 0; i < nb_pkts; ++i, ++txdp, ++pkt)
     749                 :          0 :                 vtx1(txdp, *pkt, flags);
     750                 :            : }
     751                 :            : 
     752                 :            : static __rte_always_inline int
     753                 :            : fm10k_tx_free_bufs(struct fm10k_tx_queue *txq)
     754                 :            : {
     755                 :            :         struct rte_mbuf **txep;
     756                 :            :         uint8_t flags;
     757                 :            :         uint32_t n;
     758                 :            :         uint32_t i;
     759                 :            :         int nb_free = 0;
     760                 :            :         struct rte_mbuf *m, *free[RTE_FM10K_TX_MAX_FREE_BUF_SZ];
     761                 :            : 
     762                 :            :         /* check DD bit on threshold descriptor */
     763                 :          0 :         flags = txq->hw_ring[txq->next_dd].flags;
     764         [ #  # ]:          0 :         if (!(flags & FM10K_TXD_FLAG_DONE))
     765                 :            :                 return 0;
     766                 :            : 
     767                 :          0 :         n = txq->rs_thresh;
     768                 :            : 
     769                 :            :         /* First buffer to free from S/W ring is at index
     770                 :            :          * next_dd - (rs_thresh-1)
     771                 :            :          */
     772                 :          0 :         txep = &txq->sw_ring[txq->next_dd - (n - 1)];
     773         [ #  # ]:          0 :         m = rte_pktmbuf_prefree_seg(txep[0]);
     774         [ #  # ]:          0 :         if (likely(m != NULL)) {
     775                 :          0 :                 free[0] = m;
     776                 :            :                 nb_free = 1;
     777         [ #  # ]:          0 :                 for (i = 1; i < n; i++) {
     778         [ #  # ]:          0 :                         m = rte_pktmbuf_prefree_seg(txep[i]);
     779         [ #  # ]:          0 :                         if (likely(m != NULL)) {
     780         [ #  # ]:          0 :                                 if (likely(m->pool == free[0]->pool))
     781                 :          0 :                                         free[nb_free++] = m;
     782                 :            :                                 else {
     783         [ #  # ]:          0 :                                         rte_mempool_put_bulk(free[0]->pool,
     784                 :            :                                                         (void *)free, nb_free);
     785                 :          0 :                                         free[0] = m;
     786                 :            :                                         nb_free = 1;
     787                 :            :                                 }
     788                 :            :                         }
     789                 :            :                 }
     790         [ #  # ]:          0 :                 rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free);
     791                 :            :         } else {
     792         [ #  # ]:          0 :                 for (i = 1; i < n; i++) {
     793         [ #  # ]:          0 :                         m = rte_pktmbuf_prefree_seg(txep[i]);
     794         [ #  # ]:          0 :                         if (m != NULL)
     795         [ #  # ]:          0 :                                 rte_mempool_put(m->pool, m);
     796                 :            :                 }
     797                 :            :         }
     798                 :            : 
     799                 :            :         /* buffers were freed, update counters */
     800                 :          0 :         txq->nb_free = (uint16_t)(txq->nb_free + txq->rs_thresh);
     801                 :          0 :         txq->next_dd = (uint16_t)(txq->next_dd + txq->rs_thresh);
     802         [ #  # ]:          0 :         if (txq->next_dd >= txq->nb_desc)
     803                 :          0 :                 txq->next_dd = (uint16_t)(txq->rs_thresh - 1);
     804                 :            : 
     805                 :          0 :         return txq->rs_thresh;
     806                 :            : }
     807                 :            : 
     808                 :            : static __rte_always_inline void
     809                 :            : tx_backlog_entry(struct rte_mbuf **txep,
     810                 :            :                  struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
     811                 :            : {
     812                 :            :         int i;
     813                 :            : 
     814   [ #  #  #  # ]:          0 :         for (i = 0; i < (int)nb_pkts; ++i)
     815                 :          0 :                 txep[i] = tx_pkts[i];
     816                 :            : }
     817                 :            : 
     818                 :            : uint16_t
     819                 :          0 : fm10k_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf **tx_pkts,
     820                 :            :                            uint16_t nb_pkts)
     821                 :            : {
     822                 :            :         struct fm10k_tx_queue *txq = (struct fm10k_tx_queue *)tx_queue;
     823                 :            :         volatile struct fm10k_tx_desc *txdp;
     824                 :            :         struct rte_mbuf **txep;
     825                 :            :         uint16_t n, nb_commit, tx_id;
     826                 :            :         uint64_t flags = FM10K_TXD_FLAG_LAST;
     827                 :            :         uint64_t rs = FM10K_TXD_FLAG_RS | FM10K_TXD_FLAG_LAST;
     828                 :            :         int i;
     829                 :            : 
     830                 :            :         /* cross rx_thresh boundary is not allowed */
     831                 :          0 :         nb_pkts = RTE_MIN(nb_pkts, txq->rs_thresh);
     832                 :            : 
     833         [ #  # ]:          0 :         if (txq->nb_free < txq->free_thresh)
     834                 :            :                 fm10k_tx_free_bufs(txq);
     835                 :            : 
     836                 :          0 :         nb_commit = nb_pkts = (uint16_t)RTE_MIN(txq->nb_free, nb_pkts);
     837         [ #  # ]:          0 :         if (unlikely(nb_pkts == 0))
     838                 :            :                 return 0;
     839                 :            : 
     840                 :          0 :         tx_id = txq->next_free;
     841                 :          0 :         txdp = &txq->hw_ring[tx_id];
     842                 :          0 :         txep = &txq->sw_ring[tx_id];
     843                 :            : 
     844                 :          0 :         txq->nb_free = (uint16_t)(txq->nb_free - nb_pkts);
     845                 :            : 
     846                 :          0 :         n = (uint16_t)(txq->nb_desc - tx_id);
     847         [ #  # ]:          0 :         if (nb_commit >= n) {
     848                 :          0 :                 tx_backlog_entry(txep, tx_pkts, n);
     849                 :            : 
     850         [ #  # ]:          0 :                 for (i = 0; i < n - 1; ++i, ++tx_pkts, ++txdp)
     851                 :          0 :                         vtx1(txdp, *tx_pkts, flags);
     852                 :            : 
     853                 :          0 :                 vtx1(txdp, *tx_pkts++, rs);
     854                 :            : 
     855                 :          0 :                 nb_commit = (uint16_t)(nb_commit - n);
     856                 :            : 
     857                 :            :                 tx_id = 0;
     858                 :          0 :                 txq->next_rs = (uint16_t)(txq->rs_thresh - 1);
     859                 :            : 
     860                 :            :                 /* avoid reach the end of ring */
     861                 :          0 :                 txdp = &(txq->hw_ring[tx_id]);
     862                 :          0 :                 txep = &txq->sw_ring[tx_id];
     863                 :            :         }
     864                 :            : 
     865                 :          0 :         tx_backlog_entry(txep, tx_pkts, nb_commit);
     866                 :            : 
     867                 :            :         vtx(txdp, tx_pkts, nb_commit, flags);
     868                 :            : 
     869                 :          0 :         tx_id = (uint16_t)(tx_id + nb_commit);
     870         [ #  # ]:          0 :         if (tx_id > txq->next_rs) {
     871                 :          0 :                 txq->hw_ring[txq->next_rs].flags |= FM10K_TXD_FLAG_RS;
     872                 :          0 :                 txq->next_rs = (uint16_t)(txq->next_rs + txq->rs_thresh);
     873                 :            :         }
     874                 :            : 
     875                 :          0 :         txq->next_free = tx_id;
     876                 :            : 
     877                 :          0 :         FM10K_PCI_REG_WRITE(txq->tail_ptr, txq->next_free);
     878                 :            : 
     879                 :          0 :         return nb_pkts;
     880                 :            : }
     881                 :            : 
     882                 :            : static void __rte_cold
     883                 :          0 : fm10k_reset_tx_queue(struct fm10k_tx_queue *txq)
     884                 :            : {
     885                 :            :         static const struct fm10k_tx_desc zeroed_desc = {0};
     886                 :          0 :         struct rte_mbuf **txe = txq->sw_ring;
     887                 :            :         uint16_t i;
     888                 :            : 
     889                 :            :         /* Zero out HW ring memory */
     890         [ #  # ]:          0 :         for (i = 0; i < txq->nb_desc; i++)
     891                 :          0 :                 txq->hw_ring[i] = zeroed_desc;
     892                 :            : 
     893                 :            :         /* Initialize SW ring entries */
     894         [ #  # ]:          0 :         for (i = 0; i < txq->nb_desc; i++)
     895                 :          0 :                 txe[i] = NULL;
     896                 :            : 
     897                 :          0 :         txq->next_dd = (uint16_t)(txq->rs_thresh - 1);
     898                 :          0 :         txq->next_rs = (uint16_t)(txq->rs_thresh - 1);
     899                 :            : 
     900                 :          0 :         txq->next_free = 0;
     901                 :          0 :         txq->nb_used = 0;
     902                 :            :         /* Always allow 1 descriptor to be un-allocated to avoid
     903                 :            :          * a H/W race condition
     904                 :            :          */
     905                 :          0 :         txq->nb_free = (uint16_t)(txq->nb_desc - 1);
     906                 :          0 :         FM10K_PCI_REG_WRITE(txq->tail_ptr, 0);
     907                 :          0 : }

Generated by: LCOV version 1.14