71679650efd75eca7c392053ee1ca2209d04a3ad
[deb_dpdk.git] / lib / librte_ether / rte_tm.c
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright(c) 2017 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #include <stdint.h>
35
36 #include <rte_errno.h>
37 #include "rte_ethdev.h"
38 #include "rte_tm_driver.h"
39 #include "rte_tm.h"
40
41 /* Get generic traffic manager operations structure from a port. */
42 const struct rte_tm_ops *
43 rte_tm_ops_get(uint8_t port_id, struct rte_tm_error *error)
44 {
45         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
46         const struct rte_tm_ops *ops;
47
48         if (!rte_eth_dev_is_valid_port(port_id)) {
49                 rte_tm_error_set(error,
50                         ENODEV,
51                         RTE_TM_ERROR_TYPE_UNSPECIFIED,
52                         NULL,
53                         rte_strerror(ENODEV));
54                 return NULL;
55         }
56
57         if ((dev->dev_ops->tm_ops_get == NULL) ||
58                 (dev->dev_ops->tm_ops_get(dev, &ops) != 0) ||
59                 (ops == NULL)) {
60                 rte_tm_error_set(error,
61                         ENOSYS,
62                         RTE_TM_ERROR_TYPE_UNSPECIFIED,
63                         NULL,
64                         rte_strerror(ENOSYS));
65                 return NULL;
66         }
67
68         return ops;
69 }
70
71 #define RTE_TM_FUNC(port_id, func)                              \
72 ({                                                      \
73         const struct rte_tm_ops *ops =                  \
74                 rte_tm_ops_get(port_id, error);         \
75         if (ops == NULL)                                        \
76                 return -rte_errno;                      \
77                                                         \
78         if (ops->func == NULL)                          \
79                 return -rte_tm_error_set(error,         \
80                         ENOSYS,                         \
81                         RTE_TM_ERROR_TYPE_UNSPECIFIED,  \
82                         NULL,                           \
83                         rte_strerror(ENOSYS));          \
84                                                         \
85         ops->func;                                      \
86 })
87
88 /* Get number of leaf nodes */
89 int
90 rte_tm_get_number_of_leaf_nodes(uint8_t port_id,
91         uint32_t *n_leaf_nodes,
92         struct rte_tm_error *error)
93 {
94         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
95         const struct rte_tm_ops *ops =
96                 rte_tm_ops_get(port_id, error);
97
98         if (ops == NULL)
99                 return -rte_errno;
100
101         if (n_leaf_nodes == NULL) {
102                 rte_tm_error_set(error,
103                         EINVAL,
104                         RTE_TM_ERROR_TYPE_UNSPECIFIED,
105                         NULL,
106                         rte_strerror(EINVAL));
107                 return -rte_errno;
108         }
109
110         *n_leaf_nodes = dev->data->nb_tx_queues;
111         return 0;
112 }
113
114 /* Check node type (leaf or non-leaf) */
115 int
116 rte_tm_node_type_get(uint8_t port_id,
117         uint32_t node_id,
118         int *is_leaf,
119         struct rte_tm_error *error)
120 {
121         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
122         return RTE_TM_FUNC(port_id, node_type_get)(dev,
123                 node_id, is_leaf, error);
124 }
125
126 /* Get capabilities */
127 int rte_tm_capabilities_get(uint8_t port_id,
128         struct rte_tm_capabilities *cap,
129         struct rte_tm_error *error)
130 {
131         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
132         return RTE_TM_FUNC(port_id, capabilities_get)(dev,
133                 cap, error);
134 }
135
136 /* Get level capabilities */
137 int rte_tm_level_capabilities_get(uint8_t port_id,
138         uint32_t level_id,
139         struct rte_tm_level_capabilities *cap,
140         struct rte_tm_error *error)
141 {
142         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
143         return RTE_TM_FUNC(port_id, level_capabilities_get)(dev,
144                 level_id, cap, error);
145 }
146
147 /* Get node capabilities */
148 int rte_tm_node_capabilities_get(uint8_t port_id,
149         uint32_t node_id,
150         struct rte_tm_node_capabilities *cap,
151         struct rte_tm_error *error)
152 {
153         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
154         return RTE_TM_FUNC(port_id, node_capabilities_get)(dev,
155                 node_id, cap, error);
156 }
157
158 /* Add WRED profile */
159 int rte_tm_wred_profile_add(uint8_t port_id,
160         uint32_t wred_profile_id,
161         struct rte_tm_wred_params *profile,
162         struct rte_tm_error *error)
163 {
164         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
165         return RTE_TM_FUNC(port_id, wred_profile_add)(dev,
166                 wred_profile_id, profile, error);
167 }
168
169 /* Delete WRED profile */
170 int rte_tm_wred_profile_delete(uint8_t port_id,
171         uint32_t wred_profile_id,
172         struct rte_tm_error *error)
173 {
174         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
175         return RTE_TM_FUNC(port_id, wred_profile_delete)(dev,
176                 wred_profile_id, error);
177 }
178
179 /* Add/update shared WRED context */
180 int rte_tm_shared_wred_context_add_update(uint8_t port_id,
181         uint32_t shared_wred_context_id,
182         uint32_t wred_profile_id,
183         struct rte_tm_error *error)
184 {
185         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
186         return RTE_TM_FUNC(port_id, shared_wred_context_add_update)(dev,
187                 shared_wred_context_id, wred_profile_id, error);
188 }
189
190 /* Delete shared WRED context */
191 int rte_tm_shared_wred_context_delete(uint8_t port_id,
192         uint32_t shared_wred_context_id,
193         struct rte_tm_error *error)
194 {
195         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
196         return RTE_TM_FUNC(port_id, shared_wred_context_delete)(dev,
197                 shared_wred_context_id, error);
198 }
199
200 /* Add shaper profile */
201 int rte_tm_shaper_profile_add(uint8_t port_id,
202         uint32_t shaper_profile_id,
203         struct rte_tm_shaper_params *profile,
204         struct rte_tm_error *error)
205 {
206         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
207         return RTE_TM_FUNC(port_id, shaper_profile_add)(dev,
208                 shaper_profile_id, profile, error);
209 }
210
211 /* Delete WRED profile */
212 int rte_tm_shaper_profile_delete(uint8_t port_id,
213         uint32_t shaper_profile_id,
214         struct rte_tm_error *error)
215 {
216         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
217         return RTE_TM_FUNC(port_id, shaper_profile_delete)(dev,
218                 shaper_profile_id, error);
219 }
220
221 /* Add shared shaper */
222 int rte_tm_shared_shaper_add_update(uint8_t port_id,
223         uint32_t shared_shaper_id,
224         uint32_t shaper_profile_id,
225         struct rte_tm_error *error)
226 {
227         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
228         return RTE_TM_FUNC(port_id, shared_shaper_add_update)(dev,
229                 shared_shaper_id, shaper_profile_id, error);
230 }
231
232 /* Delete shared shaper */
233 int rte_tm_shared_shaper_delete(uint8_t port_id,
234         uint32_t shared_shaper_id,
235         struct rte_tm_error *error)
236 {
237         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
238         return RTE_TM_FUNC(port_id, shared_shaper_delete)(dev,
239                 shared_shaper_id, error);
240 }
241
242 /* Add node to port traffic manager hierarchy */
243 int rte_tm_node_add(uint8_t port_id,
244         uint32_t node_id,
245         uint32_t parent_node_id,
246         uint32_t priority,
247         uint32_t weight,
248         uint32_t level_id,
249         struct rte_tm_node_params *params,
250         struct rte_tm_error *error)
251 {
252         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
253         return RTE_TM_FUNC(port_id, node_add)(dev,
254                 node_id, parent_node_id, priority, weight, level_id,
255                 params, error);
256 }
257
258 /* Delete node from traffic manager hierarchy */
259 int rte_tm_node_delete(uint8_t port_id,
260         uint32_t node_id,
261         struct rte_tm_error *error)
262 {
263         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
264         return RTE_TM_FUNC(port_id, node_delete)(dev,
265                 node_id, error);
266 }
267
268 /* Suspend node */
269 int rte_tm_node_suspend(uint8_t port_id,
270         uint32_t node_id,
271         struct rte_tm_error *error)
272 {
273         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
274         return RTE_TM_FUNC(port_id, node_suspend)(dev,
275                 node_id, error);
276 }
277
278 /* Resume node */
279 int rte_tm_node_resume(uint8_t port_id,
280         uint32_t node_id,
281         struct rte_tm_error *error)
282 {
283         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
284         return RTE_TM_FUNC(port_id, node_resume)(dev,
285                 node_id, error);
286 }
287
288 /* Commit the initial port traffic manager hierarchy */
289 int rte_tm_hierarchy_commit(uint8_t port_id,
290         int clear_on_fail,
291         struct rte_tm_error *error)
292 {
293         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
294         return RTE_TM_FUNC(port_id, hierarchy_commit)(dev,
295                 clear_on_fail, error);
296 }
297
298 /* Update node parent  */
299 int rte_tm_node_parent_update(uint8_t port_id,
300         uint32_t node_id,
301         uint32_t parent_node_id,
302         uint32_t priority,
303         uint32_t weight,
304         struct rte_tm_error *error)
305 {
306         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
307         return RTE_TM_FUNC(port_id, node_parent_update)(dev,
308                 node_id, parent_node_id, priority, weight, error);
309 }
310
311 /* Update node private shaper */
312 int rte_tm_node_shaper_update(uint8_t port_id,
313         uint32_t node_id,
314         uint32_t shaper_profile_id,
315         struct rte_tm_error *error)
316 {
317         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
318         return RTE_TM_FUNC(port_id, node_shaper_update)(dev,
319                 node_id, shaper_profile_id, error);
320 }
321
322 /* Update node shared shapers */
323 int rte_tm_node_shared_shaper_update(uint8_t port_id,
324         uint32_t node_id,
325         uint32_t shared_shaper_id,
326         int add,
327         struct rte_tm_error *error)
328 {
329         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
330         return RTE_TM_FUNC(port_id, node_shared_shaper_update)(dev,
331                 node_id, shared_shaper_id, add, error);
332 }
333
334 /* Update node stats */
335 int rte_tm_node_stats_update(uint8_t port_id,
336         uint32_t node_id,
337         uint64_t stats_mask,
338         struct rte_tm_error *error)
339 {
340         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
341         return RTE_TM_FUNC(port_id, node_stats_update)(dev,
342                 node_id, stats_mask, error);
343 }
344
345 /* Update WFQ weight mode */
346 int rte_tm_node_wfq_weight_mode_update(uint8_t port_id,
347         uint32_t node_id,
348         int *wfq_weight_mode,
349         uint32_t n_sp_priorities,
350         struct rte_tm_error *error)
351 {
352         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
353         return RTE_TM_FUNC(port_id, node_wfq_weight_mode_update)(dev,
354                 node_id, wfq_weight_mode, n_sp_priorities, error);
355 }
356
357 /* Update node congestion management mode */
358 int rte_tm_node_cman_update(uint8_t port_id,
359         uint32_t node_id,
360         enum rte_tm_cman_mode cman,
361         struct rte_tm_error *error)
362 {
363         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
364         return RTE_TM_FUNC(port_id, node_cman_update)(dev,
365                 node_id, cman, error);
366 }
367
368 /* Update node private WRED context */
369 int rte_tm_node_wred_context_update(uint8_t port_id,
370         uint32_t node_id,
371         uint32_t wred_profile_id,
372         struct rte_tm_error *error)
373 {
374         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
375         return RTE_TM_FUNC(port_id, node_wred_context_update)(dev,
376                 node_id, wred_profile_id, error);
377 }
378
379 /* Update node shared WRED context */
380 int rte_tm_node_shared_wred_context_update(uint8_t port_id,
381         uint32_t node_id,
382         uint32_t shared_wred_context_id,
383         int add,
384         struct rte_tm_error *error)
385 {
386         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
387         return RTE_TM_FUNC(port_id, node_shared_wred_context_update)(dev,
388                 node_id, shared_wred_context_id, add, error);
389 }
390
391 /* Read and/or clear stats counters for specific node */
392 int rte_tm_node_stats_read(uint8_t port_id,
393         uint32_t node_id,
394         struct rte_tm_node_stats *stats,
395         uint64_t *stats_mask,
396         int clear,
397         struct rte_tm_error *error)
398 {
399         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
400         return RTE_TM_FUNC(port_id, node_stats_read)(dev,
401                 node_id, stats, stats_mask, clear, error);
402 }
403
404 /* Packet marking - VLAN DEI */
405 int rte_tm_mark_vlan_dei(uint8_t port_id,
406         int mark_green,
407         int mark_yellow,
408         int mark_red,
409         struct rte_tm_error *error)
410 {
411         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
412         return RTE_TM_FUNC(port_id, mark_vlan_dei)(dev,
413                 mark_green, mark_yellow, mark_red, error);
414 }
415
416 /* Packet marking - IPv4/IPv6 ECN */
417 int rte_tm_mark_ip_ecn(uint8_t port_id,
418         int mark_green,
419         int mark_yellow,
420         int mark_red,
421         struct rte_tm_error *error)
422 {
423         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
424         return RTE_TM_FUNC(port_id, mark_ip_ecn)(dev,
425                 mark_green, mark_yellow, mark_red, error);
426 }
427
428 /* Packet marking - IPv4/IPv6 DSCP */
429 int rte_tm_mark_ip_dscp(uint8_t port_id,
430         int mark_green,
431         int mark_yellow,
432         int mark_red,
433         struct rte_tm_error *error)
434 {
435         struct rte_eth_dev *dev = &rte_eth_devices[port_id];
436         return RTE_TM_FUNC(port_id, mark_ip_dscp)(dev,
437                 mark_green, mark_yellow, mark_red, error);
438 }