// SPDX-License-Identifier: GPL-2.0-or-later

#include <linux/ethtool.h>
#include <linux/linkmode.h>
#include <linux/phy.h>

#include "phy-caps.h"

static struct link_capabilities link_caps[__LINK_CAPA_MAX] __ro_after_init = {
	{ SPEED_10, DUPLEX_HALF, {0} }, /* LINK_CAPA_10HD */
	{ SPEED_10, DUPLEX_FULL, {0} }, /* LINK_CAPA_10FD */
	{ SPEED_100, DUPLEX_HALF, {0} }, /* LINK_CAPA_100HD */
	{ SPEED_100, DUPLEX_FULL, {0} }, /* LINK_CAPA_100FD */
	{ SPEED_1000, DUPLEX_HALF, {0} }, /* LINK_CAPA_1000HD */
	{ SPEED_1000, DUPLEX_FULL, {0} }, /* LINK_CAPA_1000FD */
	{ SPEED_2500, DUPLEX_FULL, {0} }, /* LINK_CAPA_2500FD */
	{ SPEED_5000, DUPLEX_FULL, {0} }, /* LINK_CAPA_5000FD */
	{ SPEED_10000, DUPLEX_FULL, {0} }, /* LINK_CAPA_10000FD */
	{ SPEED_20000, DUPLEX_FULL, {0} }, /* LINK_CAPA_20000FD */
	{ SPEED_25000, DUPLEX_FULL, {0} }, /* LINK_CAPA_25000FD */
	{ SPEED_40000, DUPLEX_FULL, {0} }, /* LINK_CAPA_40000FD */
	{ SPEED_50000, DUPLEX_FULL, {0} }, /* LINK_CAPA_50000FD */
	{ SPEED_56000, DUPLEX_FULL, {0} }, /* LINK_CAPA_56000FD */
	{ SPEED_80000, DUPLEX_FULL, {0} }, /* LINK_CAPA_80000FD */
	{ SPEED_100000, DUPLEX_FULL, {0} }, /* LINK_CAPA_100000FD */
	{ SPEED_200000, DUPLEX_FULL, {0} }, /* LINK_CAPA_200000FD */
	{ SPEED_400000, DUPLEX_FULL, {0} }, /* LINK_CAPA_400000FD */
	{ SPEED_800000, DUPLEX_FULL, {0} }, /* LINK_CAPA_800000FD */
	{ SPEED_1600000, DUPLEX_FULL, {0} }, /* LINK_CAPA_1600000FD */
};

static int speed_duplex_to_capa(int speed, unsigned int duplex)
{
	if (duplex == DUPLEX_UNKNOWN ||
	    (speed > SPEED_1000 && duplex != DUPLEX_FULL))
		return -EINVAL;

	switch (speed) {
	case SPEED_10: return duplex == DUPLEX_FULL ?
			      LINK_CAPA_10FD : LINK_CAPA_10HD;
	case SPEED_100: return duplex == DUPLEX_FULL ?
			       LINK_CAPA_100FD : LINK_CAPA_100HD;
	case SPEED_1000: return duplex == DUPLEX_FULL ?
				LINK_CAPA_1000FD : LINK_CAPA_1000HD;
	case SPEED_2500: return LINK_CAPA_2500FD;
	case SPEED_5000: return LINK_CAPA_5000FD;
	case SPEED_10000: return LINK_CAPA_10000FD;
	case SPEED_20000: return LINK_CAPA_20000FD;
	case SPEED_25000: return LINK_CAPA_25000FD;
	case SPEED_40000: return LINK_CAPA_40000FD;
	case SPEED_50000: return LINK_CAPA_50000FD;
	case SPEED_56000: return LINK_CAPA_56000FD;
	case SPEED_80000: return LINK_CAPA_80000FD;
	case SPEED_100000: return LINK_CAPA_100000FD;
	case SPEED_200000: return LINK_CAPA_200000FD;
	case SPEED_400000: return LINK_CAPA_400000FD;
	case SPEED_800000: return LINK_CAPA_800000FD;
	case SPEED_1600000: return LINK_CAPA_1600000FD;
	}

	return -EINVAL;
}

#define for_each_link_caps_asc_speed(cap) \
	for (cap = link_caps; cap < &link_caps[__LINK_CAPA_MAX]; cap++)

#define for_each_link_caps_desc_speed(cap) \
	for (cap = &link_caps[__LINK_CAPA_MAX - 1]; cap >= link_caps; cap--)

/**
 * phy_caps_init() - Initializes the link_caps array from the link_mode_params.
 *
 * Returns: 0 if phy caps init was successful, -EINVAL if we found an
 *	    unexpected linkmode setting that requires LINK_CAPS update.
 *
 */
int __init phy_caps_init(void)
{
	const struct link_mode_info *linkmode;
	int i, capa;

	/* Fill the caps array from net/ethtool/common.c */
	for (i = 0; i < __ETHTOOL_LINK_MODE_MASK_NBITS; i++) {
		linkmode = &link_mode_params[i];

		/* Sanity check the linkmodes array for number of pairs */
		if (linkmode->pairs < linkmode->min_pairs) {
			pr_err("Pairs count must not be under min_pairs for linkmode %d\n",
			       i);
			return -EINVAL;
		}

		capa = speed_duplex_to_capa(linkmode->speed, linkmode->duplex);

		if (capa < 0) {
			if (linkmode->speed != SPEED_UNKNOWN) {
				pr_err("Unknown speed %d, please update LINK_CAPS\n",
				       linkmode->speed);
				return -EINVAL;
			}
			continue;
		}

		__set_bit(i, link_caps[capa].linkmodes);
	}

	return 0;
}

/**
 * phy_caps_speeds() - Fill an array of supported SPEED_* values for given modes
 * @speeds: Output array to store the speeds list into
 * @size: Size of the output array
 * @linkmodes: Linkmodes to get the speeds from
 *
 * Fills the speeds array with all possible speeds that can be achieved with
 * the specified linkmodes.
 *
 * Returns: The number of speeds filled into the array. If the input array isn't
 *	    big enough to store all speeds, fill it as much as possible.
 */
size_t phy_caps_speeds(unsigned int *speeds, size_t size,
		       unsigned long *linkmodes)
{
	struct link_capabilities *lcap;
	size_t count = 0;

	for_each_link_caps_asc_speed(lcap) {
		if (linkmode_intersects(lcap->linkmodes, linkmodes) &&
		    (count == 0 || speeds[count - 1] != lcap->speed)) {
			speeds[count++] = lcap->speed;
			if (count >= size)
				break;
		}
	}

	return count;
}

/**
 * phy_caps_lookup_by_linkmode() - Lookup the fastest matching link_capabilities
 * @linkmodes: Linkmodes to match against
 *
 * Returns: The highest-speed link_capabilities that intersects the given
 *	    linkmodes. In case several DUPLEX_ options exist at that speed,
 *	    DUPLEX_FULL is matched first. NULL is returned if no match.
 */
const struct link_capabilities *
phy_caps_lookup_by_linkmode(const unsigned long *linkmodes)
{
	struct link_capabilities *lcap;

	for_each_link_caps_desc_speed(lcap)
		if (linkmode_intersects(lcap->linkmodes, linkmodes))
			return lcap;

	return NULL;
}

/**
 * phy_caps_lookup_by_linkmode_rev() - Lookup the slowest matching link_capabilities
 * @linkmodes: Linkmodes to match against
 * @fdx_only: Full duplex match only when set
 *
 * Returns: The lowest-speed link_capabilities that intersects the given
 *	    linkmodes. When set, fdx_only will ignore half-duplex matches.
 *	    NULL is returned if no match.
 */
const struct link_capabilities *
phy_caps_lookup_by_linkmode_rev(const unsigned long *linkmodes, bool fdx_only)
{
	struct link_capabilities *lcap;

	for_each_link_caps_asc_speed(lcap) {
		if (fdx_only && lcap->duplex != DUPLEX_FULL)
			continue;

		if (linkmode_intersects(lcap->linkmodes, linkmodes))
			return lcap;
	}

	return NULL;
}

/**
 * phy_caps_lookup() - Lookup capabilities by speed/duplex that matches a mask
 * @speed: Speed to match
 * @duplex: Duplex to match
 * @supported: Mask of linkmodes to match
 * @exact: Perform an exact match or not.
 *
 * Lookup a link_capabilities entry that intersect the supported linkmodes mask,
 * and that matches the passed speed and duplex.
 *
 * When @exact is set, an exact match is performed on speed and duplex, meaning
 * that if the linkmodes for the given speed and duplex intersect the supported
 * mask, this capability is returned, otherwise we don't have a match and return
 * NULL.
 *
 * When @exact is not set, we return either an exact match, or matching capabilities
 * at lower speed, or the lowest matching speed, or NULL.
 *
 * Non-exact matches will try to return an exact speed and duplex match, but may
 * return matching capabilities with same speed but a different duplex.
 *
 * Returns: a matched link_capabilities according to the above process, NULL
 *	    otherwise.
 */
const struct link_capabilities *
phy_caps_lookup(int speed, unsigned int duplex, const unsigned long *supported,
		bool exact)
{
	const struct link_capabilities *lcap, *match = NULL, *last = NULL;

	for_each_link_caps_desc_speed(lcap) {
		if (linkmode_intersects(lcap->linkmodes, supported)) {
			last = lcap;
			/* exact match on speed and duplex*/
			if (lcap->speed == speed && lcap->duplex == duplex) {
				return lcap;
			} else if (!exact) {
				if (!match && lcap->speed <= speed)
					match = lcap;

				if (lcap->speed < speed)
					break;
			}
		}
	}

	if (!match && !exact)
		match = last;

	return match;
}
EXPORT_SYMBOL_GPL(phy_caps_lookup);

/**
 * phy_caps_linkmode_max_speed() - Clamp a linkmodes set to a max speed
 * @max_speed: Speed limit for the linkmode set
 * @linkmodes: Linkmodes to limit
 */
void phy_caps_linkmode_max_speed(u32 max_speed, unsigned long *linkmodes)
{
	struct link_capabilities *lcap;

	for_each_link_caps_desc_speed(lcap)
		if (lcap->speed > max_speed)
			linkmode_andnot(linkmodes, linkmodes, lcap->linkmodes);
		else
			break;
}

/**
 * phy_caps_valid() - Validate a linkmodes set agains given speed and duplex
 * @speed: input speed to validate
 * @duplex: input duplex to validate. Passing DUPLEX_UNKNOWN is always not valid
 * @linkmodes: The linkmodes to validate
 *
 * Returns: True if at least one of the linkmodes in @linkmodes can function at
 *          the given speed and duplex, false otherwise.
 */
bool phy_caps_valid(int speed, int duplex, const unsigned long *linkmodes)
{
	int capa = speed_duplex_to_capa(speed, duplex);

	if (capa < 0)
		return false;

	return linkmode_intersects(link_caps[capa].linkmodes, linkmodes);
}

/**
 * phy_caps_linkmodes() - Convert a bitfield of capabilities into linkmodes
 * @caps: The list of caps, each bit corresponding to a LINK_CAPA value
 * @linkmodes: The set of linkmodes to fill. Must be previously initialized.
 */
void phy_caps_linkmodes(unsigned long caps, unsigned long *linkmodes)
{
	unsigned long capa;

	for_each_set_bit(capa, &caps, __LINK_CAPA_MAX)
		linkmode_or(linkmodes, linkmodes, link_caps[capa].linkmodes);
}
EXPORT_SYMBOL_GPL(phy_caps_linkmodes);

/**
 * phy_caps_from_interface() - Get the link capa from a given PHY interface
 * @interface: The PHY interface we want to get the possible Speed/Duplex from
 *
 * Returns: A bitmask of LINK_CAPA_xxx values that can be achieved with the
 *          provided interface.
 */
unsigned long phy_caps_from_interface(phy_interface_t interface)
{
	unsigned long link_caps = 0;

	switch (interface) {
	case PHY_INTERFACE_MODE_USXGMII:
		link_caps |= BIT(LINK_CAPA_10000FD) | BIT(LINK_CAPA_5000FD);
		fallthrough;

	case PHY_INTERFACE_MODE_10G_QXGMII:
		link_caps |= BIT(LINK_CAPA_2500FD);
		fallthrough;

	case PHY_INTERFACE_MODE_RGMII_TXID:
	case PHY_INTERFACE_MODE_RGMII_RXID:
	case PHY_INTERFACE_MODE_RGMII_ID:
	case PHY_INTERFACE_MODE_RGMII:
	case PHY_INTERFACE_MODE_PSGMII:
	case PHY_INTERFACE_MODE_QSGMII:
	case PHY_INTERFACE_MODE_QUSGMII:
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_GMII:
		link_caps |= BIT(LINK_CAPA_1000HD) | BIT(LINK_CAPA_1000FD);
		fallthrough;

	case PHY_INTERFACE_MODE_REVRMII:
	case PHY_INTERFACE_MODE_RMII:
	case PHY_INTERFACE_MODE_SMII:
	case PHY_INTERFACE_MODE_REVMII:
	case PHY_INTERFACE_MODE_MII:
		link_caps |= BIT(LINK_CAPA_10HD) | BIT(LINK_CAPA_10FD);
		fallthrough;

	case PHY_INTERFACE_MODE_100BASEX:
		link_caps |= BIT(LINK_CAPA_100HD) | BIT(LINK_CAPA_100FD);
		break;

	case PHY_INTERFACE_MODE_MIILITE:
		link_caps |= BIT(LINK_CAPA_10FD) | BIT(LINK_CAPA_100FD);
		break;

	case PHY_INTERFACE_MODE_TBI:
	case PHY_INTERFACE_MODE_MOCA:
	case PHY_INTERFACE_MODE_RTBI:
	case PHY_INTERFACE_MODE_1000BASEX:
		link_caps |= BIT(LINK_CAPA_1000HD);
		fallthrough;
	case PHY_INTERFACE_MODE_1000BASEKX:
	case PHY_INTERFACE_MODE_TRGMII:
		link_caps |= BIT(LINK_CAPA_1000FD);
		break;

	case PHY_INTERFACE_MODE_2500BASEX:
		link_caps |= BIT(LINK_CAPA_2500FD);
		break;

	case PHY_INTERFACE_MODE_5GBASER:
		link_caps |= BIT(LINK_CAPA_5000FD);
		break;

	case PHY_INTERFACE_MODE_XGMII:
	case PHY_INTERFACE_MODE_RXAUI:
	case PHY_INTERFACE_MODE_XAUI:
	case PHY_INTERFACE_MODE_10GBASER:
	case PHY_INTERFACE_MODE_10GKR:
		link_caps |= BIT(LINK_CAPA_10000FD);
		break;

	case PHY_INTERFACE_MODE_25GBASER:
		link_caps |= BIT(LINK_CAPA_25000FD);
		break;

	case PHY_INTERFACE_MODE_XLGMII:
		link_caps |= BIT(LINK_CAPA_40000FD);
		break;

	case PHY_INTERFACE_MODE_50GBASER:
	case PHY_INTERFACE_MODE_LAUI:
		link_caps |= BIT(LINK_CAPA_50000FD);
		break;

	case PHY_INTERFACE_MODE_100GBASEP:
		link_caps |= BIT(LINK_CAPA_100000FD);
		break;

	case PHY_INTERFACE_MODE_INTERNAL:
		link_caps |= LINK_CAPA_ALL;
		break;

	case PHY_INTERFACE_MODE_NA:
	case PHY_INTERFACE_MODE_MAX:
		break;
	}

	return link_caps;
}
EXPORT_SYMBOL_GPL(phy_caps_from_interface);

/**
 * phy_caps_medium_get_supported() - Returns linkmodes supported on a given medium
 * @supported: After this call, contains all possible linkmodes on a given medium,
 *	       and with the given number of pairs, or less.
 * @medium: The medium to get the support from
 * @pairs: The number of pairs used on the given medium. Only relevant for modes
 *	   that support this notion, such as BaseT. Pass 0 if not applicable.
 *
 * If no match exists, the supported field is left untouched.
 */
void phy_caps_medium_get_supported(unsigned long *supported,
				   enum ethtool_link_medium medium,
				   int pairs)
{
	int i;

	for (i = 0; i < __ETHTOOL_LINK_MODE_MASK_NBITS; i++) {
		/* Special bits such as Autoneg, Pause, Asym_pause, etc. are
		 * set and will be masked away by the port parent.
		 */
		if (link_mode_params[i].mediums == BIT(ETHTOOL_LINK_MEDIUM_NONE)) {
			linkmode_set_bit(i, supported);
			continue;
		}

		/* If this medium matches, and had a non-zero min-pairs */
		if (link_mode_params[i].mediums & BIT(medium) &&
		    (!link_mode_params[i].min_pairs ||
		      (link_mode_params[i].min_pairs <= pairs &&
		      link_mode_params[i].pairs >= pairs)))
			linkmode_set_bit(i, supported);
	}
}
EXPORT_SYMBOL_GPL(phy_caps_medium_get_supported);

/**
 * phy_caps_mediums_from_linkmodes() - Get all mediums from a linkmodes list
 * @linkmodes: A bitset of linkmodes to get the mediums from
 *
 * Returns: A bitset of ETHTOOL_MEDIUM_XXX values corresponding to all medium
 *	    types in the linkmodes list
 */
u32 phy_caps_mediums_from_linkmodes(unsigned long *linkmodes)
{
	const struct link_mode_info *linkmode;
	u32 mediums = 0;
	int i;

	for_each_set_bit(i, linkmodes, __ETHTOOL_LINK_MODE_MASK_NBITS) {
		linkmode = &link_mode_params[i];
		mediums |= linkmode->mediums;
	}

	return mediums;
}
EXPORT_SYMBOL_GPL(phy_caps_mediums_from_linkmodes);
