]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
bnxt_en: Add a new ethtool -W dump flag
authorMichael Chan <michael.chan@broadcom.com>
Fri, 15 Nov 2024 15:14:36 +0000 (07:14 -0800)
committerJakub Kicinski <kuba@kernel.org>
Tue, 19 Nov 2024 03:48:55 +0000 (19:48 -0800)
Add a new ethtool -W dump flag (2) to include driver coredump segments.
This patch adds the host backing store context memory pages used by the
chip and FW to store various states to the coredump.  The pages for
each context memory type is dumped into a separate coredump segment.

Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: Selvin Thyparampil Xavier <selvin.xavier@broadcom.com>
Reviewed-by: Shruti Parab <shruti.parab@broadcom.com>
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Saravanan Vajravel <saravanan.vajravel@broadcom.com>
Reviewed-by: Kashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20241115151438.550106-11-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c
drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

index 2d63490b9f1442a569d3851e1fce0717253d6c84..231e3893398453f86ace712c568189ce1ecad96f 100644 (file)
@@ -2662,6 +2662,7 @@ struct bnxt {
        u16                     dump_flag;
 #define BNXT_DUMP_LIVE         0
 #define BNXT_DUMP_CRASH                1
+#define BNXT_DUMP_DRIVER       2
 
        struct bpf_prog         *xdp_prog;
 
index 4dfc26cfc979bf378df2cba2d28a4680d00dae25..ff92443db01b35830ca75ce7357e4c41175ef09a 100644 (file)
 #include "bnxt_hwrm.h"
 #include "bnxt_coredump.h"
 
+static const u16 bnxt_bstore_to_seg_id[] = {
+       [BNXT_CTX_QP]                   = BNXT_CTX_MEM_SEG_QP,
+       [BNXT_CTX_SRQ]                  = BNXT_CTX_MEM_SEG_SRQ,
+       [BNXT_CTX_CQ]                   = BNXT_CTX_MEM_SEG_CQ,
+       [BNXT_CTX_VNIC]                 = BNXT_CTX_MEM_SEG_VNIC,
+       [BNXT_CTX_STAT]                 = BNXT_CTX_MEM_SEG_STAT,
+       [BNXT_CTX_STQM]                 = BNXT_CTX_MEM_SEG_STQM,
+       [BNXT_CTX_FTQM]                 = BNXT_CTX_MEM_SEG_FTQM,
+       [BNXT_CTX_MRAV]                 = BNXT_CTX_MEM_SEG_MRAV,
+       [BNXT_CTX_TIM]                  = BNXT_CTX_MEM_SEG_TIM,
+};
+
 static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg,
                                  struct bnxt_hwrm_dbg_dma_info *info)
 {
@@ -267,7 +279,47 @@ bnxt_fill_coredump_record(struct bnxt *bp, struct bnxt_coredump_record *record,
        record->ioctl_high_version = 0;
 }
 
-static int __bnxt_get_coredump(struct bnxt *bp, void *buf, u32 *dump_len)
+static u32 bnxt_get_ctx_coredump(struct bnxt *bp, void *buf, u32 offset,
+                                u32 *segs)
+{
+       struct bnxt_coredump_segment_hdr seg_hdr;
+       struct bnxt_ctx_mem_info *ctx = bp->ctx;
+       u32 comp_id = BNXT_DRV_COMP_ID;
+       void *data = NULL;
+       size_t len = 0;
+       u16 type;
+
+       *segs = 0;
+       if (!ctx)
+               return 0;
+
+       if (buf)
+               buf += offset;
+       for (type = 0 ; type <= BNXT_CTX_TIM; type++) {
+               struct bnxt_ctx_mem_type *ctxm = &ctx->ctx_arr[type];
+               u32 seg_id = bnxt_bstore_to_seg_id[type];
+               size_t seg_len;
+
+               if (!ctxm->entry_size || !ctxm->pg_info || !seg_id)
+                       continue;
+
+               if (buf)
+                       data = buf + BNXT_SEG_HDR_LEN;
+               seg_len = bnxt_copy_ctx_mem(bp, ctxm, data, 0);
+               if (buf) {
+                       bnxt_fill_coredump_seg_hdr(bp, &seg_hdr, NULL, seg_len,
+                                                  0, 0, 0, comp_id, seg_id);
+                       memcpy(buf, &seg_hdr, BNXT_SEG_HDR_LEN);
+                       buf += BNXT_SEG_HDR_LEN + seg_len;
+               }
+               len += BNXT_SEG_HDR_LEN + seg_len;
+               *segs += 1;
+       }
+       return len;
+}
+
+static int __bnxt_get_coredump(struct bnxt *bp, u16 dump_type, void *buf,
+                              u32 *dump_len)
 {
        u32 ver_get_resp_len = sizeof(struct hwrm_ver_get_output);
        u32 offset = 0, seg_hdr_len, seg_record_len, buf_len = 0;
@@ -298,6 +350,18 @@ static int __bnxt_get_coredump(struct bnxt *bp, void *buf, u32 *dump_len)
                offset += ver_get_resp_len;
        }
 
+       if (dump_type == BNXT_DUMP_DRIVER) {
+               u32 drv_len, segs = 0;
+
+               drv_len = bnxt_get_ctx_coredump(bp, buf, offset, &segs);
+               *dump_len += drv_len;
+               offset += drv_len;
+               if (buf)
+                       coredump.total_segs += segs;
+               goto err;
+       }
+
+       seg_record_len = sizeof(*seg_record);
        rc = bnxt_hwrm_dbg_coredump_list(bp, &coredump);
        if (rc) {
                netdev_err(bp->dev, "Failed to get coredump segment list\n");
@@ -442,7 +506,7 @@ int bnxt_get_coredump(struct bnxt *bp, u16 dump_type, void *buf, u32 *dump_len)
                else
                        return -EOPNOTSUPP;
        } else {
-               return __bnxt_get_coredump(bp, buf, dump_len);
+               return __bnxt_get_coredump(bp, dump_type, buf, dump_len);
        }
 }
 
@@ -512,9 +576,12 @@ u32 bnxt_get_coredump_length(struct bnxt *bp, u16 dump_type)
                return bp->fw_crash_len;
        }
 
-       if (bnxt_hwrm_get_dump_len(bp, dump_type, &len)) {
-               if (dump_type != BNXT_DUMP_CRASH)
-                       __bnxt_get_coredump(bp, NULL, &len);
+       if (dump_type != BNXT_DUMP_DRIVER) {
+               if (!bnxt_hwrm_get_dump_len(bp, dump_type, &len))
+                       return len;
        }
+       if (dump_type != BNXT_DUMP_CRASH)
+               __bnxt_get_coredump(bp, dump_type, NULL, &len);
+
        return len;
 }
index f573e55f7e6247d75d4858a7d29d6367703e9473..3a6084a51be895d55ac2f575383674cda65edc42 100644 (file)
@@ -69,12 +69,27 @@ struct bnxt_coredump_record {
 };
 
 #define BNXT_VER_GET_COMP_ID   2
+#define BNXT_DRV_COMP_ID       0xd
+
+#define BNXT_CTX_MEM_SEG_ID_START  0x200
+
+#define BNXT_CTX_MEM_SEG_QP    (BNXT_CTX_MEM_SEG_ID_START + BNXT_CTX_QP)
+#define BNXT_CTX_MEM_SEG_SRQ   (BNXT_CTX_MEM_SEG_ID_START + BNXT_CTX_SRQ)
+#define BNXT_CTX_MEM_SEG_CQ    (BNXT_CTX_MEM_SEG_ID_START + BNXT_CTX_CQ)
+#define BNXT_CTX_MEM_SEG_VNIC  (BNXT_CTX_MEM_SEG_ID_START + BNXT_CTX_VNIC)
+#define BNXT_CTX_MEM_SEG_STAT  (BNXT_CTX_MEM_SEG_ID_START + BNXT_CTX_STAT)
+#define BNXT_CTX_MEM_SEG_STQM  (BNXT_CTX_MEM_SEG_ID_START + BNXT_CTX_STQM)
+#define BNXT_CTX_MEM_SEG_FTQM  (BNXT_CTX_MEM_SEG_ID_START + BNXT_CTX_FTQM)
+#define BNXT_CTX_MEM_SEG_MRAV  (BNXT_CTX_MEM_SEG_ID_START + BNXT_CTX_MRAV)
+#define BNXT_CTX_MEM_SEG_TIM   (BNXT_CTX_MEM_SEG_ID_START + BNXT_CTX_TIM)
 
 #define BNXT_CRASH_DUMP_LEN    (8 << 20)
 
 #define COREDUMP_LIST_BUF_LEN          2048
 #define COREDUMP_RETRIEVE_BUF_LEN      4096
 
+#define BNXT_SEG_HDR_LEN       sizeof(struct bnxt_coredump_segment_hdr)
+
 struct bnxt_coredump {
        void            *data;
        int             data_size;
index 061a40b1974b062f313617e7e046f3750424e2d7..2f4987ec74643c18fe318173f60d0826c6eadf52 100644 (file)
@@ -4984,8 +4984,8 @@ static int bnxt_set_dump(struct net_device *dev, struct ethtool_dump *dump)
 {
        struct bnxt *bp = netdev_priv(dev);
 
-       if (dump->flag > BNXT_DUMP_CRASH) {
-               netdev_info(dev, "Supports only Live(0) and Crash(1) dumps.\n");
+       if (dump->flag > BNXT_DUMP_DRIVER) {
+               netdev_info(dev, "Supports only Live(0), Crash(1), Driver(2) dumps.\n");
                return -EINVAL;
        }