diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/avf/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/plugins/avf/avf.h | 16 | ||||
-rw-r--r-- | src/plugins/avf/device.c | 5 | ||||
-rw-r--r-- | src/plugins/avf/elog.c | 207 |
4 files changed, 227 insertions, 2 deletions
diff --git a/src/plugins/avf/CMakeLists.txt b/src/plugins/avf/CMakeLists.txt index 939076a8286..f7900a64958 100644 --- a/src/plugins/avf/CMakeLists.txt +++ b/src/plugins/avf/CMakeLists.txt @@ -15,6 +15,7 @@ add_vpp_plugin(avf SOURCES cli.c device.c + elog.c format.c input.c output.c diff --git a/src/plugins/avf/avf.h b/src/plugins/avf/avf.h index dbcdcd249af..a1da4c8866b 100644 --- a/src/plugins/avf/avf.h +++ b/src/plugins/avf/avf.h @@ -370,6 +370,13 @@ avf_get_device (u32 dev_instance) return pool_elt_at_index (avf_main.devices, dev_instance)[0]; } +/* elog.c */ +void avf_elog_init (); +void avf_elog_reg (avf_device_t *ad, u32 addr, u32 val, int is_read); +void avf_elog_aq_enq_req (avf_device_t *ad, avf_aq_desc_t *d); +void avf_elog_aq_enq_resp (avf_device_t *ad, avf_aq_desc_t *d); +void avf_elog_arq_desc (avf_device_t *ad, avf_aq_desc_t *d); + static inline u32 avf_get_u32 (void *start, int offset) { @@ -413,13 +420,20 @@ avf_set_u32 (void *start, int offset, u32 value) static inline void avf_reg_write (avf_device_t * ad, u32 addr, u32 val) { + if (ad->flags & AVF_DEVICE_F_ELOG) + avf_elog_reg (ad, addr, val, 0); *(volatile u32 *) ((u8 *) ad->bar0 + addr) = val; } static inline u32 avf_reg_read (avf_device_t * ad, u32 addr) { - return *(volatile u32 *) (ad->bar0 + addr); + u32 val = *(volatile u32 *) (ad->bar0 + addr); + + if (ad->flags & AVF_DEVICE_F_ELOG) + avf_elog_reg (ad, addr, val, 1); + + return val; } static inline void diff --git a/src/plugins/avf/device.c b/src/plugins/avf/device.c index de470da9fbf..dbaf4a4a7f2 100644 --- a/src/plugins/avf/device.c +++ b/src/plugins/avf/device.c @@ -1614,7 +1614,10 @@ avf_create_if (vlib_main_t * vm, avf_create_if_args_t * args) ad->name = vec_dup (args->name); if (args->enable_elog) - ad->flags |= AVF_DEVICE_F_ELOG; + { + ad->flags |= AVF_DEVICE_F_ELOG; + avf_elog_init (); + } if ((error = vlib_pci_device_open (vm, &args->addr, avf_pci_device_ids, &h))) diff --git a/src/plugins/avf/elog.c b/src/plugins/avf/elog.c new file mode 100644 index 00000000000..6f7401e8286 --- /dev/null +++ b/src/plugins/avf/elog.c @@ -0,0 +1,207 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright(c) 2021 Cisco Systems, Inc. + */ + +#include <vlib/vlib.h> +#include <vlib/unix/unix.h> +#include <vlib/pci/pci.h> +#include <vnet/ethernet/ethernet.h> + +#include <avf/avf.h> + +static uword *register_name_by_addr = 0; + +void +avf_elog_aq_enq_req (avf_device_t *ad, avf_aq_desc_t *d) +{ + if (d->opcode == 0x801) /* send_to_pf */ + { + ELOG_TYPE_DECLARE (el) = { + .format = "avf[%d] aq_enq_req: send_to_pf flags 0x%x datalen %d " + "v_opcode %s (%d)", + .format_args = "i4i2i2t2i2", + .n_enum_strings = VIRTCHNL_N_OPS, + .enum_strings = { +#define _(v, n) [v] = #n, + foreach_virtchnl_op +#undef _ + }, + }; + + struct + { + u32 dev_instance; + u16 flags; + u16 datalen; + u16 v_opcode; + u16 v_opcode_val; + } * ed; + + ed = ELOG_DATA (&vlib_global_main.elog_main, el); + ed->dev_instance = ad->dev_instance; + ed->flags = d->flags; + ed->datalen = d->datalen; + ed->v_opcode = ed->v_opcode_val = d->v_opcode; + } + else + { + ELOG_TYPE_DECLARE (el) = { + .format = "avf[%d] aq_enq_req: opcode 0x%x flags 0x%x datalen %d", + .format_args = "i4i2i2i2" + }; + + struct + { + u32 dev_instance; + u16 opcode; + u16 flags; + u16 datalen; + } * ed; + + ed = ELOG_DATA (&vlib_global_main.elog_main, el); + ed->dev_instance = ad->dev_instance; + ed->opcode = d->opcode; + ed->flags = d->flags; + ed->datalen = d->datalen; + } +} + +void +avf_elog_aq_enq_resp (avf_device_t *ad, avf_aq_desc_t *d) +{ + ELOG_TYPE_DECLARE (el) = { .format = + "avf[%d] aq_enq_resp: flags 0x%x retval %d", + .format_args = "i4i2i2" }; + + struct + { + u32 dev_instance; + u16 flags; + u16 retval; + } * ed; + + ed = ELOG_DATA (&vlib_global_main.elog_main, el); + ed->dev_instance = ad->dev_instance; + ed->flags = d->flags; + ed->retval = d->retval; +} + +void +avf_elog_arq_desc (avf_device_t *ad, avf_aq_desc_t *d) +{ + if (d->opcode == 0x802) + { + ELOG_TYPE_DECLARE (el) = { + .format = "avf[%d] arq_desc: msg_from_pf flags 0x%x retval %d " + "v_opcode %s (%d) v_retval %d", + .format_args = "i4i2i2t2i2i2", + .n_enum_strings = VIRTCHNL_N_OPS, + .enum_strings = { +#define _(v, n) [v] = #n, + foreach_virtchnl_op +#undef _ + }, + }; + + struct + { + u32 dev_instance; + u16 flags; + u16 retval; + u16 v_opcode; + u16 v_opcode_val; + u16 v_retval; + } * ed; + + ed = ELOG_DATA (&vlib_global_main.elog_main, el); + ed->dev_instance = ad->dev_instance; + ed->flags = d->flags; + ed->retval = d->retval; + ed->v_opcode = ed->v_opcode_val = d->v_opcode; + ed->v_retval = d->v_retval; + } + else + { + ELOG_TYPE_DECLARE ( + el) = { .format = "avf[%d] arq_desc: flags 0x%x retval %d opcode 0x%x", + .format_args = "i4i2i2i2" }; + + struct + { + u32 dev_instance; + u16 flags; + u16 retval; + u16 opcode; + } * ed; + + ed = ELOG_DATA (&vlib_global_main.elog_main, el); + ed->dev_instance = ad->dev_instance; + ed->flags = d->flags; + ed->retval = d->retval; + ed->opcode = d->opcode; + } +} + +void +avf_elog_reg (avf_device_t *ad, u32 addr, u32 val, int is_read) +{ + uword *p; + ELOG_TYPE_DECLARE (el) = { + .format = "avf[%d] reg: %s %s [0x%04x] val 0x%08x", + .format_args = "i4s4s4i4i4", + }; + + struct + { + u32 dev_instance; + char rw[4]; + char reg_name[24]; + u32 addr; + u32 val; + } * ed; + + ed = ELOG_DATA (&vlib_global_main.elog_main, el); + ed->dev_instance = ad->dev_instance; + ed->addr = addr; + ed->val = val; + ed->rw[0] = is_read ? 'r' : 'w'; + ed->rw[1] = 0; + + p = hash_get (register_name_by_addr, addr); + strncpy (ed->reg_name, p ? (char *) p[0] : "unknown", 24); + ed->reg_name[23] = 0; +} + +void +avf_elog_init (void) +{ + if (register_name_by_addr) + return; + + register_name_by_addr = hash_create (0, sizeof (uword)); + + hash_set (register_name_by_addr, AVFINT_ICR0, "AVFINT_ICR0"); + hash_set (register_name_by_addr, AVFINT_ICR0_ENA1, "INT_ICR0_ENA1"); + hash_set (register_name_by_addr, AVFINT_DYN_CTL0, "INT_DYN_CTL0"); + hash_set (register_name_by_addr, AVF_ARQBAH, "ARQBAH"); + hash_set (register_name_by_addr, AVF_ATQH, "ATQH"); + hash_set (register_name_by_addr, AVF_ATQLEN, "ATQLEN"); + hash_set (register_name_by_addr, AVF_ARQBAL, "ARQBAL"); + hash_set (register_name_by_addr, AVF_ARQT, "ARQT"); + hash_set (register_name_by_addr, AVF_ARQH, "ARQH"); + hash_set (register_name_by_addr, AVF_ATQBAH, "ATQBAH"); + hash_set (register_name_by_addr, AVF_ATQBAL, "ATQBAL"); + hash_set (register_name_by_addr, AVF_ARQLEN, "ARQLEN"); + hash_set (register_name_by_addr, AVF_ATQT, "ATQT"); + hash_set (register_name_by_addr, AVFGEN_RSTAT, "GEN_RSTAT"); + + for (int i = 0; i < 16; i++) + { + hash_set (register_name_by_addr, AVFINT_DYN_CTLN (i), + format (0, "INT_DYN_CTLN(%u)%c", i, 0)); + hash_set (register_name_by_addr, AVF_QTX_TAIL (i), + format (0, "QTX_TAIL(%u)%c", i, 0)); + hash_set (register_name_by_addr, AVF_QRX_TAIL (i), + format (0, "QRX_TAIL(%u)%c", i, 0)); + } +} |