at master 5.6 kB view raw
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 */ 28struct 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 */ 49int 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 */ 59void 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 */ 69static 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 */ 82static 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 */ 95static 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 */ 108static 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 */ 120static 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 */ 135static 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 */ 146static 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 */ 157static 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 */ 169static 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 */ 180static 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 */ 193static 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 */ 207static 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 */ 218static 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 */ 229static inline u64 ionic_queue_dbell_val(struct ionic_queue *q) 230{ 231 return q->dbell | q->prod; 232} 233 234#endif /* _IONIC_QUEUE_H_ */