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

#include <linux/ethtool.h>
#include <linux/sfp.h>

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

struct eeprom_req_info {
	struct ethnl_req_info	base;
	u32			offset;
	u32			length;
	u8			page;
	u8			bank;
	u8			i2c_address;
};

struct eeprom_reply_data {
	struct ethnl_reply_data base;
	u32			length;
	u8			*data;
};

#define MODULE_EEPROM_REQINFO(__req_base) \
	container_of(__req_base, struct eeprom_req_info, base)

#define MODULE_EEPROM_REPDATA(__reply_base) \
	container_of(__reply_base, struct eeprom_reply_data, base)

static int fallback_set_params(struct eeprom_req_info *request,
			       struct ethtool_modinfo *modinfo,
			       struct ethtool_eeprom *eeprom)
{
	u32 offset = request->offset;
	u32 length = request->length;

	if (request->page)
		offset = request->page * ETH_MODULE_EEPROM_PAGE_LEN + offset;

	if (modinfo->type == ETH_MODULE_SFF_8472 &&
	    request->i2c_address == 0x51)
		offset += ETH_MODULE_EEPROM_PAGE_LEN * 2;

	if (offset >= modinfo->eeprom_len)
		return -EINVAL;

	if (length > modinfo->eeprom_len - offset)
		return -EINVAL;

	eeprom->cmd = ETHTOOL_GMODULEEEPROM;
	eeprom->len = length;
	eeprom->offset = offset;

	return 0;
}

static int eeprom_fallback(struct eeprom_req_info *request,
			   struct eeprom_reply_data *reply)
{
	struct net_device *dev = reply->base.dev;
	struct ethtool_modinfo modinfo = {0};
	struct ethtool_eeprom eeprom = {0};
	u8 *data;
	int err;

	modinfo.cmd = ETHTOOL_GMODULEINFO;
	err = ethtool_get_module_info_call(dev, &modinfo);
	if (err < 0)
		return err;

	err = fallback_set_params(request, &modinfo, &eeprom);
	if (err < 0)
		return err;

	data = kzalloc(eeprom.len, GFP_KERNEL);
	if (!data)
		return -ENOMEM;
	err = ethtool_get_module_eeprom_call(dev, &eeprom, data);
	if (err < 0)
		goto err_out;

	reply->data = data;
	reply->length = eeprom.len;

	return 0;

err_out:
	kfree(data);
	return err;
}

static int get_module_eeprom_by_page(struct net_device *dev,
				     struct ethtool_module_eeprom *page_data,
				     struct netlink_ext_ack *extack)
{
	const struct ethtool_ops *ops = dev->ethtool_ops;

	if (dev->ethtool->module_fw_flash_in_progress) {
		NL_SET_ERR_MSG(extack,
			       "Module firmware flashing is in progress");
		return -EBUSY;
	}

	if (dev->sfp_bus)
		return sfp_get_module_eeprom_by_page(dev->sfp_bus, page_data, extack);

	if (ops->get_module_eeprom_by_page)
		return ops->get_module_eeprom_by_page(dev, page_data, extack);

	return -EOPNOTSUPP;
}

static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
			       struct ethnl_reply_data *reply_base,
			       const struct genl_info *info)
{
	struct eeprom_reply_data *reply = MODULE_EEPROM_REPDATA(reply_base);
	struct eeprom_req_info *request = MODULE_EEPROM_REQINFO(req_base);
	struct ethtool_module_eeprom page_data = {0};
	struct net_device *dev = reply_base->dev;
	int ret;

	page_data.offset = request->offset;
	page_data.length = request->length;
	page_data.i2c_address = request->i2c_address;
	page_data.page = request->page;
	page_data.bank = request->bank;
	page_data.data = kmalloc(page_data.length, GFP_KERNEL);
	if (!page_data.data)
		return -ENOMEM;

	ret = ethnl_ops_begin(dev);
	if (ret)
		goto err_free;

	ret = get_module_eeprom_by_page(dev, &page_data, info->extack);
	if (ret < 0)
		goto err_ops;

	reply->length = ret;
	reply->data = page_data.data;

	ethnl_ops_complete(dev);
	return 0;

err_ops:
	if (ret == -EOPNOTSUPP)
		ret = eeprom_fallback(request, reply);
	ethnl_ops_complete(dev);
err_free:
	kfree(page_data.data);
	return ret;
}

static int eeprom_parse_request(struct ethnl_req_info *req_info,
				const struct genl_info *info,
				struct nlattr **tb,
				struct netlink_ext_ack *extack)
{
	struct eeprom_req_info *request = MODULE_EEPROM_REQINFO(req_info);

	if (GENL_REQ_ATTR_CHECK(info, ETHTOOL_A_MODULE_EEPROM_OFFSET) ||
	    GENL_REQ_ATTR_CHECK(info, ETHTOOL_A_MODULE_EEPROM_LENGTH) ||
	    GENL_REQ_ATTR_CHECK(info, ETHTOOL_A_MODULE_EEPROM_PAGE) ||
	    GENL_REQ_ATTR_CHECK(info, ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS))
		return -EINVAL;

	request->i2c_address = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS]);
	request->offset = nla_get_u32(tb[ETHTOOL_A_MODULE_EEPROM_OFFSET]);
	request->length = nla_get_u32(tb[ETHTOOL_A_MODULE_EEPROM_LENGTH]);

	/* The following set of conditions limit the API to only dump 1/2
	 * EEPROM page without crossing low page boundary located at offset 128.
	 * This means user may only request dumps of length limited to 128 from
	 * either low 128 bytes or high 128 bytes.
	 * For pages higher than 0 only high 128 bytes are accessible.
	 */
	request->page = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_PAGE]);
	if (request->page && request->offset < ETH_MODULE_EEPROM_PAGE_LEN) {
		NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_MODULE_EEPROM_PAGE],
				    "reading from lower half page is allowed for page 0 only");
		return -EINVAL;
	}

	if (request->offset < ETH_MODULE_EEPROM_PAGE_LEN &&
	    request->offset + request->length > ETH_MODULE_EEPROM_PAGE_LEN) {
		NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_MODULE_EEPROM_LENGTH],
				    "reading cross half page boundary is illegal");
		return -EINVAL;
	} else if (request->offset + request->length > ETH_MODULE_EEPROM_PAGE_LEN * 2) {
		NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_MODULE_EEPROM_LENGTH],
				    "reading cross page boundary is illegal");
		return -EINVAL;
	}

	if (tb[ETHTOOL_A_MODULE_EEPROM_BANK])
		request->bank = nla_get_u8(tb[ETHTOOL_A_MODULE_EEPROM_BANK]);

	return 0;
}

static int eeprom_reply_size(const struct ethnl_req_info *req_base,
			     const struct ethnl_reply_data *reply_base)
{
	const struct eeprom_req_info *request = MODULE_EEPROM_REQINFO(req_base);

	return nla_total_size(sizeof(u8) * request->length); /* _EEPROM_DATA */
}

static int eeprom_fill_reply(struct sk_buff *skb,
			     const struct ethnl_req_info *req_base,
			     const struct ethnl_reply_data *reply_base)
{
	struct eeprom_reply_data *reply = MODULE_EEPROM_REPDATA(reply_base);

	return nla_put(skb, ETHTOOL_A_MODULE_EEPROM_DATA, reply->length, reply->data);
}

static void eeprom_cleanup_data(struct ethnl_reply_data *reply_base)
{
	struct eeprom_reply_data *reply = MODULE_EEPROM_REPDATA(reply_base);

	kfree(reply->data);
}

const struct ethnl_request_ops ethnl_module_eeprom_request_ops = {
	.request_cmd		= ETHTOOL_MSG_MODULE_EEPROM_GET,
	.reply_cmd		= ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY,
	.hdr_attr		= ETHTOOL_A_MODULE_EEPROM_HEADER,
	.req_info_size		= sizeof(struct eeprom_req_info),
	.reply_data_size	= sizeof(struct eeprom_reply_data),

	.parse_request		= eeprom_parse_request,
	.prepare_data		= eeprom_prepare_data,
	.reply_size		= eeprom_reply_size,
	.fill_reply		= eeprom_fill_reply,
	.cleanup_data		= eeprom_cleanup_data,
};

const struct nla_policy ethnl_module_eeprom_get_policy[] = {
	[ETHTOOL_A_MODULE_EEPROM_HEADER]	= NLA_POLICY_NESTED(ethnl_header_policy),
	[ETHTOOL_A_MODULE_EEPROM_OFFSET]	=
		NLA_POLICY_MAX(NLA_U32, ETH_MODULE_EEPROM_PAGE_LEN * 2 - 1),
	[ETHTOOL_A_MODULE_EEPROM_LENGTH]	=
		NLA_POLICY_RANGE(NLA_U32, 1, ETH_MODULE_EEPROM_PAGE_LEN),
	[ETHTOOL_A_MODULE_EEPROM_PAGE]		= { .type = NLA_U8 },
	[ETHTOOL_A_MODULE_EEPROM_BANK]		= { .type = NLA_U8 },
	[ETHTOOL_A_MODULE_EEPROM_I2C_ADDRESS]	=
		NLA_POLICY_RANGE(NLA_U8, 0, ETH_MODULE_MAX_I2C_ADDRESS),
};

