ena: Amazon Elastic Network Adapter (ENA) native driver
[vpp.git] / src / plugins / dev_ena / format_aq.c
1 /* SPDX-License-Identifier: Apache-2.0
2  * Copyright(c) 2023 Cisco Systems, Inc.
3  */
4
5 #include <vlib/vlib.h>
6 #include <vnet/dev/dev.h>
7
8 #include <dev_ena/ena.h>
9 #include <dev_ena/ena_inlines.h>
10 #include <vnet/ethernet/ethernet.h>
11
12 static char *opcode_names[] = {
13 #define _(v, s) [v] = #s,
14   foreach_ena_aq_opcode
15 #undef _
16 };
17
18 static char *status_names[] = {
19 #define _(v, s) [v] = #s,
20   foreach_ena_aq_compl_status
21 #undef _
22 };
23
24 #define __maxval(s, f) (u64) (((typeof ((s)[0])){ .f = -1LL }).f)
25
26 #define __name(s, n)                                                          \
27   {                                                                           \
28     s = format (s, "%s%U%-32s: ", line ? "\n" : "", format_white_space,       \
29                 line ? indent : 0, #n);                                       \
30     line++;                                                                   \
31   }
32
33 #define _format_number(s, d, n, ...)                                          \
34   {                                                                           \
35     __name (s, n);                                                            \
36     if (d->n < 10)                                                            \
37       s = format (s, "%u", d->n);                                             \
38     else if (__maxval (d, n) <= 255)                                          \
39       s = format (s, "0x%02x (%u)", d->n, d->n);                              \
40     else if (__maxval (d, n) <= 65535)                                        \
41       s = format (s, "0x%04x (%u)", d->n, d->n);                              \
42     else                                                                      \
43       s = format (s, "0x%08x (%u)", d->n, d->n);                              \
44   }
45
46 #define _format_with_fn_and_ptr(s, c, n, f)                                   \
47   {                                                                           \
48     __name (s, n);                                                            \
49     s = format (s, "%U", f, &((c)->n));                                       \
50   }
51
52 #define _format_with_fn_and_val(s, c, n, f)                                   \
53   {                                                                           \
54     __name (s, n);                                                            \
55     s = format (s, "%U", f, (c)->n);                                          \
56   }
57 #define _format_ena_memory(s, c, n)                                           \
58   _format_with_fn_and_ptr (s, c, n, format_ena_mem_addr)
59
60 u8 *
61 format_ena_aq_opcode (u8 *s, va_list *args)
62 {
63   u32 opcode = va_arg (*args, u32);
64
65   if (opcode >= ARRAY_LEN (opcode_names) || opcode_names[opcode] == 0)
66     return format (s, "UNKNOWN(%u)", opcode);
67   return format (s, "%s", opcode_names[opcode]);
68 }
69
70 u8 *
71 format_ena_aq_status (u8 *s, va_list *args)
72 {
73   u32 status = va_arg (*args, u32);
74
75   if (status >= ARRAY_LEN (status_names) || status_names[status] == 0)
76     return format (s, "UNKNOWN(%u)", status);
77   return format (s, "%s", status_names[status]);
78 }
79
80 u8 *
81 format_ena_aq_aenq_groups (u8 *s, va_list *args)
82 {
83   ena_aq_aenq_groups_t g = va_arg (*args, ena_aq_aenq_groups_t);
84   u32 i, not_first = 0;
85   u32 indent = format_get_indent (s);
86
87 #define _(x)                                                                  \
88   if (g.x)                                                                    \
89     {                                                                         \
90       if (format_get_indent (s) > 80)                                         \
91         s = format (s, "\n%U", format_white_space, indent);                   \
92       s = format (s, "%s%s", not_first++ ? " " : "", #x);                     \
93       g.x = 0;                                                                \
94     }
95   foreach_ena_aq_aenq_groups;
96 #undef _
97
98   foreach_set_bit_index (i, g.as_u32)
99     s = format (s, "%sunknown-%u", not_first++ ? " " : "", i);
100
101   return s;
102 }
103
104 u8 *
105 format_ena_aq_feat_id_bitmap (u8 *s, va_list *args)
106 {
107   u32 bmp = va_arg (*args, u32);
108   int i, line = 0;
109   u32 indent = format_get_indent (s);
110
111   foreach_set_bit_index (i, bmp)
112     {
113       ena_aq_feat_info_t *info = ena_aq_get_feat_info (i);
114       if (line++)
115         s = format (s, ", ");
116       if (format_get_indent (s) > 80)
117         s = format (s, "\n%U", format_white_space, indent);
118       if (info)
119         s = format (s, "%s", info->name);
120       else
121         s = format (s, "unknown-%u", i);
122     }
123
124   return s;
125 }
126
127 u8 *
128 format_ena_aq_feat_name (u8 *s, va_list *args)
129 {
130   ena_aq_feature_id_t feat_id = va_arg (*args, int);
131   char *feat_names[] = {
132 #define _(v, r, gt, st, s, u) [v] = #s,
133     foreach_ena_aq_feature_id
134 #undef _
135   };
136
137   if (feat_id >= ARRAY_LEN (feat_names) || feat_names[feat_id] == 0)
138     return format (s, "UNKNOWN(%u)", feat_id);
139   return format (s, "%s", feat_names[feat_id]);
140 }
141
142 u8 *
143 format_ena_aq_feat_desc (u8 *s, va_list *args)
144 {
145   ena_aq_feature_id_t feat_id = va_arg (*args, int);
146   void *data = va_arg (*args, void *);
147   ena_aq_feat_info_t *info = ena_aq_get_feat_info (feat_id);
148   u32 indent = format_get_indent (s);
149   u32 line = 0;
150
151   switch (feat_id)
152     {
153     case ENA_ADMIN_FEAT_ID_DEVICE_ATTRIBUTES:
154       {
155         ena_aq_feat_device_attr_t *d = data;
156         _format_number (s, d, impl_id);
157         _format_number (s, d, device_version);
158         _format_number (s, d, phys_addr_width);
159         _format_number (s, d, virt_addr_width);
160         _format_with_fn_and_val (s, d, mac_addr, format_ethernet_address);
161         _format_number (s, d, max_mtu);
162         _format_with_fn_and_val (s, d, supported_features,
163                                  format_ena_aq_feat_id_bitmap);
164       }
165       break;
166
167     case ENA_ADMIN_FEAT_ID_AENQ_CONFIG:
168       {
169         ena_aq_feat_aenq_config_t *d = data;
170         _format_with_fn_and_val (s, d, supported_groups,
171                                  format_ena_aq_aenq_groups);
172         _format_with_fn_and_val (s, d, enabled_groups,
173                                  format_ena_aq_aenq_groups);
174       }
175       break;
176
177     case ENA_ADMIN_FEAT_ID_INTERRUPT_MODERATION:
178       {
179         ena_aq_feat_intr_moder_t *d = data;
180         _format_number (s, d, intr_delay_resolution);
181       }
182       break;
183
184     case ENA_ADMIN_FEAT_ID_STATELESS_OFFLOAD_CONFIG:
185       {
186         ena_aq_feat_stateless_offload_config_t *d = data;
187         _format_number (s, d, rx_supported);
188         _format_number (s, d, rx_enabled);
189         _format_number (s, d, tx);
190       }
191       break;
192
193     case ENA_ADMIN_FEAT_ID_RSS_INDIRECTION_TABLE_CONFIG:
194       {
195         ena_aq_feat_rss_ind_table_config_t *d = data;
196         _format_number (s, d, min_size);
197         _format_number (s, d, max_size);
198         _format_number (s, d, size);
199         _format_number (s, d, one_entry_update);
200         _format_number (s, d, inline_index);
201         _format_number (s, d, inline_entry.cq_idx);
202       }
203       break;
204
205     case ENA_ADMIN_FEAT_ID_MAX_QUEUES_NUM:
206       {
207         ena_aq_feat_max_queue_num_t *d = data;
208         _format_number (s, d, max_sq_num);
209         _format_number (s, d, max_sq_depth);
210         _format_number (s, d, max_cq_num);
211         _format_number (s, d, max_cq_depth);
212         _format_number (s, d, max_legacy_llq_num);
213         _format_number (s, d, max_legacy_llq_depth);
214         _format_number (s, d, max_header_size);
215         _format_number (s, d, max_packet_tx_descs);
216         _format_number (s, d, max_packet_rx_descs);
217       }
218       break;
219
220     case ENA_ADMIN_FEAT_ID_MAX_QUEUES_EXT:
221       {
222         ena_aq_feat_max_queue_ext_t *d = data;
223         _format_number (s, d, max_rx_sq_num);
224         _format_number (s, d, max_rx_cq_num);
225         _format_number (s, d, max_tx_sq_num);
226         _format_number (s, d, max_tx_cq_num);
227         _format_number (s, d, max_rx_sq_depth);
228         _format_number (s, d, max_rx_cq_depth);
229         _format_number (s, d, max_tx_sq_depth);
230         _format_number (s, d, max_tx_cq_depth);
231         _format_number (s, d, version);
232         _format_number (s, d, max_tx_header_size);
233         _format_number (s, d, max_per_packet_tx_descs);
234         _format_number (s, d, max_per_packet_rx_descs);
235       }
236       break;
237
238     case ENA_ADMIN_FEAT_ID_RSS_HASH_FUNCTION:
239       {
240         ena_aq_feat_rss_hash_function_t *d = data;
241         _format_number (s, d, supported_func);
242         _format_number (s, d, selected_func);
243         _format_number (s, d, init_val);
244       }
245       break;
246
247     case ENA_ADMIN_FEAT_ID_LLQ:
248       {
249         ena_aq_feat_llq_t *d = data;
250         _format_number (s, d, max_llq_num);
251         _format_number (s, d, max_llq_depth);
252         _format_number (s, d, header_location_ctrl_supported);
253         _format_number (s, d, header_location_ctrl_enabled);
254         _format_number (s, d, entry_size_ctrl_supported);
255         _format_number (s, d, entry_size_ctrl_enabled);
256         _format_number (s, d, desc_num_before_header_supported);
257         _format_number (s, d, desc_num_before_header_enabled);
258         _format_number (s, d, descriptors_stride_ctrl_supported);
259         _format_number (s, d, descriptors_stride_ctrl_enabled);
260         _format_number (s, d, accel_mode.get.supported_flags);
261         _format_number (s, d, accel_mode.get.max_tx_burst_size);
262         _format_number (s, d, accel_mode.set.enabled_flags);
263       }
264       break;
265
266     case ENA_ADMIN_FEAT_ID_EXTRA_PROPERTIES_STRINGS:
267       {
268         ena_aq_feat_extra_properties_strings_t *d = data;
269         _format_number (s, d, count);
270       }
271       break;
272
273     case ENA_ADMIN_FEAT_ID_EXTRA_PROPERTIES_FLAGS:
274       {
275         ena_aq_feat_extra_properties_flags_t *d = data;
276         _format_number (s, d, flags);
277       }
278       break;
279
280     case ENA_ADMIN_FEAT_ID_HOST_ATTR_CONFIG:
281       {
282         ena_aq_feat_host_attr_config_t *d = data;
283         _format_ena_memory (s, d, os_info_ba);
284         _format_ena_memory (s, d, debug_ba);
285         _format_number (s, d, debug_area_size);
286       }
287       break;
288
289     default:
290       if (info)
291         s = format (s, "%U", format_hexdump, data, info->data_sz);
292       break;
293     }
294
295   return s;
296 }
297
298 u8 *
299 format_ena_aq_create_sq_cmd (u8 *s, va_list *args)
300 {
301   ena_aq_create_sq_cmd_t *cmd = va_arg (*args, ena_aq_create_sq_cmd_t *);
302   u32 indent = format_get_indent (s);
303   u32 line = 0;
304
305   _format_number (s, cmd, sq_direction);
306   _format_number (s, cmd, placement_policy);
307   _format_number (s, cmd, completion_policy);
308   _format_number (s, cmd, is_physically_contiguous);
309   _format_number (s, cmd, cq_idx);
310   _format_number (s, cmd, sq_depth);
311   _format_ena_memory (s, cmd, sq_ba);
312   _format_ena_memory (s, cmd, sq_head_writeback);
313   return s;
314 }
315
316 u8 *
317 format_ena_aq_create_cq_cmd (u8 *s, va_list *args)
318 {
319   ena_aq_create_cq_cmd_t *cmd = va_arg (*args, ena_aq_create_cq_cmd_t *);
320   u32 indent = format_get_indent (s);
321   u32 line = 0;
322
323   _format_number (s, cmd, interrupt_mode_enabled);
324   _format_number (s, cmd, cq_entry_size_words);
325   _format_number (s, cmd, cq_depth);
326   _format_number (s, cmd, msix_vector);
327   _format_ena_memory (s, cmd, cq_ba);
328   return s;
329 }
330
331 u8 *
332 format_ena_aq_create_sq_resp (u8 *s, va_list *args)
333 {
334   ena_aq_create_sq_resp_t *resp = va_arg (*args, ena_aq_create_sq_resp_t *);
335   u32 indent = format_get_indent (s);
336   u32 line = 0;
337
338   _format_number (s, resp, sq_idx);
339   _format_number (s, resp, sq_doorbell_offset);
340   _format_number (s, resp, llq_descriptors_offset);
341   _format_number (s, resp, llq_headers_offset);
342   return s;
343 }
344
345 u8 *
346 format_ena_aq_create_cq_resp (u8 *s, va_list *args)
347 {
348   ena_aq_create_cq_resp_t *resp = va_arg (*args, ena_aq_create_cq_resp_t *);
349   u32 indent = format_get_indent (s);
350   u32 line = 0;
351
352   _format_number (s, resp, cq_idx);
353   _format_number (s, resp, cq_actual_depth);
354   _format_number (s, resp, numa_node_register_offset);
355   _format_number (s, resp, cq_head_db_register_offset);
356   _format_number (s, resp, cq_interrupt_unmask_register_offset);
357   return s;
358 }
359
360 u8 *
361 format_ena_aq_destroy_sq_cmd (u8 *s, va_list *args)
362 {
363   ena_aq_destroy_sq_cmd_t *cmd = va_arg (*args, ena_aq_destroy_sq_cmd_t *);
364   u32 indent = format_get_indent (s);
365   u32 line = 0;
366
367   _format_number (s, cmd, sq_idx);
368   _format_number (s, cmd, sq_direction);
369   return s;
370 }
371
372 u8 *
373 format_ena_aq_destroy_cq_cmd (u8 *s, va_list *args)
374 {
375   ena_aq_destroy_cq_cmd_t *cmd = va_arg (*args, ena_aq_destroy_cq_cmd_t *);
376   u32 indent = format_get_indent (s);
377   u32 line = 0;
378
379   _format_number (s, cmd, cq_idx);
380   return s;
381 }
382
383 u8 *
384 format_ena_aq_basic_stats (u8 *s, va_list *args)
385 {
386   ena_aq_basic_stats_t *st = va_arg (*args, ena_aq_basic_stats_t *);
387   u32 indent = format_get_indent (s);
388   u32 line = 0;
389
390   _format_number (s, st, tx_bytes);
391   _format_number (s, st, tx_pkts);
392   _format_number (s, st, rx_bytes);
393   _format_number (s, st, rx_pkts);
394   _format_number (s, st, rx_drops);
395   _format_number (s, st, tx_drops);
396   return s;
397 }
398
399 u8 *
400 format_ena_aq_eni_stats (u8 *s, va_list *args)
401 {
402   ena_aq_eni_stats_t *st = va_arg (*args, ena_aq_eni_stats_t *);
403   u32 indent = format_get_indent (s);
404   u32 line = 0;
405
406   _format_number (s, st, bw_in_allowance_exceeded);
407   _format_number (s, st, bw_out_allowance_exceeded);
408   _format_number (s, st, pps_allowance_exceeded);
409   _format_number (s, st, conntrack_allowance_exceeded);
410   _format_number (s, st, linklocal_allowance_exceeded);
411   return s;
412 }