New upstream version 18.11-rc1
[deb_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         /* Initialize MTR objects list */
21         TAILQ_INIT(&p->mtr.mtrs);
22
23         return 0;
24 }
25
26 void
27 softnic_mtr_free(struct pmd_internals *p)
28 {
29         /* Remove MTR objects */
30         for ( ; ; ) {
31                 struct softnic_mtr *m;
32
33                 m = TAILQ_FIRST(&p->mtr.mtrs);
34                 if (m == NULL)
35                         break;
36
37                 TAILQ_REMOVE(&p->mtr.mtrs, m, node);
38                 free(m);
39         }
40
41         /* Remove meter profiles */
42         for ( ; ; ) {
43                 struct softnic_mtr_meter_profile *mp;
44
45                 mp = TAILQ_FIRST(&p->mtr.meter_profiles);
46                 if (mp == NULL)
47                         break;
48
49                 TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
50                 free(mp);
51         }
52 }
53
54 struct softnic_mtr_meter_profile *
55 softnic_mtr_meter_profile_find(struct pmd_internals *p,
56         uint32_t meter_profile_id)
57 {
58         struct softnic_mtr_meter_profile_list *mpl = &p->mtr.meter_profiles;
59         struct softnic_mtr_meter_profile *mp;
60
61         TAILQ_FOREACH(mp, mpl, node)
62                 if (meter_profile_id == mp->meter_profile_id)
63                         return mp;
64
65         return NULL;
66 }
67
68 static int
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)
73 {
74         struct pmd_internals *p = dev->data->dev_private;
75         struct softnic_mtr_meter_profile *mp;
76
77         /* Meter profile ID must be valid. */
78         if (meter_profile_id == UINT32_MAX)
79                 return -rte_mtr_error_set(error,
80                         EINVAL,
81                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
82                         NULL,
83                         "Meter profile id not valid");
84
85         /* Meter profile must not exist. */
86         mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
87         if (mp)
88                 return -rte_mtr_error_set(error,
89                         EEXIST,
90                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
91                         NULL,
92                         "Meter prfile already exists");
93
94         /* Profile must not be NULL. */
95         if (profile == NULL)
96                 return -rte_mtr_error_set(error,
97                         EINVAL,
98                         RTE_MTR_ERROR_TYPE_METER_PROFILE,
99                         NULL,
100                         "profile null");
101
102         /* Traffic metering algorithm : TRTCM_RFC2698 */
103         if (profile->alg != RTE_MTR_TRTCM_RFC2698)
104                 return -rte_mtr_error_set(error,
105                         EINVAL,
106                         RTE_MTR_ERROR_TYPE_METER_PROFILE,
107                         NULL,
108                         "Metering alg not supported");
109
110         return 0;
111 }
112
113 /* MTR meter profile add */
114 static int
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)
119 {
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;
123         int status;
124
125         /* Check input params */
126         status = meter_profile_check(dev, meter_profile_id, profile, error);
127         if (status)
128                 return status;
129
130         /* Memory allocation */
131         mp = calloc(1, sizeof(struct softnic_mtr_meter_profile));
132         if (mp == NULL)
133                 return -rte_mtr_error_set(error,
134                         ENOMEM,
135                         RTE_MTR_ERROR_TYPE_UNSPECIFIED,
136                         NULL,
137                         "Memory alloc failed");
138
139         /* Fill in */
140         mp->meter_profile_id = meter_profile_id;
141         memcpy(&mp->params, profile, sizeof(mp->params));
142
143         /* Add to list */
144         TAILQ_INSERT_TAIL(mpl, mp, node);
145
146         return 0;
147 }
148
149 /* MTR meter profile delete */
150 static int
151 pmd_mtr_meter_profile_delete(struct rte_eth_dev *dev,
152         uint32_t meter_profile_id,
153         struct rte_mtr_error *error)
154 {
155         struct pmd_internals *p = dev->data->dev_private;
156         struct softnic_mtr_meter_profile *mp;
157
158         /* Meter profile must exist */
159         mp = softnic_mtr_meter_profile_find(p, meter_profile_id);
160         if (mp == NULL)
161                 return -rte_mtr_error_set(error,
162                         EINVAL,
163                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
164                         NULL,
165                         "Meter profile id invalid");
166
167         /* Check unused */
168         if (mp->n_users)
169                 return -rte_mtr_error_set(error,
170                         EBUSY,
171                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
172                         NULL,
173                         "Meter profile in use");
174
175         /* Remove from list */
176         TAILQ_REMOVE(&p->mtr.meter_profiles, mp, node);
177         free(mp);
178
179         return 0;
180 }
181
182 struct softnic_mtr *
183 softnic_mtr_find(struct pmd_internals *p, uint32_t mtr_id)
184 {
185         struct softnic_mtr_list *ml = &p->mtr.mtrs;
186         struct softnic_mtr *m;
187
188         TAILQ_FOREACH(m, ml, node)
189                 if (m->mtr_id == mtr_id)
190                         return m;
191
192         return NULL;
193 }
194
195
196 static int
197 mtr_check(struct pmd_internals *p,
198         uint32_t mtr_id,
199         struct rte_mtr_params *params,
200         int shared,
201         struct rte_mtr_error *error)
202 {
203         /* MTR id valid  */
204         if (softnic_mtr_find(p, mtr_id))
205                 return -rte_mtr_error_set(error,
206                         EEXIST,
207                         RTE_MTR_ERROR_TYPE_MTR_ID,
208                         NULL,
209                         "MTR object already exists");
210
211         /* MTR params must not be NULL */
212         if (params == NULL)
213                 return -rte_mtr_error_set(error,
214                         EINVAL,
215                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
216                         NULL,
217                         "MTR object params null");
218
219         /* Previous meter color not supported */
220         if (params->use_prev_mtr_color)
221                 return -rte_mtr_error_set(error,
222                         EINVAL,
223                         RTE_MTR_ERROR_TYPE_MTR_PARAMS,
224                         NULL,
225                         "Previous meter color not supported");
226
227         /* Shared MTR object not supported */
228         if (shared)
229                 return -rte_mtr_error_set(error,
230                         EINVAL,
231                         RTE_MTR_ERROR_TYPE_SHARED,
232                         NULL,
233                         "Shared MTR object not supported");
234
235         return 0;
236 }
237
238 /* MTR object create */
239 static int
240 pmd_mtr_create(struct rte_eth_dev *dev,
241         uint32_t mtr_id,
242         struct rte_mtr_params *params,
243         int shared,
244         struct rte_mtr_error *error)
245 {
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;
250         int status;
251
252         /* Check parameters */
253         status = mtr_check(p, mtr_id, params, shared, error);
254         if (status)
255                 return status;
256
257         /* Meter profile must exist */
258         mp = softnic_mtr_meter_profile_find(p, params->meter_profile_id);
259         if (mp == NULL)
260                 return -rte_mtr_error_set(error,
261                         EINVAL,
262                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
263                         NULL,
264                         "Meter profile id not valid");
265
266         /* Memory allocation */
267         m = calloc(1, sizeof(struct softnic_mtr));
268         if (m == NULL)
269                 return -rte_mtr_error_set(error,
270                         ENOMEM,
271                         RTE_MTR_ERROR_TYPE_UNSPECIFIED,
272                         NULL,
273                         "Memory alloc failed");
274
275         /* Fill in */
276         m->mtr_id = mtr_id;
277         memcpy(&m->params, params, sizeof(m->params));
278
279         /* Add to list */
280         TAILQ_INSERT_TAIL(ml, m, node);
281
282         /* Update dependencies */
283         mp->n_users++;
284
285         return 0;
286 }
287
288 /* MTR object destroy */
289 static int
290 pmd_mtr_destroy(struct rte_eth_dev *dev,
291         uint32_t mtr_id,
292         struct rte_mtr_error *error)
293 {
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;
298
299         /* MTR object must exist */
300         m = softnic_mtr_find(p, mtr_id);
301         if (m == NULL)
302                 return -rte_mtr_error_set(error,
303                         EEXIST,
304                         RTE_MTR_ERROR_TYPE_MTR_ID,
305                         NULL,
306                         "MTR object id not valid");
307
308         /* MTR object must not have any owner */
309         if (m->flow != NULL)
310                 return -rte_mtr_error_set(error,
311                         EINVAL,
312                         RTE_MTR_ERROR_TYPE_UNSPECIFIED,
313                         NULL,
314                         "MTR object is being used");
315
316         /* Get meter profile */
317         mp = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
318         if (mp == NULL)
319                 return -rte_mtr_error_set(error,
320                         EINVAL,
321                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
322                         NULL,
323                         "MTR object meter profile invalid");
324
325         /* Update dependencies */
326         mp->n_users--;
327
328         /* Remove from list */
329         TAILQ_REMOVE(ml, m, node);
330         free(m);
331
332         return 0;
333 }
334
335 /* MTR object meter profile update */
336 static int
337 pmd_mtr_meter_profile_update(struct rte_eth_dev *dev,
338         uint32_t mtr_id,
339         uint32_t meter_profile_id,
340         struct rte_mtr_error *error)
341 {
342         struct pmd_internals *p = dev->data->dev_private;
343         struct softnic_mtr_meter_profile *mp_new, *mp_old;
344         struct softnic_mtr *m;
345         int status;
346
347         /* MTR object id must be valid */
348         m = softnic_mtr_find(p, mtr_id);
349         if (m == NULL)
350                 return -rte_mtr_error_set(error,
351                         EEXIST,
352                         RTE_MTR_ERROR_TYPE_MTR_ID,
353                         NULL,
354                         "MTR object id not valid");
355
356         /* Meter profile id must be valid */
357         mp_new = softnic_mtr_meter_profile_find(p, meter_profile_id);
358         if (mp_new == NULL)
359                 return -rte_mtr_error_set(error,
360                         EINVAL,
361                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
362                         NULL,
363                         "Meter profile not valid");
364
365         /* MTR object already set to meter profile id */
366         if (m->params.meter_profile_id == meter_profile_id)
367                 return 0;
368
369         /*  MTR object owner table update */
370         if (m->flow) {
371                 uint32_t table_id = m->flow->table_id;
372                 struct softnic_table *table = &m->flow->pipeline->table[table_id];
373                 struct softnic_table_rule_action action;
374
375                 if (!softnic_pipeline_table_meter_profile_find(table,
376                         meter_profile_id)) {
377                         struct rte_table_action_meter_profile profile;
378
379                         memset(&profile, 0, sizeof(profile));
380
381                         profile.alg = RTE_TABLE_ACTION_METER_TRTCM;
382                         profile.trtcm.cir = mp_new->params.trtcm_rfc2698.cir;
383                         profile.trtcm.pir = mp_new->params.trtcm_rfc2698.pir;
384                         profile.trtcm.cbs = mp_new->params.trtcm_rfc2698.cbs;
385                         profile.trtcm.pbs = mp_new->params.trtcm_rfc2698.pbs;
386
387                         /* Add meter profile to pipeline table */
388                         status = softnic_pipeline_table_mtr_profile_add(p,
389                                         m->flow->pipeline->name,
390                                         table_id,
391                                         meter_profile_id,
392                                         &profile);
393                         if (status)
394                                 return -rte_mtr_error_set(error,
395                                         EINVAL,
396                                         RTE_MTR_ERROR_TYPE_UNSPECIFIED,
397                                         NULL,
398                                         "Table meter profile add failed");
399                 }
400
401                 /* Set meter action */
402                 memcpy(&action, &m->flow->action, sizeof(action));
403
404                 action.mtr.mtr[0].meter_profile_id = meter_profile_id;
405
406                 /* Re-add rule */
407                 status = softnic_pipeline_table_rule_add(p,
408                         m->flow->pipeline->name,
409                         table_id,
410                         &m->flow->match,
411                         &action,
412                         &m->flow->data);
413                 if (status)
414                         return -rte_mtr_error_set(error,
415                                 EINVAL,
416                                 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
417                                 NULL,
418                                 "Pipeline table rule add failed");
419
420                 /* Flow: update meter action */
421                 memcpy(&m->flow->action, &action, sizeof(m->flow->action));
422         }
423
424         mp_old = softnic_mtr_meter_profile_find(p, m->params.meter_profile_id);
425
426         /* Meter: Set meter profile */
427         m->params.meter_profile_id = meter_profile_id;
428
429         /* Update dependencies*/
430         mp_old->n_users--;
431         mp_new->n_users++;
432
433         return 0;
434 }
435
436 /* MTR object meter DSCP table update */
437 static int
438 pmd_mtr_meter_dscp_table_update(struct rte_eth_dev *dev,
439         uint32_t mtr_id,
440         enum rte_mtr_color *dscp_table,
441         struct rte_mtr_error *error)
442 {
443         struct pmd_internals *p = dev->data->dev_private;
444         struct rte_table_action_dscp_table dt;
445         struct pipeline *pipeline;
446         struct softnic_table *table;
447         struct softnic_mtr *m;
448         uint32_t table_id, i;
449         int status;
450
451         /* MTR object id must be valid */
452         m = softnic_mtr_find(p, mtr_id);
453         if (m == NULL)
454                 return -rte_mtr_error_set(error,
455                         EEXIST,
456                         RTE_MTR_ERROR_TYPE_MTR_ID,
457                         NULL,
458                         "MTR object id not valid");
459
460         /* MTR object owner valid? */
461         if (m->flow == NULL)
462                 return 0;
463
464         pipeline = m->flow->pipeline;
465         table_id = m->flow->table_id;
466         table = &pipeline->table[table_id];
467
468         memcpy(&dt, &table->dscp_table, sizeof(dt));
469         for (i = 0; i < RTE_DIM(dt.entry); i++)
470                 dt.entry[i].color = (enum rte_meter_color)dscp_table[i];
471
472         /* Update table */
473         status = softnic_pipeline_table_dscp_table_update(p,
474                         pipeline->name,
475                         table_id,
476                         UINT64_MAX,
477                         &dt);
478         if (status)
479                 return -rte_mtr_error_set(error,
480                         EINVAL,
481                         RTE_MTR_ERROR_TYPE_UNSPECIFIED,
482                         NULL,
483                         "Table action dscp table update failed");
484
485         return 0;
486 }
487
488 /* MTR object policer action update */
489 static int
490 pmd_mtr_policer_actions_update(struct rte_eth_dev *dev,
491         uint32_t mtr_id,
492         uint32_t action_mask,
493         enum rte_mtr_policer_action *actions,
494         struct rte_mtr_error *error)
495 {
496         struct pmd_internals *p = dev->data->dev_private;
497         struct softnic_mtr *m;
498         uint32_t i;
499         int status;
500
501         /* MTR object id must be valid */
502         m = softnic_mtr_find(p, mtr_id);
503         if (m == NULL)
504                 return -rte_mtr_error_set(error,
505                         EEXIST,
506                         RTE_MTR_ERROR_TYPE_MTR_ID,
507                         NULL,
508                         "MTR object id not valid");
509
510         /* Valid policer actions */
511         if (actions == NULL)
512                 return -rte_mtr_error_set(error,
513                         EINVAL,
514                         RTE_MTR_ERROR_TYPE_UNSPECIFIED,
515                         NULL,
516                         "Invalid actions");
517
518         for (i = 0; i < RTE_MTR_COLORS; i++) {
519                 if (action_mask & (1 << i)) {
520                         if (actions[i] != MTR_POLICER_ACTION_COLOR_GREEN  &&
521                                 actions[i] != MTR_POLICER_ACTION_COLOR_YELLOW &&
522                                 actions[i] != MTR_POLICER_ACTION_COLOR_RED &&
523                                 actions[i] != MTR_POLICER_ACTION_DROP) {
524                                 return -rte_mtr_error_set(error,
525                                         EINVAL,
526                                         RTE_MTR_ERROR_TYPE_UNSPECIFIED,
527                                         NULL,
528                                         " Invalid action value");
529                         }
530                 }
531         }
532
533         /* MTR object owner valid? */
534         if (m->flow) {
535                 struct pipeline *pipeline = m->flow->pipeline;
536                 struct softnic_table *table = &pipeline->table[m->flow->table_id];
537                 struct softnic_table_rule_action action;
538
539                 memcpy(&action, &m->flow->action, sizeof(action));
540
541                 /* Set action */
542                 for (i = 0; i < RTE_MTR_COLORS; i++)
543                         if (action_mask & (1 << i))
544                                 action.mtr.mtr[0].policer[i] =
545                                         (enum rte_table_action_policer)actions[i];
546
547                 /* Re-add the rule */
548                 status = softnic_pipeline_table_rule_add(p,
549                         pipeline->name,
550                         m->flow->table_id,
551                         &m->flow->match,
552                         &action,
553                         &m->flow->data);
554                 if (status)
555                         return -rte_mtr_error_set(error,
556                                 EINVAL,
557                                 RTE_MTR_ERROR_TYPE_UNSPECIFIED,
558                                 NULL,
559                                 "Pipeline table rule re-add failed");
560
561                 /* Flow: Update meter action */
562                 memcpy(&m->flow->action, &action, sizeof(m->flow->action));
563
564                 /* Reset the meter stats */
565                 rte_table_action_meter_read(table->a, m->flow->data,
566                         1, NULL, 1);
567         }
568
569         /* Meter: Update policer actions */
570         for (i = 0; i < RTE_MTR_COLORS; i++)
571                 if (action_mask & (1 << i))
572                         m->params.action[i] = actions[i];
573
574         return 0;
575 }
576
577 #define MTR_STATS_PKTS_DEFAULT (RTE_MTR_STATS_N_PKTS_GREEN | \
578                                 RTE_MTR_STATS_N_PKTS_YELLOW | \
579                                 RTE_MTR_STATS_N_PKTS_RED | \
580                                 RTE_MTR_STATS_N_PKTS_DROPPED)
581
582 #define MTR_STATS_BYTES_DEFAULT (RTE_MTR_STATS_N_BYTES_GREEN | \
583                                 RTE_MTR_STATS_N_BYTES_YELLOW | \
584                                 RTE_MTR_STATS_N_BYTES_RED | \
585                                 RTE_MTR_STATS_N_BYTES_DROPPED)
586
587 /* MTR object stats read */
588 static void
589 mtr_stats_convert(struct softnic_mtr *m,
590         struct rte_table_action_mtr_counters_tc *in,
591         struct rte_mtr_stats *out,
592         uint64_t *out_mask)
593 {
594         memset(&out, 0, sizeof(out));
595         *out_mask = 0;
596
597         if (in->n_packets_valid) {
598                 uint32_t i;
599
600                 for (i = 0; i < RTE_MTR_COLORS; i++) {
601                         if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN)
602                                 out->n_pkts[RTE_MTR_GREEN] += in->n_packets[i];
603
604                         if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW)
605                                 out->n_pkts[RTE_MTR_YELLOW] += in->n_packets[i];
606
607                         if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED)
608                                 out->n_pkts[RTE_MTR_RED] += in->n_packets[i];
609
610                         if (m->params.action[i] == MTR_POLICER_ACTION_DROP)
611                                 out->n_pkts_dropped += in->n_packets[i];
612                 }
613
614                 *out_mask |= MTR_STATS_PKTS_DEFAULT;
615         }
616
617         if (in->n_bytes_valid) {
618                 uint32_t i;
619
620                 for (i = 0; i < RTE_MTR_COLORS; i++) {
621                         if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_GREEN)
622                                 out->n_bytes[RTE_MTR_GREEN] += in->n_bytes[i];
623
624                         if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_YELLOW)
625                                 out->n_bytes[RTE_MTR_YELLOW] += in->n_bytes[i];
626
627                         if (m->params.action[i] == MTR_POLICER_ACTION_COLOR_RED)
628                                 out->n_bytes[RTE_MTR_RED] += in->n_bytes[i];
629
630                         if (m->params.action[i] == MTR_POLICER_ACTION_DROP)
631                                 out->n_bytes_dropped += in->n_bytes[i];
632                 }
633
634                 *out_mask |= MTR_STATS_BYTES_DEFAULT;
635         }
636 }
637
638 /* MTR object stats read */
639 static int
640 pmd_mtr_stats_read(struct rte_eth_dev *dev,
641         uint32_t mtr_id,
642         struct rte_mtr_stats *stats,
643         uint64_t *stats_mask,
644         int clear,
645         struct rte_mtr_error *error)
646 {
647         struct pmd_internals *p = dev->data->dev_private;
648         struct rte_table_action_mtr_counters counters;
649         struct pipeline *pipeline;
650         struct softnic_table *table;
651         struct softnic_mtr *m;
652         int status;
653
654         /* MTR object id must be valid */
655         m = softnic_mtr_find(p, mtr_id);
656         if (m == NULL)
657                 return -rte_mtr_error_set(error,
658                         EEXIST,
659                         RTE_MTR_ERROR_TYPE_MTR_ID,
660                         NULL,
661                         "MTR object id not valid");
662
663         /* MTR meter object owner valid? */
664         if (m->flow == NULL) {
665                 if (stats != NULL)
666                         memset(stats, 0, sizeof(*stats));
667
668                 if (stats_mask)
669                         *stats_mask = MTR_STATS_PKTS_DEFAULT |
670                                 MTR_STATS_BYTES_DEFAULT;
671
672                 return 0;
673         }
674
675         pipeline = m->flow->pipeline;
676         table = &pipeline->table[m->flow->table_id];
677
678         /* Meter stats read. */
679         status = rte_table_action_meter_read(table->a,
680                 m->flow->data,
681                 1,
682                 &counters,
683                 clear);
684         if (status)
685                 return -rte_mtr_error_set(error,
686                         EINVAL,
687                         RTE_MTR_ERROR_TYPE_UNSPECIFIED,
688                         NULL,
689                         "Meter stats read failed");
690
691         /* Stats format conversion. */
692         if (stats || stats_mask) {
693                 struct rte_mtr_stats s;
694                 uint64_t s_mask = 0;
695
696                 mtr_stats_convert(m,
697                         &counters.stats[0],
698                         &s,
699                         &s_mask);
700
701                 if (stats)
702                         memcpy(stats, &s, sizeof(*stats));
703
704                 if (stats_mask)
705                         *stats_mask = s_mask;
706         }
707
708         return 0;
709 }
710
711 const struct rte_mtr_ops pmd_mtr_ops = {
712         .capabilities_get = NULL,
713
714         .meter_profile_add = pmd_mtr_meter_profile_add,
715         .meter_profile_delete = pmd_mtr_meter_profile_delete,
716
717         .create = pmd_mtr_create,
718         .destroy = pmd_mtr_destroy,
719         .meter_enable = NULL,
720         .meter_disable = NULL,
721
722         .meter_profile_update = pmd_mtr_meter_profile_update,
723         .meter_dscp_table_update = pmd_mtr_meter_dscp_table_update,
724         .policer_actions_update = pmd_mtr_policer_actions_update,
725         .stats_update = NULL,
726
727         .stats_read = pmd_mtr_stats_read,
728 };