Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2022 Corigine, Inc.
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include "nfp_mtr.h"
7 : :
8 : : #include <rte_alarm.h>
9 : : #include <rte_malloc.h>
10 : : #include <rte_mtr_driver.h>
11 : :
12 : : #include "flower/nfp_flower_representor.h"
13 : : #include "nfp_logs.h"
14 : :
15 : : #ifndef LIST_FOREACH_SAFE
16 : : #define LIST_FOREACH_SAFE(var, head, field, tvar) \
17 : : for ((var) = LIST_FIRST((head)); \
18 : : (var) && ((tvar) = LIST_NEXT((var), field), 1); \
19 : : (var) = (tvar))
20 : : #endif
21 : :
22 : : #define NFP_MAX_POLICY_CNT NFP_MAX_MTR_CNT
23 : : #define NFP_MAX_PROFILE_CNT NFP_MAX_MTR_CNT
24 : :
25 : : #define NFP_FL_QOS_PPS RTE_BIT32(15)
26 : : #define NFP_FL_QOS_METER RTE_BIT32(10)
27 : : #define NFP_FL_QOS_RFC2697 RTE_BIT32(0)
28 : :
29 : : /* Alarm timeout value in microseconds */
30 : : #define NFP_METER_STATS_INTERVAL 1000000 /* 1 second */
31 : :
32 : : /**
33 : : * Callback to get MTR capabilities.
34 : : *
35 : : * @param[in] dev
36 : : * Pointer to the device (unused).
37 : : * @param[out] cap
38 : : * Pointer to the meter object capabilities.
39 : : * @param[out] error
40 : : * Pointer to the error (unused).
41 : : *
42 : : * @returns
43 : : * 0 on success, a negative value otherwise and rte_errno is set.
44 : : */
45 : : static int
46 : 0 : nfp_mtr_cap_get(struct rte_eth_dev *dev __rte_unused,
47 : : struct rte_mtr_capabilities *cap,
48 : : struct rte_mtr_error *error)
49 : : {
50 [ # # ]: 0 : if (cap == NULL) {
51 : 0 : return -rte_mtr_error_set(error, EINVAL,
52 : : RTE_MTR_ERROR_TYPE_UNSPECIFIED,
53 : : NULL, "NULL pointer for capabilitie argument.");
54 : : }
55 : :
56 : : memset(cap, 0, sizeof(struct rte_mtr_capabilities));
57 : :
58 : 0 : cap->n_max = NFP_MAX_MTR_CNT;
59 : 0 : cap->n_shared_max = NFP_MAX_MTR_CNT;
60 : 0 : cap->identical = 1;
61 : 0 : cap->shared_identical = 1;
62 : 0 : cap->chaining_n_mtrs_per_flow_max = 1;
63 : 0 : cap->meter_srtcm_rfc2697_n_max = NFP_MAX_MTR_CNT;
64 : 0 : cap->meter_trtcm_rfc2698_n_max = NFP_MAX_MTR_CNT;
65 : 0 : cap->meter_rate_max = UINT64_MAX;
66 : 0 : cap->meter_policy_n_max = NFP_MAX_POLICY_CNT;
67 : 0 : cap->srtcm_rfc2697_byte_mode_supported = 1;
68 : 0 : cap->srtcm_rfc2697_packet_mode_supported = 1;
69 : 0 : cap->trtcm_rfc2698_byte_mode_supported = 1;
70 : 0 : cap->trtcm_rfc2698_packet_mode_supported = 1;
71 : 0 : cap->stats_mask = RTE_MTR_STATS_N_PKTS_GREEN |
72 : : RTE_MTR_STATS_N_PKTS_DROPPED |
73 : : RTE_MTR_STATS_N_BYTES_GREEN |
74 : : RTE_MTR_STATS_N_BYTES_DROPPED;
75 : :
76 : 0 : return 0;
77 : : }
78 : :
79 : : static int
80 : 0 : nfp_mtr_profile_validate(uint32_t mtr_profile_id,
81 : : struct rte_mtr_meter_profile *profile,
82 : : struct rte_mtr_error *error)
83 : : {
84 : : /* Profile must not be NULL. */
85 [ # # ]: 0 : if (profile == NULL) {
86 : 0 : return -rte_mtr_error_set(error, EINVAL,
87 : : RTE_MTR_ERROR_TYPE_METER_PROFILE,
88 : : NULL, "Meter profile is null.");
89 : : }
90 : :
91 : : /* Meter profile ID must be valid. */
92 [ # # ]: 0 : if (mtr_profile_id >= NFP_MAX_PROFILE_CNT) {
93 : 0 : return -rte_mtr_error_set(error, EINVAL,
94 : : RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
95 : : NULL, "Meter profile id not valid.");
96 : : }
97 : :
98 [ # # # ]: 0 : switch (profile->alg) {
99 : : case RTE_MTR_SRTCM_RFC2697:
100 : : case RTE_MTR_TRTCM_RFC2698:
101 : : return 0;
102 : : case RTE_MTR_TRTCM_RFC4115:
103 : 0 : return -rte_mtr_error_set(error, ENOTSUP,
104 : : RTE_MTR_ERROR_TYPE_METER_PROFILE,
105 : : NULL, "Unsupported metering algorithm.");
106 : : default:
107 : 0 : return -rte_mtr_error_set(error, ENOTSUP,
108 : : RTE_MTR_ERROR_TYPE_METER_PROFILE,
109 : : NULL, "Unknown metering algorithm.");
110 : : }
111 : : }
112 : :
113 : : static void
114 : 0 : nfp_mtr_profile_config_2698(uint32_t mtr_profile_id,
115 : : struct rte_mtr_meter_profile *profile,
116 : : struct nfp_profile_conf *conf)
117 : : {
118 [ # # ]: 0 : if (profile->packet_mode != 0)
119 : 0 : conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_PPS);
120 : :
121 : 0 : conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_METER);
122 [ # # ]: 0 : conf->head.profile_id = rte_cpu_to_be_32(mtr_profile_id);
123 : :
124 [ # # ]: 0 : conf->bkt_tkn_c = rte_cpu_to_be_32(profile->trtcm_rfc2698.cbs);
125 [ # # ]: 0 : conf->bkt_tkn_p = rte_cpu_to_be_32(profile->trtcm_rfc2698.pbs);
126 [ # # ]: 0 : conf->cbs = rte_cpu_to_be_32(profile->trtcm_rfc2698.cbs);
127 [ # # ]: 0 : conf->pbs = rte_cpu_to_be_32(profile->trtcm_rfc2698.pbs);
128 [ # # ]: 0 : conf->cir = rte_cpu_to_be_32(profile->trtcm_rfc2698.cir);
129 [ # # ]: 0 : conf->pir = rte_cpu_to_be_32(profile->trtcm_rfc2698.pir);
130 : 0 : }
131 : :
132 : : static void
133 : 0 : nfp_mtr_profile_config_2697(uint32_t mtr_profile_id,
134 : : struct rte_mtr_meter_profile *profile,
135 : : struct nfp_profile_conf *conf)
136 : : {
137 [ # # ]: 0 : if (profile->packet_mode != 0)
138 : 0 : conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_PPS);
139 : :
140 : 0 : conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_RFC2697);
141 : 0 : conf->head.flags_opts |= rte_cpu_to_be_32(NFP_FL_QOS_METER);
142 [ # # ]: 0 : conf->head.profile_id = rte_cpu_to_be_32(mtr_profile_id);
143 : :
144 [ # # ]: 0 : conf->bkt_tkn_c = rte_cpu_to_be_32(profile->srtcm_rfc2697.cbs);
145 [ # # ]: 0 : conf->bkt_tkn_p = rte_cpu_to_be_32(profile->srtcm_rfc2697.ebs);
146 [ # # ]: 0 : conf->cbs = rte_cpu_to_be_32(profile->srtcm_rfc2697.cbs);
147 [ # # ]: 0 : conf->pbs = rte_cpu_to_be_32(profile->srtcm_rfc2697.ebs);
148 [ # # ]: 0 : conf->cir = rte_cpu_to_be_32(profile->srtcm_rfc2697.cir);
149 [ # # ]: 0 : conf->pir = rte_cpu_to_be_32(profile->srtcm_rfc2697.cir);
150 : 0 : }
151 : :
152 : : static int
153 : 0 : nfp_mtr_profile_conf_mod(uint32_t mtr_profile_id,
154 : : struct rte_mtr_meter_profile *profile,
155 : : struct nfp_profile_conf *conf)
156 : : {
157 [ # # # # ]: 0 : switch (profile->alg) {
158 : 0 : case RTE_MTR_SRTCM_RFC2697:
159 : 0 : nfp_mtr_profile_config_2697(mtr_profile_id, profile, conf);
160 : 0 : return 0;
161 : 0 : case RTE_MTR_TRTCM_RFC2698:
162 : 0 : nfp_mtr_profile_config_2698(mtr_profile_id, profile, conf);
163 : 0 : return 0;
164 : : case RTE_MTR_TRTCM_RFC4115:
165 : : return -ENOTSUP;
166 : 0 : default:
167 : 0 : return -EINVAL;
168 : : }
169 : : }
170 : :
171 : : static int
172 : : nfp_mtr_profile_conf_insert(uint32_t mtr_profile_id,
173 : : struct rte_mtr_meter_profile *profile,
174 : : struct nfp_mtr_profile *mtr_profile)
175 : : {
176 : 0 : mtr_profile->profile_id = mtr_profile_id;
177 : 0 : mtr_profile->in_use = false;
178 : :
179 : 0 : return nfp_mtr_profile_conf_mod(mtr_profile_id, profile,
180 : : &mtr_profile->conf);
181 : : }
182 : :
183 : : static struct nfp_mtr_profile *
184 : : nfp_mtr_profile_search(struct nfp_mtr_priv *priv, uint32_t mtr_profile_id)
185 : : {
186 : : struct nfp_mtr_profile *mtr_profile;
187 : :
188 [ # # # # : 0 : LIST_FOREACH(mtr_profile, &priv->profiles, next)
# # # # ]
189 [ # # # # : 0 : if (mtr_profile->profile_id == mtr_profile_id)
# # # # ]
190 : : break;
191 : :
192 : : return mtr_profile;
193 : : }
194 : :
195 : : static int
196 : 0 : nfp_mtr_profile_insert(struct nfp_app_fw_flower *app_fw_flower,
197 : : struct rte_mtr_meter_profile *profile,
198 : : uint32_t mtr_profile_id,
199 : : struct rte_mtr_error *error)
200 : : {
201 : : int ret;
202 : : struct nfp_mtr_priv *priv;
203 : : struct nfp_mtr_profile *mtr_profile;
204 : :
205 : 0 : priv = app_fw_flower->mtr_priv;
206 : :
207 : : /* Meter profile memory allocation. */
208 : 0 : mtr_profile = rte_zmalloc(NULL, sizeof(struct nfp_mtr_profile), 0);
209 [ # # ]: 0 : if (mtr_profile == NULL) {
210 : 0 : return -rte_mtr_error_set(error, ENOMEM,
211 : : RTE_MTR_ERROR_TYPE_UNSPECIFIED,
212 : : NULL, "Meter profile alloc failed.");
213 : : }
214 : :
215 : : ret = nfp_mtr_profile_conf_insert(mtr_profile_id,
216 : : profile, mtr_profile);
217 [ # # ]: 0 : if (ret != 0) {
218 : : rte_mtr_error_set(error, EINVAL,
219 : : RTE_MTR_ERROR_TYPE_UNSPECIFIED,
220 : : NULL, "Insert profile config failed.");
221 : 0 : goto free_profile;
222 : : }
223 : :
224 : 0 : ret = nfp_flower_cmsg_qos_add(app_fw_flower, &mtr_profile->conf);
225 [ # # ]: 0 : if (ret != 0) {
226 : : rte_mtr_error_set(error, EINVAL,
227 : : RTE_MTR_ERROR_TYPE_UNSPECIFIED,
228 : : NULL, "Add meter to firmware failed.");
229 : 0 : goto free_profile;
230 : : }
231 : :
232 : : /* Insert profile into profile list */
233 [ # # ]: 0 : LIST_INSERT_HEAD(&priv->profiles, mtr_profile, next);
234 : :
235 : 0 : return 0;
236 : :
237 : 0 : free_profile:
238 : 0 : rte_free(mtr_profile);
239 : :
240 : 0 : return ret;
241 : : }
242 : :
243 : : static int
244 : 0 : nfp_mtr_profile_mod(struct nfp_app_fw_flower *app_fw_flower,
245 : : struct rte_mtr_meter_profile *profile,
246 : : struct nfp_mtr_profile *mtr_profile,
247 : : struct rte_mtr_error *error)
248 : : {
249 : : int ret;
250 : : struct nfp_profile_conf old_conf;
251 : :
252 : : /* Get the old profile config */
253 [ # # ]: 0 : rte_memcpy(&old_conf, &mtr_profile->conf, sizeof(old_conf));
254 : :
255 : : memset(&mtr_profile->conf, 0, sizeof(struct nfp_profile_conf));
256 : :
257 : 0 : ret = nfp_mtr_profile_conf_mod(mtr_profile->profile_id,
258 : : profile, &mtr_profile->conf);
259 [ # # ]: 0 : if (ret != 0) {
260 : : rte_mtr_error_set(error, EINVAL,
261 : : RTE_MTR_ERROR_TYPE_UNSPECIFIED,
262 : : NULL, "Mod profile config failed.");
263 : 0 : goto rollback;
264 : : }
265 : :
266 : 0 : ret = nfp_flower_cmsg_qos_add(app_fw_flower, &mtr_profile->conf);
267 [ # # ]: 0 : if (ret != 0) {
268 : : rte_mtr_error_set(error, EINVAL,
269 : : RTE_MTR_ERROR_TYPE_UNSPECIFIED,
270 : : NULL, "Mod meter to firmware failed.");
271 : 0 : goto rollback;
272 : : }
273 : :
274 : : return 0;
275 : :
276 [ # # ]: 0 : rollback:
277 : : rte_memcpy(&mtr_profile->conf, &old_conf, sizeof(old_conf));
278 : :
279 : : return ret;
280 : : }
281 : :
282 : : /**
283 : : * Callback to add MTR profile.
284 : : *
285 : : * @param[in] dev
286 : : * Pointer to Ethernet device.
287 : : * @param[in] mtr_profile_id
288 : : * Meter profile id.
289 : : * @param[in] profile
290 : : * Pointer to meter profile detail.
291 : : * @param[out] error
292 : : * Pointer to the error structure.
293 : : *
294 : : * @return
295 : : * 0 on success, a negative value otherwise and rte_errno is set.
296 : : */
297 : : static int
298 : 0 : nfp_mtr_profile_add(struct rte_eth_dev *dev,
299 : : uint32_t mtr_profile_id,
300 : : struct rte_mtr_meter_profile *profile,
301 : : struct rte_mtr_error *error)
302 : : {
303 : : int ret;
304 : : struct nfp_mtr_priv *priv;
305 : : struct nfp_mtr_profile *mtr_profile;
306 : : struct nfp_app_fw_flower *app_fw_flower;
307 : : struct nfp_flower_representor *representor;
308 : :
309 : 0 : representor = dev->data->dev_private;
310 : 0 : app_fw_flower = representor->app_fw_flower;
311 : 0 : priv = app_fw_flower->mtr_priv;
312 : :
313 : : /* Check input params */
314 : 0 : ret = nfp_mtr_profile_validate(mtr_profile_id, profile, error);
315 [ # # ]: 0 : if (ret != 0)
316 : : return ret;
317 : :
318 : : /* Check if mtr profile id exist */
319 : : mtr_profile = nfp_mtr_profile_search(priv, mtr_profile_id);
320 [ # # ]: 0 : if (mtr_profile == NULL) {
321 : 0 : ret = nfp_mtr_profile_insert(app_fw_flower,
322 : : profile, mtr_profile_id, error);
323 : : } else {
324 : 0 : ret = nfp_mtr_profile_mod(app_fw_flower,
325 : : profile, mtr_profile, error);
326 : : }
327 : :
328 : : return ret;
329 : : }
330 : :
331 : : /**
332 : : * Callback to delete MTR profile.
333 : : *
334 : : * @param[in] dev
335 : : * Pointer to Ethernet device.
336 : : * @param[in] mtr_profile_id
337 : : * Meter profile id.
338 : : * @param[out] error
339 : : * Pointer to the error structure.
340 : : *
341 : : * @return
342 : : * 0 on success, a negative value otherwise and rte_errno is set.
343 : : */
344 : : static int
345 : 0 : nfp_mtr_profile_delete(struct rte_eth_dev *dev,
346 : : uint32_t mtr_profile_id,
347 : : struct rte_mtr_error *error)
348 : : {
349 : : int ret;
350 : : struct nfp_mtr_priv *priv;
351 : : struct nfp_mtr_profile *mtr_profile;
352 : : struct nfp_app_fw_flower *app_fw_flower;
353 : : struct nfp_flower_representor *representor;
354 : :
355 : 0 : representor = dev->data->dev_private;
356 : 0 : app_fw_flower = representor->app_fw_flower;
357 : 0 : priv = app_fw_flower->mtr_priv;
358 : :
359 : : /* Check if mtr profile id exist */
360 : : mtr_profile = nfp_mtr_profile_search(priv, mtr_profile_id);
361 [ # # ]: 0 : if (mtr_profile == NULL) {
362 : 0 : return -rte_mtr_error_set(error, EINVAL,
363 : : RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
364 : : NULL, "Request meter profile not exist.");
365 : : }
366 : :
367 [ # # ]: 0 : if (mtr_profile->in_use) {
368 : 0 : return -rte_mtr_error_set(error, EINVAL,
369 : : RTE_MTR_ERROR_TYPE_METER_PROFILE,
370 : : NULL, "Request meter profile is been used.");
371 : : }
372 : :
373 : 0 : ret = nfp_flower_cmsg_qos_delete(app_fw_flower, &mtr_profile->conf);
374 [ # # ]: 0 : if (ret != 0) {
375 : 0 : return -rte_mtr_error_set(error, EINVAL,
376 : : RTE_MTR_ERROR_TYPE_UNSPECIFIED,
377 : : NULL, "Delete meter from firmware failed.");
378 : : }
379 : :
380 : : /* Remove profile from profile list */
381 [ # # ]: 0 : LIST_REMOVE(mtr_profile, next);
382 : 0 : rte_free(mtr_profile);
383 : :
384 : 0 : return 0;
385 : : }
386 : :
387 : : static struct nfp_mtr_policy *
388 : : nfp_mtr_policy_search(struct nfp_mtr_priv *priv, uint32_t mtr_policy_id)
389 : : {
390 : : struct nfp_mtr_policy *mtr_policy;
391 : :
392 [ # # # # : 0 : LIST_FOREACH(mtr_policy, &priv->policies, next)
# # ]
393 [ # # # # : 0 : if (mtr_policy->policy_id == mtr_policy_id)
# # ]
394 : : break;
395 : :
396 : : return mtr_policy;
397 : : }
398 : :
399 : : static int
400 : 0 : nfp_mtr_policy_validate(uint32_t mtr_policy_id,
401 : : struct rte_mtr_meter_policy_params *policy,
402 : : struct rte_mtr_error *error)
403 : : {
404 : : const struct rte_flow_action *action;
405 : :
406 : : /* Policy must not be NULL */
407 [ # # ]: 0 : if (policy == NULL) {
408 : 0 : return -rte_mtr_error_set(error, EINVAL,
409 : : RTE_MTR_ERROR_TYPE_METER_POLICY,
410 : : NULL, "Meter policy is null.");
411 : : }
412 : :
413 : : /* Meter policy ID must be valid. */
414 [ # # ]: 0 : if (mtr_policy_id >= NFP_MAX_POLICY_CNT) {
415 : 0 : return -rte_mtr_error_set(error, EINVAL,
416 : : RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
417 : : NULL, "Meter policy id not valid.");
418 : : }
419 : :
420 : : /* Check green action
421 : : * Actions equal NULL means end action
422 : : */
423 : 0 : action = policy->actions[RTE_COLOR_GREEN];
424 [ # # # # ]: 0 : if (action != NULL && action->type != RTE_FLOW_ACTION_TYPE_VOID) {
425 : 0 : return -rte_mtr_error_set(error, EINVAL,
426 : : RTE_MTR_ERROR_TYPE_METER_POLICY,
427 : : NULL, "Green action must be void or end.");
428 : : }
429 : :
430 : : /* Check yellow action
431 : : * Actions equal NULL means end action
432 : : */
433 : 0 : action = policy->actions[RTE_COLOR_YELLOW];
434 [ # # # # ]: 0 : if (action != NULL && action->type != RTE_FLOW_ACTION_TYPE_VOID) {
435 : 0 : return -rte_mtr_error_set(error, EINVAL,
436 : : RTE_MTR_ERROR_TYPE_METER_POLICY,
437 : : NULL, "Yellow action must be void or end.");
438 : : }
439 : :
440 : : /* Check red action */
441 : 0 : action = policy->actions[RTE_COLOR_RED];
442 [ # # # # ]: 0 : if (action == NULL || action->type != RTE_FLOW_ACTION_TYPE_DROP) {
443 : 0 : return -rte_mtr_error_set(error, EINVAL,
444 : : RTE_MTR_ERROR_TYPE_METER_POLICY,
445 : : NULL, "Red action must be drop.");
446 : : }
447 : :
448 : : return 0;
449 : : }
450 : :
451 : : /**
452 : : * Callback to add MTR policy.
453 : : *
454 : : * @param[in] dev
455 : : * Pointer to Ethernet device.
456 : : * @param[in] mtr_policy_id
457 : : * Meter policy id.
458 : : * @param[in] policy
459 : : * Pointer to meter policy detail.
460 : : * @param[out] error
461 : : * Pointer to the error structure.
462 : : *
463 : : * @return
464 : : * 0 on success, a negative value otherwise and rte_errno is set.
465 : : */
466 : : static int
467 : 0 : nfp_mtr_policy_add(struct rte_eth_dev *dev,
468 : : uint32_t mtr_policy_id,
469 : : struct rte_mtr_meter_policy_params *policy,
470 : : struct rte_mtr_error *error)
471 : : {
472 : : int ret;
473 : : struct nfp_mtr_priv *priv;
474 : : struct nfp_mtr_policy *mtr_policy;
475 : : struct nfp_flower_representor *representor;
476 : :
477 : 0 : representor = dev->data->dev_private;
478 : 0 : priv = representor->app_fw_flower->mtr_priv;
479 : :
480 : : /* Check if mtr policy id exist */
481 : : mtr_policy = nfp_mtr_policy_search(priv, mtr_policy_id);
482 [ # # ]: 0 : if (mtr_policy != NULL) {
483 : 0 : return -rte_mtr_error_set(error, EEXIST,
484 : : RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
485 : : NULL, "Meter policy already exist.");
486 : : }
487 : :
488 : : /* Check input params */
489 : 0 : ret = nfp_mtr_policy_validate(mtr_policy_id, policy, error);
490 [ # # ]: 0 : if (ret != 0)
491 : : return ret;
492 : :
493 : : /* Meter policy memory alloc */
494 : 0 : mtr_policy = rte_zmalloc(NULL, sizeof(struct nfp_mtr_policy), 0);
495 [ # # ]: 0 : if (mtr_policy == NULL) {
496 : 0 : return -rte_mtr_error_set(error, ENOMEM,
497 : : RTE_MTR_ERROR_TYPE_UNSPECIFIED,
498 : : NULL, "Meter policy alloc failed.");
499 : : }
500 : :
501 : 0 : mtr_policy->policy_id = mtr_policy_id;
502 [ # # ]: 0 : rte_memcpy(&mtr_policy->policy, policy,
503 : : sizeof(struct rte_mtr_meter_policy_params));
504 : :
505 : : /* Insert policy into policy list */
506 [ # # ]: 0 : LIST_INSERT_HEAD(&priv->policies, mtr_policy, next);
507 : :
508 : 0 : return 0;
509 : : }
510 : :
511 : : /**
512 : : * Callback to delete MTR policy.
513 : : *
514 : : * @param[in] dev
515 : : * Pointer to Ethernet device.
516 : : * @param[in] mtr_policy_id
517 : : * Meter policy id.
518 : : * @param[out] error
519 : : * Pointer to the error structure.
520 : : *
521 : : * @return
522 : : * 0 on success, a negative value otherwise and rte_errno is set.
523 : : */
524 : : static int
525 : 0 : nfp_mtr_policy_delete(struct rte_eth_dev *dev,
526 : : uint32_t mtr_policy_id,
527 : : struct rte_mtr_error *error)
528 : : {
529 : : struct nfp_mtr_priv *priv;
530 : : struct nfp_mtr_policy *mtr_policy;
531 : : struct nfp_flower_representor *representor;
532 : :
533 : 0 : representor = dev->data->dev_private;
534 : 0 : priv = representor->app_fw_flower->mtr_priv;
535 : :
536 : : /* Check if mtr policy id exist */
537 : : mtr_policy = nfp_mtr_policy_search(priv, mtr_policy_id);
538 [ # # ]: 0 : if (mtr_policy == NULL) {
539 : 0 : return -rte_mtr_error_set(error, EINVAL,
540 : : RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
541 : : NULL, "Request meter policy not exist.");
542 : : }
543 : :
544 [ # # ]: 0 : if (mtr_policy->ref_cnt > 0) {
545 : 0 : return -rte_mtr_error_set(error, EBUSY,
546 : : RTE_MTR_ERROR_TYPE_METER_POLICY,
547 : : NULL, "Request mtr policy is been used.");
548 : : }
549 : :
550 : : /* Remove profile from profile list */
551 [ # # ]: 0 : LIST_REMOVE(mtr_policy, next);
552 : 0 : rte_free(mtr_policy);
553 : :
554 : 0 : return 0;
555 : : }
556 : :
557 : : struct nfp_mtr *
558 : 0 : nfp_mtr_find_by_mtr_id(struct nfp_mtr_priv *priv, uint32_t mtr_id)
559 : : {
560 : : struct nfp_mtr *mtr;
561 : :
562 [ # # ]: 0 : LIST_FOREACH(mtr, &priv->mtrs, next)
563 [ # # ]: 0 : if (mtr->mtr_id == mtr_id)
564 : : break;
565 : :
566 : 0 : return mtr;
567 : : }
568 : :
569 : : struct nfp_mtr *
570 : 0 : nfp_mtr_find_by_profile_id(struct nfp_mtr_priv *priv, uint32_t profile_id)
571 : : {
572 : : struct nfp_mtr *mtr;
573 : :
574 [ # # ]: 0 : LIST_FOREACH(mtr, &priv->mtrs, next)
575 [ # # ]: 0 : if (mtr->mtr_profile->profile_id == profile_id)
576 : : break;
577 : :
578 : 0 : return mtr;
579 : : }
580 : :
581 : : static int
582 : 0 : nfp_mtr_stats_mask_validate(uint64_t stats_mask, struct rte_mtr_error *error)
583 : : {
584 [ # # ]: 0 : if ((stats_mask & RTE_MTR_STATS_N_PKTS_YELLOW) != 0) {
585 : 0 : return -rte_mtr_error_set(error, EINVAL,
586 : : RTE_MTR_ERROR_TYPE_MTR_PARAMS,
587 : : NULL, "RTE_MTR_STATS_N_PKTS_YELLOW not support.");
588 : : }
589 : :
590 [ # # ]: 0 : if ((stats_mask & RTE_MTR_STATS_N_PKTS_RED) != 0) {
591 : 0 : return -rte_mtr_error_set(error, EINVAL,
592 : : RTE_MTR_ERROR_TYPE_MTR_PARAMS,
593 : : NULL, "RTE_MTR_STATS_N_PKTS_RED not support.");
594 : : }
595 : :
596 [ # # ]: 0 : if ((stats_mask & RTE_MTR_STATS_N_BYTES_YELLOW) != 0) {
597 : 0 : return -rte_mtr_error_set(error, EINVAL,
598 : : RTE_MTR_ERROR_TYPE_MTR_PARAMS,
599 : : NULL, "RTE_MTR_STATS_N_BYTES_YELLOW not support.");
600 : : }
601 : :
602 [ # # ]: 0 : if ((stats_mask & RTE_MTR_STATS_N_BYTES_RED) != 0) {
603 : 0 : return -rte_mtr_error_set(error, EINVAL,
604 : : RTE_MTR_ERROR_TYPE_MTR_PARAMS,
605 : : NULL, "RTE_MTR_STATS_N_BYTES_RED not support.");
606 : : }
607 : :
608 : : return 0;
609 : : }
610 : :
611 : : static int
612 : 0 : nfp_mtr_validate(uint32_t meter_id,
613 : : struct rte_mtr_params *params,
614 : : struct rte_mtr_error *error)
615 : : {
616 : : /* Params must not be NULL */
617 [ # # ]: 0 : if (params == NULL) {
618 : 0 : return -rte_mtr_error_set(error, EINVAL,
619 : : RTE_MTR_ERROR_TYPE_MTR_PARAMS,
620 : : NULL, "Meter params is null.");
621 : : }
622 : :
623 : : /* Meter policy ID must be valid. */
624 [ # # ]: 0 : if (meter_id >= NFP_MAX_MTR_CNT) {
625 : 0 : return -rte_mtr_error_set(error, EINVAL,
626 : : RTE_MTR_ERROR_TYPE_MTR_ID,
627 : : NULL, "Meter id not valid.");
628 : : }
629 : :
630 [ # # ]: 0 : if (params->use_prev_mtr_color != 0) {
631 : 0 : return -rte_mtr_error_set(error, EINVAL,
632 : : RTE_MTR_ERROR_TYPE_MTR_PARAMS,
633 : : NULL, "Feature use_prev_mtr_color not support.");
634 : : }
635 : :
636 : 0 : return nfp_mtr_stats_mask_validate(params->stats_mask, error);
637 : : }
638 : :
639 : : static void
640 : : nfp_mtr_config(uint32_t mtr_id,
641 : : int shared,
642 : : struct rte_mtr_params *params,
643 : : struct nfp_mtr_profile *mtr_profile,
644 : : struct nfp_mtr_policy *mtr_policy,
645 : : struct nfp_mtr *mtr)
646 : : {
647 : 0 : mtr->mtr_id = mtr_id;
648 : :
649 [ # # ]: 0 : if (shared != 0)
650 : 0 : mtr->shared = true;
651 : :
652 [ # # ]: 0 : if (params->meter_enable != 0)
653 : 0 : mtr->enable = true;
654 : :
655 : 0 : mtr->mtr_profile = mtr_profile;
656 : 0 : mtr->mtr_policy = mtr_policy;
657 : 0 : mtr->stats_mask = params->stats_mask;
658 : : }
659 : :
660 : : /**
661 : : * Create meter rules.
662 : : *
663 : : * @param[in] dev
664 : : * Pointer to Ethernet device.
665 : : * @param[in] mtr_id
666 : : * Meter id.
667 : : * @param[in] params
668 : : * Pointer to rte meter parameters.
669 : : * @param[in] shared
670 : : * Meter shared with other flow or not.
671 : : * @param[out] error
672 : : * Pointer to rte meter error structure.
673 : : *
674 : : * @return
675 : : * 0 on success, a negative value otherwise and rte_errno is set.
676 : : */
677 : : static int
678 : 0 : nfp_mtr_create(struct rte_eth_dev *dev,
679 : : uint32_t mtr_id,
680 : : struct rte_mtr_params *params,
681 : : int shared,
682 : : struct rte_mtr_error *error)
683 : : {
684 : : int ret;
685 : : struct nfp_mtr *mtr;
686 : : struct nfp_mtr_priv *priv;
687 : : struct nfp_mtr_policy *mtr_policy;
688 : : struct nfp_mtr_profile *mtr_profile;
689 : : struct nfp_flower_representor *representor;
690 : :
691 : 0 : representor = dev->data->dev_private;
692 : 0 : priv = representor->app_fw_flower->mtr_priv;
693 : :
694 : : /* Check if meter id exist */
695 : 0 : mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
696 [ # # ]: 0 : if (mtr != NULL) {
697 : 0 : return -rte_mtr_error_set(error, EEXIST,
698 : : RTE_MTR_ERROR_TYPE_MTR_ID,
699 : : NULL, "Meter already exist.");
700 : : }
701 : :
702 : : /* Check input meter params */
703 : 0 : ret = nfp_mtr_validate(mtr_id, params, error);
704 [ # # ]: 0 : if (ret != 0)
705 : : return ret;
706 : :
707 : 0 : mtr_profile = nfp_mtr_profile_search(priv, params->meter_profile_id);
708 [ # # ]: 0 : if (mtr_profile == NULL) {
709 : 0 : return -rte_mtr_error_set(error, EINVAL,
710 : : RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
711 : : NULL, "Request meter profile not exist.");
712 : : }
713 : :
714 [ # # ]: 0 : if (mtr_profile->in_use) {
715 : 0 : return -rte_mtr_error_set(error, EINVAL,
716 : : RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
717 : : NULL, "Request meter profile is been used.");
718 : : }
719 : :
720 : 0 : mtr_policy = nfp_mtr_policy_search(priv, params->meter_policy_id);
721 [ # # ]: 0 : if (mtr_policy == NULL) {
722 : 0 : return -rte_mtr_error_set(error, EINVAL,
723 : : RTE_MTR_ERROR_TYPE_METER_POLICY_ID,
724 : : NULL, "Request meter policy not exist.");
725 : : }
726 : :
727 : : /* Meter param memory alloc */
728 : 0 : mtr = rte_zmalloc(NULL, sizeof(struct nfp_mtr), 0);
729 [ # # ]: 0 : if (mtr == NULL) {
730 : 0 : return -rte_mtr_error_set(error, ENOMEM,
731 : : RTE_MTR_ERROR_TYPE_UNSPECIFIED,
732 : : NULL, "Meter param alloc failed.");
733 : : }
734 : :
735 : : nfp_mtr_config(mtr_id, shared, params, mtr_profile, mtr_policy, mtr);
736 : :
737 : : /* Update profile/policy status */
738 : 0 : mtr->mtr_policy->ref_cnt++;
739 : 0 : mtr->mtr_profile->in_use = true;
740 : :
741 : : /* Insert mtr into mtr list */
742 [ # # ]: 0 : LIST_INSERT_HEAD(&priv->mtrs, mtr, next);
743 : :
744 : 0 : return 0;
745 : : }
746 : :
747 : : /**
748 : : * Destroy meter rules.
749 : : *
750 : : * @param[in] dev
751 : : * Pointer to Ethernet device.
752 : : * @param[in] mtr_id
753 : : * Meter id.
754 : : * @param[out] error
755 : : * Pointer to rte meter error structure.
756 : : *
757 : : * @return
758 : : * 0 on success, a negative value otherwise and rte_errno is set.
759 : : */
760 : : static int
761 : 0 : nfp_mtr_destroy(struct rte_eth_dev *dev,
762 : : uint32_t mtr_id,
763 : : struct rte_mtr_error *error)
764 : : {
765 : : struct nfp_mtr *mtr;
766 : : struct nfp_mtr_priv *priv;
767 : : struct nfp_flower_representor *representor;
768 : :
769 : 0 : representor = dev->data->dev_private;
770 : 0 : priv = representor->app_fw_flower->mtr_priv;
771 : :
772 : : /* Check if meter id exist */
773 : 0 : mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
774 [ # # ]: 0 : if (mtr == NULL) {
775 : 0 : return -rte_mtr_error_set(error, EINVAL,
776 : : RTE_MTR_ERROR_TYPE_MTR_ID,
777 : : NULL, "Request meter not exist.");
778 : : }
779 : :
780 [ # # ]: 0 : if (mtr->ref_cnt > 0) {
781 : 0 : return -rte_mtr_error_set(error, EINVAL,
782 : : RTE_MTR_ERROR_TYPE_MTR_ID,
783 : : NULL, "Meter object is being used.");
784 : : }
785 : :
786 : : /* Update profile/policy status */
787 : 0 : mtr->mtr_policy->ref_cnt--;
788 : 0 : mtr->mtr_profile->in_use = false;
789 : :
790 : : /* Remove mtr from mtr list */
791 [ # # ]: 0 : LIST_REMOVE(mtr, next);
792 : 0 : rte_free(mtr);
793 : :
794 : 0 : return 0;
795 : : }
796 : :
797 : : /**
798 : : * Enable meter object.
799 : : *
800 : : * @param[in] dev
801 : : * Pointer to the device.
802 : : * @param[in] mtr_id
803 : : * Id of the meter.
804 : : * @param[out] error
805 : : * Pointer to the error.
806 : : *
807 : : * @returns
808 : : * 0 in success, negative value otherwise and rte_errno is set..
809 : : */
810 : : static int
811 : 0 : nfp_mtr_enable(struct rte_eth_dev *dev,
812 : : uint32_t mtr_id,
813 : : struct rte_mtr_error *error)
814 : : {
815 : : struct nfp_mtr *mtr;
816 : : struct nfp_mtr_priv *priv;
817 : : struct nfp_flower_representor *representor;
818 : :
819 : 0 : representor = dev->data->dev_private;
820 : 0 : priv = representor->app_fw_flower->mtr_priv;
821 : :
822 : : /* Check if meter id exist */
823 : 0 : mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
824 [ # # ]: 0 : if (mtr == NULL) {
825 : 0 : return -rte_mtr_error_set(error, EINVAL,
826 : : RTE_MTR_ERROR_TYPE_MTR_ID,
827 : : NULL, "Request meter not exist.");
828 : : }
829 : :
830 : 0 : mtr->enable = true;
831 : :
832 : 0 : return 0;
833 : : }
834 : :
835 : : /**
836 : : * Disable meter object.
837 : : *
838 : : * @param[in] dev
839 : : * Pointer to the device.
840 : : * @param[in] mtr_id
841 : : * Id of the meter.
842 : : * @param[out] error
843 : : * Pointer to the error.
844 : : *
845 : : * @returns
846 : : * 0 on success, negative value otherwise and rte_errno is set..
847 : : */
848 : : static int
849 : 0 : nfp_mtr_disable(struct rte_eth_dev *dev,
850 : : uint32_t mtr_id,
851 : : struct rte_mtr_error *error)
852 : : {
853 : : struct nfp_mtr *mtr;
854 : : struct nfp_mtr_priv *priv;
855 : : struct nfp_flower_representor *representor;
856 : :
857 : 0 : representor = dev->data->dev_private;
858 : 0 : priv = representor->app_fw_flower->mtr_priv;
859 : :
860 : : /* Check if meter id exist */
861 : 0 : mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
862 [ # # ]: 0 : if (mtr == NULL) {
863 : 0 : return -rte_mtr_error_set(error, EINVAL,
864 : : RTE_MTR_ERROR_TYPE_MTR_ID,
865 : : NULL, "Request meter not exist.");
866 : : }
867 : :
868 [ # # ]: 0 : if (mtr->ref_cnt > 0) {
869 : 0 : return -rte_mtr_error_set(error, EINVAL,
870 : : RTE_MTR_ERROR_TYPE_MTR_ID,
871 : : NULL, "Can not disable a used meter.");
872 : : }
873 : :
874 : 0 : mtr->enable = false;
875 : :
876 : 0 : return 0;
877 : : }
878 : :
879 : : /**
880 : : * Callback to update meter profile.
881 : : *
882 : : * @param[in] dev
883 : : * Pointer to Ethernet device.
884 : : * @param[in] mtr_id
885 : : * Meter id.
886 : : * @param[in] mtr_profile_id
887 : : * To be updated meter profile id.
888 : : * @param[out] error
889 : : * Pointer to rte meter error structure.
890 : : *
891 : : * @return
892 : : * 0 on success, a negative value otherwise and rte_errno is set.
893 : : */
894 : : static int
895 : 0 : nfp_mtr_profile_update(struct rte_eth_dev *dev,
896 : : uint32_t mtr_id,
897 : : uint32_t mtr_profile_id,
898 : : struct rte_mtr_error *error)
899 : : {
900 : : struct nfp_mtr *mtr;
901 : : struct nfp_mtr_priv *priv;
902 : : struct nfp_mtr_profile *mtr_profile;
903 : : struct nfp_flower_representor *representor;
904 : :
905 : 0 : representor = dev->data->dev_private;
906 : 0 : priv = representor->app_fw_flower->mtr_priv;
907 : :
908 : : /* Check if meter id exist */
909 : 0 : mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
910 [ # # ]: 0 : if (mtr == NULL) {
911 : 0 : return -rte_mtr_error_set(error, EINVAL,
912 : : RTE_MTR_ERROR_TYPE_MTR_ID,
913 : : NULL, "Request meter not exist.");
914 : : }
915 : :
916 [ # # ]: 0 : if (mtr->ref_cnt > 0) {
917 : 0 : return -rte_mtr_error_set(error, EINVAL,
918 : : RTE_MTR_ERROR_TYPE_MTR_ID,
919 : : NULL, "Request meter is been used.");
920 : : }
921 : :
922 [ # # ]: 0 : if (mtr->mtr_profile->profile_id == mtr_profile_id)
923 : : return 0;
924 : :
925 : : mtr_profile = nfp_mtr_profile_search(priv, mtr_profile_id);
926 [ # # ]: 0 : if (mtr_profile == NULL) {
927 : 0 : return -rte_mtr_error_set(error, EINVAL,
928 : : RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
929 : : NULL, "Request meter profile not exist.");
930 : : }
931 : :
932 [ # # ]: 0 : if (mtr_profile->in_use) {
933 : 0 : return -rte_mtr_error_set(error, EINVAL,
934 : : RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
935 : : NULL, "Request meter profile is been used.");
936 : : }
937 : :
938 : 0 : mtr_profile->in_use = true;
939 : 0 : mtr->mtr_profile->in_use = false;
940 : 0 : mtr->mtr_profile = mtr_profile;
941 : :
942 : 0 : return 0;
943 : : }
944 : :
945 : : /**
946 : : * Callback to update meter stats mask.
947 : : *
948 : : * @param[in] dev
949 : : * Pointer to Ethernet device.
950 : : * @param[in] mtr_id
951 : : * Meter id.
952 : : * @param[in] stats_mask
953 : : * To be updated stats_mask.
954 : : * @param[out] error
955 : : * Pointer to rte meter error structure.
956 : : *
957 : : * @return
958 : : * 0 on success, a negative value otherwise and rte_errno is set.
959 : : */
960 : : static int
961 : 0 : nfp_mtr_stats_update(struct rte_eth_dev *dev,
962 : : uint32_t mtr_id,
963 : : uint64_t stats_mask,
964 : : struct rte_mtr_error *error)
965 : : {
966 : : int ret;
967 : : struct nfp_mtr *mtr;
968 : : struct nfp_mtr_priv *priv;
969 : : struct nfp_flower_representor *representor;
970 : :
971 : 0 : representor = dev->data->dev_private;
972 : 0 : priv = representor->app_fw_flower->mtr_priv;
973 : :
974 : : /* Check if meter id exist */
975 : 0 : mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
976 [ # # ]: 0 : if (mtr == NULL) {
977 : 0 : return -rte_mtr_error_set(error, EEXIST,
978 : : RTE_MTR_ERROR_TYPE_MTR_ID,
979 : : NULL, "Request meter id not exist.");
980 : : }
981 : :
982 : 0 : ret = nfp_mtr_stats_mask_validate(stats_mask, error);
983 [ # # ]: 0 : if (ret != 0)
984 : : return ret;
985 : :
986 : 0 : mtr->stats_mask = stats_mask;
987 : :
988 : 0 : return 0;
989 : : }
990 : :
991 : : /**
992 : : * Callback to read meter statistics.
993 : : *
994 : : * @param[in] dev
995 : : * Pointer to Ethernet device.
996 : : * @param[in] mtr_id
997 : : * Meter id.
998 : : * @param[out] stats
999 : : * Pointer to store the statistics.
1000 : : * @param[out] stats_mask
1001 : : * Pointer to store the stats_mask.
1002 : : * @param[in] clear
1003 : : * Statistic to be cleared after read or not.
1004 : : * @param[out] error
1005 : : * Pointer to rte meter error structure.
1006 : : *
1007 : : * @return
1008 : : * 0 on success, a negative value otherwise and rte_errno is set.
1009 : : */
1010 : : static int
1011 : 0 : nfp_mtr_stats_read(struct rte_eth_dev *dev,
1012 : : uint32_t mtr_id,
1013 : : struct rte_mtr_stats *stats,
1014 : : uint64_t *stats_mask,
1015 : : int clear,
1016 : : struct rte_mtr_error *error)
1017 : : {
1018 : : struct nfp_mtr *mtr;
1019 : : struct nfp_mtr_priv *priv;
1020 : : struct nfp_mtr_stats curr;
1021 : : struct nfp_mtr_stats *prev;
1022 : : struct nfp_flower_representor *representor;
1023 : :
1024 : 0 : representor = dev->data->dev_private;
1025 : 0 : priv = representor->app_fw_flower->mtr_priv;
1026 : :
1027 : : /* Check if meter id exist */
1028 : 0 : mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
1029 [ # # ]: 0 : if (mtr == NULL) {
1030 : 0 : return -rte_mtr_error_set(error, EINVAL,
1031 : : RTE_MTR_ERROR_TYPE_MTR_ID,
1032 : : NULL, "Request meter not exist.");
1033 : : }
1034 : :
1035 : 0 : *stats_mask = mtr->stats_mask;
1036 : :
1037 : 0 : rte_spinlock_lock(&priv->mtr_stats_lock);
1038 [ # # ]: 0 : rte_memcpy(&curr, &mtr->mtr_stats.curr, sizeof(curr));
1039 : : rte_spinlock_unlock(&priv->mtr_stats_lock);
1040 : :
1041 : : prev = &mtr->mtr_stats.prev;
1042 : :
1043 : 0 : stats->n_pkts[RTE_COLOR_GREEN] = curr.pass_pkts - prev->pass_pkts;
1044 : 0 : stats->n_bytes[RTE_COLOR_GREEN] = curr.pass_bytes - prev->pass_bytes;
1045 : 0 : stats->n_pkts_dropped = curr.drop_pkts - prev->drop_pkts;
1046 : 0 : stats->n_bytes_dropped = curr.drop_bytes - prev->drop_bytes;
1047 : :
1048 [ # # ]: 0 : if (clear != 0) {
1049 : 0 : prev->pass_pkts = curr.pass_pkts;
1050 : 0 : prev->pass_bytes = curr.pass_bytes;
1051 : 0 : prev->drop_pkts = curr.drop_pkts;
1052 : 0 : prev->drop_bytes = curr.drop_bytes;
1053 : : }
1054 : :
1055 : : return 0;
1056 : : }
1057 : :
1058 : : static const struct rte_mtr_ops nfp_mtr_ops = {
1059 : : .capabilities_get = nfp_mtr_cap_get,
1060 : : .meter_profile_add = nfp_mtr_profile_add,
1061 : : .meter_profile_delete = nfp_mtr_profile_delete,
1062 : : .meter_policy_add = nfp_mtr_policy_add,
1063 : : .meter_policy_delete = nfp_mtr_policy_delete,
1064 : : .create = nfp_mtr_create,
1065 : : .destroy = nfp_mtr_destroy,
1066 : : .meter_enable = nfp_mtr_enable,
1067 : : .meter_disable = nfp_mtr_disable,
1068 : : .meter_profile_update = nfp_mtr_profile_update,
1069 : : .stats_update = nfp_mtr_stats_update,
1070 : : .stats_read = nfp_mtr_stats_read,
1071 : : };
1072 : :
1073 : : int
1074 [ # # ]: 0 : nfp_net_mtr_ops_get(struct rte_eth_dev *dev, void *arg)
1075 : : {
1076 [ # # ]: 0 : if (!rte_eth_dev_is_repr(dev)) {
1077 : 0 : PMD_DRV_LOG(ERR, "Port is not a representor.");
1078 : 0 : return -EINVAL;
1079 : : }
1080 : :
1081 : 0 : *(const struct rte_mtr_ops **)arg = &nfp_mtr_ops;
1082 : :
1083 : 0 : return 0;
1084 : : }
1085 : :
1086 : : static void
1087 : 0 : nfp_mtr_stats_request(void *arg)
1088 : : {
1089 : : struct nfp_mtr *mtr;
1090 : : struct nfp_app_fw_flower *app_fw_flower = arg;
1091 : :
1092 [ # # ]: 0 : LIST_FOREACH(mtr, &app_fw_flower->mtr_priv->mtrs, next)
1093 : 0 : nfp_flower_cmsg_qos_stats(app_fw_flower, &mtr->mtr_profile->conf.head);
1094 : :
1095 : 0 : rte_eal_alarm_set(NFP_METER_STATS_INTERVAL, nfp_mtr_stats_request, arg);
1096 : 0 : }
1097 : :
1098 : : int
1099 : 0 : nfp_mtr_priv_init(struct nfp_pf_dev *pf_dev)
1100 : : {
1101 : : int ret;
1102 : : struct nfp_mtr_priv *priv;
1103 : : struct nfp_app_fw_flower *app_fw_flower;
1104 : :
1105 : 0 : priv = rte_zmalloc("nfp_app_mtr_priv", sizeof(struct nfp_mtr_priv), 0);
1106 [ # # ]: 0 : if (priv == NULL) {
1107 : 0 : PMD_INIT_LOG(ERR, "NFP app mtr priv creation failed.");
1108 : 0 : return -ENOMEM;
1109 : : }
1110 : :
1111 : 0 : app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
1112 : 0 : app_fw_flower->mtr_priv = priv;
1113 : :
1114 : 0 : ret = rte_eal_alarm_set(NFP_METER_STATS_INTERVAL, nfp_mtr_stats_request,
1115 : : (void *)app_fw_flower);
1116 [ # # ]: 0 : if (ret < 0) {
1117 : 0 : PMD_INIT_LOG(ERR, "NFP mtr timer init failed.");
1118 : 0 : rte_free(priv);
1119 : 0 : return ret;
1120 : : }
1121 : :
1122 : 0 : LIST_INIT(&priv->mtrs);
1123 : 0 : LIST_INIT(&priv->profiles);
1124 : 0 : LIST_INIT(&priv->policies);
1125 : :
1126 : : rte_spinlock_init(&priv->mtr_stats_lock);
1127 : :
1128 : 0 : return 0;
1129 : : }
1130 : :
1131 : : void
1132 : 0 : nfp_mtr_priv_uninit(struct nfp_pf_dev *pf_dev)
1133 : : {
1134 : : struct nfp_mtr *mtr, *tmp_mtr;
1135 : : struct nfp_mtr_priv *priv;
1136 : : struct nfp_mtr_policy *mtr_policy, *tmp_policy;
1137 : : struct nfp_mtr_profile *mtr_profile, *tmp_profile;
1138 : : struct nfp_app_fw_flower *app_fw_flower;
1139 : :
1140 : 0 : app_fw_flower = NFP_PRIV_TO_APP_FW_FLOWER(pf_dev->app_fw_priv);
1141 : 0 : priv = app_fw_flower->mtr_priv;
1142 : :
1143 : 0 : rte_eal_alarm_cancel(nfp_mtr_stats_request, (void *)app_fw_flower);
1144 : :
1145 [ # # ]: 0 : LIST_FOREACH_SAFE(mtr, &priv->mtrs, next, tmp_mtr) {
1146 [ # # ]: 0 : LIST_REMOVE(mtr, next);
1147 : 0 : rte_free(mtr);
1148 : : }
1149 : :
1150 [ # # ]: 0 : LIST_FOREACH_SAFE(mtr_profile, &priv->profiles, next, tmp_profile) {
1151 [ # # ]: 0 : LIST_REMOVE(mtr_profile, next);
1152 : 0 : rte_free(mtr_profile);
1153 : : }
1154 : :
1155 [ # # ]: 0 : LIST_FOREACH_SAFE(mtr_policy, &priv->policies, next, tmp_policy) {
1156 [ # # ]: 0 : LIST_REMOVE(mtr_policy, next);
1157 : 0 : rte_free(mtr_policy);
1158 : : }
1159 : :
1160 : 0 : rte_free(priv);
1161 : 0 : }
1162 : :
1163 : : int
1164 : 0 : nfp_mtr_update_ref_cnt(struct nfp_mtr_priv *priv,
1165 : : uint32_t mtr_id,
1166 : : bool add)
1167 : : {
1168 : : struct nfp_mtr *mtr;
1169 : :
1170 : 0 : mtr = nfp_mtr_find_by_mtr_id(priv, mtr_id);
1171 [ # # ]: 0 : if (mtr == NULL)
1172 : : return -EINVAL;
1173 : :
1174 [ # # ]: 0 : mtr->ref_cnt += add ? 1 : -1;
1175 : :
1176 : 0 : return 0;
1177 : : }
|