// SPDX-License-Identifier: GPL-2.0-or-later
#include <net/dsa.h>

#include "chip.h"
#include "devlink.h"
#include "global1.h"
#include "global2.h"
#include "port.h"

static int mv88e6xxx_atu_get_hash(struct mv88e6xxx_chip *chip, u8 *hash)
{
	if (chip->info->ops->atu_get_hash)
		return chip->info->ops->atu_get_hash(chip, hash);

	return -EOPNOTSUPP;
}

static int mv88e6xxx_atu_set_hash(struct mv88e6xxx_chip *chip, u8 hash)
{
	if (chip->info->ops->atu_set_hash)
		return chip->info->ops->atu_set_hash(chip, hash);

	return -EOPNOTSUPP;
}

enum mv88e6xxx_devlink_param_id {
	MV88E6XXX_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
	MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH,
};

int mv88e6xxx_devlink_param_get(struct dsa_switch *ds, u32 id,
				struct devlink_param_gset_ctx *ctx)
{
	struct mv88e6xxx_chip *chip = ds->priv;
	int err;

	mv88e6xxx_reg_lock(chip);

	switch (id) {
	case MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH:
		err = mv88e6xxx_atu_get_hash(chip, &ctx->val.vu8);
		break;
	default:
		err = -EOPNOTSUPP;
		break;
	}

	mv88e6xxx_reg_unlock(chip);

	return err;
}

int mv88e6xxx_devlink_param_set(struct dsa_switch *ds, u32 id,
				struct devlink_param_gset_ctx *ctx)
{
	struct mv88e6xxx_chip *chip = ds->priv;
	int err;

	mv88e6xxx_reg_lock(chip);

	switch (id) {
	case MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH:
		err = mv88e6xxx_atu_set_hash(chip, ctx->val.vu8);
		break;
	default:
		err = -EOPNOTSUPP;
		break;
	}

	mv88e6xxx_reg_unlock(chip);

	return err;
}

static const struct devlink_param mv88e6xxx_devlink_params[] = {
	DSA_DEVLINK_PARAM_DRIVER(MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH,
				 "ATU_hash", DEVLINK_PARAM_TYPE_U8,
				 BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
};

int mv88e6xxx_setup_devlink_params(struct dsa_switch *ds)
{
	return dsa_devlink_params_register(ds, mv88e6xxx_devlink_params,
					   ARRAY_SIZE(mv88e6xxx_devlink_params));
}

void mv88e6xxx_teardown_devlink_params(struct dsa_switch *ds)
{
	dsa_devlink_params_unregister(ds, mv88e6xxx_devlink_params,
				      ARRAY_SIZE(mv88e6xxx_devlink_params));
}

enum mv88e6xxx_devlink_resource_id {
	MV88E6XXX_RESOURCE_ID_ATU,
	MV88E6XXX_RESOURCE_ID_ATU_BIN_0,
	MV88E6XXX_RESOURCE_ID_ATU_BIN_1,
	MV88E6XXX_RESOURCE_ID_ATU_BIN_2,
	MV88E6XXX_RESOURCE_ID_ATU_BIN_3,
};

static u64 mv88e6xxx_devlink_atu_bin_get(struct mv88e6xxx_chip *chip,
					 u16 bin)
{
	u16 occupancy = 0;
	int err;

	mv88e6xxx_reg_lock(chip);

	err = mv88e6xxx_g2_atu_stats_set(chip, MV88E6XXX_G2_ATU_STATS_MODE_ALL,
					 bin);
	if (err) {
		dev_err(chip->dev, "failed to set ATU stats kind/bin\n");
		goto unlock;
	}

	err = mv88e6xxx_g1_atu_get_next(chip, 0);
	if (err) {
		dev_err(chip->dev, "failed to perform ATU get next\n");
		goto unlock;
	}

	err = mv88e6xxx_g2_atu_stats_get(chip, &occupancy);
	if (err) {
		dev_err(chip->dev, "failed to get ATU stats\n");
		goto unlock;
	}

	occupancy &= MV88E6XXX_G2_ATU_STATS_MASK;

unlock:
	mv88e6xxx_reg_unlock(chip);

	return occupancy;
}

static u64 mv88e6xxx_devlink_atu_bin_0_get(void *priv)
{
	struct mv88e6xxx_chip *chip = priv;

	return mv88e6xxx_devlink_atu_bin_get(chip,
					     MV88E6XXX_G2_ATU_STATS_BIN_0);
}

static u64 mv88e6xxx_devlink_atu_bin_1_get(void *priv)
{
	struct mv88e6xxx_chip *chip = priv;

	return mv88e6xxx_devlink_atu_bin_get(chip,
					     MV88E6XXX_G2_ATU_STATS_BIN_1);
}

static u64 mv88e6xxx_devlink_atu_bin_2_get(void *priv)
{
	struct mv88e6xxx_chip *chip = priv;

	return mv88e6xxx_devlink_atu_bin_get(chip,
					     MV88E6XXX_G2_ATU_STATS_BIN_2);
}

static u64 mv88e6xxx_devlink_atu_bin_3_get(void *priv)
{
	struct mv88e6xxx_chip *chip = priv;

	return mv88e6xxx_devlink_atu_bin_get(chip,
					     MV88E6XXX_G2_ATU_STATS_BIN_3);
}

static u64 mv88e6xxx_devlink_atu_get(void *priv)
{
	return mv88e6xxx_devlink_atu_bin_0_get(priv) +
		mv88e6xxx_devlink_atu_bin_1_get(priv) +
		mv88e6xxx_devlink_atu_bin_2_get(priv) +
		mv88e6xxx_devlink_atu_bin_3_get(priv);
}

int mv88e6xxx_setup_devlink_resources(struct dsa_switch *ds)
{
	struct devlink_resource_size_params size_params;
	struct mv88e6xxx_chip *chip = ds->priv;
	int err;

	devlink_resource_size_params_init(&size_params,
					  mv88e6xxx_num_macs(chip),
					  mv88e6xxx_num_macs(chip),
					  1, DEVLINK_RESOURCE_UNIT_ENTRY);

	err = dsa_devlink_resource_register(ds, "ATU",
					    mv88e6xxx_num_macs(chip),
					    MV88E6XXX_RESOURCE_ID_ATU,
					    DEVLINK_RESOURCE_ID_PARENT_TOP,
					    &size_params);
	if (err)
		goto out;

	devlink_resource_size_params_init(&size_params,
					  mv88e6xxx_num_macs(chip) / 4,
					  mv88e6xxx_num_macs(chip) / 4,
					  1, DEVLINK_RESOURCE_UNIT_ENTRY);

	err = dsa_devlink_resource_register(ds, "ATU_bin_0",
					    mv88e6xxx_num_macs(chip) / 4,
					    MV88E6XXX_RESOURCE_ID_ATU_BIN_0,
					    MV88E6XXX_RESOURCE_ID_ATU,
					    &size_params);
	if (err)
		goto out;

	err = dsa_devlink_resource_register(ds, "ATU_bin_1",
					    mv88e6xxx_num_macs(chip) / 4,
					    MV88E6XXX_RESOURCE_ID_ATU_BIN_1,
					    MV88E6XXX_RESOURCE_ID_ATU,
					    &size_params);
	if (err)
		goto out;

	err = dsa_devlink_resource_register(ds, "ATU_bin_2",
					    mv88e6xxx_num_macs(chip) / 4,
					    MV88E6XXX_RESOURCE_ID_ATU_BIN_2,
					    MV88E6XXX_RESOURCE_ID_ATU,
					    &size_params);
	if (err)
		goto out;

	err = dsa_devlink_resource_register(ds, "ATU_bin_3",
					    mv88e6xxx_num_macs(chip) / 4,
					    MV88E6XXX_RESOURCE_ID_ATU_BIN_3,
					    MV88E6XXX_RESOURCE_ID_ATU,
					    &size_params);
	if (err)
		goto out;

	dsa_devlink_resource_occ_get_register(ds,
					      MV88E6XXX_RESOURCE_ID_ATU,
					      mv88e6xxx_devlink_atu_get,
					      chip);

	dsa_devlink_resource_occ_get_register(ds,
					      MV88E6XXX_RESOURCE_ID_ATU_BIN_0,
					      mv88e6xxx_devlink_atu_bin_0_get,
					      chip);

	dsa_devlink_resource_occ_get_register(ds,
					      MV88E6XXX_RESOURCE_ID_ATU_BIN_1,
					      mv88e6xxx_devlink_atu_bin_1_get,
					      chip);

	dsa_devlink_resource_occ_get_register(ds,
					      MV88E6XXX_RESOURCE_ID_ATU_BIN_2,
					      mv88e6xxx_devlink_atu_bin_2_get,
					      chip);

	dsa_devlink_resource_occ_get_register(ds,
					      MV88E6XXX_RESOURCE_ID_ATU_BIN_3,
					      mv88e6xxx_devlink_atu_bin_3_get,
					      chip);

	return 0;

out:
	dsa_devlink_resources_unregister(ds);
	return err;
}

static int mv88e6xxx_region_global_snapshot(struct devlink *dl,
					    const struct devlink_region_ops *ops,
					    struct netlink_ext_ack *extack,
					    u8 **data)
{
	struct mv88e6xxx_region_priv *region_priv = ops->priv;
	struct dsa_switch *ds = dsa_devlink_to_ds(dl);
	struct mv88e6xxx_chip *chip = ds->priv;
	u16 *registers;
	int i, err;

	registers = kmalloc_array(32, sizeof(u16), GFP_KERNEL);
	if (!registers)
		return -ENOMEM;

	mv88e6xxx_reg_lock(chip);
	for (i = 0; i < 32; i++) {
		switch (region_priv->id) {
		case MV88E6XXX_REGION_GLOBAL1:
			err = mv88e6xxx_g1_read(chip, i, &registers[i]);
			break;
		case MV88E6XXX_REGION_GLOBAL2:
			err = mv88e6xxx_g2_read(chip, i, &registers[i]);
			break;
		default:
			err = -EOPNOTSUPP;
		}

		if (err) {
			kfree(registers);
			goto out;
		}
	}
	*data = (u8 *)registers;
out:
	mv88e6xxx_reg_unlock(chip);

	return err;
}

/* The ATU entry varies between mv88e6xxx chipset generations. Define
 * a generic format which covers all the current and hopefully future
 * mv88e6xxx generations
 */

struct mv88e6xxx_devlink_atu_entry {
	/* The FID is scattered over multiple registers. */
	u16 fid;
	u16 atu_op;
	u16 atu_data;
	u16 atu_01;
	u16 atu_23;
	u16 atu_45;
};

static int mv88e6xxx_region_atu_snapshot_fid(struct mv88e6xxx_chip *chip,
					     int fid,
					     struct mv88e6xxx_devlink_atu_entry *table,
					     int *count)
{
	u16 atu_op, atu_data, atu_01, atu_23, atu_45;
	struct mv88e6xxx_atu_entry addr;
	int err;

	addr.state = 0;
	eth_broadcast_addr(addr.mac);

	do {
		err = mv88e6xxx_g1_atu_getnext(chip, fid, &addr);
		if (err)
			return err;

		if (!addr.state)
			break;

		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_OP, &atu_op);
		if (err)
			return err;

		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_DATA, &atu_data);
		if (err)
			return err;

		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_MAC01, &atu_01);
		if (err)
			return err;

		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_MAC23, &atu_23);
		if (err)
			return err;

		err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_MAC45, &atu_45);
		if (err)
			return err;

		table[*count].fid = fid;
		table[*count].atu_op = atu_op;
		table[*count].atu_data = atu_data;
		table[*count].atu_01 = atu_01;
		table[*count].atu_23 = atu_23;
		table[*count].atu_45 = atu_45;
		(*count)++;
	} while (!is_broadcast_ether_addr(addr.mac));

	return 0;
}

static int mv88e6xxx_region_atu_snapshot(struct devlink *dl,
					 const struct devlink_region_ops *ops,
					 struct netlink_ext_ack *extack,
					 u8 **data)
{
	struct dsa_switch *ds = dsa_devlink_to_ds(dl);
	DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID);
	struct mv88e6xxx_devlink_atu_entry *table;
	struct mv88e6xxx_chip *chip = ds->priv;
	int fid = -1, count, err;

	table = kmalloc_array(mv88e6xxx_num_databases(chip),
			      sizeof(struct mv88e6xxx_devlink_atu_entry),
			      GFP_KERNEL);
	if (!table)
		return -ENOMEM;

	memset(table, 0, mv88e6xxx_num_databases(chip) *
	       sizeof(struct mv88e6xxx_devlink_atu_entry));

	count = 0;

	mv88e6xxx_reg_lock(chip);

	err = mv88e6xxx_fid_map(chip, fid_bitmap);
	if (err) {
		kfree(table);
		goto out;
	}

	while (1) {
		fid = find_next_bit(fid_bitmap, MV88E6XXX_N_FID, fid + 1);
		if (fid == MV88E6XXX_N_FID)
			break;

		err =  mv88e6xxx_region_atu_snapshot_fid(chip, fid, table,
							 &count);
		if (err) {
			kfree(table);
			goto out;
		}
	}
	*data = (u8 *)table;
out:
	mv88e6xxx_reg_unlock(chip);

	return err;
}

/**
 * struct mv88e6xxx_devlink_vtu_entry - Devlink VTU entry
 * @fid:   Global1/2:   FID and VLAN policy.
 * @sid:   Global1/3:   SID, unknown filters and learning.
 * @op:    Global1/5:   FID (old chipsets).
 * @vid:   Global1/6:   VID, valid, and page.
 * @data:  Global1/7-9: Membership data and priority override.
 * @resvd: Reserved. Also happens to align the size to 16B.
 *
 * The VTU entry format varies between chipset generations, the
 * descriptions above represent the superset of all possible
 * information, not all fields are valid on all devices. Since this is
 * a low-level debug interface, copy all data verbatim and defer
 * parsing to the consumer.
 */
struct mv88e6xxx_devlink_vtu_entry {
	u16 fid;
	u16 sid;
	u16 op;
	u16 vid;
	u16 data[3];
	u16 resvd;
};

static int mv88e6xxx_region_vtu_snapshot(struct devlink *dl,
					 const struct devlink_region_ops *ops,
					 struct netlink_ext_ack *extack,
					 u8 **data)
{
	struct mv88e6xxx_devlink_vtu_entry *table, *entry;
	struct dsa_switch *ds = dsa_devlink_to_ds(dl);
	struct mv88e6xxx_chip *chip = ds->priv;
	struct mv88e6xxx_vtu_entry vlan;
	int err;

	table = kcalloc(mv88e6xxx_max_vid(chip) + 1,
			sizeof(struct mv88e6xxx_devlink_vtu_entry),
			GFP_KERNEL);
	if (!table)
		return -ENOMEM;

	entry = table;
	vlan.vid = mv88e6xxx_max_vid(chip);
	vlan.valid = false;

	mv88e6xxx_reg_lock(chip);

	do {
		err = mv88e6xxx_g1_vtu_getnext(chip, &vlan);
		if (err)
			break;

		if (!vlan.valid)
			break;

		err = err ? : mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_FID,
						&entry->fid);
		err = err ? : mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_SID,
						&entry->sid);
		err = err ? : mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_OP,
						&entry->op);
		err = err ? : mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_VID,
						&entry->vid);
		err = err ? : mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1,
						&entry->data[0]);
		err = err ? : mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA2,
						&entry->data[1]);
		err = err ? : mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA3,
						&entry->data[2]);
		if (err)
			break;

		entry++;
	} while (vlan.vid < mv88e6xxx_max_vid(chip));

	mv88e6xxx_reg_unlock(chip);

	if (err) {
		kfree(table);
		return err;
	}

	*data = (u8 *)table;
	return 0;
}

/**
 * struct mv88e6xxx_devlink_stu_entry - Devlink STU entry
 * @sid:   Global1/3:   SID, unknown filters and learning.
 * @vid:   Global1/6:   Valid bit.
 * @data:  Global1/7-9: Membership data and priority override.
 * @resvd: Reserved. In case we forgot something.
 *
 * The STU entry format varies between chipset generations. Peridot
 * and Amethyst packs the STU data into Global1/7-8. Older silicon
 * spreads the information across all three VTU data registers -
 * inheriting the layout of even older hardware that had no STU at
 * all. Since this is a low-level debug interface, copy all data
 * verbatim and defer parsing to the consumer.
 */
struct mv88e6xxx_devlink_stu_entry {
	u16 sid;
	u16 vid;
	u16 data[3];
	u16 resvd;
};

static int mv88e6xxx_region_stu_snapshot(struct devlink *dl,
					 const struct devlink_region_ops *ops,
					 struct netlink_ext_ack *extack,
					 u8 **data)
{
	struct mv88e6xxx_devlink_stu_entry *table, *entry;
	struct dsa_switch *ds = dsa_devlink_to_ds(dl);
	struct mv88e6xxx_chip *chip = ds->priv;
	struct mv88e6xxx_stu_entry stu;
	int err;

	table = kcalloc(mv88e6xxx_max_sid(chip) + 1,
			sizeof(struct mv88e6xxx_devlink_stu_entry),
			GFP_KERNEL);
	if (!table)
		return -ENOMEM;

	entry = table;
	stu.sid = mv88e6xxx_max_sid(chip);
	stu.valid = false;

	mv88e6xxx_reg_lock(chip);

	do {
		err = mv88e6xxx_g1_stu_getnext(chip, &stu);
		if (err)
			break;

		if (!stu.valid)
			break;

		err = err ? : mv88e6xxx_g1_read(chip, MV88E6352_G1_VTU_SID,
						&entry->sid);
		err = err ? : mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_VID,
						&entry->vid);
		err = err ? : mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA1,
						&entry->data[0]);
		err = err ? : mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA2,
						&entry->data[1]);
		err = err ? : mv88e6xxx_g1_read(chip, MV88E6XXX_G1_VTU_DATA3,
						&entry->data[2]);
		if (err)
			break;

		entry++;
	} while (stu.sid < mv88e6xxx_max_sid(chip));

	mv88e6xxx_reg_unlock(chip);

	if (err) {
		kfree(table);
		return err;
	}

	*data = (u8 *)table;
	return 0;
}

static int mv88e6xxx_region_pvt_snapshot(struct devlink *dl,
					 const struct devlink_region_ops *ops,
					 struct netlink_ext_ack *extack,
					 u8 **data)
{
	struct dsa_switch *ds = dsa_devlink_to_ds(dl);
	struct mv88e6xxx_chip *chip = ds->priv;
	int dev, port, err;
	u16 *pvt, *cur;

	pvt = kcalloc(MV88E6XXX_MAX_PVT_ENTRIES, sizeof(*pvt), GFP_KERNEL);
	if (!pvt)
		return -ENOMEM;

	mv88e6xxx_reg_lock(chip);

	cur = pvt;
	for (dev = 0; dev < MV88E6XXX_MAX_PVT_SWITCHES; dev++) {
		for (port = 0; port < MV88E6XXX_MAX_PVT_PORTS; port++) {
			err = mv88e6xxx_g2_pvt_read(chip, dev, port, cur);
			if (err)
				break;

			cur++;
		}
	}

	mv88e6xxx_reg_unlock(chip);

	if (err) {
		kfree(pvt);
		return err;
	}

	*data = (u8 *)pvt;
	return 0;
}

static int mv88e6xxx_region_port_snapshot(struct devlink_port *devlink_port,
					  const struct devlink_port_region_ops *ops,
					  struct netlink_ext_ack *extack,
					  u8 **data)
{
	struct dsa_switch *ds = dsa_devlink_port_to_ds(devlink_port);
	int port = dsa_devlink_port_to_port(devlink_port);
	struct mv88e6xxx_chip *chip = ds->priv;
	u16 *registers;
	int i, err;

	registers = kmalloc_array(32, sizeof(u16), GFP_KERNEL);
	if (!registers)
		return -ENOMEM;

	mv88e6xxx_reg_lock(chip);
	for (i = 0; i < 32; i++) {
		err = mv88e6xxx_port_read(chip, port, i, &registers[i]);
		if (err) {
			kfree(registers);
			goto out;
		}
	}
	*data = (u8 *)registers;
out:
	mv88e6xxx_reg_unlock(chip);

	return err;
}

static struct mv88e6xxx_region_priv mv88e6xxx_region_global1_priv = {
	.id = MV88E6XXX_REGION_GLOBAL1,
};

static struct devlink_region_ops mv88e6xxx_region_global1_ops = {
	.name = "global1",
	.snapshot = mv88e6xxx_region_global_snapshot,
	.destructor = kfree,
	.priv = &mv88e6xxx_region_global1_priv,
};

static struct mv88e6xxx_region_priv mv88e6xxx_region_global2_priv = {
	.id = MV88E6XXX_REGION_GLOBAL2,
};

static struct devlink_region_ops mv88e6xxx_region_global2_ops = {
	.name = "global2",
	.snapshot = mv88e6xxx_region_global_snapshot,
	.destructor = kfree,
	.priv = &mv88e6xxx_region_global2_priv,
};

static struct devlink_region_ops mv88e6xxx_region_atu_ops = {
	.name = "atu",
	.snapshot = mv88e6xxx_region_atu_snapshot,
	.destructor = kfree,
};

static struct devlink_region_ops mv88e6xxx_region_vtu_ops = {
	.name = "vtu",
	.snapshot = mv88e6xxx_region_vtu_snapshot,
	.destructor = kfree,
};

static struct devlink_region_ops mv88e6xxx_region_stu_ops = {
	.name = "stu",
	.snapshot = mv88e6xxx_region_stu_snapshot,
	.destructor = kfree,
};

static struct devlink_region_ops mv88e6xxx_region_pvt_ops = {
	.name = "pvt",
	.snapshot = mv88e6xxx_region_pvt_snapshot,
	.destructor = kfree,
};

static const struct devlink_port_region_ops mv88e6xxx_region_port_ops = {
	.name = "port",
	.snapshot = mv88e6xxx_region_port_snapshot,
	.destructor = kfree,
};

struct mv88e6xxx_region {
	struct devlink_region_ops *ops;
	u64 size;

	bool (*cond)(struct mv88e6xxx_chip *chip);
};

static struct mv88e6xxx_region mv88e6xxx_regions[] = {
	[MV88E6XXX_REGION_GLOBAL1] = {
		.ops = &mv88e6xxx_region_global1_ops,
		.size = 32 * sizeof(u16)
	},
	[MV88E6XXX_REGION_GLOBAL2] = {
		.ops = &mv88e6xxx_region_global2_ops,
		.size = 32 * sizeof(u16) },
	[MV88E6XXX_REGION_ATU] = {
		.ops = &mv88e6xxx_region_atu_ops
	  /* calculated at runtime */
	},
	[MV88E6XXX_REGION_VTU] = {
		.ops = &mv88e6xxx_region_vtu_ops
	  /* calculated at runtime */
	},
	[MV88E6XXX_REGION_STU] = {
		.ops = &mv88e6xxx_region_stu_ops,
		.cond = mv88e6xxx_has_stu,
	  /* calculated at runtime */
	},
	[MV88E6XXX_REGION_PVT] = {
		.ops = &mv88e6xxx_region_pvt_ops,
		.size = MV88E6XXX_MAX_PVT_ENTRIES * sizeof(u16),
		.cond = mv88e6xxx_has_pvt,
	},
};

void mv88e6xxx_teardown_devlink_regions_global(struct dsa_switch *ds)
{
	struct mv88e6xxx_chip *chip = ds->priv;
	int i;

	for (i = 0; i < ARRAY_SIZE(mv88e6xxx_regions); i++)
		dsa_devlink_region_destroy(chip->regions[i]);
}

void mv88e6xxx_teardown_devlink_regions_port(struct dsa_switch *ds, int port)
{
	struct mv88e6xxx_chip *chip = ds->priv;

	dsa_devlink_region_destroy(chip->ports[port].region);
}

int mv88e6xxx_setup_devlink_regions_port(struct dsa_switch *ds, int port)
{
	struct mv88e6xxx_chip *chip = ds->priv;
	struct devlink_region *region;

	region = dsa_devlink_port_region_create(ds,
						port,
						&mv88e6xxx_region_port_ops, 1,
						32 * sizeof(u16));
	if (IS_ERR(region))
		return PTR_ERR(region);

	chip->ports[port].region = region;

	return 0;
}

int mv88e6xxx_setup_devlink_regions_global(struct dsa_switch *ds)
{
	bool (*cond)(struct mv88e6xxx_chip *chip);
	struct mv88e6xxx_chip *chip = ds->priv;
	struct devlink_region_ops *ops;
	struct devlink_region *region;
	u64 size;
	int i, j;

	for (i = 0; i < ARRAY_SIZE(mv88e6xxx_regions); i++) {
		ops = mv88e6xxx_regions[i].ops;
		size = mv88e6xxx_regions[i].size;
		cond = mv88e6xxx_regions[i].cond;

		if (cond && !cond(chip))
			continue;

		switch (i) {
		case MV88E6XXX_REGION_ATU:
			size = mv88e6xxx_num_databases(chip) *
				sizeof(struct mv88e6xxx_devlink_atu_entry);
			break;
		case MV88E6XXX_REGION_VTU:
			size = (mv88e6xxx_max_vid(chip) + 1) *
				sizeof(struct mv88e6xxx_devlink_vtu_entry);
			break;
		case MV88E6XXX_REGION_STU:
			size = (mv88e6xxx_max_sid(chip) + 1) *
				sizeof(struct mv88e6xxx_devlink_stu_entry);
			break;
		}

		region = dsa_devlink_region_create(ds, ops, 1, size);
		if (IS_ERR(region))
			goto out;
		chip->regions[i] = region;
	}
	return 0;

out:
	for (j = 0; j < i; j++)
		dsa_devlink_region_destroy(chip->regions[j]);

	return PTR_ERR(region);
}

int mv88e6xxx_devlink_info_get(struct dsa_switch *ds,
			       struct devlink_info_req *req,
			       struct netlink_ext_ack *extack)
{
	struct mv88e6xxx_chip *chip = ds->priv;
	int err;

	err = devlink_info_driver_name_put(req, "mv88e6xxx");
	if (err)
		return err;

	return devlink_info_version_fixed_put(req,
					      DEVLINK_INFO_VERSION_GENERIC_ASIC_ID,
					      chip->info->name);
}
