Branch data Line data Source code
1 : : /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2 : : *
3 : : * Copyright 2011-2016 Freescale Semiconductor Inc.
4 : : * Copyright 2017,2020 NXP
5 : : *
6 : : */
7 : : #include <assert.h>
8 : : #include <fcntl.h>
9 : : #include <unistd.h>
10 : : #include <sys/ioctl.h>
11 : : #include <rte_ethdev.h>
12 : :
13 : : #include "process.h"
14 : :
15 : : #include <fsl_usd.h>
16 : :
17 : : /* As higher-level drivers will be built on top of this (dma_mem, qbman, ...),
18 : : * it's preferable that the process driver itself not provide any exported API.
19 : : * As such, combined with the fact that none of these operations are
20 : : * performance critical, it is justified to use lazy initialisation, so that's
21 : : * what the lock is for.
22 : : */
23 : : static int fd = -1;
24 : : static pthread_mutex_t fd_init_lock = PTHREAD_MUTEX_INITIALIZER;
25 : :
26 : 0 : static int check_fd(void)
27 : : {
28 : : int ret;
29 : :
30 [ # # ]: 0 : if (fd >= 0)
31 : : return 0;
32 : 0 : ret = pthread_mutex_lock(&fd_init_lock);
33 [ # # ]: 0 : assert(!ret);
34 : : /* check again with the lock held */
35 [ # # ]: 0 : if (fd < 0)
36 : 0 : fd = open(PROCESS_PATH, O_RDWR);
37 : 0 : ret = pthread_mutex_unlock(&fd_init_lock);
38 [ # # ]: 0 : assert(!ret);
39 [ # # ]: 0 : return (fd >= 0) ? 0 : -ENODEV;
40 : : }
41 : :
42 : : #define DPAA_IOCTL_MAGIC 'u'
43 : : struct dpaa_ioctl_id_alloc {
44 : : uint32_t base; /* Return value, the start of the allocated range */
45 : : enum dpaa_id_type id_type; /* what kind of resource(s) to allocate */
46 : : uint32_t num; /* how many IDs to allocate (and return value) */
47 : : uint32_t align; /* must be a power of 2, 0 is treated like 1 */
48 : : int partial; /* whether to allow less than 'num' */
49 : : };
50 : :
51 : : struct dpaa_ioctl_id_release {
52 : : /* Input; */
53 : : enum dpaa_id_type id_type;
54 : : uint32_t base;
55 : : uint32_t num;
56 : : };
57 : :
58 : : struct dpaa_ioctl_id_reserve {
59 : : enum dpaa_id_type id_type;
60 : : uint32_t base;
61 : : uint32_t num;
62 : : };
63 : :
64 : : #define DPAA_IOCTL_ID_ALLOC \
65 : : _IOWR(DPAA_IOCTL_MAGIC, 0x01, struct dpaa_ioctl_id_alloc)
66 : : #define DPAA_IOCTL_ID_RELEASE \
67 : : _IOW(DPAA_IOCTL_MAGIC, 0x02, struct dpaa_ioctl_id_release)
68 : : #define DPAA_IOCTL_ID_RESERVE \
69 : : _IOW(DPAA_IOCTL_MAGIC, 0x0A, struct dpaa_ioctl_id_reserve)
70 : :
71 : 0 : int process_alloc(enum dpaa_id_type id_type, uint32_t *base, uint32_t num,
72 : : uint32_t align, int partial)
73 : : {
74 : 0 : struct dpaa_ioctl_id_alloc id = {
75 : : .id_type = id_type,
76 : : .num = num,
77 : : .align = align,
78 : : .partial = partial
79 : : };
80 : 0 : int ret = check_fd();
81 : :
82 [ # # ]: 0 : if (ret)
83 : : return ret;
84 : 0 : ret = ioctl(fd, DPAA_IOCTL_ID_ALLOC, &id);
85 [ # # ]: 0 : if (ret)
86 : : return ret;
87 [ # # ]: 0 : for (ret = 0; ret < (int)id.num; ret++)
88 : 0 : base[ret] = id.base + ret;
89 : : return id.num;
90 : : }
91 : :
92 : 0 : void process_release(enum dpaa_id_type id_type, uint32_t base, uint32_t num)
93 : : {
94 : 0 : struct dpaa_ioctl_id_release id = {
95 : : .id_type = id_type,
96 : : .base = base,
97 : : .num = num
98 : : };
99 : 0 : int ret = check_fd();
100 : :
101 [ # # ]: 0 : if (ret) {
102 : 0 : fprintf(stderr, "Process FD failure\n");
103 : 0 : return;
104 : : }
105 : 0 : ret = ioctl(fd, DPAA_IOCTL_ID_RELEASE, &id);
106 [ # # ]: 0 : if (ret)
107 : 0 : fprintf(stderr, "Process FD ioctl failure type %d base 0x%x num %d\n",
108 : : id_type, base, num);
109 : : }
110 : :
111 : 0 : int process_reserve(enum dpaa_id_type id_type, uint32_t base, uint32_t num)
112 : : {
113 : 0 : struct dpaa_ioctl_id_reserve id = {
114 : : .id_type = id_type,
115 : : .base = base,
116 : : .num = num
117 : : };
118 : 0 : int ret = check_fd();
119 : :
120 [ # # ]: 0 : if (ret)
121 : : return ret;
122 : 0 : return ioctl(fd, DPAA_IOCTL_ID_RESERVE, &id);
123 : : }
124 : :
125 : : /***************************************/
126 : : /* Mapping and using QMan/BMan portals */
127 : : /***************************************/
128 : :
129 : : #define DPAA_IOCTL_PORTAL_MAP \
130 : : _IOWR(DPAA_IOCTL_MAGIC, 0x07, struct dpaa_ioctl_portal_map)
131 : : #define DPAA_IOCTL_PORTAL_UNMAP \
132 : : _IOW(DPAA_IOCTL_MAGIC, 0x08, struct dpaa_portal_map)
133 : :
134 : 0 : int process_portal_map(struct dpaa_ioctl_portal_map *params)
135 : : {
136 : 0 : int ret = check_fd();
137 : :
138 [ # # ]: 0 : if (ret)
139 : : return ret;
140 : :
141 : 0 : ret = ioctl(fd, DPAA_IOCTL_PORTAL_MAP, params);
142 [ # # ]: 0 : if (ret) {
143 : 0 : perror("ioctl(DPAA_IOCTL_PORTAL_MAP)");
144 : 0 : return ret;
145 : : }
146 : : return 0;
147 : : }
148 : :
149 : 0 : int process_portal_unmap(struct dpaa_portal_map *map)
150 : : {
151 : 0 : int ret = check_fd();
152 : :
153 [ # # ]: 0 : if (ret)
154 : : return ret;
155 : :
156 : 0 : ret = ioctl(fd, DPAA_IOCTL_PORTAL_UNMAP, map);
157 [ # # ]: 0 : if (ret) {
158 : 0 : perror("ioctl(DPAA_IOCTL_PORTAL_UNMAP)");
159 : 0 : return ret;
160 : : }
161 : : return 0;
162 : : }
163 : :
164 : : #define DPAA_IOCTL_PORTAL_IRQ_MAP \
165 : : _IOW(DPAA_IOCTL_MAGIC, 0x09, struct dpaa_ioctl_irq_map)
166 : :
167 : 0 : int process_portal_irq_map(int ifd, struct dpaa_ioctl_irq_map *map)
168 : : {
169 : 0 : map->fd = fd;
170 : 0 : return ioctl(ifd, DPAA_IOCTL_PORTAL_IRQ_MAP, map);
171 : : }
172 : :
173 : 0 : int process_portal_irq_unmap(int ifd)
174 : : {
175 : 0 : return close(ifd);
176 : : }
177 : :
178 : : struct dpaa_ioctl_raw_portal {
179 : : /* inputs */
180 : : enum dpaa_portal_type type; /* Type of portal to allocate */
181 : :
182 : : uint8_t enable_stash; /* set to non zero to turn on stashing */
183 : : /* Stashing attributes for the portal */
184 : : uint32_t cpu;
185 : : uint32_t cache;
186 : : uint32_t window;
187 : : /* Specifies the stash request queue this portal should use */
188 : : uint8_t sdest;
189 : :
190 : : /* Specifes a specific portal index to map or QBMAN_ANY_PORTAL_IDX
191 : : * for don't care. The portal index will be populated by the
192 : : * driver when the ioctl() successfully completes.
193 : : */
194 : : uint32_t index;
195 : :
196 : : /* outputs */
197 : : uint64_t cinh;
198 : : uint64_t cena;
199 : : };
200 : :
201 : : #define DPAA_IOCTL_ALLOC_RAW_PORTAL \
202 : : _IOWR(DPAA_IOCTL_MAGIC, 0x0C, struct dpaa_ioctl_raw_portal)
203 : :
204 : : #define DPAA_IOCTL_FREE_RAW_PORTAL \
205 : : _IOR(DPAA_IOCTL_MAGIC, 0x0D, struct dpaa_ioctl_raw_portal)
206 : :
207 : 0 : static int process_portal_allocate(struct dpaa_ioctl_raw_portal *portal)
208 : : {
209 : 0 : int ret = check_fd();
210 : :
211 [ # # ]: 0 : if (ret)
212 : : return ret;
213 : :
214 : 0 : ret = ioctl(fd, DPAA_IOCTL_ALLOC_RAW_PORTAL, portal);
215 [ # # ]: 0 : if (ret) {
216 : 0 : perror("ioctl(DPAA_IOCTL_ALLOC_RAW_PORTAL)");
217 : 0 : return ret;
218 : : }
219 : : return 0;
220 : : }
221 : :
222 : 0 : static int process_portal_free(struct dpaa_ioctl_raw_portal *portal)
223 : : {
224 : 0 : int ret = check_fd();
225 : :
226 [ # # ]: 0 : if (ret)
227 : : return ret;
228 : :
229 : 0 : ret = ioctl(fd, DPAA_IOCTL_FREE_RAW_PORTAL, portal);
230 [ # # ]: 0 : if (ret) {
231 : 0 : perror("ioctl(DPAA_IOCTL_FREE_RAW_PORTAL)");
232 : 0 : return ret;
233 : : }
234 : : return 0;
235 : : }
236 : :
237 : 0 : int qman_allocate_raw_portal(struct dpaa_raw_portal *portal)
238 : : {
239 : : struct dpaa_ioctl_raw_portal input;
240 : : int ret;
241 : :
242 : 0 : input.type = dpaa_portal_qman;
243 : 0 : input.index = portal->index;
244 : 0 : input.enable_stash = portal->enable_stash;
245 : 0 : input.cpu = portal->cpu;
246 : 0 : input.cache = portal->cache;
247 : 0 : input.window = portal->window;
248 : 0 : input.sdest = portal->sdest;
249 : :
250 : 0 : ret = process_portal_allocate(&input);
251 [ # # ]: 0 : if (ret)
252 : : return ret;
253 : 0 : portal->index = input.index;
254 : 0 : portal->cinh = input.cinh;
255 : 0 : portal->cena = input.cena;
256 : 0 : return 0;
257 : : }
258 : :
259 : 0 : int qman_free_raw_portal(struct dpaa_raw_portal *portal)
260 : : {
261 : : struct dpaa_ioctl_raw_portal input;
262 : :
263 : 0 : input.type = dpaa_portal_qman;
264 : 0 : input.index = portal->index;
265 : 0 : input.cinh = portal->cinh;
266 : 0 : input.cena = portal->cena;
267 : :
268 : 0 : return process_portal_free(&input);
269 : : }
270 : :
271 : 0 : int bman_allocate_raw_portal(struct dpaa_raw_portal *portal)
272 : : {
273 : : struct dpaa_ioctl_raw_portal input;
274 : : int ret;
275 : :
276 : 0 : input.type = dpaa_portal_bman;
277 : 0 : input.index = portal->index;
278 : 0 : input.enable_stash = 0;
279 : :
280 : 0 : ret = process_portal_allocate(&input);
281 [ # # ]: 0 : if (ret)
282 : : return ret;
283 : 0 : portal->index = input.index;
284 : 0 : portal->cinh = input.cinh;
285 : 0 : portal->cena = input.cena;
286 : 0 : return 0;
287 : : }
288 : :
289 : 0 : int bman_free_raw_portal(struct dpaa_raw_portal *portal)
290 : : {
291 : : struct dpaa_ioctl_raw_portal input;
292 : :
293 : 0 : input.type = dpaa_portal_bman;
294 : 0 : input.index = portal->index;
295 : 0 : input.cinh = portal->cinh;
296 : 0 : input.cena = portal->cena;
297 : :
298 : 0 : return process_portal_free(&input);
299 : : }
300 : :
301 : : #define DPAA_IOCTL_ENABLE_LINK_STATUS_INTERRUPT \
302 : : _IOW(DPAA_IOCTL_MAGIC, 0x0E, struct usdpaa_ioctl_link_status)
303 : :
304 : : #define DPAA_IOCTL_DISABLE_LINK_STATUS_INTERRUPT \
305 : : _IOW(DPAA_IOCTL_MAGIC, 0x0F, char[IF_NAME_MAX_LEN])
306 : :
307 : 0 : int dpaa_intr_enable(char *if_name, int efd)
308 : : {
309 : : struct usdpaa_ioctl_link_status args;
310 : :
311 : 0 : int ret = check_fd();
312 : :
313 [ # # ]: 0 : if (ret)
314 : : return ret;
315 : :
316 : 0 : args.efd = (uint32_t)efd;
317 : : strcpy(args.if_name, if_name);
318 : :
319 : 0 : ret = ioctl(fd, DPAA_IOCTL_ENABLE_LINK_STATUS_INTERRUPT, &args);
320 [ # # ]: 0 : if (ret)
321 : 0 : return errno;
322 : :
323 : : return 0;
324 : : }
325 : :
326 : 0 : int dpaa_intr_disable(char *if_name)
327 : : {
328 : 0 : int ret = check_fd();
329 : :
330 [ # # ]: 0 : if (ret)
331 : : return ret;
332 : :
333 : 0 : ret = ioctl(fd, DPAA_IOCTL_DISABLE_LINK_STATUS_INTERRUPT, if_name);
334 [ # # ]: 0 : if (ret) {
335 [ # # ]: 0 : if (errno == EINVAL)
336 : : printf("Failed to disable interrupt: Not Supported\n");
337 : : else
338 : : printf("Failed to disable interrupt\n");
339 : 0 : return ret;
340 : : }
341 : :
342 : : return 0;
343 : : }
344 : :
345 : : #define DPAA_IOCTL_GET_IOCTL_VERSION \
346 : : _IOR(DPAA_IOCTL_MAGIC, 0x14, int)
347 : :
348 : 0 : int dpaa_get_ioctl_version_number(void)
349 : : {
350 : 0 : int version_num, ret = check_fd();
351 : :
352 [ # # ]: 0 : if (ret)
353 : : return ret;
354 : :
355 : 0 : ret = ioctl(fd, DPAA_IOCTL_GET_IOCTL_VERSION, &version_num);
356 [ # # ]: 0 : if (ret) {
357 [ # # ]: 0 : if (errno == EINVAL) {
358 : 0 : version_num = 1;
359 : : } else {
360 : : printf("Failed to get ioctl version number\n");
361 : 0 : version_num = -1;
362 : : }
363 : : }
364 : :
365 : 0 : return version_num;
366 : : }
367 : :
368 : : #define DPAA_IOCTL_GET_LINK_STATUS \
369 : : _IOWR(DPAA_IOCTL_MAGIC, 0x10, struct usdpaa_ioctl_link_status_args)
370 : :
371 : : #define DPAA_IOCTL_GET_LINK_STATUS_OLD \
372 : : _IOWR(DPAA_IOCTL_MAGIC, 0x10, struct usdpaa_ioctl_link_status_args_old)
373 : :
374 : :
375 : 0 : int dpaa_get_link_status(char *if_name, struct rte_eth_link *link)
376 : : {
377 : 0 : int ioctl_version, ret = check_fd();
378 : :
379 [ # # ]: 0 : if (ret)
380 : : return ret;
381 : :
382 : 0 : ioctl_version = dpaa_get_ioctl_version_number();
383 : :
384 [ # # ]: 0 : if (ioctl_version == 2) {
385 : : struct usdpaa_ioctl_link_status_args args;
386 : :
387 : : strcpy(args.if_name, if_name);
388 : :
389 : 0 : ret = ioctl(fd, DPAA_IOCTL_GET_LINK_STATUS, &args);
390 [ # # ]: 0 : if (ret) {
391 : : printf("Failed to get link status\n");
392 : 0 : return ret;
393 : : }
394 : :
395 : 0 : link->link_status = args.link_status;
396 : 0 : link->link_speed = args.link_speed;
397 : 0 : link->link_duplex = args.link_duplex;
398 : 0 : link->link_autoneg = args.link_autoneg;
399 : : } else {
400 : : struct usdpaa_ioctl_link_status_args_old args;
401 : :
402 : : strcpy(args.if_name, if_name);
403 : :
404 : 0 : ret = ioctl(fd, DPAA_IOCTL_GET_LINK_STATUS_OLD, &args);
405 [ # # ]: 0 : if (ret) {
406 [ # # ]: 0 : if (errno == EINVAL)
407 : : printf("Get link status: Not Supported\n");
408 : : else
409 : : printf("Failed to get link status\n");
410 : 0 : return ret;
411 : : }
412 : :
413 : 0 : link->link_status = args.link_status;
414 : : }
415 : :
416 : : return 0;
417 : : }
418 : :
419 : : #define DPAA_IOCTL_UPDATE_LINK_STATUS \
420 : : _IOW(DPAA_IOCTL_MAGIC, 0x11, struct usdpaa_ioctl_update_link_status_args)
421 : :
422 : 0 : int dpaa_update_link_status(char *if_name, int link_status)
423 : : {
424 : : struct usdpaa_ioctl_update_link_status_args args;
425 : : int ret;
426 : :
427 : 0 : ret = check_fd();
428 [ # # ]: 0 : if (ret)
429 : : return ret;
430 : :
431 : : strcpy(args.if_name, if_name);
432 : 0 : args.link_status = link_status;
433 : :
434 : 0 : ret = ioctl(fd, DPAA_IOCTL_UPDATE_LINK_STATUS, &args);
435 [ # # ]: 0 : if (ret) {
436 [ # # ]: 0 : if (errno == EINVAL)
437 : : printf("Failed to set link status: Not Supported\n");
438 : : else
439 : : printf("Failed to set link status");
440 : 0 : return ret;
441 : : }
442 : :
443 : : return 0;
444 : : }
445 : :
446 : : #define DPAA_IOCTL_UPDATE_LINK_SPEED \
447 : : _IOW(DPAA_IOCTL_MAGIC, 0x12, struct usdpaa_ioctl_update_link_speed)
448 : :
449 : 0 : int dpaa_update_link_speed(char *if_name, int link_speed, int link_duplex)
450 : : {
451 : : struct usdpaa_ioctl_update_link_speed args;
452 : : int ret;
453 : :
454 : 0 : ret = check_fd();
455 [ # # ]: 0 : if (ret)
456 : : return ret;
457 : :
458 : : strcpy(args.if_name, if_name);
459 : 0 : args.link_speed = link_speed;
460 : 0 : args.link_duplex = link_duplex;
461 : :
462 : 0 : ret = ioctl(fd, DPAA_IOCTL_UPDATE_LINK_SPEED, &args);
463 [ # # ]: 0 : if (ret) {
464 [ # # ]: 0 : if (errno == EINVAL)
465 : : printf("Failed to set link speed: Not Supported\n");
466 : : else
467 : : printf("Failed to set link speed\n");
468 : 0 : return ret;
469 : : }
470 : :
471 : : return ret;
472 : : }
473 : :
474 : : #define DPAA_IOCTL_RESTART_LINK_AUTONEG \
475 : : _IOW(DPAA_IOCTL_MAGIC, 0x13, char[IF_NAME_MAX_LEN])
476 : :
477 : 0 : int dpaa_restart_link_autoneg(char *if_name)
478 : : {
479 : 0 : int ret = check_fd();
480 : :
481 [ # # ]: 0 : if (ret)
482 : : return ret;
483 : :
484 : 0 : ret = ioctl(fd, DPAA_IOCTL_RESTART_LINK_AUTONEG, if_name);
485 [ # # ]: 0 : if (ret) {
486 [ # # ]: 0 : if (errno == EINVAL)
487 : : printf("Failed to restart autoneg: Not Supported\n");
488 : : else
489 : : printf("Failed to restart autoneg\n");
490 : 0 : return ret;
491 : : }
492 : :
493 : : return ret;
494 : : }
|