/*
 * (C) Copyright 2001
 * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * This provides a bit-banged interface to the ethernet MII management
 * channel.
 */

#include <common.h>
#include <miiphy.h>
#include <phy.h>

#include <asm/types.h>
#include <linux/list.h>
#include <malloc.h>
#include <net.h>

/* local debug macro */
#undef MII_DEBUG

#undef debug
#ifdef MII_DEBUG
#define debug(fmt, args...)	printf(fmt, ##args)
#else
#define debug(fmt, args...)
#endif /* MII_DEBUG */

static struct list_head mii_devs;
static struct mii_dev *current_mii;

/*
 * Lookup the mii_dev struct by the registered device name.
 */
struct mii_dev *miiphy_get_dev_by_name(const char *devname)
{
	struct list_head *entry;
	struct mii_dev *dev;

	if (!devname) {
		printf("NULL device name!\n");
		return NULL;
	}

	list_for_each(entry, &mii_devs) {
		dev = list_entry(entry, struct mii_dev, link);
		if (strcmp(dev->name, devname) == 0)
			return dev;
	}

	return NULL;
}

/*****************************************************************************
 *
 * Initialize global data. Need to be called before any other miiphy routine.
 */
void miiphy_init(void)
{
	INIT_LIST_HEAD(&mii_devs);
	current_mii = NULL;
}

static int legacy_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
{
	unsigned short val;
	int ret;
	struct legacy_mii_dev *ldev = bus->priv;

	ret = ldev->read(bus->name, addr, reg, &val);

	return ret ? -1 : (int)val;
}

static int legacy_miiphy_write(struct mii_dev *bus, int addr, int devad,
				int reg, u16 val)
{
	struct legacy_mii_dev *ldev = bus->priv;

	return ldev->write(bus->name, addr, reg, val);
}

/*****************************************************************************
 *
 * Register read and write MII access routines for the device <name>.
 * This API is now deprecated. Please use mdio_alloc and mdio_register, instead.
 */
void miiphy_register(const char *name,
		      int (*read)(const char *devname, unsigned char addr,
				   unsigned char reg, unsigned short *value),
		      int (*write)(const char *devname, unsigned char addr,
				    unsigned char reg, unsigned short value))
{
	struct mii_dev *new_dev;
	struct legacy_mii_dev *ldev;

	BUG_ON(strlen(name) >= MDIO_NAME_LEN);

	/* check if we have unique name */
	new_dev = miiphy_get_dev_by_name(name);
	if (new_dev) {
		printf("miiphy_register: non unique device name '%s'\n", name);
		return;
	}

	/* allocate memory */
	new_dev = mdio_alloc();
	ldev = malloc(sizeof(*ldev));

	if (new_dev == NULL || ldev == NULL) {
		printf("miiphy_register: cannot allocate memory for '%s'\n",
			name);
		return;
	}

	/* initalize mii_dev struct fields */
	new_dev->read = legacy_miiphy_read;
	new_dev->write = legacy_miiphy_write;
	strncpy(new_dev->name, name, MDIO_NAME_LEN);
	new_dev->name[MDIO_NAME_LEN - 1] = 0;
	ldev->read = read;
	ldev->write = write;
	new_dev->priv = ldev;

	debug("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n",
	       new_dev->name, ldev->read, ldev->write);

	/* add it to the list */
	list_add_tail(&new_dev->link, &mii_devs);

	if (!current_mii)
		current_mii = new_dev;
}

struct mii_dev *mdio_alloc(void)
{
	struct mii_dev *bus;

	bus = malloc(sizeof(*bus));
	if (!bus)
		return bus;

	memset(bus, 0, sizeof(*bus));

	/* initalize mii_dev struct fields */
	INIT_LIST_HEAD(&bus->link);

	return bus;
}

int mdio_register(struct mii_dev *bus)
{
	if (!bus || !bus->name || !bus->read || !bus->write)
		return -1;

	/* check if we have unique name */
	if (miiphy_get_dev_by_name(bus->name)) {
		printf("mdio_register: non unique device name '%s'\n",
			bus->name);
		return -1;
	}

	/* add it to the list */
	list_add_tail(&bus->link, &mii_devs);

	if (!current_mii)
		current_mii = bus;

	return 0;
}

void mdio_list_devices(void)
{
	struct list_head *entry;

	list_for_each(entry, &mii_devs) {
		int i;
		struct mii_dev *bus = list_entry(entry, struct mii_dev, link);

		printf("%s:\n", bus->name);

		for (i = 0; i < PHY_MAX_ADDR; i++) {
			struct phy_device *phydev = bus->phymap[i];

			if (phydev) {
				printf("%d - %s", i, phydev->drv->name);

				if (phydev->dev)
					printf(" <--> %s\n", phydev->dev->name);
				else
					printf("\n");
			}
		}
	}
}

int miiphy_set_current_dev(const char *devname)
{
	struct mii_dev *dev;

	dev = miiphy_get_dev_by_name(devname);
	if (dev) {
		current_mii = dev;
		return 0;
	}

	printf("No such device: %s\n", devname);

	return 1;
}

struct mii_dev *mdio_get_current_dev(void)
{
	return current_mii;
}

struct phy_device *mdio_phydev_for_ethname(const char *ethname)
{
	struct list_head *entry;
	struct mii_dev *bus;

	list_for_each(entry, &mii_devs) {
		int i;
		bus = list_entry(entry, struct mii_dev, link);

		for (i = 0; i < PHY_MAX_ADDR; i++) {
			if (!bus->phymap[i] || !bus->phymap[i]->dev)
				continue;

			if (strcmp(bus->phymap[i]->dev->name, ethname) == 0)
				return bus->phymap[i];
		}
	}

	printf("%s is not a known ethernet\n", ethname);
	return NULL;
}

const char *miiphy_get_current_dev(void)
{
	if (current_mii)
		return current_mii->name;

	return NULL;
}

static struct mii_dev *miiphy_get_active_dev(const char *devname)
{
	/* If the current mii is the one we want, return it */
	if (current_mii)
		if (strcmp(current_mii->name, devname) == 0)
			return current_mii;

	/* Otherwise, set the active one to the one we want */
	if (miiphy_set_current_dev(devname))
		return NULL;
	else
		return current_mii;
}

/*****************************************************************************
 *
 * Read to variable <value> from the PHY attached to device <devname>,
 * use PHY address <addr> and register <reg>.
 *
 * This API is deprecated. Use phy_read on a phy_device found via phy_connect
 *
 * Returns:
 *   0 on success
 */
int miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
		 unsigned short *value)
{
	struct mii_dev *bus;
	int ret;

	bus = miiphy_get_active_dev(devname);
	if (!bus)
		return 1;

	ret = bus->read(bus, addr, MDIO_DEVAD_NONE, reg);
	if (ret < 0)
		return 1;

	*value = (unsigned short)ret;
	return 0;
}

/*****************************************************************************
 *
 * Write <value> to the PHY attached to device <devname>,
 * use PHY address <addr> and register <reg>.
 *
 * This API is deprecated. Use phy_write on a phy_device found by phy_connect
 *
 * Returns:
 *   0 on success
 */
int miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
		  unsigned short value)
{
	struct mii_dev *bus;

	bus = miiphy_get_active_dev(devname);
	if (bus)
		return bus->write(bus, addr, MDIO_DEVAD_NONE, reg, value);

	return 1;
}

/*****************************************************************************
 *
 * Print out list of registered MII capable devices.
 */
void miiphy_listdev(void)
{
	struct list_head *entry;
	struct mii_dev *dev;

	puts("MII devices: ");
	list_for_each(entry, &mii_devs) {
		dev = list_entry(entry, struct mii_dev, link);
		printf("'%s' ", dev->name);
	}
	puts("\n");

	if (current_mii)
		printf("Current device: '%s'\n", current_mii->name);
}

/*****************************************************************************
 *
 * Read the OUI, manufacture's model number, and revision number.
 *
 * OUI:     22 bits (unsigned int)
 * Model:    6 bits (unsigned char)
 * Revision: 4 bits (unsigned char)
 *
 * This API is deprecated.
 *
 * Returns:
 *   0 on success
 */
int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui,
		 unsigned char *model, unsigned char *rev)
{
	unsigned int reg = 0;
	unsigned short tmp;

	if (miiphy_read(devname, addr, MII_PHYSID2, &tmp) != 0) {
		debug("PHY ID register 2 read failed\n");
		return -1;
	}
	reg = tmp;

	debug("MII_PHYSID2 @ 0x%x = 0x%04x\n", addr, reg);

	if (reg == 0xFFFF) {
		/* No physical device present at this address */
		return -1;
	}

	if (miiphy_read(devname, addr, MII_PHYSID1, &tmp) != 0) {
		debug("PHY ID register 1 read failed\n");
		return -1;
	}
	reg |= tmp << 16;
	debug("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);

	*oui = (reg >> 10);
	*model = (unsigned char)((reg >> 4) & 0x0000003F);
	*rev = (unsigned char)(reg & 0x0000000F);
	return 0;
}

#ifndef CONFIG_PHYLIB
/*****************************************************************************
 *
 * Reset the PHY.
 *
 * This API is deprecated. Use PHYLIB.
 *
 * Returns:
 *   0 on success
 */
int miiphy_reset(const char *devname, unsigned char addr)
{
	unsigned short reg;
	int timeout = 500;

	if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
		debug("PHY status read failed\n");
		return -1;
	}
	if (miiphy_write(devname, addr, MII_BMCR, reg | BMCR_RESET) != 0) {
		debug("PHY reset failed\n");
		return -1;
	}
#ifdef CONFIG_PHY_RESET_DELAY
	udelay(CONFIG_PHY_RESET_DELAY);	/* Intel LXT971A needs this */
#endif
	/*
	 * Poll the control register for the reset bit to go to 0 (it is
	 * auto-clearing).  This should happen within 0.5 seconds per the
	 * IEEE spec.
	 */
	reg = 0x8000;
	while (((reg & 0x8000) != 0) && timeout--) {
		if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
			debug("PHY status read failed\n");
			return -1;
		}
		udelay(1000);
	}
	if ((reg & 0x8000) == 0) {
		return 0;
	} else {
		puts("PHY reset timed out\n");
		return -1;
	}
	return 0;
}
#endif /* !PHYLIB */

/*****************************************************************************
 *
 * Determine the ethernet speed (10/100/1000).  Return 10 on error.
 */
int miiphy_speed(const char *devname, unsigned char addr)
{
	u16 bmcr, anlpar;

#if defined(CONFIG_PHY_GIGE)
	u16 btsr;

	/*
	 * Check for 1000BASE-X.  If it is supported, then assume that the speed
	 * is 1000.
	 */
	if (miiphy_is_1000base_x(devname, addr))
		return _1000BASET;

	/*
	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
	 */
	/* Check for 1000BASE-T. */
	if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
		printf("PHY 1000BT status");
		goto miiphy_read_failed;
	}
	if (btsr != 0xFFFF &&
			(btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)))
		return _1000BASET;
#endif /* CONFIG_PHY_GIGE */

	/* Check Basic Management Control Register first. */
	if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
		printf("PHY speed");
		goto miiphy_read_failed;
	}
	/* Check if auto-negotiation is on. */
	if (bmcr & BMCR_ANENABLE) {
		/* Get auto-negotiation results. */
		if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
			printf("PHY AN speed");
			goto miiphy_read_failed;
		}
		return (anlpar & LPA_100) ? _100BASET : _10BASET;
	}
	/* Get speed from basic control settings. */
	return (bmcr & BMCR_SPEED100) ? _100BASET : _10BASET;

miiphy_read_failed:
	printf(" read failed, assuming 10BASE-T\n");
	return _10BASET;
}

/*****************************************************************************
 *
 * Determine full/half duplex.  Return half on error.
 */
int miiphy_duplex(const char *devname, unsigned char addr)
{
	u16 bmcr, anlpar;

#if defined(CONFIG_PHY_GIGE)
	u16 btsr;

	/* Check for 1000BASE-X. */
	if (miiphy_is_1000base_x(devname, addr)) {
		/* 1000BASE-X */
		if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
			printf("1000BASE-X PHY AN duplex");
			goto miiphy_read_failed;
		}
	}
	/*
	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
	 */
	/* Check for 1000BASE-T. */
	if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
		printf("PHY 1000BT status");
		goto miiphy_read_failed;
	}
	if (btsr != 0xFFFF) {
		if (btsr & PHY_1000BTSR_1000FD) {
			return FULL;
		} else if (btsr & PHY_1000BTSR_1000HD) {
			return HALF;
		}
	}
#endif /* CONFIG_PHY_GIGE */

	/* Check Basic Management Control Register first. */
	if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
		puts("PHY duplex");
		goto miiphy_read_failed;
	}
	/* Check if auto-negotiation is on. */
	if (bmcr & BMCR_ANENABLE) {
		/* Get auto-negotiation results. */
		if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
			puts("PHY AN duplex");
			goto miiphy_read_failed;
		}
		return (anlpar & (LPA_10FULL | LPA_100FULL)) ?
		    FULL : HALF;
	}
	/* Get speed from basic control settings. */
	return (bmcr & BMCR_FULLDPLX) ? FULL : HALF;

miiphy_read_failed:
	printf(" read failed, assuming half duplex\n");
	return HALF;
}

/*****************************************************************************
 *
 * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/
 * 1000BASE-T, or on error.
 */
int miiphy_is_1000base_x(const char *devname, unsigned char addr)
{
#if defined(CONFIG_PHY_GIGE)
	u16 exsr;

	if (miiphy_read(devname, addr, MII_ESTATUS, &exsr)) {
		printf("PHY extended status read failed, assuming no "
			"1000BASE-X\n");
		return 0;
	}
	return 0 != (exsr & (ESTATUS_1000XF | ESTATUS_1000XH));
#else
	return 0;
#endif
}

#ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
/*****************************************************************************
 *
 * Determine link status
 */
int miiphy_link(const char *devname, unsigned char addr)
{
	unsigned short reg;

	/* dummy read; needed to latch some phys */
	(void)miiphy_read(devname, addr, MII_BMSR, &reg);
	if (miiphy_read(devname, addr, MII_BMSR, &reg)) {
		puts("MII_BMSR read failed, assuming no link\n");
		return 0;
	}

	/* Determine if a link is active */
	if ((reg & BMSR_LSTATUS) != 0) {
		return 1;
	} else {
		return 0;
	}
}
#endif
