1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2017 6WIND S.A. 3 * Copyright 2017 Mellanox Technologies, Ltd 4 */ 5 6 #ifndef MLX4_RXTX_H_ 7 #define MLX4_RXTX_H_ 8 9 #include <stdint.h> 10 #include <sys/queue.h> 11 12 /* Verbs headers do not support -pedantic. */ 13 #ifdef PEDANTIC 14 #pragma GCC diagnostic ignored "-Wpedantic" 15 #endif 16 #include <infiniband/mlx4dv.h> 17 #include <infiniband/verbs.h> 18 #ifdef PEDANTIC 19 #pragma GCC diagnostic error "-Wpedantic" 20 #endif 21 22 #include <ethdev_driver.h> 23 #include <rte_mbuf.h> 24 #include <rte_mempool.h> 25 26 #include "mlx4.h" 27 #include "mlx4_prm.h" 28 #include "mlx4_mr.h" 29 30 /** Rx queue counters. */ 31 struct mlx4_rxq_stats { 32 unsigned int idx; /**< Mapping index. */ 33 uint64_t ipackets; /**< Total of successfully received packets. */ 34 uint64_t ibytes; /**< Total of successfully received bytes. */ 35 uint64_t idropped; /**< Total of packets dropped when Rx ring full. */ 36 uint64_t rx_nombuf; /**< Total of Rx mbuf allocation failures. */ 37 }; 38 39 /** Rx queue descriptor. */ 40 struct rxq { 41 struct mlx4_priv *priv; /**< Back pointer to private data. */ 42 struct rte_mempool *mp; /**< Memory pool for allocations. */ 43 struct ibv_cq *cq; /**< Completion queue. */ 44 struct ibv_wq *wq; /**< Work queue. */ 45 struct ibv_comp_channel *channel; /**< Rx completion channel. */ 46 uint16_t rq_ci; /**< Saved RQ consumer index. */ 47 uint16_t port_id; /**< Port ID for incoming packets. */ 48 uint16_t sges_n; /**< Number of segments per packet (log2 value). */ 49 uint16_t elts_n; /**< Mbuf queue size (log2 value). */ 50 struct mlx4_mr_ctrl mr_ctrl; /* MR control descriptor. */ 51 struct rte_mbuf *(*elts)[]; /**< Rx elements. */ 52 volatile struct mlx4_wqe_data_seg (*wqes)[]; /**< HW queue entries. */ 53 volatile uint32_t *rq_db; /**< RQ doorbell record. */ 54 uint32_t csum:1; /**< Enable checksum offloading. */ 55 uint32_t csum_l2tun:1; /**< Same for L2 tunnels. */ 56 uint32_t crc_present:1; /**< CRC must be subtracted. */ 57 uint32_t l2tun_offload:1; /**< L2 tunnel offload is enabled. */ 58 struct mlx4_cq mcq; /**< Info for directly manipulating the CQ. */ 59 struct mlx4_rxq_stats stats; /**< Rx queue counters. */ 60 unsigned int socket; /**< CPU socket ID for allocations. */ 61 uint32_t usecnt; /**< Number of users relying on queue resources. */ 62 uint8_t data[]; /**< Remaining queue resources. */ 63 }; 64 65 /** Shared flow target for Rx queues. */ 66 struct mlx4_rss { 67 LIST_ENTRY(mlx4_rss) next; /**< Next entry in list. */ 68 struct mlx4_priv *priv; /**< Back pointer to private data. */ 69 uint32_t refcnt; /**< Reference count for this object. */ 70 uint32_t usecnt; /**< Number of users relying on @p qp and @p ind. */ 71 struct ibv_qp *qp; /**< Queue pair. */ 72 struct ibv_rwq_ind_table *ind; /**< Indirection table. */ 73 uint64_t fields; /**< Fields for RSS processing (Verbs format). */ 74 uint8_t key[MLX4_RSS_HASH_KEY_SIZE]; /**< Hash key to use. */ 75 uint16_t queues; /**< Number of target queues. */ 76 uint16_t queue_id[]; /**< Target queues. */ 77 }; 78 79 /** Tx element. */ 80 struct txq_elt { 81 struct rte_mbuf *buf; /**< Buffer. */ 82 union { 83 volatile struct mlx4_wqe_ctrl_seg *wqe; /**< SQ WQE. */ 84 volatile uint32_t *eocb; /**< End of completion burst. */ 85 }; 86 }; 87 88 /** Tx queue counters. */ 89 struct mlx4_txq_stats { 90 unsigned int idx; /**< Mapping index. */ 91 uint64_t opackets; /**< Total of successfully sent packets. */ 92 uint64_t obytes; /**< Total of successfully sent bytes. */ 93 uint64_t odropped; /**< Total number of packets failed to transmit. */ 94 }; 95 96 /** Tx queue descriptor. */ 97 struct txq { 98 struct mlx4_sq msq; /**< Info for directly manipulating the SQ. */ 99 struct mlx4_cq mcq; /**< Info for directly manipulating the CQ. */ 100 uint16_t port_id; /**< Port ID of device. */ 101 unsigned int elts_head; /**< Current index in (*elts)[]. */ 102 unsigned int elts_tail; /**< First element awaiting completion. */ 103 int elts_comp_cd; /**< Countdown for next completion. */ 104 unsigned int elts_comp_cd_init; /**< Initial value for countdown. */ 105 unsigned int elts_n; /**< (*elts)[] length. */ 106 struct mlx4_mr_ctrl mr_ctrl; /* MR control descriptor. */ 107 struct txq_elt (*elts)[]; /**< Tx elements. */ 108 struct mlx4_txq_stats stats; /**< Tx queue counters. */ 109 uint32_t max_inline; /**< Max inline send size. */ 110 uint32_t csum:1; /**< Enable checksum offloading. */ 111 uint32_t csum_l2tun:1; /**< Same for L2 tunnels. */ 112 uint32_t lb:1; /**< Whether packets should be looped back by eSwitch. */ 113 uint8_t *bounce_buf; 114 /**< Memory used for storing the first DWORD of data TXBBs. */ 115 struct mlx4_priv *priv; /**< Back pointer to private data. */ 116 unsigned int socket; /**< CPU socket ID for allocations. */ 117 struct ibv_cq *cq; /**< Completion queue. */ 118 struct ibv_qp *qp; /**< Queue pair. */ 119 uint8_t data[]; /**< Remaining queue resources. */ 120 }; 121 122 #define MLX4_TX_BFREG(txq) \ 123 (MLX4_PROC_PRIV((txq)->port_id)->uar_table[(txq)->stats.idx]) 124 125 /* mlx4_rxq.c */ 126 127 extern uint8_t mlx4_rss_hash_key_default[MLX4_RSS_HASH_KEY_SIZE]; 128 int mlx4_rss_init(struct mlx4_priv *priv); 129 void mlx4_rss_deinit(struct mlx4_priv *priv); 130 struct mlx4_rss *mlx4_rss_get(struct mlx4_priv *priv, uint64_t fields, 131 const uint8_t key[MLX4_RSS_HASH_KEY_SIZE], 132 uint16_t queues, const uint16_t queue_id[]); 133 void mlx4_rss_put(struct mlx4_rss *rss); 134 int mlx4_rss_attach(struct mlx4_rss *rss); 135 void mlx4_rss_detach(struct mlx4_rss *rss); 136 int mlx4_rxq_attach(struct rxq *rxq); 137 void mlx4_rxq_detach(struct rxq *rxq); 138 uint64_t mlx4_get_rx_port_offloads(struct mlx4_priv *priv); 139 uint64_t mlx4_get_rx_queue_offloads(struct mlx4_priv *priv); 140 int mlx4_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, 141 uint16_t desc, unsigned int socket, 142 const struct rte_eth_rxconf *conf, 143 struct rte_mempool *mp); 144 void mlx4_rx_queue_release(void *dpdk_rxq); 145 146 /* mlx4_rxtx.c */ 147 148 uint16_t mlx4_tx_burst(void *dpdk_txq, struct rte_mbuf **pkts, 149 uint16_t pkts_n); 150 uint16_t mlx4_rx_burst(void *dpdk_rxq, struct rte_mbuf **pkts, 151 uint16_t pkts_n); 152 uint16_t mlx4_tx_burst_removed(void *dpdk_txq, struct rte_mbuf **pkts, 153 uint16_t pkts_n); 154 uint16_t mlx4_rx_burst_removed(void *dpdk_rxq, struct rte_mbuf **pkts, 155 uint16_t pkts_n); 156 157 /* mlx4_txq.c */ 158 159 int mlx4_tx_uar_init_secondary(struct rte_eth_dev *dev, int fd); 160 void mlx4_tx_uar_uninit_secondary(struct rte_eth_dev *dev); 161 uint64_t mlx4_get_tx_port_offloads(struct mlx4_priv *priv); 162 int mlx4_tx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, 163 uint16_t desc, unsigned int socket, 164 const struct rte_eth_txconf *conf); 165 void mlx4_tx_queue_release(void *dpdk_txq); 166 167 /* mlx4_mr.c */ 168 169 void mlx4_mr_flush_local_cache(struct mlx4_mr_ctrl *mr_ctrl); 170 uint32_t mlx4_rx_addr2mr_bh(struct rxq *rxq, uintptr_t addr); 171 uint32_t mlx4_tx_mb2mr_bh(struct txq *txq, struct rte_mbuf *mb); 172 uint32_t mlx4_tx_update_ext_mp(struct txq *txq, uintptr_t addr, 173 struct rte_mempool *mp); 174 175 /** 176 * Get Memory Pool (MP) from mbuf. If mbuf is indirect, the pool from which the 177 * cloned mbuf is allocated is returned instead. 178 * 179 * @param buf 180 * Pointer to mbuf. 181 * 182 * @return 183 * Memory pool where data is located for given mbuf. 184 */ 185 static inline struct rte_mempool * 186 mlx4_mb2mp(struct rte_mbuf *buf) 187 { 188 if (unlikely(RTE_MBUF_CLONED(buf))) 189 return rte_mbuf_from_indirect(buf)->pool; 190 return buf->pool; 191 } 192 193 /** 194 * Query LKey from a packet buffer for Rx. No need to flush local caches for Rx 195 * as mempool is pre-configured and static. 196 * 197 * @param rxq 198 * Pointer to Rx queue structure. 199 * @param addr 200 * Address to search. 201 * 202 * @return 203 * Searched LKey on success, UINT32_MAX on no match. 204 */ 205 static __rte_always_inline uint32_t 206 mlx4_rx_addr2mr(struct rxq *rxq, uintptr_t addr) 207 { 208 struct mlx4_mr_ctrl *mr_ctrl = &rxq->mr_ctrl; 209 uint32_t lkey; 210 211 /* Linear search on MR cache array. */ 212 lkey = mlx4_mr_lookup_cache(mr_ctrl->cache, &mr_ctrl->mru, 213 MLX4_MR_CACHE_N, addr); 214 if (likely(lkey != UINT32_MAX)) 215 return lkey; 216 /* Take slower bottom-half (Binary Search) on miss. */ 217 return mlx4_rx_addr2mr_bh(rxq, addr); 218 } 219 220 #define mlx4_rx_mb2mr(rxq, mb) mlx4_rx_addr2mr(rxq, (uintptr_t)((mb)->buf_addr)) 221 222 /** 223 * Query LKey from a packet buffer for Tx. If not found, add the mempool. 224 * 225 * @param txq 226 * Pointer to Tx queue structure. 227 * @param addr 228 * Address to search. 229 * 230 * @return 231 * Searched LKey on success, UINT32_MAX on no match. 232 */ 233 static __rte_always_inline uint32_t 234 mlx4_tx_mb2mr(struct txq *txq, struct rte_mbuf *mb) 235 { 236 struct mlx4_mr_ctrl *mr_ctrl = &txq->mr_ctrl; 237 uintptr_t addr = (uintptr_t)mb->buf_addr; 238 uint32_t lkey; 239 240 /* Check generation bit to see if there's any change on existing MRs. */ 241 if (unlikely(*mr_ctrl->dev_gen_ptr != mr_ctrl->cur_gen)) 242 mlx4_mr_flush_local_cache(mr_ctrl); 243 /* Linear search on MR cache array. */ 244 lkey = mlx4_mr_lookup_cache(mr_ctrl->cache, &mr_ctrl->mru, 245 MLX4_MR_CACHE_N, addr); 246 if (likely(lkey != UINT32_MAX)) 247 return lkey; 248 /* Take slower bottom-half on miss. */ 249 return mlx4_tx_mb2mr_bh(txq, mb); 250 } 251 252 #endif /* MLX4_RXTX_H_ */ 253