Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause 2 : : * Copyright(c) 2024 ZTE Corporation 3 : : */ 4 : : 5 : : #ifndef ZXDH_QUEUE_H 6 : : #define ZXDH_QUEUE_H 7 : : 8 : : #include <stdint.h> 9 : : 10 : : #include <rte_common.h> 11 : : #include <rte_atomic.h> 12 : : 13 : : #include "zxdh_ethdev.h" 14 : : #include "zxdh_rxtx.h" 15 : : #include "zxdh_pci.h" 16 : : 17 : : enum { ZXDH_VTNET_RQ = 0, ZXDH_VTNET_TQ = 1 }; 18 : : 19 : : #define ZXDH_VIRTQUEUE_MAX_NAME_SZ 32 20 : : #define ZXDH_RQ_QUEUE_IDX 0 21 : : #define ZXDH_TQ_QUEUE_IDX 1 22 : : #define ZXDH_MAX_TX_INDIRECT 8 23 : : 24 : : #define ZXDH_MIN_QUEUE_DEPTH 512 25 : : #define ZXDH_MAX_QUEUE_DEPTH 32768 26 : : 27 : : #define ZXDH_TX_FREE_THRESH 32 28 : : #define ZXDH_RX_FREE_THRESH 32 29 : : 30 : : #define ZXDH_MBUF_SIZE_4K 4096 31 : : 32 : : /* This marks a buffer as continuing via the next field. */ 33 : : #define ZXDH_VRING_DESC_F_NEXT 1 34 : : 35 : : /* This marks a buffer as write-only (otherwise read-only). */ 36 : : #define ZXDH_VRING_DESC_F_WRITE 2 37 : : 38 : : /* This means the buffer contains a list of buffer descriptors. */ 39 : : #define ZXDH_VRING_DESC_F_INDIRECT 4 40 : : 41 : : /* This flag means the descriptor was made available by the driver */ 42 : : #define ZXDH_VRING_PACKED_DESC_F_AVAIL (1 << (7)) 43 : : #define ZXDH_VRING_PACKED_DESC_F_USED (1 << (15)) 44 : : 45 : : /* Frequently used combinations */ 46 : : #define ZXDH_VRING_PACKED_DESC_F_AVAIL_USED \ 47 : : (ZXDH_VRING_PACKED_DESC_F_AVAIL | ZXDH_VRING_PACKED_DESC_F_USED) 48 : : 49 : : #define ZXDH_RING_EVENT_FLAGS_ENABLE 0x0 50 : : #define ZXDH_RING_EVENT_FLAGS_DISABLE 0x1 51 : : #define ZXDH_RING_EVENT_FLAGS_DESC 0x2 52 : : 53 : : #define ZXDH_RING_F_INDIRECT_DESC 28 54 : : 55 : : #define ZXDH_VQ_RING_DESC_CHAIN_END 32768 56 : : #define ZXDH_QUEUE_DEPTH 1024 57 : : 58 : : #define ZXDH_RQ_QUEUE_IDX 0 59 : : #define ZXDH_TQ_QUEUE_IDX 1 60 : : #define ZXDH_UL_1588_HDR_SIZE 8 61 : : #define ZXDH_TYPE_HDR_SIZE sizeof(struct zxdh_type_hdr) 62 : : #define ZXDH_PI_HDR_SIZE sizeof(struct zxdh_pi_hdr) 63 : : #define ZXDH_DL_NET_HDR_SIZE sizeof(struct zxdh_net_hdr_dl) 64 : : #define ZXDH_UL_NET_HDR_SIZE sizeof(struct zxdh_net_hdr_ul) 65 : : #define ZXDH_DL_PD_HDR_SIZE sizeof(struct zxdh_pd_hdr_dl) 66 : : #define ZXDH_UL_PD_HDR_SIZE sizeof(struct zxdh_pd_hdr_ul) 67 : : #define ZXDH_DL_NET_HDR_NOPI_SIZE (ZXDH_TYPE_HDR_SIZE + \ 68 : : ZXDH_DL_PD_HDR_SIZE) 69 : : #define ZXDH_UL_NOPI_HDR_SIZE_MAX (ZXDH_TYPE_HDR_SIZE + \ 70 : : ZXDH_UL_PD_HDR_SIZE + \ 71 : : ZXDH_UL_1588_HDR_SIZE) 72 : : #define ZXDH_PD_HDR_SIZE_MAX 256 73 : : #define ZXDH_PD_HDR_SIZE_MIN ZXDH_TYPE_HDR_SIZE 74 : : 75 : : #define rte_packet_prefetch(p) do {} while (0) 76 : : 77 : : /* 78 : : * ring descriptors: 16 bytes. 79 : : * These can chain together via "next". 80 : : */ 81 : : struct zxdh_vring_desc { 82 : : uint64_t addr; /* Address (guest-physical). */ 83 : : uint32_t len; /* Length. */ 84 : : uint16_t flags; /* The flags as indicated above. */ 85 : : uint16_t next; /* We chain unused descriptors via this. */ 86 : : }; 87 : : 88 : : struct zxdh_vring_used_elem { 89 : : /* Index of start of used descriptor chain. */ 90 : : uint32_t id; 91 : : /* Total length of the descriptor chain which was written to. */ 92 : : uint32_t len; 93 : : }; 94 : : 95 : : struct zxdh_vring_used { 96 : : uint16_t flags; 97 : : uint16_t idx; 98 : : struct zxdh_vring_used_elem ring[]; 99 : : }; 100 : : 101 : : struct zxdh_vring_avail { 102 : : uint16_t flags; 103 : : uint16_t idx; 104 : : uint16_t ring[]; 105 : : }; 106 : : 107 : : struct zxdh_vring_packed_desc { 108 : : uint64_t addr; 109 : : uint32_t len; 110 : : uint16_t id; 111 : : uint16_t flags; 112 : : }; 113 : : 114 : : struct zxdh_vring_packed_desc_event { 115 : : uint16_t desc_event_off_wrap; 116 : : uint16_t desc_event_flags; 117 : : }; 118 : : 119 : : struct zxdh_vring_packed { 120 : : uint32_t num; 121 : : struct zxdh_vring_packed_desc *desc; 122 : : struct zxdh_vring_packed_desc_event *driver; 123 : : struct zxdh_vring_packed_desc_event *device; 124 : : }; 125 : : 126 : : struct zxdh_vq_desc_extra { 127 : : void *cookie; 128 : : uint16_t ndescs; 129 : : uint16_t next; 130 : : }; 131 : : 132 : : struct zxdh_virtqueue { 133 : : struct zxdh_hw *hw; /* < zxdh_hw structure pointer. */ 134 : : 135 : : struct { 136 : : /* vring keeping descs and events */ 137 : : struct zxdh_vring_packed ring; 138 : : uint8_t used_wrap_counter; 139 : : uint8_t rsv; 140 : : uint16_t cached_flags; /* < cached flags for descs */ 141 : : uint16_t event_flags_shadow; 142 : : uint16_t rsv1; 143 : : } vq_packed; 144 : : 145 : : uint16_t vq_used_cons_idx; /* < last consumed descriptor */ 146 : : uint16_t vq_nentries; /* < vring desc numbers */ 147 : : uint16_t vq_free_cnt; /* < num of desc available */ 148 : : uint16_t vq_avail_idx; /* < sync until needed */ 149 : : uint16_t vq_free_thresh; /* < free threshold */ 150 : : uint16_t rsv2; 151 : : 152 : : void *vq_ring_virt_mem; /* < linear address of vring */ 153 : : uint32_t vq_ring_size; 154 : : 155 : : union { 156 : : struct zxdh_virtnet_rx rxq; 157 : : struct zxdh_virtnet_tx txq; 158 : : }; 159 : : 160 : : /* 161 : : * physical address of vring, or virtual address 162 : : */ 163 : : rte_iova_t vq_ring_mem; 164 : : 165 : : /* 166 : : * Head of the free chain in the descriptor table. If 167 : : * there are no free descriptors, this will be set to 168 : : * VQ_RING_DESC_CHAIN_END. 169 : : */ 170 : : uint16_t vq_desc_head_idx; 171 : : uint16_t vq_desc_tail_idx; 172 : : uint16_t vq_queue_index; /* < PCI queue index */ 173 : : uint16_t offset; /* < relative offset to obtain addr in mbuf */ 174 : : uint16_t *notify_addr; 175 : : struct rte_mbuf **sw_ring; /* < RX software ring. */ 176 : : struct zxdh_vq_desc_extra vq_descx[]; 177 : : }; 178 : : 179 : : struct __rte_packed_begin zxdh_type_hdr { 180 : : uint8_t port; /* bit[0:1] 00-np 01-DRS 10-DTP */ 181 : : uint8_t pd_len; 182 : : uint8_t num_buffers; 183 : : uint8_t reserved; 184 : : } __rte_packed_end; 185 : : 186 : : struct __rte_packed_begin zxdh_pi_hdr { 187 : : uint8_t pi_len; 188 : : uint8_t pkt_type; 189 : : uint16_t vlan_id; 190 : : uint32_t ipv6_extend; 191 : : uint16_t l3_offset; 192 : : uint16_t l4_offset; 193 : : uint8_t phy_port; 194 : : uint8_t pkt_flag_hi8; 195 : : uint16_t pkt_flag_lw16; 196 : : union { 197 : : struct { 198 : : uint64_t sa_idx; 199 : : uint8_t reserved_8[8]; 200 : : } dl; 201 : : struct { 202 : : uint32_t lro_flag; 203 : : uint32_t lro_mss; 204 : : uint16_t err_code; 205 : : uint16_t pm_id; 206 : : uint16_t pkt_len; 207 : : uint8_t reserved[2]; 208 : : } ul; 209 : : }; 210 : : } __rte_packed_end; /* 32B */ 211 : : 212 : : struct __rte_packed_begin zxdh_pd_hdr_dl { 213 : : uint16_t ol_flag; 214 : : uint8_t rsv; 215 : : uint8_t panel_id; 216 : : 217 : : uint16_t svlan_insert; 218 : : uint16_t cvlan_insert; 219 : : 220 : : uint8_t tag_idx; 221 : : uint8_t tag_data; 222 : : uint16_t dst_vfid; 223 : : } __rte_packed_end; /* 16B */ 224 : : 225 : : struct __rte_packed_begin zxdh_pipd_hdr_dl { 226 : : struct zxdh_pi_hdr pi_hdr; /* 32B */ 227 : : struct zxdh_pd_hdr_dl pd_hdr; /* 12B */ 228 : : } __rte_packed_end; /* 44B */ 229 : : 230 : : struct __rte_packed_begin zxdh_net_hdr_dl { 231 : : struct zxdh_type_hdr type_hdr; /* 4B */ 232 : : union { 233 : : struct zxdh_pd_hdr_dl pd_hdr; /* 12B */ 234 : : struct zxdh_pipd_hdr_dl pipd_hdr_dl; /* 44B */ 235 : : }; 236 : : } __rte_packed_end; 237 : : 238 : : struct __rte_packed_begin zxdh_pd_hdr_ul { 239 : : uint32_t pkt_flag; 240 : : uint32_t rss_hash; 241 : : uint32_t fd; 242 : : uint32_t striped_vlan_tci; 243 : : 244 : : uint16_t pkt_type_out; 245 : : uint16_t pkt_type_in; 246 : : uint16_t pkt_len; 247 : : 248 : : uint8_t tag_idx; 249 : : uint8_t tag_data; 250 : : uint16_t src_vfid; 251 : : } __rte_packed_end; /* 24B */ 252 : : 253 : : struct __rte_packed_begin zxdh_pipd_hdr_ul { 254 : : struct zxdh_pi_hdr pi_hdr; /* 32B */ 255 : : struct zxdh_pd_hdr_ul pd_hdr; /* 26B */ 256 : : } __rte_packed_end; 257 : : 258 : : struct __rte_packed_begin zxdh_net_hdr_ul { 259 : : struct zxdh_type_hdr type_hdr; /* 4B */ 260 : : union { 261 : : struct zxdh_pd_hdr_ul pd_hdr; /* 26 */ 262 : : struct zxdh_pipd_hdr_ul pipd_hdr_ul; /* 58B */ 263 : : }; 264 : : } __rte_packed_end; /* 60B */ 265 : : 266 : : 267 : : struct zxdh_tx_region { 268 : : struct zxdh_net_hdr_dl tx_hdr; 269 : : union { 270 : : struct zxdh_vring_desc tx_indir[ZXDH_MAX_TX_INDIRECT]; 271 : : struct zxdh_vring_packed_desc tx_packed_indir[ZXDH_MAX_TX_INDIRECT]; 272 : : }; 273 : : }; 274 : : 275 : : static inline size_t 276 [ # # ]: 0 : zxdh_vring_size(struct zxdh_hw *hw, uint32_t num, unsigned long align) 277 : : { 278 : : size_t size; 279 : : 280 [ # # ]: 0 : if (zxdh_pci_packed_queue(hw)) { 281 : 0 : size = num * sizeof(struct zxdh_vring_packed_desc); 282 : 0 : size += sizeof(struct zxdh_vring_packed_desc_event); 283 : 0 : size = RTE_ALIGN_CEIL(size, align); 284 : 0 : size += sizeof(struct zxdh_vring_packed_desc_event); 285 : 0 : return size; 286 : : } 287 : : 288 : 0 : size = num * sizeof(struct zxdh_vring_desc); 289 : 0 : size += sizeof(struct zxdh_vring_avail) + (num * sizeof(uint16_t)); 290 : 0 : size = RTE_ALIGN_CEIL(size, align); 291 : 0 : size += sizeof(struct zxdh_vring_used) + (num * sizeof(struct zxdh_vring_used_elem)); 292 : 0 : return size; 293 : : } 294 : : 295 : : static inline void 296 : : zxdh_vring_init_packed(struct zxdh_vring_packed *vr, uint8_t *p, 297 : : unsigned long align, uint32_t num) 298 : : { 299 : 0 : vr->num = num; 300 : 0 : vr->desc = (struct zxdh_vring_packed_desc *)p; 301 : 0 : vr->driver = (struct zxdh_vring_packed_desc_event *)(p + 302 : 0 : vr->num * sizeof(struct zxdh_vring_packed_desc)); 303 : 0 : vr->device = (struct zxdh_vring_packed_desc_event *)RTE_ALIGN_CEIL(((uintptr_t)vr->driver + 304 : : sizeof(struct zxdh_vring_packed_desc_event)), align); 305 : 0 : } 306 : : 307 : : static inline void 308 : : zxdh_vring_desc_init_packed(struct zxdh_virtqueue *vq, int32_t n) 309 : : { 310 : : int32_t i = 0; 311 : : 312 [ # # ]: 0 : for (i = 0; i < n - 1; i++) { 313 : 0 : vq->vq_packed.ring.desc[i].id = i; 314 : 0 : vq->vq_descx[i].next = i + 1; 315 : : } 316 : 0 : vq->vq_packed.ring.desc[i].id = i; 317 : 0 : vq->vq_descx[i].next = ZXDH_VQ_RING_DESC_CHAIN_END; 318 : : } 319 : : 320 : : static inline void 321 : : zxdh_vring_desc_init_indirect_packed(struct zxdh_vring_packed_desc *dp, int32_t n) 322 : : { 323 : : int32_t i = 0; 324 : : 325 [ # # ]: 0 : for (i = 0; i < n; i++) { 326 : 0 : dp[i].id = (uint16_t)i; 327 : 0 : dp[i].flags = ZXDH_VRING_DESC_F_WRITE; 328 : : } 329 : : } 330 : : 331 : : static inline void 332 : : zxdh_queue_disable_intr(struct zxdh_virtqueue *vq) 333 : : { 334 [ # # ]: 0 : if (vq->vq_packed.event_flags_shadow != ZXDH_RING_EVENT_FLAGS_DISABLE) { 335 : 0 : vq->vq_packed.event_flags_shadow = ZXDH_RING_EVENT_FLAGS_DISABLE; 336 : 0 : vq->vq_packed.ring.driver->desc_event_flags = vq->vq_packed.event_flags_shadow; 337 : : } 338 : : } 339 : : 340 : : static inline void 341 : : zxdh_queue_enable_intr(struct zxdh_virtqueue *vq) 342 : : { 343 [ # # ]: 0 : if (vq->vq_packed.event_flags_shadow == ZXDH_RING_EVENT_FLAGS_DISABLE) { 344 : 0 : vq->vq_packed.event_flags_shadow = ZXDH_RING_EVENT_FLAGS_DISABLE; 345 : 0 : vq->vq_packed.ring.driver->desc_event_flags = vq->vq_packed.event_flags_shadow; 346 : : } 347 : : } 348 : : 349 : : static inline void 350 : : zxdh_mb(uint8_t weak_barriers) 351 : : { 352 : : if (weak_barriers) 353 : : rte_atomic_thread_fence(rte_memory_order_seq_cst); 354 : : else 355 : : rte_mb(); 356 : : } 357 : : 358 : : static inline 359 : : int32_t desc_is_used(struct zxdh_vring_packed_desc *desc, struct zxdh_virtqueue *vq) 360 : : { 361 : : uint16_t flags; 362 : : uint16_t used, avail; 363 : : 364 : 0 : flags = desc->flags; 365 : 0 : rte_io_rmb(); 366 : 0 : used = !!(flags & ZXDH_VRING_PACKED_DESC_F_USED); 367 : 0 : avail = !!(flags & ZXDH_VRING_PACKED_DESC_F_AVAIL); 368 [ # # # # ]: 0 : return avail == used && used == vq->vq_packed.used_wrap_counter; 369 : : } 370 : : 371 : : static inline int32_t 372 : : zxdh_queue_full(const struct zxdh_virtqueue *vq) 373 : : { 374 [ # # ]: 0 : return (vq->vq_free_cnt == 0); 375 : : } 376 : : 377 : : static inline void 378 : : zxdh_queue_store_flags_packed(struct zxdh_vring_packed_desc *dp, uint16_t flags) 379 : : { 380 : 0 : rte_io_wmb(); 381 [ # # ]: 0 : dp->flags = flags; 382 : : } 383 : : 384 : : static inline int32_t 385 : : zxdh_desc_used(struct zxdh_vring_packed_desc *desc, struct zxdh_virtqueue *vq) 386 : : { 387 : : uint16_t flags; 388 : : uint16_t used, avail; 389 : : 390 : 0 : flags = desc->flags; 391 : 0 : rte_io_rmb(); 392 : 0 : used = !!(flags & ZXDH_VRING_PACKED_DESC_F_USED); 393 : 0 : avail = !!(flags & ZXDH_VRING_PACKED_DESC_F_AVAIL); 394 [ # # # # : 0 : return avail == used && used == vq->vq_packed.used_wrap_counter; # # # # ] 395 : : } 396 : : 397 : : static inline void zxdh_queue_notify(struct zxdh_virtqueue *vq) 398 : : { 399 : 0 : ZXDH_VTPCI_OPS(vq->hw)->notify_queue(vq->hw, vq); 400 : 0 : } 401 : : 402 : : static inline int32_t 403 : : zxdh_queue_kick_prepare_packed(struct zxdh_virtqueue *vq) 404 : : { 405 : : uint16_t flags = 0; 406 : : 407 : : zxdh_mb(1); 408 : 0 : flags = vq->vq_packed.ring.device->desc_event_flags; 409 : : 410 [ # # ]: 0 : return (flags != ZXDH_RING_EVENT_FLAGS_DISABLE); 411 : : } 412 : : 413 : : 414 : : struct rte_mbuf *zxdh_queue_detach_unused(struct zxdh_virtqueue *vq); 415 : : int32_t zxdh_free_queues(struct rte_eth_dev *dev); 416 : : int32_t zxdh_get_queue_type(uint16_t vtpci_queue_idx); 417 : : int32_t zxdh_dev_tx_queue_setup(struct rte_eth_dev *dev, 418 : : uint16_t queue_idx, 419 : : uint16_t nb_desc, 420 : : uint32_t socket_id, 421 : : const struct rte_eth_txconf *tx_conf); 422 : : int32_t zxdh_dev_rx_queue_setup(struct rte_eth_dev *dev, 423 : : uint16_t queue_idx, 424 : : uint16_t nb_desc, 425 : : uint32_t socket_id, 426 : : const struct rte_eth_rxconf *rx_conf, 427 : : struct rte_mempool *mp); 428 : : int32_t zxdh_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id); 429 : : int32_t zxdh_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id); 430 : : int32_t zxdh_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t logic_qidx); 431 : : void zxdh_queue_rxvq_flush(struct zxdh_virtqueue *vq); 432 : : int32_t zxdh_enqueue_recv_refill_packed(struct zxdh_virtqueue *vq, 433 : : struct rte_mbuf **cookie, uint16_t num); 434 : : int32_t zxdh_tx_queue_config(struct rte_eth_dev *dev, uint16_t queue_idx); 435 : : int32_t zxdh_rx_queue_config(struct rte_eth_dev *dev, uint16_t queue_idx); 436 : : #endif /* ZXDH_QUEUE_H */