// SPDX-License-Identifier: GPL-2.0+
/*
 * SMSC LAN9[12]1[567] Network driver
 *
 * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
 */

#include <common.h>
#include <command.h>
#include <malloc.h>
#include <net.h>
#include <miiphy.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/types.h>

#include "smc911x.h"

struct chip_id {
	u16 id;
	char *name;
};

struct smc911x_priv {
#ifndef CONFIG_DM_ETH
	struct eth_device	dev;
#endif
	phys_addr_t		iobase;
	const struct chip_id	*chipid;
	unsigned char		enetaddr[6];
	bool			use_32_bit_io;
};

static const struct chip_id chip_ids[] =  {
	{ CHIP_89218, "LAN89218" },
	{ CHIP_9115, "LAN9115" },
	{ CHIP_9116, "LAN9116" },
	{ CHIP_9117, "LAN9117" },
	{ CHIP_9118, "LAN9118" },
	{ CHIP_9211, "LAN9211" },
	{ CHIP_9215, "LAN9215" },
	{ CHIP_9216, "LAN9216" },
	{ CHIP_9217, "LAN9217" },
	{ CHIP_9218, "LAN9218" },
	{ CHIP_9220, "LAN9220" },
	{ CHIP_9221, "LAN9221" },
	{ 0, NULL },
};

#define DRIVERNAME "smc911x"

static u32 smc911x_reg_read(struct smc911x_priv *priv, u32 offset)
{
	if (priv->use_32_bit_io)
		return readl(priv->iobase + offset);

	return (readw(priv->iobase + offset) & 0xffff) |
	       (readw(priv->iobase + offset + 2) << 16);
}

static void smc911x_reg_write(struct smc911x_priv *priv, u32 offset, u32 val)
{
	if (priv->use_32_bit_io) {
		writel(val, priv->iobase + offset);
	} else {
		writew(val & 0xffff, priv->iobase + offset);
		writew(val >> 16, priv->iobase + offset + 2);
	}
}

static u32 smc911x_get_mac_csr(struct smc911x_priv *priv, u8 reg)
{
	while (smc911x_reg_read(priv, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
		;
	smc911x_reg_write(priv, MAC_CSR_CMD,
			MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg);
	while (smc911x_reg_read(priv, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
		;

	return smc911x_reg_read(priv, MAC_CSR_DATA);
}

static void smc911x_set_mac_csr(struct smc911x_priv *priv, u8 reg, u32 data)
{
	while (smc911x_reg_read(priv, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
		;
	smc911x_reg_write(priv, MAC_CSR_DATA, data);
	smc911x_reg_write(priv, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg);
	while (smc911x_reg_read(priv, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
		;
}

static int smc911x_detect_chip(struct smc911x_priv *priv)
{
	unsigned long val, i;

	val = smc911x_reg_read(priv, BYTE_TEST);
	if (val == 0xffffffff) {
		/* Special case -- no chip present */
		return -1;
	} else if (val != 0x87654321) {
		printf(DRIVERNAME ": Invalid chip endian 0x%08lx\n", val);
		return -1;
	}

	val = smc911x_reg_read(priv, ID_REV) >> 16;
	for (i = 0; chip_ids[i].id != 0; i++) {
		if (chip_ids[i].id == val) break;
	}
	if (!chip_ids[i].id) {
		printf(DRIVERNAME ": Unknown chip ID %04lx\n", val);
		return -1;
	}

	priv->chipid = &chip_ids[i];

	return 0;
}

static void smc911x_reset(struct smc911x_priv *priv)
{
	int timeout;

	/*
	 *  Take out of PM setting first
	 *  Device is already wake up if PMT_CTRL_READY bit is set
	 */
	if ((smc911x_reg_read(priv, PMT_CTRL) & PMT_CTRL_READY) == 0) {
		/* Write to the bytetest will take out of powerdown */
		smc911x_reg_write(priv, BYTE_TEST, 0x0);

		timeout = 10;

		while (timeout-- &&
			!(smc911x_reg_read(priv, PMT_CTRL) & PMT_CTRL_READY))
			udelay(10);
		if (timeout < 0) {
			printf(DRIVERNAME
				": timeout waiting for PM restore\n");
			return;
		}
	}

	/* Disable interrupts */
	smc911x_reg_write(priv, INT_EN, 0);

	smc911x_reg_write(priv, HW_CFG, HW_CFG_SRST);

	timeout = 1000;
	while (timeout-- && smc911x_reg_read(priv, E2P_CMD) & E2P_CMD_EPC_BUSY)
		udelay(10);

	if (timeout < 0) {
		printf(DRIVERNAME ": reset timeout\n");
		return;
	}

	/* Reset the FIFO level and flow control settings */
	smc911x_set_mac_csr(priv, FLOW, FLOW_FCPT | FLOW_FCEN);
	smc911x_reg_write(priv, AFC_CFG, 0x0050287F);

	/* Set to LED outputs */
	smc911x_reg_write(priv, GPIO_CFG, 0x70070000);
}

static void smc911x_handle_mac_address(struct smc911x_priv *priv)
{
	unsigned long addrh, addrl;
	unsigned char *m = priv->enetaddr;

	addrl = m[0] | (m[1] << 8) | (m[2] << 16) | (m[3] << 24);
	addrh = m[4] | (m[5] << 8);
	smc911x_set_mac_csr(priv, ADDRL, addrl);
	smc911x_set_mac_csr(priv, ADDRH, addrh);

	printf(DRIVERNAME ": MAC %pM\n", m);
}

static bool smc911x_read_mac_address(struct smc911x_priv *priv)
{
	u32 addrh, addrl;

	/* address is obtained from optional eeprom */
	addrh = smc911x_get_mac_csr(priv, ADDRH);
	addrl = smc911x_get_mac_csr(priv, ADDRL);
	if (addrl == 0xffffffff && addrh == 0x0000ffff)
		return false;

	priv->enetaddr[0] = addrl;
	priv->enetaddr[1] = addrl >>  8;
	priv->enetaddr[2] = addrl >> 16;
	priv->enetaddr[3] = addrl >> 24;
	priv->enetaddr[4] = addrh;
	priv->enetaddr[5] = addrh >> 8;

	return true;
}

static int smc911x_eth_phy_read(struct smc911x_priv *priv,
				u8 phy, u8 reg, u16 *val)
{
	while (smc911x_get_mac_csr(priv, MII_ACC) & MII_ACC_MII_BUSY)
		;

	smc911x_set_mac_csr(priv, MII_ACC, phy << 11 | reg << 6 |
				MII_ACC_MII_BUSY);

	while (smc911x_get_mac_csr(priv, MII_ACC) & MII_ACC_MII_BUSY)
		;

	*val = smc911x_get_mac_csr(priv, MII_DATA);

	return 0;
}

static int smc911x_eth_phy_write(struct smc911x_priv *priv,
				u8 phy, u8 reg, u16  val)
{
	while (smc911x_get_mac_csr(priv, MII_ACC) & MII_ACC_MII_BUSY)
		;

	smc911x_set_mac_csr(priv, MII_DATA, val);
	smc911x_set_mac_csr(priv, MII_ACC,
		phy << 11 | reg << 6 | MII_ACC_MII_BUSY | MII_ACC_MII_WRITE);

	while (smc911x_get_mac_csr(priv, MII_ACC) & MII_ACC_MII_BUSY)
		;
	return 0;
}

static int smc911x_phy_reset(struct smc911x_priv *priv)
{
	u32 reg;

	reg = smc911x_reg_read(priv, PMT_CTRL);
	reg &= ~0xfffff030;
	reg |= PMT_CTRL_PHY_RST;
	smc911x_reg_write(priv, PMT_CTRL, reg);

	mdelay(100);

	return 0;
}

static void smc911x_phy_configure(struct smc911x_priv *priv)
{
	int timeout;
	u16 status;

	smc911x_phy_reset(priv);

	smc911x_eth_phy_write(priv, 1, MII_BMCR, BMCR_RESET);
	mdelay(1);
	smc911x_eth_phy_write(priv, 1, MII_ADVERTISE, 0x01e1);
	smc911x_eth_phy_write(priv, 1, MII_BMCR, BMCR_ANENABLE |
				BMCR_ANRESTART);

	timeout = 5000;
	do {
		mdelay(1);
		if ((timeout--) == 0)
			goto err_out;

		if (smc911x_eth_phy_read(priv, 1, MII_BMSR, &status) != 0)
			goto err_out;
	} while (!(status & BMSR_LSTATUS));

	printf(DRIVERNAME ": phy initialized\n");

	return;

err_out:
	printf(DRIVERNAME ": autonegotiation timed out\n");
}

static void smc911x_enable(struct smc911x_priv *priv)
{
	/* Enable TX */
	smc911x_reg_write(priv, HW_CFG, 8 << 16 | HW_CFG_SF);

	smc911x_reg_write(priv, GPT_CFG, GPT_CFG_TIMER_EN | 10000);

	smc911x_reg_write(priv, TX_CFG, TX_CFG_TX_ON);

	/* no padding to start of packets */
	smc911x_reg_write(priv, RX_CFG, 0);

	smc911x_set_mac_csr(priv, MAC_CR, MAC_CR_TXEN | MAC_CR_RXEN |
				MAC_CR_HBDIS);
}

static int smc911x_init_common(struct smc911x_priv *priv)
{
	const struct chip_id *id = priv->chipid;

	printf(DRIVERNAME ": detected %s controller\n", id->name);

	smc911x_reset(priv);

	/* Configure the PHY, initialize the link state */
	smc911x_phy_configure(priv);

	smc911x_handle_mac_address(priv);

	/* Turn on Tx + Rx */
	smc911x_enable(priv);

	return 0;
}

static int smc911x_send_common(struct smc911x_priv *priv,
			       void *packet, int length)
{
	u32 *data = (u32*)packet;
	u32 tmplen;
	u32 status;

	smc911x_reg_write(priv, TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG |
				TX_CMD_A_INT_LAST_SEG | length);
	smc911x_reg_write(priv, TX_DATA_FIFO, length);

	tmplen = (length + 3) / 4;

	while (tmplen--)
		smc911x_reg_write(priv, TX_DATA_FIFO, *data++);

	/* wait for transmission */
	while (!((smc911x_reg_read(priv, TX_FIFO_INF) &
					TX_FIFO_INF_TSUSED) >> 16));

	/* get status. Ignore 'no carrier' error, it has no meaning for
	 * full duplex operation
	 */
	status = smc911x_reg_read(priv, TX_STATUS_FIFO) &
			(TX_STS_LOC | TX_STS_LATE_COLL | TX_STS_MANY_COLL |
			TX_STS_MANY_DEFER | TX_STS_UNDERRUN);

	if (!status)
		return 0;

	printf(DRIVERNAME ": failed to send packet: %s%s%s%s%s\n",
		status & TX_STS_LOC ? "TX_STS_LOC " : "",
		status & TX_STS_LATE_COLL ? "TX_STS_LATE_COLL " : "",
		status & TX_STS_MANY_COLL ? "TX_STS_MANY_COLL " : "",
		status & TX_STS_MANY_DEFER ? "TX_STS_MANY_DEFER " : "",
		status & TX_STS_UNDERRUN ? "TX_STS_UNDERRUN" : "");

	return -1;
}

static void smc911x_halt_common(struct smc911x_priv *priv)
{
	smc911x_reset(priv);
	smc911x_handle_mac_address(priv);
}

static int smc911x_recv_common(struct smc911x_priv *priv, u32 *data)
{
	u32 pktlen, tmplen;
	u32 status;

	status = smc911x_reg_read(priv, RX_FIFO_INF);
	if (!(status & RX_FIFO_INF_RXSUSED))
		return 0;

	status = smc911x_reg_read(priv, RX_STATUS_FIFO);
	pktlen = (status & RX_STS_PKT_LEN) >> 16;

	smc911x_reg_write(priv, RX_CFG, 0);

	tmplen = (pktlen + 3) / 4;
	while (tmplen--)
		*data++ = smc911x_reg_read(priv, RX_DATA_FIFO);

	if (status & RX_STS_ES) {
		printf(DRIVERNAME
			": dropped bad packet. Status: 0x%08x\n",
			status);
		return 0;
	}

	return pktlen;
}

#ifndef CONFIG_DM_ETH

#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
/* wrapper for smc911x_eth_phy_read */
static int smc911x_miiphy_read(struct mii_dev *bus, int phy, int devad,
			       int reg)
{
	struct eth_device *dev = eth_get_dev_by_name(bus->name);
	struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev);
	u16 val = 0;
	int ret;

	if (!dev || !priv)
		return -ENODEV;

	ret = smc911x_eth_phy_read(priv, phy, reg, &val);
	if (ret < 0)
		return ret;

	return val;
}

/* wrapper for smc911x_eth_phy_write */
static int smc911x_miiphy_write(struct mii_dev *bus, int phy, int devad,
				int reg, u16 val)
{
	struct eth_device *dev = eth_get_dev_by_name(bus->name);
	struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev);

	if (!dev || !priv)
		return -ENODEV;

	return smc911x_eth_phy_write(priv, phy, reg, val);
}

static int smc911x_initialize_mii(struct smc911x_priv *priv)
{
	struct mii_dev *mdiodev = mdio_alloc();
	int ret;

	if (!mdiodev)
		return -ENOMEM;

	strlcpy(mdiodev->name, priv->dev.name, MDIO_NAME_LEN);
	mdiodev->read = smc911x_miiphy_read;
	mdiodev->write = smc911x_miiphy_write;

	ret = mdio_register(mdiodev);
	if (ret < 0) {
		mdio_free(mdiodev);
		return ret;
	}

	return 0;
}
#else
static int smc911x_initialize_mii(struct smc911x_priv *priv)
{
	return 0;
}
#endif

static int smc911x_init(struct eth_device *dev, struct bd_info *bd)
{
	struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev);

	return smc911x_init_common(priv);
}

static void smc911x_halt(struct eth_device *dev)
{
	struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev);

	smc911x_halt_common(priv);
}

static int smc911x_send(struct eth_device *dev, void *packet, int length)
{
	struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev);

	return smc911x_send_common(priv, packet, length);
}

static int smc911x_recv(struct eth_device *dev)
{
	struct smc911x_priv *priv = container_of(dev, struct smc911x_priv, dev);
	u32 *data = (u32 *)net_rx_packets[0];
	int ret;

	ret = smc911x_recv_common(priv, data);
	if (ret)
		net_process_received_packet(net_rx_packets[0], ret);

	return ret;
}

int smc911x_initialize(u8 dev_num, phys_addr_t base_addr)
{
	struct smc911x_priv *priv;
	int ret;

	priv = calloc(1, sizeof(*priv));
	if (!priv)
		return -ENOMEM;

	priv->iobase = base_addr;
	priv->dev.iobase = base_addr;

	priv->use_32_bit_io = CONFIG_IS_ENABLED(SMC911X_32_BIT);

	/* Try to detect chip. Will fail if not present. */
	ret = smc911x_detect_chip(priv);
	if (ret) {
		ret = 0;	/* Card not detected is not an error */
		goto err_detect;
	}

	if (smc911x_read_mac_address(priv))
		memcpy(priv->dev.enetaddr, priv->enetaddr, 6);

	priv->dev.init = smc911x_init;
	priv->dev.halt = smc911x_halt;
	priv->dev.send = smc911x_send;
	priv->dev.recv = smc911x_recv;
	sprintf(priv->dev.name, "%s-%hu", DRIVERNAME, dev_num);

	eth_register(&priv->dev);

	ret = smc911x_initialize_mii(priv);
	if (ret)
		goto err_mii;

	return 1;

err_mii:
	eth_unregister(&priv->dev);
err_detect:
	free(priv);
	return ret;
}

#else	/* ifdef CONFIG_DM_ETH */

static int smc911x_start(struct udevice *dev)
{
	struct eth_pdata *plat = dev_get_plat(dev);
	struct smc911x_priv *priv = dev_get_priv(dev);

	memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr));

	return smc911x_init_common(priv);
}

static void smc911x_stop(struct udevice *dev)
{
	struct smc911x_priv *priv = dev_get_priv(dev);

	smc911x_halt_common(priv);
}

static int smc911x_send(struct udevice *dev, void *packet, int length)
{
	struct smc911x_priv *priv = dev_get_priv(dev);
	int ret;

	ret = smc911x_send_common(priv, packet, length);

	return ret ? 0 : -ETIMEDOUT;
}

static int smc911x_recv(struct udevice *dev, int flags, uchar **packetp)
{
	struct smc911x_priv *priv = dev_get_priv(dev);
	u32 *data = (u32 *)net_rx_packets[0];
	int ret;

	ret = smc911x_recv_common(priv, data);
	if (ret)
		*packetp = (void *)data;

	return ret ? ret : -EAGAIN;
}

static int smc911x_read_rom_hwaddr(struct udevice *dev)
{
	struct smc911x_priv *priv = dev_get_priv(dev);
	struct eth_pdata *pdata = dev_get_plat(dev);

	if (!smc911x_read_mac_address(priv))
		return -ENODEV;

	memcpy(pdata->enetaddr, priv->enetaddr, sizeof(pdata->enetaddr));

	return 0;
}

static int smc911x_bind(struct udevice *dev)
{
	return device_set_name(dev, dev->name);
}

static int smc911x_probe(struct udevice *dev)
{
	struct smc911x_priv *priv = dev_get_priv(dev);
	int ret;

	/* Try to detect chip. Will fail if not present. */
	ret = smc911x_detect_chip(priv);
	if (ret)
		return ret;

	smc911x_read_rom_hwaddr(dev);

	return 0;
}

static int smc911x_of_to_plat(struct udevice *dev)
{
	struct smc911x_priv *priv = dev_get_priv(dev);
	struct eth_pdata *pdata = dev_get_plat(dev);
	u32 io_width;
	int ret;

	pdata->iobase = dev_read_addr(dev);
	priv->iobase = pdata->iobase;

	ret = dev_read_u32(dev, "reg-io-width", &io_width);
	if (!ret)
		priv->use_32_bit_io = (io_width == 4);
	else
		priv->use_32_bit_io = CONFIG_IS_ENABLED(SMC911X_32_BIT);

	return 0;
}

static const struct eth_ops smc911x_ops = {
	.start	= smc911x_start,
	.send	= smc911x_send,
	.recv	= smc911x_recv,
	.stop	= smc911x_stop,
	.read_rom_hwaddr = smc911x_read_rom_hwaddr,
};

static const struct udevice_id smc911x_ids[] = {
	{ .compatible = "smsc,lan9115" },
	{ }
};

U_BOOT_DRIVER(smc911x) = {
	.name		= "eth_smc911x",
	.id		= UCLASS_ETH,
	.of_match	= smc911x_ids,
	.bind		= smc911x_bind,
	.of_to_plat = smc911x_of_to_plat,
	.probe		= smc911x_probe,
	.ops		= &smc911x_ops,
	.priv_auto	= sizeof(struct smc911x_priv),
	.plat_auto	= sizeof(struct eth_pdata),
	.flags		= DM_FLAG_ALLOC_PRIV_DMA,
};
#endif
