avf: improve elogs 98/29398/5
authorDamjan Marion <damarion@cisco.com>
Mon, 17 Jun 2019 18:25:54 +0000 (20:25 +0200)
committerFlorin Coras <florin.coras@gmail.com>
Wed, 19 May 2021 19:05:56 +0000 (19:05 +0000)
Change-Id: I6221e1a5924223865b3caf53590d3668965b564c
Type: fix
Fixes: b4ff07a
Signed-off-by: Damjan Marion <damarion@cisco.com>
src/plugins/avf/CMakeLists.txt
src/plugins/avf/avf.h
src/plugins/avf/device.c
src/plugins/avf/elog.c [new file with mode: 0644]

index 939076a..f7900a6 100644 (file)
@@ -15,6 +15,7 @@ add_vpp_plugin(avf
   SOURCES
   cli.c
   device.c
+  elog.c
   format.c
   input.c
   output.c
index dbcdcd2..a1da4c8 100644 (file)
@@ -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
index de470da..dbaf4a4 100644 (file)
@@ -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 (file)
index 0000000..6f7401e
--- /dev/null
@@ -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));
+    }
+}