// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2011
 * eInfochips Ltd. <www.einfochips.com>
 * Written-by: Ajay Bhargav <contact@8051projects.net>
 *
 * (C) Copyright 2010
 * Marvell Semiconductor <www.marvell.com>
 * Contributor: Mahavir Jain <mjain@marvell.com>
 */

#include <common.h>
#include <log.h>
#include <net.h>
#include <malloc.h>
#include <miiphy.h>
#include <netdev.h>
#include <asm/types.h>
#include <asm/byteorder.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/mii.h>
#include <asm/io.h>
#include <asm/arch/armada100.h>
#include "armada100_fec.h"

#define  PHY_ADR_REQ     0xFF	/* Magic number to read/write PHY address */

#ifdef DEBUG
static int eth_dump_regs(struct eth_device *dev)
{
	struct armdfec_device *darmdfec = to_darmdfec(dev);
	struct armdfec_reg *regs = darmdfec->regs;
	unsigned int i = 0;

	printf("\noffset: phy_adr, value: 0x%x\n", readl(&regs->phyadr));
	printf("offset: smi, value: 0x%x\n", readl(&regs->smi));
	for (i = 0x400; i <= 0x4e4; i += 4)
		printf("offset: 0x%x, value: 0x%x\n",
			i, readl(ARMD1_FEC_BASE + i));
	return 0;
}
#endif

static int armdfec_phy_timeout(u32 *reg, u32 flag, int cond)
{
	u32 timeout = PHY_WAIT_ITERATIONS;
	u32 reg_val;

	while (--timeout) {
		reg_val = readl(reg);
		if (cond && (reg_val & flag))
			break;
		else if (!cond && !(reg_val & flag))
			break;
		udelay(PHY_WAIT_MICRO_SECONDS);
	}
	return !timeout;
}

static int smi_reg_read(struct mii_dev *bus, int phy_addr, int devad,
			int phy_reg)
{
	u16 value = 0;
	struct eth_device *dev = eth_get_dev_by_name(bus->name);
	struct armdfec_device *darmdfec = to_darmdfec(dev);
	struct armdfec_reg *regs = darmdfec->regs;
	u32 val;

	if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) {
		val = readl(&regs->phyadr);
		value = val & 0x1f;
		return value;
	}

	/* check parameters */
	if (phy_addr > PHY_MASK) {
		printf("ARMD100 FEC: (%s) Invalid phy address: 0x%X\n",
				__func__, phy_addr);
		return -EINVAL;
	}
	if (phy_reg > PHY_MASK) {
		printf("ARMD100 FEC: (%s) Invalid register offset: 0x%X\n",
				__func__, phy_reg);
		return -EINVAL;
	}

	/* wait for the SMI register to become available */
	if (armdfec_phy_timeout(&regs->smi, SMI_BUSY, false)) {
		printf("ARMD100 FEC: (%s) PHY busy timeout\n",	__func__);
		return -1;
	}

	writel((phy_addr << 16) | (phy_reg << 21) | SMI_OP_R, &regs->smi);

	/* now wait for the data to be valid */
	if (armdfec_phy_timeout(&regs->smi, SMI_R_VALID, true)) {
		val = readl(&regs->smi);
		printf("ARMD100 FEC: (%s) PHY Read timeout, val=0x%x\n",
				__func__, val);
		return -1;
	}
	val = readl(&regs->smi);
	value = val & 0xffff;

	return value;
}

static int smi_reg_write(struct mii_dev *bus, int phy_addr, int devad,
			 int phy_reg, u16 value)
{
	struct eth_device *dev = eth_get_dev_by_name(bus->name);
	struct armdfec_device *darmdfec = to_darmdfec(dev);
	struct armdfec_reg *regs = darmdfec->regs;

	if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) {
		clrsetbits_le32(&regs->phyadr, 0x1f, value & 0x1f);
		return 0;
	}

	/* check parameters */
	if (phy_addr > PHY_MASK) {
		printf("ARMD100 FEC: (%s) Invalid phy address\n", __func__);
		return -EINVAL;
	}
	if (phy_reg > PHY_MASK) {
		printf("ARMD100 FEC: (%s) Invalid register offset\n", __func__);
		return -EINVAL;
	}

	/* wait for the SMI register to become available */
	if (armdfec_phy_timeout(&regs->smi, SMI_BUSY, false)) {
		printf("ARMD100 FEC: (%s) PHY busy timeout\n",	__func__);
		return -1;
	}

	writel((phy_addr << 16) | (phy_reg << 21) | SMI_OP_W | (value & 0xffff),
			&regs->smi);
	return 0;
}

/*
 * Abort any transmit and receive operations and put DMA
 * in idle state. AT and AR bits are cleared upon entering
 * in IDLE state. So poll those bits to verify operation.
 */
static void abortdma(struct eth_device *dev)
{
	struct armdfec_device *darmdfec = to_darmdfec(dev);
	struct armdfec_reg *regs = darmdfec->regs;
	int delay;
	int maxretries = 40;
	u32 tmp;

	while (--maxretries) {
		writel(SDMA_CMD_AR | SDMA_CMD_AT, &regs->sdma_cmd);
		udelay(100);

		delay = 10;
		while (--delay) {
			tmp = readl(&regs->sdma_cmd);
			if (!(tmp & (SDMA_CMD_AR | SDMA_CMD_AT)))
				break;
			udelay(10);
		}
		if (delay)
			break;
	}

	if (!maxretries)
		printf("ARMD100 FEC: (%s) DMA Stuck\n", __func__);
}

static inline u32 nibble_swapping_32_bit(u32 x)
{
	return ((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4);
}

static inline u32 nibble_swapping_16_bit(u32 x)
{
	return ((x & 0x0000f0f0) >> 4) | ((x & 0x00000f0f) << 4);
}

static inline u32 flip_4_bits(u32 x)
{
	return ((x & 0x01) << 3) | ((x & 0x002) << 1)
		| ((x & 0x04) >> 1) | ((x & 0x008) >> 3);
}

/*
 * This function will calculate the hash function of the address.
 * depends on the hash mode and hash size.
 * Inputs
 * mach             - the 2 most significant bytes of the MAC address.
 * macl             - the 4 least significant bytes of the MAC address.
 * Outputs
 * return the calculated entry.
 */
static u32 hash_function(u32 mach, u32 macl)
{
	u32 hashresult;
	u32 addrh;
	u32 addrl;
	u32 addr0;
	u32 addr1;
	u32 addr2;
	u32 addr3;
	u32 addrhswapped;
	u32 addrlswapped;

	addrh = nibble_swapping_16_bit(mach);
	addrl = nibble_swapping_32_bit(macl);

	addrhswapped = flip_4_bits(addrh & 0xf)
		+ ((flip_4_bits((addrh >> 4) & 0xf)) << 4)
		+ ((flip_4_bits((addrh >> 8) & 0xf)) << 8)
		+ ((flip_4_bits((addrh >> 12) & 0xf)) << 12);

	addrlswapped = flip_4_bits(addrl & 0xf)
		+ ((flip_4_bits((addrl >> 4) & 0xf)) << 4)
		+ ((flip_4_bits((addrl >> 8) & 0xf)) << 8)
		+ ((flip_4_bits((addrl >> 12) & 0xf)) << 12)
		+ ((flip_4_bits((addrl >> 16) & 0xf)) << 16)
		+ ((flip_4_bits((addrl >> 20) & 0xf)) << 20)
		+ ((flip_4_bits((addrl >> 24) & 0xf)) << 24)
		+ ((flip_4_bits((addrl >> 28) & 0xf)) << 28);

	addrh = addrhswapped;
	addrl = addrlswapped;

	addr0 = (addrl >> 2) & 0x03f;
	addr1 = (addrl & 0x003) | (((addrl >> 8) & 0x7f) << 2);
	addr2 = (addrl >> 15) & 0x1ff;
	addr3 = ((addrl >> 24) & 0x0ff) | ((addrh & 1) << 8);

	hashresult = (addr0 << 9) | (addr1 ^ addr2 ^ addr3);
	hashresult = hashresult & 0x07ff;
	return hashresult;
}

/*
 * This function will add an entry to the address table.
 * depends on the hash mode and hash size that was initialized.
 * Inputs
 * mach - the 2 most significant bytes of the MAC address.
 * macl - the 4 least significant bytes of the MAC address.
 * skip - if 1, skip this address.
 * rd   - the RD field in the address table.
 * Outputs
 * address table entry is added.
 * 0 if success.
 * -ENOSPC if table full
 */
static int add_del_hash_entry(struct armdfec_device *darmdfec, u32 mach,
			      u32 macl, u32 rd, u32 skip, int del)
{
	struct addr_table_entry_t *entry, *start;
	u32 newhi;
	u32 newlo;
	u32 i;

	newlo = (((mach >> 4) & 0xf) << 15)
		| (((mach >> 0) & 0xf) << 11)
		| (((mach >> 12) & 0xf) << 7)
		| (((mach >> 8) & 0xf) << 3)
		| (((macl >> 20) & 0x1) << 31)
		| (((macl >> 16) & 0xf) << 27)
		| (((macl >> 28) & 0xf) << 23)
		| (((macl >> 24) & 0xf) << 19)
		| (skip << HTESKIP) | (rd << HTERDBIT)
		| HTEVALID;

	newhi = (((macl >> 4) & 0xf) << 15)
		| (((macl >> 0) & 0xf) << 11)
		| (((macl >> 12) & 0xf) << 7)
		| (((macl >> 8) & 0xf) << 3)
		| (((macl >> 21) & 0x7) << 0);

	/*
	 * Pick the appropriate table, start scanning for free/reusable
	 * entries at the index obtained by hashing the specified MAC address
	 */
	start = (struct addr_table_entry_t *)(darmdfec->htpr);
	entry = start + hash_function(mach, macl);
	for (i = 0; i < HOP_NUMBER; i++) {
		if (!(entry->lo & HTEVALID)) {
			break;
		} else {
			/* if same address put in same position */
			if (((entry->lo & 0xfffffff8) == (newlo & 0xfffffff8))
					&& (entry->hi == newhi))
				break;
		}
		if (entry == start + 0x7ff)
			entry = start;
		else
			entry++;
	}

	if (((entry->lo & 0xfffffff8) != (newlo & 0xfffffff8)) &&
		(entry->hi != newhi) && del)
		return 0;

	if (i == HOP_NUMBER) {
		if (!del) {
			printf("ARMD100 FEC: (%s) table section is full\n",
					__func__);
			return -ENOSPC;
		} else {
			return 0;
		}
	}

	/*
	 * Update the selected entry
	 */
	if (del) {
		entry->hi = 0;
		entry->lo = 0;
	} else {
		entry->hi = newhi;
		entry->lo = newlo;
	}

	return 0;
}

/*
 *  Create an addressTable entry from MAC address info
 *  found in the specifed net_device struct
 *
 *  Input : pointer to ethernet interface network device structure
 *  Output : N/A
 */
static void update_hash_table_mac_address(struct armdfec_device *darmdfec,
					  u8 *oaddr, u8 *addr)
{
	u32 mach;
	u32 macl;

	/* Delete old entry */
	if (oaddr) {
		mach = (oaddr[0] << 8) | oaddr[1];
		macl = (oaddr[2] << 24) | (oaddr[3] << 16) |
			(oaddr[4] << 8) | oaddr[5];
		add_del_hash_entry(darmdfec, mach, macl, 1, 0, HASH_DELETE);
	}

	/* Add new entry */
	mach = (addr[0] << 8) | addr[1];
	macl = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
	add_del_hash_entry(darmdfec, mach, macl, 1, 0, HASH_ADD);
}

/* Address Table Initialization */
static void init_hashtable(struct eth_device *dev)
{
	struct armdfec_device *darmdfec = to_darmdfec(dev);
	struct armdfec_reg *regs = darmdfec->regs;
	memset(darmdfec->htpr, 0, HASH_ADDR_TABLE_SIZE);
	writel((u32)darmdfec->htpr, &regs->htpr);
}

/*
 * This detects PHY chip from address 0-31 by reading PHY status
 * registers. PHY chip can be connected at any of this address.
 */
static int ethernet_phy_detect(struct eth_device *dev)
{
	u32 val;
	u16 tmp, mii_status;
	u8 addr;

	for (addr = 0; addr < 32; addr++) {
		if (miiphy_read(dev->name, addr, MII_BMSR, &mii_status)	!= 0)
			/* try next phy */
			continue;

		/* invalid MII status. More validation required here... */
		if (mii_status == 0 || mii_status == 0xffff)
			/* try next phy */
			continue;

		if (miiphy_read(dev->name, addr, MII_PHYSID1, &tmp) != 0)
			/* try next phy */
			continue;

		val = tmp << 16;
		if (miiphy_read(dev->name, addr, MII_PHYSID2, &tmp) != 0)
			/* try next phy */
			continue;

		val |= tmp;

		if ((val & 0xfffffff0) != 0)
			return addr;
	}
	return -1;
}

static void armdfec_init_rx_desc_ring(struct armdfec_device *darmdfec)
{
	struct rx_desc *p_rx_desc;
	int i;

	/* initialize the Rx descriptors ring */
	p_rx_desc = darmdfec->p_rxdesc;
	for (i = 0; i < RINGSZ; i++) {
		p_rx_desc->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT;
		p_rx_desc->buf_size = PKTSIZE_ALIGN;
		p_rx_desc->byte_cnt = 0;
		p_rx_desc->buf_ptr = darmdfec->p_rxbuf + i * PKTSIZE_ALIGN;
		if (i == (RINGSZ - 1)) {
			p_rx_desc->nxtdesc_p = darmdfec->p_rxdesc;
		} else {
			p_rx_desc->nxtdesc_p = (struct rx_desc *)
			    ((u32)p_rx_desc + ARMDFEC_RXQ_DESC_ALIGNED_SIZE);
			p_rx_desc = p_rx_desc->nxtdesc_p;
		}
	}
	darmdfec->p_rxdesc_curr = darmdfec->p_rxdesc;
}

static int armdfec_init(struct eth_device *dev, struct bd_info *bd)
{
	struct armdfec_device *darmdfec = to_darmdfec(dev);
	struct armdfec_reg *regs = darmdfec->regs;
	int phy_adr;
	u32 temp;

	armdfec_init_rx_desc_ring(darmdfec);

	/* Disable interrupts */
	writel(0, &regs->im);
	writel(0, &regs->ic);
	/* Write to ICR to clear interrupts. */
	writel(0, &regs->iwc);

	/*
	 * Abort any transmit and receive operations and put DMA
	 * in idle state.
	 */
	abortdma(dev);

	/* Initialize address hash table */
	init_hashtable(dev);

	/* SDMA configuration */
	writel(SDCR_BSZ8 |	/* Burst size = 32 bytes */
		SDCR_RIFB |	/* Rx interrupt on frame */
		SDCR_BLMT |	/* Little endian transmit */
		SDCR_BLMR |	/* Little endian receive */
		SDCR_RC_MAX_RETRANS,	/* Max retransmit count */
		&regs->sdma_conf);
	/* Port Configuration */
	writel(PCR_HS, &regs->pconf);	/* Hash size is 1/2kb */

	/* Set extended port configuration */
	writel(PCXR_2BSM |		/* Two byte suffix aligns IP hdr */
		PCXR_DSCP_EN |		/* Enable DSCP in IP */
		PCXR_MFL_1536 |		/* Set MTU = 1536 */
		PCXR_FLP |		/* do not force link pass */
		PCXR_TX_HIGH_PRI,	/* Transmit - high priority queue */
		&regs->pconf_ext);

	update_hash_table_mac_address(darmdfec, NULL, dev->enetaddr);

	/* Update TX and RX queue descriptor register */
	temp = (u32)&regs->txcdp[TXQ];
	writel((u32)darmdfec->p_txdesc, temp);
	temp = (u32)&regs->rxfdp[RXQ];
	writel((u32)darmdfec->p_rxdesc, temp);
	temp = (u32)&regs->rxcdp[RXQ];
	writel((u32)darmdfec->p_rxdesc_curr, temp);

	/* Enable Interrupts */
	writel(ALL_INTS, &regs->im);

	/* Enable Ethernet Port */
	setbits_le32(&regs->pconf, PCR_EN);

	/* Enable RX DMA engine */
	setbits_le32(&regs->sdma_cmd, SDMA_CMD_ERD);

#ifdef DEBUG
	eth_dump_regs(dev);
#endif

#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII))

#if defined(CONFIG_PHY_BASE_ADR)
	miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ, CONFIG_PHY_BASE_ADR);
#else
	/* Search phy address from range 0-31 */
	phy_adr = ethernet_phy_detect(dev);
	if (phy_adr < 0) {
		printf("ARMD100 FEC: PHY not detected at address range 0-31\n");
		return -1;
	} else {
		debug("ARMD100 FEC: PHY detected at addr %d\n", phy_adr);
		miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ, phy_adr);
	}
#endif

#if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
	/* Wait up to 5s for the link status */
	for (i = 0; i < 5; i++) {
		u16 phy_adr;

		miiphy_read(dev->name, 0xFF, 0xFF, &phy_adr);
		/* Return if we get link up */
		if (miiphy_link(dev->name, phy_adr))
			return 0;
		udelay(1000000);
	}

	printf("ARMD100 FEC: No link on %s\n", dev->name);
	return -1;
#endif
#endif
	return 0;
}

static void armdfec_halt(struct eth_device *dev)
{
	struct armdfec_device *darmdfec = to_darmdfec(dev);
	struct armdfec_reg *regs = darmdfec->regs;

	/* Stop RX DMA */
	clrbits_le32(&regs->sdma_cmd, SDMA_CMD_ERD);

	/*
	 * Abort any transmit and receive operations and put DMA
	 * in idle state.
	 */
	abortdma(dev);

	/* Disable interrupts */
	writel(0, &regs->im);
	writel(0, &regs->ic);
	writel(0, &regs->iwc);

	/* Disable Port */
	clrbits_le32(&regs->pconf, PCR_EN);
}

static int armdfec_send(struct eth_device *dev, void *dataptr, int datasize)
{
	struct armdfec_device *darmdfec = to_darmdfec(dev);
	struct armdfec_reg *regs = darmdfec->regs;
	struct tx_desc *p_txdesc = darmdfec->p_txdesc;
	void *p = (void *)dataptr;
	int retry = PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS;
	u32 cmd_sts, temp;

	/* Copy buffer if it's misaligned */
	if ((u32)dataptr & 0x07) {
		if (datasize > PKTSIZE_ALIGN) {
			printf("ARMD100 FEC: Non-aligned data too large (%d)\n",
					datasize);
			return -1;
		}
		memcpy(darmdfec->p_aligned_txbuf, p, datasize);
		p = darmdfec->p_aligned_txbuf;
	}

	p_txdesc->cmd_sts = TX_ZERO_PADDING | TX_GEN_CRC;
	p_txdesc->cmd_sts |= TX_FIRST_DESC | TX_LAST_DESC;
	p_txdesc->cmd_sts |= BUF_OWNED_BY_DMA;
	p_txdesc->cmd_sts |= TX_EN_INT;
	p_txdesc->buf_ptr = p;
	p_txdesc->byte_cnt = datasize;

	/* Apply send command using high priority TX queue */
	temp = (u32)&regs->txcdp[TXQ];
	writel((u32)p_txdesc, temp);
	writel(SDMA_CMD_TXDL | SDMA_CMD_TXDH | SDMA_CMD_ERD, &regs->sdma_cmd);

	/*
	 * wait for packet xmit completion
	 */
	cmd_sts = readl(&p_txdesc->cmd_sts);
	while (cmd_sts & BUF_OWNED_BY_DMA) {
		/* return fail if error is detected */
		if ((cmd_sts & (TX_ERROR | TX_LAST_DESC)) ==
			(TX_ERROR | TX_LAST_DESC)) {
			printf("ARMD100 FEC: (%s) in xmit packet\n", __func__);
			return -1;
		}
		cmd_sts = readl(&p_txdesc->cmd_sts);
		if (!(retry--)) {
			printf("ARMD100 FEC: (%s) xmit packet timeout!\n",
					__func__);
			return -1;
		}
	}

	return 0;
}

static int armdfec_recv(struct eth_device *dev)
{
	struct armdfec_device *darmdfec = to_darmdfec(dev);
	struct rx_desc *p_rxdesc_curr = darmdfec->p_rxdesc_curr;
	u32 cmd_sts;
	u32 timeout = 0;
	u32 temp;

	/* wait untill rx packet available or timeout */
	do {
		if (timeout < PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS) {
			timeout++;
		} else {
			debug("ARMD100 FEC: %s time out...\n", __func__);
			return -1;
		}
	} while (readl(&p_rxdesc_curr->cmd_sts) & BUF_OWNED_BY_DMA);

	if (p_rxdesc_curr->byte_cnt != 0) {
		debug("ARMD100 FEC: %s: Received %d byte Packet @ 0x%x"
				"(cmd_sts= %08x)\n", __func__,
				(u32)p_rxdesc_curr->byte_cnt,
				(u32)p_rxdesc_curr->buf_ptr,
				(u32)p_rxdesc_curr->cmd_sts);
	}

	/*
	 * In case received a packet without first/last bits on
	 * OR the error summary bit is on,
	 * the packets needs to be dropeed.
	 */
	cmd_sts = readl(&p_rxdesc_curr->cmd_sts);

	if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
			(RX_FIRST_DESC | RX_LAST_DESC)) {
		printf("ARMD100 FEC: (%s) Dropping packet spread on"
			" multiple descriptors\n", __func__);
	} else if (cmd_sts & RX_ERROR) {
		printf("ARMD100 FEC: (%s) Dropping packet with errors\n",
				__func__);
	} else {
		/* !!! call higher layer processing */
		debug("ARMD100 FEC: (%s) Sending Received packet to"
		      " upper layer (net_process_received_packet)\n", __func__);

		/*
		 * let the upper layer handle the packet, subtract offset
		 * as two dummy bytes are added in received buffer see
		 * PORT_CONFIG_EXT register bit TWO_Byte_Stuff_Mode bit.
		 */
		net_process_received_packet(
			p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET,
			(int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET));
	}
	/*
	 * free these descriptors and point next in the ring
	 */
	p_rxdesc_curr->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT;
	p_rxdesc_curr->buf_size = PKTSIZE_ALIGN;
	p_rxdesc_curr->byte_cnt = 0;

	temp = (u32)&darmdfec->p_rxdesc_curr;
	writel((u32)p_rxdesc_curr->nxtdesc_p, temp);

	return 0;
}

int armada100_fec_register(unsigned long base_addr)
{
	struct armdfec_device *darmdfec;
	struct eth_device *dev;

	darmdfec = malloc(sizeof(struct armdfec_device));
	if (!darmdfec)
		goto error;

	memset(darmdfec, 0, sizeof(struct armdfec_device));

	darmdfec->htpr = memalign(8, HASH_ADDR_TABLE_SIZE);
	if (!darmdfec->htpr)
		goto error1;

	darmdfec->p_rxdesc = memalign(PKTALIGN,
			ARMDFEC_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);

	if (!darmdfec->p_rxdesc)
		goto error1;

	darmdfec->p_rxbuf = memalign(PKTALIGN, RINGSZ * PKTSIZE_ALIGN + 1);
	if (!darmdfec->p_rxbuf)
		goto error1;

	darmdfec->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
	if (!darmdfec->p_aligned_txbuf)
		goto error1;

	darmdfec->p_txdesc = memalign(PKTALIGN, sizeof(struct tx_desc) + 1);
	if (!darmdfec->p_txdesc)
		goto error1;

	dev = &darmdfec->dev;
	/* Assign ARMADA100 Fast Ethernet Controller Base Address */
	darmdfec->regs = (void *)base_addr;

	/* must be less than sizeof(dev->name) */
	strcpy(dev->name, "armd-fec0");

	dev->init = armdfec_init;
	dev->halt = armdfec_halt;
	dev->send = armdfec_send;
	dev->recv = armdfec_recv;

	eth_register(dev);

#if defined(CONFIG_MII) || 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 = smi_reg_read;
	mdiodev->write = smi_reg_write;

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

error1:
	free(darmdfec->p_aligned_txbuf);
	free(darmdfec->p_rxbuf);
	free(darmdfec->p_rxdesc);
	free(darmdfec->htpr);
error:
	free(darmdfec);
	printf("AMD100 FEC: (%s) Failed to allocate memory\n", __func__);
	return -1;
}
