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 : : #include <rte_io.h> 13 : : 14 : : #include "zxdh_ethdev.h" 15 : : #include "zxdh_rxtx.h" 16 : : #include "zxdh_pci.h" 17 : : 18 : : enum { ZXDH_VTNET_RQ = 0, ZXDH_VTNET_TQ = 1 }; 19 : : 20 : : #define ZXDH_VIRTQUEUE_MAX_NAME_SZ 32 21 : : #define ZXDH_RQ_QUEUE_IDX 0 22 : : #define ZXDH_TQ_QUEUE_IDX 1 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 : : struct zxdh_vring_packed_desc *desc; 121 : : struct zxdh_vring_packed_desc_event *driver; 122 : : struct zxdh_vring_packed_desc_event *device; 123 : : }; 124 : : 125 : : struct zxdh_vq_desc_extra { 126 : : void *cookie; 127 : : uint16_t next; 128 : : }; 129 : : 130 : : struct zxdh_virtqueue { 131 : : struct { 132 : : struct zxdh_vring_packed ring; 133 : : } vq_packed; 134 : : struct zxdh_hw *hw; /* < zxdh_hw structure pointer. */ 135 : : 136 : : uint16_t vq_used_cons_idx; /**< last consumed descriptor */ 137 : : uint16_t vq_avail_idx; /**< sync until needed */ 138 : : uint16_t vq_nentries; /**< vring desc numbers */ 139 : : uint16_t vq_free_cnt; /**< num of desc available */ 140 : : 141 : : uint16_t cached_flags; /**< cached flags for descs */ 142 : : uint8_t used_wrap_counter; 143 : : uint8_t rsv; 144 : : uint16_t vq_free_thresh; /**< free threshold */ 145 : : uint16_t rsv1; 146 : : 147 : : void *notify_addr; 148 : : 149 : : union { 150 : : struct zxdh_virtnet_rx rxq; 151 : : struct zxdh_virtnet_tx txq; 152 : : }; 153 : : 154 : : uint16_t vq_queue_index; /* PACKED: phy_idx, SPLIT: logic_idx */ 155 : : uint16_t event_flags_shadow; 156 : : uint32_t vq_ring_size; 157 : : 158 : : /** 159 : : * Head of the free chain in the descriptor table. If 160 : : * there are no free descriptors, this will be set to 161 : : * VQ_RING_DESC_CHAIN_END. 162 : : */ 163 : : uint16_t vq_desc_head_idx; 164 : : uint16_t vq_desc_tail_idx; 165 : : uint32_t rsv2; 166 : : 167 : : void *vq_ring_virt_mem; /**< linear address of vring*/ 168 : : /* physical address of vring, or virtual address for virtio_user. */ 169 : : rte_iova_t vq_ring_mem; 170 : : 171 : : struct zxdh_vq_desc_extra vq_descx[]; 172 : : }; 173 : : 174 : : struct __rte_packed_begin zxdh_type_hdr { 175 : : uint8_t port; /* bit[0:1] 00-np 01-DRS 10-DTP */ 176 : : uint8_t pd_len; 177 : : uint8_t num_buffers; 178 : : uint8_t reserved; 179 : : } __rte_packed_end; 180 : : 181 : : struct __rte_packed_begin zxdh_pi_hdr { 182 : : uint8_t pi_len; 183 : : uint8_t pkt_type; 184 : : uint16_t vlan_id; 185 : : uint32_t ipv6_extend; 186 : : uint16_t l3_offset; 187 : : uint16_t l4_offset; 188 : : uint8_t phy_port; 189 : : uint8_t pkt_flag_hi8; 190 : : uint16_t pkt_flag_lw16; 191 : : union { 192 : : struct { 193 : : uint64_t sa_idx; 194 : : uint8_t reserved_8[8]; 195 : : } dl; 196 : : struct { 197 : : uint32_t lro_flag; 198 : : uint32_t lro_mss; 199 : : uint16_t err_code; 200 : : uint16_t pm_id; 201 : : uint16_t pkt_len; 202 : : uint8_t reserved[2]; 203 : : } ul; 204 : : }; 205 : : } __rte_packed_end; /* 32B */ 206 : : 207 : : struct __rte_packed_begin zxdh_pd_hdr_dl { 208 : : uint16_t ol_flag; 209 : : uint8_t rsv; 210 : : uint8_t panel_id; 211 : : 212 : : uint16_t svlan_insert; 213 : : uint16_t cvlan_insert; 214 : : 215 : : uint8_t tag_idx; 216 : : uint8_t tag_data; 217 : : uint16_t dst_vfid; 218 : : } __rte_packed_end; /* 16B */ 219 : : 220 : : struct __rte_packed_begin zxdh_pipd_hdr_dl { 221 : : struct zxdh_pi_hdr pi_hdr; /* 32B */ 222 : : struct zxdh_pd_hdr_dl pd_hdr; /* 12B */ 223 : : } __rte_packed_end; /* 44B */ 224 : : 225 : : struct __rte_packed_begin zxdh_net_hdr_dl { 226 : : struct zxdh_type_hdr type_hdr; /* 4B */ 227 : : union { 228 : : struct zxdh_pd_hdr_dl pd_hdr; /* 12B */ 229 : : struct zxdh_pipd_hdr_dl pipd_hdr_dl; /* 44B */ 230 : : }; 231 : : } __rte_packed_end; 232 : : 233 : : struct __rte_packed_begin zxdh_pd_hdr_ul { 234 : : uint32_t pkt_flag; 235 : : uint32_t rss_hash; 236 : : uint32_t fd; 237 : : uint32_t striped_vlan_tci; 238 : : 239 : : uint16_t pkt_type_out; 240 : : uint16_t pkt_type_in; 241 : : uint16_t pkt_len; 242 : : 243 : : uint8_t tag_idx; 244 : : uint8_t tag_data; 245 : : uint16_t src_vfid; 246 : : } __rte_packed_end; /* 24B */ 247 : : 248 : : struct __rte_packed_begin zxdh_pipd_hdr_ul { 249 : : struct zxdh_pi_hdr pi_hdr; /* 32B */ 250 : : struct zxdh_pd_hdr_ul pd_hdr; /* 26B */ 251 : : } __rte_packed_end; 252 : : 253 : : struct __rte_packed_begin zxdh_net_hdr_ul { 254 : : struct zxdh_type_hdr type_hdr; /* 4B */ 255 : : union { 256 : : struct zxdh_pd_hdr_ul pd_hdr; /* 26 */ 257 : : struct zxdh_pipd_hdr_ul pipd_hdr_ul; /* 58B */ 258 : : }; 259 : : } __rte_packed_end; /* 60B */ 260 : : 261 : : 262 : : struct zxdh_tx_region { 263 : : struct zxdh_net_hdr_dl tx_hdr; 264 : : }; 265 : : 266 : : static inline size_t 267 [ # # ]: 0 : zxdh_vring_size(struct zxdh_hw *hw, uint32_t num, unsigned long align) 268 : : { 269 : : size_t size; 270 : : 271 [ # # ]: 0 : if (zxdh_pci_packed_queue(hw)) { 272 : 0 : size = num * sizeof(struct zxdh_vring_packed_desc); 273 : 0 : size += sizeof(struct zxdh_vring_packed_desc_event); 274 : 0 : size = RTE_ALIGN_CEIL(size, align); 275 : 0 : size += sizeof(struct zxdh_vring_packed_desc_event); 276 : 0 : return size; 277 : : } 278 : : 279 : 0 : size = num * sizeof(struct zxdh_vring_desc); 280 : 0 : size += sizeof(struct zxdh_vring_avail) + (num * sizeof(uint16_t)); 281 : 0 : size = RTE_ALIGN_CEIL(size, align); 282 : 0 : size += sizeof(struct zxdh_vring_used) + (num * sizeof(struct zxdh_vring_used_elem)); 283 : 0 : return size; 284 : : } 285 : : 286 : : static inline void 287 : : zxdh_vring_init_packed(struct zxdh_vring_packed *vr, uint8_t *p, 288 : : unsigned long align, uint32_t num) 289 : : { 290 : 0 : vr->desc = (struct zxdh_vring_packed_desc *)p; 291 : 0 : vr->driver = (struct zxdh_vring_packed_desc_event *)(p + 292 : 0 : num * sizeof(struct zxdh_vring_packed_desc)); 293 : 0 : vr->device = (struct zxdh_vring_packed_desc_event *)RTE_ALIGN_CEIL(((uintptr_t)vr->driver + 294 : : sizeof(struct zxdh_vring_packed_desc_event)), align); 295 : 0 : } 296 : : 297 : : static inline void 298 : : zxdh_vring_desc_init_packed(struct zxdh_virtqueue *vq, int32_t n) 299 : : { 300 : : int32_t i = 0; 301 : : 302 [ # # ]: 0 : for (i = 0; i < n - 1; i++) { 303 : 0 : vq->vq_packed.ring.desc[i].id = i; 304 : 0 : vq->vq_descx[i].next = i + 1; 305 : : } 306 : 0 : vq->vq_packed.ring.desc[i].id = i; 307 : 0 : vq->vq_descx[i].next = ZXDH_VQ_RING_DESC_CHAIN_END; 308 : : } 309 : : 310 : : static inline void 311 : : zxdh_queue_disable_intr(struct zxdh_virtqueue *vq) 312 : : { 313 [ # # ]: 0 : if (vq->event_flags_shadow != ZXDH_RING_EVENT_FLAGS_DISABLE) { 314 : 0 : vq->event_flags_shadow = ZXDH_RING_EVENT_FLAGS_DISABLE; 315 : 0 : vq->vq_packed.ring.driver->desc_event_flags = vq->event_flags_shadow; 316 : : } 317 : : } 318 : : 319 : : static inline void 320 : : zxdh_queue_enable_intr(struct zxdh_virtqueue *vq) 321 : : { 322 [ # # ]: 0 : if (vq->event_flags_shadow != ZXDH_RING_EVENT_FLAGS_ENABLE) { 323 : 0 : vq->event_flags_shadow = ZXDH_RING_EVENT_FLAGS_ENABLE; 324 : 0 : vq->vq_packed.ring.driver->desc_event_flags = vq->event_flags_shadow; 325 : : } 326 : : } 327 : : 328 : : static inline 329 : : int32_t desc_is_used(struct zxdh_vring_packed_desc *desc, struct zxdh_virtqueue *vq) 330 : : { 331 : : uint16_t flags; 332 : : uint16_t used, avail; 333 : : 334 : 0 : flags = desc->flags; 335 : 0 : rte_io_rmb(); 336 : 0 : used = !!(flags & ZXDH_VRING_PACKED_DESC_F_USED); 337 : 0 : avail = !!(flags & ZXDH_VRING_PACKED_DESC_F_AVAIL); 338 [ # # # # : 0 : return avail == used && used == vq->used_wrap_counter; # # # # ] 339 : : } 340 : : 341 : : static inline int32_t 342 : : zxdh_queue_full(const struct zxdh_virtqueue *vq) 343 : : { 344 [ # # ]: 0 : return (vq->vq_free_cnt == 0); 345 : : } 346 : : 347 : : static inline void 348 : : zxdh_queue_store_flags_packed(struct zxdh_vring_packed_desc *dp, uint16_t flags) 349 : : { 350 : 0 : rte_io_wmb(); 351 [ # # ]: 0 : dp->flags = flags; 352 : : } 353 : : 354 : 0 : static inline void zxdh_queue_notify(struct zxdh_virtqueue *vq) 355 : : { 356 : : uint32_t notify_data = 0; 357 : : 358 [ # # ]: 0 : if (!zxdh_pci_with_feature(vq->hw, ZXDH_F_NOTIFICATION_DATA)) { 359 : 0 : rte_write16(vq->vq_queue_index, vq->notify_addr); 360 : 0 : return; 361 : : } 362 : : /* Bit[0:15]: vq queue index 363 : : * Bit[16:30]: avail index 364 : : * Bit[31]: avail wrap counter 365 : : */ 366 [ # # ]: 0 : notify_data = ((uint32_t)vq->vq_avail_idx << 16) | vq->vq_queue_index; 367 [ # # ]: 0 : if (zxdh_pci_with_feature(vq->hw, ZXDH_F_RING_PACKED) && 368 [ # # ]: 0 : (vq->cached_flags & ZXDH_VRING_PACKED_DESC_F_AVAIL)) 369 : 0 : notify_data |= RTE_BIT32(31); 370 : 0 : rte_write32(notify_data, vq->notify_addr); 371 : : } 372 : : 373 : : struct rte_mbuf *zxdh_queue_detach_unused(struct zxdh_virtqueue *vq); 374 : : int32_t zxdh_free_queues(struct rte_eth_dev *dev); 375 : : int32_t zxdh_get_queue_type(uint16_t vtpci_queue_idx); 376 : : int32_t zxdh_dev_tx_queue_setup(struct rte_eth_dev *dev, 377 : : uint16_t queue_idx, 378 : : uint16_t nb_desc, 379 : : uint32_t socket_id, 380 : : const struct rte_eth_txconf *tx_conf); 381 : : int32_t zxdh_dev_rx_queue_setup(struct rte_eth_dev *dev, 382 : : uint16_t queue_idx, 383 : : uint16_t nb_desc, 384 : : uint32_t socket_id, 385 : : const struct rte_eth_rxconf *rx_conf, 386 : : struct rte_mempool *mp); 387 : : int32_t zxdh_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id); 388 : : int32_t zxdh_dev_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id); 389 : : int32_t zxdh_dev_rx_queue_setup_finish(struct rte_eth_dev *dev, uint16_t logic_qidx); 390 : : void zxdh_queue_rxvq_flush(struct zxdh_virtqueue *vq); 391 : : int32_t zxdh_enqueue_recv_refill_packed(struct zxdh_virtqueue *vq, 392 : : struct rte_mbuf **cookie, uint16_t num); 393 : : int32_t zxdh_tx_queue_config(struct rte_eth_dev *dev, uint16_t queue_idx); 394 : : int32_t zxdh_rx_queue_config(struct rte_eth_dev *dev, uint16_t queue_idx); 395 : : #endif /* ZXDH_QUEUE_H */