1f0d2114fSYongseok Koh /*- 2f0d2114fSYongseok Koh * BSD LICENSE 3f0d2114fSYongseok Koh * 4f0d2114fSYongseok Koh * Copyright 2017 6WIND S.A. 5f0d2114fSYongseok Koh * Copyright 2017 Mellanox. 6f0d2114fSYongseok Koh * 7f0d2114fSYongseok Koh * Redistribution and use in source and binary forms, with or without 8f0d2114fSYongseok Koh * modification, are permitted provided that the following conditions 9f0d2114fSYongseok Koh * are met: 10f0d2114fSYongseok Koh * 11f0d2114fSYongseok Koh * * Redistributions of source code must retain the above copyright 12f0d2114fSYongseok Koh * notice, this list of conditions and the following disclaimer. 13f0d2114fSYongseok Koh * * Redistributions in binary form must reproduce the above copyright 14f0d2114fSYongseok Koh * notice, this list of conditions and the following disclaimer in 15f0d2114fSYongseok Koh * the documentation and/or other materials provided with the 16f0d2114fSYongseok Koh * distribution. 17f0d2114fSYongseok Koh * * Neither the name of 6WIND S.A. nor the names of its 18f0d2114fSYongseok Koh * contributors may be used to endorse or promote products derived 19f0d2114fSYongseok Koh * from this software without specific prior written permission. 20f0d2114fSYongseok Koh * 21f0d2114fSYongseok Koh * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22f0d2114fSYongseok Koh * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23f0d2114fSYongseok Koh * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24f0d2114fSYongseok Koh * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25f0d2114fSYongseok Koh * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26f0d2114fSYongseok Koh * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27f0d2114fSYongseok Koh * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28f0d2114fSYongseok Koh * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29f0d2114fSYongseok Koh * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30f0d2114fSYongseok Koh * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31f0d2114fSYongseok Koh * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32f0d2114fSYongseok Koh */ 33f0d2114fSYongseok Koh 34f0d2114fSYongseok Koh #include <assert.h> 35f0d2114fSYongseok Koh #include <stdint.h> 36f0d2114fSYongseok Koh #include <string.h> 37f0d2114fSYongseok Koh #include <stdlib.h> 38f0d2114fSYongseok Koh 39f0d2114fSYongseok Koh /* Verbs header. */ 40f0d2114fSYongseok Koh /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */ 41f0d2114fSYongseok Koh #ifdef PEDANTIC 42f0d2114fSYongseok Koh #pragma GCC diagnostic ignored "-Wpedantic" 43f0d2114fSYongseok Koh #endif 44f0d2114fSYongseok Koh #include <infiniband/verbs.h> 45f0d2114fSYongseok Koh #include <infiniband/mlx5dv.h> 46f0d2114fSYongseok Koh #ifdef PEDANTIC 47f0d2114fSYongseok Koh #pragma GCC diagnostic error "-Wpedantic" 48f0d2114fSYongseok Koh #endif 49f0d2114fSYongseok Koh 50f0d2114fSYongseok Koh #include <rte_mbuf.h> 51f0d2114fSYongseok Koh #include <rte_mempool.h> 52f0d2114fSYongseok Koh #include <rte_prefetch.h> 53f0d2114fSYongseok Koh 54f0d2114fSYongseok Koh #include "mlx5.h" 55f0d2114fSYongseok Koh #include "mlx5_utils.h" 56f0d2114fSYongseok Koh #include "mlx5_rxtx.h" 575bfc9fc1SYongseok Koh #include "mlx5_rxtx_vec.h" 58f0d2114fSYongseok Koh #include "mlx5_autoconf.h" 59f0d2114fSYongseok Koh #include "mlx5_defs.h" 60f0d2114fSYongseok Koh #include "mlx5_prm.h" 61f0d2114fSYongseok Koh 62*3c2ddbd4SYongseok Koh #ifdef RTE_ARCH_X86_64 63*3c2ddbd4SYongseok Koh #include "mlx5_rxtx_vec_sse.h" 64*3c2ddbd4SYongseok Koh #else 65*3c2ddbd4SYongseok Koh #error "This should not be compiled if SIMD instructions are not supported." 66f0d2114fSYongseok Koh #endif 67f0d2114fSYongseok Koh 68f0d2114fSYongseok Koh /** 69f0d2114fSYongseok Koh * Count the number of continuous single segment packets. 70f0d2114fSYongseok Koh * 71f0d2114fSYongseok Koh * @param pkts 72f0d2114fSYongseok Koh * Pointer to array of packets. 73f0d2114fSYongseok Koh * @param pkts_n 74f0d2114fSYongseok Koh * Number of packets. 75f0d2114fSYongseok Koh * 76f0d2114fSYongseok Koh * @return 77f0d2114fSYongseok Koh * Number of continuous single segment packets. 78f0d2114fSYongseok Koh */ 79f0d2114fSYongseok Koh static inline unsigned int 80f0d2114fSYongseok Koh txq_check_multiseg(struct rte_mbuf **pkts, uint16_t pkts_n) 81f0d2114fSYongseok Koh { 82f0d2114fSYongseok Koh unsigned int pos; 83f0d2114fSYongseok Koh 84f0d2114fSYongseok Koh if (!pkts_n) 85f0d2114fSYongseok Koh return 0; 86f0d2114fSYongseok Koh /* Count the number of continuous single segment packets. */ 87f0d2114fSYongseok Koh for (pos = 0; pos < pkts_n; ++pos) 88f0d2114fSYongseok Koh if (NB_SEGS(pkts[pos]) > 1) 89f0d2114fSYongseok Koh break; 90f0d2114fSYongseok Koh return pos; 91f0d2114fSYongseok Koh } 92f0d2114fSYongseok Koh 93f0d2114fSYongseok Koh /** 94f0d2114fSYongseok Koh * Count the number of packets having same ol_flags and calculate cs_flags. 95f0d2114fSYongseok Koh * 96f0d2114fSYongseok Koh * @param txq 97f0d2114fSYongseok Koh * Pointer to TX queue structure. 98f0d2114fSYongseok Koh * @param pkts 99f0d2114fSYongseok Koh * Pointer to array of packets. 100f0d2114fSYongseok Koh * @param pkts_n 101f0d2114fSYongseok Koh * Number of packets. 102f0d2114fSYongseok Koh * @param cs_flags 103f0d2114fSYongseok Koh * Pointer of flags to be returned. 104f0d2114fSYongseok Koh * 105f0d2114fSYongseok Koh * @return 106f0d2114fSYongseok Koh * Number of packets having same ol_flags. 107f0d2114fSYongseok Koh */ 108f0d2114fSYongseok Koh static inline unsigned int 109f0d2114fSYongseok Koh txq_calc_offload(struct mlx5_txq_data *txq, struct rte_mbuf **pkts, 110f0d2114fSYongseok Koh uint16_t pkts_n, uint8_t *cs_flags) 111f0d2114fSYongseok Koh { 112f0d2114fSYongseok Koh unsigned int pos; 113f0d2114fSYongseok Koh const uint64_t ol_mask = 114f0d2114fSYongseok Koh PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | 115f0d2114fSYongseok Koh PKT_TX_UDP_CKSUM | PKT_TX_TUNNEL_GRE | 116f0d2114fSYongseok Koh PKT_TX_TUNNEL_VXLAN | PKT_TX_OUTER_IP_CKSUM; 117f0d2114fSYongseok Koh 118f0d2114fSYongseok Koh if (!pkts_n) 119f0d2114fSYongseok Koh return 0; 120f0d2114fSYongseok Koh /* Count the number of packets having same ol_flags. */ 121f0d2114fSYongseok Koh for (pos = 1; pos < pkts_n; ++pos) 122f0d2114fSYongseok Koh if ((pkts[pos]->ol_flags ^ pkts[0]->ol_flags) & ol_mask) 123f0d2114fSYongseok Koh break; 124f0d2114fSYongseok Koh /* Should open another MPW session for the rest. */ 125f0d2114fSYongseok Koh if (pkts[0]->ol_flags & 126f0d2114fSYongseok Koh (PKT_TX_IP_CKSUM | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)) { 127f0d2114fSYongseok Koh const uint64_t is_tunneled = 128f0d2114fSYongseok Koh pkts[0]->ol_flags & 129f0d2114fSYongseok Koh (PKT_TX_TUNNEL_GRE | 130f0d2114fSYongseok Koh PKT_TX_TUNNEL_VXLAN); 131f0d2114fSYongseok Koh 132f0d2114fSYongseok Koh if (is_tunneled && txq->tunnel_en) { 133f0d2114fSYongseok Koh *cs_flags = MLX5_ETH_WQE_L3_INNER_CSUM | 134f0d2114fSYongseok Koh MLX5_ETH_WQE_L4_INNER_CSUM; 135f0d2114fSYongseok Koh if (pkts[0]->ol_flags & PKT_TX_OUTER_IP_CKSUM) 136f0d2114fSYongseok Koh *cs_flags |= MLX5_ETH_WQE_L3_CSUM; 137f0d2114fSYongseok Koh } else { 138f0d2114fSYongseok Koh *cs_flags = MLX5_ETH_WQE_L3_CSUM | 139f0d2114fSYongseok Koh MLX5_ETH_WQE_L4_CSUM; 140f0d2114fSYongseok Koh } 141f0d2114fSYongseok Koh } 142f0d2114fSYongseok Koh return pos; 143f0d2114fSYongseok Koh } 144f0d2114fSYongseok Koh 145f0d2114fSYongseok Koh /** 146f0d2114fSYongseok Koh * DPDK callback for vectorized TX. 147f0d2114fSYongseok Koh * 148f0d2114fSYongseok Koh * @param dpdk_txq 149f0d2114fSYongseok Koh * Generic pointer to TX queue structure. 150f0d2114fSYongseok Koh * @param[in] pkts 151f0d2114fSYongseok Koh * Packets to transmit. 152f0d2114fSYongseok Koh * @param pkts_n 153f0d2114fSYongseok Koh * Number of packets in array. 154f0d2114fSYongseok Koh * 155f0d2114fSYongseok Koh * @return 156f0d2114fSYongseok Koh * Number of packets successfully transmitted (<= pkts_n). 157f0d2114fSYongseok Koh */ 158f0d2114fSYongseok Koh uint16_t 159f0d2114fSYongseok Koh mlx5_tx_burst_raw_vec(void *dpdk_txq, struct rte_mbuf **pkts, 160f0d2114fSYongseok Koh uint16_t pkts_n) 161f0d2114fSYongseok Koh { 162f0d2114fSYongseok Koh struct mlx5_txq_data *txq = (struct mlx5_txq_data *)dpdk_txq; 163f0d2114fSYongseok Koh uint16_t nb_tx = 0; 164f0d2114fSYongseok Koh 165f0d2114fSYongseok Koh while (pkts_n > nb_tx) { 166f0d2114fSYongseok Koh uint16_t n; 167f0d2114fSYongseok Koh uint16_t ret; 168f0d2114fSYongseok Koh 169f0d2114fSYongseok Koh n = RTE_MIN((uint16_t)(pkts_n - nb_tx), MLX5_VPMD_TX_MAX_BURST); 170f0d2114fSYongseok Koh ret = txq_burst_v(txq, &pkts[nb_tx], n, 0); 171f0d2114fSYongseok Koh nb_tx += ret; 172f0d2114fSYongseok Koh if (!ret) 173f0d2114fSYongseok Koh break; 174f0d2114fSYongseok Koh } 175f0d2114fSYongseok Koh return nb_tx; 176f0d2114fSYongseok Koh } 177f0d2114fSYongseok Koh 178f0d2114fSYongseok Koh /** 179f0d2114fSYongseok Koh * DPDK callback for vectorized TX with multi-seg packets and offload. 180f0d2114fSYongseok Koh * 181f0d2114fSYongseok Koh * @param dpdk_txq 182f0d2114fSYongseok Koh * Generic pointer to TX queue structure. 183f0d2114fSYongseok Koh * @param[in] pkts 184f0d2114fSYongseok Koh * Packets to transmit. 185f0d2114fSYongseok Koh * @param pkts_n 186f0d2114fSYongseok Koh * Number of packets in array. 187f0d2114fSYongseok Koh * 188f0d2114fSYongseok Koh * @return 189f0d2114fSYongseok Koh * Number of packets successfully transmitted (<= pkts_n). 190f0d2114fSYongseok Koh */ 191f0d2114fSYongseok Koh uint16_t 192f0d2114fSYongseok Koh mlx5_tx_burst_vec(void *dpdk_txq, struct rte_mbuf **pkts, uint16_t pkts_n) 193f0d2114fSYongseok Koh { 194f0d2114fSYongseok Koh struct mlx5_txq_data *txq = (struct mlx5_txq_data *)dpdk_txq; 195f0d2114fSYongseok Koh uint16_t nb_tx = 0; 196f0d2114fSYongseok Koh 197f0d2114fSYongseok Koh while (pkts_n > nb_tx) { 198f0d2114fSYongseok Koh uint8_t cs_flags = 0; 199f0d2114fSYongseok Koh uint16_t n; 200f0d2114fSYongseok Koh uint16_t ret; 201f0d2114fSYongseok Koh 202f0d2114fSYongseok Koh /* Transmit multi-seg packets in the head of pkts list. */ 203f0d2114fSYongseok Koh if (!(txq->flags & ETH_TXQ_FLAGS_NOMULTSEGS) && 204f0d2114fSYongseok Koh NB_SEGS(pkts[nb_tx]) > 1) 205f0d2114fSYongseok Koh nb_tx += txq_scatter_v(txq, 206f0d2114fSYongseok Koh &pkts[nb_tx], 207f0d2114fSYongseok Koh pkts_n - nb_tx); 208f0d2114fSYongseok Koh n = RTE_MIN((uint16_t)(pkts_n - nb_tx), MLX5_VPMD_TX_MAX_BURST); 209f0d2114fSYongseok Koh if (!(txq->flags & ETH_TXQ_FLAGS_NOMULTSEGS)) 210f0d2114fSYongseok Koh n = txq_check_multiseg(&pkts[nb_tx], n); 211f0d2114fSYongseok Koh if (!(txq->flags & ETH_TXQ_FLAGS_NOOFFLOADS)) 212f0d2114fSYongseok Koh n = txq_calc_offload(txq, &pkts[nb_tx], n, &cs_flags); 213f0d2114fSYongseok Koh ret = txq_burst_v(txq, &pkts[nb_tx], n, cs_flags); 214f0d2114fSYongseok Koh nb_tx += ret; 215f0d2114fSYongseok Koh if (!ret) 216f0d2114fSYongseok Koh break; 217f0d2114fSYongseok Koh } 218f0d2114fSYongseok Koh return nb_tx; 219f0d2114fSYongseok Koh } 220f0d2114fSYongseok Koh 221f0d2114fSYongseok Koh /** 222f0d2114fSYongseok Koh * Skip error packets. 223f0d2114fSYongseok Koh * 224f0d2114fSYongseok Koh * @param rxq 225f0d2114fSYongseok Koh * Pointer to RX queue structure. 226f0d2114fSYongseok Koh * @param[out] pkts 227f0d2114fSYongseok Koh * Array to store received packets. 228f0d2114fSYongseok Koh * @param pkts_n 229f0d2114fSYongseok Koh * Maximum number of packets in array. 230f0d2114fSYongseok Koh * 231f0d2114fSYongseok Koh * @return 232f0d2114fSYongseok Koh * Number of packets successfully received (<= pkts_n). 233f0d2114fSYongseok Koh */ 234f0d2114fSYongseok Koh static uint16_t 235f0d2114fSYongseok Koh rxq_handle_pending_error(struct mlx5_rxq_data *rxq, struct rte_mbuf **pkts, 236f0d2114fSYongseok Koh uint16_t pkts_n) 237f0d2114fSYongseok Koh { 238f0d2114fSYongseok Koh uint16_t n = 0; 239f0d2114fSYongseok Koh unsigned int i; 240f0d2114fSYongseok Koh #ifdef MLX5_PMD_SOFT_COUNTERS 241f0d2114fSYongseok Koh uint32_t err_bytes = 0; 242f0d2114fSYongseok Koh #endif 243f0d2114fSYongseok Koh 244f0d2114fSYongseok Koh for (i = 0; i < pkts_n; ++i) { 245f0d2114fSYongseok Koh struct rte_mbuf *pkt = pkts[i]; 246f0d2114fSYongseok Koh 247f0d2114fSYongseok Koh if (pkt->packet_type == RTE_PTYPE_ALL_MASK) { 248f0d2114fSYongseok Koh #ifdef MLX5_PMD_SOFT_COUNTERS 249f0d2114fSYongseok Koh err_bytes += PKT_LEN(pkt); 250f0d2114fSYongseok Koh #endif 251f0d2114fSYongseok Koh rte_pktmbuf_free_seg(pkt); 252f0d2114fSYongseok Koh } else { 253f0d2114fSYongseok Koh pkts[n++] = pkt; 254f0d2114fSYongseok Koh } 255f0d2114fSYongseok Koh } 256f0d2114fSYongseok Koh rxq->stats.idropped += (pkts_n - n); 257f0d2114fSYongseok Koh #ifdef MLX5_PMD_SOFT_COUNTERS 258f0d2114fSYongseok Koh /* Correct counters of errored completions. */ 259f0d2114fSYongseok Koh rxq->stats.ipackets -= (pkts_n - n); 260f0d2114fSYongseok Koh rxq->stats.ibytes -= err_bytes; 261f0d2114fSYongseok Koh #endif 262f0d2114fSYongseok Koh rxq->pending_err = 0; 263f0d2114fSYongseok Koh return n; 264f0d2114fSYongseok Koh } 265f0d2114fSYongseok Koh 266f0d2114fSYongseok Koh /** 267f0d2114fSYongseok Koh * DPDK callback for vectorized RX. 268f0d2114fSYongseok Koh * 269f0d2114fSYongseok Koh * @param dpdk_rxq 270f0d2114fSYongseok Koh * Generic pointer to RX queue structure. 271f0d2114fSYongseok Koh * @param[out] pkts 272f0d2114fSYongseok Koh * Array to store received packets. 273f0d2114fSYongseok Koh * @param pkts_n 274f0d2114fSYongseok Koh * Maximum number of packets in array. 275f0d2114fSYongseok Koh * 276f0d2114fSYongseok Koh * @return 277f0d2114fSYongseok Koh * Number of packets successfully received (<= pkts_n). 278f0d2114fSYongseok Koh */ 279f0d2114fSYongseok Koh uint16_t 280f0d2114fSYongseok Koh mlx5_rx_burst_vec(void *dpdk_rxq, struct rte_mbuf **pkts, uint16_t pkts_n) 281f0d2114fSYongseok Koh { 282f0d2114fSYongseok Koh struct mlx5_rxq_data *rxq = dpdk_rxq; 283f0d2114fSYongseok Koh uint16_t nb_rx; 284f0d2114fSYongseok Koh 285f0d2114fSYongseok Koh nb_rx = rxq_burst_v(rxq, pkts, pkts_n); 286f0d2114fSYongseok Koh if (unlikely(rxq->pending_err)) 287f0d2114fSYongseok Koh nb_rx = rxq_handle_pending_error(rxq, pkts, nb_rx); 288f0d2114fSYongseok Koh return nb_rx; 289f0d2114fSYongseok Koh } 290f0d2114fSYongseok Koh 291f0d2114fSYongseok Koh /** 292f0d2114fSYongseok Koh * Check Tx queue flags are set for raw vectorized Tx. 293f0d2114fSYongseok Koh * 294f0d2114fSYongseok Koh * @param priv 295f0d2114fSYongseok Koh * Pointer to private structure. 296f0d2114fSYongseok Koh * 297f0d2114fSYongseok Koh * @return 298f0d2114fSYongseok Koh * 1 if supported, negative errno value if not. 299f0d2114fSYongseok Koh */ 300f0d2114fSYongseok Koh int __attribute__((cold)) 301f0d2114fSYongseok Koh priv_check_raw_vec_tx_support(struct priv *priv) 302f0d2114fSYongseok Koh { 303f0d2114fSYongseok Koh uint16_t i; 304f0d2114fSYongseok Koh 305f0d2114fSYongseok Koh /* All the configured queues should support. */ 306f0d2114fSYongseok Koh for (i = 0; i < priv->txqs_n; ++i) { 307f0d2114fSYongseok Koh struct mlx5_txq_data *txq = (*priv->txqs)[i]; 308f0d2114fSYongseok Koh 309f0d2114fSYongseok Koh if (!(txq->flags & ETH_TXQ_FLAGS_NOMULTSEGS) || 310f0d2114fSYongseok Koh !(txq->flags & ETH_TXQ_FLAGS_NOOFFLOADS)) 311f0d2114fSYongseok Koh break; 312f0d2114fSYongseok Koh } 313f0d2114fSYongseok Koh if (i != priv->txqs_n) 314f0d2114fSYongseok Koh return -ENOTSUP; 315f0d2114fSYongseok Koh return 1; 316f0d2114fSYongseok Koh } 317f0d2114fSYongseok Koh 318f0d2114fSYongseok Koh /** 319f0d2114fSYongseok Koh * Check a device can support vectorized TX. 320f0d2114fSYongseok Koh * 321f0d2114fSYongseok Koh * @param priv 322f0d2114fSYongseok Koh * Pointer to private structure. 323f0d2114fSYongseok Koh * 324f0d2114fSYongseok Koh * @return 325f0d2114fSYongseok Koh * 1 if supported, negative errno value if not. 326f0d2114fSYongseok Koh */ 327f0d2114fSYongseok Koh int __attribute__((cold)) 328f0d2114fSYongseok Koh priv_check_vec_tx_support(struct priv *priv) 329f0d2114fSYongseok Koh { 330f0d2114fSYongseok Koh if (!priv->tx_vec_en || 331f0d2114fSYongseok Koh priv->txqs_n > MLX5_VPMD_MIN_TXQS || 332f0d2114fSYongseok Koh priv->mps != MLX5_MPW_ENHANCED || 333f0d2114fSYongseok Koh priv->tso) 334f0d2114fSYongseok Koh return -ENOTSUP; 335f0d2114fSYongseok Koh return 1; 336f0d2114fSYongseok Koh } 337f0d2114fSYongseok Koh 338f0d2114fSYongseok Koh /** 339f0d2114fSYongseok Koh * Check a RX queue can support vectorized RX. 340f0d2114fSYongseok Koh * 341f0d2114fSYongseok Koh * @param rxq 342f0d2114fSYongseok Koh * Pointer to RX queue. 343f0d2114fSYongseok Koh * 344f0d2114fSYongseok Koh * @return 345f0d2114fSYongseok Koh * 1 if supported, negative errno value if not. 346f0d2114fSYongseok Koh */ 347f0d2114fSYongseok Koh int __attribute__((cold)) 348f0d2114fSYongseok Koh rxq_check_vec_support(struct mlx5_rxq_data *rxq) 349f0d2114fSYongseok Koh { 350f0d2114fSYongseok Koh struct mlx5_rxq_ctrl *ctrl = 351f0d2114fSYongseok Koh container_of(rxq, struct mlx5_rxq_ctrl, rxq); 352f0d2114fSYongseok Koh 353f0d2114fSYongseok Koh if (!ctrl->priv->rx_vec_en || rxq->sges_n != 0) 354f0d2114fSYongseok Koh return -ENOTSUP; 355f0d2114fSYongseok Koh return 1; 356f0d2114fSYongseok Koh } 357f0d2114fSYongseok Koh 358f0d2114fSYongseok Koh /** 359f0d2114fSYongseok Koh * Check a device can support vectorized RX. 360f0d2114fSYongseok Koh * 361f0d2114fSYongseok Koh * @param priv 362f0d2114fSYongseok Koh * Pointer to private structure. 363f0d2114fSYongseok Koh * 364f0d2114fSYongseok Koh * @return 365f0d2114fSYongseok Koh * 1 if supported, negative errno value if not. 366f0d2114fSYongseok Koh */ 367f0d2114fSYongseok Koh int __attribute__((cold)) 368f0d2114fSYongseok Koh priv_check_vec_rx_support(struct priv *priv) 369f0d2114fSYongseok Koh { 370f0d2114fSYongseok Koh uint16_t i; 371f0d2114fSYongseok Koh 372f0d2114fSYongseok Koh if (!priv->rx_vec_en) 373f0d2114fSYongseok Koh return -ENOTSUP; 374f0d2114fSYongseok Koh /* All the configured queues should support. */ 375f0d2114fSYongseok Koh for (i = 0; i < priv->rxqs_n; ++i) { 376f0d2114fSYongseok Koh struct mlx5_rxq_data *rxq = (*priv->rxqs)[i]; 377f0d2114fSYongseok Koh 378f0d2114fSYongseok Koh if (!rxq) 379f0d2114fSYongseok Koh continue; 380f0d2114fSYongseok Koh if (rxq_check_vec_support(rxq) < 0) 381f0d2114fSYongseok Koh break; 382f0d2114fSYongseok Koh } 383f0d2114fSYongseok Koh if (i != priv->rxqs_n) 384f0d2114fSYongseok Koh return -ENOTSUP; 385f0d2114fSYongseok Koh return 1; 386f0d2114fSYongseok Koh } 387