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