1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* Copyright (C) 2018-2025, Advanced Micro Devices, Inc. */ 3 4 #ifndef _IONIC_QUEUE_H_ 5 #define _IONIC_QUEUE_H_ 6 7 #include <linux/io.h> 8 #include <ionic_regs.h> 9 10 #define IONIC_MAX_DEPTH 0xffff 11 #define IONIC_MAX_CQ_DEPTH 0xffff 12 #define IONIC_CQ_RING_ARM IONIC_DBELL_RING_1 13 #define IONIC_CQ_RING_SOL IONIC_DBELL_RING_2 14 15 /** 16 * struct ionic_queue - Ring buffer used between device and driver 17 * @size: Size of the buffer, in bytes 18 * @dma: Dma address of the buffer 19 * @ptr: Buffer virtual address 20 * @prod: Driver position in the queue 21 * @cons: Device position in the queue 22 * @mask: Capacity of the queue, subtracting the hole 23 * This value is equal to ((1 << depth_log2) - 1) 24 * @depth_log2: Log base two size depth of the queue 25 * @stride_log2: Log base two size of an element in the queue 26 * @dbell: Doorbell identifying bits 27 */ 28 struct ionic_queue { 29 size_t size; 30 dma_addr_t dma; 31 void *ptr; 32 u16 prod; 33 u16 cons; 34 u16 mask; 35 u8 depth_log2; 36 u8 stride_log2; 37 u64 dbell; 38 }; 39 40 /** 41 * ionic_queue_init() - Initialize user space queue 42 * @q: Uninitialized queue structure 43 * @dma_dev: DMA device for mapping 44 * @depth: Depth of the queue 45 * @stride: Size of each element of the queue 46 * 47 * Return: status code 48 */ 49 int ionic_queue_init(struct ionic_queue *q, struct device *dma_dev, 50 int depth, size_t stride); 51 52 /** 53 * ionic_queue_destroy() - Destroy user space queue 54 * @q: Queue structure 55 * @dma_dev: DMA device for mapping 56 * 57 * Return: status code 58 */ 59 void ionic_queue_destroy(struct ionic_queue *q, struct device *dma_dev); 60 61 /** 62 * ionic_queue_empty() - Test if queue is empty 63 * @q: Queue structure 64 * 65 * This is only valid for to-device queues. 66 * 67 * Return: is empty 68 */ 69 static inline bool ionic_queue_empty(struct ionic_queue *q) 70 { 71 return q->prod == q->cons; 72 } 73 74 /** 75 * ionic_queue_length() - Get the current length of the queue 76 * @q: Queue structure 77 * 78 * This is only valid for to-device queues. 79 * 80 * Return: length 81 */ 82 static inline u16 ionic_queue_length(struct ionic_queue *q) 83 { 84 return (q->prod - q->cons) & q->mask; 85 } 86 87 /** 88 * ionic_queue_length_remaining() - Get the remaining length of the queue 89 * @q: Queue structure 90 * 91 * This is only valid for to-device queues. 92 * 93 * Return: length remaining 94 */ 95 static inline u16 ionic_queue_length_remaining(struct ionic_queue *q) 96 { 97 return q->mask - ionic_queue_length(q); 98 } 99 100 /** 101 * ionic_queue_full() - Test if queue is full 102 * @q: Queue structure 103 * 104 * This is only valid for to-device queues. 105 * 106 * Return: is full 107 */ 108 static inline bool ionic_queue_full(struct ionic_queue *q) 109 { 110 return q->mask == ionic_queue_length(q); 111 } 112 113 /** 114 * ionic_color_wrap() - Flip the color if prod is wrapped 115 * @prod: Queue index just after advancing 116 * @color: Queue color just prior to advancing the index 117 * 118 * Return: color after advancing the index 119 */ 120 static inline bool ionic_color_wrap(u16 prod, bool color) 121 { 122 /* logical xor color with (prod == 0) */ 123 return color != (prod == 0); 124 } 125 126 /** 127 * ionic_queue_at() - Get the element at the given index 128 * @q: Queue structure 129 * @idx: Index in the queue 130 * 131 * The index must be within the bounds of the queue. It is not checked here. 132 * 133 * Return: pointer to element at index 134 */ 135 static inline void *ionic_queue_at(struct ionic_queue *q, u16 idx) 136 { 137 return q->ptr + ((unsigned long)idx << q->stride_log2); 138 } 139 140 /** 141 * ionic_queue_at_prod() - Get the element at the producer index 142 * @q: Queue structure 143 * 144 * Return: pointer to element at producer index 145 */ 146 static inline void *ionic_queue_at_prod(struct ionic_queue *q) 147 { 148 return ionic_queue_at(q, q->prod); 149 } 150 151 /** 152 * ionic_queue_at_cons() - Get the element at the consumer index 153 * @q: Queue structure 154 * 155 * Return: pointer to element at consumer index 156 */ 157 static inline void *ionic_queue_at_cons(struct ionic_queue *q) 158 { 159 return ionic_queue_at(q, q->cons); 160 } 161 162 /** 163 * ionic_queue_next() - Compute the next index 164 * @q: Queue structure 165 * @idx: Index 166 * 167 * Return: next index after idx 168 */ 169 static inline u16 ionic_queue_next(struct ionic_queue *q, u16 idx) 170 { 171 return (idx + 1) & q->mask; 172 } 173 174 /** 175 * ionic_queue_produce() - Increase the producer index 176 * @q: Queue structure 177 * 178 * Caller must ensure that the queue is not full. It is not checked here. 179 */ 180 static inline void ionic_queue_produce(struct ionic_queue *q) 181 { 182 q->prod = ionic_queue_next(q, q->prod); 183 } 184 185 /** 186 * ionic_queue_consume() - Increase the consumer index 187 * @q: Queue structure 188 * 189 * Caller must ensure that the queue is not empty. It is not checked here. 190 * 191 * This is only valid for to-device queues. 192 */ 193 static inline void ionic_queue_consume(struct ionic_queue *q) 194 { 195 q->cons = ionic_queue_next(q, q->cons); 196 } 197 198 /** 199 * ionic_queue_consume_entries() - Increase the consumer index by entries 200 * @q: Queue structure 201 * @entries: Number of entries to increment 202 * 203 * Caller must ensure that the queue is not empty. It is not checked here. 204 * 205 * This is only valid for to-device queues. 206 */ 207 static inline void ionic_queue_consume_entries(struct ionic_queue *q, 208 u16 entries) 209 { 210 q->cons = (q->cons + entries) & q->mask; 211 } 212 213 /** 214 * ionic_queue_dbell_init() - Initialize doorbell bits for queue id 215 * @q: Queue structure 216 * @qid: Queue identifying number 217 */ 218 static inline void ionic_queue_dbell_init(struct ionic_queue *q, u32 qid) 219 { 220 q->dbell = IONIC_DBELL_QID(qid); 221 } 222 223 /** 224 * ionic_queue_dbell_val() - Get current doorbell update value 225 * @q: Queue structure 226 * 227 * Return: current doorbell update value 228 */ 229 static inline u64 ionic_queue_dbell_val(struct ionic_queue *q) 230 { 231 return q->dbell | q->prod; 232 } 233 234 #endif /* _IONIC_QUEUE_H_ */ 235