/*
 * (C) Copyright 2002 Wolfgang Grandegger, wg@denx.de.
 *
 * This driver for AMD PCnet network controllers is derived from the
 * Linux driver pcnet32.c written 1996-1999 by Thomas Bogendoerfer.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <malloc.h>
#include <net.h>
#include <asm/io.h>
#include <pci.h>

#if 0
#define	PCNET_DEBUG_LEVEL	0	/* 0=off, 1=init, 2=rx/tx */
#endif

#if PCNET_DEBUG_LEVEL > 0
#define	PCNET_DEBUG1(fmt,args...)	printf (fmt ,##args)
#if PCNET_DEBUG_LEVEL > 1
#define	PCNET_DEBUG2(fmt,args...)	printf (fmt ,##args)
#else
#define PCNET_DEBUG2(fmt,args...)
#endif
#else
#define PCNET_DEBUG1(fmt,args...)
#define PCNET_DEBUG2(fmt,args...)
#endif

#if !defined(CONF_PCNET_79C973) && defined(CONF_PCNET_79C975)
#error "Macro for PCnet chip version is not defined!"
#endif

/*
 * Set the number of Tx and Rx buffers, using Log_2(# buffers).
 * Reasonable default values are 4 Tx buffers, and 16 Rx buffers.
 * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
 */
#define PCNET_LOG_TX_BUFFERS	0
#define PCNET_LOG_RX_BUFFERS	2

#define TX_RING_SIZE		(1 << (PCNET_LOG_TX_BUFFERS))
#define TX_RING_LEN_BITS	((PCNET_LOG_TX_BUFFERS) << 12)

#define RX_RING_SIZE		(1 << (PCNET_LOG_RX_BUFFERS))
#define RX_RING_LEN_BITS	((PCNET_LOG_RX_BUFFERS) << 4)

#define PKT_BUF_SZ		1544

/* The PCNET Rx and Tx ring descriptors. */
struct pcnet_rx_head {
	u32 base;
	s16 buf_length;
	s16 status;
	u32 msg_length;
	u32 reserved;
};

struct pcnet_tx_head {
	u32 base;
	s16 length;
	s16 status;
	u32 misc;
	u32 reserved;
};

/* The PCNET 32-Bit initialization block, described in databook. */
struct pcnet_init_block {
	u16 mode;
	u16 tlen_rlen;
	u8 phys_addr[6];
	u16 reserved;
	u32 filter[2];
	/* Receive and transmit ring base, along with extra bits. */
	u32 rx_ring;
	u32 tx_ring;
	u32 reserved2;
};

typedef struct pcnet_priv {
	struct pcnet_rx_head rx_ring[RX_RING_SIZE];
	struct pcnet_tx_head tx_ring[TX_RING_SIZE];
	struct pcnet_init_block init_block;
	/* Receive Buffer space */
	unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4];
	int cur_rx;
	int cur_tx;
} pcnet_priv_t;

static pcnet_priv_t *lp;

/* Offsets from base I/O address for WIO mode */
#define PCNET_RDP		0x10
#define PCNET_RAP		0x12
#define PCNET_RESET		0x14
#define PCNET_BDP		0x16

static u16 pcnet_read_csr (struct eth_device *dev, int index)
{
	outw (index, dev->iobase + PCNET_RAP);
	return inw (dev->iobase + PCNET_RDP);
}

static void pcnet_write_csr (struct eth_device *dev, int index, u16 val)
{
	outw (index, dev->iobase + PCNET_RAP);
	outw (val, dev->iobase + PCNET_RDP);
}

static u16 pcnet_read_bcr (struct eth_device *dev, int index)
{
	outw (index, dev->iobase + PCNET_RAP);
	return inw (dev->iobase + PCNET_BDP);
}

static void pcnet_write_bcr (struct eth_device *dev, int index, u16 val)
{
	outw (index, dev->iobase + PCNET_RAP);
	outw (val, dev->iobase + PCNET_BDP);
}

static void pcnet_reset (struct eth_device *dev)
{
	inw (dev->iobase + PCNET_RESET);
}

static int pcnet_check (struct eth_device *dev)
{
	outw (88, dev->iobase + PCNET_RAP);
	return (inw (dev->iobase + PCNET_RAP) == 88);
}

static int pcnet_init (struct eth_device *dev, bd_t * bis);
static int pcnet_send (struct eth_device *dev, volatile void *packet,
		       int length);
static int pcnet_recv (struct eth_device *dev);
static void pcnet_halt (struct eth_device *dev);
static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_num);

#define PCI_TO_MEM(d,a) pci_phys_to_mem((pci_dev_t)d->priv, (u_long)(a))
#define PCI_TO_MEM_LE(d,a) (u32)(cpu_to_le32(PCI_TO_MEM(d,a)))

static struct pci_device_id supported[] = {
	{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE},
	{}
};


int pcnet_initialize (bd_t * bis)
{
	pci_dev_t devbusfn;
	struct eth_device *dev;
	u16 command, status;
	int dev_nr = 0;

	PCNET_DEBUG1 ("\npcnet_initialize...\n");

	for (dev_nr = 0;; dev_nr++) {

		/*
		 * Find the PCnet PCI device(s).
		 */
		if ((devbusfn = pci_find_devices (supported, dev_nr)) < 0) {
			break;
		}

		/*
		 * Allocate and pre-fill the device structure.
		 */
		dev = (struct eth_device *) malloc (sizeof *dev);
		dev->priv = (void *) devbusfn;
		sprintf (dev->name, "pcnet#%d", dev_nr);

		/*
		 * Setup the PCI device.
		 */
		pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0,
				       (unsigned int *) &dev->iobase);
		dev->iobase=pci_io_to_phys (devbusfn, dev->iobase);
		dev->iobase &= ~0xf;

		PCNET_DEBUG1 ("%s: devbusfn=0x%x iobase=0x%x: ",
			      dev->name, devbusfn, dev->iobase);

		command = PCI_COMMAND_IO | PCI_COMMAND_MASTER;
		pci_write_config_word (devbusfn, PCI_COMMAND, command);
		pci_read_config_word (devbusfn, PCI_COMMAND, &status);
		if ((status & command) != command) {
			printf ("%s: Couldn't enable IO access or Bus Mastering\n", dev->name);
			free (dev);
			continue;
		}

		pci_write_config_byte (devbusfn, PCI_LATENCY_TIMER, 0x40);

		/*
		 * Probe the PCnet chip.
		 */
		if (pcnet_probe (dev, bis, dev_nr) < 0) {
			free (dev);
			continue;
		}

		/*
		 * Setup device structure and register the driver.
		 */
		dev->init = pcnet_init;
		dev->halt = pcnet_halt;
		dev->send = pcnet_send;
		dev->recv = pcnet_recv;

		eth_register (dev);
	}

	udelay (10 * 1000);

	return dev_nr;
}

static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr)
{
	int chip_version;
	char *chipname;

#ifdef PCNET_HAS_PROM
	int i;
#endif

	/* Reset the PCnet controller */
	pcnet_reset (dev);

	/* Check if register access is working */
	if (pcnet_read_csr (dev, 0) != 4 || !pcnet_check (dev)) {
		printf ("%s: CSR register access check failed\n", dev->name);
		return -1;
	}

	/* Identify the chip */
	chip_version =
		pcnet_read_csr (dev, 88) | (pcnet_read_csr (dev, 89) << 16);
	if ((chip_version & 0xfff) != 0x003)
		return -1;
	chip_version = (chip_version >> 12) & 0xffff;
	switch (chip_version) {
	case 0x2621:
		chipname = "PCnet/PCI II 79C970A";	/* PCI */
		break;
#ifdef CONFIG_PCNET_79C973
	case 0x2625:
		chipname = "PCnet/FAST III 79C973";	/* PCI */
		break;
#endif
#ifdef CONFIG_PCNET_79C975
	case 0x2627:
		chipname = "PCnet/FAST III 79C975";	/* PCI */
		break;
#endif
	default:
		printf ("%s: PCnet version %#x not supported\n",
			dev->name, chip_version);
		return -1;
	}

	PCNET_DEBUG1 ("AMD %s\n", chipname);

#ifdef PCNET_HAS_PROM
	/*
	 * In most chips, after a chip reset, the ethernet address is read from
	 * the station address PROM at the base address and programmed into the
	 * "Physical Address Registers" CSR12-14.
	 */
	for (i = 0; i < 3; i++) {
		unsigned int val;

		val = pcnet_read_csr (dev, i + 12) & 0x0ffff;
		/* There may be endianness issues here. */
		dev->enetaddr[2 * i] = val & 0x0ff;
		dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff;
	}
#endif /* PCNET_HAS_PROM */

	return 0;
}

static int pcnet_init (struct eth_device *dev, bd_t * bis)
{
	int i, val;
	u32 addr;

	PCNET_DEBUG1 ("%s: pcnet_init...\n", dev->name);

	/* Switch pcnet to 32bit mode */
	pcnet_write_bcr (dev, 20, 2);

#ifdef CONFIG_PN62
	/* Setup LED registers */
	val = pcnet_read_bcr (dev, 2) | 0x1000;
	pcnet_write_bcr (dev, 2, val);	/* enable LEDPE */
	pcnet_write_bcr (dev, 4, 0x5080);	/* 100MBit */
	pcnet_write_bcr (dev, 5, 0x40c0);	/* LNKSE */
	pcnet_write_bcr (dev, 6, 0x4090);	/* TX Activity */
	pcnet_write_bcr (dev, 7, 0x4084);	/* RX Activity */
#endif

	/* Set/reset autoselect bit */
	val = pcnet_read_bcr (dev, 2) & ~2;
	val |= 2;
	pcnet_write_bcr (dev, 2, val);

	/* Enable auto negotiate, setup, disable fd */
	val = pcnet_read_bcr (dev, 32) & ~0x98;
	val |= 0x20;
	pcnet_write_bcr (dev, 32, val);

	/*
	 * We only maintain one structure because the drivers will never
	 * be used concurrently. In 32bit mode the RX and TX ring entries
	 * must be aligned on 16-byte boundaries.
	 */
	if (lp == NULL) {
		addr = (u32) malloc (sizeof (pcnet_priv_t) + 0x10);
		addr = (addr + 0xf) & ~0xf;
		lp = (pcnet_priv_t *) addr;
	}

	lp->init_block.mode = cpu_to_le16 (0x0000);
	lp->init_block.filter[0] = 0x00000000;
	lp->init_block.filter[1] = 0x00000000;

	/*
	 * Initialize the Rx ring.
	 */
	lp->cur_rx = 0;
	for (i = 0; i < RX_RING_SIZE; i++) {
		lp->rx_ring[i].base = PCI_TO_MEM_LE (dev, lp->rx_buf[i]);
		lp->rx_ring[i].buf_length = cpu_to_le16 (-PKT_BUF_SZ);
		lp->rx_ring[i].status = cpu_to_le16 (0x8000);
		PCNET_DEBUG1
			("Rx%d: base=0x%x buf_length=0x%hx status=0x%hx\n", i,
			 lp->rx_ring[i].base, lp->rx_ring[i].buf_length,
			 lp->rx_ring[i].status);
	}

	/*
	 * Initialize the Tx ring. The Tx buffer address is filled in as
	 * needed, but we do need to clear the upper ownership bit.
	 */
	lp->cur_tx = 0;
	for (i = 0; i < TX_RING_SIZE; i++) {
		lp->tx_ring[i].base = 0;
		lp->tx_ring[i].status = 0;
	}

	/*
	 * Setup Init Block.
	 */
	PCNET_DEBUG1 ("Init block at 0x%p: MAC", &lp->init_block);

	for (i = 0; i < 6; i++) {
		lp->init_block.phys_addr[i] = dev->enetaddr[i];
		PCNET_DEBUG1 (" %02x", lp->init_block.phys_addr[i]);
	}

	lp->init_block.tlen_rlen = cpu_to_le16 (TX_RING_LEN_BITS |
						RX_RING_LEN_BITS);
	lp->init_block.rx_ring = PCI_TO_MEM_LE (dev, lp->rx_ring);
	lp->init_block.tx_ring = PCI_TO_MEM_LE (dev, lp->tx_ring);

	PCNET_DEBUG1 ("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n",
		      lp->init_block.tlen_rlen,
		      lp->init_block.rx_ring, lp->init_block.tx_ring);

	/*
	 * Tell the controller where the Init Block is located.
	 */
	addr = PCI_TO_MEM (dev, &lp->init_block);
	pcnet_write_csr (dev, 1, addr & 0xffff);
	pcnet_write_csr (dev, 2, (addr >> 16) & 0xffff);

	pcnet_write_csr (dev, 4, 0x0915);
	pcnet_write_csr (dev, 0, 0x0001);	/* start */

	/* Wait for Init Done bit */
	for (i = 10000; i > 0; i--) {
		if (pcnet_read_csr (dev, 0) & 0x0100)
			break;
		udelay (10);
	}
	if (i <= 0) {
		printf ("%s: TIMEOUT: controller init failed\n", dev->name);
		pcnet_reset (dev);
		return -1;
	}

	/*
	 * Finally start network controller operation.
	 */
	pcnet_write_csr (dev, 0, 0x0002);

	return 0;
}

static int pcnet_send (struct eth_device *dev, volatile void *packet,
		       int pkt_len)
{
	int i, status;
	struct pcnet_tx_head *entry = &lp->tx_ring[lp->cur_tx];

	PCNET_DEBUG2 ("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len,
		      packet);

	/* Wait for completion by testing the OWN bit */
	for (i = 1000; i > 0; i--) {
		status = le16_to_cpu (entry->status);
		if ((status & 0x8000) == 0)
			break;
		udelay (100);
		PCNET_DEBUG2 (".");
	}
	if (i <= 0) {
		printf ("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n",
			dev->name, lp->cur_tx, status);
		pkt_len = 0;
		goto failure;
	}

	/*
	 * Setup Tx ring. Caution: the write order is important here,
	 * set the status with the "ownership" bits last.
	 */
	status = 0x8300;
	entry->length = le16_to_cpu (-pkt_len);
	entry->misc = 0x00000000;
	entry->base = PCI_TO_MEM_LE (dev, packet);
	entry->status = le16_to_cpu (status);

	/* Trigger an immediate send poll. */
	pcnet_write_csr (dev, 0, 0x0008);

      failure:
	if (++lp->cur_tx >= TX_RING_SIZE)
		lp->cur_tx = 0;

	PCNET_DEBUG2 ("done\n");
	return pkt_len;
}

static int pcnet_recv (struct eth_device *dev)
{
	struct pcnet_rx_head *entry;
	int pkt_len = 0;
	u16 status;

	while (1) {
		entry = &lp->rx_ring[lp->cur_rx];
		/*
		 * If we own the next entry, it's a new packet. Send it up.
		 */
		if (((status = le16_to_cpu (entry->status)) & 0x8000) != 0) {
			break;
		}
		status >>= 8;

		if (status != 0x03) {	/* There was an error. */

			printf ("%s: Rx%d", dev->name, lp->cur_rx);
			PCNET_DEBUG1 (" (status=0x%x)", status);
			if (status & 0x20)
				printf (" Frame");
			if (status & 0x10)
				printf (" Overflow");
			if (status & 0x08)
				printf (" CRC");
			if (status & 0x04)
				printf (" Fifo");
			printf (" Error\n");
			entry->status &= le16_to_cpu (0x03ff);

		} else {

			pkt_len =
				(le32_to_cpu (entry->msg_length) & 0xfff) - 4;
			if (pkt_len < 60) {
				printf ("%s: Rx%d: invalid packet length %d\n", dev->name, lp->cur_rx, pkt_len);
			} else {
				NetReceive (lp->rx_buf[lp->cur_rx], pkt_len);
				PCNET_DEBUG2 ("Rx%d: %d bytes from 0x%p\n",
					      lp->cur_rx, pkt_len,
					      lp->rx_buf[lp->cur_rx]);
			}
		}
		entry->status |= cpu_to_le16 (0x8000);

		if (++lp->cur_rx >= RX_RING_SIZE)
			lp->cur_rx = 0;
	}
	return pkt_len;
}

static void pcnet_halt (struct eth_device *dev)
{
	int i;

	PCNET_DEBUG1 ("%s: pcnet_halt...\n", dev->name);

	/* Reset the PCnet controller */
	pcnet_reset (dev);

	/* Wait for Stop bit */
	for (i = 1000; i > 0; i--) {
		if (pcnet_read_csr (dev, 0) & 0x4)
			break;
		udelay (10);
	}
	if (i <= 0) {
		printf ("%s: TIMEOUT: controller reset failed\n", dev->name);
	}
}
