Commit 23a18b91 authored by Sreekanth Reddy's avatar Sreekanth Reddy Committed by Jakub Kicinski
Browse files

bnxt_en: Add functions to copy host context memory



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: default avatarPavan Chebbi <pavan.chebbi@broadcom.com>
Reviewed-by: default avatarHongguang Gao <hongguang.gao@broadcom.com>
Co-developed-by: default avatarShruti Parab <shruti.parab@broadcom.com>
Signed-off-by: default avatarShruti Parab <shruti.parab@broadcom.com>
Signed-off-by: default avatarSreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20241115151438.550106-9-michael.chan@broadcom.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent de999362
Loading
Loading
Loading
Loading
+103 −0
Original line number Diff line number Diff line
@@ -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)
{
+4 −0
Original line number Diff line number Diff line
@@ -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);