xref: /linux/drivers/infiniband/hw/ionic/ionic_queue.h (revision 6093a688a07da07808f0122f9aa2a3eed250d853)
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