event/sw: add device capabilities function
[dpdk.git] / drivers / event / sw / sw_evdev.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2016-2017 Intel Corporation. All rights reserved.
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *     * Redistributions in binary form must reproduce the above copyright
13  *       notice, this list of conditions and the following disclaimer in
14  *       the documentation and/or other materials provided with the
15  *       distribution.
16  *     * Neither the name of Intel Corporation nor the names of its
17  *       contributors may be used to endorse or promote products derived
18  *       from this software without specific prior written permission.
19  *
20  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include <string.h>
34
35 #include <rte_vdev.h>
36 #include <rte_memzone.h>
37 #include <rte_kvargs.h>
38 #include <rte_ring.h>
39
40 #include "sw_evdev.h"
41
42 #define EVENTDEV_NAME_SW_PMD event_sw
43 #define NUMA_NODE_ARG "numa_node"
44 #define SCHED_QUANTA_ARG "sched_quanta"
45 #define CREDIT_QUANTA_ARG "credit_quanta"
46
47 static void
48 sw_info_get(struct rte_eventdev *dev, struct rte_event_dev_info *info)
49 {
50         RTE_SET_USED(dev);
51
52         static const struct rte_event_dev_info evdev_sw_info = {
53                         .driver_name = SW_PMD_NAME,
54                         .max_event_queues = RTE_EVENT_MAX_QUEUES_PER_DEV,
55                         .max_event_queue_flows = SW_QID_NUM_FIDS,
56                         .max_event_queue_priority_levels = SW_Q_PRIORITY_MAX,
57                         .max_event_priority_levels = SW_IQS_MAX,
58                         .max_event_ports = SW_PORTS_MAX,
59                         .max_event_port_dequeue_depth = MAX_SW_CONS_Q_DEPTH,
60                         .max_event_port_enqueue_depth = MAX_SW_PROD_Q_DEPTH,
61                         .max_num_events = SW_INFLIGHT_EVENTS_TOTAL,
62                         .event_dev_cap = (RTE_EVENT_DEV_CAP_QUEUE_QOS |
63                                         RTE_EVENT_DEV_CAP_EVENT_QOS),
64         };
65
66         *info = evdev_sw_info;
67 }
68
69 static int
70 assign_numa_node(const char *key __rte_unused, const char *value, void *opaque)
71 {
72         int *socket_id = opaque;
73         *socket_id = atoi(value);
74         if (*socket_id >= RTE_MAX_NUMA_NODES)
75                 return -1;
76         return 0;
77 }
78
79 static int
80 set_sched_quanta(const char *key __rte_unused, const char *value, void *opaque)
81 {
82         int *quanta = opaque;
83         *quanta = atoi(value);
84         if (*quanta < 0 || *quanta >= 4096)
85                 return -1;
86         return 0;
87 }
88
89 static int
90 set_credit_quanta(const char *key __rte_unused, const char *value, void *opaque)
91 {
92         int *credit = opaque;
93         *credit = atoi(value);
94         if (*credit < 0 || *credit >= 128)
95                 return -1;
96         return 0;
97 }
98
99 static int
100 sw_probe(const char *name, const char *params)
101 {
102         static const struct rte_eventdev_ops evdev_sw_ops = {
103                         .dev_infos_get = sw_info_get,
104         };
105
106         static const char *const args[] = {
107                 NUMA_NODE_ARG,
108                 SCHED_QUANTA_ARG,
109                 CREDIT_QUANTA_ARG,
110                 NULL
111         };
112         struct rte_eventdev *dev;
113         struct sw_evdev *sw;
114         int socket_id = rte_socket_id();
115         int sched_quanta  = SW_DEFAULT_SCHED_QUANTA;
116         int credit_quanta = SW_DEFAULT_CREDIT_QUANTA;
117
118         if (params != NULL && params[0] != '\0') {
119                 struct rte_kvargs *kvlist = rte_kvargs_parse(params, args);
120
121                 if (!kvlist) {
122                         SW_LOG_INFO(
123                                 "Ignoring unsupported parameters when creating device '%s'\n",
124                                 name);
125                 } else {
126                         int ret = rte_kvargs_process(kvlist, NUMA_NODE_ARG,
127                                         assign_numa_node, &socket_id);
128                         if (ret != 0) {
129                                 SW_LOG_ERR(
130                                         "%s: Error parsing numa node parameter",
131                                         name);
132                                 rte_kvargs_free(kvlist);
133                                 return ret;
134                         }
135
136                         ret = rte_kvargs_process(kvlist, SCHED_QUANTA_ARG,
137                                         set_sched_quanta, &sched_quanta);
138                         if (ret != 0) {
139                                 SW_LOG_ERR(
140                                         "%s: Error parsing sched quanta parameter",
141                                         name);
142                                 rte_kvargs_free(kvlist);
143                                 return ret;
144                         }
145
146                         ret = rte_kvargs_process(kvlist, CREDIT_QUANTA_ARG,
147                                         set_credit_quanta, &credit_quanta);
148                         if (ret != 0) {
149                                 SW_LOG_ERR(
150                                         "%s: Error parsing credit quanta parameter",
151                                         name);
152                                 rte_kvargs_free(kvlist);
153                                 return ret;
154                         }
155
156                         rte_kvargs_free(kvlist);
157                 }
158         }
159
160         SW_LOG_INFO(
161                         "Creating eventdev sw device %s, numa_node=%d, sched_quanta=%d, credit_quanta=%d\n",
162                         name, socket_id, sched_quanta, credit_quanta);
163
164         dev = rte_event_pmd_vdev_init(name,
165                         sizeof(struct sw_evdev), socket_id);
166         if (dev == NULL) {
167                 SW_LOG_ERR("eventdev vdev init() failed");
168                 return -EFAULT;
169         }
170         dev->dev_ops = &evdev_sw_ops;
171
172         sw = dev->data->dev_private;
173         sw->data = dev->data;
174
175         /* copy values passed from vdev command line to instance */
176         sw->credit_update_quanta = credit_quanta;
177         sw->sched_quanta = sched_quanta;
178
179         return 0;
180 }
181
182 static int
183 sw_remove(const char *name)
184 {
185         if (name == NULL)
186                 return -EINVAL;
187
188         SW_LOG_INFO("Closing eventdev sw device %s\n", name);
189
190         return rte_event_pmd_vdev_uninit(name);
191 }
192
193 static struct rte_vdev_driver evdev_sw_pmd_drv = {
194         .probe = sw_probe,
195         .remove = sw_remove
196 };
197
198 RTE_PMD_REGISTER_VDEV(EVENTDEV_NAME_SW_PMD, evdev_sw_pmd_drv);
199 RTE_PMD_REGISTER_PARAM_STRING(event_sw, NUMA_NODE_ARG "=<int> "
200                 SCHED_QUANTA_ARG "=<int>" CREDIT_QUANTA_ARG "=<int>");