/*
 * 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 <asm/unaligned.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, void *packet, int length)
{
	struct dnet_device *dnet = to_dnet(netdev);
	int i, wrsz;
	unsigned int *bufp;
	unsigned int tx_cmd;

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

	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 = get_unaligned_be16(netdev->enetaddr);
	dnet_writew_mac(dnet, DNET_INTERNAL_MAC_ADDR_0_REG, tmp);
	tmp = get_unaligned_be16(&netdev->enetaddr[2]);
	dnet_writew_mac(dnet, DNET_INTERNAL_MAC_ADDR_1_REG, tmp);
	tmp = get_unaligned_be16(&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;
}
