// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
 */

#include "devl_internal.h"

static const struct devlink_param devlink_param_generic[] = {
	{
		.id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
		.name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
		.type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
		.name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
		.type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
		.name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
		.type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
		.name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
		.type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
		.name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
		.type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
		.name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
		.type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
		.name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
		.type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
		.name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
		.type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
		.name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
		.type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
		.name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
		.type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET,
		.name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME,
		.type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
		.name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME,
		.type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
		.name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME,
		.type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
		.name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME,
		.type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP,
		.name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME,
		.type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
		.name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME,
		.type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
		.name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME,
		.type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_ENABLE_PHC,
		.name = DEVLINK_PARAM_GENERIC_ENABLE_PHC_NAME,
		.type = DEVLINK_PARAM_GENERIC_ENABLE_PHC_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_CLOCK_ID,
		.name = DEVLINK_PARAM_GENERIC_CLOCK_ID_NAME,
		.type = DEVLINK_PARAM_GENERIC_CLOCK_ID_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_TOTAL_VFS,
		.name = DEVLINK_PARAM_GENERIC_TOTAL_VFS_NAME,
		.type = DEVLINK_PARAM_GENERIC_TOTAL_VFS_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_NUM_DOORBELLS,
		.name = DEVLINK_PARAM_GENERIC_NUM_DOORBELLS_NAME,
		.type = DEVLINK_PARAM_GENERIC_NUM_DOORBELLS_TYPE,
	},
	{
		.id = DEVLINK_PARAM_GENERIC_ID_MAX_MAC_PER_VF,
		.name = DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_NAME,
		.type = DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_TYPE,
	},
};

static int devlink_param_generic_verify(const struct devlink_param *param)
{
	/* verify it match generic parameter by id and name */
	if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
		return -EINVAL;
	if (strcmp(param->name, devlink_param_generic[param->id].name))
		return -ENOENT;

	WARN_ON(param->type != devlink_param_generic[param->id].type);

	return 0;
}

static int devlink_param_driver_verify(const struct devlink_param *param)
{
	int i;

	if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
		return -EINVAL;
	/* verify no such name in generic params */
	for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
		if (!strcmp(param->name, devlink_param_generic[i].name))
			return -EEXIST;

	return 0;
}

static struct devlink_param_item *
devlink_param_find_by_name(struct xarray *params, const char *param_name)
{
	struct devlink_param_item *param_item;
	unsigned long param_id;

	xa_for_each(params, param_id, param_item) {
		if (!strcmp(param_item->param->name, param_name))
			return param_item;
	}
	return NULL;
}

static struct devlink_param_item *
devlink_param_find_by_id(struct xarray *params, u32 param_id)
{
	return xa_load(params, param_id);
}

static bool
devlink_param_cmode_is_supported(const struct devlink_param *param,
				 enum devlink_param_cmode cmode)
{
	return test_bit(cmode, &param->supported_cmodes);
}

static int devlink_param_get(struct devlink *devlink,
			     const struct devlink_param *param,
			     struct devlink_param_gset_ctx *ctx,
			     struct netlink_ext_ack *extack)
{
	if (!param->get)
		return -EOPNOTSUPP;
	return param->get(devlink, param->id, ctx, extack);
}

static int devlink_param_set(struct devlink *devlink,
			     const struct devlink_param *param,
			     struct devlink_param_gset_ctx *ctx,
			     struct netlink_ext_ack *extack)
{
	if (!param->set)
		return -EOPNOTSUPP;
	return param->set(devlink, param->id, ctx, extack);
}

static int devlink_param_get_default(struct devlink *devlink,
				     const struct devlink_param *param,
				     struct devlink_param_gset_ctx *ctx,
				     struct netlink_ext_ack *extack)
{
	if (!param->get_default)
		return -EOPNOTSUPP;

	return param->get_default(devlink, param->id, ctx, extack);
}

static int devlink_param_reset_default(struct devlink *devlink,
				       const struct devlink_param *param,
				       enum devlink_param_cmode cmode,
				       struct netlink_ext_ack *extack)
{
	if (!param->reset_default)
		return -EOPNOTSUPP;

	return param->reset_default(devlink, param->id, cmode, extack);
}

static int
devlink_nl_param_value_put(struct sk_buff *msg, enum devlink_param_type type,
			   int nla_type, union devlink_param_value val,
			   bool flag_as_u8)
{
	switch (type) {
	case DEVLINK_PARAM_TYPE_U8:
		if (nla_put_u8(msg, nla_type, val.vu8))
			return -EMSGSIZE;
		break;
	case DEVLINK_PARAM_TYPE_U16:
		if (nla_put_u16(msg, nla_type, val.vu16))
			return -EMSGSIZE;
		break;
	case DEVLINK_PARAM_TYPE_U32:
		if (nla_put_u32(msg, nla_type, val.vu32))
			return -EMSGSIZE;
		break;
	case DEVLINK_PARAM_TYPE_U64:
		if (devlink_nl_put_u64(msg, nla_type, val.vu64))
			return -EMSGSIZE;
		break;
	case DEVLINK_PARAM_TYPE_STRING:
		if (nla_put_string(msg, nla_type, val.vstr))
			return -EMSGSIZE;
		break;
	case DEVLINK_PARAM_TYPE_BOOL:
		/* default values of type bool are encoded with u8, so that
		 * false can be distinguished from not present
		 */
		if (flag_as_u8) {
			if (nla_put_u8(msg, nla_type, val.vbool))
				return -EMSGSIZE;
		} else {
			if (val.vbool && nla_put_flag(msg, nla_type))
				return -EMSGSIZE;
		}
		break;
	}
	return 0;
}

static int
devlink_nl_param_value_fill_one(struct sk_buff *msg,
				enum devlink_param_type type,
				enum devlink_param_cmode cmode,
				union devlink_param_value val,
				union devlink_param_value default_val,
				bool has_default)
{
	struct nlattr *param_value_attr;
	int err = -EMSGSIZE;

	param_value_attr = nla_nest_start_noflag(msg,
						 DEVLINK_ATTR_PARAM_VALUE);
	if (!param_value_attr)
		return -EMSGSIZE;

	if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
		goto value_nest_cancel;

	err = devlink_nl_param_value_put(msg, type,
					 DEVLINK_ATTR_PARAM_VALUE_DATA,
					 val, false);
	if (err)
		goto value_nest_cancel;

	if (has_default) {
		err = devlink_nl_param_value_put(msg, type,
						 DEVLINK_ATTR_PARAM_VALUE_DEFAULT,
						 default_val, true);
		if (err)
			goto value_nest_cancel;
	}

	nla_nest_end(msg, param_value_attr);
	return 0;

value_nest_cancel:
	nla_nest_cancel(msg, param_value_attr);
	return err;
}

static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
				 unsigned int port_index,
				 struct devlink_param_item *param_item,
				 enum devlink_command cmd,
				 u32 portid, u32 seq, int flags,
				 struct netlink_ext_ack *extack)
{
	union devlink_param_value default_value[DEVLINK_PARAM_CMODE_MAX + 1];
	union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
	bool default_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
	bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
	const struct devlink_param *param = param_item->param;
	struct devlink_param_gset_ctx ctx;
	struct nlattr *param_values_list;
	struct nlattr *param_attr;
	void *hdr;
	int err;
	int i;

	/* Get value from driver part to driverinit configuration mode */
	for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
		if (!devlink_param_cmode_is_supported(param, i))
			continue;
		if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
			if (param_item->driverinit_value_new_valid)
				param_value[i] = param_item->driverinit_value_new;
			else if (param_item->driverinit_value_valid)
				param_value[i] = param_item->driverinit_value;
			else
				return -EOPNOTSUPP;

			if (param_item->driverinit_value_valid) {
				default_value[i] = param_item->driverinit_default;
				default_value_set[i] = true;
			}
		} else {
			ctx.cmode = i;
			err = devlink_param_get(devlink, param, &ctx, extack);
			if (err)
				return err;
			param_value[i] = ctx.val;

			err = devlink_param_get_default(devlink, param, &ctx,
							extack);
			if (!err) {
				default_value[i] = ctx.val;
				default_value_set[i] = true;
			} else if (err != -EOPNOTSUPP) {
				return err;
			}
		}
		param_value_set[i] = true;
	}

	hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
	if (!hdr)
		return -EMSGSIZE;

	if (devlink_nl_put_handle(msg, devlink))
		goto genlmsg_cancel;

	if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
	    cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
	    cmd == DEVLINK_CMD_PORT_PARAM_DEL)
		if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
			goto genlmsg_cancel;

	param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
	if (!param_attr)
		goto genlmsg_cancel;
	if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
		goto param_nest_cancel;
	if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
		goto param_nest_cancel;
	if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, param->type))
		goto param_nest_cancel;

	param_values_list = nla_nest_start_noflag(msg,
						  DEVLINK_ATTR_PARAM_VALUES_LIST);
	if (!param_values_list)
		goto param_nest_cancel;

	for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
		if (!param_value_set[i])
			continue;
		err = devlink_nl_param_value_fill_one(msg, param->type,
						      i, param_value[i],
						      default_value[i],
						      default_value_set[i]);
		if (err)
			goto values_list_nest_cancel;
	}

	nla_nest_end(msg, param_values_list);
	nla_nest_end(msg, param_attr);
	genlmsg_end(msg, hdr);
	return 0;

values_list_nest_cancel:
	nla_nest_end(msg, param_values_list);
param_nest_cancel:
	nla_nest_cancel(msg, param_attr);
genlmsg_cancel:
	genlmsg_cancel(msg, hdr);
	return -EMSGSIZE;
}

static void devlink_param_notify(struct devlink *devlink,
				 unsigned int port_index,
				 struct devlink_param_item *param_item,
				 enum devlink_command cmd)
{
	struct sk_buff *msg;
	int err;

	WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
		cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
		cmd != DEVLINK_CMD_PORT_PARAM_DEL);

	/* devlink_notify_register() / devlink_notify_unregister()
	 * will replay the notifications if the params are added/removed
	 * outside of the lifetime of the instance.
	 */
	if (!devl_is_registered(devlink) || !devlink_nl_notify_need(devlink))
		return;

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		return;
	err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
				    0, 0, 0, NULL);
	if (err) {
		nlmsg_free(msg);
		return;
	}

	devlink_nl_notify_send(devlink, msg);
}

static void devlink_params_notify(struct devlink *devlink,
				  enum devlink_command cmd)
{
	struct devlink_param_item *param_item;
	unsigned long param_id;

	xa_for_each(&devlink->params, param_id, param_item)
		devlink_param_notify(devlink, 0, param_item, cmd);
}

void devlink_params_notify_register(struct devlink *devlink)
{
	devlink_params_notify(devlink, DEVLINK_CMD_PARAM_NEW);
}

void devlink_params_notify_unregister(struct devlink *devlink)
{
	devlink_params_notify(devlink, DEVLINK_CMD_PARAM_DEL);
}

static int devlink_nl_param_get_dump_one(struct sk_buff *msg,
					 struct devlink *devlink,
					 struct netlink_callback *cb,
					 int flags)
{
	struct devlink_nl_dump_state *state = devlink_dump_state(cb);
	struct devlink_param_item *param_item;
	unsigned long param_id;
	int err = 0;

	xa_for_each_start(&devlink->params, param_id, param_item, state->idx) {
		err = devlink_nl_param_fill(msg, devlink, 0, param_item,
					    DEVLINK_CMD_PARAM_GET,
					    NETLINK_CB(cb->skb).portid,
					    cb->nlh->nlmsg_seq, flags,
					    cb->extack);
		if (err == -EOPNOTSUPP) {
			err = 0;
		} else if (err) {
			state->idx = param_id;
			break;
		}
	}

	return err;
}

int devlink_nl_param_get_dumpit(struct sk_buff *skb,
				struct netlink_callback *cb)
{
	return devlink_nl_dumpit(skb, cb, devlink_nl_param_get_dump_one);
}

static int
devlink_param_type_get_from_info(struct genl_info *info,
				 enum devlink_param_type *param_type)
{
	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE))
		return -EINVAL;

	*param_type = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE]);

	return 0;
}

static int
devlink_param_value_get_from_info(const struct devlink_param *param,
				  struct genl_info *info,
				  union devlink_param_value *value)
{
	struct nlattr *param_data;
	int len;

	param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];

	if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
		return -EINVAL;

	switch (param->type) {
	case DEVLINK_PARAM_TYPE_U8:
		if (nla_len(param_data) != sizeof(u8))
			return -EINVAL;
		value->vu8 = nla_get_u8(param_data);
		break;
	case DEVLINK_PARAM_TYPE_U16:
		if (nla_len(param_data) != sizeof(u16))
			return -EINVAL;
		value->vu16 = nla_get_u16(param_data);
		break;
	case DEVLINK_PARAM_TYPE_U32:
		if (nla_len(param_data) != sizeof(u32))
			return -EINVAL;
		value->vu32 = nla_get_u32(param_data);
		break;
	case DEVLINK_PARAM_TYPE_U64:
		if (nla_len(param_data) != sizeof(u64))
			return -EINVAL;
		value->vu64 = nla_get_u64(param_data);
		break;
	case DEVLINK_PARAM_TYPE_STRING:
		len = strnlen(nla_data(param_data), nla_len(param_data));
		if (len == nla_len(param_data) ||
		    len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
			return -EINVAL;
		strcpy(value->vstr, nla_data(param_data));
		break;
	case DEVLINK_PARAM_TYPE_BOOL:
		if (param_data && nla_len(param_data))
			return -EINVAL;
		value->vbool = nla_get_flag(param_data);
		break;
	}
	return 0;
}

static struct devlink_param_item *
devlink_param_get_from_info(struct xarray *params, struct genl_info *info)
{
	char *param_name;

	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME))
		return NULL;

	param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
	return devlink_param_find_by_name(params, param_name);
}

int devlink_nl_param_get_doit(struct sk_buff *skb,
			      struct genl_info *info)
{
	struct devlink *devlink = info->user_ptr[0];
	struct devlink_param_item *param_item;
	struct sk_buff *msg;
	int err;

	param_item = devlink_param_get_from_info(&devlink->params, info);
	if (!param_item)
		return -EINVAL;

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	err = devlink_nl_param_fill(msg, devlink, 0, param_item,
				    DEVLINK_CMD_PARAM_GET, info->snd_portid,
				    info->snd_seq, 0, info->extack);
	if (err) {
		nlmsg_free(msg);
		return err;
	}

	return genlmsg_reply(msg, info);
}

static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
					   unsigned int port_index,
					   struct xarray *params,
					   struct genl_info *info,
					   enum devlink_command cmd)
{
	enum devlink_param_type param_type;
	struct devlink_param_gset_ctx ctx;
	enum devlink_param_cmode cmode;
	struct devlink_param_item *param_item;
	const struct devlink_param *param;
	union devlink_param_value value;
	bool reset_default;
	int err = 0;

	param_item = devlink_param_get_from_info(params, info);
	if (!param_item)
		return -EINVAL;
	param = param_item->param;
	err = devlink_param_type_get_from_info(info, &param_type);
	if (err)
		return err;
	if (param_type != param->type)
		return -EINVAL;

	reset_default = info->attrs[DEVLINK_ATTR_PARAM_RESET_DEFAULT];
	if (!reset_default) {
		err = devlink_param_value_get_from_info(param, info, &value);
		if (err)
			return err;
		if (param->validate) {
			err = param->validate(devlink, param->id, value,
					      info->extack);
			if (err)
				return err;
		}
	}

	if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE))
		return -EINVAL;
	cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
	if (!devlink_param_cmode_is_supported(param, cmode))
		return -EOPNOTSUPP;

	if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
		if (reset_default) {
			if (!param_item->driverinit_value_valid) {
				NL_SET_ERR_MSG(info->extack,
					       "Default value not available");
				return -EOPNOTSUPP;
			}
			value = param_item->driverinit_default;
		}

		param_item->driverinit_value_new = value;
		param_item->driverinit_value_new_valid = true;
	} else {
		if (!param->set)
			return -EOPNOTSUPP;
		ctx.val = value;
		ctx.cmode = cmode;
		if (reset_default)
			err = devlink_param_reset_default(devlink, param, cmode,
							  info->extack);
		else
			err = devlink_param_set(devlink, param, &ctx,
						info->extack);
		if (err)
			return err;
	}

	devlink_param_notify(devlink, port_index, param_item, cmd);
	return 0;
}

int devlink_nl_param_set_doit(struct sk_buff *skb, struct genl_info *info)
{
	struct devlink *devlink = info->user_ptr[0];

	return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->params,
					       info, DEVLINK_CMD_PARAM_NEW);
}

int devlink_nl_port_param_get_dumpit(struct sk_buff *msg,
				     struct netlink_callback *cb)
{
	NL_SET_ERR_MSG(cb->extack, "Port params are not supported");
	return msg->len;
}

int devlink_nl_port_param_get_doit(struct sk_buff *skb,
				   struct genl_info *info)
{
	NL_SET_ERR_MSG(info->extack, "Port params are not supported");
	return -EINVAL;
}

int devlink_nl_port_param_set_doit(struct sk_buff *skb,
				   struct genl_info *info)
{
	NL_SET_ERR_MSG(info->extack, "Port params are not supported");
	return -EINVAL;
}

static int devlink_param_verify(const struct devlink_param *param)
{
	if (!param || !param->name || !param->supported_cmodes)
		return -EINVAL;
	if (param->generic)
		return devlink_param_generic_verify(param);
	else
		return devlink_param_driver_verify(param);
}

static int devlink_param_register(struct devlink *devlink,
				  const struct devlink_param *param)
{
	struct devlink_param_item *param_item;
	int err;

	WARN_ON(devlink_param_verify(param));
	WARN_ON(devlink_param_find_by_name(&devlink->params, param->name));

	if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
		WARN_ON(param->get || param->set);
	else
		WARN_ON(!param->get || !param->set);

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

	param_item->param = param;

	err = xa_insert(&devlink->params, param->id, param_item, GFP_KERNEL);
	if (err)
		goto err_xa_insert;

	devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
	return 0;

err_xa_insert:
	kfree(param_item);
	return err;
}

static void devlink_param_unregister(struct devlink *devlink,
				     const struct devlink_param *param)
{
	struct devlink_param_item *param_item;

	param_item = devlink_param_find_by_id(&devlink->params, param->id);
	if (WARN_ON(!param_item))
		return;
	devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_DEL);
	xa_erase(&devlink->params, param->id);
	kfree(param_item);
}

/**
 *	devl_params_register - register configuration parameters
 *
 *	@devlink: devlink
 *	@params: configuration parameters array
 *	@params_count: number of parameters provided
 *
 *	Register the configuration parameters supported by the driver.
 */
int devl_params_register(struct devlink *devlink,
			 const struct devlink_param *params,
			 size_t params_count)
{
	const struct devlink_param *param = params;
	int i, err;

	lockdep_assert_held(&devlink->lock);

	for (i = 0; i < params_count; i++, param++) {
		err = devlink_param_register(devlink, param);
		if (err)
			goto rollback;
	}
	return 0;

rollback:
	if (!i)
		return err;

	for (param--; i > 0; i--, param--)
		devlink_param_unregister(devlink, param);
	return err;
}
EXPORT_SYMBOL_GPL(devl_params_register);

int devlink_params_register(struct devlink *devlink,
			    const struct devlink_param *params,
			    size_t params_count)
{
	int err;

	devl_lock(devlink);
	err = devl_params_register(devlink, params, params_count);
	devl_unlock(devlink);
	return err;
}
EXPORT_SYMBOL_GPL(devlink_params_register);

/**
 *	devl_params_unregister - unregister configuration parameters
 *	@devlink: devlink
 *	@params: configuration parameters to unregister
 *	@params_count: number of parameters provided
 */
void devl_params_unregister(struct devlink *devlink,
			    const struct devlink_param *params,
			    size_t params_count)
{
	const struct devlink_param *param = params;
	int i;

	lockdep_assert_held(&devlink->lock);

	for (i = 0; i < params_count; i++, param++)
		devlink_param_unregister(devlink, param);
}
EXPORT_SYMBOL_GPL(devl_params_unregister);

void devlink_params_unregister(struct devlink *devlink,
			       const struct devlink_param *params,
			       size_t params_count)
{
	devl_lock(devlink);
	devl_params_unregister(devlink, params, params_count);
	devl_unlock(devlink);
}
EXPORT_SYMBOL_GPL(devlink_params_unregister);

/**
 *	devl_param_driverinit_value_get - get configuration parameter
 *					  value for driver initializing
 *
 *	@devlink: devlink
 *	@param_id: parameter ID
 *	@val: pointer to store the value of parameter in driverinit
 *	      configuration mode
 *
 *	This function should be used by the driver to get driverinit
 *	configuration for initialization after reload command.
 *
 *	Note that lockless call of this function relies on the
 *	driver to maintain following basic sane behavior:
 *	1) Driver ensures a call to this function cannot race with
 *	   registering/unregistering the parameter with the same parameter ID.
 *	2) Driver ensures a call to this function cannot race with
 *	   devl_param_driverinit_value_set() call with the same parameter ID.
 *	3) Driver ensures a call to this function cannot race with
 *	   reload operation.
 *	If the driver is not able to comply, it has to take the devlink->lock
 *	while calling this.
 */
int devl_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
				    union devlink_param_value *val)
{
	struct devlink_param_item *param_item;

	if (WARN_ON(!devlink_reload_supported(devlink->ops)))
		return -EOPNOTSUPP;

	param_item = devlink_param_find_by_id(&devlink->params, param_id);
	if (!param_item)
		return -EINVAL;

	if (!param_item->driverinit_value_valid)
		return -EOPNOTSUPP;

	if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param,
						      DEVLINK_PARAM_CMODE_DRIVERINIT)))
		return -EOPNOTSUPP;

	*val = param_item->driverinit_value;

	return 0;
}
EXPORT_SYMBOL_GPL(devl_param_driverinit_value_get);

/**
 *	devl_param_driverinit_value_set - set value of configuration
 *					  parameter for driverinit
 *					  configuration mode
 *
 *	@devlink: devlink
 *	@param_id: parameter ID
 *	@init_val: value of parameter to set for driverinit configuration mode
 *
 *	This function should be used by the driver to set driverinit
 *	configuration mode default value.
 */
void devl_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
				     union devlink_param_value init_val)
{
	struct devlink_param_item *param_item;

	devl_assert_locked(devlink);

	param_item = devlink_param_find_by_id(&devlink->params, param_id);
	if (WARN_ON(!param_item))
		return;

	if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param,
						      DEVLINK_PARAM_CMODE_DRIVERINIT)))
		return;

	param_item->driverinit_value = init_val;
	param_item->driverinit_value_valid = true;
	param_item->driverinit_default = init_val;

	devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
}
EXPORT_SYMBOL_GPL(devl_param_driverinit_value_set);

void devlink_params_driverinit_load_new(struct devlink *devlink)
{
	struct devlink_param_item *param_item;
	unsigned long param_id;

	xa_for_each(&devlink->params, param_id, param_item) {
		if (!devlink_param_cmode_is_supported(param_item->param,
						      DEVLINK_PARAM_CMODE_DRIVERINIT) ||
		    !param_item->driverinit_value_new_valid)
			continue;
		param_item->driverinit_value = param_item->driverinit_value_new;
		param_item->driverinit_value_valid = true;
		param_item->driverinit_value_new_valid = false;
	}
}

/**
 *	devl_param_value_changed - notify devlink on a parameter's value
 *				   change. Should be called by the driver
 *				   right after the change.
 *
 *	@devlink: devlink
 *	@param_id: parameter ID
 *
 *	This function should be used by the driver to notify devlink on value
 *	change, excluding driverinit configuration mode.
 *	For driverinit configuration mode driver should use the function
 */
void devl_param_value_changed(struct devlink *devlink, u32 param_id)
{
	struct devlink_param_item *param_item;

	param_item = devlink_param_find_by_id(&devlink->params, param_id);
	WARN_ON(!param_item);

	devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
}
EXPORT_SYMBOL_GPL(devl_param_value_changed);
