Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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_ */