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