1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright (C) 2023 Intel Corporation */
3
4 #include "idpf_controlq.h"
5
6 /**
7 * idpf_ctlq_alloc_desc_ring - Allocate Control Queue (CQ) rings
8 * @hw: pointer to hw struct
9 * @cq: pointer to the specific Control queue
10 */
idpf_ctlq_alloc_desc_ring(struct idpf_hw * hw,struct idpf_ctlq_info * cq)11 static int idpf_ctlq_alloc_desc_ring(struct idpf_hw *hw,
12 struct idpf_ctlq_info *cq)
13 {
14 size_t size = cq->ring_size * sizeof(struct idpf_ctlq_desc);
15
16 cq->desc_ring.va = idpf_alloc_dma_mem(hw, &cq->desc_ring, size);
17 if (!cq->desc_ring.va)
18 return -ENOMEM;
19
20 return 0;
21 }
22
23 /**
24 * idpf_ctlq_alloc_bufs - Allocate Control Queue (CQ) buffers
25 * @hw: pointer to hw struct
26 * @cq: pointer to the specific Control queue
27 *
28 * Allocate the buffer head for all control queues, and if it's a receive
29 * queue, allocate DMA buffers
30 */
idpf_ctlq_alloc_bufs(struct idpf_hw * hw,struct idpf_ctlq_info * cq)31 static int idpf_ctlq_alloc_bufs(struct idpf_hw *hw,
32 struct idpf_ctlq_info *cq)
33 {
34 int i;
35
36 /* Do not allocate DMA buffers for transmit queues */
37 if (cq->cq_type == IDPF_CTLQ_TYPE_MAILBOX_TX)
38 return 0;
39
40 /* We'll be allocating the buffer info memory first, then we can
41 * allocate the mapped buffers for the event processing
42 */
43 cq->bi.rx_buff = kzalloc_objs(struct idpf_dma_mem *, cq->ring_size);
44 if (!cq->bi.rx_buff)
45 return -ENOMEM;
46
47 /* allocate the mapped buffers (except for the last one) */
48 for (i = 0; i < cq->ring_size - 1; i++) {
49 struct idpf_dma_mem *bi;
50 int num = 1; /* number of idpf_dma_mem to be allocated */
51
52 cq->bi.rx_buff[i] = kzalloc_objs(struct idpf_dma_mem, num);
53 if (!cq->bi.rx_buff[i])
54 goto unwind_alloc_cq_bufs;
55
56 bi = cq->bi.rx_buff[i];
57
58 bi->va = idpf_alloc_dma_mem(hw, bi, cq->buf_size);
59 if (!bi->va) {
60 /* unwind will not free the failed entry */
61 kfree(cq->bi.rx_buff[i]);
62 goto unwind_alloc_cq_bufs;
63 }
64 }
65
66 return 0;
67
68 unwind_alloc_cq_bufs:
69 /* don't try to free the one that failed... */
70 i--;
71 for (; i >= 0; i--) {
72 idpf_free_dma_mem(hw, cq->bi.rx_buff[i]);
73 kfree(cq->bi.rx_buff[i]);
74 }
75 kfree(cq->bi.rx_buff);
76
77 return -ENOMEM;
78 }
79
80 /**
81 * idpf_ctlq_free_desc_ring - Free Control Queue (CQ) rings
82 * @hw: pointer to hw struct
83 * @cq: pointer to the specific Control queue
84 *
85 * This assumes the posted send buffers have already been cleaned
86 * and de-allocated
87 */
idpf_ctlq_free_desc_ring(struct idpf_hw * hw,struct idpf_ctlq_info * cq)88 static void idpf_ctlq_free_desc_ring(struct idpf_hw *hw,
89 struct idpf_ctlq_info *cq)
90 {
91 idpf_free_dma_mem(hw, &cq->desc_ring);
92 }
93
94 /**
95 * idpf_ctlq_free_bufs - Free CQ buffer info elements
96 * @hw: pointer to hw struct
97 * @cq: pointer to the specific Control queue
98 *
99 * Free the DMA buffers for RX queues, and DMA buffer header for both RX and TX
100 * queues. The upper layers are expected to manage freeing of TX DMA buffers
101 */
idpf_ctlq_free_bufs(struct idpf_hw * hw,struct idpf_ctlq_info * cq)102 static void idpf_ctlq_free_bufs(struct idpf_hw *hw, struct idpf_ctlq_info *cq)
103 {
104 void *bi;
105
106 if (cq->cq_type == IDPF_CTLQ_TYPE_MAILBOX_RX) {
107 int i;
108
109 /* free DMA buffers for rx queues*/
110 for (i = 0; i < cq->ring_size; i++) {
111 if (cq->bi.rx_buff[i]) {
112 idpf_free_dma_mem(hw, cq->bi.rx_buff[i]);
113 kfree(cq->bi.rx_buff[i]);
114 }
115 }
116
117 bi = (void *)cq->bi.rx_buff;
118 } else {
119 bi = (void *)cq->bi.tx_msg;
120 }
121
122 /* free the buffer header */
123 kfree(bi);
124 }
125
126 /**
127 * idpf_ctlq_dealloc_ring_res - Free memory allocated for control queue
128 * @hw: pointer to hw struct
129 * @cq: pointer to the specific Control queue
130 *
131 * Free the memory used by the ring, buffers and other related structures
132 */
idpf_ctlq_dealloc_ring_res(struct idpf_hw * hw,struct idpf_ctlq_info * cq)133 void idpf_ctlq_dealloc_ring_res(struct idpf_hw *hw, struct idpf_ctlq_info *cq)
134 {
135 /* free ring buffers and the ring itself */
136 idpf_ctlq_free_bufs(hw, cq);
137 idpf_ctlq_free_desc_ring(hw, cq);
138 }
139
140 /**
141 * idpf_ctlq_alloc_ring_res - allocate memory for descriptor ring and bufs
142 * @hw: pointer to hw struct
143 * @cq: pointer to control queue struct
144 *
145 * Do *NOT* hold cq_lock when calling this as the memory allocation routines
146 * called are not going to be atomic context safe
147 */
idpf_ctlq_alloc_ring_res(struct idpf_hw * hw,struct idpf_ctlq_info * cq)148 int idpf_ctlq_alloc_ring_res(struct idpf_hw *hw, struct idpf_ctlq_info *cq)
149 {
150 int err;
151
152 /* allocate the ring memory */
153 err = idpf_ctlq_alloc_desc_ring(hw, cq);
154 if (err)
155 return err;
156
157 /* allocate buffers in the rings */
158 err = idpf_ctlq_alloc_bufs(hw, cq);
159 if (err)
160 goto idpf_init_cq_free_ring;
161
162 /* success! */
163 return 0;
164
165 idpf_init_cq_free_ring:
166 idpf_free_dma_mem(hw, &cq->desc_ring);
167
168 return err;
169 }
170