// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright (C) 2017-2018 Netronome Systems, Inc. */

#include <linux/ethtool.h>
#include <linux/vmalloc.h>

#include "nfp_asm.h"
#include "nfp_main.h"
#include "nfpcore/nfp.h"
#include "nfpcore/nfp_nffw.h"
#include "nfpcore/nfp6000/nfp6000.h"

#define NFP_DUMP_SPEC_RTSYM	"_abi_dump_spec"

#define ALIGN8(x)	ALIGN(x, 8)

enum nfp_dumpspec_type {
	NFP_DUMPSPEC_TYPE_CPP_CSR = 0,
	NFP_DUMPSPEC_TYPE_XPB_CSR = 1,
	NFP_DUMPSPEC_TYPE_ME_CSR = 2,
	NFP_DUMPSPEC_TYPE_INDIRECT_ME_CSR = 3,
	NFP_DUMPSPEC_TYPE_RTSYM = 4,
	NFP_DUMPSPEC_TYPE_HWINFO = 5,
	NFP_DUMPSPEC_TYPE_FWNAME = 6,
	NFP_DUMPSPEC_TYPE_HWINFO_FIELD = 7,
	NFP_DUMPSPEC_TYPE_PROLOG = 10000,
	NFP_DUMPSPEC_TYPE_ERROR = 10001,
};

/* The following structs must be carefully aligned so that they can be used to
 * interpret the binary dumpspec and populate the dump data in a deterministic
 * way.
 */

/* generic type plus length */
struct nfp_dump_tl {
	__be32 type;
	__be32 length;	/* chunk length to follow, aligned to 8 bytes */
	char data[0];
};

/* NFP CPP parameters */
struct nfp_dumpspec_cpp_isl_id {
	u8 target;
	u8 action;
	u8 token;
	u8 island;
};

struct nfp_dump_common_cpp {
	struct nfp_dumpspec_cpp_isl_id cpp_id;
	__be32 offset;		/* address to start dump */
	__be32 dump_length;	/* total bytes to dump, aligned to reg size */
};

/* CSR dumpables */
struct nfp_dumpspec_csr {
	struct nfp_dump_tl tl;
	struct nfp_dump_common_cpp cpp;
	__be32 register_width;	/* in bits */
};

struct nfp_dumpspec_rtsym {
	struct nfp_dump_tl tl;
	char rtsym[0];
};

/* header for register dumpable */
struct nfp_dump_csr {
	struct nfp_dump_tl tl;
	struct nfp_dump_common_cpp cpp;
	__be32 register_width;	/* in bits */
	__be32 error;		/* error code encountered while reading */
	__be32 error_offset;	/* offset being read when error occurred */
};

struct nfp_dump_rtsym {
	struct nfp_dump_tl tl;
	struct nfp_dump_common_cpp cpp;
	__be32 error;		/* error code encountered while reading */
	u8 padded_name_length;	/* pad so data starts at 8 byte boundary */
	char rtsym[0];
	/* after padded_name_length, there is dump_length data */
};

struct nfp_dump_prolog {
	struct nfp_dump_tl tl;
	__be32 dump_level;
};

struct nfp_dump_error {
	struct nfp_dump_tl tl;
	__be32 error;
	char padding[4];
	char spec[0];
};

/* to track state through debug size calculation TLV traversal */
struct nfp_level_size {
	__be32 requested_level;	/* input */
	u32 total_size;		/* output */
};

/* to track state during debug dump creation TLV traversal */
struct nfp_dump_state {
	__be32 requested_level;	/* input param */
	u32 dumped_size;	/* adds up to size of dumped data */
	u32 buf_size;		/* size of buffer pointer to by p */
	void *p;		/* current point in dump buffer */
};

typedef int (*nfp_tlv_visit)(struct nfp_pf *pf, struct nfp_dump_tl *tl,
			     void *param);

static int
nfp_traverse_tlvs(struct nfp_pf *pf, void *data, u32 data_length, void *param,
		  nfp_tlv_visit tlv_visit)
{
	long long remaining = data_length;
	struct nfp_dump_tl *tl;
	u32 total_tlv_size;
	void *p = data;
	int err;

	while (remaining >= sizeof(*tl)) {
		tl = p;
		if (!tl->type && !tl->length)
			break;

		if (be32_to_cpu(tl->length) > remaining - sizeof(*tl))
			return -EINVAL;

		total_tlv_size = sizeof(*tl) + be32_to_cpu(tl->length);

		/* Spec TLVs should be aligned to 4 bytes. */
		if (total_tlv_size % 4 != 0)
			return -EINVAL;

		p += total_tlv_size;
		remaining -= total_tlv_size;
		err = tlv_visit(pf, tl, param);
		if (err)
			return err;
	}

	return 0;
}

static u32 nfp_get_numeric_cpp_id(struct nfp_dumpspec_cpp_isl_id *cpp_id)
{
	return NFP_CPP_ISLAND_ID(cpp_id->target, cpp_id->action, cpp_id->token,
				 cpp_id->island);
}

struct nfp_dumpspec *
nfp_net_dump_load_dumpspec(struct nfp_cpp *cpp, struct nfp_rtsym_table *rtbl)
{
	const struct nfp_rtsym *specsym;
	struct nfp_dumpspec *dumpspec;
	int bytes_read;
	u64 sym_size;

	specsym = nfp_rtsym_lookup(rtbl, NFP_DUMP_SPEC_RTSYM);
	if (!specsym)
		return NULL;
	sym_size = nfp_rtsym_size(specsym);

	/* expected size of this buffer is in the order of tens of kilobytes */
	dumpspec = vmalloc(sizeof(*dumpspec) + sym_size);
	if (!dumpspec)
		return NULL;
	dumpspec->size = sym_size;

	bytes_read = nfp_rtsym_read(cpp, specsym, 0, dumpspec->data, sym_size);
	if (bytes_read != sym_size) {
		vfree(dumpspec);
		nfp_warn(cpp, "Debug dump specification read failed.\n");
		return NULL;
	}

	return dumpspec;
}

static int nfp_dump_error_tlv_size(struct nfp_dump_tl *spec)
{
	return ALIGN8(sizeof(struct nfp_dump_error) + sizeof(*spec) +
		      be32_to_cpu(spec->length));
}

static int nfp_calc_fwname_tlv_size(struct nfp_pf *pf)
{
	u32 fwname_len = strlen(nfp_mip_name(pf->mip));

	return sizeof(struct nfp_dump_tl) + ALIGN8(fwname_len + 1);
}

static int nfp_calc_hwinfo_field_sz(struct nfp_pf *pf, struct nfp_dump_tl *spec)
{
	u32 tl_len, key_len;
	const char *value;

	tl_len = be32_to_cpu(spec->length);
	key_len = strnlen(spec->data, tl_len);
	if (key_len == tl_len)
		return nfp_dump_error_tlv_size(spec);

	value = nfp_hwinfo_lookup(pf->hwinfo, spec->data);
	if (!value)
		return nfp_dump_error_tlv_size(spec);

	return sizeof(struct nfp_dump_tl) + ALIGN8(key_len + strlen(value) + 2);
}

static bool nfp_csr_spec_valid(struct nfp_dumpspec_csr *spec_csr)
{
	u32 required_read_sz = sizeof(*spec_csr) - sizeof(spec_csr->tl);
	u32 available_sz = be32_to_cpu(spec_csr->tl.length);
	u32 reg_width;

	if (available_sz < required_read_sz)
		return false;

	reg_width = be32_to_cpu(spec_csr->register_width);

	return reg_width == 32 || reg_width == 64;
}

static int
nfp_calc_rtsym_dump_sz(struct nfp_pf *pf, struct nfp_dump_tl *spec)
{
	struct nfp_rtsym_table *rtbl = pf->rtbl;
	struct nfp_dumpspec_rtsym *spec_rtsym;
	const struct nfp_rtsym *sym;
	u32 tl_len, key_len;

	spec_rtsym = (struct nfp_dumpspec_rtsym *)spec;
	tl_len = be32_to_cpu(spec->length);
	key_len = strnlen(spec_rtsym->rtsym, tl_len);
	if (key_len == tl_len)
		return nfp_dump_error_tlv_size(spec);

	sym = nfp_rtsym_lookup(rtbl, spec_rtsym->rtsym);
	if (!sym)
		return nfp_dump_error_tlv_size(spec);

	return ALIGN8(offsetof(struct nfp_dump_rtsym, rtsym) + key_len + 1) +
	       ALIGN8(nfp_rtsym_size(sym));
}

static int
nfp_add_tlv_size(struct nfp_pf *pf, struct nfp_dump_tl *tl, void *param)
{
	struct nfp_dumpspec_csr *spec_csr;
	u32 *size = param;
	u32 hwinfo_size;

	switch (be32_to_cpu(tl->type)) {
	case NFP_DUMPSPEC_TYPE_FWNAME:
		*size += nfp_calc_fwname_tlv_size(pf);
		break;
	case NFP_DUMPSPEC_TYPE_CPP_CSR:
	case NFP_DUMPSPEC_TYPE_XPB_CSR:
	case NFP_DUMPSPEC_TYPE_ME_CSR:
		spec_csr = (struct nfp_dumpspec_csr *)tl;
		if (!nfp_csr_spec_valid(spec_csr))
			*size += nfp_dump_error_tlv_size(tl);
		else
			*size += ALIGN8(sizeof(struct nfp_dump_csr)) +
				 ALIGN8(be32_to_cpu(spec_csr->cpp.dump_length));
		break;
	case NFP_DUMPSPEC_TYPE_INDIRECT_ME_CSR:
		spec_csr = (struct nfp_dumpspec_csr *)tl;
		if (!nfp_csr_spec_valid(spec_csr))
			*size += nfp_dump_error_tlv_size(tl);
		else
			*size += ALIGN8(sizeof(struct nfp_dump_csr)) +
				 ALIGN8(be32_to_cpu(spec_csr->cpp.dump_length) *
					NFP_IND_NUM_CONTEXTS);
		break;
	case NFP_DUMPSPEC_TYPE_RTSYM:
		*size += nfp_calc_rtsym_dump_sz(pf, tl);
		break;
	case NFP_DUMPSPEC_TYPE_HWINFO:
		hwinfo_size = nfp_hwinfo_get_packed_str_size(pf->hwinfo);
		*size += sizeof(struct nfp_dump_tl) + ALIGN8(hwinfo_size);
		break;
	case NFP_DUMPSPEC_TYPE_HWINFO_FIELD:
		*size += nfp_calc_hwinfo_field_sz(pf, tl);
		break;
	default:
		*size += nfp_dump_error_tlv_size(tl);
		break;
	}

	return 0;
}

static int
nfp_calc_specific_level_size(struct nfp_pf *pf, struct nfp_dump_tl *dump_level,
			     void *param)
{
	struct nfp_level_size *lev_sz = param;

	if (dump_level->type != lev_sz->requested_level)
		return 0;

	return nfp_traverse_tlvs(pf, dump_level->data,
				 be32_to_cpu(dump_level->length),
				 &lev_sz->total_size, nfp_add_tlv_size);
}

s64 nfp_net_dump_calculate_size(struct nfp_pf *pf, struct nfp_dumpspec *spec,
				u32 flag)
{
	struct nfp_level_size lev_sz;
	int err;

	lev_sz.requested_level = cpu_to_be32(flag);
	lev_sz.total_size = ALIGN8(sizeof(struct nfp_dump_prolog));

	err = nfp_traverse_tlvs(pf, spec->data, spec->size, &lev_sz,
				nfp_calc_specific_level_size);
	if (err)
		return err;

	return lev_sz.total_size;
}

static int nfp_add_tlv(u32 type, u32 total_tlv_sz, struct nfp_dump_state *dump)
{
	struct nfp_dump_tl *tl = dump->p;

	if (total_tlv_sz > dump->buf_size)
		return -ENOSPC;

	if (dump->buf_size - total_tlv_sz < dump->dumped_size)
		return -ENOSPC;

	tl->type = cpu_to_be32(type);
	tl->length = cpu_to_be32(total_tlv_sz - sizeof(*tl));

	dump->dumped_size += total_tlv_sz;
	dump->p += total_tlv_sz;

	return 0;
}

static int
nfp_dump_error_tlv(struct nfp_dump_tl *spec, int error,
		   struct nfp_dump_state *dump)
{
	struct nfp_dump_error *dump_header = dump->p;
	u32 total_spec_size, total_size;
	int err;

	total_spec_size = sizeof(*spec) + be32_to_cpu(spec->length);
	total_size = ALIGN8(sizeof(*dump_header) + total_spec_size);

	err = nfp_add_tlv(NFP_DUMPSPEC_TYPE_ERROR, total_size, dump);
	if (err)
		return err;

	dump_header->error = cpu_to_be32(error);
	memcpy(dump_header->spec, spec, total_spec_size);

	return 0;
}

static int nfp_dump_fwname(struct nfp_pf *pf, struct nfp_dump_state *dump)
{
	struct nfp_dump_tl *dump_header = dump->p;
	u32 fwname_len, total_size;
	const char *fwname;
	int err;

	fwname = nfp_mip_name(pf->mip);
	fwname_len = strlen(fwname);
	total_size = sizeof(*dump_header) + ALIGN8(fwname_len + 1);

	err = nfp_add_tlv(NFP_DUMPSPEC_TYPE_FWNAME, total_size, dump);
	if (err)
		return err;

	memcpy(dump_header->data, fwname, fwname_len);

	return 0;
}

static int
nfp_dump_hwinfo(struct nfp_pf *pf, struct nfp_dump_tl *spec,
		struct nfp_dump_state *dump)
{
	struct nfp_dump_tl *dump_header = dump->p;
	u32 hwinfo_size, total_size;
	char *hwinfo;
	int err;

	hwinfo = nfp_hwinfo_get_packed_strings(pf->hwinfo);
	hwinfo_size = nfp_hwinfo_get_packed_str_size(pf->hwinfo);
	total_size = sizeof(*dump_header) + ALIGN8(hwinfo_size);

	err = nfp_add_tlv(NFP_DUMPSPEC_TYPE_HWINFO, total_size, dump);
	if (err)
		return err;

	memcpy(dump_header->data, hwinfo, hwinfo_size);

	return 0;
}

static int nfp_dump_hwinfo_field(struct nfp_pf *pf, struct nfp_dump_tl *spec,
				 struct nfp_dump_state *dump)
{
	struct nfp_dump_tl *dump_header = dump->p;
	u32 tl_len, key_len, val_len;
	const char *key, *value;
	u32 total_size;
	int err;

	tl_len = be32_to_cpu(spec->length);
	key_len = strnlen(spec->data, tl_len);
	if (key_len == tl_len)
		return nfp_dump_error_tlv(spec, -EINVAL, dump);

	key = spec->data;
	value = nfp_hwinfo_lookup(pf->hwinfo, key);
	if (!value)
		return nfp_dump_error_tlv(spec, -ENOENT, dump);

	val_len = strlen(value);
	total_size = sizeof(*dump_header) + ALIGN8(key_len + val_len + 2);
	err = nfp_add_tlv(NFP_DUMPSPEC_TYPE_HWINFO_FIELD, total_size, dump);
	if (err)
		return err;

	memcpy(dump_header->data, key, key_len + 1);
	memcpy(dump_header->data + key_len + 1, value, val_len + 1);

	return 0;
}

static bool is_xpb_read(struct nfp_dumpspec_cpp_isl_id *cpp_id)
{
	return cpp_id->target == NFP_CPP_TARGET_ISLAND_XPB &&
	       cpp_id->action == 0 && cpp_id->token == 0;
}

static int
nfp_dump_csr_range(struct nfp_pf *pf, struct nfp_dumpspec_csr *spec_csr,
		   struct nfp_dump_state *dump)
{
	struct nfp_dump_csr *dump_header = dump->p;
	u32 reg_sz, header_size, total_size;
	u32 cpp_rd_addr, max_rd_addr;
	int bytes_read;
	void *dest;
	u32 cpp_id;
	int err;

	if (!nfp_csr_spec_valid(spec_csr))
		return nfp_dump_error_tlv(&spec_csr->tl, -EINVAL, dump);

	reg_sz = be32_to_cpu(spec_csr->register_width) / BITS_PER_BYTE;
	header_size = ALIGN8(sizeof(*dump_header));
	total_size = header_size +
		     ALIGN8(be32_to_cpu(spec_csr->cpp.dump_length));
	dest = dump->p + header_size;

	err = nfp_add_tlv(be32_to_cpu(spec_csr->tl.type), total_size, dump);
	if (err)
		return err;

	dump_header->cpp = spec_csr->cpp;
	dump_header->register_width = spec_csr->register_width;

	cpp_id = nfp_get_numeric_cpp_id(&spec_csr->cpp.cpp_id);
	cpp_rd_addr = be32_to_cpu(spec_csr->cpp.offset);
	max_rd_addr = cpp_rd_addr + be32_to_cpu(spec_csr->cpp.dump_length);

	while (cpp_rd_addr < max_rd_addr) {
		if (is_xpb_read(&spec_csr->cpp.cpp_id)) {
			err = nfp_xpb_readl(pf->cpp, cpp_rd_addr, (u32 *)dest);
		} else {
			bytes_read = nfp_cpp_read(pf->cpp, cpp_id, cpp_rd_addr,
						  dest, reg_sz);
			err = bytes_read == reg_sz ? 0 : -EIO;
		}
		if (err) {
			dump_header->error = cpu_to_be32(err);
			dump_header->error_offset = cpu_to_be32(cpp_rd_addr);
			break;
		}
		cpp_rd_addr += reg_sz;
		dest += reg_sz;
	}

	return 0;
}

/* Write context to CSRCtxPtr, then read from it. Then the value can be read
 * from IndCtxStatus.
 */
static int
nfp_read_indirect_csr(struct nfp_cpp *cpp,
		      struct nfp_dumpspec_cpp_isl_id cpp_params, u32 offset,
		      u32 reg_sz, u32 context, void *dest)
{
	u32 csr_ctx_ptr_offs;
	u32 cpp_id;
	int result;

	csr_ctx_ptr_offs = nfp_get_ind_csr_ctx_ptr_offs(offset);
	cpp_id = NFP_CPP_ISLAND_ID(cpp_params.target,
				   NFP_IND_ME_REFL_WR_SIG_INIT,
				   cpp_params.token, cpp_params.island);
	result = nfp_cpp_writel(cpp, cpp_id, csr_ctx_ptr_offs, context);
	if (result)
		return result;

	cpp_id = nfp_get_numeric_cpp_id(&cpp_params);
	result = nfp_cpp_read(cpp, cpp_id, csr_ctx_ptr_offs, dest, reg_sz);
	if (result != reg_sz)
		return result < 0 ? result : -EIO;

	result = nfp_cpp_read(cpp, cpp_id, offset, dest, reg_sz);
	if (result != reg_sz)
		return result < 0 ? result : -EIO;

	return 0;
}

static int
nfp_read_all_indirect_csr_ctx(struct nfp_cpp *cpp,
			      struct nfp_dumpspec_csr *spec_csr, u32 address,
			      u32 reg_sz, void *dest)
{
	u32 ctx;
	int err;

	for (ctx = 0; ctx < NFP_IND_NUM_CONTEXTS; ctx++) {
		err = nfp_read_indirect_csr(cpp, spec_csr->cpp.cpp_id, address,
					    reg_sz, ctx, dest + ctx * reg_sz);
		if (err)
			return err;
	}

	return 0;
}

static int
nfp_dump_indirect_csr_range(struct nfp_pf *pf,
			    struct nfp_dumpspec_csr *spec_csr,
			    struct nfp_dump_state *dump)
{
	struct nfp_dump_csr *dump_header = dump->p;
	u32 reg_sz, header_size, total_size;
	u32 cpp_rd_addr, max_rd_addr;
	u32 reg_data_length;
	void *dest;
	int err;

	if (!nfp_csr_spec_valid(spec_csr))
		return nfp_dump_error_tlv(&spec_csr->tl, -EINVAL, dump);

	reg_sz = be32_to_cpu(spec_csr->register_width) / BITS_PER_BYTE;
	header_size = ALIGN8(sizeof(*dump_header));
	reg_data_length = be32_to_cpu(spec_csr->cpp.dump_length) *
			  NFP_IND_NUM_CONTEXTS;
	total_size = header_size + ALIGN8(reg_data_length);
	dest = dump->p + header_size;

	err = nfp_add_tlv(be32_to_cpu(spec_csr->tl.type), total_size, dump);
	if (err)
		return err;

	dump_header->cpp = spec_csr->cpp;
	dump_header->register_width = spec_csr->register_width;

	cpp_rd_addr = be32_to_cpu(spec_csr->cpp.offset);
	max_rd_addr = cpp_rd_addr + be32_to_cpu(spec_csr->cpp.dump_length);
	while (cpp_rd_addr < max_rd_addr) {
		err = nfp_read_all_indirect_csr_ctx(pf->cpp, spec_csr,
						    cpp_rd_addr, reg_sz, dest);
		if (err) {
			dump_header->error = cpu_to_be32(err);
			dump_header->error_offset = cpu_to_be32(cpp_rd_addr);
			break;
		}
		cpp_rd_addr += reg_sz;
		dest += reg_sz * NFP_IND_NUM_CONTEXTS;
	}

	return 0;
}

static int
nfp_dump_single_rtsym(struct nfp_pf *pf, struct nfp_dumpspec_rtsym *spec,
		      struct nfp_dump_state *dump)
{
	struct nfp_dump_rtsym *dump_header = dump->p;
	struct nfp_dumpspec_cpp_isl_id cpp_params;
	struct nfp_rtsym_table *rtbl = pf->rtbl;
	u32 header_size, total_size, sym_size;
	const struct nfp_rtsym *sym;
	u32 tl_len, key_len;
	int bytes_read;
	void *dest;
	int err;

	tl_len = be32_to_cpu(spec->tl.length);
	key_len = strnlen(spec->rtsym, tl_len);
	if (key_len == tl_len)
		return nfp_dump_error_tlv(&spec->tl, -EINVAL, dump);

	sym = nfp_rtsym_lookup(rtbl, spec->rtsym);
	if (!sym)
		return nfp_dump_error_tlv(&spec->tl, -ENOENT, dump);

	sym_size = nfp_rtsym_size(sym);
	header_size =
		ALIGN8(offsetof(struct nfp_dump_rtsym, rtsym) + key_len + 1);
	total_size = header_size + ALIGN8(sym_size);
	dest = dump->p + header_size;

	err = nfp_add_tlv(be32_to_cpu(spec->tl.type), total_size, dump);
	if (err)
		return err;

	dump_header->padded_name_length =
		header_size - offsetof(struct nfp_dump_rtsym, rtsym);
	memcpy(dump_header->rtsym, spec->rtsym, key_len + 1);
	dump_header->cpp.dump_length = cpu_to_be32(sym_size);

	if (sym->type != NFP_RTSYM_TYPE_ABS) {
		cpp_params.target = sym->target;
		cpp_params.action = NFP_CPP_ACTION_RW;
		cpp_params.token  = 0;
		cpp_params.island = sym->domain;
		dump_header->cpp.cpp_id = cpp_params;
		dump_header->cpp.offset = cpu_to_be32(sym->addr);
	}

	bytes_read = nfp_rtsym_read(pf->cpp, sym, 0, dest, sym_size);
	if (bytes_read != sym_size) {
		if (bytes_read >= 0)
			bytes_read = -EIO;
		dump_header->error = cpu_to_be32(bytes_read);
	}

	return 0;
}

static int
nfp_dump_for_tlv(struct nfp_pf *pf, struct nfp_dump_tl *tl, void *param)
{
	struct nfp_dumpspec_rtsym *spec_rtsym;
	struct nfp_dump_state *dump = param;
	struct nfp_dumpspec_csr *spec_csr;
	int err;

	switch (be32_to_cpu(tl->type)) {
	case NFP_DUMPSPEC_TYPE_FWNAME:
		err = nfp_dump_fwname(pf, dump);
		if (err)
			return err;
		break;
	case NFP_DUMPSPEC_TYPE_CPP_CSR:
	case NFP_DUMPSPEC_TYPE_XPB_CSR:
	case NFP_DUMPSPEC_TYPE_ME_CSR:
		spec_csr = (struct nfp_dumpspec_csr *)tl;
		err = nfp_dump_csr_range(pf, spec_csr, dump);
		if (err)
			return err;
		break;
	case NFP_DUMPSPEC_TYPE_INDIRECT_ME_CSR:
		spec_csr = (struct nfp_dumpspec_csr *)tl;
		err = nfp_dump_indirect_csr_range(pf, spec_csr, dump);
		if (err)
			return err;
		break;
	case NFP_DUMPSPEC_TYPE_RTSYM:
		spec_rtsym = (struct nfp_dumpspec_rtsym *)tl;
		err = nfp_dump_single_rtsym(pf, spec_rtsym, dump);
		if (err)
			return err;
		break;
	case NFP_DUMPSPEC_TYPE_HWINFO:
		err = nfp_dump_hwinfo(pf, tl, dump);
		if (err)
			return err;
		break;
	case NFP_DUMPSPEC_TYPE_HWINFO_FIELD:
		err = nfp_dump_hwinfo_field(pf, tl, dump);
		if (err)
			return err;
		break;
	default:
		err = nfp_dump_error_tlv(tl, -EOPNOTSUPP, dump);
		if (err)
			return err;
	}

	return 0;
}

static int
nfp_dump_specific_level(struct nfp_pf *pf, struct nfp_dump_tl *dump_level,
			void *param)
{
	struct nfp_dump_state *dump = param;

	if (dump_level->type != dump->requested_level)
		return 0;

	return nfp_traverse_tlvs(pf, dump_level->data,
				 be32_to_cpu(dump_level->length), dump,
				 nfp_dump_for_tlv);
}

static int nfp_dump_populate_prolog(struct nfp_dump_state *dump)
{
	struct nfp_dump_prolog *prolog = dump->p;
	u32 total_size;
	int err;

	total_size = ALIGN8(sizeof(*prolog));

	err = nfp_add_tlv(NFP_DUMPSPEC_TYPE_PROLOG, total_size, dump);
	if (err)
		return err;

	prolog->dump_level = dump->requested_level;

	return 0;
}

int nfp_net_dump_populate_buffer(struct nfp_pf *pf, struct nfp_dumpspec *spec,
				 struct ethtool_dump *dump_param, void *dest)
{
	struct nfp_dump_state dump;
	int err;

	dump.requested_level = cpu_to_be32(dump_param->flag);
	dump.dumped_size = 0;
	dump.p = dest;
	dump.buf_size = dump_param->len;

	err = nfp_dump_populate_prolog(&dump);
	if (err)
		return err;

	err = nfp_traverse_tlvs(pf, spec->data, spec->size, &dump,
				nfp_dump_specific_level);
	if (err)
		return err;

	/* Set size of actual dump, to trigger warning if different from
	 * calculated size.
	 */
	dump_param->len = dump.dumped_size;

	return 0;
}
