// SPDX-License-Identifier: GPL-2.0-only

#include <linux/net_tstamp.h>
#include <linux/ptp_clock_kernel.h>

#include "netlink.h"
#include "common.h"
#include "bitset.h"
#include "../core/dev.h"
#include "ts.h"

struct tsconfig_req_info {
	struct ethnl_req_info base;
};

struct tsconfig_reply_data {
	struct ethnl_reply_data		base;
	struct hwtstamp_provider_desc	hwprov_desc;
	struct {
		u32 tx_type;
		u32 rx_filter;
		u32 flags;
	} hwtst_config;
};

#define TSCONFIG_REPDATA(__reply_base) \
	container_of(__reply_base, struct tsconfig_reply_data, base)

const struct nla_policy ethnl_tsconfig_get_policy[ETHTOOL_A_TSCONFIG_HEADER + 1] = {
	[ETHTOOL_A_TSCONFIG_HEADER]		=
		NLA_POLICY_NESTED(ethnl_header_policy),
};

static int tsconfig_prepare_data(const struct ethnl_req_info *req_base,
				 struct ethnl_reply_data *reply_base,
				 const struct genl_info *info)
{
	struct tsconfig_reply_data *data = TSCONFIG_REPDATA(reply_base);
	struct hwtstamp_provider *hwprov = NULL;
	struct net_device *dev = reply_base->dev;
	struct kernel_hwtstamp_config cfg = {};
	int ret;

	if (!dev->netdev_ops->ndo_hwtstamp_get)
		return -EOPNOTSUPP;

	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		return ret;

	ret = dev_get_hwtstamp_phylib(dev, &cfg);
	if (ret)
		goto out;

	data->hwtst_config.tx_type = BIT(cfg.tx_type);
	data->hwtst_config.rx_filter = BIT(cfg.rx_filter);
	data->hwtst_config.flags = BIT(cfg.flags);

	data->hwprov_desc.index = -1;
	hwprov = rtnl_dereference(dev->hwprov);
	if (hwprov) {
		data->hwprov_desc.index = hwprov->desc.index;
		data->hwprov_desc.qualifier = hwprov->desc.qualifier;
	} else {
		struct kernel_ethtool_ts_info ts_info = {};

		ts_info.phc_index = -1;
		ret = __ethtool_get_ts_info(dev, &ts_info);
		if (ret)
			goto out;

		if (ts_info.phc_index == -1)
			return -ENODEV;

		data->hwprov_desc.index = ts_info.phc_index;
		data->hwprov_desc.qualifier = ts_info.phc_qualifier;
	}

out:
	ethnl_ops_complete(dev);
	return ret;
}

static int tsconfig_reply_size(const struct ethnl_req_info *req_base,
			       const struct ethnl_reply_data *reply_base)
{
	const struct tsconfig_reply_data *data = TSCONFIG_REPDATA(reply_base);
	bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
	int len = 0;
	int ret;

	BUILD_BUG_ON(__HWTSTAMP_TX_CNT > 32);
	BUILD_BUG_ON(__HWTSTAMP_FILTER_CNT > 32);

	if (data->hwtst_config.flags)
		/* _TSCONFIG_HWTSTAMP_FLAGS */
		len += nla_total_size(sizeof(u32));

	if (data->hwtst_config.tx_type) {
		ret = ethnl_bitset32_size(&data->hwtst_config.tx_type,
					  NULL, __HWTSTAMP_TX_CNT,
					  ts_tx_type_names, compact);
		if (ret < 0)
			return ret;
		len += ret;	/* _TSCONFIG_TX_TYPES */
	}
	if (data->hwtst_config.rx_filter) {
		ret = ethnl_bitset32_size(&data->hwtst_config.rx_filter,
					  NULL, __HWTSTAMP_FILTER_CNT,
					  ts_rx_filter_names, compact);
		if (ret < 0)
			return ret;
		len += ret;	/* _TSCONFIG_RX_FILTERS */
	}

	if (data->hwprov_desc.index >= 0)
		/* _TSCONFIG_HWTSTAMP_PROVIDER */
		len += nla_total_size(0) +
		       2 * nla_total_size(sizeof(u32));

	return len;
}

static int tsconfig_fill_reply(struct sk_buff *skb,
			       const struct ethnl_req_info *req_base,
			       const struct ethnl_reply_data *reply_base)
{
	const struct tsconfig_reply_data *data = TSCONFIG_REPDATA(reply_base);
	bool compact = req_base->flags & ETHTOOL_FLAG_COMPACT_BITSETS;
	int ret;

	if (data->hwtst_config.flags) {
		ret = nla_put_u32(skb, ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS,
				  data->hwtst_config.flags);
		if (ret < 0)
			return ret;
	}

	if (data->hwtst_config.tx_type) {
		ret = ethnl_put_bitset32(skb, ETHTOOL_A_TSCONFIG_TX_TYPES,
					 &data->hwtst_config.tx_type, NULL,
					 __HWTSTAMP_TX_CNT,
					 ts_tx_type_names, compact);
		if (ret < 0)
			return ret;
	}

	if (data->hwtst_config.rx_filter) {
		ret = ethnl_put_bitset32(skb, ETHTOOL_A_TSCONFIG_RX_FILTERS,
					 &data->hwtst_config.rx_filter,
					 NULL, __HWTSTAMP_FILTER_CNT,
					 ts_rx_filter_names, compact);
		if (ret < 0)
			return ret;
	}

	if (data->hwprov_desc.index >= 0) {
		struct nlattr *nest;

		nest = nla_nest_start(skb, ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER);
		if (!nest)
			return -EMSGSIZE;

		if (nla_put_u32(skb, ETHTOOL_A_TS_HWTSTAMP_PROVIDER_INDEX,
				data->hwprov_desc.index) ||
		    nla_put_u32(skb,
				ETHTOOL_A_TS_HWTSTAMP_PROVIDER_QUALIFIER,
				data->hwprov_desc.qualifier)) {
			nla_nest_cancel(skb, nest);
			return -EMSGSIZE;
		}

		nla_nest_end(skb, nest);
	}
	return 0;
}

/* TSCONFIG_SET */
const struct nla_policy ethnl_tsconfig_set_policy[ETHTOOL_A_TSCONFIG_MAX + 1] = {
	[ETHTOOL_A_TSCONFIG_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
	[ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER] =
		NLA_POLICY_NESTED(ethnl_ts_hwtst_prov_policy),
	[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS] = { .type = NLA_U32 },
	[ETHTOOL_A_TSCONFIG_RX_FILTERS] = { .type = NLA_NESTED },
	[ETHTOOL_A_TSCONFIG_TX_TYPES] = { .type = NLA_NESTED },
};

static int tsconfig_send_reply(struct net_device *dev, struct genl_info *info)
{
	struct tsconfig_reply_data *reply_data;
	struct tsconfig_req_info *req_info;
	struct sk_buff *rskb;
	void *reply_payload;
	int reply_len = 0;
	int ret;

	req_info = kzalloc(sizeof(*req_info), GFP_KERNEL);
	if (!req_info)
		return -ENOMEM;
	reply_data = kmalloc(sizeof(*reply_data), GFP_KERNEL);
	if (!reply_data) {
		kfree(req_info);
		return -ENOMEM;
	}

	ASSERT_RTNL();
	reply_data->base.dev = dev;
	ret = tsconfig_prepare_data(&req_info->base, &reply_data->base, info);
	if (ret < 0)
		goto err_cleanup;

	ret = tsconfig_reply_size(&req_info->base, &reply_data->base);
	if (ret < 0)
		goto err_cleanup;

	reply_len = ret + ethnl_reply_header_size();
	rskb = ethnl_reply_init(reply_len, dev, ETHTOOL_MSG_TSCONFIG_SET_REPLY,
				ETHTOOL_A_TSCONFIG_HEADER, info, &reply_payload);
	if (!rskb)
		goto err_cleanup;

	ret = tsconfig_fill_reply(rskb, &req_info->base, &reply_data->base);
	if (ret < 0)
		goto err_cleanup;

	genlmsg_end(rskb, reply_payload);
	ret = genlmsg_reply(rskb, info);

err_cleanup:
	kfree(reply_data);
	kfree(req_info);
	return ret;
}

static int ethnl_set_tsconfig_validate(struct ethnl_req_info *req_base,
				       struct genl_info *info)
{
	const struct net_device_ops *ops = req_base->dev->netdev_ops;

	if (!ops->ndo_hwtstamp_set || !ops->ndo_hwtstamp_get)
		return -EOPNOTSUPP;

	return 1;
}

static struct hwtstamp_provider *
tsconfig_set_hwprov_from_desc(struct net_device *dev,
			      struct genl_info *info,
			      struct hwtstamp_provider_desc *hwprov_desc)
{
	struct kernel_ethtool_ts_info ts_info;
	struct hwtstamp_provider *hwprov;
	struct nlattr **tb = info->attrs;
	struct phy_device *phy = NULL;
	enum hwtstamp_source source;
	int ret;

	ret = ethtool_net_get_ts_info_by_phc(dev, &ts_info, hwprov_desc);
	if (!ret) {
		/* Found */
		source = HWTSTAMP_SOURCE_NETDEV;
	} else {
		phy = ethtool_phy_get_ts_info_by_phc(dev, &ts_info, hwprov_desc);
		if (IS_ERR(phy)) {
			if (PTR_ERR(phy) == -ENODEV)
				NL_SET_ERR_MSG_ATTR(info->extack,
						    tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER],
						    "phc not in this net device topology");
			return ERR_CAST(phy);
		}

		source = HWTSTAMP_SOURCE_PHYLIB;
	}

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

	hwprov->desc.index = hwprov_desc->index;
	hwprov->desc.qualifier = hwprov_desc->qualifier;
	hwprov->source = source;
	hwprov->phydev = phy;

	return hwprov;
}

static int ethnl_set_tsconfig(struct ethnl_req_info *req_base,
			      struct genl_info *info)
{
	struct kernel_hwtstamp_config hwtst_config = {0};
	bool hwprov_mod = false, config_mod = false;
	struct hwtstamp_provider *hwprov = NULL;
	struct net_device *dev = req_base->dev;
	struct nlattr **tb = info->attrs;
	int ret;

	BUILD_BUG_ON(__HWTSTAMP_TX_CNT >= 32);
	BUILD_BUG_ON(__HWTSTAMP_FILTER_CNT >= 32);

	if (!netif_device_present(dev))
		return -ENODEV;

	if (tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER]) {
		struct hwtstamp_provider_desc __hwprov_desc = {.index = -1};
		struct hwtstamp_provider *__hwprov;

		__hwprov = rtnl_dereference(dev->hwprov);
		if (__hwprov) {
			__hwprov_desc.index = __hwprov->desc.index;
			__hwprov_desc.qualifier = __hwprov->desc.qualifier;
		}

		ret = ts_parse_hwtst_provider(tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_PROVIDER],
					      &__hwprov_desc, info->extack,
					      &hwprov_mod);
		if (ret < 0)
			return ret;

		if (hwprov_mod) {
			hwprov = tsconfig_set_hwprov_from_desc(dev, info,
							       &__hwprov_desc);
			if (IS_ERR(hwprov))
				return PTR_ERR(hwprov);
		}
	}

	/* Get current hwtstamp config if we are not changing the
	 * hwtstamp source. It will be zeroed in the other case.
	 */
	if (!hwprov_mod) {
		ret = dev_get_hwtstamp_phylib(dev, &hwtst_config);
		if (ret < 0 && ret != -EOPNOTSUPP)
			goto err_free_hwprov;
	}

	/* Get the hwtstamp config from netlink */
	if (tb[ETHTOOL_A_TSCONFIG_TX_TYPES]) {
		u32 req_tx_type;

		req_tx_type = BIT(hwtst_config.tx_type);
		ret = ethnl_update_bitset32(&req_tx_type,
					    __HWTSTAMP_TX_CNT,
					    tb[ETHTOOL_A_TSCONFIG_TX_TYPES],
					    ts_tx_type_names, info->extack,
					    &config_mod);
		if (ret < 0)
			goto err_free_hwprov;

		/* Select only one tx type at a time */
		if (ffs(req_tx_type) != fls(req_tx_type)) {
			ret = -EINVAL;
			goto err_free_hwprov;
		}

		hwtst_config.tx_type = ffs(req_tx_type) - 1;
	}

	if (tb[ETHTOOL_A_TSCONFIG_RX_FILTERS]) {
		u32 req_rx_filter;

		req_rx_filter = BIT(hwtst_config.rx_filter);
		ret = ethnl_update_bitset32(&req_rx_filter,
					    __HWTSTAMP_FILTER_CNT,
					    tb[ETHTOOL_A_TSCONFIG_RX_FILTERS],
					    ts_rx_filter_names, info->extack,
					    &config_mod);
		if (ret < 0)
			goto err_free_hwprov;

		/* Select only one rx filter at a time */
		if (ffs(req_rx_filter) != fls(req_rx_filter)) {
			ret = -EINVAL;
			goto err_free_hwprov;
		}

		hwtst_config.rx_filter = ffs(req_rx_filter) - 1;
	}

	if (tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS]) {
		ethnl_update_u32(&hwtst_config.flags,
				 tb[ETHTOOL_A_TSCONFIG_HWTSTAMP_FLAGS],
				 &config_mod);
	}

	ret = net_hwtstamp_validate(&hwtst_config);
	if (ret)
		goto err_free_hwprov;

	if (hwprov_mod) {
		struct kernel_hwtstamp_config zero_config = {0};
		struct hwtstamp_provider *__hwprov;

		/* Disable current time stamping if we try to enable
		 * another one
		 */
		ret = dev_set_hwtstamp_phylib(dev, &zero_config, info->extack);
		if (ret < 0)
			goto err_free_hwprov;

		/* Change the selected hwtstamp source */
		__hwprov = rcu_replace_pointer_rtnl(dev->hwprov, hwprov);
		if (__hwprov)
			kfree_rcu(__hwprov, rcu_head);
	}

	if (config_mod) {
		ret = dev_set_hwtstamp_phylib(dev, &hwtst_config,
					      info->extack);
		if (ret < 0)
			return ret;
	}

	if (hwprov_mod || config_mod) {
		ret = tsconfig_send_reply(dev, info);
		if (ret && ret != -EOPNOTSUPP) {
			NL_SET_ERR_MSG(info->extack,
				       "error while reading the new configuration set");
			return ret;
		}
	}

	/* tsconfig has no notification */
	return 0;

err_free_hwprov:
	kfree(hwprov);

	return ret;
}

const struct ethnl_request_ops ethnl_tsconfig_request_ops = {
	.request_cmd		= ETHTOOL_MSG_TSCONFIG_GET,
	.reply_cmd		= ETHTOOL_MSG_TSCONFIG_GET_REPLY,
	.hdr_attr		= ETHTOOL_A_TSCONFIG_HEADER,
	.req_info_size		= sizeof(struct tsconfig_req_info),
	.reply_data_size	= sizeof(struct tsconfig_reply_data),

	.prepare_data		= tsconfig_prepare_data,
	.reply_size		= tsconfig_reply_size,
	.fill_reply		= tsconfig_fill_reply,

	.set_validate		= ethnl_set_tsconfig_validate,
	.set			= ethnl_set_tsconfig,
};
