]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/bus/dpaa/base/qbman/process.c
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / spdk / dpdk / drivers / bus / dpaa / base / qbman / process.c
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2 *
3 * Copyright 2011-2016 Freescale Semiconductor Inc.
4 * Copyright 2017 NXP
5 *
6 */
7 #include <assert.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <sys/ioctl.h>
11
12 #include "process.h"
13
14 #include <fsl_usd.h>
15
16 /* As higher-level drivers will be built on top of this (dma_mem, qbman, ...),
17 * it's preferable that the process driver itself not provide any exported API.
18 * As such, combined with the fact that none of these operations are
19 * performance critical, it is justified to use lazy initialisation, so that's
20 * what the lock is for.
21 */
22 static int fd = -1;
23 static pthread_mutex_t fd_init_lock = PTHREAD_MUTEX_INITIALIZER;
24
25 static int check_fd(void)
26 {
27 int ret;
28
29 if (fd >= 0)
30 return 0;
31 ret = pthread_mutex_lock(&fd_init_lock);
32 assert(!ret);
33 /* check again with the lock held */
34 if (fd < 0)
35 fd = open(PROCESS_PATH, O_RDWR);
36 ret = pthread_mutex_unlock(&fd_init_lock);
37 assert(!ret);
38 return (fd >= 0) ? 0 : -ENODEV;
39 }
40
41 #define DPAA_IOCTL_MAGIC 'u'
42 struct dpaa_ioctl_id_alloc {
43 uint32_t base; /* Return value, the start of the allocated range */
44 enum dpaa_id_type id_type; /* what kind of resource(s) to allocate */
45 uint32_t num; /* how many IDs to allocate (and return value) */
46 uint32_t align; /* must be a power of 2, 0 is treated like 1 */
47 int partial; /* whether to allow less than 'num' */
48 };
49
50 struct dpaa_ioctl_id_release {
51 /* Input; */
52 enum dpaa_id_type id_type;
53 uint32_t base;
54 uint32_t num;
55 };
56
57 struct dpaa_ioctl_id_reserve {
58 enum dpaa_id_type id_type;
59 uint32_t base;
60 uint32_t num;
61 };
62
63 #define DPAA_IOCTL_ID_ALLOC \
64 _IOWR(DPAA_IOCTL_MAGIC, 0x01, struct dpaa_ioctl_id_alloc)
65 #define DPAA_IOCTL_ID_RELEASE \
66 _IOW(DPAA_IOCTL_MAGIC, 0x02, struct dpaa_ioctl_id_release)
67 #define DPAA_IOCTL_ID_RESERVE \
68 _IOW(DPAA_IOCTL_MAGIC, 0x0A, struct dpaa_ioctl_id_reserve)
69
70 int process_alloc(enum dpaa_id_type id_type, uint32_t *base, uint32_t num,
71 uint32_t align, int partial)
72 {
73 struct dpaa_ioctl_id_alloc id = {
74 .id_type = id_type,
75 .num = num,
76 .align = align,
77 .partial = partial
78 };
79 int ret = check_fd();
80
81 if (ret)
82 return ret;
83 ret = ioctl(fd, DPAA_IOCTL_ID_ALLOC, &id);
84 if (ret)
85 return ret;
86 for (ret = 0; ret < (int)id.num; ret++)
87 base[ret] = id.base + ret;
88 return id.num;
89 }
90
91 void process_release(enum dpaa_id_type id_type, uint32_t base, uint32_t num)
92 {
93 struct dpaa_ioctl_id_release id = {
94 .id_type = id_type,
95 .base = base,
96 .num = num
97 };
98 int ret = check_fd();
99
100 if (ret) {
101 fprintf(stderr, "Process FD failure\n");
102 return;
103 }
104 ret = ioctl(fd, DPAA_IOCTL_ID_RELEASE, &id);
105 if (ret)
106 fprintf(stderr, "Process FD ioctl failure type %d base 0x%x num %d\n",
107 id_type, base, num);
108 }
109
110 int process_reserve(enum dpaa_id_type id_type, uint32_t base, uint32_t num)
111 {
112 struct dpaa_ioctl_id_reserve id = {
113 .id_type = id_type,
114 .base = base,
115 .num = num
116 };
117 int ret = check_fd();
118
119 if (ret)
120 return ret;
121 return ioctl(fd, DPAA_IOCTL_ID_RESERVE, &id);
122 }
123
124 /***************************************/
125 /* Mapping and using QMan/BMan portals */
126 /***************************************/
127
128 #define DPAA_IOCTL_PORTAL_MAP \
129 _IOWR(DPAA_IOCTL_MAGIC, 0x07, struct dpaa_ioctl_portal_map)
130 #define DPAA_IOCTL_PORTAL_UNMAP \
131 _IOW(DPAA_IOCTL_MAGIC, 0x08, struct dpaa_portal_map)
132
133 int process_portal_map(struct dpaa_ioctl_portal_map *params)
134 {
135 int ret = check_fd();
136
137 if (ret)
138 return ret;
139
140 ret = ioctl(fd, DPAA_IOCTL_PORTAL_MAP, params);
141 if (ret) {
142 perror("ioctl(DPAA_IOCTL_PORTAL_MAP)");
143 return ret;
144 }
145 return 0;
146 }
147
148 int process_portal_unmap(struct dpaa_portal_map *map)
149 {
150 int ret = check_fd();
151
152 if (ret)
153 return ret;
154
155 ret = ioctl(fd, DPAA_IOCTL_PORTAL_UNMAP, map);
156 if (ret) {
157 perror("ioctl(DPAA_IOCTL_PORTAL_UNMAP)");
158 return ret;
159 }
160 return 0;
161 }
162
163 #define DPAA_IOCTL_PORTAL_IRQ_MAP \
164 _IOW(DPAA_IOCTL_MAGIC, 0x09, struct dpaa_ioctl_irq_map)
165
166 int process_portal_irq_map(int ifd, struct dpaa_ioctl_irq_map *map)
167 {
168 map->fd = fd;
169 return ioctl(ifd, DPAA_IOCTL_PORTAL_IRQ_MAP, map);
170 }
171
172 int process_portal_irq_unmap(int ifd)
173 {
174 return close(ifd);
175 }
176
177 struct dpaa_ioctl_raw_portal {
178 /* inputs */
179 enum dpaa_portal_type type; /* Type of portal to allocate */
180
181 uint8_t enable_stash; /* set to non zero to turn on stashing */
182 /* Stashing attributes for the portal */
183 uint32_t cpu;
184 uint32_t cache;
185 uint32_t window;
186 /* Specifies the stash request queue this portal should use */
187 uint8_t sdest;
188
189 /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
190 * for don't care. The portal index will be populated by the
191 * driver when the ioctl() successfully completes.
192 */
193 uint32_t index;
194
195 /* outputs */
196 uint64_t cinh;
197 uint64_t cena;
198 };
199
200 #define DPAA_IOCTL_ALLOC_RAW_PORTAL \
201 _IOWR(DPAA_IOCTL_MAGIC, 0x0C, struct dpaa_ioctl_raw_portal)
202
203 #define DPAA_IOCTL_FREE_RAW_PORTAL \
204 _IOR(DPAA_IOCTL_MAGIC, 0x0D, struct dpaa_ioctl_raw_portal)
205
206 static int process_portal_allocate(struct dpaa_ioctl_raw_portal *portal)
207 {
208 int ret = check_fd();
209
210 if (ret)
211 return ret;
212
213 ret = ioctl(fd, DPAA_IOCTL_ALLOC_RAW_PORTAL, portal);
214 if (ret) {
215 perror("ioctl(DPAA_IOCTL_ALLOC_RAW_PORTAL)");
216 return ret;
217 }
218 return 0;
219 }
220
221 static int process_portal_free(struct dpaa_ioctl_raw_portal *portal)
222 {
223 int ret = check_fd();
224
225 if (ret)
226 return ret;
227
228 ret = ioctl(fd, DPAA_IOCTL_FREE_RAW_PORTAL, portal);
229 if (ret) {
230 perror("ioctl(DPAA_IOCTL_FREE_RAW_PORTAL)");
231 return ret;
232 }
233 return 0;
234 }
235
236 int qman_allocate_raw_portal(struct dpaa_raw_portal *portal)
237 {
238 struct dpaa_ioctl_raw_portal input;
239 int ret;
240
241 input.type = dpaa_portal_qman;
242 input.index = portal->index;
243 input.enable_stash = portal->enable_stash;
244 input.cpu = portal->cpu;
245 input.cache = portal->cache;
246 input.window = portal->window;
247 input.sdest = portal->sdest;
248
249 ret = process_portal_allocate(&input);
250 if (ret)
251 return ret;
252 portal->index = input.index;
253 portal->cinh = input.cinh;
254 portal->cena = input.cena;
255 return 0;
256 }
257
258 int qman_free_raw_portal(struct dpaa_raw_portal *portal)
259 {
260 struct dpaa_ioctl_raw_portal input;
261
262 input.type = dpaa_portal_qman;
263 input.index = portal->index;
264 input.cinh = portal->cinh;
265 input.cena = portal->cena;
266
267 return process_portal_free(&input);
268 }
269
270 int bman_allocate_raw_portal(struct dpaa_raw_portal *portal)
271 {
272 struct dpaa_ioctl_raw_portal input;
273 int ret;
274
275 input.type = dpaa_portal_bman;
276 input.index = portal->index;
277 input.enable_stash = 0;
278
279 ret = process_portal_allocate(&input);
280 if (ret)
281 return ret;
282 portal->index = input.index;
283 portal->cinh = input.cinh;
284 portal->cena = input.cena;
285 return 0;
286 }
287
288 int bman_free_raw_portal(struct dpaa_raw_portal *portal)
289 {
290 struct dpaa_ioctl_raw_portal input;
291
292 input.type = dpaa_portal_bman;
293 input.index = portal->index;
294 input.cinh = portal->cinh;
295 input.cena = portal->cena;
296
297 return process_portal_free(&input);
298 }