LCOV - code coverage report
Current view: top level - drivers/net/enic - enic_rxtx_vec_avx2.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 85 0.0 %
Date: 2024-02-14 00:53:57 Functions: 0 3 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 56 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright 2008-2018 Cisco Systems, Inc.  All rights reserved.
       3                 :            :  * Copyright 2007 Nuova Systems, Inc.  All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include <rte_mbuf.h>
       7                 :            : #include <ethdev_driver.h>
       8                 :            : #include <rte_vect.h>
       9                 :            : 
      10                 :            : #include "enic_compat.h"
      11                 :            : #include "rq_enet_desc.h"
      12                 :            : #include "enic.h"
      13                 :            : #include "enic_rxtx_common.h"
      14                 :            : 
      15                 :            : #include <x86intrin.h>
      16                 :            : 
      17                 :            : static struct rte_mbuf *
      18                 :          0 : rx_one(struct cq_enet_rq_desc *cqd, struct rte_mbuf *mb, struct enic *enic)
      19                 :            : {
      20                 :            :         bool tnl;
      21                 :            : 
      22                 :          0 :         *(uint64_t *)&mb->rearm_data = enic->mbuf_initializer;
      23                 :          0 :         mb->data_len = cqd->bytes_written_flags &
      24                 :            :                 CQ_ENET_RQ_DESC_BYTES_WRITTEN_MASK;
      25                 :          0 :         mb->pkt_len = mb->data_len;
      26   [ #  #  #  # ]:          0 :         tnl = enic->overlay_offload && (cqd->completed_index_flags &
      27                 :            :                                         CQ_ENET_RQ_DESC_FLAGS_FCOE) != 0;
      28                 :          0 :         mb->packet_type =
      29                 :            :                 enic_cq_rx_flags_to_pkt_type((struct cq_desc *)cqd, tnl);
      30                 :          0 :         enic_cq_rx_to_pkt_flags((struct cq_desc *)cqd, mb);
      31                 :            :         /* Wipe the outer types set by enic_cq_rx_flags_to_pkt_type() */
      32         [ #  # ]:          0 :         if (tnl) {
      33                 :          0 :                 mb->packet_type &= ~(RTE_PTYPE_L3_MASK |
      34                 :            :                                      RTE_PTYPE_L4_MASK);
      35                 :            :         }
      36                 :          0 :         return mb;
      37                 :            : }
      38                 :            : 
      39                 :            : static uint16_t
      40                 :          0 : enic_noscatter_vec_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
      41                 :            :                              uint16_t nb_pkts)
      42                 :            : {
      43                 :            :         struct rte_mbuf **rx, **rxmb;
      44                 :            :         uint16_t cq_idx, nb_rx, max_rx;
      45                 :            :         struct cq_enet_rq_desc *cqd;
      46                 :            :         struct rq_enet_desc *rqd;
      47                 :            :         struct vnic_cq *cq;
      48                 :            :         struct vnic_rq *rq;
      49                 :            :         struct enic *enic;
      50                 :            :         uint8_t color;
      51                 :            : 
      52                 :            :         rq = rx_queue;
      53                 :          0 :         enic = vnic_dev_priv(rq->vdev);
      54                 :          0 :         cq = &enic->cq[enic_cq_rq(enic, rq->index)];
      55                 :          0 :         cq_idx = cq->to_clean;
      56                 :            : 
      57                 :            :         /*
      58                 :            :          * Fill up the reserve of free mbufs. Below, we restock the receive
      59                 :            :          * ring with these mbufs to avoid allocation failures.
      60                 :            :          */
      61         [ #  # ]:          0 :         if (rq->num_free_mbufs == 0) {
      62   [ #  #  #  # ]:          0 :                 if (rte_mempool_get_bulk(rq->mp, (void **)rq->free_mbufs,
      63                 :            :                                          ENIC_RX_BURST_MAX))
      64                 :            :                         return 0;
      65                 :          0 :                 rq->num_free_mbufs = ENIC_RX_BURST_MAX;
      66                 :            :         }
      67                 :            :         /* Receive until the end of the ring, at most. */
      68                 :          0 :         max_rx = RTE_MIN(nb_pkts, rq->num_free_mbufs);
      69                 :          0 :         max_rx = RTE_MIN(max_rx, cq->ring.desc_count - cq_idx);
      70                 :            : 
      71                 :          0 :         rxmb = rq->mbuf_ring + cq_idx;
      72                 :          0 :         color = cq->last_color;
      73                 :          0 :         cqd = (struct cq_enet_rq_desc *)(cq->ring.descs) + cq_idx;
      74                 :            :         rx = rx_pkts;
      75         [ #  # ]:          0 :         if (max_rx == 0 ||
      76         [ #  # ]:          0 :             (cqd->type_color & CQ_DESC_COLOR_MASK_NOSHIFT) == color)
      77                 :            :                 return 0;
      78                 :            : 
      79                 :            :         /* Step 1: Process one packet to do aligned 256-bit load below */
      80         [ #  # ]:          0 :         if (cq_idx & 0x1) {
      81         [ #  # ]:          0 :                 if (unlikely(cqd->bytes_written_flags &
      82                 :            :                              CQ_ENET_RQ_DESC_FLAGS_TRUNCATED)) {
      83                 :          0 :                         rte_pktmbuf_free(*rxmb++);
      84                 :          0 :                         rte_atomic64_inc(&enic->soft_stats.rx_packet_errors);
      85                 :            :                 } else {
      86                 :          0 :                         *rx++ = rx_one(cqd, *rxmb++, enic);
      87                 :            :                 }
      88                 :          0 :                 cqd++;
      89                 :          0 :                 max_rx--;
      90                 :            :         }
      91                 :            : 
      92                 :            :         const __m256i mask =
      93                 :            :                 _mm256_set_epi8(/* Second descriptor */
      94                 :            :                         0xff, /* type_color */
      95                 :            :                         (CQ_ENET_RQ_DESC_FLAGS_IPV4_FRAGMENT |
      96                 :            :                          CQ_ENET_RQ_DESC_FLAGS_IPV4 |
      97                 :            :                          CQ_ENET_RQ_DESC_FLAGS_IPV6 |
      98                 :            :                          CQ_ENET_RQ_DESC_FLAGS_TCP |
      99                 :            :                          CQ_ENET_RQ_DESC_FLAGS_UDP), /* flags */
     100                 :            :                         0, 0, /* checksum_fcoe */
     101                 :            :                         0xff, 0xff, /* vlan */
     102                 :            :                         0x3f, 0xff, /* bytes_written_flags */
     103                 :            :                         0xff, 0xff, 0xff, 0xff, /* rss_hash */
     104                 :            :                         0xff, 0xff, /* q_number_rss_type_flags */
     105                 :            :                         0, 0, /* completed_index_flags */
     106                 :            :                         /* First descriptor */
     107                 :            :                         0xff, /* type_color */
     108                 :            :                         (CQ_ENET_RQ_DESC_FLAGS_IPV4_FRAGMENT |
     109                 :            :                          CQ_ENET_RQ_DESC_FLAGS_IPV4 |
     110                 :            :                          CQ_ENET_RQ_DESC_FLAGS_IPV6 |
     111                 :            :                          CQ_ENET_RQ_DESC_FLAGS_TCP |
     112                 :            :                          CQ_ENET_RQ_DESC_FLAGS_UDP), /* flags */
     113                 :            :                         0, 0, /* checksum_fcoe */
     114                 :            :                         0xff, 0xff, /* vlan */
     115                 :            :                         0x3f, 0xff, /* bytes_written_flags */
     116                 :            :                         0xff, 0xff, 0xff, 0xff, /* rss_hash */
     117                 :            :                         0xff, 0xff, /* q_number_rss_type_flags */
     118                 :            :                         0, 0 /* completed_index_flags */
     119                 :            :                         );
     120                 :            :         const __m256i shuffle_mask =
     121                 :            :                 _mm256_set_epi8(/* Second descriptor */
     122                 :            :                         7, 6, 5, 4,             /* rss = rss_hash */
     123                 :            :                         11, 10,                 /* vlan_tci = vlan */
     124                 :            :                         9, 8,                   /* data_len = bytes_written */
     125                 :            :                         0x80, 0x80, 9, 8,       /* pkt_len = bytes_written */
     126                 :            :                         0x80, 0x80, 0x80, 0x80, /* packet_type = 0 */
     127                 :            :                         /* First descriptor */
     128                 :            :                         7, 6, 5, 4,             /* rss = rss_hash */
     129                 :            :                         11, 10,                 /* vlan_tci = vlan */
     130                 :            :                         9, 8,                   /* data_len = bytes_written */
     131                 :            :                         0x80, 0x80, 9, 8,       /* pkt_len = bytes_written */
     132                 :            :                         0x80, 0x80, 0x80, 0x80  /* packet_type = 0 */
     133                 :            :                         );
     134                 :            :         /* Used to collect 8 flags from 8 desc into one register */
     135                 :            :         const __m256i flags_shuffle_mask =
     136                 :            :                 _mm256_set_epi8(/* Second descriptor */
     137                 :            :                         1, 3, 9, 14,
     138                 :            :                         1, 3, 9, 14,
     139                 :            :                         1, 3, 9, 14,
     140                 :            :                         1, 3, 9, 14,
     141                 :            :                         /* First descriptor */
     142                 :            :                         1, 3, 9, 14,
     143                 :            :                         1, 3, 9, 14,
     144                 :            :                         1, 3, 9, 14,
     145                 :            :                         /*
     146                 :            :                          * Byte 3: upper byte of completed_index_flags
     147                 :            :                          *         bit 5 = fcoe (tunnel)
     148                 :            :                          * Byte 2: upper byte of q_number_rss_type_flags
     149                 :            :                          *         bits 2,3,4,5 = rss type
     150                 :            :                          *         bit 6 = csum_not_calc
     151                 :            :                          * Byte 1: upper byte of bytes_written_flags
     152                 :            :                          *         bit 6 = truncated
     153                 :            :                          *         bit 7 = vlan stripped
     154                 :            :                          * Byte 0: flags
     155                 :            :                          */
     156                 :            :                         1, 3, 9, 14
     157                 :            :                         );
     158                 :            :         /* Used to collect 8 VLAN IDs from 8 desc into one register */
     159                 :            :         const __m256i vlan_shuffle_mask =
     160                 :            :                 _mm256_set_epi8(/* Second descriptor */
     161                 :            :                         0x80, 0x80, 11, 10,
     162                 :            :                         0x80, 0x80, 11, 10,
     163                 :            :                         0x80, 0x80, 11, 10,
     164                 :            :                         0x80, 0x80, 11, 10,
     165                 :            :                         /* First descriptor */
     166                 :            :                         0x80, 0x80, 11, 10,
     167                 :            :                         0x80, 0x80, 11, 10,
     168                 :            :                         0x80, 0x80, 11, 10,
     169                 :            :                         0x80, 0x80, 11, 10);
     170                 :            :         /* RTE_MBUF_F_RX_RSS_HASH is 1<<1 so fits in 8-bit integer */
     171                 :            :         const __m256i rss_shuffle =
     172                 :            :                 _mm256_set_epi8(/* second 128 bits */
     173                 :            :                         RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH,
     174                 :            :                         RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH,
     175                 :            :                         RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH,
     176                 :            :                         RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH,
     177                 :            :                         RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH,
     178                 :            :                         0, /* rss_types = 0 */
     179                 :            :                         /* first 128 bits */
     180                 :            :                         RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH,
     181                 :            :                         RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH,
     182                 :            :                         RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH,
     183                 :            :                         RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH,
     184                 :            :                         RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH, RTE_MBUF_F_RX_RSS_HASH,
     185                 :            :                         0 /* rss_types = 0 */);
     186                 :            :         /*
     187                 :            :          * VLAN offload flags.
     188                 :            :          * shuffle index:
     189                 :            :          * vlan_stripped => bit 0
     190                 :            :          * vlan_id == 0  => bit 1
     191                 :            :          */
     192                 :            :         const __m256i vlan_shuffle =
     193                 :            :                 _mm256_set_epi32(0, 0, 0, 0,
     194                 :            :                         RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED, 0,
     195                 :            :                         RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED, RTE_MBUF_F_RX_VLAN);
     196                 :            :         /* Use the same shuffle index as vlan_shuffle */
     197                 :            :         const __m256i vlan_ptype_shuffle =
     198                 :            :                 _mm256_set_epi32(0, 0, 0, 0,
     199                 :            :                                  RTE_PTYPE_L2_ETHER,
     200                 :            :                                  RTE_PTYPE_L2_ETHER,
     201                 :            :                                  RTE_PTYPE_L2_ETHER,
     202                 :            :                                  RTE_PTYPE_L2_ETHER_VLAN);
     203                 :            :         /*
     204                 :            :          * CKSUM flags. Shift right so they fit int 8-bit integers.
     205                 :            :          * shuffle index:
     206                 :            :          * ipv4_csum_ok    => bit 3
     207                 :            :          * ip4             => bit 2
     208                 :            :          * tcp_or_udp      => bit 1
     209                 :            :          * tcp_udp_csum_ok => bit 0
     210                 :            :          */
     211                 :            :         const __m256i csum_shuffle =
     212                 :            :                 _mm256_set_epi8(/* second 128 bits */
     213                 :            :                         /* 1111 ip4+ip4_ok+l4+l4_ok */
     214                 :            :                         ((RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1),
     215                 :            :                         /* 1110 ip4_ok+ip4+l4+!l4_ok */
     216                 :            :                         ((RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1),
     217                 :            :                         (RTE_MBUF_F_RX_IP_CKSUM_GOOD >> 1), /* 1101 ip4+ip4_ok */
     218                 :            :                         (RTE_MBUF_F_RX_IP_CKSUM_GOOD >> 1), /* 1100 ip4_ok+ip4 */
     219                 :            :                         (RTE_MBUF_F_RX_L4_CKSUM_GOOD >> 1), /* 1011 l4+l4_ok */
     220                 :            :                         (RTE_MBUF_F_RX_L4_CKSUM_BAD >> 1),  /* 1010 l4+!l4_ok */
     221                 :            :                         0, /* 1001 */
     222                 :            :                         0, /* 1000 */
     223                 :            :                         /* 0111 !ip4_ok+ip4+l4+l4_ok */
     224                 :            :                         ((RTE_MBUF_F_RX_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1),
     225                 :            :                         /* 0110 !ip4_ok+ip4+l4+!l4_ok */
     226                 :            :                         ((RTE_MBUF_F_RX_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1),
     227                 :            :                         (RTE_MBUF_F_RX_IP_CKSUM_BAD >> 1),  /* 0101 !ip4_ok+ip4 */
     228                 :            :                         (RTE_MBUF_F_RX_IP_CKSUM_BAD >> 1),  /* 0100 !ip4_ok+ip4 */
     229                 :            :                         (RTE_MBUF_F_RX_L4_CKSUM_GOOD >> 1), /* 0011 l4+l4_ok */
     230                 :            :                         (RTE_MBUF_F_RX_L4_CKSUM_BAD >> 1),  /* 0010 l4+!l4_ok */
     231                 :            :                         0, /* 0001 */
     232                 :            :                         0, /* 0000 */
     233                 :            :                         /* first 128 bits */
     234                 :            :                         ((RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1),
     235                 :            :                         ((RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1),
     236                 :            :                         (RTE_MBUF_F_RX_IP_CKSUM_GOOD >> 1),
     237                 :            :                         (RTE_MBUF_F_RX_IP_CKSUM_GOOD >> 1),
     238                 :            :                         (RTE_MBUF_F_RX_L4_CKSUM_GOOD >> 1),
     239                 :            :                         (RTE_MBUF_F_RX_L4_CKSUM_BAD >> 1),
     240                 :            :                         0, 0,
     241                 :            :                         ((RTE_MBUF_F_RX_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1),
     242                 :            :                         ((RTE_MBUF_F_RX_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1),
     243                 :            :                         (RTE_MBUF_F_RX_IP_CKSUM_BAD >> 1),
     244                 :            :                         (RTE_MBUF_F_RX_IP_CKSUM_BAD >> 1),
     245                 :            :                         (RTE_MBUF_F_RX_L4_CKSUM_GOOD >> 1),
     246                 :            :                         (RTE_MBUF_F_RX_L4_CKSUM_BAD >> 1),
     247                 :            :                         0, 0);
     248                 :            :         /*
     249                 :            :          * Non-fragment PTYPEs.
     250                 :            :          * Shuffle 4-bit index:
     251                 :            :          * ip6 => bit 0
     252                 :            :          * ip4 => bit 1
     253                 :            :          * udp => bit 2
     254                 :            :          * tcp => bit 3
     255                 :            :          *   bit
     256                 :            :          * 3 2 1 0
     257                 :            :          * -------
     258                 :            :          * 0 0 0 0 unknown
     259                 :            :          * 0 0 0 1 ip6 | nonfrag
     260                 :            :          * 0 0 1 0 ip4 | nonfrag
     261                 :            :          * 0 0 1 1 unknown
     262                 :            :          * 0 1 0 0 unknown
     263                 :            :          * 0 1 0 1 ip6 | udp
     264                 :            :          * 0 1 1 0 ip4 | udp
     265                 :            :          * 0 1 1 1 unknown
     266                 :            :          * 1 0 0 0 unknown
     267                 :            :          * 1 0 0 1 ip6 | tcp
     268                 :            :          * 1 0 1 0 ip4 | tcp
     269                 :            :          * 1 0 1 1 unknown
     270                 :            :          * 1 1 0 0 unknown
     271                 :            :          * 1 1 0 1 unknown
     272                 :            :          * 1 1 1 0 unknown
     273                 :            :          * 1 1 1 1 unknown
     274                 :            :          *
     275                 :            :          * PTYPEs do not fit in 8 bits, so shift right 4..
     276                 :            :          */
     277                 :            :         const __m256i nonfrag_ptype_shuffle =
     278                 :            :                 _mm256_set_epi8(/* second 128 bits */
     279                 :            :                         RTE_PTYPE_UNKNOWN,
     280                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     281                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     282                 :            :                         (RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_TCP) >> 4,
     283                 :            :                         (RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_TCP) >> 4,
     284                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     285                 :            :                         (RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP) >> 4,
     286                 :            :                         (RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_UDP) >> 4,
     287                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     288                 :            :                         (RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
     289                 :            :                          RTE_PTYPE_L4_NONFRAG) >> 4,
     290                 :            :                         (RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
     291                 :            :                          RTE_PTYPE_L4_NONFRAG) >> 4,
     292                 :            :                         RTE_PTYPE_UNKNOWN,
     293                 :            :                         /* first 128 bits */
     294                 :            :                         RTE_PTYPE_UNKNOWN,
     295                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     296                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     297                 :            :                         (RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_TCP) >> 4,
     298                 :            :                         (RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_TCP) >> 4,
     299                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     300                 :            :                         (RTE_PTYPE_L3_IPV4_EXT_UNKNOWN | RTE_PTYPE_L4_UDP) >> 4,
     301                 :            :                         (RTE_PTYPE_L3_IPV6_EXT_UNKNOWN | RTE_PTYPE_L4_UDP) >> 4,
     302                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     303                 :            :                         (RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
     304                 :            :                          RTE_PTYPE_L4_NONFRAG) >> 4,
     305                 :            :                         (RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
     306                 :            :                          RTE_PTYPE_L4_NONFRAG) >> 4,
     307                 :            :                         RTE_PTYPE_UNKNOWN);
     308                 :            :         /* Fragment PTYPEs. Use the same shuffle index as above. */
     309                 :            :         const __m256i frag_ptype_shuffle =
     310                 :            :                 _mm256_set_epi8(/* second 128 bits */
     311                 :            :                         RTE_PTYPE_UNKNOWN,
     312                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     313                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     314                 :            :                         (RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
     315                 :            :                          RTE_PTYPE_L4_FRAG) >> 4,
     316                 :            :                         (RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
     317                 :            :                          RTE_PTYPE_L4_FRAG) >> 4,
     318                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     319                 :            :                         (RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
     320                 :            :                          RTE_PTYPE_L4_FRAG) >> 4,
     321                 :            :                         (RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
     322                 :            :                          RTE_PTYPE_L4_FRAG) >> 4,
     323                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     324                 :            :                         (RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
     325                 :            :                          RTE_PTYPE_L4_FRAG) >> 4,
     326                 :            :                         (RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
     327                 :            :                          RTE_PTYPE_L4_FRAG) >> 4,
     328                 :            :                         RTE_PTYPE_UNKNOWN,
     329                 :            :                         /* first 128 bits */
     330                 :            :                         RTE_PTYPE_UNKNOWN,
     331                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     332                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     333                 :            :                         (RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
     334                 :            :                          RTE_PTYPE_L4_FRAG) >> 4,
     335                 :            :                         (RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
     336                 :            :                          RTE_PTYPE_L4_FRAG) >> 4,
     337                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     338                 :            :                         (RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
     339                 :            :                          RTE_PTYPE_L4_FRAG) >> 4,
     340                 :            :                         (RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
     341                 :            :                          RTE_PTYPE_L4_FRAG) >> 4,
     342                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     343                 :            :                         (RTE_PTYPE_L3_IPV4_EXT_UNKNOWN |
     344                 :            :                          RTE_PTYPE_L4_FRAG) >> 4,
     345                 :            :                         (RTE_PTYPE_L3_IPV6_EXT_UNKNOWN |
     346                 :            :                          RTE_PTYPE_L4_FRAG) >> 4,
     347                 :            :                         RTE_PTYPE_UNKNOWN);
     348                 :            :         /*
     349                 :            :          * Tunnel PTYPEs. Use the same shuffle index as above.
     350                 :            :          * L4 types are not part of this table. They come from non-tunnel
     351                 :            :          * types above.
     352                 :            :          */
     353                 :            :         const __m256i tnl_l3_ptype_shuffle =
     354                 :            :                 _mm256_set_epi8(/* second 128 bits */
     355                 :            :                         RTE_PTYPE_UNKNOWN,
     356                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     357                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     358                 :            :                         RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN >> 16,
     359                 :            :                         RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN >> 16,
     360                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     361                 :            :                         RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN >> 16,
     362                 :            :                         RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN >> 16,
     363                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     364                 :            :                         RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN >> 16,
     365                 :            :                         RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN >> 16,
     366                 :            :                         RTE_PTYPE_UNKNOWN,
     367                 :            :                         /* first 128 bits */
     368                 :            :                         RTE_PTYPE_UNKNOWN,
     369                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     370                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     371                 :            :                         RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN >> 16,
     372                 :            :                         RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN >> 16,
     373                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     374                 :            :                         RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN >> 16,
     375                 :            :                         RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN >> 16,
     376                 :            :                         RTE_PTYPE_UNKNOWN, RTE_PTYPE_UNKNOWN,
     377                 :            :                         RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN >> 16,
     378                 :            :                         RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN >> 16,
     379                 :            :                         RTE_PTYPE_UNKNOWN);
     380                 :            : 
     381                 :          0 :         const __m256i mbuf_init = _mm256_set_epi64x(0, enic->mbuf_initializer,
     382                 :          0 :                                                     0, enic->mbuf_initializer);
     383                 :            : 
     384                 :            :         /*
     385                 :            :          * --- cq desc fields ---    offset
     386                 :            :          * completed_index_flags    - 0   use: fcoe
     387                 :            :          * q_number_rss_type_flags  - 2   use: rss types, csum_not_calc
     388                 :            :          * rss_hash                 - 4   ==> mbuf.hash.rss
     389                 :            :          * bytes_written_flags      - 8   ==> mbuf.pkt_len,data_len
     390                 :            :          *                                use: truncated, vlan_stripped
     391                 :            :          * vlan                     - 10  ==> mbuf.vlan_tci
     392                 :            :          * checksum_fcoe            - 12  (unused)
     393                 :            :          * flags                    - 14  use: all bits
     394                 :            :          * type_color               - 15  (unused)
     395                 :            :          *
     396                 :            :          * --- mbuf fields ---       offset
     397                 :            :          * rearm_data              ---- 16
     398                 :            :          * data_off    - 0      (mbuf_init) -+
     399                 :            :          * refcnt      - 2      (mbuf_init)  |
     400                 :            :          * nb_segs     - 4      (mbuf_init)  | 16B 128b
     401                 :            :          * port        - 6      (mbuf_init)  |
     402                 :            :          * ol_flag     - 8      (from cqd)  -+
     403                 :            :          * rx_descriptor_fields1   ---- 32
     404                 :            :          * packet_type - 0      (from cqd)  -+
     405                 :            :          * pkt_len     - 4      (from cqd)   |
     406                 :            :          * data_len    - 8      (from cqd)   | 16B 128b
     407                 :            :          * vlan_tci    - 10     (from cqd)   |
     408                 :            :          * rss         - 12     (from cqd)  -+
     409                 :            :          */
     410                 :            : 
     411                 :            :         __m256i overlay_enabled =
     412                 :          0 :                 _mm256_set1_epi32((uint32_t)enic->overlay_offload);
     413                 :            : 
     414                 :            :         /* Step 2: Process 8 packets per loop using SIMD */
     415   [ #  #  #  # ]:          0 :         while (max_rx > 7 && (((cqd + 7)->type_color &
     416                 :            :                                CQ_DESC_COLOR_MASK_NOSHIFT) != color)) {
     417                 :            :                 /* Load 8 16B CQ descriptors */
     418                 :            :                 __m256i cqd01 = _mm256_load_si256((void *)cqd);
     419                 :            :                 __m256i cqd23 = _mm256_load_si256((void *)(cqd + 2));
     420                 :            :                 __m256i cqd45 = _mm256_load_si256((void *)(cqd + 4));
     421                 :            :                 __m256i cqd67 = _mm256_load_si256((void *)(cqd + 6));
     422                 :            :                 /* Copy 8 mbuf pointers to rx_pkts */
     423                 :            :                 _mm256_storeu_si256((void *)rx,
     424                 :            :                                     _mm256_loadu_si256((void *)rxmb));
     425                 :            :                 _mm256_storeu_si256((void *)(rx + 4),
     426                 :            :                                     _mm256_loadu_si256((void *)(rxmb + 4)));
     427                 :            : 
     428                 :            :                 /*
     429                 :            :                  * Collect 8 flags (each 32 bits) into one register.
     430                 :            :                  * 4 shuffles, 3 blends, 1 permute for 8 desc: 1 inst/desc
     431                 :            :                  */
     432                 :            :                 __m256i flags01 =
     433                 :            :                         _mm256_shuffle_epi8(cqd01, flags_shuffle_mask);
     434                 :            :                 /*
     435                 :            :                  * Shuffle above produces 8 x 32-bit flags for 8 descriptors
     436                 :            :                  * in this order: 0, 0, 0, 0, 1, 1, 1, 1
     437                 :            :                  * The duplicates in each 128-bit lane simplifies blending
     438                 :            :                  * below.
     439                 :            :                  */
     440                 :            :                 __m256i flags23 =
     441                 :            :                         _mm256_shuffle_epi8(cqd23, flags_shuffle_mask);
     442                 :            :                 __m256i flags45 =
     443                 :            :                         _mm256_shuffle_epi8(cqd45, flags_shuffle_mask);
     444                 :            :                 __m256i flags67 =
     445                 :            :                         _mm256_shuffle_epi8(cqd67, flags_shuffle_mask);
     446                 :            :                 /* 1st blend produces flags for desc: 0, 2, 0, 0, 1, 3, 1, 1 */
     447                 :            :                 __m256i flags0_3 = _mm256_blend_epi32(flags01, flags23, 0x22);
     448                 :            :                 /* 2nd blend produces flags for desc: 4, 4, 4, 6, 5, 5, 5, 7 */
     449                 :            :                 __m256i flags4_7 = _mm256_blend_epi32(flags45, flags67, 0x88);
     450                 :            :                 /* 3rd blend produces flags for desc: 0, 2, 4, 6, 1, 3, 5, 7 */
     451                 :            :                 __m256i flags0_7 = _mm256_blend_epi32(flags0_3, flags4_7, 0xcc);
     452                 :            :                 /*
     453                 :            :                  * Swap to reorder flags in this order: 1, 3, 5, 7, 0, 2, 4, 6
     454                 :            :                  * This order simplifies blend operations way below that
     455                 :            :                  * produce 'rearm' data for each mbuf.
     456                 :            :                  */
     457                 :            :                 flags0_7 = _mm256_permute4x64_epi64(flags0_7,
     458                 :            :                         (1 << 6) + (0 << 4) + (3 << 2) + 2);
     459                 :            : 
     460                 :            :                 /*
     461                 :            :                  * Check truncated bits and bail out early on.
     462                 :            :                  * 6 avx inst, 1 or, 1 if-then-else for 8 desc: 1 inst/desc
     463                 :            :                  */
     464                 :            :                 __m256i trunc =
     465                 :            :                         _mm256_srli_epi32(_mm256_slli_epi32(flags0_7, 17), 31);
     466                 :            :                 trunc = _mm256_add_epi64(trunc, _mm256_permute4x64_epi64(trunc,
     467                 :            :                         (1 << 6) + (0 << 4) + (3 << 2) + 2));
     468                 :            :                 /* 0:63 contains 1+3+0+2 and 64:127 contains 5+7+4+6 */
     469   [ #  #  #  # ]:          0 :                 if (_mm256_extract_epi64(trunc, 0) ||
     470                 :            :                     _mm256_extract_epi64(trunc, 1))
     471                 :            :                         break;
     472                 :            : 
     473                 :            :                 /*
     474                 :            :                  * Compute RTE_MBUF_F_RX_RSS_HASH.
     475                 :            :                  * Use 2 shifts and 1 shuffle for 8 desc: 0.375 inst/desc
     476                 :            :                  * RSS types in byte 0, 4, 8, 12, 16, 20, 24, 28
     477                 :            :                  * Everything else is zero.
     478                 :            :                  */
     479                 :            :                 __m256i rss_types =
     480                 :            :                         _mm256_srli_epi32(_mm256_slli_epi32(flags0_7, 10), 28);
     481                 :            :                 /*
     482                 :            :                  * RSS flags (RTE_MBUF_F_RX_RSS_HASH) are in
     483                 :            :                  * byte 0, 4, 8, 12, 16, 20, 24, 28
     484                 :            :                  * Everything else is zero.
     485                 :            :                  */
     486                 :            :                 __m256i rss_flags = _mm256_shuffle_epi8(rss_shuffle, rss_types);
     487                 :            : 
     488                 :            :                 /*
     489                 :            :                  * Compute CKSUM flags. First build the index and then
     490                 :            :                  * use it to shuffle csum_shuffle.
     491                 :            :                  * 20 instructions including const loads: 2.5 inst/desc
     492                 :            :                  */
     493                 :            :                 /*
     494                 :            :                  * csum_not_calc (bit 22)
     495                 :            :                  * csum_not_calc (0) => 0xffffffff
     496                 :            :                  * csum_not_calc (1) => 0x0
     497                 :            :                  */
     498                 :            :                 const __m256i zero4 = _mm256_setzero_si256();
     499                 :            :                 const __m256i mask22 = _mm256_set1_epi32(0x400000);
     500                 :            :                 __m256i csum_not_calc = _mm256_cmpeq_epi32(zero4,
     501                 :            :                         _mm256_and_si256(flags0_7, mask22));
     502                 :            :                 /*
     503                 :            :                  * (tcp|udp) && !fragment => bit 1
     504                 :            :                  * tcp = bit 2, udp = bit 1, frag = bit 6
     505                 :            :                  */
     506                 :            :                 const __m256i mask1 = _mm256_set1_epi32(0x2);
     507                 :            :                 __m256i tcp_udp =
     508                 :            :                         _mm256_andnot_si256(_mm256_srli_epi32(flags0_7, 5),
     509                 :            :                                 _mm256_or_si256(flags0_7,
     510                 :            :                                         _mm256_srli_epi32(flags0_7, 1)));
     511                 :            :                 tcp_udp = _mm256_and_si256(tcp_udp, mask1);
     512                 :            :                 /* ipv4 (bit 5) => bit 2 */
     513                 :            :                 const __m256i mask2 = _mm256_set1_epi32(0x4);
     514                 :            :                 __m256i ipv4 = _mm256_and_si256(mask2,
     515                 :            :                         _mm256_srli_epi32(flags0_7, 3));
     516                 :            :                 /*
     517                 :            :                  * ipv4_csum_ok (bit 3) => bit 3
     518                 :            :                  * tcp_udp_csum_ok (bit 0) => bit 0
     519                 :            :                  * 0x9
     520                 :            :                  */
     521                 :            :                 const __m256i mask0_3 = _mm256_set1_epi32(0x9);
     522                 :            :                 __m256i csum_idx = _mm256_and_si256(flags0_7, mask0_3);
     523                 :            :                 csum_idx = _mm256_and_si256(csum_not_calc,
     524                 :            :                         _mm256_or_si256(_mm256_or_si256(csum_idx, ipv4),
     525                 :            :                                 tcp_udp));
     526                 :            :                 __m256i csum_flags =
     527                 :            :                         _mm256_shuffle_epi8(csum_shuffle, csum_idx);
     528                 :            :                 /* Shift left to restore CKSUM flags. See csum_shuffle. */
     529                 :            :                 csum_flags = _mm256_slli_epi32(csum_flags, 1);
     530                 :            :                 /* Combine csum flags and offload flags: 0.125 inst/desc */
     531                 :            :                 rss_flags = _mm256_or_si256(rss_flags, csum_flags);
     532                 :            : 
     533                 :            :                 /*
     534                 :            :                  * Collect 8 VLAN IDs and compute vlan_id != 0 on each.
     535                 :            :                  * 4 shuffles, 3 blends, 1 permute, 1 cmp, 1 sub for 8 desc:
     536                 :            :                  * 1.25 inst/desc
     537                 :            :                  */
     538                 :            :                 __m256i vlan01 = _mm256_shuffle_epi8(cqd01, vlan_shuffle_mask);
     539                 :            :                 __m256i vlan23 = _mm256_shuffle_epi8(cqd23, vlan_shuffle_mask);
     540                 :            :                 __m256i vlan45 = _mm256_shuffle_epi8(cqd45, vlan_shuffle_mask);
     541                 :            :                 __m256i vlan67 = _mm256_shuffle_epi8(cqd67, vlan_shuffle_mask);
     542                 :            :                 __m256i vlan0_3 = _mm256_blend_epi32(vlan01, vlan23, 0x22);
     543                 :            :                 __m256i vlan4_7 = _mm256_blend_epi32(vlan45, vlan67, 0x88);
     544                 :            :                 /* desc: 0, 2, 4, 6, 1, 3, 5, 7 */
     545                 :            :                 __m256i vlan0_7 = _mm256_blend_epi32(vlan0_3, vlan4_7, 0xcc);
     546                 :            :                 /* desc: 1, 3, 5, 7, 0, 2, 4, 6 */
     547                 :            :                 vlan0_7 = _mm256_permute4x64_epi64(vlan0_7,
     548                 :            :                         (1 << 6) + (0 << 4) + (3 << 2) + 2);
     549                 :            :                 /*
     550                 :            :                  * Compare 0 == vlan_id produces 0xffffffff (-1) if
     551                 :            :                  * vlan 0 and 0 if vlan non-0. Then subtracting the
     552                 :            :                  * result from 0 produces 0 - (-1) = 1 for vlan 0, and
     553                 :            :                  * 0 - 0 = 0 for vlan non-0.
     554                 :            :                  */
     555                 :            :                 vlan0_7 = _mm256_cmpeq_epi32(zero4, vlan0_7);
     556                 :            :                 /* vlan_id != 0 => 0, vlan_id == 0 => 1 */
     557                 :            :                 vlan0_7 = _mm256_sub_epi32(zero4, vlan0_7);
     558                 :            : 
     559                 :            :                 /*
     560                 :            :                  * Compute RTE_MBUF_F_RX_VLAN and RTE_MBUF_F_RX_VLAN_STRIPPED.
     561                 :            :                  * Use 3 shifts, 1 or,  1 shuffle for 8 desc: 0.625 inst/desc
     562                 :            :                  * VLAN offload flags in byte 0, 4, 8, 12, 16, 20, 24, 28
     563                 :            :                  * Everything else is zero.
     564                 :            :                  */
     565                 :            :                 __m256i vlan_idx =
     566                 :            :                         _mm256_or_si256(/* vlan_stripped => bit 0 */
     567                 :            :                                 _mm256_srli_epi32(_mm256_slli_epi32(flags0_7,
     568                 :            :                                         16), 31),
     569                 :            :                                 /* (vlan_id == 0) => bit 1 */
     570                 :            :                                 _mm256_slli_epi32(vlan0_7, 1));
     571                 :            :                 /*
     572                 :            :                  * The index captures 4 cases.
     573                 :            :                  * stripped, id = 0   ==> 11b = 3
     574                 :            :                  * stripped, id != 0  ==> 01b = 1
     575                 :            :                  * not strip, id == 0 ==> 10b = 2
     576                 :            :                  * not strip, id != 0 ==> 00b = 0
     577                 :            :                  */
     578                 :            :                 __m256i vlan_flags = _mm256_permutevar8x32_epi32(vlan_shuffle,
     579                 :            :                         vlan_idx);
     580                 :            :                 /* Combine vlan and offload flags: 0.125 inst/desc */
     581                 :            :                 rss_flags = _mm256_or_si256(rss_flags, vlan_flags);
     582                 :            : 
     583                 :            :                 /*
     584                 :            :                  * Compute non-tunnel PTYPEs.
     585                 :            :                  * 17 inst / 8 desc = 2.125 inst/desc
     586                 :            :                  */
     587                 :            :                 /* ETHER and ETHER_VLAN */
     588                 :            :                 __m256i vlan_ptype =
     589                 :            :                         _mm256_permutevar8x32_epi32(vlan_ptype_shuffle,
     590                 :            :                                 vlan_idx);
     591                 :            :                 /* Build the ptype index from flags */
     592                 :            :                 tcp_udp = _mm256_slli_epi32(flags0_7, 29);
     593                 :            :                 tcp_udp = _mm256_slli_epi32(_mm256_srli_epi32(tcp_udp, 30), 2);
     594                 :            :                 __m256i ip4_ip6 =
     595                 :            :                         _mm256_srli_epi32(_mm256_slli_epi32(flags0_7, 26), 30);
     596                 :            :                 __m256i ptype_idx = _mm256_or_si256(tcp_udp, ip4_ip6);
     597                 :            :                 __m256i frag_bit =
     598                 :            :                         _mm256_srli_epi32(_mm256_slli_epi32(flags0_7, 25), 31);
     599                 :            :                 __m256i nonfrag_ptype =
     600                 :            :                         _mm256_shuffle_epi8(nonfrag_ptype_shuffle, ptype_idx);
     601                 :            :                 __m256i frag_ptype =
     602                 :            :                         _mm256_shuffle_epi8(frag_ptype_shuffle, ptype_idx);
     603                 :            :                 /*
     604                 :            :                  * Zero out the unwanted types and combine the remaining bits.
     605                 :            :                  * The effect is same as selecting non-frag or frag types
     606                 :            :                  * depending on the frag bit.
     607                 :            :                  */
     608                 :            :                 nonfrag_ptype = _mm256_and_si256(nonfrag_ptype,
     609                 :            :                         _mm256_cmpeq_epi32(zero4, frag_bit));
     610                 :            :                 frag_ptype = _mm256_and_si256(frag_ptype,
     611                 :            :                         _mm256_cmpgt_epi32(frag_bit, zero4));
     612                 :            :                 __m256i ptype = _mm256_or_si256(nonfrag_ptype, frag_ptype);
     613                 :            :                 ptype = _mm256_slli_epi32(ptype, 4);
     614                 :            :                 /*
     615                 :            :                  * Compute tunnel PTYPEs.
     616                 :            :                  * 15 inst / 8 desc = 1.875 inst/desc
     617                 :            :                  */
     618                 :            :                 __m256i tnl_l3_ptype =
     619                 :            :                         _mm256_shuffle_epi8(tnl_l3_ptype_shuffle, ptype_idx);
     620                 :            :                 tnl_l3_ptype = _mm256_slli_epi32(tnl_l3_ptype, 16);
     621                 :            :                 /*
     622                 :            :                  * Shift non-tunnel L4 types to make them tunnel types.
     623                 :            :                  * RTE_PTYPE_L4_TCP << 16 == RTE_PTYPE_INNER_L4_TCP
     624                 :            :                  */
     625                 :            :                 __m256i tnl_l4_ptype =
     626                 :            :                         _mm256_slli_epi32(_mm256_and_si256(ptype,
     627                 :            :                                 _mm256_set1_epi32(RTE_PTYPE_L4_MASK)), 16);
     628                 :            :                 __m256i tnl_ptype =
     629                 :            :                         _mm256_or_si256(tnl_l3_ptype, tnl_l4_ptype);
     630                 :            :                 tnl_ptype = _mm256_or_si256(tnl_ptype,
     631                 :            :                         _mm256_set1_epi32(RTE_PTYPE_TUNNEL_GRENAT |
     632                 :            :                                 RTE_PTYPE_INNER_L2_ETHER));
     633                 :            :                 /*
     634                 :            :                  * Select non-tunnel or tunnel types by zeroing out the
     635                 :            :                  * unwanted ones.
     636                 :            :                  */
     637                 :            :                 __m256i tnl_flags = _mm256_and_si256(overlay_enabled,
     638                 :            :                         _mm256_srli_epi32(_mm256_slli_epi32(flags0_7, 2), 31));
     639                 :            :                 tnl_ptype = _mm256_and_si256(tnl_ptype,
     640                 :            :                         _mm256_sub_epi32(zero4, tnl_flags));
     641                 :            :                 ptype = _mm256_and_si256(ptype,
     642                 :            :                         _mm256_cmpeq_epi32(zero4, tnl_flags));
     643                 :            :                 /*
     644                 :            :                  * Combine types and swap to have ptypes in the same order
     645                 :            :                  * as desc.
     646                 :            :                  * desc: 0 2 4 6 1 3 5 7
     647                 :            :                  * 3 inst / 8 desc = 0.375 inst/desc
     648                 :            :                  */
     649                 :            :                 ptype = _mm256_or_si256(ptype, tnl_ptype);
     650                 :            :                 ptype = _mm256_or_si256(ptype, vlan_ptype);
     651                 :            :                 ptype = _mm256_permute4x64_epi64(ptype,
     652                 :            :                         (1 << 6) + (0 << 4) + (3 << 2) + 2);
     653                 :            : 
     654                 :            :                 /*
     655                 :            :                  * Mask packet length.
     656                 :            :                  * Use 4 ands: 0.5 instructions/desc
     657                 :            :                  */
     658                 :            :                 cqd01 = _mm256_and_si256(cqd01, mask);
     659                 :            :                 cqd23 = _mm256_and_si256(cqd23, mask);
     660                 :            :                 cqd45 = _mm256_and_si256(cqd45, mask);
     661                 :            :                 cqd67 = _mm256_and_si256(cqd67, mask);
     662                 :            :                 /*
     663                 :            :                  * Shuffle. Two 16B sets of the mbuf fields.
     664                 :            :                  * packet_type, pkt_len, data_len, vlan_tci, rss
     665                 :            :                  */
     666                 :            :                 __m256i rearm01 = _mm256_shuffle_epi8(cqd01, shuffle_mask);
     667                 :            :                 __m256i rearm23 = _mm256_shuffle_epi8(cqd23, shuffle_mask);
     668                 :            :                 __m256i rearm45 = _mm256_shuffle_epi8(cqd45, shuffle_mask);
     669                 :            :                 __m256i rearm67 = _mm256_shuffle_epi8(cqd67, shuffle_mask);
     670                 :            : 
     671                 :            :                 /*
     672                 :            :                  * Blend in ptypes
     673                 :            :                  * 4 blends and 3 shuffles for 8 desc: 0.875 inst/desc
     674                 :            :                  */
     675                 :            :                 rearm01 = _mm256_blend_epi32(rearm01, ptype, 0x11);
     676                 :            :                 rearm23 = _mm256_blend_epi32(rearm23,
     677                 :            :                         _mm256_shuffle_epi32(ptype, 1), 0x11);
     678                 :            :                 rearm45 = _mm256_blend_epi32(rearm45,
     679                 :            :                         _mm256_shuffle_epi32(ptype, 2), 0x11);
     680                 :            :                 rearm67 = _mm256_blend_epi32(rearm67,
     681                 :            :                         _mm256_shuffle_epi32(ptype, 3), 0x11);
     682                 :            : 
     683                 :            :                 /*
     684                 :            :                  * Move rss_flags into ol_flags in mbuf_init.
     685                 :            :                  * Use 1 shift and 1 blend for each desc: 2 inst/desc
     686                 :            :                  */
     687                 :            :                 __m256i mbuf_init4_5 = _mm256_blend_epi32(mbuf_init,
     688                 :            :                         rss_flags, 0x44);
     689                 :            :                 __m256i mbuf_init2_3 = _mm256_blend_epi32(mbuf_init,
     690                 :            :                         _mm256_slli_si256(rss_flags, 4), 0x44);
     691                 :            :                 __m256i mbuf_init0_1 = _mm256_blend_epi32(mbuf_init,
     692                 :            :                         _mm256_slli_si256(rss_flags, 8), 0x44);
     693                 :            :                 __m256i mbuf_init6_7 = _mm256_blend_epi32(mbuf_init,
     694                 :            :                         _mm256_srli_si256(rss_flags, 4), 0x44);
     695                 :            : 
     696                 :            :                 /*
     697                 :            :                  * Build rearm, one per desc.
     698                 :            :                  * 8 blends and 4 permutes: 1.5 inst/desc
     699                 :            :                  */
     700                 :            :                 __m256i rearm0 = _mm256_blend_epi32(rearm01,
     701                 :            :                         mbuf_init0_1, 0xf0);
     702                 :            :                 __m256i rearm1 = _mm256_blend_epi32(mbuf_init0_1,
     703                 :            :                         rearm01, 0xf0);
     704                 :            :                 __m256i rearm2 = _mm256_blend_epi32(rearm23,
     705                 :            :                         mbuf_init2_3, 0xf0);
     706                 :            :                 __m256i rearm3 = _mm256_blend_epi32(mbuf_init2_3,
     707                 :            :                         rearm23, 0xf0);
     708                 :            :                 /* Swap upper and lower 64 bits */
     709                 :            :                 rearm0 = _mm256_permute4x64_epi64(rearm0,
     710                 :            :                         (1 << 6) + (0 << 4) + (3 << 2) + 2);
     711                 :            :                 rearm2 = _mm256_permute4x64_epi64(rearm2,
     712                 :            :                         (1 << 6) + (0 << 4) + (3 << 2) + 2);
     713                 :            :                 /* Second set of 4 descriptors */
     714                 :            :                 __m256i rearm4 = _mm256_blend_epi32(rearm45,
     715                 :            :                         mbuf_init4_5, 0xf0);
     716                 :            :                 __m256i rearm5 = _mm256_blend_epi32(mbuf_init4_5,
     717                 :            :                         rearm45, 0xf0);
     718                 :            :                 __m256i rearm6 = _mm256_blend_epi32(rearm67,
     719                 :            :                         mbuf_init6_7, 0xf0);
     720                 :            :                 __m256i rearm7 = _mm256_blend_epi32(mbuf_init6_7,
     721                 :            :                         rearm67, 0xf0);
     722                 :            :                 rearm4 = _mm256_permute4x64_epi64(rearm4,
     723                 :            :                         (1 << 6) + (0 << 4) + (3 << 2) + 2);
     724                 :            :                 rearm6 = _mm256_permute4x64_epi64(rearm6,
     725                 :            :                         (1 << 6) + (0 << 4) + (3 << 2) + 2);
     726                 :            : 
     727                 :            :                 /*
     728                 :            :                  * Write out 32B of mbuf fields.
     729                 :            :                  * data_off    - off 0  (mbuf_init)
     730                 :            :                  * refcnt      - 2      (mbuf_init)
     731                 :            :                  * nb_segs     - 4      (mbuf_init)
     732                 :            :                  * port        - 6      (mbuf_init)
     733                 :            :                  * ol_flag     - 8      (from cqd)
     734                 :            :                  * packet_type - 16     (from cqd)
     735                 :            :                  * pkt_len     - 20     (from cqd)
     736                 :            :                  * data_len    - 24     (from cqd)
     737                 :            :                  * vlan_tci    - 26     (from cqd)
     738                 :            :                  * rss         - 28     (from cqd)
     739                 :            :                  */
     740                 :          0 :                 _mm256_storeu_si256((__m256i *)&rxmb[0]->rearm_data, rearm0);
     741                 :          0 :                 _mm256_storeu_si256((__m256i *)&rxmb[1]->rearm_data, rearm1);
     742                 :          0 :                 _mm256_storeu_si256((__m256i *)&rxmb[2]->rearm_data, rearm2);
     743                 :          0 :                 _mm256_storeu_si256((__m256i *)&rxmb[3]->rearm_data, rearm3);
     744                 :          0 :                 _mm256_storeu_si256((__m256i *)&rxmb[4]->rearm_data, rearm4);
     745                 :          0 :                 _mm256_storeu_si256((__m256i *)&rxmb[5]->rearm_data, rearm5);
     746                 :          0 :                 _mm256_storeu_si256((__m256i *)&rxmb[6]->rearm_data, rearm6);
     747                 :          0 :                 _mm256_storeu_si256((__m256i *)&rxmb[7]->rearm_data, rearm7);
     748                 :            : 
     749                 :          0 :                 max_rx -= 8;
     750                 :          0 :                 cqd += 8;
     751                 :          0 :                 rx += 8;
     752                 :          0 :                 rxmb += 8;
     753                 :            :         }
     754                 :            : 
     755                 :            :         /*
     756                 :            :          * Step 3: Slow path to handle a small (<8) number of packets and
     757                 :            :          * occasional truncated packets.
     758                 :            :          */
     759   [ #  #  #  # ]:          0 :         while (max_rx && ((cqd->type_color &
     760                 :            :                            CQ_DESC_COLOR_MASK_NOSHIFT) != color)) {
     761         [ #  # ]:          0 :                 if (unlikely(cqd->bytes_written_flags &
     762                 :            :                              CQ_ENET_RQ_DESC_FLAGS_TRUNCATED)) {
     763                 :          0 :                         rte_pktmbuf_free(*rxmb++);
     764                 :          0 :                         rte_atomic64_inc(&enic->soft_stats.rx_packet_errors);
     765                 :            :                 } else {
     766                 :          0 :                         *rx++ = rx_one(cqd, *rxmb++, enic);
     767                 :            :                 }
     768                 :          0 :                 cqd++;
     769                 :          0 :                 max_rx--;
     770                 :            :         }
     771                 :            : 
     772                 :            :         /* Number of descriptors visited */
     773                 :          0 :         nb_rx = cqd - (struct cq_enet_rq_desc *)(cq->ring.descs) - cq_idx;
     774         [ #  # ]:          0 :         if (nb_rx == 0)
     775                 :            :                 return 0;
     776                 :          0 :         rqd = ((struct rq_enet_desc *)rq->ring.descs) + cq_idx;
     777                 :          0 :         rxmb = rq->mbuf_ring + cq_idx;
     778                 :            :         cq_idx += nb_rx;
     779                 :          0 :         rq->rx_nb_hold += nb_rx;
     780         [ #  # ]:          0 :         if (unlikely(cq_idx == cq->ring.desc_count)) {
     781                 :            :                 cq_idx = 0;
     782                 :          0 :                 cq->last_color ^= CQ_DESC_COLOR_MASK_NOSHIFT;
     783                 :            :         }
     784                 :          0 :         cq->to_clean = cq_idx;
     785                 :            : 
     786                 :            :         /* Step 4: Restock RQ with new mbufs */
     787                 :          0 :         memcpy(rxmb, rq->free_mbufs + ENIC_RX_BURST_MAX - rq->num_free_mbufs,
     788                 :            :                sizeof(struct rte_mbuf *) * nb_rx);
     789                 :          0 :         rq->num_free_mbufs -= nb_rx;
     790         [ #  # ]:          0 :         while (nb_rx) {
     791                 :          0 :                 rqd->address = (*rxmb)->buf_iova + RTE_PKTMBUF_HEADROOM;
     792                 :          0 :                 nb_rx--;
     793                 :          0 :                 rqd++;
     794                 :          0 :                 rxmb++;
     795                 :            :         }
     796         [ #  # ]:          0 :         if (rq->rx_nb_hold > rq->rx_free_thresh) {
     797         [ #  # ]:          0 :                 rq->posted_index = enic_ring_add(rq->ring.desc_count,
     798                 :            :                                                  rq->posted_index,
     799                 :            :                                                  rq->rx_nb_hold);
     800                 :          0 :                 rq->rx_nb_hold = 0;
     801                 :            :                 rte_wmb();
     802                 :          0 :                 iowrite32_relaxed(rq->posted_index,
     803                 :          0 :                                   &rq->ctrl->posted_index);
     804                 :            :         }
     805                 :            : 
     806                 :          0 :         return rx - rx_pkts;
     807                 :            : }
     808                 :            : 
     809                 :            : bool
     810         [ #  # ]:          0 : enic_use_vector_rx_handler(struct rte_eth_dev *eth_dev)
     811                 :            : {
     812                 :            :         struct enic *enic = pmd_priv(eth_dev);
     813                 :            : 
     814                 :            :         /* User needs to request for the avx2 handler */
     815         [ #  # ]:          0 :         if (!enic->enable_avx2_rx)
     816                 :            :                 return false;
     817                 :            :         /* Do not support scatter Rx */
     818   [ #  #  #  # ]:          0 :         if (!(enic->rq_count > 0 && enic->rq[0].data_queue_enable == 0))
     819                 :            :                 return false;
     820   [ #  #  #  # ]:          0 :         if (rte_cpu_get_flag_enabled(RTE_CPUFLAG_AVX2) &&
     821                 :          0 :                         rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_256) {
     822                 :          0 :                 ENICPMD_LOG(DEBUG, " use the non-scatter avx2 Rx handler");
     823                 :          0 :                 eth_dev->rx_pkt_burst = &enic_noscatter_vec_recv_pkts;
     824                 :          0 :                 enic->use_noscatter_vec_rx_handler = 1;
     825                 :          0 :                 return true;
     826                 :            :         }
     827                 :            :         return false;
     828                 :            : }

Generated by: LCOV version 1.14