// SPDX-License-Identifier: GPL-2.0+
/*
 * Ethernet driver for TI TMS320DM644x (DaVinci) chips.
 *
 * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
 *
 * Parts shamelessly stolen from TI's dm644x_emac.c. Original copyright
 * follows:
 *
 * ----------------------------------------------------------------------------
 *
 * dm644x_emac.c
 *
 * TI DaVinci (DM644X) EMAC peripheral driver source for DV-EVM
 *
 * Copyright (C) 2005 Texas Instruments.
 *
 * ----------------------------------------------------------------------------
 *
 * Modifications:
 * ver. 1.0: Sep 2005, Anant Gole - Created EMAC version for uBoot.
 * ver  1.1: Nov 2005, Anant Gole - Extended the RX logic for multiple descriptors
 */
#include <config.h>
#include <command.h>
#include <cpu_func.h>
#include <log.h>
#include <net.h>
#include <miiphy.h>
#include <malloc.h>
#include <asm/cache.h>
#include <linux/compiler.h>
#include <asm/arch/emac_defs.h>
#include <asm/io.h>
#include <linux/delay.h>
#include "davinci_emac.h"

unsigned int	emac_dbg = 0;
#define debug_emac(fmt,args...)	if (emac_dbg) printf(fmt,##args)

#ifdef EMAC_HW_RAM_ADDR
static inline unsigned long BD_TO_HW(unsigned long x)
{
	if (x == 0)
		return 0;

	return x - EMAC_WRAPPER_RAM_ADDR + EMAC_HW_RAM_ADDR;
}

static inline unsigned long HW_TO_BD(unsigned long x)
{
	if (x == 0)
		return 0;

	return x - EMAC_HW_RAM_ADDR + EMAC_WRAPPER_RAM_ADDR;
}
#else
#define BD_TO_HW(x)	(x)
#define HW_TO_BD(x)	(x)
#endif

#ifdef DAVINCI_EMAC_GIG_ENABLE
#define emac_gigabit_enable(phy_addr)	davinci_eth_gigabit_enable(phy_addr)
#else
#define emac_gigabit_enable(phy_addr)	/* no gigabit to enable */
#endif

#if !defined(CFG_SYS_EMAC_TI_CLKDIV)
#define CFG_SYS_EMAC_TI_CLKDIV	((EMAC_MDIO_BUS_FREQ / \
		EMAC_MDIO_CLOCK_FREQ) - 1)
#endif

static void davinci_eth_mdio_enable(void);

static int gen_init_phy(int phy_addr);
static int gen_is_phy_connected(int phy_addr);
static int gen_get_link_speed(int phy_addr);
static int gen_auto_negotiate(int phy_addr);

void eth_mdio_enable(void)
{
	davinci_eth_mdio_enable();
}

/* EMAC Addresses */
static volatile emac_regs	*adap_emac = (emac_regs *)EMAC_BASE_ADDR;
static volatile ewrap_regs	*adap_ewrap = (ewrap_regs *)EMAC_WRAPPER_BASE_ADDR;
static volatile mdio_regs	*adap_mdio = (mdio_regs *)EMAC_MDIO_BASE_ADDR;

/* EMAC descriptors */
static volatile emac_desc	*emac_rx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_RX_DESC_BASE);
static volatile emac_desc	*emac_tx_desc = (emac_desc *)(EMAC_WRAPPER_RAM_ADDR + EMAC_TX_DESC_BASE);
static volatile emac_desc	*emac_rx_active_head = 0;
static volatile emac_desc	*emac_rx_active_tail = 0;
static int			emac_rx_queue_active = 0;

/* Receive packet buffers */
static unsigned char emac_rx_buffers[EMAC_MAX_RX_BUFFERS * EMAC_RXBUF_SIZE]
				__aligned(ARCH_DMA_MINALIGN);

#ifndef CFG_SYS_DAVINCI_EMAC_PHY_COUNT
#define CFG_SYS_DAVINCI_EMAC_PHY_COUNT	3
#endif

/* PHY address for a discovered PHY (0xff - not found) */
static u_int8_t	active_phy_addr[CFG_SYS_DAVINCI_EMAC_PHY_COUNT];

/* number of PHY found active */
static u_int8_t	num_phy;

phy_t				phy[CFG_SYS_DAVINCI_EMAC_PHY_COUNT];

static int davinci_emac_write_hwaddr(struct udevice *dev)
{
	struct eth_pdata *pdata = dev_get_plat(dev);
	unsigned long		mac_hi;
	unsigned long		mac_lo;

	/*
	 * Set MAC Addresses & Init multicast Hash to 0 (disable any multicast
	 * receive)
	 *  Using channel 0 only - other channels are disabled
	 *  */
	writel(0, &adap_emac->MACINDEX);
	mac_hi = (pdata->enetaddr[3] << 24) |
		 (pdata->enetaddr[2] << 16) |
		 (pdata->enetaddr[1] << 8)  |
		 (pdata->enetaddr[0]);
	mac_lo = (pdata->enetaddr[5] << 8) |
		 (pdata->enetaddr[4]);

	writel(mac_hi, &adap_emac->MACADDRHI);
#if defined(DAVINCI_EMAC_VERSION2)
	writel(mac_lo | EMAC_MAC_ADDR_IS_VALID | EMAC_MAC_ADDR_MATCH,
	       &adap_emac->MACADDRLO);
#else
	writel(mac_lo, &adap_emac->MACADDRLO);
#endif

	writel(0, &adap_emac->MACHASH1);
	writel(0, &adap_emac->MACHASH2);

	/* Set source MAC address - REQUIRED */
	writel(mac_hi, &adap_emac->MACSRCADDRHI);
	writel(mac_lo, &adap_emac->MACSRCADDRLO);

	return 0;
}

static void davinci_eth_mdio_enable(void)
{
	u_int32_t	clkdiv;

	clkdiv = CFG_SYS_EMAC_TI_CLKDIV;

	writel((clkdiv & 0xff) |
	       MDIO_CONTROL_ENABLE |
	       MDIO_CONTROL_FAULT |
	       MDIO_CONTROL_FAULT_ENABLE,
	       &adap_mdio->CONTROL);

	while (readl(&adap_mdio->CONTROL) & MDIO_CONTROL_IDLE)
		;
}

/*
 * Tries to find an active connected PHY. Returns 1 if address if found.
 * If no active PHY (or more than one PHY) found returns 0.
 * Sets active_phy_addr variable.
 */
static int davinci_eth_phy_detect(void)
{
	u_int32_t	phy_act_state;
	int		i;
	int		j;
	unsigned int	count = 0;

	for (i = 0; i < CFG_SYS_DAVINCI_EMAC_PHY_COUNT; i++)
		active_phy_addr[i] = 0xff;

	udelay(1000);
	phy_act_state = readl(&adap_mdio->ALIVE);

	if (phy_act_state == 0)
		return 0;		/* No active PHYs */

	debug_emac("davinci_eth_phy_detect(), ALIVE = 0x%08x\n", phy_act_state);

	for (i = 0, j = 0; i < 32; i++)
		if (phy_act_state & (1 << i)) {
			count++;
			if (count <= CFG_SYS_DAVINCI_EMAC_PHY_COUNT) {
				active_phy_addr[j++] = i;
			} else {
				printf("%s: to many PHYs detected.\n",
					__func__);
				count = 0;
				break;
			}
		}

	num_phy = count;

	return count;
}

/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */
int davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
{
	int	tmp;

	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
		;

	writel(MDIO_USERACCESS0_GO |
	       MDIO_USERACCESS0_WRITE_READ |
	       ((reg_num & 0x1f) << 21) |
	       ((phy_addr & 0x1f) << 16),
	       &adap_mdio->USERACCESS0);

	/* Wait for command to complete */
	while ((tmp = readl(&adap_mdio->USERACCESS0)) & MDIO_USERACCESS0_GO)
		;

	if (tmp & MDIO_USERACCESS0_ACK) {
		*data = tmp & 0xffff;
		return 1;
	}

	return 0;
}

/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
{

	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
		;

	writel(MDIO_USERACCESS0_GO |
	       MDIO_USERACCESS0_WRITE_WRITE |
	       ((reg_num & 0x1f) << 21) |
	       ((phy_addr & 0x1f) << 16) |
	       (data & 0xffff),
	       &adap_mdio->USERACCESS0);

	/* Wait for command to complete */
	while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
		;

	return 1;
}

/* PHY functions for a generic PHY */
static int gen_init_phy(int phy_addr)
{
	int	ret = 1;

	if (gen_get_link_speed(phy_addr)) {
		/* Try another time */
		ret = gen_get_link_speed(phy_addr);
	}

	return(ret);
}

static int gen_is_phy_connected(int phy_addr)
{
	u_int16_t	dummy;

	return davinci_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
}

static int get_active_phy(void)
{
	int i;

	for (i = 0; i < num_phy; i++)
		if (phy[i].get_link_speed(active_phy_addr[i]))
			return i;

	return -1;	/* Return error if no link */
}

static int gen_get_link_speed(int phy_addr)
{
	u_int16_t	tmp;

	if (davinci_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp) &&
			(tmp & 0x04)) {
#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
		defined(CONFIG_MACH_DAVINCI_DA850_EVM)
		davinci_eth_phy_read(phy_addr, MII_LPA, &tmp);

		/* Speed doesn't matter, there is no setting for it in EMAC. */
		if (tmp & (LPA_100FULL | LPA_10FULL)) {
			/* set EMAC for Full Duplex  */
			writel(EMAC_MACCONTROL_MIIEN_ENABLE |
					EMAC_MACCONTROL_FULLDUPLEX_ENABLE,
					&adap_emac->MACCONTROL);
		} else {
			/*set EMAC for Half Duplex  */
			writel(EMAC_MACCONTROL_MIIEN_ENABLE,
					&adap_emac->MACCONTROL);
		}

		if (tmp & (LPA_100FULL | LPA_100HALF))
			writel(readl(&adap_emac->MACCONTROL) |
					EMAC_MACCONTROL_RMIISPEED_100,
					 &adap_emac->MACCONTROL);
		else
			writel(readl(&adap_emac->MACCONTROL) &
					~EMAC_MACCONTROL_RMIISPEED_100,
					 &adap_emac->MACCONTROL);
#endif
		return(1);
	}

	return(0);
}

static int gen_auto_negotiate(int phy_addr)
{
	u_int16_t	tmp;
	u_int16_t	val;
	unsigned long	cntr = 0;

	if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
		return 0;

	val = tmp | BMCR_FULLDPLX | BMCR_ANENABLE |
						BMCR_SPEED100;
	davinci_eth_phy_write(phy_addr, MII_BMCR, val);

	if (!davinci_eth_phy_read(phy_addr, MII_ADVERTISE, &val))
		return 0;

	val |= (ADVERTISE_100FULL | ADVERTISE_100HALF | ADVERTISE_10FULL |
							ADVERTISE_10HALF);
	davinci_eth_phy_write(phy_addr, MII_ADVERTISE, val);

	if (!davinci_eth_phy_read(phy_addr, MII_BMCR, &tmp))
		return(0);

#ifdef DAVINCI_EMAC_GIG_ENABLE
	davinci_eth_phy_read(phy_addr, MII_CTRL1000, &val);
	val |= PHY_1000BTCR_1000FD;
	val &= ~PHY_1000BTCR_1000HD;
	davinci_eth_phy_write(phy_addr, MII_CTRL1000, val);
	davinci_eth_phy_read(phy_addr, MII_CTRL1000, &val);
#endif

	/* Restart Auto_negotiation  */
	tmp |= BMCR_ANRESTART;
	davinci_eth_phy_write(phy_addr, MII_BMCR, tmp);

	/*check AutoNegotiate complete */
	do {
		udelay(40000);
		if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
			return 0;

		if (tmp & BMSR_ANEGCOMPLETE)
			break;

		cntr++;
	} while (cntr < 200);

	if (!davinci_eth_phy_read(phy_addr, MII_BMSR, &tmp))
		return(0);

	if (!(tmp & BMSR_ANEGCOMPLETE))
		return(0);

	return(gen_get_link_speed(phy_addr));
}
/* End of generic PHY functions */

#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
static int davinci_mii_phy_read(struct mii_dev *bus, int addr, int devad,
				int reg)
{
	unsigned short value = 0;
	int retval = davinci_eth_phy_read(addr, reg, &value);

	return retval ? value : -EIO;
}

static int davinci_mii_phy_write(struct mii_dev *bus, int addr, int devad,
				 int reg, u16 value)
{
	return davinci_eth_phy_write(addr, reg, value) ? 0 : 1;
}
#endif

static void  __attribute__((unused)) davinci_eth_gigabit_enable(int phy_addr)
{
	u_int16_t data;

	if (davinci_eth_phy_read(phy_addr, 0, &data)) {
		if (data & (1 << 6)) { /* speed selection MSB */
			/*
			 * Check if link detected is giga-bit
			 * If Gigabit mode detected, enable gigbit in MAC
			 */
			writel(readl(&adap_emac->MACCONTROL) |
				EMAC_MACCONTROL_GIGFORCE |
				EMAC_MACCONTROL_GIGABIT_ENABLE,
				&adap_emac->MACCONTROL);
		}
	}
}

/* Eth device open */
static int davinci_emac_start(struct udevice *dev)
{
	dv_reg_p		addr;
	u_int32_t		clkdiv, cnt, mac_control;
	uint16_t		__maybe_unused lpa_val;
	volatile emac_desc	*rx_desc;
	int			index;

	debug_emac("+ emac_open\n");

	/* Reset EMAC module and disable interrupts in wrapper */
	writel(1, &adap_emac->SOFTRESET);
	while (readl(&adap_emac->SOFTRESET) != 0)
		;
#if defined(DAVINCI_EMAC_VERSION2)
	writel(1, &adap_ewrap->softrst);
	while (readl(&adap_ewrap->softrst) != 0)
		;
#else
	writel(0, &adap_ewrap->EWCTL);
	for (cnt = 0; cnt < 5; cnt++) {
		clkdiv = readl(&adap_ewrap->EWCTL);
	}
#endif

#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
	defined(CONFIG_MACH_DAVINCI_DA850_EVM)
	adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0;
	adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0;
	adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0;
#endif
	rx_desc = emac_rx_desc;

	writel(1, &adap_emac->TXCONTROL);
	writel(1, &adap_emac->RXCONTROL);

	davinci_emac_write_hwaddr(dev);

	/* Set DMA 8 TX / 8 RX Head pointers to 0 */
	addr = &adap_emac->TX0HDP;
	for (cnt = 0; cnt < 8; cnt++)
		writel(0, addr++);

	addr = &adap_emac->RX0HDP;
	for (cnt = 0; cnt < 8; cnt++)
		writel(0, addr++);

	/* Clear Statistics (do this before setting MacControl register) */
	addr = &adap_emac->RXGOODFRAMES;
	for(cnt = 0; cnt < EMAC_NUM_STATS; cnt++)
		writel(0, addr++);

	/* No multicast addressing */
	writel(0, &adap_emac->MACHASH1);
	writel(0, &adap_emac->MACHASH2);

	/* Create RX queue and set receive process in place */
	emac_rx_active_head = emac_rx_desc;
	for (cnt = 0; cnt < EMAC_MAX_RX_BUFFERS; cnt++) {
		rx_desc->next = BD_TO_HW((u_int32_t)(rx_desc + 1));
		rx_desc->buffer = &emac_rx_buffers[cnt * EMAC_RXBUF_SIZE];
		rx_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
		rx_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
		rx_desc++;
	}

	/* Finalize the rx desc list */
	rx_desc--;
	rx_desc->next = 0;
	emac_rx_active_tail = rx_desc;
	emac_rx_queue_active = 1;

	/* Enable TX/RX */
	writel(EMAC_MAX_ETHERNET_PKT_SIZE, &adap_emac->RXMAXLEN);
	writel(0, &adap_emac->RXBUFFEROFFSET);

	/*
	 * No fancy configs - Use this for promiscous debug
	 *   - EMAC_RXMBPENABLE_RXCAFEN_ENABLE
	 */
	writel(EMAC_RXMBPENABLE_RXBROADEN, &adap_emac->RXMBPENABLE);

	/* Enable ch 0 only */
	writel(1, &adap_emac->RXUNICASTSET);

	/* Init MDIO & get link state */
	clkdiv = CFG_SYS_EMAC_TI_CLKDIV;
	writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | MDIO_CONTROL_FAULT,
	       &adap_mdio->CONTROL);

	/* We need to wait for MDIO to start */
	udelay(1000);

	index = get_active_phy();
	if (index == -1)
		return(0);

	/* Enable MII interface */
	mac_control = EMAC_MACCONTROL_MIIEN_ENABLE;
#ifdef DAVINCI_EMAC_GIG_ENABLE
	davinci_eth_phy_read(active_phy_addr[index], MII_STAT1000, &lpa_val);
	if (lpa_val & PHY_1000BTSR_1000FD) {
		debug_emac("eth_open : gigabit negotiated\n");
		mac_control |= EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
		mac_control |= EMAC_MACCONTROL_GIGABIT_ENABLE;
	}
#endif

	davinci_eth_phy_read(active_phy_addr[index], MII_LPA, &lpa_val);
	if (lpa_val & (LPA_100FULL | LPA_10FULL))
		/* set EMAC for Full Duplex  */
		mac_control |= EMAC_MACCONTROL_FULLDUPLEX_ENABLE;
#if defined(CONFIG_SOC_DA8XX) || \
	(defined(CONFIG_OMAP34XX) && defined(CONFIG_DRIVER_TI_EMAC_USE_RMII))
	mac_control |= EMAC_MACCONTROL_RMIISPEED_100;
#endif
	writel(mac_control, &adap_emac->MACCONTROL);
	/* Start receive process */
	writel(BD_TO_HW((u_int32_t)emac_rx_desc), &adap_emac->RX0HDP);

	debug_emac("- emac_open\n");

	return(1);
}

/* EMAC Channel Teardown */
static void davinci_eth_ch_teardown(int ch)
{
	dv_reg		dly = 0xff;
	dv_reg		cnt;

	debug_emac("+ emac_ch_teardown\n");

	if (ch == EMAC_CH_TX) {
		/* Init TX channel teardown */
		writel(0, &adap_emac->TXTEARDOWN);
		do {
			/*
			 * Wait here for Tx teardown completion interrupt to
			 * occur. Note: A task delay can be called here to pend
			 * rather than occupying CPU cycles - anyway it has
			 * been found that teardown takes very few cpu cycles
			 * and does not affect functionality
			 */
			dly--;
			udelay(1);
			if (dly == 0)
				break;
			cnt = readl(&adap_emac->TX0CP);
		} while (cnt != 0xfffffffc);
		writel(cnt, &adap_emac->TX0CP);
		writel(0, &adap_emac->TX0HDP);
	} else {
		/* Init RX channel teardown */
		writel(0, &adap_emac->RXTEARDOWN);
		do {
			/*
			 * Wait here for Rx teardown completion interrupt to
			 * occur. Note: A task delay can be called here to pend
			 * rather than occupying CPU cycles - anyway it has
			 * been found that teardown takes very few cpu cycles
			 * and does not affect functionality
			 */
			dly--;
			udelay(1);
			if (dly == 0)
				break;
			cnt = readl(&adap_emac->RX0CP);
		} while (cnt != 0xfffffffc);
		writel(cnt, &adap_emac->RX0CP);
		writel(0, &adap_emac->RX0HDP);
	}

	debug_emac("- emac_ch_teardown\n");
}

/* Eth device close */
static void davinci_emac_stop(struct udevice *dev)
{
	debug_emac("+ emac_close\n");

	davinci_eth_ch_teardown(EMAC_CH_TX);	/* TX Channel teardown */
	if (readl(&adap_emac->RXCONTROL) & 1)
		davinci_eth_ch_teardown(EMAC_CH_RX); /* RX Channel teardown */

	/* Reset EMAC module and disable interrupts in wrapper */
	writel(1, &adap_emac->SOFTRESET);
#if defined(DAVINCI_EMAC_VERSION2)
	writel(1, &adap_ewrap->softrst);
#else
	writel(0, &adap_ewrap->EWCTL);
#endif

#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
	defined(CONFIG_MACH_DAVINCI_DA850_EVM)
	adap_ewrap->c0rxen = adap_ewrap->c1rxen = adap_ewrap->c2rxen = 0;
	adap_ewrap->c0txen = adap_ewrap->c1txen = adap_ewrap->c2txen = 0;
	adap_ewrap->c0miscen = adap_ewrap->c1miscen = adap_ewrap->c2miscen = 0;
#endif
	debug_emac("- emac_close\n");
}

static int tx_send_loop = 0;

/*
 * This function sends a single packet on the network and returns
 * positive number (number of bytes transmitted) or negative for error
 */
static int davinci_emac_send(struct udevice *dev,
			     void *packet, int length)
{
	int ret_status = -1;
	int index;
	tx_send_loop = 0;

	index = get_active_phy();
	if (index == -1) {
		printf(" WARN: emac_send_packet: No link\n");
		return (ret_status);
	}

	/* Check packet size and if < EMAC_MIN_ETHERNET_PKT_SIZE, pad it up */
	if (length < EMAC_MIN_ETHERNET_PKT_SIZE) {
		length = EMAC_MIN_ETHERNET_PKT_SIZE;
	}

	/* Populate the TX descriptor */
	emac_tx_desc->next = 0;
	emac_tx_desc->buffer = (u_int8_t *) packet;
	emac_tx_desc->buff_off_len = (length & 0xffff);
	emac_tx_desc->pkt_flag_len = ((length & 0xffff) |
				      EMAC_CPPI_SOP_BIT |
				      EMAC_CPPI_OWNERSHIP_BIT |
				      EMAC_CPPI_EOP_BIT);

	flush_dcache_range((unsigned long)packet,
			   (unsigned long)packet + ALIGN(length, PKTALIGN));

	/* Send the packet */
	writel(BD_TO_HW((unsigned long)emac_tx_desc), &adap_emac->TX0HDP);

	/* Wait for packet to complete or link down */
	while (1) {
		if (!phy[index].get_link_speed(active_phy_addr[index])) {
			davinci_eth_ch_teardown (EMAC_CH_TX);
			return (ret_status);
		}

		if (readl(&adap_emac->TXINTSTATRAW) & 0x01) {
			ret_status = length;
			break;
		}
		tx_send_loop++;
	}

	return (ret_status);
}

/*
 * This function handles receipt of a packet from the network
 */
static int davinci_emac_recv(struct udevice *dev, int flags, uchar **packetp)
{
	volatile emac_desc *rx_curr_desc;
	volatile emac_desc *curr_desc;
	volatile emac_desc *tail_desc;
	int status, ret = -1;

	rx_curr_desc = emac_rx_active_head;
	if (!rx_curr_desc)
		return 0;
	*packetp = rx_curr_desc->buffer;
	status = rx_curr_desc->pkt_flag_len;
	if ((status & EMAC_CPPI_OWNERSHIP_BIT) == 0) {
		if (status & EMAC_CPPI_RX_ERROR_FRAME) {
			/* Error in packet - discard it and requeue desc */
			printf ("WARN: emac_rcv_pkt: Error in packet\n");
		} else {
			unsigned long tmp = (unsigned long)rx_curr_desc->buffer;
			unsigned short len =
				rx_curr_desc->buff_off_len & 0xffff;

			invalidate_dcache_range(tmp, tmp + ALIGN(len, PKTALIGN));
			ret = len;
		}

		/* Ack received packet descriptor */
		writel(BD_TO_HW((ulong)rx_curr_desc), &adap_emac->RX0CP);
		curr_desc = rx_curr_desc;
		emac_rx_active_head =
			(volatile emac_desc *) (HW_TO_BD(rx_curr_desc->next));

		if (status & EMAC_CPPI_EOQ_BIT) {
			if (emac_rx_active_head) {
				writel(BD_TO_HW((ulong)emac_rx_active_head),
				       &adap_emac->RX0HDP);
			} else {
				emac_rx_queue_active = 0;
				printf ("INFO:emac_rcv_packet: RX Queue not active\n");
			}
		}

		/* Recycle RX descriptor */
		rx_curr_desc->buff_off_len = EMAC_MAX_ETHERNET_PKT_SIZE;
		rx_curr_desc->pkt_flag_len = EMAC_CPPI_OWNERSHIP_BIT;
		rx_curr_desc->next = 0;

		if (emac_rx_active_head == 0) {
			printf ("INFO: emac_rcv_pkt: active queue head = 0\n");
			emac_rx_active_head = curr_desc;
			emac_rx_active_tail = curr_desc;
			if (emac_rx_queue_active != 0) {
				writel(BD_TO_HW((ulong)emac_rx_active_head),
				       &adap_emac->RX0HDP);
				printf ("INFO: emac_rcv_pkt: active queue head = 0, HDP fired\n");
				emac_rx_queue_active = 1;
			}
		} else {
			tail_desc = emac_rx_active_tail;
			emac_rx_active_tail = curr_desc;
			tail_desc->next = BD_TO_HW((ulong) curr_desc);
			status = tail_desc->pkt_flag_len;
			if (status & EMAC_CPPI_EOQ_BIT) {
				writel(BD_TO_HW((ulong)curr_desc),
				       &adap_emac->RX0HDP);
				status &= ~EMAC_CPPI_EOQ_BIT;
				tail_desc->pkt_flag_len = status;
			}
		}
		return (ret);
	}

	return (0);
}

/*
 * This function initializes the emac hardware. It does NOT initialize
 * EMAC modules power or pin multiplexors, that is done by board_init()
 * much earlier in bootup process. Returns 1 on success, 0 otherwise.
 */
static int davinci_emac_probe(struct udevice *dev)
{
	u_int32_t	phy_id;
	u_int16_t	tmp;
	int		i;
	int		ret;

	davinci_eth_mdio_enable();

	/* let the EMAC detect the PHYs */
	udelay(5000);

	for (i = 0; i < 256; i++) {
		if (readl(&adap_mdio->ALIVE))
			break;
		udelay(1000);
	}

	if (i >= 256) {
		printf("No ETH PHY detected!!!\n");
		return(0);
	}

	/* Find if PHY(s) is/are connected */
	ret = davinci_eth_phy_detect();
	if (!ret)
		return(0);
	else
		debug_emac(" %d ETH PHY detected\n", ret);

	/* Get PHY ID and initialize phy_ops for a detected PHY */
	for (i = 0; i < num_phy; i++) {
		if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID1,
							&tmp)) {
			active_phy_addr[i] = 0xff;
			continue;
		}

		phy_id = (tmp << 16) & 0xffff0000;

		if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID2,
							&tmp)) {
			active_phy_addr[i] = 0xff;
			continue;
		}

		phy_id |= tmp & 0x0000ffff;

		sprintf(phy[i].name, "GENERIC @ 0x%02x",
			active_phy_addr[i]);
		phy[i].init = gen_init_phy;
		phy[i].is_phy_connected = gen_is_phy_connected;
		phy[i].get_link_speed = gen_get_link_speed;
		phy[i].auto_negotiate = gen_auto_negotiate;

		debug("Ethernet PHY: %s\n", phy[i].name);

		int retval;
		struct mii_dev *mdiodev = mdio_alloc();
		if (!mdiodev)
			return -ENOMEM;
		strlcpy(mdiodev->name, phy[i].name, MDIO_NAME_LEN);
		mdiodev->read = davinci_mii_phy_read;
		mdiodev->write = davinci_mii_phy_write;

		retval = mdio_register(mdiodev);
		if (retval < 0)
			return retval;
#ifdef DAVINCI_EMAC_GIG_ENABLE
#define PHY_CONF_REG	22
		/* Enable PHY to clock out TX_CLK */
		davinci_eth_phy_read(active_phy_addr[i], PHY_CONF_REG, &tmp);
		tmp |= PHY_CONF_TXCLKEN;
		davinci_eth_phy_write(active_phy_addr[i], PHY_CONF_REG, tmp);
		davinci_eth_phy_read(active_phy_addr[i], PHY_CONF_REG, &tmp);
#endif
	}

#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
		defined(CONFIG_MACH_DAVINCI_DA850_EVM) && \
			!defined(CONFIG_DRIVER_TI_EMAC_RMII_NO_NEGOTIATE)
	for (i = 0; i < num_phy; i++) {
		if (phy[i].is_phy_connected(i))
			phy[i].auto_negotiate(i);
	}
#endif
	return 0;
}

static const struct eth_ops davinci_emac_ops = {
	.start		= davinci_emac_start,
	.send		= davinci_emac_send,
	.recv		= davinci_emac_recv,
	.stop		= davinci_emac_stop,
	.write_hwaddr	= davinci_emac_write_hwaddr,
};

static const struct udevice_id davinci_emac_ids[] = {
	{ .compatible = "ti,davinci-dm6467-emac" },
	{ .compatible = "ti,am3517-emac", },
	{ .compatible = "ti,dm816-emac", },
	{ }
};

U_BOOT_DRIVER(davinci_emac) = {
	.name		= "davinci_emac",
	.id		= UCLASS_ETH,
	.of_match	= davinci_emac_ids,
	.probe		= davinci_emac_probe,
	.ops		= &davinci_emac_ops,
	.plat_auto	= sizeof(struct eth_pdata),
};
