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

#include "netlink.h"
#include "common.h"
#include <linux/phy.h>

struct linkstate_req_info {
	struct ethnl_req_info		base;
};

struct linkstate_reply_data {
	struct ethnl_reply_data			base;
	int					link;
	int					sqi;
	int					sqi_max;
	bool					link_ext_state_provided;
	struct ethtool_link_ext_state_info	ethtool_link_ext_state_info;
};

#define LINKSTATE_REPDATA(__reply_base) \
	container_of(__reply_base, struct linkstate_reply_data, base)

const struct nla_policy ethnl_linkstate_get_policy[] = {
	[ETHTOOL_A_LINKSTATE_HEADER]		=
		NLA_POLICY_NESTED(ethnl_header_policy),
};

static int linkstate_get_sqi(struct net_device *dev)
{
	struct phy_device *phydev = dev->phydev;
	int ret;

	if (!phydev)
		return -EOPNOTSUPP;

	mutex_lock(&phydev->lock);
	if (!phydev->drv || !phydev->drv->get_sqi)
		ret = -EOPNOTSUPP;
	else if (!phydev->link)
		ret = -ENETDOWN;
	else
		ret = phydev->drv->get_sqi(phydev);
	mutex_unlock(&phydev->lock);

	return ret;
}

static int linkstate_get_sqi_max(struct net_device *dev)
{
	struct phy_device *phydev = dev->phydev;
	int ret;

	if (!phydev)
		return -EOPNOTSUPP;

	mutex_lock(&phydev->lock);
	if (!phydev->drv || !phydev->drv->get_sqi_max)
		ret = -EOPNOTSUPP;
	else if (!phydev->link)
		ret = -ENETDOWN;
	else
		ret = phydev->drv->get_sqi_max(phydev);
	mutex_unlock(&phydev->lock);

	return ret;
};

static bool linkstate_sqi_critical_error(int sqi)
{
	return sqi < 0 && sqi != -EOPNOTSUPP && sqi != -ENETDOWN;
}

static bool linkstate_sqi_valid(struct linkstate_reply_data *data)
{
	return data->sqi >= 0 && data->sqi_max >= 0 &&
	       data->sqi <= data->sqi_max;
}

static int linkstate_get_link_ext_state(struct net_device *dev,
					struct linkstate_reply_data *data)
{
	int err;

	if (!dev->ethtool_ops->get_link_ext_state)
		return -EOPNOTSUPP;

	err = dev->ethtool_ops->get_link_ext_state(dev, &data->ethtool_link_ext_state_info);
	if (err)
		return err;

	data->link_ext_state_provided = true;

	return 0;
}

static int linkstate_prepare_data(const struct ethnl_req_info *req_base,
				  struct ethnl_reply_data *reply_base,
				  struct genl_info *info)
{
	struct linkstate_reply_data *data = LINKSTATE_REPDATA(reply_base);
	struct net_device *dev = reply_base->dev;
	int ret;

	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		return ret;
	data->link = __ethtool_get_link(dev);

	ret = linkstate_get_sqi(dev);
	if (linkstate_sqi_critical_error(ret))
		goto out;
	data->sqi = ret;

	ret = linkstate_get_sqi_max(dev);
	if (linkstate_sqi_critical_error(ret))
		goto out;
	data->sqi_max = ret;

	if (dev->flags & IFF_UP) {
		ret = linkstate_get_link_ext_state(dev, data);
		if (ret < 0 && ret != -EOPNOTSUPP && ret != -ENODATA)
			goto out;
	}

	ret = 0;
out:
	ethnl_ops_complete(dev);
	return ret;
}

static int linkstate_reply_size(const struct ethnl_req_info *req_base,
				const struct ethnl_reply_data *reply_base)
{
	struct linkstate_reply_data *data = LINKSTATE_REPDATA(reply_base);
	int len;

	len = nla_total_size(sizeof(u8)) /* LINKSTATE_LINK */
		+ 0;

	if (linkstate_sqi_valid(data)) {
		len += nla_total_size(sizeof(u32)); /* LINKSTATE_SQI */
		len += nla_total_size(sizeof(u32)); /* LINKSTATE_SQI_MAX */
	}

	if (data->link_ext_state_provided)
		len += nla_total_size(sizeof(u8)); /* LINKSTATE_EXT_STATE */

	if (data->ethtool_link_ext_state_info.__link_ext_substate)
		len += nla_total_size(sizeof(u8)); /* LINKSTATE_EXT_SUBSTATE */

	return len;
}

static int linkstate_fill_reply(struct sk_buff *skb,
				const struct ethnl_req_info *req_base,
				const struct ethnl_reply_data *reply_base)
{
	struct linkstate_reply_data *data = LINKSTATE_REPDATA(reply_base);

	if (data->link >= 0 &&
	    nla_put_u8(skb, ETHTOOL_A_LINKSTATE_LINK, !!data->link))
		return -EMSGSIZE;

	if (linkstate_sqi_valid(data)) {
		if (nla_put_u32(skb, ETHTOOL_A_LINKSTATE_SQI, data->sqi))
			return -EMSGSIZE;

		if (nla_put_u32(skb, ETHTOOL_A_LINKSTATE_SQI_MAX,
				data->sqi_max))
			return -EMSGSIZE;
	}

	if (data->link_ext_state_provided) {
		if (nla_put_u8(skb, ETHTOOL_A_LINKSTATE_EXT_STATE,
			       data->ethtool_link_ext_state_info.link_ext_state))
			return -EMSGSIZE;

		if (data->ethtool_link_ext_state_info.__link_ext_substate &&
		    nla_put_u8(skb, ETHTOOL_A_LINKSTATE_EXT_SUBSTATE,
			       data->ethtool_link_ext_state_info.__link_ext_substate))
			return -EMSGSIZE;
	}

	return 0;
}

const struct ethnl_request_ops ethnl_linkstate_request_ops = {
	.request_cmd		= ETHTOOL_MSG_LINKSTATE_GET,
	.reply_cmd		= ETHTOOL_MSG_LINKSTATE_GET_REPLY,
	.hdr_attr		= ETHTOOL_A_LINKSTATE_HEADER,
	.req_info_size		= sizeof(struct linkstate_req_info),
	.reply_data_size	= sizeof(struct linkstate_reply_data),

	.prepare_data		= linkstate_prepare_data,
	.reply_size		= linkstate_reply_size,
	.fill_reply		= linkstate_fill_reply,
};
