// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/* Copyright (c) 2019 Mellanox Technologies. */

#include "rsc_dump.h"
#include "lib/mlx5.h"

#define MLX5_SGMT_TYPE(SGMT) MLX5_SGMT_TYPE_##SGMT
#define MLX5_SGMT_STR_ASSING(SGMT)[MLX5_SGMT_TYPE(SGMT)] = #SGMT
static const char *const mlx5_rsc_sgmt_name[] = {
	MLX5_SGMT_STR_ASSING(HW_CQPC),
	MLX5_SGMT_STR_ASSING(HW_SQPC),
	MLX5_SGMT_STR_ASSING(HW_RQPC),
	MLX5_SGMT_STR_ASSING(FULL_SRQC),
	MLX5_SGMT_STR_ASSING(FULL_CQC),
	MLX5_SGMT_STR_ASSING(FULL_EQC),
	MLX5_SGMT_STR_ASSING(FULL_QPC),
	MLX5_SGMT_STR_ASSING(SND_BUFF),
	MLX5_SGMT_STR_ASSING(RCV_BUFF),
	MLX5_SGMT_STR_ASSING(SRQ_BUFF),
	MLX5_SGMT_STR_ASSING(CQ_BUFF),
	MLX5_SGMT_STR_ASSING(EQ_BUFF),
	MLX5_SGMT_STR_ASSING(SX_SLICE),
	MLX5_SGMT_STR_ASSING(SX_SLICE_ALL),
	MLX5_SGMT_STR_ASSING(RDB),
	MLX5_SGMT_STR_ASSING(RX_SLICE_ALL),
};

struct mlx5_rsc_dump {
	u32 pdn;
	struct mlx5_core_mkey mkey;
	u16 fw_segment_type[MLX5_SGMT_TYPE_NUM];
};

struct mlx5_rsc_dump_cmd {
	u64 mem_size;
	u8 cmd[MLX5_ST_SZ_BYTES(resource_dump)];
};

static int mlx5_rsc_dump_sgmt_get_by_name(char *name)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(mlx5_rsc_sgmt_name); i++)
		if (!strcmp(name, mlx5_rsc_sgmt_name[i]))
			return i;

	return -EINVAL;
}

static void mlx5_rsc_dump_read_menu_sgmt(struct mlx5_rsc_dump *rsc_dump, struct page *page)
{
	void *data = page_address(page);
	enum mlx5_sgmt_type sgmt_idx;
	int num_of_items;
	char *sgmt_name;
	void *member;
	void *menu;
	int i;

	menu = MLX5_ADDR_OF(menu_resource_dump_response, data, menu);
	num_of_items = MLX5_GET(resource_dump_menu_segment, menu, num_of_records);

	for (i = 0; i < num_of_items; i++) {
		member = MLX5_ADDR_OF(resource_dump_menu_segment, menu, record[i]);
		sgmt_name =  MLX5_ADDR_OF(resource_dump_menu_record, member, segment_name);
		sgmt_idx = mlx5_rsc_dump_sgmt_get_by_name(sgmt_name);
		if (sgmt_idx == -EINVAL)
			continue;
		rsc_dump->fw_segment_type[sgmt_idx] = MLX5_GET(resource_dump_menu_record,
							       member, segment_type);
	}
}

static int mlx5_rsc_dump_trigger(struct mlx5_core_dev *dev, struct mlx5_rsc_dump_cmd *cmd,
				 struct page *page)
{
	struct mlx5_rsc_dump *rsc_dump = dev->rsc_dump;
	struct device *ddev = &dev->pdev->dev;
	u32 out_seq_num;
	u32 in_seq_num;
	dma_addr_t dma;
	int err;

	dma = dma_map_page(ddev, page, 0, cmd->mem_size, DMA_FROM_DEVICE);
	if (unlikely(dma_mapping_error(ddev, dma)))
		return -ENOMEM;

	in_seq_num = MLX5_GET(resource_dump, cmd->cmd, seq_num);
	MLX5_SET(resource_dump, cmd->cmd, mkey, rsc_dump->mkey.key);
	MLX5_SET64(resource_dump, cmd->cmd, address, dma);

	err = mlx5_core_access_reg(dev, cmd->cmd, sizeof(cmd->cmd), cmd->cmd,
				   sizeof(cmd->cmd), MLX5_REG_RESOURCE_DUMP, 0, 1);
	if (err) {
		mlx5_core_err(dev, "Resource dump: Failed to access err %d\n", err);
		goto out;
	}
	out_seq_num = MLX5_GET(resource_dump, cmd->cmd, seq_num);
	if (out_seq_num && (in_seq_num + 1 != out_seq_num))
		err = -EIO;
out:
	dma_unmap_page(ddev, dma, cmd->mem_size, DMA_FROM_DEVICE);
	return err;
}

struct mlx5_rsc_dump_cmd *mlx5_rsc_dump_cmd_create(struct mlx5_core_dev *dev,
						   struct mlx5_rsc_key *key)
{
	struct mlx5_rsc_dump_cmd *cmd;
	int sgmt_type;

	if (IS_ERR_OR_NULL(dev->rsc_dump))
		return ERR_PTR(-EOPNOTSUPP);

	sgmt_type = dev->rsc_dump->fw_segment_type[key->rsc];
	if (!sgmt_type && key->rsc != MLX5_SGMT_TYPE_MENU)
		return ERR_PTR(-EOPNOTSUPP);

	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (!cmd) {
		mlx5_core_err(dev, "Resource dump: Failed to allocate command\n");
		return ERR_PTR(-ENOMEM);
	}
	MLX5_SET(resource_dump, cmd->cmd, segment_type, sgmt_type);
	MLX5_SET(resource_dump, cmd->cmd, index1, key->index1);
	MLX5_SET(resource_dump, cmd->cmd, index2, key->index2);
	MLX5_SET(resource_dump, cmd->cmd, num_of_obj1, key->num_of_obj1);
	MLX5_SET(resource_dump, cmd->cmd, num_of_obj2, key->num_of_obj2);
	MLX5_SET(resource_dump, cmd->cmd, size, key->size);
	cmd->mem_size = key->size;
	return cmd;
}

void mlx5_rsc_dump_cmd_destroy(struct mlx5_rsc_dump_cmd *cmd)
{
	kfree(cmd);
}

int mlx5_rsc_dump_next(struct mlx5_core_dev *dev, struct mlx5_rsc_dump_cmd *cmd,
		       struct page *page, int *size)
{
	bool more_dump;
	int err;

	if (IS_ERR_OR_NULL(dev->rsc_dump))
		return -EOPNOTSUPP;

	err = mlx5_rsc_dump_trigger(dev, cmd, page);
	if (err) {
		mlx5_core_err(dev, "Resource dump: Failed to trigger dump, %d\n", err);
		return err;
	}
	*size = MLX5_GET(resource_dump, cmd->cmd, size);
	more_dump = MLX5_GET(resource_dump, cmd->cmd, more_dump);

	return more_dump;
}

#define MLX5_RSC_DUMP_MENU_SEGMENT 0xffff
static int mlx5_rsc_dump_menu(struct mlx5_core_dev *dev)
{
	struct mlx5_rsc_dump_cmd *cmd = NULL;
	struct mlx5_rsc_key key = {};
	struct page *page;
	int size;
	int err;

	page = alloc_page(GFP_KERNEL);
	if (!page)
		return -ENOMEM;

	key.rsc = MLX5_SGMT_TYPE_MENU;
	key.size = PAGE_SIZE;
	cmd  = mlx5_rsc_dump_cmd_create(dev, &key);
	if (IS_ERR(cmd)) {
		err = PTR_ERR(cmd);
		goto free_page;
	}
	MLX5_SET(resource_dump, cmd->cmd, segment_type, MLX5_RSC_DUMP_MENU_SEGMENT);

	do {
		err = mlx5_rsc_dump_next(dev, cmd, page, &size);
		if (err < 0)
			goto destroy_cmd;

		mlx5_rsc_dump_read_menu_sgmt(dev->rsc_dump, page);

	} while (err > 0);

destroy_cmd:
	mlx5_rsc_dump_cmd_destroy(cmd);
free_page:
	__free_page(page);

	return err;
}

static int mlx5_rsc_dump_create_mkey(struct mlx5_core_dev *mdev, u32 pdn,
				     struct mlx5_core_mkey *mkey)
{
	int inlen = MLX5_ST_SZ_BYTES(create_mkey_in);
	void *mkc;
	u32 *in;
	int err;

	in = kvzalloc(inlen, GFP_KERNEL);
	if (!in)
		return -ENOMEM;

	mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
	MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_PA);
	MLX5_SET(mkc, mkc, lw, 1);
	MLX5_SET(mkc, mkc, lr, 1);

	MLX5_SET(mkc, mkc, pd, pdn);
	MLX5_SET(mkc, mkc, length64, 1);
	MLX5_SET(mkc, mkc, qpn, 0xffffff);

	err = mlx5_core_create_mkey(mdev, mkey, in, inlen);

	kvfree(in);
	return err;
}

struct mlx5_rsc_dump *mlx5_rsc_dump_create(struct mlx5_core_dev *dev)
{
	struct mlx5_rsc_dump *rsc_dump;

	if (!MLX5_CAP_DEBUG(dev, resource_dump)) {
		mlx5_core_dbg(dev, "Resource dump: capability not present\n");
		return NULL;
	}
	rsc_dump = kzalloc(sizeof(*rsc_dump), GFP_KERNEL);
	if (!rsc_dump)
		return ERR_PTR(-ENOMEM);

	return rsc_dump;
}

void mlx5_rsc_dump_destroy(struct mlx5_core_dev *dev)
{
	if (IS_ERR_OR_NULL(dev->rsc_dump))
		return;
	kfree(dev->rsc_dump);
}

int mlx5_rsc_dump_init(struct mlx5_core_dev *dev)
{
	struct mlx5_rsc_dump *rsc_dump = dev->rsc_dump;
	int err;

	if (IS_ERR_OR_NULL(dev->rsc_dump))
		return 0;

	err = mlx5_core_alloc_pd(dev, &rsc_dump->pdn);
	if (err) {
		mlx5_core_warn(dev, "Resource dump: Failed to allocate PD %d\n", err);
		return err;
	}
	err = mlx5_rsc_dump_create_mkey(dev, rsc_dump->pdn, &rsc_dump->mkey);
	if (err) {
		mlx5_core_err(dev, "Resource dump: Failed to create mkey, %d\n", err);
		goto free_pd;
	}
	err = mlx5_rsc_dump_menu(dev);
	if (err) {
		mlx5_core_err(dev, "Resource dump: Failed to read menu, %d\n", err);
		goto destroy_mkey;
	}
	return err;

destroy_mkey:
	mlx5_core_destroy_mkey(dev, &rsc_dump->mkey);
free_pd:
	mlx5_core_dealloc_pd(dev, rsc_dump->pdn);
	return err;
}

void mlx5_rsc_dump_cleanup(struct mlx5_core_dev *dev)
{
	if (IS_ERR_OR_NULL(dev->rsc_dump))
		return;

	mlx5_core_destroy_mkey(dev, &dev->rsc_dump->mkey);
	mlx5_core_dealloc_pd(dev, dev->rsc_dump->pdn);
}
