// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2023 Bootlin
 *
 */
#include <linux/phy.h>
#include <linux/phy_link_topology.h>
#include <linux/sfp.h>
#include <net/netdev_lock.h>

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

struct phy_req_info {
	struct ethnl_req_info base;
};

struct phy_reply_data {
	struct ethnl_reply_data	base;
	u32 phyindex;
	char *drvname;
	char *name;
	unsigned int upstream_type;
	char *upstream_sfp_name;
	unsigned int upstream_index;
	char *downstream_sfp_name;
};

#define PHY_REPDATA(__reply_base) \
	container_of(__reply_base, struct phy_reply_data, base)

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

static int phy_reply_size(const struct ethnl_req_info *req_info,
			  const struct ethnl_reply_data *reply_data)
{
	struct phy_reply_data *rep_data = PHY_REPDATA(reply_data);
	size_t size = 0;

	/* ETHTOOL_A_PHY_INDEX */
	size += nla_total_size(sizeof(u32));

	/* ETHTOOL_A_DRVNAME */
	if (rep_data->drvname)
		size += nla_total_size(strlen(rep_data->drvname) + 1);

	/* ETHTOOL_A_NAME */
	size += nla_total_size(strlen(rep_data->name) + 1);

	/* ETHTOOL_A_PHY_UPSTREAM_TYPE */
	size += nla_total_size(sizeof(u32));

	/* ETHTOOL_A_PHY_UPSTREAM_SFP_NAME */
	if (rep_data->upstream_sfp_name)
		size += nla_total_size(strlen(rep_data->upstream_sfp_name) + 1);

	/* ETHTOOL_A_PHY_UPSTREAM_INDEX */
	if (rep_data->upstream_index)
		size += nla_total_size(sizeof(u32));

	/* ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME */
	if (rep_data->downstream_sfp_name)
		size += nla_total_size(strlen(rep_data->downstream_sfp_name) + 1);

	return size;
}

static int phy_prepare_data(const struct ethnl_req_info *req_info,
			    struct ethnl_reply_data *reply_data,
			    const struct genl_info *info)
{
	struct phy_link_topology *topo = reply_data->dev->link_topo;
	struct phy_reply_data *rep_data = PHY_REPDATA(reply_data);
	struct nlattr **tb = info->attrs;
	struct phy_device_node *pdn;
	struct phy_device *phydev;
	int ret;

	phydev = ethnl_req_get_phydev(req_info, tb, ETHTOOL_A_PHY_HEADER,
				      info->extack);
	if (IS_ERR_OR_NULL(phydev))
		return -EOPNOTSUPP;

	pdn = xa_load(&topo->phys, phydev->phyindex);
	if (!pdn)
		return -EOPNOTSUPP;

	rep_data->phyindex = phydev->phyindex;

	rep_data->name = kstrdup(dev_name(&phydev->mdio.dev), GFP_KERNEL);
	if (!rep_data->name)
		return -ENOMEM;

	if (phydev->drv) {
		rep_data->drvname = kstrdup(phydev->drv->name, GFP_KERNEL);
		if (!rep_data->drvname) {
			ret = -ENOMEM;
			goto err_free_name;
		}
	}

	rep_data->upstream_type = pdn->upstream_type;

	if (pdn->upstream_type == PHY_UPSTREAM_PHY) {
		struct phy_device *upstream = pdn->upstream.phydev;
		rep_data->upstream_index = upstream->phyindex;
	}

	if (pdn->parent_sfp_bus) {
		rep_data->upstream_sfp_name = kstrdup(sfp_get_name(pdn->parent_sfp_bus),
						      GFP_KERNEL);
		if (!rep_data->upstream_sfp_name) {
			ret = -ENOMEM;
			goto err_free_drvname;
		}
	}

	if (phydev->sfp_bus) {
		rep_data->downstream_sfp_name = kstrdup(sfp_get_name(phydev->sfp_bus),
							GFP_KERNEL);
		if (!rep_data->downstream_sfp_name) {
			ret = -ENOMEM;
			goto err_free_upstream_sfp;
		}
	}

	return 0;

err_free_upstream_sfp:
	kfree(rep_data->upstream_sfp_name);
err_free_drvname:
	kfree(rep_data->drvname);
err_free_name:
	kfree(rep_data->name);
	return ret;
}

static int phy_fill_reply(struct sk_buff *skb,
			  const struct ethnl_req_info *req_info,
			  const struct ethnl_reply_data *reply_data)
{
	struct phy_reply_data *rep_data = PHY_REPDATA(reply_data);

	if (nla_put_u32(skb, ETHTOOL_A_PHY_INDEX, rep_data->phyindex) ||
	    nla_put_string(skb, ETHTOOL_A_PHY_NAME, rep_data->name) ||
	    nla_put_u32(skb, ETHTOOL_A_PHY_UPSTREAM_TYPE, rep_data->upstream_type))
		return -EMSGSIZE;

	if (rep_data->drvname &&
	    nla_put_string(skb, ETHTOOL_A_PHY_DRVNAME, rep_data->drvname))
		return -EMSGSIZE;

	if (rep_data->upstream_index &&
	    nla_put_u32(skb, ETHTOOL_A_PHY_UPSTREAM_INDEX,
			rep_data->upstream_index))
		return -EMSGSIZE;

	if (rep_data->upstream_sfp_name &&
	    nla_put_string(skb, ETHTOOL_A_PHY_UPSTREAM_SFP_NAME,
			   rep_data->upstream_sfp_name))
		return -EMSGSIZE;

	if (rep_data->downstream_sfp_name &&
	    nla_put_string(skb, ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME,
			   rep_data->downstream_sfp_name))
		return -EMSGSIZE;

	return 0;
}

static void phy_cleanup_data(struct ethnl_reply_data *reply_data)
{
	struct phy_reply_data *rep_data = PHY_REPDATA(reply_data);

	kfree(rep_data->drvname);
	kfree(rep_data->name);
	kfree(rep_data->upstream_sfp_name);
	kfree(rep_data->downstream_sfp_name);
}

const struct ethnl_request_ops ethnl_phy_request_ops = {
	.request_cmd		= ETHTOOL_MSG_PHY_GET,
	.reply_cmd		= ETHTOOL_MSG_PHY_GET_REPLY,
	.hdr_attr		= ETHTOOL_A_PHY_HEADER,
	.req_info_size		= sizeof(struct phy_req_info),
	.reply_data_size	= sizeof(struct phy_reply_data),

	.prepare_data		= phy_prepare_data,
	.reply_size		= phy_reply_size,
	.fill_reply		= phy_fill_reply,
	.cleanup_data		= phy_cleanup_data,
};
