/*
 * Faraday 10/100Mbps Ethernet Controller
 *
 * (C) Copyright 2013 Faraday Technology
 * Dante Su <dantesu@faraday-tech.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <command.h>
#include <malloc.h>
#include <net.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/dma-mapping.h>

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

#include "ftmac110.h"

#define CFG_RXDES_NUM   8
#define CFG_TXDES_NUM   2
#define CFG_XBUF_SIZE   1536

#define CFG_MDIORD_TIMEOUT  (CONFIG_SYS_HZ >> 1) /* 500 ms */
#define CFG_MDIOWR_TIMEOUT  (CONFIG_SYS_HZ >> 1) /* 500 ms */
#define CFG_LINKUP_TIMEOUT  (CONFIG_SYS_HZ << 2) /* 4 sec */

/*
 * FTMAC110 DMA design issue
 *
 * Its DMA engine has a weird restriction that its Rx DMA engine
 * accepts only 16-bits aligned address, 32-bits aligned is not
 * acceptable. However this restriction does not apply to Tx DMA.
 *
 * Conclusion:
 * (1) Tx DMA Buffer Address:
 *     1 bytes aligned: Invalid
 *     2 bytes aligned: O.K
 *     4 bytes aligned: O.K (-> u-boot ZeroCopy is possible)
 * (2) Rx DMA Buffer Address:
 *     1 bytes aligned: Invalid
 *     2 bytes aligned: O.K
 *     4 bytes aligned: Invalid
 */

struct ftmac110_chip {
	void __iomem *regs;
	uint32_t imr;
	uint32_t maccr;
	uint32_t lnkup;
	uint32_t phy_addr;

	struct ftmac110_desc *rxd;
	ulong                rxd_dma;
	uint32_t             rxd_idx;

	struct ftmac110_desc *txd;
	ulong                txd_dma;
	uint32_t             txd_idx;
};

static int ftmac110_reset(struct eth_device *dev);

static uint16_t mdio_read(struct eth_device *dev,
	uint8_t phyaddr, uint8_t phyreg)
{
	struct ftmac110_chip *chip = dev->priv;
	struct ftmac110_regs *regs = chip->regs;
	uint32_t tmp, ts;
	uint16_t ret = 0xffff;

	tmp = PHYCR_READ
		| (phyaddr << PHYCR_ADDR_SHIFT)
		| (phyreg  << PHYCR_REG_SHIFT);

	writel(tmp, &regs->phycr);

	for (ts = get_timer(0); get_timer(ts) < CFG_MDIORD_TIMEOUT; ) {
		tmp = readl(&regs->phycr);
		if (tmp & PHYCR_READ)
			continue;
		break;
	}

	if (tmp & PHYCR_READ)
		printf("ftmac110: mdio read timeout\n");
	else
		ret = (uint16_t)(tmp & 0xffff);

	return ret;
}

static void mdio_write(struct eth_device *dev,
	uint8_t phyaddr, uint8_t phyreg, uint16_t phydata)
{
	struct ftmac110_chip *chip = dev->priv;
	struct ftmac110_regs *regs = chip->regs;
	uint32_t tmp, ts;

	tmp = PHYCR_WRITE
		| (phyaddr << PHYCR_ADDR_SHIFT)
		| (phyreg  << PHYCR_REG_SHIFT);

	writel(phydata, &regs->phydr);
	writel(tmp, &regs->phycr);

	for (ts = get_timer(0); get_timer(ts) < CFG_MDIOWR_TIMEOUT; ) {
		if (readl(&regs->phycr) & PHYCR_WRITE)
			continue;
		break;
	}

	if (readl(&regs->phycr) & PHYCR_WRITE)
		printf("ftmac110: mdio write timeout\n");
}

static uint32_t ftmac110_phyqry(struct eth_device *dev)
{
	ulong ts;
	uint32_t maccr;
	uint16_t pa, tmp, bmsr, bmcr;
	struct ftmac110_chip *chip = dev->priv;

	/* Default = 100Mbps Full */
	maccr = MACCR_100M | MACCR_FD;

	/* 1. find the phy device  */
	for (pa = 0; pa < 32; ++pa) {
		tmp = mdio_read(dev, pa, MII_PHYSID1);
		if (tmp == 0xFFFF || tmp == 0x0000)
			continue;
		chip->phy_addr = pa;
		break;
	}
	if (pa >= 32) {
		puts("ftmac110: phy device not found!\n");
		goto exit;
	}

	/* 2. wait until link-up & auto-negotiation complete */
	chip->lnkup = 0;
	bmcr = mdio_read(dev, chip->phy_addr, MII_BMCR);
	ts = get_timer(0);
	do {
		bmsr = mdio_read(dev, chip->phy_addr, MII_BMSR);
		chip->lnkup = (bmsr & BMSR_LSTATUS) ? 1 : 0;
		if (!chip->lnkup)
			continue;
		if (!(bmcr & BMCR_ANENABLE) || (bmsr & BMSR_ANEGCOMPLETE))
			break;
	} while (get_timer(ts) < CFG_LINKUP_TIMEOUT);
	if (!chip->lnkup) {
		puts("ftmac110: link down\n");
		goto exit;
	}
	if (!(bmcr & BMCR_ANENABLE))
		puts("ftmac110: auto negotiation disabled\n");
	else if (!(bmsr & BMSR_ANEGCOMPLETE))
		puts("ftmac110: auto negotiation timeout\n");

	/* 3. derive MACCR */
	if ((bmcr & BMCR_ANENABLE) && (bmsr & BMSR_ANEGCOMPLETE)) {
		tmp  = mdio_read(dev, chip->phy_addr, MII_ADVERTISE);
		tmp &= mdio_read(dev, chip->phy_addr, MII_LPA);
		if (tmp & LPA_100FULL)      /* 100Mbps full-duplex */
			maccr = MACCR_100M | MACCR_FD;
		else if (tmp & LPA_100HALF) /* 100Mbps half-duplex */
			maccr = MACCR_100M;
		else if (tmp & LPA_10FULL)  /* 10Mbps full-duplex */
			maccr = MACCR_FD;
		else if (tmp & LPA_10HALF)  /* 10Mbps half-duplex */
			maccr = 0;
	} else {
		if (bmcr & BMCR_SPEED100)
			maccr = MACCR_100M;
		else
			maccr = 0;
		if (bmcr & BMCR_FULLDPLX)
			maccr |= MACCR_FD;
	}

exit:
	printf("ftmac110: %d Mbps, %s\n",
	       (maccr & MACCR_100M) ? 100 : 10,
	       (maccr & MACCR_FD) ? "Full" : "half");
	return maccr;
}

static int ftmac110_reset(struct eth_device *dev)
{
	uint8_t *a;
	uint32_t i, maccr;
	struct ftmac110_chip *chip = dev->priv;
	struct ftmac110_regs *regs = chip->regs;

	/* 1. MAC reset */
	writel(MACCR_RESET, &regs->maccr);
	for (i = get_timer(0); get_timer(i) < 1000; ) {
		if (readl(&regs->maccr) & MACCR_RESET)
			continue;
		break;
	}
	if (readl(&regs->maccr) & MACCR_RESET) {
		printf("ftmac110: reset failed\n");
		return -ENXIO;
	}

	/* 1-1. Init tx ring */
	for (i = 0; i < CFG_TXDES_NUM; ++i) {
		/* owned by SW */
		chip->txd[i].ctrl &= cpu_to_le64(FTMAC110_TXD_CLRMASK);
	}
	chip->txd_idx = 0;

	/* 1-2. Init rx ring */
	for (i = 0; i < CFG_RXDES_NUM; ++i) {
		/* owned by HW */
		chip->rxd[i].ctrl &= cpu_to_le64(FTMAC110_RXD_CLRMASK);
		chip->rxd[i].ctrl |= cpu_to_le64(FTMAC110_RXD_OWNER);
	}
	chip->rxd_idx = 0;

	/* 2. PHY status query */
	maccr = ftmac110_phyqry(dev);

	/* 3. Fix up the MACCR value */
	chip->maccr = maccr | MACCR_CRCAPD | MACCR_RXALL | MACCR_RXRUNT
		| MACCR_RXEN | MACCR_TXEN | MACCR_RXDMAEN | MACCR_TXDMAEN;

	/* 4. MAC address setup */
	a = dev->enetaddr;
	writel(a[1] | (a[0] << 8), &regs->mac[0]);
	writel(a[5] | (a[4] << 8) | (a[3] << 16)
		| (a[2] << 24), &regs->mac[1]);

	/* 5. MAC registers setup */
	writel(chip->rxd_dma, &regs->rxba);
	writel(chip->txd_dma, &regs->txba);
	/* interrupt at each tx/rx */
	writel(ITC_DEFAULT, &regs->itc);
	/* no tx pool, rx poll = 1 normal cycle */
	writel(APTC_DEFAULT, &regs->aptc);
	/* rx threshold = [6/8 fifo, 2/8 fifo] */
	writel(DBLAC_DEFAULT, &regs->dblac);
	/* disable & clear all interrupt status */
	chip->imr = 0;
	writel(ISR_ALL, &regs->isr);
	writel(chip->imr, &regs->imr);
	/* enable mac */
	writel(chip->maccr, &regs->maccr);

	return 0;
}

static int ftmac110_probe(struct eth_device *dev, bd_t *bis)
{
	debug("ftmac110: probe\n");

	if (ftmac110_reset(dev))
		return -1;

	return 0;
}

static void ftmac110_halt(struct eth_device *dev)
{
	struct ftmac110_chip *chip = dev->priv;
	struct ftmac110_regs *regs = chip->regs;

	writel(0, &regs->imr);
	writel(0, &regs->maccr);

	debug("ftmac110: halt\n");
}

static int ftmac110_send(struct eth_device *dev, void *pkt, int len)
{
	struct ftmac110_chip *chip = dev->priv;
	struct ftmac110_regs *regs = chip->regs;
	struct ftmac110_desc *txd;
	uint64_t ctrl;

	if (!chip->lnkup)
		return 0;

	if (len <= 0 || len > CFG_XBUF_SIZE) {
		printf("ftmac110: bad tx pkt len(%d)\n", len);
		return 0;
	}

	len = max(60, len);

	txd = &chip->txd[chip->txd_idx];
	ctrl = le64_to_cpu(txd->ctrl);
	if (ctrl & FTMAC110_TXD_OWNER) {
		/* kick-off Tx DMA */
		writel(0xffffffff, &regs->txpd);
		printf("ftmac110: out of txd\n");
		return 0;
	}

	memcpy(txd->vbuf, (void *)pkt, len);
	dma_map_single(txd->vbuf, len, DMA_TO_DEVICE);

	/* clear control bits */
	ctrl &= FTMAC110_TXD_CLRMASK;
	/* set len, fts and lts */
	ctrl |= FTMAC110_TXD_LEN(len) | FTMAC110_TXD_FTS | FTMAC110_TXD_LTS;
	/* set owner bit */
	ctrl |= FTMAC110_TXD_OWNER;
	/* write back to descriptor */
	txd->ctrl = cpu_to_le64(ctrl);

	/* kick-off Tx DMA */
	writel(0xffffffff, &regs->txpd);

	chip->txd_idx = (chip->txd_idx + 1) % CFG_TXDES_NUM;

	return len;
}

static int ftmac110_recv(struct eth_device *dev)
{
	struct ftmac110_chip *chip = dev->priv;
	struct ftmac110_desc *rxd;
	uint32_t len, rlen = 0;
	uint64_t ctrl;
	uint8_t *buf;

	if (!chip->lnkup)
		return 0;

	do {
		rxd = &chip->rxd[chip->rxd_idx];
		ctrl = le64_to_cpu(rxd->ctrl);
		if (ctrl & FTMAC110_RXD_OWNER)
			break;

		len = (uint32_t)FTMAC110_RXD_LEN(ctrl);
		buf = rxd->vbuf;

		if (ctrl & FTMAC110_RXD_ERRMASK) {
			printf("ftmac110: rx error\n");
		} else {
			dma_map_single(buf, len, DMA_FROM_DEVICE);
			net_process_received_packet(buf, len);
			rlen += len;
		}

		/* owned by hardware */
		ctrl &= FTMAC110_RXD_CLRMASK;
		ctrl |= FTMAC110_RXD_OWNER;
		rxd->ctrl |= cpu_to_le64(ctrl);

		chip->rxd_idx = (chip->rxd_idx + 1) % CFG_RXDES_NUM;
	} while (0);

	return rlen;
}

#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)

static int ftmac110_mdio_read(
	const char *devname, uint8_t addr, uint8_t reg, uint16_t *value)
{
	int ret = 0;
	struct eth_device *dev;

	dev = eth_get_dev_by_name(devname);
	if (dev == NULL) {
		printf("%s: no such device\n", devname);
		ret = -1;
	} else {
		*value = mdio_read(dev, addr, reg);
	}

	return ret;
}

static int ftmac110_mdio_write(
	const char *devname, uint8_t addr, uint8_t reg, uint16_t value)
{
	int ret = 0;
	struct eth_device *dev;

	dev = eth_get_dev_by_name(devname);
	if (dev == NULL) {
		printf("%s: no such device\n", devname);
		ret = -1;
	} else {
		mdio_write(dev, addr, reg, value);
	}

	return ret;
}

#endif    /* #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) */

int ftmac110_initialize(bd_t *bis)
{
	int i, card_nr = 0;
	struct eth_device *dev;
	struct ftmac110_chip *chip;

	dev = malloc(sizeof(*dev) + sizeof(*chip));
	if (dev == NULL) {
		panic("ftmac110: out of memory 1\n");
		return -1;
	}
	chip = (struct ftmac110_chip *)(dev + 1);
	memset(dev, 0, sizeof(*dev) + sizeof(*chip));

	sprintf(dev->name, "FTMAC110#%d", card_nr);

	dev->iobase = CONFIG_FTMAC110_BASE;
	chip->regs = (void __iomem *)dev->iobase;
	dev->priv = chip;
	dev->init = ftmac110_probe;
	dev->halt = ftmac110_halt;
	dev->send = ftmac110_send;
	dev->recv = ftmac110_recv;

	if (!eth_getenv_enetaddr_by_index("eth", card_nr, dev->enetaddr))
		net_random_ethaddr(dev->enetaddr);

	/* allocate tx descriptors (it must be 16 bytes aligned) */
	chip->txd = dma_alloc_coherent(
		sizeof(struct ftmac110_desc) * CFG_TXDES_NUM, &chip->txd_dma);
	if (!chip->txd)
		panic("ftmac110: out of memory 3\n");
	memset(chip->txd, 0,
	       sizeof(struct ftmac110_desc) * CFG_TXDES_NUM);
	for (i = 0; i < CFG_TXDES_NUM; ++i) {
		void *va = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE);

		if (!va)
			panic("ftmac110: out of memory 4\n");
		chip->txd[i].vbuf = va;
		chip->txd[i].pbuf = cpu_to_le32(virt_to_phys(va));
		chip->txd[i].ctrl = 0;	/* owned by SW */
	}
	chip->txd[i - 1].ctrl |= cpu_to_le64(FTMAC110_TXD_END);
	chip->txd_idx = 0;

	/* allocate rx descriptors (it must be 16 bytes aligned) */
	chip->rxd = dma_alloc_coherent(
		sizeof(struct ftmac110_desc) * CFG_RXDES_NUM, &chip->rxd_dma);
	if (!chip->rxd)
		panic("ftmac110: out of memory 4\n");
	memset((void *)chip->rxd, 0,
	       sizeof(struct ftmac110_desc) * CFG_RXDES_NUM);
	for (i = 0; i < CFG_RXDES_NUM; ++i) {
		void *va = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE + 2);

		if (!va)
			panic("ftmac110: out of memory 5\n");
		/* it needs to be exactly 2 bytes aligned */
		va = ((uint8_t *)va + 2);
		chip->rxd[i].vbuf = va;
		chip->rxd[i].pbuf = cpu_to_le32(virt_to_phys(va));
		chip->rxd[i].ctrl = cpu_to_le64(FTMAC110_RXD_OWNER
			| FTMAC110_RXD_BUFSZ(CFG_XBUF_SIZE));
	}
	chip->rxd[i - 1].ctrl |= cpu_to_le64(FTMAC110_RXD_END);
	chip->rxd_idx = 0;

	eth_register(dev);

#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
	miiphy_register(dev->name, ftmac110_mdio_read, ftmac110_mdio_write);
#endif

	card_nr++;

	return card_nr;
}
