/*
 * Dave Ethernet Controller driver
 *
 * Copyright (C) 2008 Dave S.r.l. <www.dave.eu>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <common.h>

#ifndef CONFIG_DNET_AUTONEG_TIMEOUT
#define CONFIG_DNET_AUTONEG_TIMEOUT	5000000	/* default value */
#endif

#include <net.h>
#include <malloc.h>
#include <linux/mii.h>

#include <miiphy.h>
#include <asm/io.h>

#include "dnet.h"

struct dnet_device {
	struct dnet_registers	*regs;
	const struct device	*dev;
	struct eth_device	netdev;
	unsigned short		phy_addr;
};

/* get struct dnet_device from given struct netdev */
#define to_dnet(_nd) container_of(_nd, struct dnet_device, netdev)

/* function for reading internal MAC register */
u16 dnet_readw_mac(struct dnet_device *dnet, u16 reg)
{
	u16 data_read;

	/* issue a read */
	writel(reg, &dnet->regs->MACREG_ADDR);

	/* since a read/write op to the MAC is very slow,
	 * we must wait before reading the data */
	udelay(1);

	/* read data read from the MAC register */
	data_read = readl(&dnet->regs->MACREG_DATA);

	/* all done */
	return data_read;
}

/* function for writing internal MAC register */
void dnet_writew_mac(struct dnet_device *dnet, u16 reg, u16 val)
{
	/* load data to write */
	writel(val, &dnet->regs->MACREG_DATA);

	/* issue a write */
	writel(reg | DNET_INTERNAL_WRITE, &dnet->regs->MACREG_ADDR);

	/* since a read/write op to the MAC is very slow,
	 * we must wait before exiting */
	udelay(1);
}

static void dnet_mdio_write(struct dnet_device *dnet, u8 reg, u16 value)
{
	u16 tmp;

	debug(DRIVERNAME "dnet_mdio_write %02x:%02x <- %04x\n",
			dnet->phy_addr, reg, value);

	while (!(dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG) &
				DNET_INTERNAL_GMII_MNG_CMD_FIN))
		;

	/* prepare for a write operation */
	tmp = (1 << 13);

	/* only 5 bits allowed for register offset */
	reg &= 0x1f;

	/* prepare reg_value for a write */
	tmp |= (dnet->phy_addr << 8);
	tmp |= reg;

	/* write data to write first */
	dnet_writew_mac(dnet, DNET_INTERNAL_GMII_MNG_DAT_REG, value);

	/* write control word */
	dnet_writew_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG, tmp);

	while (!(dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG) &
				DNET_INTERNAL_GMII_MNG_CMD_FIN))
		;
}

static u16 dnet_mdio_read(struct dnet_device *dnet, u8 reg)
{
	u16 value;

	while (!(dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG) &
				DNET_INTERNAL_GMII_MNG_CMD_FIN))
		;

	/* only 5 bits allowed for register offset*/
	reg &= 0x1f;

	/* prepare reg_value for a read */
	value = (dnet->phy_addr << 8);
	value |= reg;

	/* write control word */
	dnet_writew_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG, value);

	/* wait for end of transfer */
	while (!(dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_CTL_REG) &
				DNET_INTERNAL_GMII_MNG_CMD_FIN))
		;

	value = dnet_readw_mac(dnet, DNET_INTERNAL_GMII_MNG_DAT_REG);

	debug(DRIVERNAME "dnet_mdio_read %02x:%02x <- %04x\n",
		dnet->phy_addr, reg, value);

	return value;
}

static int dnet_send(struct eth_device *netdev, volatile void *packet,
		     int length)
{
	struct dnet_device *dnet = to_dnet(netdev);
	int i, len, wrsz;
	unsigned int *bufp;
	unsigned int tx_cmd;

	debug(DRIVERNAME "[%s] Sending %u bytes\n", __func__, length);

	/* frame size (words) */
	len = (length + 3) >> 2;

	bufp = (unsigned int *) (((u32)packet) & 0xFFFFFFFC);
	wrsz = (u32)length + 3;
	wrsz += ((u32)packet) & 0x3;
	wrsz >>= 2;
	tx_cmd = ((((unsigned int)(packet)) & 0x03) << 16) | (u32)length;

	/* check if there is enough room for the current frame */
	if (wrsz < (DNET_FIFO_SIZE - readl(&dnet->regs->TX_FIFO_WCNT))) {
		for (i = 0; i < wrsz; i++)
			writel(*bufp++, &dnet->regs->TX_DATA_FIFO);
		/*
		 * inform MAC that a packet's written and ready
		 * to be shipped out
		 */
		writel(tx_cmd, &dnet->regs->TX_LEN_FIFO);
	} else {
		printf(DRIVERNAME "No free space (actual %d, required %d "
				"(words))\n", DNET_FIFO_SIZE -
				readl(&dnet->regs->TX_FIFO_WCNT), wrsz);
	}

	/* No one cares anyway */
	return 0;
}


static int dnet_recv(struct eth_device *netdev)
{
	struct dnet_device *dnet = to_dnet(netdev);
	unsigned int *data_ptr;
	int pkt_len, poll, i;
	u32 cmd_word;

	debug("Waiting for pkt (polling)\n");
	poll = 50;
	while ((readl(&dnet->regs->RX_FIFO_WCNT) >> 16) == 0) {
		udelay(10);  /* wait 10 usec */
		if (--poll == 0)
			return 0;	/* no pkt available */
	}

	cmd_word = readl(&dnet->regs->RX_LEN_FIFO);
	pkt_len = cmd_word & 0xFFFF;

	debug("Got pkt with size %d bytes\n", pkt_len);

	if (cmd_word & 0xDF180000)
		printf("%s packet receive error %x\n", __func__, cmd_word);

	data_ptr = (unsigned int *) NetRxPackets[0];

	for (i = 0; i < (pkt_len + 3) >> 2; i++)
		*data_ptr++ = readl(&dnet->regs->RX_DATA_FIFO);

	NetReceive(NetRxPackets[0], pkt_len + 5); /* ok + 5 ?? */

	return 0;
}

static void dnet_set_hwaddr(struct eth_device *netdev)
{
	struct dnet_device *dnet = to_dnet(netdev);
	u16 tmp;

	tmp = cpu_to_be16(*((u16 *)netdev->enetaddr));
	dnet_writew_mac(dnet, DNET_INTERNAL_MAC_ADDR_0_REG, tmp);
	tmp = cpu_to_be16(*((u16 *)(netdev->enetaddr + 2)));
	dnet_writew_mac(dnet, DNET_INTERNAL_MAC_ADDR_1_REG, tmp);
	tmp = cpu_to_be16(*((u16 *)(netdev->enetaddr + 4)));
	dnet_writew_mac(dnet, DNET_INTERNAL_MAC_ADDR_2_REG, tmp);
}

static void dnet_phy_reset(struct dnet_device *dnet)
{
	struct eth_device *netdev = &dnet->netdev;
	int i;
	u16 status, adv;

	adv = ADVERTISE_CSMA | ADVERTISE_ALL;
	dnet_mdio_write(dnet, MII_ADVERTISE, adv);
	printf("%s: Starting autonegotiation...\n", netdev->name);
	dnet_mdio_write(dnet, MII_BMCR, (BMCR_ANENABLE
					 | BMCR_ANRESTART));

	for (i = 0; i < CONFIG_DNET_AUTONEG_TIMEOUT / 100; i++) {
		status = dnet_mdio_read(dnet, MII_BMSR);
		if (status & BMSR_ANEGCOMPLETE)
			break;
		udelay(100);
	}

	if (status & BMSR_ANEGCOMPLETE)
		printf("%s: Autonegotiation complete\n", netdev->name);
	else
		printf("%s: Autonegotiation timed out (status=0x%04x)\n",
		       netdev->name, status);
}

static int dnet_phy_init(struct dnet_device *dnet)
{
	struct eth_device *netdev = &dnet->netdev;
	u16 phy_id, status, adv, lpa;
	int media, speed, duplex;
	int i;
	u32 ctl_reg;

	/* Find a PHY */
	for (i = 0; i < 32; i++) {
		dnet->phy_addr = i;
		phy_id = dnet_mdio_read(dnet, MII_PHYSID1);
		if (phy_id != 0xffff) {
			/* ok we found it */
			printf("Found PHY at address %d PHYID (%04x:%04x)\n",
					i, phy_id,
					dnet_mdio_read(dnet, MII_PHYSID2));
			break;
		}
	}

	/* Check if the PHY is up to snuff... */
	phy_id = dnet_mdio_read(dnet, MII_PHYSID1);
	if (phy_id == 0xffff) {
		printf("%s: No PHY present\n", netdev->name);
		return -1;
	}

	status = dnet_mdio_read(dnet, MII_BMSR);
	if (!(status & BMSR_LSTATUS)) {
		/* Try to re-negotiate if we don't have link already. */
		dnet_phy_reset(dnet);

		for (i = 0; i < CONFIG_DNET_AUTONEG_TIMEOUT / 100; i++) {
			status = dnet_mdio_read(dnet, MII_BMSR);
			if (status & BMSR_LSTATUS)
				break;
			udelay(100);
		}
	}

	if (!(status & BMSR_LSTATUS)) {
		printf("%s: link down (status: 0x%04x)\n",
		       netdev->name, status);
		return -1;
	} else {
		adv = dnet_mdio_read(dnet, MII_ADVERTISE);
		lpa = dnet_mdio_read(dnet, MII_LPA);
		media = mii_nway_result(lpa & adv);
		speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
			 ? 1 : 0);
		duplex = (media & ADVERTISE_FULL) ? 1 : 0;
		/* 1000BaseT ethernet is not supported */
		printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
		       netdev->name,
		       speed ? "100" : "10",
		       duplex ? "full" : "half",
		       lpa);

		ctl_reg = dnet_readw_mac(dnet, DNET_INTERNAL_RXTX_CONTROL_REG);

		if (duplex)
			ctl_reg &= ~(DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP);
		else
			ctl_reg |= DNET_INTERNAL_RXTX_CONTROL_ENABLEHALFDUP;

		dnet_writew_mac(dnet, DNET_INTERNAL_RXTX_CONTROL_REG, ctl_reg);

		return 0;
	}
}

static int dnet_init(struct eth_device *netdev, bd_t *bd)
{
	struct dnet_device *dnet = to_dnet(netdev);
	u32 config;

	/*
	 * dnet_halt should have been called at some point before now,
	 * so we'll assume the controller is idle.
	 */

	/* set hardware address */
	dnet_set_hwaddr(netdev);

	if (dnet_phy_init(dnet) < 0)
		return -1;

	/* flush rx/tx fifos */
	writel(DNET_SYS_CTL_RXFIFOFLUSH | DNET_SYS_CTL_TXFIFOFLUSH,
			&dnet->regs->SYS_CTL);
	udelay(1000);
	writel(0, &dnet->regs->SYS_CTL);

	config = dnet_readw_mac(dnet, DNET_INTERNAL_RXTX_CONTROL_REG);

	config |= DNET_INTERNAL_RXTX_CONTROL_RXPAUSE |
			DNET_INTERNAL_RXTX_CONTROL_RXBROADCAST |
			DNET_INTERNAL_RXTX_CONTROL_DROPCONTROL |
			DNET_INTERNAL_RXTX_CONTROL_DISCFXFCS;

	dnet_writew_mac(dnet, DNET_INTERNAL_RXTX_CONTROL_REG, config);

	/* Enable TX and RX */
	dnet_writew_mac(dnet, DNET_INTERNAL_MODE_REG,
			DNET_INTERNAL_MODE_RXEN | DNET_INTERNAL_MODE_TXEN);

	return 0;
}

static void dnet_halt(struct eth_device *netdev)
{
	struct dnet_device *dnet = to_dnet(netdev);

	/* Disable TX and RX */
	dnet_writew_mac(dnet, DNET_INTERNAL_MODE_REG, 0);
}

int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr)
{
	struct dnet_device *dnet;
	struct eth_device *netdev;
	unsigned int dev_capa;

	dnet = malloc(sizeof(struct dnet_device));
	if (!dnet) {
		printf("Error: Failed to allocate memory for DNET%d\n", id);
		return -1;
	}
	memset(dnet, 0, sizeof(struct dnet_device));

	netdev = &dnet->netdev;

	dnet->regs = (struct dnet_registers *)regs;
	dnet->phy_addr = phy_addr;

	sprintf(netdev->name, "dnet%d", id);
	netdev->init = dnet_init;
	netdev->halt = dnet_halt;
	netdev->send = dnet_send;
	netdev->recv = dnet_recv;

	dev_capa = readl(&dnet->regs->VERCAPS) & 0xFFFF;
	debug("%s: has %smdio, %sirq, %sgigabit, %sdma \n", netdev->name,
		(dev_capa & DNET_HAS_MDIO) ? "" : "no ",
		(dev_capa & DNET_HAS_IRQ) ? "" : "no ",
		(dev_capa & DNET_HAS_GIGABIT) ? "" : "no ",
		(dev_capa & DNET_HAS_DMA) ? "" : "no ");

	eth_register(netdev);

	return 0;
}
