// SPDX-License-Identifier: GPL-2.0+
/*
 * (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.
 */

#include <common.h>
#include <cpu_func.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)

/*
 * 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;
};

struct pcnet_uncached_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;
};

typedef struct pcnet_priv {
	struct pcnet_uncached_priv *uc;
	/* 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)
{
	void __iomem *base = (void __iomem *)dev->iobase;

	writew(index, base + PCNET_RAP);
	return readw(base + PCNET_RDP);
}

static void pcnet_write_csr(struct eth_device *dev, int index, u16 val)
{
	void __iomem *base = (void __iomem *)dev->iobase;

	writew(index, base + PCNET_RAP);
	writew(val, base + PCNET_RDP);
}

static u16 pcnet_read_bcr(struct eth_device *dev, int index)
{
	void __iomem *base = (void __iomem *)dev->iobase;

	writew(index, base + PCNET_RAP);
	return readw(base + PCNET_BDP);
}

static void pcnet_write_bcr(struct eth_device *dev, int index, u16 val)
{
	void __iomem *base = (void __iomem *)dev->iobase;

	writew(index, base + PCNET_RAP);
	writew(val, base + PCNET_BDP);
}

static void pcnet_reset(struct eth_device *dev)
{
	void __iomem *base = (void __iomem *)dev->iobase;

	readw(base + PCNET_RESET);
}

static int pcnet_check(struct eth_device *dev)
{
	void __iomem *base = (void __iomem *)dev->iobase;

	writew(88, base + PCNET_RAP);
	return readw(base + PCNET_RAP) == 88;
}

static int pcnet_init (struct eth_device *dev, bd_t * bis);
static int pcnet_send(struct eth_device *dev, 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);

static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev,
						void *addr)
{
	pci_dev_t devbusfn = (pci_dev_t)(unsigned long)dev->priv;
	void *virt_addr = addr;

	return pci_virt_to_mem(devbusfn, virt_addr);
}

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;
	u32 bar;

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

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

		/*
		 * Find the PCnet PCI device(s).
		 */
		devbusfn = pci_find_devices(supported, dev_nr);
		if (devbusfn < 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 *)(unsigned long)devbusfn;
		sprintf(dev->name, "pcnet#%d", dev_nr);

		/*
		 * Setup the PCI device.
		 */
		pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &bar);
		dev->iobase = pci_mem_to_phys(devbusfn, bar);
		dev->iobase &= ~0xf;

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

		command = PCI_COMMAND_MEMORY | 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;
	case 0x2625:
		chipname = "PCnet/FAST III 79C973";	/* PCI */
		break;
	case 0x2627:
		chipname = "PCnet/FAST III 79C975";	/* PCI */
		break;
	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)
{
	struct pcnet_uncached_priv *uc;
	int i, val;
	unsigned long addr;

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

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

	/* 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);

	/*
	 * Enable NOUFLO on supported controllers, with the transmit
	 * start point set to the full packet. This will cause entire
	 * packets to be buffered by the ethernet controller before
	 * transmission, eliminating underflows which are common on
	 * slower devices. Controllers which do not support NOUFLO will
	 * simply be left with a larger transmit FIFO threshold.
	 */
	val = pcnet_read_bcr(dev, 18);
	val |= 1 << 11;
	pcnet_write_bcr(dev, 18, val);
	val = pcnet_read_csr(dev, 80);
	val |= 0x3 << 10;
	pcnet_write_csr(dev, 80, 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 = (unsigned long)malloc(sizeof(pcnet_priv_t) + 0x10);
		addr = (addr + 0xf) & ~0xf;
		lp = (pcnet_priv_t *)addr;

		addr = (unsigned long)memalign(ARCH_DMA_MINALIGN,
					       sizeof(*lp->uc));
		flush_dcache_range(addr, addr + sizeof(*lp->uc));
		addr = (unsigned long)map_physmem(addr,
				roundup(sizeof(*lp->uc), ARCH_DMA_MINALIGN),
				MAP_NOCACHE);
		lp->uc = (struct pcnet_uncached_priv *)addr;

		addr = (unsigned long)memalign(ARCH_DMA_MINALIGN,
					       sizeof(*lp->rx_buf));
		flush_dcache_range(addr, addr + sizeof(*lp->rx_buf));
		lp->rx_buf = (void *)addr;
	}

	uc = lp->uc;

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

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

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

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

	uc->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS |
					       RX_RING_LEN_BITS);
	addr = pcnet_virt_to_mem(dev, uc->rx_ring);
	uc->init_block.rx_ring = cpu_to_le32(addr);
	addr = pcnet_virt_to_mem(dev, uc->tx_ring);
	uc->init_block.tx_ring = cpu_to_le32(addr);

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

	/*
	 * Tell the controller where the Init Block is located.
	 */
	barrier();
	addr = pcnet_virt_to_mem(dev, &lp->uc->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, void *packet, int pkt_len)
{
	int i, status;
	u32 addr;
	struct pcnet_tx_head *entry = &lp->uc->tx_ring[lp->cur_tx];

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

	flush_dcache_range((unsigned long)packet,
			   (unsigned long)packet + pkt_len);

	/* Wait for completion by testing the OWN bit */
	for (i = 1000; i > 0; i--) {
		status = readw(&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.
	 */
	addr = pcnet_virt_to_mem(dev, packet);
	writew(-pkt_len, &entry->length);
	writel(0, &entry->misc);
	writel(addr, &entry->base);
	writew(0x8300, &entry->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;
	unsigned char *buf;
	int pkt_len = 0;
	u16 status, err_status;

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

		if (err_status != 0x03) {	/* There was an error. */
			printf("%s: Rx%d", dev->name, lp->cur_rx);
			PCNET_DEBUG1(" (status=0x%x)", err_status);
			if (err_status & 0x20)
				printf(" Frame");
			if (err_status & 0x10)
				printf(" Overflow");
			if (err_status & 0x08)
				printf(" CRC");
			if (err_status & 0x04)
				printf(" Fifo");
			printf(" Error\n");
			status &= 0x03ff;

		} else {
			pkt_len = (readl(&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 {
				buf = (*lp->rx_buf)[lp->cur_rx];
				invalidate_dcache_range((unsigned long)buf,
					(unsigned long)buf + pkt_len);
				net_process_received_packet(buf, pkt_len);
				PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n",
					     lp->cur_rx, pkt_len, buf);
			}
		}

		status |= 0x8000;
		writew(status, &entry->status);

		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);
}
