1b0cd36e9SDanylo Vodopianov /* 2b0cd36e9SDanylo Vodopianov * SPDX-License-Identifier: BSD-3-Clause 3b0cd36e9SDanylo Vodopianov * Copyright(c) 2023 Napatech A/S 4b0cd36e9SDanylo Vodopianov */ 5b0cd36e9SDanylo Vodopianov 6b0cd36e9SDanylo Vodopianov #ifndef __NTOSS_VIRT_QUEUE_H__ 7b0cd36e9SDanylo Vodopianov #define __NTOSS_VIRT_QUEUE_H__ 8b0cd36e9SDanylo Vodopianov 9b0cd36e9SDanylo Vodopianov #include <stdint.h> 10b0cd36e9SDanylo Vodopianov #include <stdalign.h> 11b0cd36e9SDanylo Vodopianov 12b0cd36e9SDanylo Vodopianov #include <rte_memory.h> 13b0cd36e9SDanylo Vodopianov 14b0cd36e9SDanylo Vodopianov struct nthw_virt_queue; 15b0cd36e9SDanylo Vodopianov 166b0047faSDanylo Vodopianov #define SPLIT_RING 0 17da25ae3cSDanylo Vodopianov #define PACKED_RING 1 186b0047faSDanylo Vodopianov #define IN_ORDER 1 19b0cd36e9SDanylo Vodopianov 20da25ae3cSDanylo Vodopianov /* 21da25ae3cSDanylo Vodopianov * SPLIT : This marks a buffer as continuing via the next field. 22da25ae3cSDanylo Vodopianov * PACKED: This marks a buffer as continuing. (packed does not have a next field, so must be 23da25ae3cSDanylo Vodopianov * contiguous) In Used descriptors it must be ignored 24da25ae3cSDanylo Vodopianov */ 25da25ae3cSDanylo Vodopianov #define VIRTQ_DESC_F_NEXT 1 26e13da07fSDanylo Vodopianov /* 27e13da07fSDanylo Vodopianov * SPLIT : This marks a buffer as device write-only (otherwise device read-only). 28e13da07fSDanylo Vodopianov * PACKED: This marks a descriptor as device write-only (otherwise device read-only). 29e13da07fSDanylo Vodopianov * PACKED: In a used descriptor, this bit is used to specify whether any data has been written by 30e13da07fSDanylo Vodopianov * the device into any parts of the buffer. 31e13da07fSDanylo Vodopianov */ 32e13da07fSDanylo Vodopianov #define VIRTQ_DESC_F_WRITE 2 33b0cd36e9SDanylo Vodopianov 34da25ae3cSDanylo Vodopianov /* 35da25ae3cSDanylo Vodopianov * Split Ring virtq Descriptor 36da25ae3cSDanylo Vodopianov */ 37da25ae3cSDanylo Vodopianov struct __rte_aligned(8) virtq_desc { 38da25ae3cSDanylo Vodopianov /* Address (guest-physical). */ 39da25ae3cSDanylo Vodopianov uint64_t addr; 40da25ae3cSDanylo Vodopianov /* Length. */ 41da25ae3cSDanylo Vodopianov uint32_t len; 42da25ae3cSDanylo Vodopianov /* The flags as indicated above. */ 43da25ae3cSDanylo Vodopianov uint16_t flags; 44da25ae3cSDanylo Vodopianov /* Next field if flags & NEXT */ 45da25ae3cSDanylo Vodopianov uint16_t next; 46da25ae3cSDanylo Vodopianov }; 47da25ae3cSDanylo Vodopianov 48*f0fe222eSDanylo Vodopianov 49*f0fe222eSDanylo Vodopianov /* 50*f0fe222eSDanylo Vodopianov * Packed Ring special structures and defines 51*f0fe222eSDanylo Vodopianov */ 52*f0fe222eSDanylo Vodopianov 53af300887SDanylo Vodopianov /* additional packed ring flags */ 54af300887SDanylo Vodopianov #define VIRTQ_DESC_F_AVAIL (1 << 7) 55*f0fe222eSDanylo Vodopianov #define VIRTQ_DESC_F_USED (1 << 15) 56af300887SDanylo Vodopianov 57da25ae3cSDanylo Vodopianov /* descr phys address must be 16 byte aligned */ 58da25ae3cSDanylo Vodopianov struct __rte_aligned(16) pvirtq_desc { 59da25ae3cSDanylo Vodopianov /* Buffer Address. */ 60da25ae3cSDanylo Vodopianov uint64_t addr; 61da25ae3cSDanylo Vodopianov /* Buffer Length. */ 62da25ae3cSDanylo Vodopianov uint32_t len; 63da25ae3cSDanylo Vodopianov /* Buffer ID. */ 64da25ae3cSDanylo Vodopianov uint16_t id; 65da25ae3cSDanylo Vodopianov /* The flags depending on descriptor type. */ 66da25ae3cSDanylo Vodopianov uint16_t flags; 67da25ae3cSDanylo Vodopianov }; 68da25ae3cSDanylo Vodopianov 69af300887SDanylo Vodopianov /* Disable events */ 70af300887SDanylo Vodopianov #define RING_EVENT_FLAGS_DISABLE 0x1 71af300887SDanylo Vodopianov 72af300887SDanylo Vodopianov struct __rte_aligned(16) pvirtq_event_suppress { 73af300887SDanylo Vodopianov union { 74af300887SDanylo Vodopianov struct { 75af300887SDanylo Vodopianov /* Descriptor Ring Change Event Offset */ 76af300887SDanylo Vodopianov uint16_t desc_event_off : 15; 77af300887SDanylo Vodopianov /* Descriptor Ring Change Event Wrap Counter */ 78af300887SDanylo Vodopianov uint16_t desc_event_wrap : 1; 79af300887SDanylo Vodopianov }; 80af300887SDanylo Vodopianov /* If desc_event_flags set to RING_EVENT_FLAGS_DESC */ 81af300887SDanylo Vodopianov uint16_t desc; 82af300887SDanylo Vodopianov }; 83af300887SDanylo Vodopianov 84af300887SDanylo Vodopianov union { 85af300887SDanylo Vodopianov struct { 86af300887SDanylo Vodopianov uint16_t desc_event_flags : 2; /* Descriptor Ring Change Event Flags */ 87af300887SDanylo Vodopianov uint16_t reserved : 14; /* Reserved, set to 0 */ 88af300887SDanylo Vodopianov }; 89af300887SDanylo Vodopianov uint16_t flags; 90af300887SDanylo Vodopianov }; 91af300887SDanylo Vodopianov }; 92af300887SDanylo Vodopianov 93da25ae3cSDanylo Vodopianov /* 94da25ae3cSDanylo Vodopianov * Common virtq descr 95da25ae3cSDanylo Vodopianov */ 96da25ae3cSDanylo Vodopianov #define vq_set_next(vq, index, nxt) \ 97da25ae3cSDanylo Vodopianov do { \ 98da25ae3cSDanylo Vodopianov struct nthw_cvirtq_desc *temp_vq = (vq); \ 99da25ae3cSDanylo Vodopianov if (temp_vq->vq_type == SPLIT_RING) \ 100da25ae3cSDanylo Vodopianov temp_vq->s[index].next = nxt; \ 101da25ae3cSDanylo Vodopianov } while (0) 102da25ae3cSDanylo Vodopianov 103da25ae3cSDanylo Vodopianov #define vq_add_flags(vq, index, flgs) \ 104da25ae3cSDanylo Vodopianov do { \ 105da25ae3cSDanylo Vodopianov struct nthw_cvirtq_desc *temp_vq = (vq); \ 106da25ae3cSDanylo Vodopianov uint16_t tmp_index = (index); \ 107da25ae3cSDanylo Vodopianov typeof(flgs) tmp_flgs = (flgs); \ 108da25ae3cSDanylo Vodopianov if (temp_vq->vq_type == SPLIT_RING) \ 109da25ae3cSDanylo Vodopianov temp_vq->s[tmp_index].flags |= tmp_flgs; \ 110da25ae3cSDanylo Vodopianov else if (temp_vq->vq_type == PACKED_RING) \ 111da25ae3cSDanylo Vodopianov temp_vq->p[tmp_index].flags |= tmp_flgs; \ 112da25ae3cSDanylo Vodopianov } while (0) 113da25ae3cSDanylo Vodopianov 114da25ae3cSDanylo Vodopianov #define vq_set_flags(vq, index, flgs) \ 115da25ae3cSDanylo Vodopianov do { \ 116da25ae3cSDanylo Vodopianov struct nthw_cvirtq_desc *temp_vq = (vq); \ 117da25ae3cSDanylo Vodopianov uint32_t temp_flags = (flgs); \ 118da25ae3cSDanylo Vodopianov uint32_t temp_index = (index); \ 119da25ae3cSDanylo Vodopianov if ((temp_vq)->vq_type == SPLIT_RING) \ 120da25ae3cSDanylo Vodopianov (temp_vq)->s[temp_index].flags = temp_flags; \ 121da25ae3cSDanylo Vodopianov else if ((temp_vq)->vq_type == PACKED_RING) \ 122da25ae3cSDanylo Vodopianov (temp_vq)->p[temp_index].flags = temp_flags; \ 123da25ae3cSDanylo Vodopianov } while (0) 124da25ae3cSDanylo Vodopianov 125da25ae3cSDanylo Vodopianov struct nthw_virtq_desc_buf { 126da25ae3cSDanylo Vodopianov /* Address (guest-physical). */ 127da25ae3cSDanylo Vodopianov alignas(16) uint64_t addr; 128da25ae3cSDanylo Vodopianov /* Length. */ 129da25ae3cSDanylo Vodopianov uint32_t len; 130da25ae3cSDanylo Vodopianov }; 131da25ae3cSDanylo Vodopianov 132da25ae3cSDanylo Vodopianov struct nthw_cvirtq_desc { 133da25ae3cSDanylo Vodopianov union { 134da25ae3cSDanylo Vodopianov struct nthw_virtq_desc_buf *b; /* buffer part as is common */ 135da25ae3cSDanylo Vodopianov struct virtq_desc *s; /* SPLIT */ 136da25ae3cSDanylo Vodopianov struct pvirtq_desc *p; /* PACKED */ 137da25ae3cSDanylo Vodopianov }; 138da25ae3cSDanylo Vodopianov uint16_t vq_type; 139da25ae3cSDanylo Vodopianov }; 140da25ae3cSDanylo Vodopianov 141da25ae3cSDanylo Vodopianov struct nthw_received_packets { 142da25ae3cSDanylo Vodopianov void *addr; 143da25ae3cSDanylo Vodopianov uint32_t len; 144da25ae3cSDanylo Vodopianov }; 145b0cd36e9SDanylo Vodopianov 146b0cd36e9SDanylo Vodopianov #endif /* __NTOSS_VIRT_QUEUE_H__ */ 147