/*
 * (C) Copyright 2010
 * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de
 * Martin Krause, Martin.Krause@tqs.de
 * reworked original enc28j60.c
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <net.h>
#include <spi.h>
#include <malloc.h>
#include <netdev.h>
#include <miiphy.h>
#include "enc28j60.h"

/*
 * IMPORTANT: spi_claim_bus() and spi_release_bus()
 * are called at begin and end of each of the following functions:
 * enc_miiphy_read(), enc_miiphy_write(), enc_write_hwaddr(),
 * enc_init(), enc_recv(), enc_send(), enc_halt()
 * ALL other functions assume that the bus has already been claimed!
 * Since NetReceive() might call enc_send() in return, the bus must be
 * released, NetReceive() called and claimed again.
 */

/*
 * Controller memory layout.
 * We only allow 1 frame for transmission and reserve the rest
 * for reception to handle as many broadcast packets as possible.
 * Also use the memory from 0x0000 for receiver buffer. See errata pt. 5
 * 0x0000 - 0x19ff 6656 bytes receive buffer
 * 0x1a00 - 0x1fff 1536 bytes transmit buffer =
 * control(1)+frame(1518)+status(7)+reserve(10).
 */
#define ENC_RX_BUF_START	0x0000
#define ENC_RX_BUF_END		0x19ff
#define ENC_TX_BUF_START	0x1a00
#define ENC_TX_BUF_END		0x1fff
#define ENC_MAX_FRM_LEN		1518
#define RX_RESET_COUNTER	1000

/*
 * For non data transfer functions, like phy read/write, set hwaddr, init
 * we do not need a full, time consuming init including link ready wait.
 * This enum helps to bring the chip through the minimum necessary inits.
 */
enum enc_initstate {none=0, setupdone, linkready};
typedef struct enc_device {
	struct eth_device	*dev;	/* back pointer */
	struct spi_slave	*slave;
	int			rx_reset_counter;
	u16			next_pointer;
	u8			bank;	/* current bank in enc28j60 */
	enum enc_initstate	initstate;
} enc_dev_t;

/*
 * enc_bset:		set bits in a common register
 * enc_bclr:		clear bits in a common register
 *
 * making the reg parameter u8 will give a compile time warning if the
 * functions are called with a register not accessible in all Banks
 */
static void enc_bset(enc_dev_t *enc, const u8 reg, const u8 data)
{
	u8 dout[2];

	dout[0] = CMD_BFS(reg);
	dout[1] = data;
	spi_xfer(enc->slave, 2 * 8, dout, NULL,
		SPI_XFER_BEGIN | SPI_XFER_END);
}

static void enc_bclr(enc_dev_t *enc, const u8 reg, const u8 data)
{
	u8 dout[2];

	dout[0] = CMD_BFC(reg);
	dout[1] = data;
	spi_xfer(enc->slave, 2 * 8, dout, NULL,
		SPI_XFER_BEGIN | SPI_XFER_END);
}

/*
 * high byte of the register contains bank number:
 * 0: no bank switch necessary
 * 1: switch to bank 0
 * 2: switch to bank 1
 * 3: switch to bank 2
 * 4: switch to bank 3
 */
static void enc_set_bank(enc_dev_t *enc, const u16 reg)
{
	u8 newbank = reg >> 8;

	if (newbank == 0 || newbank == enc->bank)
		return;
	switch (newbank) {
	case 1:
		enc_bclr(enc, CTL_REG_ECON1,
			ENC_ECON1_BSEL0 | ENC_ECON1_BSEL1);
		break;
	case 2:
		enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_BSEL0);
		enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_BSEL1);
		break;
	case 3:
		enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_BSEL0);
		enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_BSEL1);
		break;
	case 4:
		enc_bset(enc, CTL_REG_ECON1,
			ENC_ECON1_BSEL0 | ENC_ECON1_BSEL1);
		break;
	}
	enc->bank = newbank;
}

/*
 * local functions to access SPI
 *
 * reg: register inside ENC28J60
 * data: 8/16 bits to write
 * c: number of retries
 *
 * enc_r8:		read 8 bits
 * enc_r16:		read 16 bits
 * enc_w8:		write 8 bits
 * enc_w16:		write 16 bits
 * enc_w8_retry:	write 8 bits, verify and retry
 * enc_rbuf:		read from ENC28J60 into buffer
 * enc_wbuf:		write from buffer into ENC28J60
 */

/*
 * MAC and MII registers need a 3 byte SPI transfer to read,
 * all other registers need a 2 byte SPI transfer.
 */
static int enc_reg2nbytes(const u16 reg)
{
	/* check if MAC or MII register */
	return ((reg >= CTL_REG_MACON1 && reg <= CTL_REG_MIRDH) ||
		(reg >= CTL_REG_MAADR1 && reg <= CTL_REG_MAADR4) ||
		(reg == CTL_REG_MISTAT)) ? 3 : 2;
}

/*
 * Read a byte register
 */
static u8 enc_r8(enc_dev_t *enc, const u16 reg)
{
	u8 dout[3];
	u8 din[3];
	int nbytes = enc_reg2nbytes(reg);

	enc_set_bank(enc, reg);
	dout[0] = CMD_RCR(reg);
	spi_xfer(enc->slave, nbytes * 8, dout, din,
		SPI_XFER_BEGIN | SPI_XFER_END);
	return din[nbytes-1];
}

/*
 * Read a L/H register pair and return a word.
 * Must be called with the L register's address.
 */
static u16 enc_r16(enc_dev_t *enc, const u16 reg)
{
	u8 dout[3];
	u8 din[3];
	u16 result;
	int nbytes = enc_reg2nbytes(reg);

	enc_set_bank(enc, reg);
	dout[0] = CMD_RCR(reg);
	spi_xfer(enc->slave, nbytes * 8, dout, din,
		SPI_XFER_BEGIN | SPI_XFER_END);
	result = din[nbytes-1];
	dout[0]++; /* next register */
	spi_xfer(enc->slave, nbytes * 8, dout, din,
		SPI_XFER_BEGIN | SPI_XFER_END);
	result |= din[nbytes-1] << 8;
	return result;
}

/*
 * Write a byte register
 */
static void enc_w8(enc_dev_t *enc, const u16 reg, const u8 data)
{
	u8 dout[2];

	enc_set_bank(enc, reg);
	dout[0] = CMD_WCR(reg);
	dout[1] = data;
	spi_xfer(enc->slave, 2 * 8, dout, NULL,
		SPI_XFER_BEGIN | SPI_XFER_END);
}

/*
 * Write a L/H register pair.
 * Must be called with the L register's address.
 */
static void enc_w16(enc_dev_t *enc, const u16 reg, const u16 data)
{
	u8 dout[2];

	enc_set_bank(enc, reg);
	dout[0] = CMD_WCR(reg);
	dout[1] = data;
	spi_xfer(enc->slave, 2 * 8, dout, NULL,
		SPI_XFER_BEGIN | SPI_XFER_END);
	dout[0]++; /* next register */
	dout[1] = data >> 8;
	spi_xfer(enc->slave, 2 * 8, dout, NULL,
		SPI_XFER_BEGIN | SPI_XFER_END);
}

/*
 * Write a byte register, verify and retry
 */
static void enc_w8_retry(enc_dev_t *enc, const u16 reg, const u8 data, const int c)
{
	u8 dout[2];
	u8 readback;
	int i;

	enc_set_bank(enc, reg);
	for (i = 0; i < c; i++) {
		dout[0] = CMD_WCR(reg);
		dout[1] = data;
		spi_xfer(enc->slave, 2 * 8, dout, NULL,
			SPI_XFER_BEGIN | SPI_XFER_END);
		readback = enc_r8(enc, reg);
		if (readback == data)
			break;
		/* wait 1ms */
		udelay(1000);
	}
	if (i == c) {
		printf("%s: write reg 0x%03x failed\n", enc->dev->name, reg);
	}
}

/*
 * Read ENC RAM into buffer
 */
static void enc_rbuf(enc_dev_t *enc, const u16 length, u8 *buf)
{
	u8 dout[1];

	dout[0] = CMD_RBM;
	spi_xfer(enc->slave, 8, dout, NULL, SPI_XFER_BEGIN);
	spi_xfer(enc->slave, length * 8, NULL, buf, SPI_XFER_END);
#ifdef DEBUG
	puts("Rx:\n");
	print_buffer(0, buf, 1, length, 0);
#endif
}

/*
 * Write buffer into ENC RAM
 */
static void enc_wbuf(enc_dev_t *enc, const u16 length, const u8 *buf, const u8 control)
{
	u8 dout[2];
	dout[0] = CMD_WBM;
	dout[1] = control;
	spi_xfer(enc->slave, 2 * 8, dout, NULL, SPI_XFER_BEGIN);
	spi_xfer(enc->slave, length * 8, buf, NULL, SPI_XFER_END);
#ifdef DEBUG
	puts("Tx:\n");
	print_buffer(0, buf, 1, length, 0);
#endif
}

/*
 * Try to claim the SPI bus.
 * Print error message on failure.
 */
static int enc_claim_bus(enc_dev_t *enc)
{
	int rc = spi_claim_bus(enc->slave);
	if (rc)
		printf("%s: failed to claim SPI bus\n", enc->dev->name);
	return rc;
}

/*
 * Release previously claimed SPI bus.
 * This function is mainly for symmetry to enc_claim_bus().
 * Let the toolchain decide to inline it...
 */
static void enc_release_bus(enc_dev_t *enc)
{
	spi_release_bus(enc->slave);
}

/*
 * Read PHY register
 */
static u16 enc_phy_read(enc_dev_t *enc, const u8 addr)
{
	uint64_t etime;
	u8 status;

	enc_w8(enc, CTL_REG_MIREGADR, addr);
	enc_w8(enc, CTL_REG_MICMD, ENC_MICMD_MIIRD);
	/* 1 second timeout - only happens on hardware problem */
	etime = get_ticks() + get_tbclk();
	/* poll MISTAT.BUSY bit until operation is complete */
	do
	{
		status = enc_r8(enc, CTL_REG_MISTAT);
	} while (get_ticks() <= etime && (status & ENC_MISTAT_BUSY));
	if (status & ENC_MISTAT_BUSY) {
		printf("%s: timeout reading phy\n", enc->dev->name);
		return 0;
	}
	enc_w8(enc, CTL_REG_MICMD, 0);
	return enc_r16(enc, CTL_REG_MIRDL);
}

/*
 * Write PHY register
 */
static void enc_phy_write(enc_dev_t *enc, const u8 addr, const u16 data)
{
	uint64_t etime;
	u8 status;

	enc_w8(enc, CTL_REG_MIREGADR, addr);
	enc_w16(enc, CTL_REG_MIWRL, data);
	/* 1 second timeout - only happens on hardware problem */
	etime = get_ticks() + get_tbclk();
	/* poll MISTAT.BUSY bit until operation is complete */
	do
	{
		status = enc_r8(enc, CTL_REG_MISTAT);
	} while (get_ticks() <= etime && (status & ENC_MISTAT_BUSY));
	if (status & ENC_MISTAT_BUSY) {
		printf("%s: timeout writing phy\n", enc->dev->name);
		return;
	}
}

/*
 * Verify link status, wait if necessary
 *
 * Note: with a 10 MBit/s only PHY there is no autonegotiation possible,
 * half/full duplex is a pure setup matter. For the time being, this driver
 * will setup in half duplex mode only.
 */
static int enc_phy_link_wait(enc_dev_t *enc)
{
	u16 status;
	int duplex;
	uint64_t etime;

#ifdef CONFIG_ENC_SILENTLINK
	/* check if we have a link, then just return */
	status = enc_phy_read(enc, PHY_REG_PHSTAT1);
	if (status & ENC_PHSTAT1_LLSTAT)
		return 0;
#endif

	/* wait for link with 1 second timeout */
	etime = get_ticks() + get_tbclk();
	while (get_ticks() <= etime) {
		status = enc_phy_read(enc, PHY_REG_PHSTAT1);
		if (status & ENC_PHSTAT1_LLSTAT) {
			/* now we have a link */
			status = enc_phy_read(enc, PHY_REG_PHSTAT2);
			duplex = (status & ENC_PHSTAT2_DPXSTAT) ? 1 : 0;
			printf("%s: link up, 10Mbps %s-duplex\n",
				enc->dev->name, duplex ? "full" : "half");
			return 0;
		}
		udelay(1000);
	}

	/* timeout occured */
	printf("%s: link down\n", enc->dev->name);
	return 1;
}

/*
 * This function resets the receiver only.
 */
static void enc_reset_rx(enc_dev_t *enc)
{
	u8 econ1;

	econ1 = enc_r8(enc, CTL_REG_ECON1);
	if ((econ1 & ENC_ECON1_RXRST) == 0) {
		enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_RXRST);
		enc->rx_reset_counter = RX_RESET_COUNTER;
	}
}

/*
 * Reset receiver and reenable it.
 */
static void enc_reset_rx_call(enc_dev_t *enc)
{
	enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_RXRST);
	enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_RXEN);
}

/*
 * Copy a packet from the receive ring and forward it to
 * the protocol stack.
 */
static void enc_receive(enc_dev_t *enc)
{
	u8 *packet = (u8 *)NetRxPackets[0];
	u16 pkt_len;
	u16 copy_len;
	u16 status;
	u8 pkt_cnt = 0;
	u16 rxbuf_rdpt;
	u8 hbuf[6];

	enc_w16(enc, CTL_REG_ERDPTL, enc->next_pointer);
	do {
		enc_rbuf(enc, 6, hbuf);
		enc->next_pointer = hbuf[0] | (hbuf[1] << 8);
		pkt_len = hbuf[2] | (hbuf[3] << 8);
		status = hbuf[4] | (hbuf[5] << 8);
		debug("next_pointer=$%04x pkt_len=%u status=$%04x\n",
			enc->next_pointer, pkt_len, status);
		if (pkt_len <= ENC_MAX_FRM_LEN)
			copy_len = pkt_len;
		else
			copy_len = 0;
		if ((status & (1L << 7)) == 0) /* check Received Ok bit */
			copy_len = 0;
		/* check if next pointer is resonable */
		if (enc->next_pointer >= ENC_TX_BUF_START)
			copy_len = 0;
		if (copy_len > 0) {
			enc_rbuf(enc, copy_len, packet);
		}
		/* advance read pointer to next pointer */
		enc_w16(enc, CTL_REG_ERDPTL, enc->next_pointer);
		/* decrease packet counter */
		enc_bset(enc, CTL_REG_ECON2, ENC_ECON2_PKTDEC);
		/*
		 * Only odd values should be written to ERXRDPTL,
		 * see errata B4 pt.13
		 */
		rxbuf_rdpt = enc->next_pointer - 1;
		if ((rxbuf_rdpt < enc_r16(enc, CTL_REG_ERXSTL)) ||
			(rxbuf_rdpt > enc_r16(enc, CTL_REG_ERXNDL))) {
			enc_w16(enc, CTL_REG_ERXRDPTL,
				enc_r16(enc, CTL_REG_ERXNDL));
		} else {
			enc_w16(enc, CTL_REG_ERXRDPTL, rxbuf_rdpt);
		}
		/* read pktcnt */
		pkt_cnt = enc_r8(enc, CTL_REG_EPKTCNT);
		if (copy_len == 0) {
			(void)enc_r8(enc, CTL_REG_EIR);
			enc_reset_rx(enc);
			printf("%s: receive copy_len=0\n", enc->dev->name);
			continue;
		}
		/*
		 * Because NetReceive() might call enc_send(), we need to
		 * release the SPI bus, call NetReceive(), reclaim the bus
		 */
		enc_release_bus(enc);
		NetReceive(packet, pkt_len);
		if (enc_claim_bus(enc))
			return;
		(void)enc_r8(enc, CTL_REG_EIR);
	} while (pkt_cnt);
	/* Use EPKTCNT not EIR.PKTIF flag, see errata pt. 6 */
}

/*
 * Poll for completely received packets.
 */
static void enc_poll(enc_dev_t *enc)
{
	u8 eir_reg;
	u8 pkt_cnt;

#ifdef CONFIG_USE_IRQ
	/* clear global interrupt enable bit in enc28j60 */
	enc_bclr(enc, CTL_REG_EIE, ENC_EIE_INTIE);
#endif
	(void)enc_r8(enc, CTL_REG_ESTAT);
	eir_reg = enc_r8(enc, CTL_REG_EIR);
	if (eir_reg & ENC_EIR_TXIF) {
		/* clear TXIF bit in EIR */
		enc_bclr(enc, CTL_REG_EIR, ENC_EIR_TXIF);
	}
	/* We have to use pktcnt and not pktif bit, see errata pt. 6 */
	pkt_cnt = enc_r8(enc, CTL_REG_EPKTCNT);
	if (pkt_cnt > 0) {
		if ((eir_reg & ENC_EIR_PKTIF) == 0) {
			debug("enc_poll: pkt cnt > 0, but pktif not set\n");
		}
		enc_receive(enc);
		/*
		 * clear PKTIF bit in EIR, this should not need to be done
		 * but it seems like we get problems if we do not
		 */
		enc_bclr(enc, CTL_REG_EIR, ENC_EIR_PKTIF);
	}
	if (eir_reg & ENC_EIR_RXERIF) {
		printf("%s: rx error\n", enc->dev->name);
		enc_bclr(enc, CTL_REG_EIR, ENC_EIR_RXERIF);
	}
	if (eir_reg & ENC_EIR_TXERIF) {
		printf("%s: tx error\n", enc->dev->name);
		enc_bclr(enc, CTL_REG_EIR, ENC_EIR_TXERIF);
	}
#ifdef CONFIG_USE_IRQ
	/* set global interrupt enable bit in enc28j60 */
	enc_bset(enc, CTL_REG_EIE, ENC_EIE_INTIE);
#endif
}

/*
 * Completely Reset the ENC
 */
static void enc_reset(enc_dev_t *enc)
{
	u8 dout[1];

	dout[0] = CMD_SRC;
	spi_xfer(enc->slave, 8, dout, NULL,
		SPI_XFER_BEGIN | SPI_XFER_END);
	/* sleep 1 ms. See errata pt. 2 */
	udelay(1000);
}

/*
 * Initialisation data for most of the ENC registers
 */
static const u16 enc_initdata[] = {
	/*
	 * Setup the buffer space. The reset values are valid for the
	 * other pointers.
	 *
	 * We shall not write to ERXST, see errata pt. 5. Instead we
	 * have to make sure that ENC_RX_BUS_START is 0.
	 */
	CTL_REG_ERXSTL, ENC_RX_BUF_START,
	CTL_REG_ERXSTH, ENC_RX_BUF_START >> 8,
	CTL_REG_ERXNDL, ENC_RX_BUF_END,
	CTL_REG_ERXNDH, ENC_RX_BUF_END >> 8,
	CTL_REG_ERDPTL, ENC_RX_BUF_START,
	CTL_REG_ERDPTH, ENC_RX_BUF_START >> 8,
	/*
	 * Set the filter to receive only good-CRC, unicast and broadcast
	 * frames.
	 * Note: some DHCP servers return their answers as broadcasts!
	 * So its unwise to remove broadcast from this. This driver
	 * might incur receiver overruns with packet loss on a broadcast
	 * flooded network.
	 */
	CTL_REG_ERXFCON, ENC_RFR_BCEN | ENC_RFR_UCEN | ENC_RFR_CRCEN,

	/* enable MAC to receive frames */
	CTL_REG_MACON1,
		ENC_MACON1_MARXEN | ENC_MACON1_TXPAUS | ENC_MACON1_RXPAUS,

	/* configure pad, tx-crc and duplex */
	CTL_REG_MACON3,
		ENC_MACON3_PADCFG0 | ENC_MACON3_TXCRCEN |
		ENC_MACON3_FRMLNEN,

	/* Allow infinite deferals if the medium is continously busy */
	CTL_REG_MACON4, ENC_MACON4_DEFER,

	/* Late collisions occur beyond 63 bytes */
	CTL_REG_MACLCON2, 63,

	/*
	 * Set (low byte) Non-Back-to_Back Inter-Packet Gap.
	 * Recommended 0x12
	 */
	CTL_REG_MAIPGL, 0x12,

	/*
	 * Set (high byte) Non-Back-to_Back Inter-Packet Gap.
	 * Recommended 0x0c for half-duplex. Nothing for full-duplex
	 */
	CTL_REG_MAIPGH, 0x0C,

	/* set maximum frame length */
	CTL_REG_MAMXFLL, ENC_MAX_FRM_LEN,
	CTL_REG_MAMXFLH, ENC_MAX_FRM_LEN >> 8,

	/*
	 * Set MAC back-to-back inter-packet gap.
	 * Recommended 0x12 for half duplex
	 * and 0x15 for full duplex.
	 */
	CTL_REG_MABBIPG, 0x12,

	/* end of table */
	0xffff
};

/*
 * Wait for the XTAL oscillator to become ready
 */
static int enc_clock_wait(enc_dev_t *enc)
{
	uint64_t etime;

	/* one second timeout */
	etime = get_ticks() + get_tbclk();

	/*
	 * Wait for CLKRDY to become set (i.e., check that we can
	 * communicate with the ENC)
	 */
	do
	{
		if (enc_r8(enc, CTL_REG_ESTAT) & ENC_ESTAT_CLKRDY)
			return 0;
	} while (get_ticks() <= etime);

	printf("%s: timeout waiting for CLKRDY\n", enc->dev->name);
	return -1;
}

/*
 * Write the MAC address into the ENC
 */
static int enc_write_macaddr(enc_dev_t *enc)
{
	unsigned char *p = enc->dev->enetaddr;

	enc_w8_retry(enc, CTL_REG_MAADR5, *p++, 5);
	enc_w8_retry(enc, CTL_REG_MAADR4, *p++, 5);
	enc_w8_retry(enc, CTL_REG_MAADR3, *p++, 5);
	enc_w8_retry(enc, CTL_REG_MAADR2, *p++, 5);
	enc_w8_retry(enc, CTL_REG_MAADR1, *p++, 5);
	enc_w8_retry(enc, CTL_REG_MAADR0, *p, 5);
	return 0;
}

/*
 * Setup most of the ENC registers
 */
static int enc_setup(enc_dev_t *enc)
{
	u16 phid1 = 0;
	u16 phid2 = 0;
	const u16 *tp;

	/* reset enc struct values */
	enc->next_pointer = ENC_RX_BUF_START;
	enc->rx_reset_counter = RX_RESET_COUNTER;
	enc->bank = 0xff;	/* invalidate current bank in enc28j60 */

	/* verify PHY identification */
	phid1 = enc_phy_read(enc, PHY_REG_PHID1);
	phid2 = enc_phy_read(enc, PHY_REG_PHID2) & ENC_PHID2_MASK;
	if (phid1 != ENC_PHID1_VALUE || phid2 != ENC_PHID2_VALUE) {
		printf("%s: failed to identify PHY. Found %04x:%04x\n",
			enc->dev->name, phid1, phid2);
		return -1;
	}

	/* now program registers */
	for (tp = enc_initdata; *tp != 0xffff; tp += 2)
		enc_w8_retry(enc, tp[0], tp[1], 10);

	/*
	 * Prevent automatic loopback of data beeing transmitted by setting
	 * ENC_PHCON2_HDLDIS
	 */
	enc_phy_write(enc, PHY_REG_PHCON2, (1<<8));

	/*
	 * LEDs configuration
	 * LEDA: LACFG = 0100 -> display link status
	 * LEDB: LBCFG = 0111 -> display TX & RX activity
	 * STRCH = 1 -> LED pulses
	 */
	enc_phy_write(enc, PHY_REG_PHLCON, 0x0472);

	/* Reset PDPXMD-bit => half duplex */
	enc_phy_write(enc, PHY_REG_PHCON1, 0);

#ifdef CONFIG_USE_IRQ
	/* enable interrupts */
	enc_bset(enc, CTL_REG_EIE, ENC_EIE_PKTIE);
	enc_bset(enc, CTL_REG_EIE, ENC_EIE_TXIE);
	enc_bset(enc, CTL_REG_EIE, ENC_EIE_RXERIE);
	enc_bset(enc, CTL_REG_EIE, ENC_EIE_TXERIE);
	enc_bset(enc, CTL_REG_EIE, ENC_EIE_INTIE);
#endif

	return 0;
}

/*
 * Check if ENC has been initialized.
 * If not, try to initialize it.
 * Remember initialized state in struct.
 */
static int enc_initcheck(enc_dev_t *enc, const enum enc_initstate requiredstate)
{
	if (enc->initstate >= requiredstate)
		return 0;

	if (enc->initstate < setupdone) {
		/* Initialize the ENC only */
		enc_reset(enc);
		/* if any of functions fails, skip the rest and return an error */
		if (enc_clock_wait(enc) || enc_setup(enc) || enc_write_macaddr(enc)) {
			return -1;
		}
		enc->initstate = setupdone;
	}
	/* if that's all we need, return here */
	if (enc->initstate >= requiredstate)
		return 0;

	/* now wait for link ready condition */
	if (enc_phy_link_wait(enc)) {
		return -1;
	}
	enc->initstate = linkready;
	return 0;
}

#if defined(CONFIG_CMD_MII)
/*
 * Read a PHY register.
 *
 * This function is registered with miiphy_register().
 */
int enc_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value)
{
	struct eth_device *dev = eth_get_dev_by_name(devname);
	enc_dev_t *enc;

	if (!dev || phy_adr != 0)
		return -1;

	enc = dev->priv;
	if (enc_claim_bus(enc))
		return -1;
	if (enc_initcheck(enc, setupdone)) {
		enc_release_bus(enc);
		return -1;
	}
	*value = enc_phy_read(enc, reg);
	enc_release_bus(enc);
	return 0;
}

/*
 * Write a PHY register.
 *
 * This function is registered with miiphy_register().
 */
int enc_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value)
{
	struct eth_device *dev = eth_get_dev_by_name(devname);
	enc_dev_t *enc;

	if (!dev || phy_adr != 0)
		return -1;

	enc = dev->priv;
	if (enc_claim_bus(enc))
		return -1;
	if (enc_initcheck(enc, setupdone)) {
		enc_release_bus(enc);
		return -1;
	}
	enc_phy_write(enc, reg, value);
	enc_release_bus(enc);
	return 0;
}
#endif

/*
 * Write hardware (MAC) address.
 *
 * This function entered into eth_device structure.
 */
static int enc_write_hwaddr(struct eth_device *dev)
{
	enc_dev_t *enc = dev->priv;

	if (enc_claim_bus(enc))
		return -1;
	if (enc_initcheck(enc, setupdone)) {
		enc_release_bus(enc);
		return -1;
	}
	enc_release_bus(enc);
	return 0;
}

/*
 * Initialize ENC28J60 for use.
 *
 * This function entered into eth_device structure.
 */
static int enc_init(struct eth_device *dev, bd_t *bis)
{
	enc_dev_t *enc = dev->priv;

	if (enc_claim_bus(enc))
		return -1;
	if (enc_initcheck(enc, linkready)) {
		enc_release_bus(enc);
		return -1;
	}
	/* enable receive */
	enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_RXEN);
	enc_release_bus(enc);
	return 0;
}

/*
 * Check for received packets.
 *
 * This function entered into eth_device structure.
 */
static int enc_recv(struct eth_device *dev)
{
	enc_dev_t *enc = dev->priv;

	if (enc_claim_bus(enc))
		return -1;
	if (enc_initcheck(enc, linkready)) {
		enc_release_bus(enc);
		return -1;
	}
	/* Check for dead receiver */
	if (enc->rx_reset_counter > 0)
		enc->rx_reset_counter--;
	else
		enc_reset_rx_call(enc);
	enc_poll(enc);
	enc_release_bus(enc);
	return 0;
}

/*
 * Send a packet.
 *
 * This function entered into eth_device structure.
 *
 * Should we wait here until we have a Link? Or shall we leave that to
 * protocol retries?
 */
static int enc_send(
	struct eth_device *dev,
	void *packet,
	int length)
{
	enc_dev_t *enc = dev->priv;

	if (enc_claim_bus(enc))
		return -1;
	if (enc_initcheck(enc, linkready)) {
		enc_release_bus(enc);
		return -1;
	}
	/* setup transmit pointers */
	enc_w16(enc, CTL_REG_EWRPTL, ENC_TX_BUF_START);
	enc_w16(enc, CTL_REG_ETXNDL, length + ENC_TX_BUF_START);
	enc_w16(enc, CTL_REG_ETXSTL, ENC_TX_BUF_START);
	/* write packet to ENC */
	enc_wbuf(enc, length, (u8 *) packet, 0x00);
	/*
	 * Check that the internal transmit logic has not been altered
	 * by excessive collisions. Reset transmitter if so.
	 * See Errata B4 12 and 14.
	 */
	if (enc_r8(enc, CTL_REG_EIR) & ENC_EIR_TXERIF) {
		enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_TXRST);
		enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_TXRST);
	}
	enc_bclr(enc, CTL_REG_EIR, (ENC_EIR_TXERIF | ENC_EIR_TXIF));
	/* start transmitting */
	enc_bset(enc, CTL_REG_ECON1, ENC_ECON1_TXRTS);
	enc_release_bus(enc);
	return 0;
}

/*
 * Finish use of ENC.
 *
 * This function entered into eth_device structure.
 */
static void enc_halt(struct eth_device *dev)
{
	enc_dev_t *enc = dev->priv;

	if (enc_claim_bus(enc))
		return;
	/* Just disable receiver */
	enc_bclr(enc, CTL_REG_ECON1, ENC_ECON1_RXEN);
	enc_release_bus(enc);
}

/*
 * This is the only exported function.
 *
 * It may be called several times with different bus:cs combinations.
 */
int enc28j60_initialize(unsigned int bus, unsigned int cs,
	unsigned int max_hz, unsigned int mode)
{
	struct eth_device *dev;
	enc_dev_t *enc;

	/* try to allocate, check and clear eth_device object */
	dev = malloc(sizeof(*dev));
	if (!dev) {
		return -1;
	}
	memset(dev, 0, sizeof(*dev));

	/* try to allocate, check and clear enc_dev_t object */
	enc = malloc(sizeof(*enc));
	if (!enc) {
		free(dev);
		return -1;
	}
	memset(enc, 0, sizeof(*enc));

	/* try to setup the SPI slave */
	enc->slave = spi_setup_slave(bus, cs, max_hz, mode);
	if (!enc->slave) {
		printf("enc28j60: invalid SPI device %i:%i\n", bus, cs);
		free(enc);
		free(dev);
		return -1;
	}

	enc->dev = dev;
	/* now fill the eth_device object */
	dev->priv = enc;
	dev->init = enc_init;
	dev->halt = enc_halt;
	dev->send = enc_send;
	dev->recv = enc_recv;
	dev->write_hwaddr = enc_write_hwaddr;
	sprintf(dev->name, "enc%i.%i", bus, cs);
	eth_register(dev);
#if defined(CONFIG_CMD_MII)
	miiphy_register(dev->name, enc_miiphy_read, enc_miiphy_write);
#endif
	return 0;
}
