1 /* SPDX-License-Identifier: Apache-2.0
2 * Copyright(c) 2023 Cisco Systems, Inc.
6 #include <vnet/dev/dev.h>
8 #include <dev_ena/ena.h>
9 #include <dev_ena/ena_inlines.h>
10 #include <vnet/ethernet/ethernet.h>
12 static char *opcode_names[] = {
13 #define _(v, s) [v] = #s,
18 static char *status_names[] = {
19 #define _(v, s) [v] = #s,
20 foreach_ena_aq_compl_status
24 #define __maxval(s, f) (u64) (((typeof ((s)[0])){ .f = -1LL }).f)
26 #define __name(s, n) \
28 s = format (s, "%s%U%-32s: ", line ? "\n" : "", format_white_space, \
29 line ? indent : 0, #n); \
33 #define _format_number(s, d, n, ...) \
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); \
43 s = format (s, "0x%08x (%u)", d->n, d->n); \
46 #define _format_with_fn_and_ptr(s, c, n, f) \
49 s = format (s, "%U", f, &((c)->n)); \
52 #define _format_with_fn_and_val(s, c, n, f) \
55 s = format (s, "%U", f, (c)->n); \
57 #define _format_ena_memory(s, c, n) \
58 _format_with_fn_and_ptr (s, c, n, format_ena_mem_addr)
61 format_ena_aq_opcode (u8 *s, va_list *args)
63 u32 opcode = va_arg (*args, u32);
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]);
71 format_ena_aq_status (u8 *s, va_list *args)
73 u32 status = va_arg (*args, u32);
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]);
81 format_ena_aq_aenq_groups (u8 *s, va_list *args)
83 ena_aq_aenq_groups_t g = va_arg (*args, ena_aq_aenq_groups_t);
85 u32 indent = format_get_indent (s);
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); \
95 foreach_ena_aq_aenq_groups;
98 foreach_set_bit_index (i, g.as_u32)
99 s = format (s, "%sunknown-%u", not_first++ ? " " : "", i);
105 format_ena_aq_feat_id_bitmap (u8 *s, va_list *args)
107 u32 bmp = va_arg (*args, u32);
109 u32 indent = format_get_indent (s);
111 foreach_set_bit_index (i, bmp)
113 ena_aq_feat_info_t *info = ena_aq_get_feat_info (i);
115 s = format (s, ", ");
116 if (format_get_indent (s) > 80)
117 s = format (s, "\n%U", format_white_space, indent);
119 s = format (s, "%s", info->name);
121 s = format (s, "unknown-%u", i);
128 format_ena_aq_feat_name (u8 *s, va_list *args)
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
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]);
143 format_ena_aq_feat_desc (u8 *s, va_list *args)
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);
153 case ENA_ADMIN_FEAT_ID_DEVICE_ATTRIBUTES:
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);
167 case ENA_ADMIN_FEAT_ID_AENQ_CONFIG:
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);
177 case ENA_ADMIN_FEAT_ID_INTERRUPT_MODERATION:
179 ena_aq_feat_intr_moder_t *d = data;
180 _format_number (s, d, intr_delay_resolution);
184 case ENA_ADMIN_FEAT_ID_STATELESS_OFFLOAD_CONFIG:
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);
193 case ENA_ADMIN_FEAT_ID_RSS_INDIRECTION_TABLE_CONFIG:
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);
205 case ENA_ADMIN_FEAT_ID_MAX_QUEUES_NUM:
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);
220 case ENA_ADMIN_FEAT_ID_MAX_QUEUES_EXT:
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);
238 case ENA_ADMIN_FEAT_ID_RSS_HASH_FUNCTION:
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);
247 case ENA_ADMIN_FEAT_ID_LLQ:
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);
266 case ENA_ADMIN_FEAT_ID_EXTRA_PROPERTIES_STRINGS:
268 ena_aq_feat_extra_properties_strings_t *d = data;
269 _format_number (s, d, count);
273 case ENA_ADMIN_FEAT_ID_EXTRA_PROPERTIES_FLAGS:
275 ena_aq_feat_extra_properties_flags_t *d = data;
276 _format_number (s, d, flags);
280 case ENA_ADMIN_FEAT_ID_HOST_ATTR_CONFIG:
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);
291 s = format (s, "%U", format_hexdump, data, info->data_sz);
299 format_ena_aq_create_sq_cmd (u8 *s, va_list *args)
301 ena_aq_create_sq_cmd_t *cmd = va_arg (*args, ena_aq_create_sq_cmd_t *);
302 u32 indent = format_get_indent (s);
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);
317 format_ena_aq_create_cq_cmd (u8 *s, va_list *args)
319 ena_aq_create_cq_cmd_t *cmd = va_arg (*args, ena_aq_create_cq_cmd_t *);
320 u32 indent = format_get_indent (s);
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);
332 format_ena_aq_create_sq_resp (u8 *s, va_list *args)
334 ena_aq_create_sq_resp_t *resp = va_arg (*args, ena_aq_create_sq_resp_t *);
335 u32 indent = format_get_indent (s);
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);
346 format_ena_aq_create_cq_resp (u8 *s, va_list *args)
348 ena_aq_create_cq_resp_t *resp = va_arg (*args, ena_aq_create_cq_resp_t *);
349 u32 indent = format_get_indent (s);
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);
361 format_ena_aq_destroy_sq_cmd (u8 *s, va_list *args)
363 ena_aq_destroy_sq_cmd_t *cmd = va_arg (*args, ena_aq_destroy_sq_cmd_t *);
364 u32 indent = format_get_indent (s);
367 _format_number (s, cmd, sq_idx);
368 _format_number (s, cmd, sq_direction);
373 format_ena_aq_destroy_cq_cmd (u8 *s, va_list *args)
375 ena_aq_destroy_cq_cmd_t *cmd = va_arg (*args, ena_aq_destroy_cq_cmd_t *);
376 u32 indent = format_get_indent (s);
379 _format_number (s, cmd, cq_idx);
384 format_ena_aq_basic_stats (u8 *s, va_list *args)
386 ena_aq_basic_stats_t *st = va_arg (*args, ena_aq_basic_stats_t *);
387 u32 indent = format_get_indent (s);
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);
400 format_ena_aq_eni_stats (u8 *s, va_list *args)
402 ena_aq_eni_stats_t *st = va_arg (*args, ena_aq_eni_stats_t *);
403 u32 indent = format_get_indent (s);
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);