blob: 33d08ffbecd8219fcaa1d1fdf519fac31f0b95eb [file] [log] [blame]
Damjan Marion38c61912023-10-17 16:06:26 +00001/* 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
10typedef 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
17typedef 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
28typedef 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
35typedef 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
45typedef 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
90vnet_dev_counter_main_t *vnet_dev_counters_alloc (vlib_main_t *,
91 vnet_dev_counter_t *, u16,
92 char *, ...);
93void vnet_dev_counters_clear (vlib_main_t *, vnet_dev_counter_main_t *);
94void vnet_dev_counters_free (vlib_main_t *, vnet_dev_counter_main_t *);
95
96format_function_t format_vnet_dev_counters;
97format_function_t format_vnet_dev_counters_all;
98
99static_always_inline vnet_dev_counter_main_t *
100vnet_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
107static_always_inline void
108vnet_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
115static_always_inline void
116vnet_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_ */