1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2025 Intel Corporation */
3
4 #include <linux/bitfield.h>
5 #include <net/libeth/rx.h>
6
7 #include <linux/net/intel/libie/controlq.h>
8
9 #define LIBIE_CTLQ_DESC_QWORD0(sz) \
10 (LIBIE_CTLQ_DESC_FLAG_BUF | \
11 LIBIE_CTLQ_DESC_FLAG_RD | \
12 FIELD_PREP(LIBIE_CTLQ_DESC_DATA_LEN, sz))
13
14 /**
15 * libie_ctlq_free_fq - free fill queue resources, including buffers
16 * @ctlq: Rx control queue whose resources need to be freed
17 */
libie_ctlq_free_fq(struct libie_ctlq_info * ctlq)18 static void libie_ctlq_free_fq(struct libie_ctlq_info *ctlq)
19 {
20 struct libeth_fq fq = {
21 .fqes = ctlq->rx_fqes,
22 .pp = ctlq->pp,
23 };
24
25 for (u32 ntc = ctlq->next_to_clean; ntc != ctlq->next_to_post; ) {
26 page_pool_put_full_netmem(fq.pp, fq.fqes[ntc].netmem, false);
27
28 if (++ntc >= ctlq->ring_len)
29 ntc = 0;
30 }
31
32 libeth_rx_fq_destroy(&fq);
33 }
34
35 /**
36 * libie_ctlq_init_fq - initialize fill queue for an Rx controlq
37 * @ctlq: control queue that needs Rx buffer allocation
38 *
39 * Return: %0 on success, -%errno on failure
40 */
libie_ctlq_init_fq(struct libie_ctlq_info * ctlq)41 static int libie_ctlq_init_fq(struct libie_ctlq_info *ctlq)
42 {
43 struct libeth_fq fq = {
44 .count = ctlq->ring_len,
45 .truesize = LIBIE_CTLQ_MAX_BUF_LEN,
46 .nid = NUMA_NO_NODE,
47 .type = LIBETH_FQE_SHORT,
48 .hsplit = true,
49 .no_napi = true,
50 };
51 int err;
52
53 err = libeth_rx_fq_create(&fq, ctlq->dev);
54 if (err)
55 return err;
56
57 ctlq->pp = fq.pp;
58 ctlq->rx_fqes = fq.fqes;
59 ctlq->truesize = fq.truesize;
60
61 return 0;
62 }
63
64 /**
65 * libie_ctlq_prep_rx_desc - prepare the descriptor with a new address
66 * @desc: descriptor to (re)initialize
67 * @addr: physical address to put into descriptor
68 * @mem_truesize: size of the accessible memory
69 */
libie_ctlq_prep_rx_desc(struct libie_ctlq_desc * desc,dma_addr_t addr,u32 mem_truesize)70 static void libie_ctlq_prep_rx_desc(struct libie_ctlq_desc *desc,
71 dma_addr_t addr, u32 mem_truesize)
72 {
73 u64 qword;
74
75 qword = LIBIE_CTLQ_DESC_QWORD0(mem_truesize);
76 desc->qword0 = cpu_to_le64(qword);
77
78 qword = FIELD_PREP(LIBIE_CTLQ_DESC_DATA_ADDR_HIGH,
79 upper_32_bits(addr)) |
80 FIELD_PREP(LIBIE_CTLQ_DESC_DATA_ADDR_LOW,
81 lower_32_bits(addr));
82 desc->qword3 = cpu_to_le64(qword);
83 }
84
85 /**
86 * libie_ctlq_post_rx_buffs - post buffers to descriptor ring
87 * @ctlq: control queue that requires Rx descriptor ring to be initialized with
88 * new Rx buffers
89 *
90 * The caller must make sure that calls to libie_ctlq_post_rx_buffs()
91 * and libie_ctlq_recv() for each queue are either serialized
92 * or used under ctlq->lock.
93 *
94 * Return: %0 on success, -%ENOMEM if any buffer could not be allocated
95 */
libie_ctlq_post_rx_buffs(struct libie_ctlq_info * ctlq)96 int libie_ctlq_post_rx_buffs(struct libie_ctlq_info *ctlq)
97 {
98 u32 ntp = ctlq->next_to_post, ntc = ctlq->next_to_clean, num_to_post;
99 const struct libeth_fq_fp fq = {
100 .pp = ctlq->pp,
101 .fqes = ctlq->rx_fqes,
102 .truesize = ctlq->truesize,
103 .count = ctlq->ring_len,
104 };
105 int ret = 0;
106
107 num_to_post = (ntc > ntp ? 0 : ctlq->ring_len) + ntc - ntp - 1;
108
109 while (num_to_post--) {
110 dma_addr_t addr;
111
112 ctlq->descs[ntp] = (struct libie_ctlq_desc) {};
113
114 addr = libeth_rx_alloc(&fq, ntp);
115 if (unlikely(addr == DMA_MAPPING_ERROR)) {
116 ret = -ENOMEM;
117 goto post_bufs;
118 }
119
120 libie_ctlq_prep_rx_desc(&ctlq->descs[ntp], addr, fq.truesize);
121
122 if (unlikely(++ntp == ctlq->ring_len))
123 ntp = 0;
124 }
125
126 post_bufs:
127 if (likely(ctlq->next_to_post != ntp)) {
128 ctlq->next_to_post = ntp;
129
130 dma_wmb();
131 writel(ntp, ctlq->reg.tail);
132 }
133
134 return ret;
135 }
136 EXPORT_SYMBOL_NS_GPL(libie_ctlq_post_rx_buffs, "LIBIE_CP");
137
138 /**
139 * libie_ctlq_free_tx_msgs - Free Tx control queue messages
140 * @ctlq: Tx control queue being destroyed
141 * @num_msgs: number of messages allocated so far
142 */
libie_ctlq_free_tx_msgs(struct libie_ctlq_info * ctlq,u32 num_msgs)143 static void libie_ctlq_free_tx_msgs(struct libie_ctlq_info *ctlq,
144 u32 num_msgs)
145 {
146 for (u32 i = 0; i < num_msgs; i++)
147 kfree(ctlq->tx_msg[i]);
148
149 kvfree(ctlq->tx_msg);
150 }
151
152 /**
153 * libie_ctlq_alloc_tx_msgs - Allocate Tx control queue messages
154 * @ctlq: Tx control queue being created
155 *
156 * Return: %0 on success, -%ENOMEM on allocation error
157 */
libie_ctlq_alloc_tx_msgs(struct libie_ctlq_info * ctlq)158 static int libie_ctlq_alloc_tx_msgs(struct libie_ctlq_info *ctlq)
159 {
160 ctlq->tx_msg = kvzalloc_objs(*ctlq->tx_msg, ctlq->ring_len);
161 if (!ctlq->tx_msg)
162 return -ENOMEM;
163
164 for (u32 i = 0; i < ctlq->ring_len; i++) {
165 ctlq->tx_msg[i] = kzalloc_obj(*ctlq->tx_msg[i]);
166 if (!ctlq->tx_msg[i]) {
167 libie_ctlq_free_tx_msgs(ctlq, i);
168 return -ENOMEM;
169 }
170 }
171
172 return 0;
173 }
174
175 /**
176 * libie_cp_free_desc_mem - free the previously allocated descriptor DMA memory
177 * @dev: device information
178 * @mem: DMA memory information
179 */
libie_cp_free_desc_mem(struct device * dev,struct libie_cp_dma_mem * mem)180 static void libie_cp_free_desc_mem(struct device *dev,
181 struct libie_cp_dma_mem *mem)
182 {
183 dma_free_coherent(dev, mem->size, mem->va, mem->pa);
184 mem->va = NULL;
185 }
186
187 /**
188 * libie_ctlq_dealloc_ring_res - free memory allocated for control queue
189 * @ctlq: control queue that requires its ring memory to be freed
190 *
191 * Free the memory used by the ring, buffers and other related structures.
192 */
libie_ctlq_dealloc_ring_res(struct libie_ctlq_info * ctlq)193 static void libie_ctlq_dealloc_ring_res(struct libie_ctlq_info *ctlq)
194 {
195 struct libie_cp_dma_mem *dma = &ctlq->ring_mem;
196
197 if (ctlq->type == LIBIE_CTLQ_TYPE_TX)
198 libie_ctlq_free_tx_msgs(ctlq, ctlq->ring_len);
199 else
200 libie_ctlq_free_fq(ctlq);
201
202 libie_cp_free_desc_mem(ctlq->dev, dma);
203 }
204
205 /**
206 * libie_cp_alloc_desc_mem - allocate DMA memory for descriptor ring
207 * @dev: device information
208 * @mem: memory for DMA information to be stored
209 * @size: size of the memory to allocate
210 *
211 * Return: virtual address of DMA memory or NULL.
212 */
libie_cp_alloc_desc_mem(struct device * dev,struct libie_cp_dma_mem * mem,u32 size)213 static void *libie_cp_alloc_desc_mem(struct device *dev,
214 struct libie_cp_dma_mem *mem, u32 size)
215 {
216 size = LARGEST_ALIGN(size);
217
218 mem->va = dma_alloc_coherent(dev, size, &mem->pa, GFP_KERNEL);
219 mem->size = size;
220 mem->direction = DMA_BIDIRECTIONAL;
221
222 return mem->va;
223 }
224
225 /**
226 * libie_ctlq_alloc_queue_res - allocate memory for descriptor ring and bufs
227 * @ctlq: control queue that requires its ring resources to be allocated
228 *
229 * Return: %0 on success, -%errno on failure
230 */
libie_ctlq_alloc_queue_res(struct libie_ctlq_info * ctlq)231 static int libie_ctlq_alloc_queue_res(struct libie_ctlq_info *ctlq)
232 {
233 size_t size = array_size(ctlq->ring_len, sizeof(*ctlq->descs));
234 struct libie_cp_dma_mem *dma = &ctlq->ring_mem;
235 int err = -ENOMEM;
236
237 if (!libie_cp_alloc_desc_mem(ctlq->dev, dma, size))
238 return -ENOMEM;
239
240 ctlq->descs = dma->va;
241
242 if (ctlq->type == LIBIE_CTLQ_TYPE_TX) {
243 if (libie_ctlq_alloc_tx_msgs(ctlq))
244 goto free_dma_mem;
245 } else {
246 err = libie_ctlq_init_fq(ctlq);
247 if (err)
248 goto free_dma_mem;
249
250 err = libie_ctlq_post_rx_buffs(ctlq);
251 if (err) {
252 libie_ctlq_free_fq(ctlq);
253 goto free_dma_mem;
254 }
255 }
256
257 return 0;
258
259 free_dma_mem:
260 libie_cp_free_desc_mem(ctlq->dev, dma);
261
262 return err;
263 }
264
265 /**
266 * libie_ctlq_init_regs - Initialize control queue registers
267 * @ctlq: control queue that needs to be initialized
268 *
269 * Initialize registers. The caller is expected to have already initialized the
270 * descriptor ring memory and buffer memory.
271 */
libie_ctlq_init_regs(struct libie_ctlq_info * ctlq)272 static void libie_ctlq_init_regs(struct libie_ctlq_info *ctlq)
273 {
274 u32 dword;
275
276 if (ctlq->type == LIBIE_CTLQ_TYPE_RX)
277 writel(ctlq->ring_len - 1, ctlq->reg.tail);
278 else
279 writel(0, ctlq->reg.tail);
280
281 writel(0, ctlq->reg.head);
282 writel(lower_32_bits(ctlq->ring_mem.pa), ctlq->reg.addr_low);
283 writel(upper_32_bits(ctlq->ring_mem.pa), ctlq->reg.addr_high);
284
285 dword = FIELD_PREP(LIBIE_CTLQ_MBX_ATQ_LEN, ctlq->ring_len) |
286 ctlq->reg.len_ena_mask;
287 writel(dword, ctlq->reg.len);
288 }
289
290 /**
291 * libie_find_ctlq - find the controlq for the given id and type
292 * @ctx: libie CP context information
293 * @type: type of controlq to find
294 * @id: controlq id to find
295 *
296 * Return: control queue info pointer on success, NULL on failure
297 */
libie_find_ctlq(struct libie_ctlq_ctx * ctx,enum libie_ctlq_type type,int id)298 struct libie_ctlq_info *libie_find_ctlq(struct libie_ctlq_ctx *ctx,
299 enum libie_ctlq_type type,
300 int id)
301 {
302 struct libie_ctlq_info *cq;
303
304 guard(spinlock)(&ctx->ctlqs_lock);
305
306 list_for_each_entry(cq, &ctx->ctlqs, list)
307 if (cq->qid == id && cq->type == type)
308 return cq;
309
310 return NULL;
311 }
312 EXPORT_SYMBOL_NS_GPL(libie_find_ctlq, "LIBIE_CP");
313
314 /**
315 * libie_ctlq_add - add one control queue
316 * @ctx: libie CP context information
317 * @qinfo: information required for queue creation
318 *
319 * Allocate and initialize a control queue and add it to the control queue list.
320 * libie_ctlq_init() must be called prior to any calls to libie_ctlq_add.
321 *
322 * Return: added control queue info pointer on success, error pointer on failure
323 */
324 static struct libie_ctlq_info *
libie_ctlq_add(struct libie_ctlq_ctx * ctx,const struct libie_ctlq_create_info * qinfo)325 libie_ctlq_add(struct libie_ctlq_ctx *ctx,
326 const struct libie_ctlq_create_info *qinfo)
327 {
328 struct libie_ctlq_info *ctlq;
329 int err;
330
331 if (qinfo->id != LIBIE_CTLQ_MBX_ID)
332 return ERR_PTR(-EOPNOTSUPP);
333
334 if (qinfo->len > FIELD_MAX(LIBIE_CTLQ_MBX_ATQ_LEN) || !qinfo->len)
335 return ERR_PTR(-EINVAL);
336
337 ctlq = kvzalloc_obj(*ctlq);
338 if (!ctlq)
339 return ERR_PTR(-ENOMEM);
340
341 ctlq->type = qinfo->type;
342 ctlq->qid = qinfo->id;
343 ctlq->ring_len = qinfo->len;
344 ctlq->dev = &ctx->mmio_info.pdev->dev;
345 ctlq->reg = qinfo->reg;
346
347 err = libie_ctlq_alloc_queue_res(ctlq);
348 if (err) {
349 kvfree(ctlq);
350 return ERR_PTR(err);
351 }
352
353 libie_ctlq_init_regs(ctlq);
354
355 spin_lock_init(&ctlq->lock);
356
357 scoped_guard(spinlock, &ctx->ctlqs_lock)
358 list_add(&ctlq->list, &ctx->ctlqs);
359
360 return ctlq;
361 }
362
363 /**
364 * libie_ctlq_remove - deallocate and remove specified control queue
365 * @ctx: libie CP context information
366 * @ctlq: specific control queue that needs to be removed
367 */
libie_ctlq_remove(struct libie_ctlq_ctx * ctx,struct libie_ctlq_info * ctlq)368 static void libie_ctlq_remove(struct libie_ctlq_ctx *ctx,
369 struct libie_ctlq_info *ctlq)
370 {
371 scoped_guard(spinlock, &ctx->ctlqs_lock)
372 list_del(&ctlq->list);
373
374 libie_ctlq_dealloc_ring_res(ctlq);
375 kvfree(ctlq);
376 }
377
378 /**
379 * libie_ctlq_init - main initialization routine for all control queues
380 * @ctx: libie CP context information
381 * @qinfo: array of structs containing info for each queue to be initialized
382 * @numq: number of queues to initialize
383 *
384 * This initializes queue list and adds any number and any type of control
385 * queues. This is an all or nothing routine; if one fails, all previously
386 * allocated queues will be destroyed.
387 *
388 * Please note that any control queue send/receive functions are not
389 * softirq/NAPI safe, and therefore API can be used in process context only.
390 *
391 * Return: %0 on success, -%errno on failure
392 */
libie_ctlq_init(struct libie_ctlq_ctx * ctx,const struct libie_ctlq_create_info * qinfo,u32 numq)393 int libie_ctlq_init(struct libie_ctlq_ctx *ctx,
394 const struct libie_ctlq_create_info *qinfo,
395 u32 numq)
396 {
397 INIT_LIST_HEAD(&ctx->ctlqs);
398 spin_lock_init(&ctx->ctlqs_lock);
399
400 for (u32 i = 0; i < numq; i++) {
401 struct libie_ctlq_info *ctlq;
402
403 ctlq = libie_ctlq_add(ctx, &qinfo[i]);
404 if (IS_ERR(ctlq)) {
405 libie_ctlq_deinit(ctx);
406 return PTR_ERR(ctlq);
407 }
408 }
409
410 return 0;
411 }
412 EXPORT_SYMBOL_NS_GPL(libie_ctlq_init, "LIBIE_CP");
413
414 /**
415 * libie_ctlq_deinit - destroy all control queues
416 * @ctx: libie CP context information
417 */
libie_ctlq_deinit(struct libie_ctlq_ctx * ctx)418 void libie_ctlq_deinit(struct libie_ctlq_ctx *ctx)
419 {
420 struct libie_ctlq_info *ctlq, *tmp;
421
422 list_for_each_entry_safe(ctlq, tmp, &ctx->ctlqs, list)
423 libie_ctlq_remove(ctx, ctlq);
424 }
425 EXPORT_SYMBOL_NS_GPL(libie_ctlq_deinit, "LIBIE_CP");
426
427 /**
428 * libie_ctlq_tx_desc_from_msg - initialize a Tx descriptor from a message
429 * @desc: descriptor to be initialized
430 * @msg: filled control queue message
431 */
libie_ctlq_tx_desc_from_msg(struct libie_ctlq_desc * desc,const struct libie_ctlq_msg * msg)432 static void libie_ctlq_tx_desc_from_msg(struct libie_ctlq_desc *desc,
433 const struct libie_ctlq_msg *msg)
434 {
435 const struct libie_cp_dma_mem *dma = &msg->send_mem;
436 u64 qword;
437
438 qword = FIELD_PREP(LIBIE_CTLQ_DESC_FLAGS, msg->flags) |
439 FIELD_PREP(LIBIE_CTLQ_DESC_INFRA_OPCODE, msg->opcode) |
440 FIELD_PREP(LIBIE_CTLQ_DESC_PFID_VFID, msg->func_id);
441 desc->qword0 = cpu_to_le64(qword);
442
443 qword = FIELD_PREP(LIBIE_CTLQ_DESC_VIRTCHNL_OPCODE,
444 msg->chnl_opcode) |
445 FIELD_PREP(LIBIE_CTLQ_DESC_VIRTCHNL_MSG_RET_VAL,
446 msg->chnl_retval);
447 desc->qword1 = cpu_to_le64(qword);
448
449 qword = FIELD_PREP(LIBIE_CTLQ_DESC_MSG_PARAM0, msg->param0) |
450 FIELD_PREP(LIBIE_CTLQ_DESC_SW_COOKIE,
451 msg->sw_cookie) |
452 FIELD_PREP(LIBIE_CTLQ_DESC_VIRTCHNL_FLAGS,
453 msg->virt_flags);
454 desc->qword2 = cpu_to_le64(qword);
455
456 if (likely(msg->data_len)) {
457 desc->qword0 |=
458 cpu_to_le64(LIBIE_CTLQ_DESC_QWORD0(msg->data_len));
459 qword = FIELD_PREP(LIBIE_CTLQ_DESC_DATA_ADDR_HIGH,
460 upper_32_bits(dma->pa)) |
461 FIELD_PREP(LIBIE_CTLQ_DESC_DATA_ADDR_LOW,
462 lower_32_bits(dma->pa));
463 } else {
464 qword = msg->addr_param;
465 }
466
467 desc->qword3 = cpu_to_le64(qword);
468 }
469
470 /**
471 * libie_ctlq_send_desc_avail - get number of free descriptors on a Tx ctlq
472 * @ctlq: specific control queue which is going be used for sending messages
473 *
474 * The caller must hold ctlq->lock. Any dependent sending must be done
475 * in the same critical section.
476 *
477 * Return: number of available descriptors/messages on a given control queue.
478 */
libie_ctlq_send_desc_avail(const struct libie_ctlq_info * ctlq)479 u32 libie_ctlq_send_desc_avail(const struct libie_ctlq_info *ctlq)
480 {
481 u32 ntu = ctlq->next_to_use, ntc = ctlq->next_to_clean;
482
483 lockdep_assert_held(&ctlq->lock);
484
485 return (ntc > ntu ? 0 : ctlq->ring_len) + ntc - ntu - 1;
486 }
487 EXPORT_SYMBOL_NS_GPL(libie_ctlq_send_desc_avail, "LIBIE_CP");
488
489 /**
490 * libie_ctlq_send - send a message to Control Plane or Peer
491 * @ctlq: specific control queue which is used for sending a message
492 * @num_q_msg: number of messages present to send on @ctlq,
493 * positive and no greater than the number of available descriptors
494 *
495 * The caller must fill in @num_q_msg Tx messages starting at ntu beforehand.
496 *
497 * The caller must hold ctlq->lock. The intended pattern is to first check
498 * the number of descriptors available, then fill in the messages and perform
499 * send within a single critical section.
500 */
libie_ctlq_send(struct libie_ctlq_info * ctlq,u32 num_q_msg)501 void libie_ctlq_send(struct libie_ctlq_info *ctlq, u32 num_q_msg)
502 {
503 u32 ntu = ctlq->next_to_use;
504
505 lockdep_assert_held(&ctlq->lock);
506
507 for (int i = 0; i < num_q_msg; i++) {
508 struct libie_ctlq_msg *msg = ctlq->tx_msg[ntu];
509 struct libie_ctlq_desc *desc;
510
511 desc = &ctlq->descs[ntu];
512 libie_ctlq_tx_desc_from_msg(desc, msg);
513
514 if (unlikely(++ntu == ctlq->ring_len))
515 ntu = 0;
516 }
517 dma_wmb();
518 writel(ntu, ctlq->reg.tail);
519 ctlq->next_to_use = ntu;
520 }
521 EXPORT_SYMBOL_NS_GPL(libie_ctlq_send, "LIBIE_CP");
522
523 /**
524 * libie_ctlq_send_clean - cleanup the send control queue message buffers
525 * @params: information for handling of Tx completions
526 *
527 * Cleanup the send buffers for the given control queue, if force is set, then
528 * clear all the outstanding send messages irrespective of their send status,
529 * until a zero-length message is encountered, which is either a message that
530 * is already cleared, or a VF reset message, which is always last.
531 * Force should be used during deinit or reset.
532 *
533 * Return: number of send buffers cleaned.
534 */
libie_ctlq_send_clean(const struct libie_ctlq_clean_params * params)535 u32 libie_ctlq_send_clean(const struct libie_ctlq_clean_params *params)
536 {
537 struct libie_ctlq_info *ctlq = params->ctlq;
538 u32 ntc, i;
539
540 spin_lock(&ctlq->lock);
541 ntc = ctlq->next_to_clean;
542
543 for (i = 0; i < params->num_msgs; i++) {
544 struct libie_ctlq_msg *msg = ctlq->tx_msg[ntc];
545 struct libie_ctlq_desc *desc;
546 u64 qword;
547
548 desc = &ctlq->descs[ntc];
549 qword = le64_to_cpu(desc->qword0);
550
551 if (!FIELD_GET(LIBIE_CTLQ_DESC_FLAG_DD, qword) &&
552 !(unlikely(params->force) && msg->data_len))
553 break;
554
555 /* This cannot be reordered and lock is taken, so no barriers */
556 desc->qword0 = 0;
557
558 params->rel_dma_mem(params->rel_ctx, &msg->send_mem);
559 memset(msg, 0, sizeof(*msg));
560
561 if (unlikely(++ntc == ctlq->ring_len))
562 ntc = 0;
563 }
564
565 ctlq->next_to_clean = ntc;
566 spin_unlock(&ctlq->lock);
567
568 return i;
569 }
570 EXPORT_SYMBOL_NS_GPL(libie_ctlq_send_clean, "LIBIE_CP");
571
572 /**
573 * libie_ctlq_fill_rx_msg - fill in a message from Rx descriptor and buffer
574 * @msg: message to be filled in
575 * @desc: received descriptor
576 * @rx_buf: fill queue buffer associated with the descriptor
577 */
libie_ctlq_fill_rx_msg(struct libie_ctlq_msg * msg,const struct libie_ctlq_desc * desc,struct libeth_fqe * rx_buf)578 static void libie_ctlq_fill_rx_msg(struct libie_ctlq_msg *msg,
579 const struct libie_ctlq_desc *desc,
580 struct libeth_fqe *rx_buf)
581 {
582 u64 qword = le64_to_cpu(desc->qword0);
583
584 msg->flags = FIELD_GET(LIBIE_CTLQ_DESC_FLAGS, qword);
585 msg->opcode = FIELD_GET(LIBIE_CTLQ_DESC_INFRA_OPCODE, qword);
586 msg->data_len = FIELD_GET(LIBIE_CTLQ_DESC_DATA_LEN, qword);
587 msg->hw_retval = FIELD_GET(LIBIE_CTLQ_DESC_HW_RETVAL, qword);
588
589 qword = le64_to_cpu(desc->qword1);
590 msg->chnl_opcode =
591 FIELD_GET(LIBIE_CTLQ_DESC_VIRTCHNL_OPCODE, qword);
592 msg->chnl_retval =
593 FIELD_GET(LIBIE_CTLQ_DESC_VIRTCHNL_MSG_RET_VAL, qword);
594
595 qword = le64_to_cpu(desc->qword2);
596 msg->param0 =
597 FIELD_GET(LIBIE_CTLQ_DESC_MSG_PARAM0, qword);
598 msg->sw_cookie =
599 FIELD_GET(LIBIE_CTLQ_DESC_SW_COOKIE, qword);
600 msg->virt_flags =
601 FIELD_GET(LIBIE_CTLQ_DESC_VIRTCHNL_FLAGS, qword);
602
603 if (likely(msg->data_len)) {
604 if (unlikely(msg->data_len > LIBIE_CTLQ_MAX_BUF_LEN)) {
605 msg->data_len = LIBIE_CTLQ_MAX_BUF_LEN;
606 msg->chnl_retval = U32_MAX;
607 }
608 msg->recv_mem = (struct kvec) {
609 .iov_base = netmem_address(rx_buf->netmem) +
610 rx_buf->offset,
611 .iov_len = msg->data_len,
612 };
613 libeth_rx_sync_for_cpu(rx_buf, msg->data_len);
614 } else {
615 msg->recv_mem = (struct kvec) {};
616 msg->addr_param = le64_to_cpu(desc->qword3);
617 page_pool_put_full_netmem(netmem_get_pp(rx_buf->netmem),
618 rx_buf->netmem, false);
619 }
620 }
621
622 /**
623 * libie_ctlq_recv - receive control queue messages
624 * @ctlq: control queue that needs to processed for receive
625 * @msg: array of received control queue messages on this q;
626 * needs to be pre-allocated by caller for as many messages as requested
627 * @num_q_msg: number of messages that can be stored in msg buffer,
628 * no greater than number of posted buffers
629 *
630 * Caller is expected to return buffers via libie_ctlq_release_rx_buf().
631 *
632 * The caller must make sure that calls to libie_ctlq_post_rx_buffs()
633 * and libie_ctlq_recv() for each queue are either serialized
634 * or used under ctlq->lock.
635 *
636 * Return: number of messages received
637 */
libie_ctlq_recv(struct libie_ctlq_info * ctlq,struct libie_ctlq_msg * msg,u32 num_q_msg)638 u32 libie_ctlq_recv(struct libie_ctlq_info *ctlq, struct libie_ctlq_msg *msg,
639 u32 num_q_msg)
640 {
641 u32 ntc, i;
642
643 ntc = ctlq->next_to_clean;
644
645 for (i = 0; i < num_q_msg; i++) {
646 struct libie_ctlq_desc *desc = &ctlq->descs[ntc];
647 struct libeth_fqe *rx_buf = &ctlq->rx_fqes[ntc];
648 u64 qword;
649
650 qword = le64_to_cpu(desc->qword0);
651 if (!FIELD_GET(LIBIE_CTLQ_DESC_FLAG_DD, qword))
652 break;
653
654 dma_rmb();
655
656 libie_ctlq_fill_rx_msg(&msg[i], desc, rx_buf);
657 desc->qword0 = 0;
658
659 if (unlikely(++ntc == ctlq->ring_len))
660 ntc = 0;
661 }
662
663 ctlq->next_to_clean = ntc;
664
665 return i;
666 }
667 EXPORT_SYMBOL_NS_GPL(libie_ctlq_recv, "LIBIE_CP");
668
669 /**
670 * libie_ctlq_xn_pop_free - get a free Xn entry from the free list
671 * @xnm: Xn transaction manager
672 *
673 * Retrieve a free Xn entry from the free list.
674 *
675 * Return: valid Xn entry pointer or NULL if there are no free Xn entries.
676 */
677 static struct libie_ctlq_xn *
libie_ctlq_xn_pop_free(struct libie_ctlq_xn_manager * xnm)678 libie_ctlq_xn_pop_free(struct libie_ctlq_xn_manager *xnm)
679 {
680 struct libie_ctlq_xn *xn;
681 u32 free_idx;
682
683 guard(spinlock)(&xnm->free_xns_bm_lock);
684
685 if (unlikely(xnm->shutdown))
686 return NULL;
687
688 for_each_set_bit(free_idx, xnm->free_xns_bm,
689 LIBIE_CTLQ_MAX_XN_ENTRIES) {
690 xn = &xnm->ring[free_idx];
691
692 /* Torn read of the physical address is possible, the worst case
693 * scenario is a transient spurious skip. If the physical
694 * address is dirty in any way, reuse is already safe.
695 */
696 if (xn->tx_msg &&
697 data_race(xn->tx_msg->send_mem.pa) == xn->small_dma_mem.pa)
698 continue;
699
700 clear_bit(free_idx, xnm->free_xns_bm);
701
702 return xn;
703 }
704
705 return NULL;
706 }
707
708 /**
709 * __libie_ctlq_xn_push_free - unsafely push an xn entry into the free list
710 * @xnm: Xn transaction manager
711 * @xn: xn entry to be added into the free list
712 *
713 * Return: whether xnm destruction can be triggered by the caller
714 */
__libie_ctlq_xn_push_free(struct libie_ctlq_xn_manager * xnm,struct libie_ctlq_xn * xn)715 static bool __libie_ctlq_xn_push_free(struct libie_ctlq_xn_manager *xnm,
716 struct libie_ctlq_xn *xn)
717 {
718 xn->cookie++;
719 set_bit(xn->index, xnm->free_xns_bm);
720
721 if (unlikely(xnm->shutdown) &&
722 bitmap_full(xnm->free_xns_bm, LIBIE_CTLQ_MAX_XN_ENTRIES))
723 return true;
724
725 return false;
726 }
727
728 /**
729 * libie_ctlq_xn_push_free - push a Xn entry into the free list
730 * @xnm: Xn transaction manager
731 * @xn: xn entry to be added into the free list, not locked
732 *
733 * Safely add a used Xn entry back to the free list.
734 */
libie_ctlq_xn_push_free(struct libie_ctlq_xn_manager * xnm,struct libie_ctlq_xn * xn)735 static void libie_ctlq_xn_push_free(struct libie_ctlq_xn_manager *xnm,
736 struct libie_ctlq_xn *xn)
737 {
738 bool can_destroy;
739
740 scoped_guard(spinlock, &xnm->free_xns_bm_lock)
741 can_destroy = __libie_ctlq_xn_push_free(xnm, xn);
742
743 if (can_destroy)
744 complete(&xnm->can_destroy);
745 }
746
747 /**
748 * libie_ctlq_xn_deinit_dma - free the DMA memory allocated for send messages
749 * @xnm: pointer to the transaction manager
750 * @num_entries: number of Xn entries to free the DMA for
751 */
libie_ctlq_xn_deinit_dma(struct libie_ctlq_xn_manager * xnm,u32 num_entries)752 static void libie_ctlq_xn_deinit_dma(struct libie_ctlq_xn_manager *xnm,
753 u32 num_entries)
754 {
755 for (u32 i = 0; i < num_entries; i++) {
756 struct libie_ctlq_xn *xn = &xnm->ring[i];
757
758 dma_pool_free(xnm->small_buff_pool, xn->small_dma_mem.va,
759 xn->small_dma_mem.pa);
760 }
761
762 dma_pool_destroy(xnm->small_buff_pool);
763 }
764
765 /**
766 * libie_ctlq_xn_init_dma - pre-allocate DMA memory for send messages that use
767 * stack variables
768 * @dev: device pointer
769 * @xnm: pointer to transaction manager
770 *
771 * Return: %0 on success or error if memory allocation fails
772 */
libie_ctlq_xn_init_dma(struct device * dev,struct libie_ctlq_xn_manager * xnm)773 static int libie_ctlq_xn_init_dma(struct device *dev,
774 struct libie_ctlq_xn_manager *xnm)
775 {
776 u32 i;
777
778 xnm->small_buff_pool =
779 dma_pool_create("libie_ctlq_xn_tx", dev, LIBIE_CP_TX_COPYBREAK,
780 LIBIE_CP_TX_COPYBREAK, 0);
781 if (!xnm->small_buff_pool)
782 return -ENOMEM;
783
784 for (i = 0; i < LIBIE_CTLQ_MAX_XN_ENTRIES; i++) {
785 struct libie_cp_dma_mem *mem = &xnm->ring[i].small_dma_mem;
786
787 mem->va = dma_pool_zalloc(xnm->small_buff_pool, GFP_KERNEL,
788 &mem->pa);
789 if (!mem->va)
790 goto dealloc_dma;
791
792 mem->direction = DMA_BIDIRECTIONAL;
793 mem->size = LIBIE_CP_TX_COPYBREAK;
794 }
795
796 return 0;
797
798 dealloc_dma:
799 libie_ctlq_xn_deinit_dma(xnm, i);
800
801 return -ENOMEM;
802 }
803
804 /**
805 * libie_ctlq_xn_process_recv - process Xn data in receive message
806 * @params: Xn receive param information to handle a receive message
807 * @ctlq_msg: received control queue message
808 *
809 * Process a control queue receive message and send a complete event
810 * notification.
811 *
812 * Return: true if a message has been processed, false otherwise.
813 */
814 static bool
libie_ctlq_xn_process_recv(struct libie_ctlq_xn_recv_params * params,struct libie_ctlq_msg * ctlq_msg)815 libie_ctlq_xn_process_recv(struct libie_ctlq_xn_recv_params *params,
816 struct libie_ctlq_msg *ctlq_msg)
817 {
818 struct libie_ctlq_xn_manager *xnm = params->xnm;
819 struct libie_ctlq_xn *xn;
820 u16 msg_cookie, xn_index;
821 struct kvec *response;
822 int status;
823 u16 data;
824
825 data = ctlq_msg->sw_cookie;
826 xn_index = FIELD_GET(LIBIE_CTLQ_XN_INDEX_M, data);
827 msg_cookie = FIELD_GET(LIBIE_CTLQ_XN_COOKIE_M, data);
828 status = ctlq_msg->chnl_retval ? -EFAULT : 0;
829
830 xn = &xnm->ring[xn_index];
831 spin_lock(&xn->xn_lock);
832 if (ctlq_msg->chnl_opcode != xn->virtchnl_opcode ||
833 msg_cookie != xn->cookie) {
834 spin_unlock(&xn->xn_lock);
835 return false;
836 }
837
838 if (xn->state != LIBIE_CTLQ_XN_ASYNC &&
839 xn->state != LIBIE_CTLQ_XN_WAITING) {
840 spin_unlock(&xn->xn_lock);
841 return false;
842 }
843
844 response = &ctlq_msg->recv_mem;
845 if (xn->state == LIBIE_CTLQ_XN_ASYNC) {
846 xn->resp_cb(xn->send_ctx, response, status);
847 libie_ctlq_release_rx_buf(response);
848 xn->state = LIBIE_CTLQ_XN_IDLE;
849 spin_unlock(&xn->xn_lock);
850 libie_ctlq_xn_push_free(xnm, xn);
851
852 return true;
853 }
854
855 xn->recv_mem = *response;
856 xn->state = status ? LIBIE_CTLQ_XN_COMPLETED_FAILED :
857 LIBIE_CTLQ_XN_COMPLETED_SUCCESS;
858
859 complete(&xn->cmd_completion_event);
860 spin_unlock(&xn->xn_lock);
861
862 return true;
863 }
864
865 /**
866 * libie_xn_check_async_timeout - Check for asynchronous message timeouts
867 * @xnm: Xn transaction manager
868 *
869 * Call the corresponding callback to notify the caller about the timeout.
870 * Iterates free_xns_bm locklessly, potential races are caught under
871 * xn->xn_lock.
872 */
libie_xn_check_async_timeout(struct libie_ctlq_xn_manager * xnm)873 static void libie_xn_check_async_timeout(struct libie_ctlq_xn_manager *xnm)
874 {
875 u32 idx;
876
877 for_each_clear_bit(idx, xnm->free_xns_bm, LIBIE_CTLQ_MAX_XN_ENTRIES) {
878 struct libie_ctlq_xn *xn = &xnm->ring[idx];
879 u64 timeout_ms;
880
881 spin_lock(&xn->xn_lock);
882
883 timeout_ms = ktime_ms_delta(ktime_get(), xn->timestamp);
884 if (xn->state != LIBIE_CTLQ_XN_ASYNC ||
885 timeout_ms < xn->timeout_ms) {
886 spin_unlock(&xn->xn_lock);
887 continue;
888 }
889
890 xn->resp_cb(xn->send_ctx, NULL, -ETIMEDOUT);
891 xn->state = LIBIE_CTLQ_XN_IDLE;
892 spin_unlock(&xn->xn_lock);
893 libie_ctlq_xn_push_free(xnm, xn);
894 }
895 }
896
897 /**
898 * libie_ctlq_xn_recv - process control queue receive message
899 * @params: Xn receive param information to handle a receive message
900 *
901 * Process a receive message and update the receive queue buffer.
902 * Also terminates async transactions for which it failed to receive a response
903 * within a given timeframe.
904 * Function is intended to be called periodically from a single task.
905 *
906 * Return: remaining budget.
907 */
libie_ctlq_xn_recv(struct libie_ctlq_xn_recv_params * params)908 u32 libie_ctlq_xn_recv(struct libie_ctlq_xn_recv_params *params)
909 {
910 struct libie_ctlq_msg ctlq_msg;
911 u32 budget = params->budget;
912
913 while (budget && libie_ctlq_recv(params->ctlq, &ctlq_msg, 1)) {
914 budget--;
915 if (!libie_ctlq_xn_process_recv(params, &ctlq_msg))
916 params->ctlq_msg_handler(params->xnm->ctx, &ctlq_msg);
917 }
918
919 libie_ctlq_post_rx_buffs(params->ctlq);
920 libie_xn_check_async_timeout(params->xnm);
921
922 return budget;
923 }
924 EXPORT_SYMBOL_NS_GPL(libie_ctlq_xn_recv, "LIBIE_CP");
925
926 /**
927 * libie_cp_map_dma_mem - map a given virtual address for DMA
928 * @dev: device information
929 * @va: virtual address to be mapped
930 * @size: size of the memory
931 * @direction: DMA direction either from/to device
932 * @dma_mem: memory for DMA information to be stored
933 *
934 * Return: true on success, false on DMA map failure.
935 */
libie_cp_map_dma_mem(struct device * dev,void * va,size_t size,int direction,struct libie_cp_dma_mem * dma_mem)936 static bool libie_cp_map_dma_mem(struct device *dev, void *va, size_t size,
937 int direction,
938 struct libie_cp_dma_mem *dma_mem)
939 {
940 dma_mem->pa = dma_map_single(dev, va, size, direction);
941
942 return dma_mapping_error(dev, dma_mem->pa) ? false : true;
943 }
944
945 /**
946 * libie_cp_unmap_dma_mem - unmap previously mapped DMA address
947 * @dev: device information
948 * @dma_mem: DMA memory information
949 */
libie_cp_unmap_dma_mem(struct device * dev,const struct libie_cp_dma_mem * dma_mem)950 static void libie_cp_unmap_dma_mem(struct device *dev,
951 const struct libie_cp_dma_mem *dma_mem)
952 {
953 dma_unmap_single(dev, dma_mem->pa, dma_mem->size,
954 dma_mem->direction);
955 }
956
957 /**
958 * libie_ctlq_xn_process_send - process and send a control queue message
959 * @params: Xn send param information for sending a control queue message
960 * @xn: Assigned Xn entry for tracking the control queue message
961 *
962 * Return: %0 on success, -%errno on failure.
963 */
964 static
libie_ctlq_xn_process_send(struct libie_ctlq_xn_send_params * params,struct libie_ctlq_xn * xn)965 int libie_ctlq_xn_process_send(struct libie_ctlq_xn_send_params *params,
966 struct libie_ctlq_xn *xn)
967 {
968 size_t buf_len = params->send_buf.iov_len;
969 struct device *dev = params->ctlq->dev;
970 void *buf = params->send_buf.iov_base;
971 struct libie_cp_dma_mem *dma_mem;
972 u16 cookie;
973
974 if (!buf || !buf_len)
975 return -EOPNOTSUPP;
976
977 if (libie_cp_can_send_onstack(buf_len)) {
978 dma_mem = &xn->small_dma_mem;
979 memcpy(dma_mem->va, buf, buf_len);
980 } else {
981 dma_mem = &xn->send_dma_mem;
982 dma_mem->va = buf;
983 dma_mem->size = buf_len;
984 dma_mem->direction = DMA_TO_DEVICE;
985
986 if (!libie_cp_map_dma_mem(dev, buf, buf_len, DMA_TO_DEVICE,
987 dma_mem))
988 return -ENOMEM;
989 }
990
991 cookie = FIELD_PREP(LIBIE_CTLQ_XN_COOKIE_M, xn->cookie) |
992 FIELD_PREP(LIBIE_CTLQ_XN_INDEX_M, xn->index);
993
994 scoped_guard(spinlock, ¶ms->ctlq->lock) {
995 struct libie_ctlq_info *ctlq = params->ctlq;
996 struct libie_ctlq_msg *ctlq_msg;
997
998 if (!libie_ctlq_send_desc_avail(ctlq)) {
999 if (!libie_cp_can_send_onstack(buf_len))
1000 libie_cp_unmap_dma_mem(dev, dma_mem);
1001
1002 return -EBUSY;
1003 }
1004
1005 ctlq_msg = ctlq->tx_msg[ctlq->next_to_use];
1006 xn->tx_msg = dma_mem == &xn->small_dma_mem ? ctlq_msg : NULL;
1007 if (params->ctlq_msg)
1008 *ctlq_msg = *params->ctlq_msg;
1009 else
1010 /* Unused ctlq messages are already zeroed */
1011 ctlq_msg->opcode = LIBIE_CTLQ_SEND_MSG_TO_CP;
1012
1013 ctlq_msg->sw_cookie = cookie;
1014 ctlq_msg->send_mem = *dma_mem;
1015 ctlq_msg->data_len = buf_len;
1016 ctlq_msg->chnl_opcode = params->chnl_opcode;
1017 libie_ctlq_send(params->ctlq, 1);
1018 }
1019
1020 return 0;
1021 }
1022
1023 /**
1024 * libie_ctlq_xn_send - send a control queue message, initiating a transaction
1025 * @params: Xn send param information for sending a control queue message
1026 *
1027 * Send a control queue (mailbox or config) message.
1028 * Based on the params value, the call can be completed synchronously or
1029 * asynchronously.
1030 *
1031 * Return: %0 on success, -%errno on failure.
1032 */
libie_ctlq_xn_send(struct libie_ctlq_xn_send_params * params)1033 int libie_ctlq_xn_send(struct libie_ctlq_xn_send_params *params)
1034 {
1035 bool free_send = !libie_cp_can_send_onstack(params->send_buf.iov_len);
1036 struct libie_ctlq_xn *xn;
1037 int ret;
1038
1039 if (params->send_buf.iov_len > LIBIE_CTLQ_MAX_BUF_LEN) {
1040 ret = -EINVAL;
1041 goto free_buf;
1042 }
1043
1044 xn = libie_ctlq_xn_pop_free(params->xnm);
1045 /* no free transactions available */
1046 if (unlikely(!xn)) {
1047 ret = -EAGAIN;
1048 goto free_buf;
1049 }
1050
1051 spin_lock(&xn->xn_lock);
1052 if (xn->state == LIBIE_CTLQ_XN_SHUTDOWN) {
1053 ret = -ENXIO;
1054 goto unlock_xn;
1055 }
1056
1057 xn->state = params->resp_cb ? LIBIE_CTLQ_XN_ASYNC :
1058 LIBIE_CTLQ_XN_WAITING;
1059 xn->virtchnl_opcode = params->chnl_opcode;
1060
1061 if (params->resp_cb) {
1062 xn->send_ctx = params->send_ctx;
1063 xn->resp_cb = params->resp_cb;
1064 xn->timeout_ms = params->timeout_ms;
1065 xn->timestamp = ktime_get();
1066 }
1067
1068 ret = libie_ctlq_xn_process_send(params, xn);
1069 if (ret)
1070 goto release_xn;
1071 else
1072 free_send = false;
1073
1074 spin_unlock(&xn->xn_lock);
1075
1076 if (params->resp_cb)
1077 return 0;
1078
1079 wait_for_completion_timeout(&xn->cmd_completion_event,
1080 msecs_to_jiffies(params->timeout_ms));
1081
1082 spin_lock(&xn->xn_lock);
1083 switch (xn->state) {
1084 case LIBIE_CTLQ_XN_WAITING:
1085 ret = -ETIMEDOUT;
1086 break;
1087 case LIBIE_CTLQ_XN_COMPLETED_SUCCESS:
1088 params->recv_mem = xn->recv_mem;
1089 break;
1090 default:
1091 ret = -EBADMSG;
1092 break;
1093 }
1094
1095 /* Free the receive buffer in case of failure. On timeout, receive
1096 * buffer is not allocated.
1097 */
1098 if (ret && ret != -ETIMEDOUT)
1099 libie_ctlq_release_rx_buf(&xn->recv_mem);
1100
1101 release_xn:
1102 xn->state = LIBIE_CTLQ_XN_IDLE;
1103 reinit_completion(&xn->cmd_completion_event);
1104 unlock_xn:
1105 spin_unlock(&xn->xn_lock);
1106 libie_ctlq_xn_push_free(params->xnm, xn);
1107 free_buf:
1108 if (free_send)
1109 params->rel_tx_buf(params->send_buf.iov_base);
1110
1111 return ret;
1112 }
1113 EXPORT_SYMBOL_NS_GPL(libie_ctlq_xn_send, "LIBIE_CP");
1114
1115 /**
1116 * struct libie_ctlq_xn_rel_tx_ctx - context needed to release xn Tx message
1117 * @dev: device for which DMA was mapped
1118 * @rel_tx_buf: freeing function for non-small buffers
1119 */
1120 struct libie_ctlq_xn_rel_tx_ctx {
1121 struct device *dev;
1122 void (*rel_tx_buf)(const void *buf_va);
1123 };
1124
1125 /**
1126 * libie_ctlq_xn_rel_tx_buf - release xn-controlled Tx message buffer
1127 * @ctx: context, namely DMA device and freeing function
1128 * @dma_mem: DMA memory to reclaim/unmap
1129 */
libie_ctlq_xn_rel_tx_buf(const void * ctx,struct libie_cp_dma_mem * dma_mem)1130 static void libie_ctlq_xn_rel_tx_buf(const void *ctx,
1131 struct libie_cp_dma_mem *dma_mem)
1132 {
1133 const struct libie_ctlq_xn_rel_tx_ctx *rel_ctx = ctx;
1134
1135 if (!libie_cp_can_send_onstack(dma_mem->size)) {
1136 libie_cp_unmap_dma_mem(rel_ctx->dev, dma_mem);
1137 rel_ctx->rel_tx_buf(dma_mem->va);
1138 }
1139 }
1140
1141 /**
1142 * libie_ctlq_xn_send_clean - clean xn-controlled Tx messages
1143 * @ctlq: control queue to clean
1144 * @rel_tx_buf: driver callback to free the buffer
1145 * @force: clean regardless of DD
1146 *
1147 * Return: number of completed/released messages.
1148 */
libie_ctlq_xn_send_clean(struct libie_ctlq_info * ctlq,void (* rel_tx_buf)(const void * buf_va),bool force)1149 u32 libie_ctlq_xn_send_clean(struct libie_ctlq_info *ctlq,
1150 void (*rel_tx_buf)(const void *buf_va),
1151 bool force)
1152 {
1153 struct libie_ctlq_xn_rel_tx_ctx rel_ctx = {
1154 .dev = ctlq->dev,
1155 .rel_tx_buf = rel_tx_buf,
1156 };
1157 struct libie_ctlq_clean_params params = {
1158 .ctlq = ctlq,
1159 .force = force,
1160 .num_msgs = ctlq->ring_len,
1161 .rel_ctx = &rel_ctx,
1162 .rel_dma_mem = libie_ctlq_xn_rel_tx_buf,
1163 };
1164
1165 return libie_ctlq_send_clean(¶ms);
1166 }
1167 EXPORT_SYMBOL_NS_GPL(libie_ctlq_xn_send_clean, "LIBIE_CP");
1168
1169 /**
1170 * libie_ctlq_xn_shutdown - terminate control queue transactions
1171 * @xnm: pointer to the transaction manager
1172 *
1173 * Synchronously terminate existing transactions and stop accepting new ones.
1174 * Async transactions are discarded without invoking resp_cb.
1175 */
libie_ctlq_xn_shutdown(struct libie_ctlq_xn_manager * xnm)1176 void libie_ctlq_xn_shutdown(struct libie_ctlq_xn_manager *xnm)
1177 {
1178 bool must_wait = false;
1179 u32 i;
1180
1181 /* Should be no new clear bits after this */
1182 spin_lock(&xnm->free_xns_bm_lock);
1183 xnm->shutdown = true;
1184
1185 for_each_clear_bit(i, xnm->free_xns_bm, LIBIE_CTLQ_MAX_XN_ENTRIES) {
1186 struct libie_ctlq_xn *xn = &xnm->ring[i];
1187
1188 spin_lock(&xn->xn_lock);
1189
1190 switch (xn->state) {
1191 /* if an idle xn is not free, it is about to be either
1192 * freed or initialized, prevent the latter and wait
1193 */
1194 case LIBIE_CTLQ_XN_IDLE:
1195 xn->state = LIBIE_CTLQ_XN_SHUTDOWN;
1196 fallthrough;
1197 /* waiting thread possibly needs a push to return the xn,
1198 * transaction will be reported as timed out
1199 */
1200 case LIBIE_CTLQ_XN_WAITING:
1201 complete(&xn->cmd_completion_event);
1202 fallthrough;
1203 /* these states will return the xn soon */
1204 case LIBIE_CTLQ_XN_COMPLETED_SUCCESS:
1205 case LIBIE_CTLQ_XN_COMPLETED_FAILED:
1206 case LIBIE_CTLQ_XN_SHUTDOWN:
1207 must_wait = true;
1208 break;
1209 /* no thread should reference async xns at this point */
1210 case LIBIE_CTLQ_XN_ASYNC:
1211 xn->state = LIBIE_CTLQ_XN_IDLE;
1212 __libie_ctlq_xn_push_free(xnm, xn);
1213 break;
1214 }
1215
1216 spin_unlock(&xn->xn_lock);
1217 }
1218
1219 spin_unlock(&xnm->free_xns_bm_lock);
1220
1221 if (must_wait)
1222 wait_for_completion(&xnm->can_destroy);
1223 }
1224 EXPORT_SYMBOL_NS_GPL(libie_ctlq_xn_shutdown, "LIBIE_CP");
1225
1226 /**
1227 * libie_ctlq_xn_deinit - deallocate and free the transaction manager resources
1228 * @xnm: pointer to the transaction manager
1229 * @ctx: libie CP context information
1230 *
1231 * Rx processing must be stopped beforehand via cancelling tasks.
1232 * Tx processing must be stopped beforehand via libie_ctlq_xn_shutdown(),
1233 * all buffers must be force-cleaned from the send queue.
1234 */
libie_ctlq_xn_deinit(struct libie_ctlq_xn_manager * xnm,struct libie_ctlq_ctx * ctx)1235 void libie_ctlq_xn_deinit(struct libie_ctlq_xn_manager *xnm,
1236 struct libie_ctlq_ctx *ctx)
1237 {
1238 libie_ctlq_xn_deinit_dma(xnm, LIBIE_CTLQ_MAX_XN_ENTRIES);
1239 kvfree(xnm);
1240 libie_ctlq_deinit(ctx);
1241 }
1242 EXPORT_SYMBOL_NS_GPL(libie_ctlq_xn_deinit, "LIBIE_CP");
1243
1244 /**
1245 * libie_ctlq_xn_init - initialize the Xn transaction manager
1246 * @params: Xn init param information for allocating Xn manager resources
1247 *
1248 * Return: %0 on success, -%errno on failure.
1249 */
libie_ctlq_xn_init(struct libie_ctlq_xn_init_params * params)1250 int libie_ctlq_xn_init(struct libie_ctlq_xn_init_params *params)
1251 {
1252 struct libie_ctlq_xn_manager *xnm;
1253 int ret;
1254
1255 ret = libie_ctlq_init(params->ctx, params->cctlq_info, params->num_qs);
1256 if (ret)
1257 return ret;
1258
1259 xnm = kvzalloc_obj(*xnm);
1260 if (!xnm)
1261 goto ctlq_deinit;
1262
1263 ret = libie_ctlq_xn_init_dma(¶ms->ctx->mmio_info.pdev->dev, xnm);
1264 if (ret)
1265 goto free_xnm;
1266
1267 spin_lock_init(&xnm->free_xns_bm_lock);
1268 init_completion(&xnm->can_destroy);
1269 bitmap_fill(xnm->free_xns_bm, LIBIE_CTLQ_MAX_XN_ENTRIES);
1270
1271 for (u32 i = 0; i < LIBIE_CTLQ_MAX_XN_ENTRIES; i++) {
1272 struct libie_ctlq_xn *xn = &xnm->ring[i];
1273
1274 xn->index = i;
1275 init_completion(&xn->cmd_completion_event);
1276 spin_lock_init(&xn->xn_lock);
1277 }
1278 xnm->ctx = params->ctx;
1279 params->xnm = xnm;
1280
1281 return 0;
1282
1283 free_xnm:
1284 kvfree(xnm);
1285 ctlq_deinit:
1286 libie_ctlq_deinit(params->ctx);
1287
1288 return -ENOMEM;
1289 }
1290 EXPORT_SYMBOL_NS_GPL(libie_ctlq_xn_init, "LIBIE_CP");
1291
1292 MODULE_DESCRIPTION("Control Plane communication API");
1293 MODULE_IMPORT_NS("LIBETH");
1294 MODULE_LICENSE("GPL");
1295