/*
 * (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 net_process_received_packet() might call enc_send() in return, the bus
 * must be released, net_process_received_packet() 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 occurred */
	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 *)net_rx_packets[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 net_process_received_packet() might call enc_send(),
		 * we need to release the SPI bus, call
		 * net_process_received_packet(), reclaim the bus.
		 */
		enc_release_bus(enc);
		net_process_received_packet(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;

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

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

	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(struct mii_dev *bus, int phy_adr, int devad, int reg)
{
	u16 value = 0;
	struct eth_device *dev = eth_get_dev_by_name(bus->name);
	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 value;
}

/*
 * Write a PHY register.
 *
 * This function is registered with miiphy_register().
 */
int enc_miiphy_write(struct mii_dev *bus, int phy_adr, int devad, int reg,
		     u16 value)
{
	struct eth_device *dev = eth_get_dev_by_name(bus->name);
	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)
	int retval;
	struct mii_dev *mdiodev = mdio_alloc();
	if (!mdiodev)
		return -ENOMEM;
	strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
	mdiodev->read = enc_miiphy_read;
	mdiodev->write = enc_miiphy_write;

	retval = mdio_register(mdiodev);
	if (retval < 0)
		return retval;
#endif
	return 0;
}
