// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */

#include <linux/refcount.h>
#include <linux/idr.h>

#include "spectrum.h"
#include "reg.h"

struct mlxsw_sp_pgt {
	struct idr pgt_idr;
	u16 end_index; /* Exclusive. */
	struct mutex lock; /* Protects PGT. */
	bool smpe_index_valid;
};

struct mlxsw_sp_pgt_entry {
	struct list_head ports_list;
	u16 index;
	u16 smpe_index;
};

struct mlxsw_sp_pgt_entry_port {
	struct list_head list; /* Member of 'ports_list'. */
	u16 local_port;
};

int mlxsw_sp_pgt_mid_alloc(struct mlxsw_sp *mlxsw_sp, u16 *p_mid)
{
	int index, err = 0;

	mutex_lock(&mlxsw_sp->pgt->lock);
	index = idr_alloc(&mlxsw_sp->pgt->pgt_idr, NULL, 0,
			  mlxsw_sp->pgt->end_index, GFP_KERNEL);

	if (index < 0) {
		err = index;
		goto err_idr_alloc;
	}

	*p_mid = index;
	mutex_unlock(&mlxsw_sp->pgt->lock);
	return 0;

err_idr_alloc:
	mutex_unlock(&mlxsw_sp->pgt->lock);
	return err;
}

void mlxsw_sp_pgt_mid_free(struct mlxsw_sp *mlxsw_sp, u16 mid_base)
{
	mutex_lock(&mlxsw_sp->pgt->lock);
	WARN_ON(idr_remove(&mlxsw_sp->pgt->pgt_idr, mid_base));
	mutex_unlock(&mlxsw_sp->pgt->lock);
}

int mlxsw_sp_pgt_mid_alloc_range(struct mlxsw_sp *mlxsw_sp, u16 *p_mid_base,
				 u16 count)
{
	unsigned int mid_base;
	int i, err;

	mutex_lock(&mlxsw_sp->pgt->lock);

	mid_base = idr_get_cursor(&mlxsw_sp->pgt->pgt_idr);
	for (i = 0; i < count; i++) {
		err = idr_alloc_cyclic(&mlxsw_sp->pgt->pgt_idr, NULL,
				       mid_base, mid_base + count, GFP_KERNEL);
		if (err < 0)
			goto err_idr_alloc_cyclic;
	}

	mutex_unlock(&mlxsw_sp->pgt->lock);
	*p_mid_base = mid_base;
	return 0;

err_idr_alloc_cyclic:
	for (i--; i >= 0; i--)
		idr_remove(&mlxsw_sp->pgt->pgt_idr, mid_base + i);
	mutex_unlock(&mlxsw_sp->pgt->lock);
	return err;
}

void
mlxsw_sp_pgt_mid_free_range(struct mlxsw_sp *mlxsw_sp, u16 mid_base, u16 count)
{
	struct idr *pgt_idr = &mlxsw_sp->pgt->pgt_idr;
	int i;

	mutex_lock(&mlxsw_sp->pgt->lock);

	for (i = 0; i < count; i++)
		WARN_ON_ONCE(idr_remove(pgt_idr, mid_base + i));

	mutex_unlock(&mlxsw_sp->pgt->lock);
}

static struct mlxsw_sp_pgt_entry_port *
mlxsw_sp_pgt_entry_port_lookup(struct mlxsw_sp_pgt_entry *pgt_entry,
			       u16 local_port)
{
	struct mlxsw_sp_pgt_entry_port *pgt_entry_port;

	list_for_each_entry(pgt_entry_port, &pgt_entry->ports_list, list) {
		if (pgt_entry_port->local_port == local_port)
			return pgt_entry_port;
	}

	return NULL;
}

static struct mlxsw_sp_pgt_entry *
mlxsw_sp_pgt_entry_create(struct mlxsw_sp_pgt *pgt, u16 mid, u16 smpe)
{
	struct mlxsw_sp_pgt_entry *pgt_entry;
	void *ret;
	int err;

	pgt_entry = kzalloc(sizeof(*pgt_entry), GFP_KERNEL);
	if (!pgt_entry)
		return ERR_PTR(-ENOMEM);

	ret = idr_replace(&pgt->pgt_idr, pgt_entry, mid);
	if (IS_ERR(ret)) {
		err = PTR_ERR(ret);
		goto err_idr_replace;
	}

	INIT_LIST_HEAD(&pgt_entry->ports_list);
	pgt_entry->index = mid;
	pgt_entry->smpe_index = smpe;
	return pgt_entry;

err_idr_replace:
	kfree(pgt_entry);
	return ERR_PTR(err);
}

static void mlxsw_sp_pgt_entry_destroy(struct mlxsw_sp_pgt *pgt,
				       struct mlxsw_sp_pgt_entry *pgt_entry)
{
	WARN_ON(!list_empty(&pgt_entry->ports_list));

	pgt_entry = idr_replace(&pgt->pgt_idr, NULL, pgt_entry->index);
	if (WARN_ON(IS_ERR(pgt_entry)))
		return;

	kfree(pgt_entry);
}

static struct mlxsw_sp_pgt_entry *
mlxsw_sp_pgt_entry_get(struct mlxsw_sp_pgt *pgt, u16 mid, u16 smpe)
{
	struct mlxsw_sp_pgt_entry *pgt_entry;

	pgt_entry = idr_find(&pgt->pgt_idr, mid);
	if (pgt_entry)
		return pgt_entry;

	return mlxsw_sp_pgt_entry_create(pgt, mid, smpe);
}

static void mlxsw_sp_pgt_entry_put(struct mlxsw_sp_pgt *pgt, u16 mid)
{
	struct mlxsw_sp_pgt_entry *pgt_entry;

	pgt_entry = idr_find(&pgt->pgt_idr, mid);
	if (WARN_ON(!pgt_entry))
		return;

	if (list_empty(&pgt_entry->ports_list))
		mlxsw_sp_pgt_entry_destroy(pgt, pgt_entry);
}

static void mlxsw_sp_pgt_smid2_port_set(char *smid2_pl, u16 local_port,
					bool member)
{
	mlxsw_reg_smid2_port_set(smid2_pl, local_port, member);
	mlxsw_reg_smid2_port_mask_set(smid2_pl, local_port, 1);
}

static int
mlxsw_sp_pgt_entry_port_write(struct mlxsw_sp *mlxsw_sp,
			      const struct mlxsw_sp_pgt_entry *pgt_entry,
			      u16 local_port, bool member)
{
	char *smid2_pl;
	int err;

	smid2_pl = kmalloc(MLXSW_REG_SMID2_LEN, GFP_KERNEL);
	if (!smid2_pl)
		return -ENOMEM;

	mlxsw_reg_smid2_pack(smid2_pl, pgt_entry->index, 0, 0,
			     mlxsw_sp->pgt->smpe_index_valid,
			     pgt_entry->smpe_index);

	mlxsw_sp_pgt_smid2_port_set(smid2_pl, local_port, member);
	err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(smid2), smid2_pl);

	kfree(smid2_pl);

	return err;
}

static struct mlxsw_sp_pgt_entry_port *
mlxsw_sp_pgt_entry_port_create(struct mlxsw_sp *mlxsw_sp,
			       struct mlxsw_sp_pgt_entry *pgt_entry,
			       u16 local_port)
{
	struct mlxsw_sp_pgt_entry_port *pgt_entry_port;
	int err;

	pgt_entry_port = kzalloc(sizeof(*pgt_entry_port), GFP_KERNEL);
	if (!pgt_entry_port)
		return ERR_PTR(-ENOMEM);

	err = mlxsw_sp_pgt_entry_port_write(mlxsw_sp, pgt_entry, local_port,
					    true);
	if (err)
		goto err_pgt_entry_port_write;

	pgt_entry_port->local_port = local_port;
	list_add(&pgt_entry_port->list, &pgt_entry->ports_list);

	return pgt_entry_port;

err_pgt_entry_port_write:
	kfree(pgt_entry_port);
	return ERR_PTR(err);
}

static void
mlxsw_sp_pgt_entry_port_destroy(struct mlxsw_sp *mlxsw_sp,
				struct mlxsw_sp_pgt_entry *pgt_entry,
				struct mlxsw_sp_pgt_entry_port *pgt_entry_port)

{
	list_del(&pgt_entry_port->list);
	mlxsw_sp_pgt_entry_port_write(mlxsw_sp, pgt_entry,
				      pgt_entry_port->local_port, false);
	kfree(pgt_entry_port);
}

static int mlxsw_sp_pgt_entry_port_add(struct mlxsw_sp *mlxsw_sp, u16 mid,
				       u16 smpe, u16 local_port)
{
	struct mlxsw_sp_pgt_entry_port *pgt_entry_port;
	struct mlxsw_sp_pgt_entry *pgt_entry;
	int err;

	mutex_lock(&mlxsw_sp->pgt->lock);

	pgt_entry = mlxsw_sp_pgt_entry_get(mlxsw_sp->pgt, mid, smpe);
	if (IS_ERR(pgt_entry)) {
		err = PTR_ERR(pgt_entry);
		goto err_pgt_entry_get;
	}

	pgt_entry_port = mlxsw_sp_pgt_entry_port_create(mlxsw_sp, pgt_entry,
							local_port);
	if (IS_ERR(pgt_entry_port)) {
		err = PTR_ERR(pgt_entry_port);
		goto err_pgt_entry_port_get;
	}

	mutex_unlock(&mlxsw_sp->pgt->lock);
	return 0;

err_pgt_entry_port_get:
	mlxsw_sp_pgt_entry_put(mlxsw_sp->pgt, mid);
err_pgt_entry_get:
	mutex_unlock(&mlxsw_sp->pgt->lock);
	return err;
}

static void mlxsw_sp_pgt_entry_port_del(struct mlxsw_sp *mlxsw_sp,
					u16 mid, u16 smpe, u16 local_port)
{
	struct mlxsw_sp_pgt_entry_port *pgt_entry_port;
	struct mlxsw_sp_pgt_entry *pgt_entry;

	mutex_lock(&mlxsw_sp->pgt->lock);

	pgt_entry = idr_find(&mlxsw_sp->pgt->pgt_idr, mid);
	if (!pgt_entry)
		goto out;

	pgt_entry_port = mlxsw_sp_pgt_entry_port_lookup(pgt_entry, local_port);
	if (!pgt_entry_port)
		goto out;

	mlxsw_sp_pgt_entry_port_destroy(mlxsw_sp, pgt_entry, pgt_entry_port);
	mlxsw_sp_pgt_entry_put(mlxsw_sp->pgt, mid);

out:
	mutex_unlock(&mlxsw_sp->pgt->lock);
}

int mlxsw_sp_pgt_entry_port_set(struct mlxsw_sp *mlxsw_sp, u16 mid,
				u16 smpe, u16 local_port, bool member)
{
	if (member)
		return mlxsw_sp_pgt_entry_port_add(mlxsw_sp, mid, smpe,
						   local_port);

	mlxsw_sp_pgt_entry_port_del(mlxsw_sp, mid, smpe, local_port);
	return 0;
}

int mlxsw_sp_pgt_init(struct mlxsw_sp *mlxsw_sp)
{
	struct mlxsw_sp_pgt *pgt;

	if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, PGT_SIZE))
		return -EIO;

	pgt = kzalloc(sizeof(*mlxsw_sp->pgt), GFP_KERNEL);
	if (!pgt)
		return -ENOMEM;

	idr_init(&pgt->pgt_idr);
	pgt->end_index = MLXSW_CORE_RES_GET(mlxsw_sp->core, PGT_SIZE);
	mutex_init(&pgt->lock);
	pgt->smpe_index_valid = mlxsw_sp->pgt_smpe_index_valid;
	mlxsw_sp->pgt = pgt;
	return 0;
}

void mlxsw_sp_pgt_fini(struct mlxsw_sp *mlxsw_sp)
{
	mutex_destroy(&mlxsw_sp->pgt->lock);
	WARN_ON(!idr_is_empty(&mlxsw_sp->pgt->pgt_idr));
	idr_destroy(&mlxsw_sp->pgt->pgt_idr);
	kfree(mlxsw_sp->pgt);
}
