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