// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2015-2017 Broadcom
 */

#include "bcm-phy-lib.h"
#include <linux/bitfield.h>
#include <linux/brcmphy.h>
#include <linux/export.h>
#include <linux/mdio.h>
#include <linux/module.h>
#include <linux/phy.h>
#include <linux/ethtool.h>
#include <linux/ethtool_netlink.h>

#define MII_BCM_CHANNEL_WIDTH     0x2000
#define BCM_CL45VEN_EEE_ADV       0x3c

int __bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val)
{
	int rc;

	rc = __phy_write(phydev, MII_BCM54XX_EXP_SEL, reg);
	if (rc < 0)
		return rc;

	return __phy_write(phydev, MII_BCM54XX_EXP_DATA, val);
}
EXPORT_SYMBOL_GPL(__bcm_phy_write_exp);

int bcm_phy_write_exp(struct phy_device *phydev, u16 reg, u16 val)
{
	int rc;

	phy_lock_mdio_bus(phydev);
	rc = __bcm_phy_write_exp(phydev, reg, val);
	phy_unlock_mdio_bus(phydev);

	return rc;
}
EXPORT_SYMBOL_GPL(bcm_phy_write_exp);

int __bcm_phy_read_exp(struct phy_device *phydev, u16 reg)
{
	int val;

	val = __phy_write(phydev, MII_BCM54XX_EXP_SEL, reg);
	if (val < 0)
		return val;

	val = __phy_read(phydev, MII_BCM54XX_EXP_DATA);

	/* Restore default value.  It's O.K. if this write fails. */
	__phy_write(phydev, MII_BCM54XX_EXP_SEL, 0);

	return val;
}
EXPORT_SYMBOL_GPL(__bcm_phy_read_exp);

int bcm_phy_read_exp(struct phy_device *phydev, u16 reg)
{
	int rc;

	phy_lock_mdio_bus(phydev);
	rc = __bcm_phy_read_exp(phydev, reg);
	phy_unlock_mdio_bus(phydev);

	return rc;
}
EXPORT_SYMBOL_GPL(bcm_phy_read_exp);

int __bcm_phy_modify_exp(struct phy_device *phydev, u16 reg, u16 mask, u16 set)
{
	int new, ret;

	ret = __phy_write(phydev, MII_BCM54XX_EXP_SEL, reg);
	if (ret < 0)
		return ret;

	ret = __phy_read(phydev, MII_BCM54XX_EXP_DATA);
	if (ret < 0)
		return ret;

	new = (ret & ~mask) | set;
	if (new == ret)
		return 0;

	return __phy_write(phydev, MII_BCM54XX_EXP_DATA, new);
}
EXPORT_SYMBOL_GPL(__bcm_phy_modify_exp);

int bcm_phy_modify_exp(struct phy_device *phydev, u16 reg, u16 mask, u16 set)
{
	int ret;

	phy_lock_mdio_bus(phydev);
	ret = __bcm_phy_modify_exp(phydev, reg, mask, set);
	phy_unlock_mdio_bus(phydev);

	return ret;
}
EXPORT_SYMBOL_GPL(bcm_phy_modify_exp);

int bcm54xx_auxctl_read(struct phy_device *phydev, u16 regnum)
{
	/* The register must be written to both the Shadow Register Select and
	 * the Shadow Read Register Selector
	 */
	phy_write(phydev, MII_BCM54XX_AUX_CTL, MII_BCM54XX_AUXCTL_SHDWSEL_MASK |
		  regnum << MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT);
	return phy_read(phydev, MII_BCM54XX_AUX_CTL);
}
EXPORT_SYMBOL_GPL(bcm54xx_auxctl_read);

int bcm54xx_auxctl_write(struct phy_device *phydev, u16 regnum, u16 val)
{
	return phy_write(phydev, MII_BCM54XX_AUX_CTL, regnum | val);
}
EXPORT_SYMBOL(bcm54xx_auxctl_write);

int bcm_phy_write_misc(struct phy_device *phydev,
		       u16 reg, u16 chl, u16 val)
{
	int rc;
	int tmp;

	rc = phy_write(phydev, MII_BCM54XX_AUX_CTL,
		       MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
	if (rc < 0)
		return rc;

	tmp = phy_read(phydev, MII_BCM54XX_AUX_CTL);
	tmp |= MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA;
	rc = phy_write(phydev, MII_BCM54XX_AUX_CTL, tmp);
	if (rc < 0)
		return rc;

	tmp = (chl * MII_BCM_CHANNEL_WIDTH) | reg;
	rc = bcm_phy_write_exp(phydev, tmp, val);

	return rc;
}
EXPORT_SYMBOL_GPL(bcm_phy_write_misc);

int bcm_phy_read_misc(struct phy_device *phydev,
		      u16 reg, u16 chl)
{
	int rc;
	int tmp;

	rc = phy_write(phydev, MII_BCM54XX_AUX_CTL,
		       MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
	if (rc < 0)
		return rc;

	tmp = phy_read(phydev, MII_BCM54XX_AUX_CTL);
	tmp |= MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA;
	rc = phy_write(phydev, MII_BCM54XX_AUX_CTL, tmp);
	if (rc < 0)
		return rc;

	tmp = (chl * MII_BCM_CHANNEL_WIDTH) | reg;
	rc = bcm_phy_read_exp(phydev, tmp);

	return rc;
}
EXPORT_SYMBOL_GPL(bcm_phy_read_misc);

int bcm_phy_ack_intr(struct phy_device *phydev)
{
	int reg;

	/* Clear pending interrupts.  */
	reg = phy_read(phydev, MII_BCM54XX_ISR);
	if (reg < 0)
		return reg;

	return 0;
}
EXPORT_SYMBOL_GPL(bcm_phy_ack_intr);

int bcm_phy_config_intr(struct phy_device *phydev)
{
	int reg, err;

	reg = phy_read(phydev, MII_BCM54XX_ECR);
	if (reg < 0)
		return reg;

	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
		err = bcm_phy_ack_intr(phydev);
		if (err)
			return err;

		reg &= ~MII_BCM54XX_ECR_IM;
		err = phy_write(phydev, MII_BCM54XX_ECR, reg);
	} else {
		reg |= MII_BCM54XX_ECR_IM;
		err = phy_write(phydev, MII_BCM54XX_ECR, reg);
		if (err)
			return err;

		err = bcm_phy_ack_intr(phydev);
	}
	return err;
}
EXPORT_SYMBOL_GPL(bcm_phy_config_intr);

irqreturn_t bcm_phy_handle_interrupt(struct phy_device *phydev)
{
	int irq_status, irq_mask;

	irq_status = phy_read(phydev, MII_BCM54XX_ISR);
	if (irq_status < 0) {
		phy_error(phydev);
		return IRQ_NONE;
	}

	/* If a bit from the Interrupt Mask register is set, the corresponding
	 * bit from the Interrupt Status register is masked. So read the IMR
	 * and then flip the bits to get the list of possible interrupt
	 * sources.
	 */
	irq_mask = phy_read(phydev, MII_BCM54XX_IMR);
	if (irq_mask < 0) {
		phy_error(phydev);
		return IRQ_NONE;
	}
	irq_mask = ~irq_mask;

	if (!(irq_status & irq_mask))
		return IRQ_NONE;

	phy_trigger_machine(phydev);

	return IRQ_HANDLED;
}
EXPORT_SYMBOL_GPL(bcm_phy_handle_interrupt);

int bcm_phy_read_shadow(struct phy_device *phydev, u16 shadow)
{
	phy_write(phydev, MII_BCM54XX_SHD, MII_BCM54XX_SHD_VAL(shadow));
	return MII_BCM54XX_SHD_DATA(phy_read(phydev, MII_BCM54XX_SHD));
}
EXPORT_SYMBOL_GPL(bcm_phy_read_shadow);

int bcm_phy_write_shadow(struct phy_device *phydev, u16 shadow,
			 u16 val)
{
	return phy_write(phydev, MII_BCM54XX_SHD,
			 MII_BCM54XX_SHD_WRITE |
			 MII_BCM54XX_SHD_VAL(shadow) |
			 MII_BCM54XX_SHD_DATA(val));
}
EXPORT_SYMBOL_GPL(bcm_phy_write_shadow);

int __bcm_phy_read_rdb(struct phy_device *phydev, u16 rdb)
{
	int val;

	val = __phy_write(phydev, MII_BCM54XX_RDB_ADDR, rdb);
	if (val < 0)
		return val;

	return __phy_read(phydev, MII_BCM54XX_RDB_DATA);
}
EXPORT_SYMBOL_GPL(__bcm_phy_read_rdb);

int bcm_phy_read_rdb(struct phy_device *phydev, u16 rdb)
{
	int ret;

	phy_lock_mdio_bus(phydev);
	ret = __bcm_phy_read_rdb(phydev, rdb);
	phy_unlock_mdio_bus(phydev);

	return ret;
}
EXPORT_SYMBOL_GPL(bcm_phy_read_rdb);

int __bcm_phy_write_rdb(struct phy_device *phydev, u16 rdb, u16 val)
{
	int ret;

	ret = __phy_write(phydev, MII_BCM54XX_RDB_ADDR, rdb);
	if (ret < 0)
		return ret;

	return __phy_write(phydev, MII_BCM54XX_RDB_DATA, val);
}
EXPORT_SYMBOL_GPL(__bcm_phy_write_rdb);

int bcm_phy_write_rdb(struct phy_device *phydev, u16 rdb, u16 val)
{
	int ret;

	phy_lock_mdio_bus(phydev);
	ret = __bcm_phy_write_rdb(phydev, rdb, val);
	phy_unlock_mdio_bus(phydev);

	return ret;
}
EXPORT_SYMBOL_GPL(bcm_phy_write_rdb);

int __bcm_phy_modify_rdb(struct phy_device *phydev, u16 rdb, u16 mask, u16 set)
{
	int new, ret;

	ret = __phy_write(phydev, MII_BCM54XX_RDB_ADDR, rdb);
	if (ret < 0)
		return ret;

	ret = __phy_read(phydev, MII_BCM54XX_RDB_DATA);
	if (ret < 0)
		return ret;

	new = (ret & ~mask) | set;
	if (new == ret)
		return 0;

	return __phy_write(phydev, MII_BCM54XX_RDB_DATA, new);
}
EXPORT_SYMBOL_GPL(__bcm_phy_modify_rdb);

int bcm_phy_modify_rdb(struct phy_device *phydev, u16 rdb, u16 mask, u16 set)
{
	int ret;

	phy_lock_mdio_bus(phydev);
	ret = __bcm_phy_modify_rdb(phydev, rdb, mask, set);
	phy_unlock_mdio_bus(phydev);

	return ret;
}
EXPORT_SYMBOL_GPL(bcm_phy_modify_rdb);

int bcm_phy_enable_apd(struct phy_device *phydev, bool dll_pwr_down)
{
	int val;

	if (dll_pwr_down) {
		val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3);
		if (val < 0)
			return val;

		val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
		bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR3, val);
	}

	val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_APD);
	if (val < 0)
		return val;

	/* Clear APD bits */
	val &= BCM_APD_CLR_MASK;

	if (phydev->autoneg == AUTONEG_ENABLE)
		val |= BCM54XX_SHD_APD_EN;
	else
		val |= BCM_NO_ANEG_APD_EN;

	/* Enable energy detect single link pulse for easy wakeup */
	val |= BCM_APD_SINGLELP_EN;

	/* Enable Auto Power-Down (APD) for the PHY */
	return bcm_phy_write_shadow(phydev, BCM54XX_SHD_APD, val);
}
EXPORT_SYMBOL_GPL(bcm_phy_enable_apd);

int bcm_phy_set_eee(struct phy_device *phydev, bool enable)
{
	int val, mask = 0;

	/* Enable EEE at PHY level */
	val = phy_read_mmd(phydev, MDIO_MMD_AN, BRCM_CL45VEN_EEE_CONTROL);
	if (val < 0)
		return val;

	if (enable)
		val |= LPI_FEATURE_EN | LPI_FEATURE_EN_DIG1000X;
	else
		val &= ~(LPI_FEATURE_EN | LPI_FEATURE_EN_DIG1000X);

	phy_write_mmd(phydev, MDIO_MMD_AN, BRCM_CL45VEN_EEE_CONTROL, (u32)val);

	/* Advertise EEE */
	val = phy_read_mmd(phydev, MDIO_MMD_AN, BCM_CL45VEN_EEE_ADV);
	if (val < 0)
		return val;

	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
			      phydev->supported))
		mask |= MDIO_EEE_1000T;
	if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
			      phydev->supported))
		mask |= MDIO_EEE_100TX;

	if (enable)
		val |= mask;
	else
		val &= ~mask;

	phy_write_mmd(phydev, MDIO_MMD_AN, BCM_CL45VEN_EEE_ADV, (u32)val);

	return 0;
}
EXPORT_SYMBOL_GPL(bcm_phy_set_eee);

int bcm_phy_downshift_get(struct phy_device *phydev, u8 *count)
{
	int val;

	val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
	if (val < 0)
		return val;

	/* Check if wirespeed is enabled or not */
	if (!(val & MII_BCM54XX_AUXCTL_SHDWSEL_MISC_WIRESPEED_EN)) {
		*count = DOWNSHIFT_DEV_DISABLE;
		return 0;
	}

	val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR2);
	if (val < 0)
		return val;

	/* Downgrade after one link attempt */
	if (val & BCM54XX_SHD_SCR2_WSPD_RTRY_DIS) {
		*count = 1;
	} else {
		/* Downgrade after configured retry count */
		val >>= BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_SHIFT;
		val &= BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_MASK;
		*count = val + BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_OFFSET;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(bcm_phy_downshift_get);

int bcm_phy_downshift_set(struct phy_device *phydev, u8 count)
{
	int val = 0, ret = 0;

	/* Range check the number given */
	if (count - BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_OFFSET >
	    BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_MASK &&
	    count != DOWNSHIFT_DEV_DEFAULT_COUNT) {
		return -ERANGE;
	}

	val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
	if (val < 0)
		return val;

	/* Se the write enable bit */
	val |= MII_BCM54XX_AUXCTL_MISC_WREN;

	if (count == DOWNSHIFT_DEV_DISABLE) {
		val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_WIRESPEED_EN;
		return bcm54xx_auxctl_write(phydev,
					    MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
					    val);
	} else {
		val |= MII_BCM54XX_AUXCTL_SHDWSEL_MISC_WIRESPEED_EN;
		ret = bcm54xx_auxctl_write(phydev,
					   MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
					   val);
		if (ret < 0)
			return ret;
	}

	val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR2);
	val &= ~(BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_MASK <<
		 BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_SHIFT |
		 BCM54XX_SHD_SCR2_WSPD_RTRY_DIS);

	switch (count) {
	case 1:
		val |= BCM54XX_SHD_SCR2_WSPD_RTRY_DIS;
		break;
	case DOWNSHIFT_DEV_DEFAULT_COUNT:
		val |= 1 << BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_SHIFT;
		break;
	default:
		val |= (count - BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_OFFSET) <<
			BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_SHIFT;
		break;
	}

	return bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR2, val);
}
EXPORT_SYMBOL_GPL(bcm_phy_downshift_set);

struct bcm_phy_hw_stat {
	const char *string;
	u8 reg;
	u8 shift;
	u8 bits;
};

/* Counters freeze at either 0xffff or 0xff, better than nothing */
static const struct bcm_phy_hw_stat bcm_phy_hw_stats[] = {
	{ "phy_receive_errors", MII_BRCM_CORE_BASE12, 0, 16 },
	{ "phy_serdes_ber_errors", MII_BRCM_CORE_BASE13, 8, 8 },
	{ "phy_false_carrier_sense_errors", MII_BRCM_CORE_BASE13, 0, 8 },
	{ "phy_local_rcvr_nok", MII_BRCM_CORE_BASE14, 8, 8 },
	{ "phy_remote_rcv_nok", MII_BRCM_CORE_BASE14, 0, 8 },
};

int bcm_phy_get_sset_count(struct phy_device *phydev)
{
	return ARRAY_SIZE(bcm_phy_hw_stats);
}
EXPORT_SYMBOL_GPL(bcm_phy_get_sset_count);

void bcm_phy_get_strings(struct phy_device *phydev, u8 *data)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(bcm_phy_hw_stats); i++)
		strlcpy(data + i * ETH_GSTRING_LEN,
			bcm_phy_hw_stats[i].string, ETH_GSTRING_LEN);
}
EXPORT_SYMBOL_GPL(bcm_phy_get_strings);

/* Caller is supposed to provide appropriate storage for the library code to
 * access the shadow copy
 */
static u64 bcm_phy_get_stat(struct phy_device *phydev, u64 *shadow,
			    unsigned int i)
{
	struct bcm_phy_hw_stat stat = bcm_phy_hw_stats[i];
	int val;
	u64 ret;

	val = phy_read(phydev, stat.reg);
	if (val < 0) {
		ret = U64_MAX;
	} else {
		val >>= stat.shift;
		val = val & ((1 << stat.bits) - 1);
		shadow[i] += val;
		ret = shadow[i];
	}

	return ret;
}

void bcm_phy_get_stats(struct phy_device *phydev, u64 *shadow,
		       struct ethtool_stats *stats, u64 *data)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(bcm_phy_hw_stats); i++)
		data[i] = bcm_phy_get_stat(phydev, shadow, i);
}
EXPORT_SYMBOL_GPL(bcm_phy_get_stats);

void bcm_phy_r_rc_cal_reset(struct phy_device *phydev)
{
	/* Reset R_CAL/RC_CAL Engine */
	bcm_phy_write_exp_sel(phydev, 0x00b0, 0x0010);

	/* Disable Reset R_AL/RC_CAL Engine */
	bcm_phy_write_exp_sel(phydev, 0x00b0, 0x0000);
}
EXPORT_SYMBOL_GPL(bcm_phy_r_rc_cal_reset);

int bcm_phy_28nm_a0b0_afe_config_init(struct phy_device *phydev)
{
	/* Increase VCO range to prevent unlocking problem of PLL at low
	 * temp
	 */
	bcm_phy_write_misc(phydev, PLL_PLLCTRL_1, 0x0048);

	/* Change Ki to 011 */
	bcm_phy_write_misc(phydev, PLL_PLLCTRL_2, 0x021b);

	/* Disable loading of TVCO buffer to bandgap, set bandgap trim
	 * to 111
	 */
	bcm_phy_write_misc(phydev, PLL_PLLCTRL_4, 0x0e20);

	/* Adjust bias current trim by -3 */
	bcm_phy_write_misc(phydev, DSP_TAP10, 0x690b);

	/* Switch to CORE_BASE1E */
	phy_write(phydev, MII_BRCM_CORE_BASE1E, 0xd);

	bcm_phy_r_rc_cal_reset(phydev);

	/* write AFE_RXCONFIG_0 */
	bcm_phy_write_misc(phydev, AFE_RXCONFIG_0, 0xeb19);

	/* write AFE_RXCONFIG_1 */
	bcm_phy_write_misc(phydev, AFE_RXCONFIG_1, 0x9a3f);

	/* write AFE_RX_LP_COUNTER */
	bcm_phy_write_misc(phydev, AFE_RX_LP_COUNTER, 0x7fc0);

	/* write AFE_HPF_TRIM_OTHERS */
	bcm_phy_write_misc(phydev, AFE_HPF_TRIM_OTHERS, 0x000b);

	/* write AFTE_TX_CONFIG */
	bcm_phy_write_misc(phydev, AFE_TX_CONFIG, 0x0800);

	return 0;
}
EXPORT_SYMBOL_GPL(bcm_phy_28nm_a0b0_afe_config_init);

int bcm_phy_enable_jumbo(struct phy_device *phydev)
{
	int ret;

	ret = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL);
	if (ret < 0)
		return ret;

	/* Enable extended length packet reception */
	ret = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
				   ret | MII_BCM54XX_AUXCTL_ACTL_EXT_PKT_LEN);
	if (ret < 0)
		return ret;

	/* Enable the elastic FIFO for raising the transmission limit from
	 * 4.5KB to 10KB, at the expense of an additional 16 ns in propagation
	 * latency.
	 */
	return phy_set_bits(phydev, MII_BCM54XX_ECR, MII_BCM54XX_ECR_FIFOE);
}
EXPORT_SYMBOL_GPL(bcm_phy_enable_jumbo);

static int __bcm_phy_enable_rdb_access(struct phy_device *phydev)
{
	return __bcm_phy_write_exp(phydev, BCM54XX_EXP_REG7E, 0);
}

static int __bcm_phy_enable_legacy_access(struct phy_device *phydev)
{
	return __bcm_phy_write_rdb(phydev, BCM54XX_RDB_REG0087,
				   BCM54XX_ACCESS_MODE_LEGACY_EN);
}

static int _bcm_phy_cable_test_start(struct phy_device *phydev, bool is_rdb)
{
	u16 mask, set;
	int ret;

	/* Auto-negotiation must be enabled for cable diagnostics to work, but
	 * don't advertise any capabilities.
	 */
	phy_write(phydev, MII_BMCR, BMCR_ANENABLE);
	phy_write(phydev, MII_ADVERTISE, ADVERTISE_CSMA);
	phy_write(phydev, MII_CTRL1000, 0);

	phy_lock_mdio_bus(phydev);
	if (is_rdb) {
		ret = __bcm_phy_enable_legacy_access(phydev);
		if (ret)
			goto out;
	}

	mask = BCM54XX_ECD_CTRL_CROSS_SHORT_DIS | BCM54XX_ECD_CTRL_UNIT_MASK;
	set = BCM54XX_ECD_CTRL_RUN | BCM54XX_ECD_CTRL_BREAK_LINK |
	      FIELD_PREP(BCM54XX_ECD_CTRL_UNIT_MASK,
			 BCM54XX_ECD_CTRL_UNIT_CM);

	ret = __bcm_phy_modify_exp(phydev, BCM54XX_EXP_ECD_CTRL, mask, set);

out:
	/* re-enable the RDB access even if there was an error */
	if (is_rdb)
		ret = __bcm_phy_enable_rdb_access(phydev) ? : ret;

	phy_unlock_mdio_bus(phydev);

	return ret;
}

static int bcm_phy_cable_test_report_trans(int result)
{
	switch (result) {
	case BCM54XX_ECD_FAULT_TYPE_OK:
		return ETHTOOL_A_CABLE_RESULT_CODE_OK;
	case BCM54XX_ECD_FAULT_TYPE_OPEN:
		return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
	case BCM54XX_ECD_FAULT_TYPE_SAME_SHORT:
		return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
	case BCM54XX_ECD_FAULT_TYPE_CROSS_SHORT:
		return ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT;
	case BCM54XX_ECD_FAULT_TYPE_INVALID:
	case BCM54XX_ECD_FAULT_TYPE_BUSY:
	default:
		return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
	}
}

static bool bcm_phy_distance_valid(int result)
{
	switch (result) {
	case BCM54XX_ECD_FAULT_TYPE_OPEN:
	case BCM54XX_ECD_FAULT_TYPE_SAME_SHORT:
	case BCM54XX_ECD_FAULT_TYPE_CROSS_SHORT:
		return true;
	}
	return false;
}

static int bcm_phy_report_length(struct phy_device *phydev, int pair)
{
	int val;

	val = __bcm_phy_read_exp(phydev,
				 BCM54XX_EXP_ECD_PAIR_A_LENGTH_RESULTS + pair);
	if (val < 0)
		return val;

	if (val == BCM54XX_ECD_LENGTH_RESULTS_INVALID)
		return 0;

	ethnl_cable_test_fault_length(phydev, pair, val);

	return 0;
}

static int _bcm_phy_cable_test_get_status(struct phy_device *phydev,
					  bool *finished, bool is_rdb)
{
	int pair_a, pair_b, pair_c, pair_d, ret;

	*finished = false;

	phy_lock_mdio_bus(phydev);

	if (is_rdb) {
		ret = __bcm_phy_enable_legacy_access(phydev);
		if (ret)
			goto out;
	}

	ret = __bcm_phy_read_exp(phydev, BCM54XX_EXP_ECD_CTRL);
	if (ret < 0)
		goto out;

	if (ret & BCM54XX_ECD_CTRL_IN_PROGRESS) {
		ret = 0;
		goto out;
	}

	ret = __bcm_phy_read_exp(phydev, BCM54XX_EXP_ECD_FAULT_TYPE);
	if (ret < 0)
		goto out;

	pair_a = FIELD_GET(BCM54XX_ECD_FAULT_TYPE_PAIR_A_MASK, ret);
	pair_b = FIELD_GET(BCM54XX_ECD_FAULT_TYPE_PAIR_B_MASK, ret);
	pair_c = FIELD_GET(BCM54XX_ECD_FAULT_TYPE_PAIR_C_MASK, ret);
	pair_d = FIELD_GET(BCM54XX_ECD_FAULT_TYPE_PAIR_D_MASK, ret);

	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A,
				bcm_phy_cable_test_report_trans(pair_a));
	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B,
				bcm_phy_cable_test_report_trans(pair_b));
	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_C,
				bcm_phy_cable_test_report_trans(pair_c));
	ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D,
				bcm_phy_cable_test_report_trans(pair_d));

	if (bcm_phy_distance_valid(pair_a))
		bcm_phy_report_length(phydev, 0);
	if (bcm_phy_distance_valid(pair_b))
		bcm_phy_report_length(phydev, 1);
	if (bcm_phy_distance_valid(pair_c))
		bcm_phy_report_length(phydev, 2);
	if (bcm_phy_distance_valid(pair_d))
		bcm_phy_report_length(phydev, 3);

	ret = 0;
	*finished = true;
out:
	/* re-enable the RDB access even if there was an error */
	if (is_rdb)
		ret = __bcm_phy_enable_rdb_access(phydev) ? : ret;

	phy_unlock_mdio_bus(phydev);

	return ret;
}

int bcm_phy_cable_test_start(struct phy_device *phydev)
{
	return _bcm_phy_cable_test_start(phydev, false);
}
EXPORT_SYMBOL_GPL(bcm_phy_cable_test_start);

int bcm_phy_cable_test_get_status(struct phy_device *phydev, bool *finished)
{
	return _bcm_phy_cable_test_get_status(phydev, finished, false);
}
EXPORT_SYMBOL_GPL(bcm_phy_cable_test_get_status);

/* We assume that all PHYs which support RDB access can be switched to legacy
 * mode. If, in the future, this is not true anymore, we have to re-implement
 * this with RDB access.
 */
int bcm_phy_cable_test_start_rdb(struct phy_device *phydev)
{
	return _bcm_phy_cable_test_start(phydev, true);
}
EXPORT_SYMBOL_GPL(bcm_phy_cable_test_start_rdb);

int bcm_phy_cable_test_get_status_rdb(struct phy_device *phydev,
				      bool *finished)
{
	return _bcm_phy_cable_test_get_status(phydev, finished, true);
}
EXPORT_SYMBOL_GPL(bcm_phy_cable_test_get_status_rdb);

MODULE_DESCRIPTION("Broadcom PHY Library");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Broadcom Corporation");
