regexdev: add core functions
[dpdk.git] / lib / librte_regexdev / rte_regexdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  * Copyright 2020 Mellanox Technologies, Ltd
4  */
5
6 #include <string.h>
7
8 #include <rte_memory.h>
9 #include <rte_memcpy.h>
10 #include <rte_memzone.h>
11 #include <rte_string_fns.h>
12
13 #include "rte_regexdev.h"
14 #include "rte_regexdev_core.h"
15 #include "rte_regexdev_driver.h"
16
17 static const char *MZ_RTE_REGEXDEV_DATA = "rte_regexdev_data";
18 static struct rte_regexdev regex_devices[RTE_MAX_REGEXDEV_DEVS];
19 /* Shared memory between primary and secondary processes. */
20 static struct {
21         struct rte_regexdev_data data[RTE_MAX_REGEXDEV_DEVS];
22 } *rte_regexdev_shared_data;
23
24 int rte_regexdev_logtype;
25
26 static uint16_t
27 regexdev_find_free_dev(void)
28 {
29         uint16_t i;
30
31         for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
32                 if (regex_devices[i].state == RTE_REGEXDEV_UNUSED)
33                         return i;
34         }
35         return RTE_MAX_REGEXDEV_DEVS;
36 }
37
38 static struct rte_regexdev*
39 regexdev_allocated(const char *name)
40 {
41         uint16_t i;
42
43         for (i = 0; i < RTE_MAX_REGEXDEV_DEVS; i++) {
44                 if (regex_devices[i].state != RTE_REGEXDEV_UNUSED)
45                         if (!strcmp(name, regex_devices[i].data->dev_name))
46                                 return &regex_devices[i];
47         }
48         return NULL;
49 }
50
51 static int
52 regexdev_shared_data_prepare(void)
53 {
54         const unsigned int flags = 0;
55         const struct rte_memzone *mz;
56
57         if (rte_regexdev_shared_data == NULL) {
58                 /* Allocate port data and ownership shared memory. */
59                 mz = rte_memzone_reserve(MZ_RTE_REGEXDEV_DATA,
60                                          sizeof(*rte_regexdev_shared_data),
61                                          rte_socket_id(), flags);
62                 if (mz == NULL)
63                         return -ENOMEM;
64
65                 rte_regexdev_shared_data = mz->addr;
66                 memset(rte_regexdev_shared_data->data, 0,
67                        sizeof(rte_regexdev_shared_data->data));
68         }
69         return 0;
70 }
71
72 static int
73 regexdev_check_name(const char *name)
74 {
75         size_t name_len;
76
77         if (name == NULL) {
78                 RTE_REGEXDEV_LOG(ERR, "Name can't be NULL\n");
79                 return -EINVAL;
80         }
81         name_len = strnlen(name, RTE_REGEXDEV_NAME_MAX_LEN);
82         if (name_len == 0) {
83                 RTE_REGEXDEV_LOG(ERR, "Zero length RegEx device name\n");
84                 return -EINVAL;
85         }
86         if (name_len >= RTE_REGEXDEV_NAME_MAX_LEN) {
87                 RTE_REGEXDEV_LOG(ERR, "RegEx device name is too long\n");
88                 return -EINVAL;
89         }
90         return (int)name_len;
91
92 }
93
94 struct rte_regexdev *
95 rte_regexdev_register(const char *name)
96 {
97         uint16_t dev_id;
98         int name_len;
99         struct rte_regexdev *dev;
100
101         name_len = regexdev_check_name(name);
102         if (name_len < 0)
103                 return NULL;
104         dev = regexdev_allocated(name);
105         if (dev != NULL) {
106                 RTE_REGEXDEV_LOG(ERR, "RegEx device already allocated\n");
107                 return NULL;
108         }
109         dev_id = regexdev_find_free_dev();
110         if (dev_id == RTE_MAX_REGEXDEV_DEVS) {
111                 RTE_REGEXDEV_LOG
112                         (ERR, "Reached maximum number of RegEx devices\n");
113                 return NULL;
114         }
115         if (regexdev_shared_data_prepare() < 0) {
116                 RTE_REGEXDEV_LOG(ERR, "Cannot allocate RegEx shared data\n");
117                 return NULL;
118         }
119
120         dev = &regex_devices[dev_id];
121         dev->state = RTE_REGEXDEV_REGISTERED;
122         if (dev->data == NULL)
123                 dev->data = &rte_regexdev_shared_data->data[dev_id];
124         else
125                 memset(dev->data, 1, sizeof(*dev->data));
126         dev->data->dev_id = dev_id;
127         strlcpy(dev->data->dev_name, name, sizeof(dev->data->dev_name));
128         return dev;
129 }
130
131 void
132 rte_regexdev_unregister(struct rte_regexdev *dev)
133 {
134         dev->state = RTE_REGEXDEV_UNUSED;
135 }
136
137 struct rte_regexdev *
138 rte_regexdev_get_device_by_name(const char *name)
139 {
140         if (regexdev_check_name(name) < 0)
141                 return NULL;
142         return regexdev_allocated(name);
143 }