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

#include "common.h"
#include "netlink.h"

struct linkinfo_req_info {
	struct ethnl_req_info		base;
};

struct linkinfo_reply_data {
	struct ethnl_reply_data		base;
	struct ethtool_link_ksettings	ksettings;
	struct ethtool_link_settings	*lsettings;
};

#define LINKINFO_REPDATA(__reply_base) \
	container_of(__reply_base, struct linkinfo_reply_data, base)

const struct nla_policy ethnl_linkinfo_get_policy[] = {
	[ETHTOOL_A_LINKINFO_HEADER]		=
		NLA_POLICY_NESTED(ethnl_header_policy),
};

static int linkinfo_prepare_data(const struct ethnl_req_info *req_base,
				 struct ethnl_reply_data *reply_base,
				 const struct genl_info *info)
{
	struct linkinfo_reply_data *data = LINKINFO_REPDATA(reply_base);
	struct net_device *dev = reply_base->dev;
	int ret;

	data->lsettings = &data->ksettings.base;

	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		return ret;
	ret = netif_get_link_ksettings(dev, &data->ksettings);
	if (ret < 0)
		GENL_SET_ERR_MSG(info, "failed to retrieve link settings");
	ethnl_ops_complete(dev);

	return ret;
}

static int linkinfo_reply_size(const struct ethnl_req_info *req_base,
			       const struct ethnl_reply_data *reply_base)
{
	return nla_total_size(sizeof(u8)) /* LINKINFO_PORT */
		+ nla_total_size(sizeof(u8)) /* LINKINFO_PHYADDR */
		+ nla_total_size(sizeof(u8)) /* LINKINFO_TP_MDIX */
		+ nla_total_size(sizeof(u8)) /* LINKINFO_TP_MDIX_CTRL */
		+ nla_total_size(sizeof(u8)) /* LINKINFO_TRANSCEIVER */
		+ 0;
}

static int linkinfo_fill_reply(struct sk_buff *skb,
			       const struct ethnl_req_info *req_base,
			       const struct ethnl_reply_data *reply_base)
{
	const struct linkinfo_reply_data *data = LINKINFO_REPDATA(reply_base);

	if (nla_put_u8(skb, ETHTOOL_A_LINKINFO_PORT, data->lsettings->port) ||
	    nla_put_u8(skb, ETHTOOL_A_LINKINFO_PHYADDR,
		       data->lsettings->phy_address) ||
	    nla_put_u8(skb, ETHTOOL_A_LINKINFO_TP_MDIX,
		       data->lsettings->eth_tp_mdix) ||
	    nla_put_u8(skb, ETHTOOL_A_LINKINFO_TP_MDIX_CTRL,
		       data->lsettings->eth_tp_mdix_ctrl) ||
	    nla_put_u8(skb, ETHTOOL_A_LINKINFO_TRANSCEIVER,
		       data->lsettings->transceiver))
		return -EMSGSIZE;

	return 0;
}

/* LINKINFO_SET */

const struct nla_policy ethnl_linkinfo_set_policy[] = {
	[ETHTOOL_A_LINKINFO_HEADER]		=
		NLA_POLICY_NESTED(ethnl_header_policy),
	[ETHTOOL_A_LINKINFO_PORT]		= { .type = NLA_U8 },
	[ETHTOOL_A_LINKINFO_PHYADDR]		= { .type = NLA_U8 },
	[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL]	= { .type = NLA_U8 },
};

static int
ethnl_set_linkinfo_validate(struct ethnl_req_info *req_info,
			    struct genl_info *info)
{
	const struct ethtool_ops *ops = req_info->dev->ethtool_ops;

	if (!ops->get_link_ksettings || !ops->set_link_ksettings)
		return -EOPNOTSUPP;
	return 1;
}

static int
ethnl_set_linkinfo(struct ethnl_req_info *req_info, struct genl_info *info)
{
	struct ethtool_link_ksettings ksettings = {};
	struct ethtool_link_settings *lsettings;
	struct net_device *dev = req_info->dev;
	struct nlattr **tb = info->attrs;
	bool mod = false;
	int ret;

	ret = netif_get_link_ksettings(dev, &ksettings);
	if (ret < 0) {
		GENL_SET_ERR_MSG(info, "failed to retrieve link settings");
		return ret;
	}
	lsettings = &ksettings.base;

	ethnl_update_u8(&lsettings->port, tb[ETHTOOL_A_LINKINFO_PORT], &mod);
	ethnl_update_u8(&lsettings->phy_address, tb[ETHTOOL_A_LINKINFO_PHYADDR],
			&mod);
	ethnl_update_u8(&lsettings->eth_tp_mdix_ctrl,
			tb[ETHTOOL_A_LINKINFO_TP_MDIX_CTRL], &mod);
	if (!mod)
		return 0;

	ret = dev->ethtool_ops->set_link_ksettings(dev, &ksettings);
	if (ret < 0) {
		GENL_SET_ERR_MSG(info, "link settings update failed");
		return ret;
	}

	return 1;
}

const struct ethnl_request_ops ethnl_linkinfo_request_ops = {
	.request_cmd		= ETHTOOL_MSG_LINKINFO_GET,
	.reply_cmd		= ETHTOOL_MSG_LINKINFO_GET_REPLY,
	.hdr_attr		= ETHTOOL_A_LINKINFO_HEADER,
	.req_info_size		= sizeof(struct linkinfo_req_info),
	.reply_data_size	= sizeof(struct linkinfo_reply_data),

	.prepare_data		= linkinfo_prepare_data,
	.reply_size		= linkinfo_reply_size,
	.fill_reply		= linkinfo_fill_reply,

	.set_validate		= ethnl_set_linkinfo_validate,
	.set			= ethnl_set_linkinfo,
	.set_ntf_cmd		= ETHTOOL_MSG_LINKINFO_NTF,
};
