/*
 * (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 <netdev.h>
#include <asm/io.h>
#include <pci.h>

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

#define PCNET_DEBUG1(fmt,args...)	\
	debug_cond(PCNET_DEBUG_LEVEL > 0, fmt ,##args)
#define PCNET_DEBUG2(fmt,args...)	\
	debug_cond(PCNET_DEBUG_LEVEL > 1, fmt ,##args)

#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);
		if (!dev) {
			printf("pcnet: Can not allocate memory\n");
			break;
		}
		memset(dev, 0, 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);
	}
}
