dev: new device driver infra
[vpp.git] / src / vnet / dev / counters.h
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright (c) 2023 Cisco Systems, Inc.
3  */
4
5 #ifndef _VNET_DEV_COUNTERS_H_
6 #define _VNET_DEV_COUNTERS_H_
7
8 #include <vnet/dev/dev.h>
9
10 typedef enum
11 {
12   VNET_DEV_CTR_DIR_NA,
13   VNET_DEV_CTR_DIR_RX,
14   VNET_DEV_CTR_DIR_TX,
15 } __clib_packed vnet_dev_counter_direction_t;
16
17 typedef enum
18 {
19   VNET_DEV_CTR_TYPE_RX_BYTES,
20   VNET_DEV_CTR_TYPE_RX_PACKETS,
21   VNET_DEV_CTR_TYPE_RX_DROPS,
22   VNET_DEV_CTR_TYPE_TX_BYTES,
23   VNET_DEV_CTR_TYPE_TX_PACKETS,
24   VNET_DEV_CTR_TYPE_TX_DROPS,
25   VNET_DEV_CTR_TYPE_VENDOR,
26 } __clib_packed vnet_dev_counter_type_t;
27
28 typedef enum
29 {
30   VNET_DEV_CTR_UNIT_NA,
31   VNET_DEV_CTR_UNIT_BYTES,
32   VNET_DEV_CTR_UNIT_PACKETS,
33 } __clib_packed vnet_dev_counter_unit_t;
34
35 typedef struct vnet_dev_counter
36 {
37   char name[24];
38   uword user_data;
39   vnet_dev_counter_type_t type;
40   vnet_dev_counter_direction_t dir;
41   vnet_dev_counter_unit_t unit;
42   u16 index;
43 } vnet_dev_counter_t;
44
45 typedef struct vnet_dev_counter_main
46 {
47   u8 *desc;
48   u64 *counter_data;
49   u64 *counter_start;
50   u16 n_counters;
51   vnet_dev_counter_t counters[];
52 } vnet_dev_counter_main_t;
53
54 #define VNET_DEV_CTR_RX_BYTES(p, ...)                                         \
55   {                                                                           \
56     .type = VNET_DEV_CTR_TYPE_RX_BYTES, .dir = VNET_DEV_CTR_DIR_RX,           \
57     .unit = VNET_DEV_CTR_UNIT_BYTES, .user_data = (p), __VA_ARGS__            \
58   }
59 #define VNET_DEV_CTR_TX_BYTES(p, ...)                                         \
60   {                                                                           \
61     .type = VNET_DEV_CTR_TYPE_TX_BYTES, .dir = VNET_DEV_CTR_DIR_TX,           \
62     .unit = VNET_DEV_CTR_UNIT_BYTES, .user_data = (p), __VA_ARGS__            \
63   }
64 #define VNET_DEV_CTR_RX_PACKETS(p, ...)                                       \
65   {                                                                           \
66     .type = VNET_DEV_CTR_TYPE_RX_PACKETS, .dir = VNET_DEV_CTR_DIR_RX,         \
67     .unit = VNET_DEV_CTR_UNIT_PACKETS, .user_data = (p), __VA_ARGS__          \
68   }
69 #define VNET_DEV_CTR_TX_PACKETS(p, ...)                                       \
70   {                                                                           \
71     .type = VNET_DEV_CTR_TYPE_TX_PACKETS, .dir = VNET_DEV_CTR_DIR_TX,         \
72     .unit = VNET_DEV_CTR_UNIT_PACKETS, .user_data = (p), __VA_ARGS__          \
73   }
74 #define VNET_DEV_CTR_RX_DROPS(p, ...)                                         \
75   {                                                                           \
76     .type = VNET_DEV_CTR_TYPE_RX_DROPS, .dir = VNET_DEV_CTR_DIR_RX,           \
77     .unit = VNET_DEV_CTR_UNIT_PACKETS, .user_data = (p), __VA_ARGS__          \
78   }
79 #define VNET_DEV_CTR_TX_DROPS(p, ...)                                         \
80   {                                                                           \
81     .type = VNET_DEV_CTR_TYPE_TX_DROPS, .dir = VNET_DEV_CTR_DIR_TX,           \
82     .unit = VNET_DEV_CTR_UNIT_PACKETS, .user_data = (p), __VA_ARGS__          \
83   }
84 #define VNET_DEV_CTR_VENDOR(p, d, u, n, ...)                                  \
85   {                                                                           \
86     .type = VNET_DEV_CTR_TYPE_VENDOR, .user_data = (p), .name = n,            \
87     .dir = VNET_DEV_CTR_DIR_##d, .unit = VNET_DEV_CTR_UNIT_##u, __VA_ARGS__   \
88   }
89
90 vnet_dev_counter_main_t *vnet_dev_counters_alloc (vlib_main_t *,
91                                                   vnet_dev_counter_t *, u16,
92                                                   char *, ...);
93 void vnet_dev_counters_clear (vlib_main_t *, vnet_dev_counter_main_t *);
94 void vnet_dev_counters_free (vlib_main_t *, vnet_dev_counter_main_t *);
95
96 format_function_t format_vnet_dev_counters;
97 format_function_t format_vnet_dev_counters_all;
98
99 static_always_inline vnet_dev_counter_main_t *
100 vnet_dev_counter_get_main (vnet_dev_counter_t *counter)
101 {
102   return (vnet_dev_counter_main_t *) ((u8 *) (counter - counter->index) -
103                                       STRUCT_OFFSET_OF (
104                                         vnet_dev_counter_main_t, counters));
105 }
106
107 static_always_inline void
108 vnet_dev_counter_value_add (vlib_main_t *vm, vnet_dev_counter_t *counter,
109                             u64 val)
110 {
111   vnet_dev_counter_main_t *cm = vnet_dev_counter_get_main (counter);
112   cm->counter_data[counter->index] += val;
113 }
114
115 static_always_inline void
116 vnet_dev_counter_value_update (vlib_main_t *vm, vnet_dev_counter_t *counter,
117                                u64 val)
118 {
119   vnet_dev_counter_main_t *cm = vnet_dev_counter_get_main (counter);
120   cm->counter_data[counter->index] = val - cm->counter_start[counter->index];
121 }
122
123 #define foreach_vnet_dev_counter(c, cm)                                       \
124   if (cm)                                                                     \
125     for (typeof (*(cm)->counters) *(c) = (cm)->counters;                      \
126          (c) < (cm)->counters + (cm)->n_counters; (c)++)
127
128 #endif /* _VNET_DEV_COUNTERS_H_ */