12228667c610c422ca16c54cb8c4baa95678176a
[dpdk.git] / drivers / net / softnic / rte_eth_softnic_meter.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Intel Corporation
3  */
4
5 #include <stdint.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include <rte_mtr.h>
10 #include <rte_mtr_driver.h>
11
12 #include "rte_eth_softnic_internals.h"
13
14 int
15 softnic_mtr_init(struct pmd_internals *p)
16 {
17         /* Initialize meter profiles list */
18         TAILQ_INIT(&p->mtr.meter_profiles);
19
20         return 0;
21 }
22
23 void
24 softnic_mtr_free(struct pmd_internals *p)
25 {
26         /* Remove meter profiles */
27         for ( ; ; ) {
28                 struct softnic_mtr_meter_profile *mp;
29
30                 mp = TAILQ_FIRST(&p->mtr.meter_profiles);
31                 if (mp == NULL)
32                         break;
33
34                 TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
35                 free(mp);
36         }
37 }
38
39 struct softnic_mtr_meter_profile *
40 softnic_mtr_meter_profile_find(struct pmd_internals *p,
41         uint32_t meter_profile_id)
42 {
43         struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
44         struct softnic_mtr_meter_profile *mp;
45
46         TAILQ_FOREACH(mp, mpl, node)
47                 if (meter_profile_id == mp->meter_profile_id)
48                         return mp;
49
50         return NULL;
51 }
52
53 static int
54 meter_profile_check(struct rte_eth_dev *dev,
55         uint32_t meter_profile_id,
56         struct rte_mtr_meter_profile *profile,
57         struct rte_mtr_error *error)
58 {
59         struct pmd_internals *p = dev->data->dev_private;
60         struct softnic_mtr_meter_profile *mp;
61
62         /* Meter profile ID must be valid. */
63         if (meter_profile_id == UINT32_MAX)
64                 return -rte_mtr_error_set(error,
65                         EINVAL,
66                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
67                         NULL,
68                         "Meter profile id not valid");
69
70         /* Meter profile must not exist. */
71         mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
72         if (mp)
73                 return -rte_mtr_error_set(error,
74                         EEXIST,
75                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
76                         NULL,
77                         "Meter prfile already exists");
78
79         /* Profile must not be NULL. */
80         if (profile == NULL)
81                 return -rte_mtr_error_set(error,
82                         EINVAL,
83                         RTE_MTR_ERROR_TYPE_METER_PROFILE,
84                         NULL,
85                         "profile null");
86
87         /* Traffic metering algorithm : TRTCM_RFC2698 */
88         if (profile->alg != RTE_MTR_TRTCM_RFC2698)
89                 return -rte_mtr_error_set(error,
90                         EINVAL,
91                         RTE_MTR_ERROR_TYPE_METER_PROFILE,
92                         NULL,
93                         "Metering alg not supported");
94
95         return 0;
96 }
97
98 /* MTR meter profile add */
99 static int
100 pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
101         uint32_t meter_profile_id,
102         struct rte_mtr_meter_profile *profile,
103         struct rte_mtr_error *error)
104 {
105         struct pmd_internals *p = dev->data->dev_private;
106         struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
107         struct softnic_mtr_meter_profile *mp;
108         int status;
109
110         /* Check input params */
111         status = meter_profile_check(dev, meter_profile_id, profile, error);
112         if (status)
113                 return status;
114
115         /* Memory allocation */
116         mp = calloc(1, sizeof(struct softnic_mtr_meter_profile));
117         if (mp == NULL)
118                 return -rte_mtr_error_set(error,
119                         ENOMEM,
120                         RTE_MTR_ERROR_TYPE_UNSPECIFIED,
121                         NULL,
122                         "Memory alloc failed");
123
124         /* Fill in */
125         mp->meter_profile_id = meter_profile_id;
126         memcpy(&mp->params, profile, sizeof(mp->params));
127
128         /* Add to list */
129         TAILQ_INSERT_TAIL(mpl, mp, node);
130
131         return 0;
132 }
133
134 const struct rte_mtr_ops pmd_mtr_ops = {
135         .capabilities_get = NULL,
136
137         .meter_profile_add = pmd_mtr_meter_profile_add,
138         .meter_profile_delete = NULL,
139
140         .create = NULL,
141         .destroy = NULL,
142         .meter_enable = NULL,
143         .meter_disable = NULL,
144
145         .meter_profile_update = NULL,
146         .meter_dscp_table_update = NULL,
147         .policer_actions_update = NULL,
148         .stats_update = NULL,
149
150         .stats_read = NULL,
151 };