ena: Amazon Elastic Network Adapter (ENA) native driver
[vpp.git] / src / plugins / dev_ena / format.c
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright (c) 2023 Cisco Systems, Inc.
3  */
4
5 #include "vlib/pci/pci.h"
6 #include "vnet/error.h"
7 #include "vppinfra/error.h"
8 #include <vnet/vnet.h>
9 #include <vnet/dev/dev.h>
10 #include <dev_ena/ena.h>
11 #include <dev_ena/ena_defs.h>
12
13 u8 *
14 format_ena_dev_info (u8 *s, va_list *args)
15 {
16   vlib_main_t *vm = vlib_get_main ();
17   vnet_dev_format_args_t __clib_unused *a =
18     va_arg (*args, vnet_dev_format_args_t *);
19   vnet_dev_t *dev = va_arg (*args, vnet_dev_t *);
20   ena_device_t *ed = vnet_dev_get_data (dev);
21   u32 indent = format_get_indent (s) + 2;
22
23   format (s, "Elastic Network Adapter:");
24   format (s, "\n%UDevice version is %u, implementation id is %u",
25           format_white_space, indent, ed->dev_attr.device_version,
26           ed->dev_attr.impl_id);
27   format (s, "\n%Urx drops %lu, tx drops %lu", format_white_space, indent,
28           ed->aenq.rx_drops, ed->aenq.tx_drops);
29   format (s, "\n%ULast keepalive arrived ", format_white_space, indent);
30   if (ed->aenq.last_keepalive != 0.0)
31     format (s, "%.2f seconds ago",
32             vlib_time_now (vm) - ed->aenq.last_keepalive);
33   else
34     format (s, "never");
35   return s;
36 }
37
38 u8 *
39 format_ena_mem_addr (u8 *s, va_list *args)
40 {
41   ena_mem_addr_t *ema = va_arg (*args, ena_mem_addr_t *);
42   return format (s, "0x%lx", (u64) ema->addr_hi << 32 | ema->addr_lo);
43 }
44
45 u8 *
46 format_ena_tx_desc (u8 *s, va_list *args)
47 {
48   ena_tx_desc_t *d = va_arg (*args, ena_tx_desc_t *);
49   s =
50     format (s, "addr 0x%012lx", (u64) d->buff_addr_hi << 32 | d->buff_addr_lo);
51   s = format (s, " len %u", d->length);
52   s = format (s, " req_id 0x%x", d->req_id_lo | d->req_id_hi << 10);
53   if (d->header_length)
54     s = format (s, " hdr_len %u", d->header_length);
55 #define _(v, n)                                                               \
56   if ((v) < 6 && #n[0] != '_' && d->n)                                        \
57     s = format (s, " " #n " %u", d->n);
58   foreach_ena_tx_desc
59 #undef _
60     return s;
61 }
62
63 u8 *
64 format_ena_rx_desc_status (u8 *s, va_list *args)
65 {
66   ena_rx_cdesc_status_t st = va_arg (*args, ena_rx_cdesc_status_t);
67   s = format (s, "0x%x", st.as_u32);
68   if (st.as_u32 != 0)
69     {
70       int not_first_line = 0;
71       s = format (s, " -> ");
72 #define _(b, n)                                                               \
73   if (st.n)                                                                   \
74     s = format (s, "%s%s %u", not_first_line++ ? ", " : "", #n, st.n);
75       foreach_ena_rx_cdesc_status
76 #undef _
77     }
78   return s;
79 }
80
81 u8 *
82 format_ena_rx_trace (u8 *s, va_list *args)
83 {
84   vlib_main_t *vm = va_arg (*args, vlib_main_t *);
85   vlib_node_t *node = va_arg (*args, vlib_node_t *);
86   ena_rx_trace_t *t = va_arg (*args, ena_rx_trace_t *);
87   vnet_main_t *vnm = vnet_get_main ();
88   vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, t->hw_if_index);
89   u32 indent = format_get_indent (s);
90
91   s = format (
92     s, "ena: %v (%d) qid %u next-node %U length %u req-id 0x%x n-desc %u",
93     hi->name, t->hw_if_index, t->qid, format_vlib_next_node_name, vm,
94     node->index, t->next_index, t->length, t->req_id, t->n_desc);
95   s = format (s, "\n%Ustatus: %U", format_white_space, indent + 2,
96               format_ena_rx_desc_status, t->status);
97   return s;
98 }
99
100 u8 *
101 format_ena_regs (u8 *s, va_list *args)
102 {
103   vnet_dev_t *dev = va_arg (*args, vnet_dev_t *);
104   int offset = va_arg (*args, int);
105   u32 indent = format_get_indent (s);
106   u32 rv = 0, f, v;
107   u8 *s2 = 0;
108
109 #define _(o, r, rn, m)                                                        \
110   if ((offset == -1 || offset == o) && r == 1)                                \
111     {                                                                         \
112       s = format (s, "\n%U", format_white_space, indent);                     \
113       vec_reset_length (s2);                                                  \
114       s2 = format (s2, "[0x%02x] %s:", o, #rn);                               \
115       ena_reg_read (dev, o, &rv);                                             \
116       s = format (s, "%-34v = 0x%08x", s2, rv);                               \
117       f = 0;                                                                  \
118       m                                                                       \
119     }
120
121 #define __(l, fn)                                                             \
122   if (#fn[0] != '_')                                                          \
123     {                                                                         \
124       vec_reset_length (s2);                                                  \
125       s2 = format (s2, "\n%U", format_white_space, indent);                   \
126       s2 = format (s2, "  [%2u:%2u] %s", f + l - 1, f, #fn);                  \
127       s = format (s, "  %-35v = ", s2);                                       \
128       v = (rv >> f) & pow2_mask (l);                                          \
129       if (l < 3)                                                              \
130         s = format (s, "%u", v);                                              \
131       else if (l <= 8)                                                        \
132         s = format (s, "0x%02x (%u)", v, v);                                  \
133       else if (l <= 16)                                                       \
134         s = format (s, "0x%04x", v);                                          \
135       else                                                                    \
136         s = format (s, "0x%08x", v);                                          \
137     }                                                                         \
138   f += l;
139
140   foreach_ena_reg;
141 #undef _
142
143   vec_free (s2);
144
145   return s;
146 }