// SPDX-License-Identifier: GPL-2.0+
/* Framework to drive Ethernet ports
 *
 * Copyright (c) 2024 Maxime Chevallier <maxime.chevallier@bootlin.com>
 */

#include <linux/linkmode.h>
#include <linux/of.h>
#include <linux/phy_port.h>

#include "phy-caps.h"

/**
 * phy_port_alloc() - Allocate a new phy_port
 *
 * Returns: a newly allocated struct phy_port, or NULL.
 */
struct phy_port *phy_port_alloc(void)
{
	struct phy_port *port;

	port = kzalloc_obj(*port);
	if (!port)
		return NULL;

	linkmode_zero(port->supported);
	INIT_LIST_HEAD(&port->head);

	return port;
}
EXPORT_SYMBOL_GPL(phy_port_alloc);

/**
 * phy_port_destroy() - Free a struct phy_port
 * @port: The port to destroy
 */
void phy_port_destroy(struct phy_port *port)
{
	kfree(port);
}
EXPORT_SYMBOL_GPL(phy_port_destroy);

/**
 * phy_of_parse_port() - Create a phy_port from a firmware representation
 * @dn: device_node representation of the port, following the
 *	ethernet-connector.yaml binding
 *
 * Returns: a newly allocated and initialized phy_port pointer, or an ERR_PTR.
 */
struct phy_port *phy_of_parse_port(struct device_node *dn)
{
	struct fwnode_handle *fwnode = of_fwnode_handle(dn);
	enum ethtool_link_medium medium;
	struct phy_port *port;
	const char *med_str;
	u32 pairs = 0;
	int ret;

	ret = fwnode_property_read_string(fwnode, "media", &med_str);
	if (ret)
		return ERR_PTR(ret);

	medium = ethtool_str_to_medium(med_str);
	if (medium == ETHTOOL_LINK_MEDIUM_NONE)
		return ERR_PTR(-EINVAL);

	if (medium == ETHTOOL_LINK_MEDIUM_BASET) {
		ret = fwnode_property_read_u32(fwnode, "pairs", &pairs);
		if (ret)
			return ERR_PTR(ret);

		switch (pairs) {
		case 1: /* BaseT1 */
		case 2: /* 100BaseTX */
		case 4:
			break;
		default:
			pr_err("%u is not a valid number of pairs\n", pairs);
			return ERR_PTR(-EINVAL);
		}
	}

	if (pairs && medium != ETHTOOL_LINK_MEDIUM_BASET) {
		pr_err("pairs property is only compatible with BaseT medium\n");
		return ERR_PTR(-EINVAL);
	}

	port = phy_port_alloc();
	if (!port)
		return ERR_PTR(-ENOMEM);

	port->pairs = pairs;
	port->mediums = BIT(medium);

	return port;
}
EXPORT_SYMBOL_GPL(phy_of_parse_port);

/**
 * phy_port_update_supported() - Setup the port->supported field
 * @port: the port to update
 *
 * Once the port's medium list and number of pairs has been configured based
 * on firmware, straps and vendor-specific properties, this function may be
 * called to update the port's supported linkmodes list.
 *
 * Any mode that was manually set in the port's supported list remains set.
 */
void phy_port_update_supported(struct phy_port *port)
{
	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = {0};
	unsigned long mode;
	int i;

	/* If there's no pairs specified, we grab the default number of
	 * pairs as the max of the default pairs for each linkmode
	 */
	if (!port->pairs)
		for_each_set_bit(mode, port->supported,
				 __ETHTOOL_LINK_MODE_MASK_NBITS)
			port->pairs = max_t(int, port->pairs,
					    ethtool_linkmode_n_pairs(mode));

	for_each_set_bit(i, &port->mediums, __ETHTOOL_LINK_MEDIUM_LAST) {
		__ETHTOOL_DECLARE_LINK_MODE_MASK(med_supported) = {0};

		phy_caps_medium_get_supported(med_supported, i, port->pairs);
		linkmode_or(supported, supported, med_supported);
	}

	/* If port->supported is already populated, filter it out with the
	 * medium/pair support. Otherwise, let's just use this medium-based
	 * support as the port's supported list.
	 */
	if (linkmode_empty(port->supported))
		linkmode_copy(port->supported, supported);
	else
		linkmode_and(port->supported, supported, port->supported);

	/* Serdes ports supported through SFP may not have any medium set,
	 * as they will output PHY_INTERFACE_MODE_XXX modes. In that case, derive
	 * the supported list based on these interfaces
	 */
	if (port->is_mii && !port->mediums) {
		unsigned long interface, link_caps = 0;

		/* Get each interface's caps */
		for_each_set_bit(interface, port->interfaces,
				 PHY_INTERFACE_MODE_MAX)
			link_caps |= phy_caps_from_interface(interface);

		phy_caps_linkmodes(link_caps, port->supported);
	}
}
EXPORT_SYMBOL_GPL(phy_port_update_supported);

/**
 * phy_port_filter_supported() - Make sure that port->supported match port->mediums
 * @port: The port to filter
 *
 * After updating a port's mediums to a more restricted subset, this helper will
 * make sure that port->supported only contains linkmodes that are compatible
 * with port->mediums.
 */
static void phy_port_filter_supported(struct phy_port *port)
{
	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0 };
	int i;

	for_each_set_bit(i, &port->mediums, __ETHTOOL_LINK_MEDIUM_LAST)
		phy_caps_medium_get_supported(supported, i, port->pairs);

	linkmode_and(port->supported, port->supported, supported);
}

/**
 * phy_port_restrict_mediums - Mask away some of the port's supported mediums
 * @port: The port to act upon
 * @mediums: A mask of mediums to support on the port
 *
 * This helper allows removing some mediums from a port's list of supported
 * mediums, which occurs once we have enough information about the port to
 * know its nature.
 *
 * Returns: 0 if the change was donne correctly, a negative value otherwise.
 */
int phy_port_restrict_mediums(struct phy_port *port, unsigned long mediums)
{
	/* We forbid ending-up with a port with empty mediums */
	if (!(port->mediums & mediums))
		return -EINVAL;

	port->mediums &= mediums;

	phy_port_filter_supported(port);

	return 0;
}
EXPORT_SYMBOL_GPL(phy_port_restrict_mediums);

/**
 * phy_port_get_type() - get the PORT_* attribute for that port.
 * @port: The port we want the information from
 *
 * Returns: A PORT_XXX value.
 */
int phy_port_get_type(struct phy_port *port)
{
	if (port->mediums & BIT(ETHTOOL_LINK_MEDIUM_BASET))
		return PORT_TP;

	if (phy_port_is_fiber(port))
		return PORT_FIBRE;

	return PORT_OTHER;
}
EXPORT_SYMBOL_GPL(phy_port_get_type);
