// 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>
#include <asm/global_data.h>
#include <linux/delay.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();
#ifdef CONFIG_DM_ETH
	info = dev_get_priv(dev);
#else
	info = dev->priv;
#endif

	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();
#ifdef CONFIG_DM_ETH
	info = dev_get_priv(dev);
#else
	info = dev->priv;
#endif

	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 */
