]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
bnxt_en: Add functions to copy host context memory
authorSreekanth Reddy <sreekanth.reddy@broadcom.com>
Fri, 15 Nov 2024 15:14:34 +0000 (07:14 -0800)
committerJakub Kicinski <kuba@kernel.org>
Tue, 19 Nov 2024 03:48:55 +0000 (19:48 -0800)
Host context memory is used by the newer chips to store context
information for various L2 and RoCE states and FW logs.  This
information will be useful for debugging.  This patch adds the
functions to copy all pages of a context memory type to a contiguous
buffer.  The next patches will include the context memory dump
during ethtool -w coredump.

Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Reviewed-by: Hongguang Gao <hongguang.gao@broadcom.com>
Co-developed-by: Shruti Parab <shruti.parab@broadcom.com>
Signed-off-by: Shruti Parab <shruti.parab@broadcom.com>
Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20241115151438.550106-9-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h

index b0f3b431708c543deb0f5b5084962fffe7a42d48..5f7bdafcf05def5c57cb77077adef2cbeff733b3 100644 (file)
@@ -3493,6 +3493,35 @@ static void bnxt_init_ctx_mem(struct bnxt_ctx_mem_type *ctxm, void *p, int len)
                *(p2 + i + offset) = init_val;
 }
 
+static size_t __bnxt_copy_ring(struct bnxt *bp, struct bnxt_ring_mem_info *rmem,
+                              void *buf, size_t offset, size_t head,
+                              size_t tail)
+{
+       int i, head_page, start_idx, source_offset;
+       size_t len, rem_len, total_len, max_bytes;
+
+       head_page = head / rmem->page_size;
+       source_offset = head % rmem->page_size;
+       total_len = (tail - head) & MAX_CTX_BYTES_MASK;
+       if (!total_len)
+               total_len = MAX_CTX_BYTES;
+       start_idx = head_page % MAX_CTX_PAGES;
+       max_bytes = (rmem->nr_pages - start_idx) * rmem->page_size -
+                   source_offset;
+       total_len = min(total_len, max_bytes);
+       rem_len = total_len;
+
+       for (i = start_idx; rem_len; i++, source_offset = 0) {
+               len = min((size_t)(rmem->page_size - source_offset), rem_len);
+               if (buf)
+                       memcpy(buf + offset, rmem->pg_arr[i] + source_offset,
+                              len);
+               offset += len;
+               rem_len -= len;
+       }
+       return total_len;
+}
+
 static void bnxt_free_ring(struct bnxt *bp, struct bnxt_ring_mem_info *rmem)
 {
        struct pci_dev *pdev = bp->pdev;
@@ -8728,6 +8757,36 @@ static int bnxt_alloc_ctx_pg_tbls(struct bnxt *bp,
        return rc;
 }
 
+static size_t bnxt_copy_ctx_pg_tbls(struct bnxt *bp,
+                                   struct bnxt_ctx_pg_info *ctx_pg,
+                                   void *buf, size_t offset, size_t head,
+                                   size_t tail)
+{
+       struct bnxt_ring_mem_info *rmem = &ctx_pg->ring_mem;
+       size_t nr_pages = ctx_pg->nr_pages;
+       int page_size = rmem->page_size;
+       size_t len = 0, total_len = 0;
+       u16 depth = rmem->depth;
+
+       tail %= nr_pages * page_size;
+       do {
+               if (depth > 1) {
+                       int i = head / (page_size * MAX_CTX_PAGES);
+                       struct bnxt_ctx_pg_info *pg_tbl;
+
+                       pg_tbl = ctx_pg->ctx_pg_tbl[i];
+                       rmem = &pg_tbl->ring_mem;
+               }
+               len = __bnxt_copy_ring(bp, rmem, buf, offset, head, tail);
+               head += len;
+               offset += len;
+               total_len += len;
+               if (head >= nr_pages * page_size)
+                       head = 0;
+       } while (head != tail);
+       return total_len;
+}
+
 static void bnxt_free_ctx_pg_tbls(struct bnxt *bp,
                                  struct bnxt_ctx_pg_info *ctx_pg)
 {
@@ -8888,6 +8947,50 @@ static int bnxt_backing_store_cfg_v2(struct bnxt *bp, u32 ena)
        return 0;
 }
 
+/**
+ * __bnxt_copy_ctx_mem - copy host context memory
+ * @bp: The driver context
+ * @ctxm: The pointer to the context memory type
+ * @buf: The destination buffer or NULL to just obtain the length
+ * @offset: The buffer offset to copy the data to
+ * @head: The head offset of context memory to copy from
+ * @tail: The tail offset (last byte + 1) of context memory to end the copy
+ *
+ * This function is called for debugging purposes to dump the host context
+ * used by the chip.
+ *
+ * Return: Length of memory copied
+ */
+static size_t __bnxt_copy_ctx_mem(struct bnxt *bp,
+                                 struct bnxt_ctx_mem_type *ctxm, void *buf,
+                                 size_t offset, size_t head, size_t tail)
+{
+       struct bnxt_ctx_pg_info *ctx_pg = ctxm->pg_info;
+       size_t len = 0, total_len = 0;
+       int i, n = 1;
+
+       if (!ctx_pg)
+               return 0;
+
+       if (ctxm->instance_bmap)
+               n = hweight32(ctxm->instance_bmap);
+       for (i = 0; i < n; i++) {
+               len = bnxt_copy_ctx_pg_tbls(bp, &ctx_pg[i], buf, offset, head,
+                                           tail);
+               offset += len;
+               total_len += len;
+       }
+       return total_len;
+}
+
+size_t bnxt_copy_ctx_mem(struct bnxt *bp, struct bnxt_ctx_mem_type *ctxm,
+                        void *buf, size_t offset)
+{
+       size_t tail = ctxm->max_entries * ctxm->entry_size;
+
+       return __bnxt_copy_ctx_mem(bp, ctxm, buf, offset, 0, tail);
+}
+
 static void bnxt_free_one_ctx_mem(struct bnxt *bp,
                                  struct bnxt_ctx_mem_type *ctxm, bool force)
 {
index 4ebee79fbe520e0b92d9b3350a11a70787194b31..2d63490b9f1442a569d3851e1fce0717253d6c84 100644 (file)
@@ -1849,6 +1849,8 @@ struct bnxt_vf_rep {
 
 #define MAX_CTX_PAGES  (BNXT_PAGE_SIZE / 8)
 #define MAX_CTX_TOTAL_PAGES    (MAX_CTX_PAGES * MAX_CTX_PAGES)
+#define MAX_CTX_BYTES          ((size_t)MAX_CTX_TOTAL_PAGES * BNXT_PAGE_SIZE)
+#define MAX_CTX_BYTES_MASK     (MAX_CTX_BYTES - 1)
 
 struct bnxt_ctx_pg_info {
        u32             entries;
@@ -2863,6 +2865,8 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic,
 int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings);
 int bnxt_nq_rings_in_use(struct bnxt *bp);
 int bnxt_hwrm_set_coal(struct bnxt *);
+size_t bnxt_copy_ctx_mem(struct bnxt *bp, struct bnxt_ctx_mem_type *ctxm,
+                        void *buf, size_t offset);
 void bnxt_free_ctx_mem(struct bnxt *bp, bool force);
 int bnxt_num_tx_to_cp(struct bnxt *bp, int tx);
 unsigned int bnxt_get_max_func_stat_ctxs(struct bnxt *bp);