// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2004-2008 Freescale Semiconductor, Inc.
 * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
 */

#include <common.h>
#include <config.h>
#include <net.h>
#include <netdev.h>

#ifdef CONFIG_MCF547x_8x
#include <asm/fsl_mcdmafec.h>
#else
#include <asm/fec.h>
#endif
#include <asm/immap.h>
#include <linux/mii.h>

DECLARE_GLOBAL_DATA_PTR;

#if defined(CONFIG_CMD_NET)
#undef MII_DEBUG
#undef ET_DEBUG

/*extern int fecpin_setclear(struct eth_device *dev, int setclear);*/

#if defined(CONFIG_SYS_DISCOVER_PHY) || defined(CONFIG_CMD_MII)
#include <miiphy.h>

/* Make MII read/write commands for the FEC. */
#define mk_mii_read(ADDR, REG)		(0x60020000 | ((ADDR << 23) | \
					 (REG & 0x1f) << 18))
#define mk_mii_write(ADDR, REG, VAL)	(0x50020000 | ((ADDR << 23) | \
					 (REG & 0x1f) << 18) | (VAL & 0xffff))

#ifndef CONFIG_SYS_UNSPEC_PHYID
#	define CONFIG_SYS_UNSPEC_PHYID		0
#endif
#ifndef CONFIG_SYS_UNSPEC_STRID
#	define CONFIG_SYS_UNSPEC_STRID		0
#endif

typedef struct phy_info_struct {
	u32 phyid;
	char *strid;
} phy_info_t;

phy_info_t phyinfo[] = {
	{0x0022561B, "AMD79C784VC"},	/* AMD 79C784VC */
	{0x00406322, "BCM5222"},	/* Broadcom 5222 */
	{0x02a80150, "Intel82555"},	/* Intel 82555 */
	{0x0016f870, "LSI80225"},	/* LSI 80225 */
	{0x0016f880, "LSI80225/B"},	/* LSI 80225/B */
	{0x78100000, "LXT970"},		/* LXT970 */
	{0x001378e0, "LXT971"},		/* LXT971 and 972 */
	{0x00221619, "KS8721BL"},	/* Micrel KS8721BL/SL */
	{0x00221512, "KSZ8041NL"},	/* Micrel KSZ8041NL */
	{0x20005CE1, "N83640"},		/* National 83640 */
	{0x20005C90, "N83848"},		/* National 83848 */
	{0x20005CA2, "N83849"},		/* National 83849 */
	{0x01814400, "QS6612"},		/* QS6612 */
#if defined(CONFIG_SYS_UNSPEC_PHYID) && defined(CONFIG_SYS_UNSPEC_STRID)
	{CONFIG_SYS_UNSPEC_PHYID, CONFIG_SYS_UNSPEC_STRID},
#endif
	{0, 0}
};

/*
 * mii_init -- Initialize the MII for MII command without ethernet
 * This function is a subset of eth_init
 */
void mii_reset(fec_info_t *info)
{
	volatile FEC_T *fecp = (FEC_T *) (info->miibase);
	int i;

	fecp->ecr = FEC_ECR_RESET;

	for (i = 0; (fecp->ecr & FEC_ECR_RESET) && (i < FEC_RESET_DELAY); ++i) {
		udelay(1);
	}
	if (i == FEC_RESET_DELAY)
		printf("FEC_RESET_DELAY timeout\n");
}

/* send command to phy using mii, wait for result */
uint mii_send(uint mii_cmd)
{
#ifdef CONFIG_DM_ETH
	struct udevice *dev;
#else
	struct eth_device *dev;
#endif
	fec_info_t *info;
	volatile FEC_T *ep;
	uint mii_reply;
	int j = 0;

	/* retrieve from register structure */
	dev = eth_get_dev();
	info = dev->priv;

	ep = (FEC_T *) info->miibase;

	ep->mmfr = mii_cmd;	/* command to phy */

	/* wait for mii complete */
	while (!(ep->eir & FEC_EIR_MII) && (j < info->to_loop)) {
		udelay(1);
		j++;
	}
	if (j >= info->to_loop) {
		printf("MII not complete\n");
		return -1;
	}

	mii_reply = ep->mmfr;	/* result from phy */
	ep->eir = FEC_EIR_MII;	/* clear MII complete */
#ifdef ET_DEBUG
	printf("%s[%d] %s: sent=0x%8.8x, reply=0x%8.8x\n",
	       __FILE__, __LINE__, __FUNCTION__, mii_cmd, mii_reply);
#endif

	return (mii_reply & 0xffff);	/* data read from phy */
}
#endif				/* CONFIG_SYS_DISCOVER_PHY || (CONFIG_MII) */

#if defined(CONFIG_SYS_DISCOVER_PHY)
int mii_discover_phy(fec_info_t *info)
{
#define MAX_PHY_PASSES 11
	int phyaddr, pass;
	uint phyno, phytype;
	int i, found = 0;

	if (info->phyname_init)
		return info->phy_addr;

	phyaddr = -1;		/* didn't find a PHY yet */
	for (pass = 1; pass <= MAX_PHY_PASSES && phyaddr < 0; ++pass) {
		if (pass > 1) {
			/* PHY may need more time to recover from reset.
			 * The LXT970 needs 50ms typical, no maximum is
			 * specified, so wait 10ms before try again.
			 * With 11 passes this gives it 100ms to wake up.
			 */
			udelay(10000);	/* wait 10ms */
		}

		for (phyno = 0; phyno < 32 && phyaddr < 0; ++phyno) {

			phytype = mii_send(mk_mii_read(phyno, MII_PHYSID1));
#ifdef ET_DEBUG
			printf("PHY type 0x%x pass %d\n", phytype, pass);
#endif
			if (phytype == 0xffff)
				continue;
			phyaddr = phyno;
			phytype <<= 16;
			phytype |=
			    mii_send(mk_mii_read(phyno, MII_PHYSID2));

#ifdef ET_DEBUG
			printf("PHY @ 0x%x pass %d\n", phyno, pass);
#endif

			for (i = 0; (i < ARRAY_SIZE(phyinfo))
				&& (phyinfo[i].phyid != 0); i++) {
				if (phyinfo[i].phyid == phytype) {
#ifdef ET_DEBUG
					printf("phyid %x - %s\n",
					       phyinfo[i].phyid,
					       phyinfo[i].strid);
#endif
					strcpy(info->phy_name, phyinfo[i].strid);
					info->phyname_init = 1;
					found = 1;
					break;
				}
			}

			if (!found) {
#ifdef ET_DEBUG
				printf("0x%08x\n", phytype);
#endif
				strcpy(info->phy_name, "unknown");
				info->phyname_init = 1;
				break;
			}
		}
	}

	if (phyaddr < 0)
		printf("No PHY device found.\n");

	return phyaddr;
}
#endif				/* CONFIG_SYS_DISCOVER_PHY */

void mii_init(void) __attribute__((weak,alias("__mii_init")));

void __mii_init(void)
{
#ifdef CONFIG_DM_ETH
	struct udevice *dev;
#else
	struct eth_device *dev;
#endif
	fec_info_t *info;
	volatile FEC_T *fecp;
	int miispd = 0, i = 0;
	u16 status = 0;
	u16 linkgood = 0;

	/* retrieve from register structure */
	dev = eth_get_dev();
	info = dev->priv;

	fecp = (FEC_T *) info->miibase;

	fecpin_setclear(info, 1);

	mii_reset(info);

	/* We use strictly polling mode only */
	fecp->eimr = 0;

	/* Clear any pending interrupt */
	fecp->eir = 0xffffffff;

	/* Set MII speed */
	miispd = (gd->bus_clk / 1000000) / 5;
	fecp->mscr = miispd << 1;

#ifdef CONFIG_SYS_DISCOVER_PHY
	info->phy_addr = mii_discover_phy(info);
#endif
	if (info->phy_addr == -1)
		return;

	while (i < info->to_loop) {
		status = 0;
		i++;
		/* Read PHY control register */
		miiphy_read(dev->name, info->phy_addr, MII_BMCR, &status);

		/* If phy set to autonegotiate, wait for autonegotiation done,
		 * if phy is not autonegotiating, just wait for link up.
		 */
		if ((status & BMCR_ANENABLE) == BMCR_ANENABLE) {
			linkgood = (BMSR_ANEGCOMPLETE | BMSR_LSTATUS);
		} else {
			linkgood = BMSR_LSTATUS;
		}
		/* Read PHY status register */
		miiphy_read(dev->name, info->phy_addr, MII_BMSR, &status);
		if ((status & linkgood) == linkgood)
			break;

		udelay(1);
	}
	if (i >= info->to_loop)
		printf("Link UP timeout\n");

	/* adapt to the duplex and speed settings of the phy */
	info->dup_spd = miiphy_duplex(dev->name, info->phy_addr) << 16;
	info->dup_spd |= miiphy_speed(dev->name, info->phy_addr);
}

/*
 * Read and write a MII PHY register, routines used by MII Utilities
 *
 * FIXME: These routines are expected to return 0 on success, but mii_send
 *	  does _not_ return an error code. Maybe 0xFFFF means error, i.e.
 *	  no PHY connected...
 *	  For now always return 0.
 * FIXME: These routines only work after calling eth_init() at least once!
 *	  Otherwise they hang in mii_send() !!! Sorry!
 */

int mcffec_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
{
	short rdreg;		/* register working value */

#ifdef MII_DEBUG
	printf("miiphy_read(0x%x) @ 0x%x = ", reg, addr);
#endif
	rdreg = mii_send(mk_mii_read(addr, reg));

#ifdef MII_DEBUG
	printf("0x%04x\n", rdreg);
#endif

	return rdreg;
}

int mcffec_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
			u16 value)
{
#ifdef MII_DEBUG
	printf("miiphy_write(0x%x) @ 0x%x = 0x%04x\n", reg, addr, value);
#endif

	mii_send(mk_mii_write(addr, reg, value));

	return 0;
}

#endif				/* CONFIG_CMD_NET */
