1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Intel Corporation
10 #include <rte_mtr_driver.h>
12 #include "rte_eth_softnic_internals.h"
15 softnic_mtr_init(struct pmd_internals *p)
17 /* Initialize meter profiles list */
18 TAILQ_INIT(&p->mtr.meter_profiles);
20 /* Initialize MTR objects list */
21 TAILQ_INIT(&p->mtr.mtrs);
27 softnic_mtr_free(struct pmd_internals *p)
29 /* Remove MTR objects */
31 struct softnic_mtr *m;
33 m = TAILQ_FIRST(&p->mtr.mtrs);
37 TAILQ_REMOVE(&p->mtr.mtrs, m, node);
41 /* Remove meter profiles */
43 struct softnic_mtr_meter_profile *mp;
45 mp = TAILQ_FIRST(&p->mtr.meter_profiles);
49 TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
54 struct softnic_mtr_meter_profile *
55 softnic_mtr_meter_profile_find(struct pmd_internals *p,
56 uint32_t meter_profile_id)
58 struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
59 struct softnic_mtr_meter_profile *mp;
61 TAILQ_FOREACH(mp, mpl, node)
62 if (meter_profile_id == mp->meter_profile_id)
69 meter_profile_check(struct rte_eth_dev *dev,
70 uint32_t meter_profile_id,
71 struct rte_mtr_meter_profile *profile,
72 struct rte_mtr_error *error)
74 struct pmd_internals *p = dev->data->dev_private;
75 struct softnic_mtr_meter_profile *mp;
77 /* Meter profile ID must be valid. */
78 if (meter_profile_id == UINT32_MAX)
79 return -rte_mtr_error_set(error,
81 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
83 "Meter profile id not valid");
85 /* Meter profile must not exist. */
86 mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
88 return -rte_mtr_error_set(error,
90 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
92 "Meter prfile already exists");
94 /* Profile must not be NULL. */
96 return -rte_mtr_error_set(error,
98 RTE_MTR_ERROR_TYPE_METER_PROFILE,
102 /* Traffic metering algorithm : TRTCM_RFC2698 */
103 if (profile->alg != RTE_MTR_TRTCM_RFC2698)
104 return -rte_mtr_error_set(error,
106 RTE_MTR_ERROR_TYPE_METER_PROFILE,
108 "Metering alg not supported");
113 /* MTR meter profile add */
115 pmd_mtr_meter_profile_add(struct rte_eth_dev *dev,
116 uint32_t meter_profile_id,
117 struct rte_mtr_meter_profile *profile,
118 struct rte_mtr_error *error)
120 struct pmd_internals *p = dev->data->dev_private;
121 struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
122 struct softnic_mtr_meter_profile *mp;
125 /* Check input params */
126 status = meter_profile_check(dev, meter_profile_id, profile, error);
130 /* Memory allocation */
131 mp = calloc(1, sizeof(struct softnic_mtr_meter_profile));
133 return -rte_mtr_error_set(error,
135 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
137 "Memory alloc failed");
140 mp->meter_profile_id = meter_profile_id;
141 memcpy(&mp->params, profile, sizeof(mp->params));
144 TAILQ_INSERT_TAIL(mpl, mp, node);
149 /* MTR meter profile delete */
151 pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
152 uint32_t meter_profile_id,
153 struct rte_mtr_error *error)
155 struct pmd_internals *p = dev->data->dev_private;
156 struct softnic_mtr_meter_profile *mp;
158 /* Meter profile must exist */
159 mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
161 return -rte_mtr_error_set(error,
163 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
165 "Meter profile id invalid");
169 return -rte_mtr_error_set(error,
171 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
173 "Meter profile in use");
175 /* Remove from list */
176 TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
183 softnic_mtr_find(struct pmd_internals *p, uint32_t mtr_id)
185 struct softnic_mtr_list *ml = &p->mtr.mtrs;
186 struct softnic_mtr *m;
188 TAILQ_FOREACH(m, ml, node)
189 if (m->mtr_id == mtr_id)
197 mtr_check(struct pmd_internals *p,
199 struct rte_mtr_params *params,
201 struct rte_mtr_error *error)
204 if (softnic_mtr_find(p, mtr_id))
205 return -rte_mtr_error_set(error,
207 RTE_MTR_ERROR_TYPE_MTR_ID,
209 "MTR object already exists");
211 /* MTR params must not be NULL */
213 return -rte_mtr_error_set(error,
215 RTE_MTR_ERROR_TYPE_MTR_PARAMS,
217 "MTR object params null");
219 /* Previous meter color not supported */
220 if (params->use_prev_mtr_color)
221 return -rte_mtr_error_set(error,
223 RTE_MTR_ERROR_TYPE_MTR_PARAMS,
225 "Previous meter color not supported");
227 /* Shared MTR object not supported */
229 return -rte_mtr_error_set(error,
231 RTE_MTR_ERROR_TYPE_SHARED,
233 "Shared MTR object not supported");
238 /* MTR object create */
240 pmd_mtr_create(struct rte_eth_dev *dev,
242 struct rte_mtr_params *params,
244 struct rte_mtr_error *error)
246 struct pmd_internals *p = dev->data->dev_private;
247 struct softnic_mtr_list *ml = &p->mtr.mtrs;
248 struct softnic_mtr_meter_profile *mp;
249 struct softnic_mtr *m;
252 /* Check parameters */
253 status = mtr_check(p, mtr_id, params, shared, error);
257 /* Meter profile must exist */
258 mp = softnic_mtr_meter_profile_find(p, params->meter_profile_id);
260 return -rte_mtr_error_set(error,
262 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
264 "Meter profile id not valid");
266 /* Memory allocation */
267 m = calloc(1, sizeof(struct softnic_mtr));
269 return -rte_mtr_error_set(error,
271 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
273 "Memory alloc failed");
277 memcpy(&m->params, params, sizeof(m->params));
280 TAILQ_INSERT_TAIL(ml, m, node);
282 /* Update dependencies */
288 /* MTR object destroy */
290 pmd_mtr_destroy(struct rte_eth_dev *dev,
292 struct rte_mtr_error *error)
294 struct pmd_internals *p = dev->data->dev_private;
295 struct softnic_mtr_list *ml = &p->mtr.mtrs;
296 struct softnic_mtr_meter_profile *mp;
297 struct softnic_mtr *m;
299 /* MTR object must exist */
300 m = softnic_mtr_find(p, mtr_id);
302 return -rte_mtr_error_set(error,
304 RTE_MTR_ERROR_TYPE_MTR_ID,
306 "MTR object id not valid");
308 /* MTR object must not have any owner */
310 return -rte_mtr_error_set(error,
312 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
314 "MTR object is being used");
316 /* Get meter profile */
317 mp = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
319 return -rte_mtr_error_set(error,
321 RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
323 "MTR object meter profile invalid");
325 /* Update dependencies */
328 /* Remove from list */
329 TAILQ_REMOVE(ml, m, node);
335 const struct rte_mtr_ops pmd_mtr_ops = {
336 .capabilities_get = NULL,
338 .meter_profile_add = pmd_mtr_meter_profile_add,
339 .meter_profile_delete = pmd_mtr_meter_profile_delete,
341 .create = pmd_mtr_create,
342 .destroy = pmd_mtr_destroy,
343 .meter_enable = NULL,
344 .meter_disable = NULL,
346 .meter_profile_update = NULL,
347 .meter_dscp_table_update = NULL,
348 .policer_actions_update = NULL,
349 .stats_update = NULL,