/*
 * (C) Copyright 2005-2006
 * Stefan Roese, DENX Software Engineering, sr@denx.de.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#if 0
#define DEBUG		/* define for debug output */
#endif

#include <config.h>
#include <common.h>
#include <net.h>
#include <miiphy.h>
#include <malloc.h>
#include <asm/processor.h>
#include <asm/arch-ixp/ixp425.h>

#include <IxOsal.h>
#include <IxEthAcc.h>
#include <IxEthDB.h>
#include <IxNpeDl.h>
#include <IxQMgr.h>
#include <IxNpeMh.h>
#include <ix_ossl.h>
#include <IxFeatureCtrl.h>

#include <npe.h>

static IxQMgrDispatcherFuncPtr qDispatcherFunc = NULL;
static int npe_exists[NPE_NUM_PORTS];
static int npe_used[NPE_NUM_PORTS];

/* A little extra so we can align to cacheline. */
static u8 npe_alloc_pool[NPE_MEM_POOL_SIZE + CONFIG_SYS_CACHELINE_SIZE - 1];
static u8 *npe_alloc_end;
static u8 *npe_alloc_free;

static void *npe_alloc(int size)
{
	static int count = 0;
	void *p = NULL;

	size = (size + (CONFIG_SYS_CACHELINE_SIZE-1)) & ~(CONFIG_SYS_CACHELINE_SIZE-1);
	count++;

	if ((npe_alloc_free + size) < npe_alloc_end) {
		p = npe_alloc_free;
		npe_alloc_free += size;
	} else {
		printf("npe_alloc: failed (count=%d, size=%d)!\n", count, size);
	}
	return p;
}

/* Not interrupt safe! */
static void mbuf_enqueue(IX_OSAL_MBUF **q, IX_OSAL_MBUF *new)
{
	IX_OSAL_MBUF *m = *q;

	IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(new) = NULL;

	if (m) {
		while(IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m))
			m = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m);
		IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = new;
	} else
		*q = new;
}

/* Not interrupt safe! */
static IX_OSAL_MBUF *mbuf_dequeue(IX_OSAL_MBUF **q)
{
	IX_OSAL_MBUF *m = *q;
	if (m)
		*q = IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m);
	return m;
}

static void reset_tx_mbufs(struct npe* p_npe)
{
	IX_OSAL_MBUF *m;
	int i;

	p_npe->txQHead = NULL;

	for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS; i++) {
		m = &p_npe->tx_mbufs[i];

		memset(m, 0, sizeof(*m));

		IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->tx_pkts[i * NPE_PKT_SIZE];
		IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE;
		mbuf_enqueue(&p_npe->txQHead, m);
	}
}

static void reset_rx_mbufs(struct npe* p_npe)
{
	IX_OSAL_MBUF *m;
	int i;

	p_npe->rxQHead = NULL;

	HAL_DCACHE_INVALIDATE(p_npe->rx_pkts, NPE_PKT_SIZE *
			      CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS);

	for (i = 0; i < CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS; i++) {
		m = &p_npe->rx_mbufs[i];

		memset(m, 0, sizeof(*m));

		IX_OSAL_MBUF_MDATA(m) = (void *)&p_npe->rx_pkts[i * NPE_PKT_SIZE];
		IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE;

		if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) {
			printf("ixEthAccPortRxFreeReplenish failed for port %d\n", p_npe->eth_id);
			break;
		}
	}
}

static void init_rx_mbufs(struct npe* p_npe)
{
	p_npe->rxQHead = NULL;

	p_npe->rx_pkts = npe_alloc(NPE_PKT_SIZE *
				   CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS);
	if (p_npe->rx_pkts == NULL) {
		printf("alloc of packets failed.\n");
		return;
	}

	p_npe->rx_mbufs = (IX_OSAL_MBUF *)
		npe_alloc(sizeof(IX_OSAL_MBUF) *
			  CONFIG_DEVS_ETH_INTEL_NPE_MAX_RX_DESCRIPTORS);
	if (p_npe->rx_mbufs == NULL) {
		printf("alloc of mbufs failed.\n");
		return;
	}

	reset_rx_mbufs(p_npe);
}

static void init_tx_mbufs(struct npe* p_npe)
{
	p_npe->tx_pkts = npe_alloc(NPE_PKT_SIZE *
				   CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS);
	if (p_npe->tx_pkts == NULL) {
		printf("alloc of packets failed.\n");
		return;
	}

	p_npe->tx_mbufs = (IX_OSAL_MBUF *)
		npe_alloc(sizeof(IX_OSAL_MBUF) *
			  CONFIG_DEVS_ETH_INTEL_NPE_MAX_TX_DESCRIPTORS);
	if (p_npe->tx_mbufs == NULL) {
		printf("alloc of mbufs failed.\n");
		return;
	}

	reset_tx_mbufs(p_npe);
}

/* Convert IX_ETH_PORT_n to IX_NPEMH_NPEID_NPEx */
static int __eth_to_npe(int eth_id)
{
	switch(eth_id) {
	case IX_ETH_PORT_1:
		return IX_NPEMH_NPEID_NPEB;

	case IX_ETH_PORT_2:
		return IX_NPEMH_NPEID_NPEC;

	case IX_ETH_PORT_3:
		return IX_NPEMH_NPEID_NPEA;
	}
	return 0;
}

/* Poll the CSR machinery. */
static void npe_poll(int eth_id)
{
	if (qDispatcherFunc != NULL) {
		ixNpeMhMessagesReceive(__eth_to_npe(eth_id));
		(*qDispatcherFunc)(IX_QMGR_QUELOW_GROUP);
	}
}

/* ethAcc RX callback */
static void npe_rx_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid)
{
	struct npe* p_npe = (struct npe *)cbTag;

	if (IX_OSAL_MBUF_MLEN(m) > 0) {
		mbuf_enqueue(&p_npe->rxQHead, m);

		if (p_npe->rx_write == ((p_npe->rx_read-1) & (PKTBUFSRX-1))) {
			debug("Rx overflow: rx_write=%d rx_read=%d\n",
			      p_npe->rx_write, p_npe->rx_read);
		} else {
			debug("Received message #%d (len=%d)\n", p_npe->rx_write,
			      IX_OSAL_MBUF_MLEN(m));
			memcpy((void *)NetRxPackets[p_npe->rx_write], IX_OSAL_MBUF_MDATA(m),
			       IX_OSAL_MBUF_MLEN(m));
			p_npe->rx_len[p_npe->rx_write] = IX_OSAL_MBUF_MLEN(m);
			p_npe->rx_write++;
			if (p_npe->rx_write == PKTBUFSRX)
				p_npe->rx_write = 0;

#ifdef CONFIG_PRINT_RX_FRAMES
			{
				u8 *ptr = IX_OSAL_MBUF_MDATA(m);
				int i;

				for (i=0; i<60; i++) {
					debug("%02x ", *ptr++);
				}
				debug("\n");
			}
#endif
		}

		m = mbuf_dequeue(&p_npe->rxQHead);
	} else {
		debug("Received frame with length 0!!!\n");
		m = mbuf_dequeue(&p_npe->rxQHead);
	}

	/* Now return mbuf to NPE */
	IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE;
	IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL;
	IX_OSAL_MBUF_FLAGS(m) = 0;

	if(ixEthAccPortRxFreeReplenish(p_npe->eth_id, m) != IX_SUCCESS) {
		debug("npe_rx_callback: Error returning mbuf.\n");
	}
}

/* ethAcc TX callback */
static void npe_tx_callback(u32 cbTag, IX_OSAL_MBUF *m)
{
	struct npe* p_npe = (struct npe *)cbTag;

	debug("%s\n", __FUNCTION__);

	IX_OSAL_MBUF_MLEN(m) = IX_OSAL_MBUF_PKT_LEN(m) = NPE_PKT_SIZE;
	IX_OSAL_MBUF_NEXT_BUFFER_IN_PKT_PTR(m) = NULL;
	IX_OSAL_MBUF_FLAGS(m) = 0;

	mbuf_enqueue(&p_npe->txQHead, m);
}


static int npe_set_mac_address(struct eth_device *dev)
{
	struct npe *p_npe = (struct npe *)dev->priv;
	IxEthAccMacAddr npeMac;

	debug("%s\n", __FUNCTION__);

	/* Set MAC address */
	memcpy(npeMac.macAddress, dev->enetaddr, 6);

	if (ixEthAccPortUnicastMacAddressSet(p_npe->eth_id, &npeMac) != IX_ETH_ACC_SUCCESS) {
		printf("Error setting unicast address! %02x:%02x:%02x:%02x:%02x:%02x\n",
		       npeMac.macAddress[0], npeMac.macAddress[1],
		       npeMac.macAddress[2], npeMac.macAddress[3],
		       npeMac.macAddress[4], npeMac.macAddress[5]);
		return 0;
	}

	return 1;
}

/* Boot-time CSR library initialization. */
static int npe_csr_load(void)
{
	int i;

	if (ixQMgrInit() != IX_SUCCESS) {
		debug("Error initialising queue manager!\n");
		return 0;
	}

	ixQMgrDispatcherLoopGet(&qDispatcherFunc);

	if(ixNpeMhInitialize(IX_NPEMH_NPEINTERRUPTS_YES) != IX_SUCCESS) {
		printf("Error initialising NPE Message handler!\n");
		return 0;
	}

	if (npe_used[IX_ETH_PORT_1] && npe_exists[IX_ETH_PORT_1] &&
	    ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEB_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS)
	    != IX_SUCCESS) {
		printf("Error downloading firmware to NPE-B!\n");
		return 0;
	}

	if (npe_used[IX_ETH_PORT_2] && npe_exists[IX_ETH_PORT_2] &&
	    ixNpeDlNpeInitAndStart(IX_NPEDL_NPEIMAGE_NPEC_ETH_LEARN_FILTER_SPAN_FIREWALL_VLAN_QOS)
	    != IX_SUCCESS) {
		printf("Error downloading firmware to NPE-C!\n");
		return 0;
	}

	/* don't need this for U-Boot */
	ixFeatureCtrlSwConfigurationWrite(IX_FEATURECTRL_ETH_LEARNING, false);

	if (ixEthAccInit() != IX_ETH_ACC_SUCCESS) {
		printf("Error initialising Ethernet access driver!\n");
		return 0;
	}

	for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) {
		if (!npe_used[i] || !npe_exists[i])
			continue;
		if (ixEthAccPortInit(i) != IX_ETH_ACC_SUCCESS) {
			printf("Error initialising Ethernet port%d!\n", i);
		}
		if (ixEthAccTxSchedulingDisciplineSet(i, FIFO_NO_PRIORITY) != IX_ETH_ACC_SUCCESS) {
			printf("Error setting scheduling discipline for port %d.\n", i);
		}
		if (ixEthAccPortRxFrameAppendFCSDisable(i) != IX_ETH_ACC_SUCCESS) {
			printf("Error disabling RX FCS for port %d.\n", i);
		}
		if (ixEthAccPortTxFrameAppendFCSEnable(i) != IX_ETH_ACC_SUCCESS) {
			printf("Error enabling TX FCS for port %d.\n", i);
		}
	}

	return 1;
}

static int npe_init(struct eth_device *dev, bd_t * bis)
{
	struct npe *p_npe = (struct npe *)dev->priv;
	int i;
	u16 reg_short;
	int speed;
	int duplex;

	debug("%s: 1\n", __FUNCTION__);

#ifdef CONFIG_MII_NPE0_FIXEDLINK
	if (0 == p_npe->eth_id) {
		speed = CONFIG_MII_NPE0_SPEED;
		duplex = CONFIG_MII_NPE0_FULLDUPLEX ? FULL : HALF;
	} else
#endif
#ifdef CONFIG_MII_NPE1_FIXEDLINK
	if (1 == p_npe->eth_id) {
		speed = CONFIG_MII_NPE1_SPEED;
		duplex = CONFIG_MII_NPE1_FULLDUPLEX ? FULL : HALF;
	} else
#endif
	{
		miiphy_read(dev->name, p_npe->phy_no, MII_BMSR, &reg_short);

		/*
		 * Wait if PHY is capable of autonegotiation and
		 * autonegotiation is not complete
		 */
		if ((reg_short & BMSR_ANEGCAPABLE) &&
		    !(reg_short & BMSR_ANEGCOMPLETE)) {
			puts("Waiting for PHY auto negotiation to complete");
			i = 0;
			while (!(reg_short & BMSR_ANEGCOMPLETE)) {
				/*
				 * Timeout reached ?
				 */
				if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
					puts(" TIMEOUT !\n");
					break;
				}

				if ((i++ % 1000) == 0) {
					putc('.');
					miiphy_read(dev->name, p_npe->phy_no,
						     MII_BMSR, &reg_short);
				}
				udelay(1000);	/* 1 ms */
			}
			puts(" done\n");
			/* another 500 ms (results in faster booting) */
			udelay(500000);
		}
		speed = miiphy_speed(dev->name, p_npe->phy_no);
		duplex = miiphy_duplex(dev->name, p_npe->phy_no);
	}

	if (p_npe->print_speed) {
		p_npe->print_speed = 0;
		printf ("ENET Speed is %d Mbps - %s duplex connection\n",
			(int) speed, (duplex == HALF) ? "HALF" : "FULL");
	}

	npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool);
	npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool +
				 CONFIG_SYS_CACHELINE_SIZE - 1) & ~(CONFIG_SYS_CACHELINE_SIZE - 1));

	/* initialize mbuf pool */
	init_rx_mbufs(p_npe);
	init_tx_mbufs(p_npe);

	if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_callback,
					   (u32)p_npe) != IX_ETH_ACC_SUCCESS) {
		printf("can't register RX callback!\n");
		return -1;
	}

	if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_callback,
					       (u32)p_npe) != IX_ETH_ACC_SUCCESS) {
		printf("can't register TX callback!\n");
		return -1;
	}

	npe_set_mac_address(dev);

	if (ixEthAccPortEnable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) {
		printf("can't enable port!\n");
		return -1;
	}

	p_npe->active = 1;

	return 0;
}

#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */
/* Uninitialize CSR library. */
static void npe_csr_unload(void)
{
	ixEthAccUnload();
	ixEthDBUnload();
	ixNpeMhUnload();
	ixQMgrUnload();
}

/* callback which is used by ethAcc to recover RX buffers when stopping */
static void npe_rx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m, IxEthAccPortId portid)
{
	debug("%s\n", __FUNCTION__);
}

/* callback which is used by ethAcc to recover TX buffers when stopping */
static void npe_tx_stop_callback(u32 cbTag, IX_OSAL_MBUF *m)
{
	debug("%s\n", __FUNCTION__);
}
#endif

static void npe_halt(struct eth_device *dev)
{
	struct npe *p_npe = (struct npe *)dev->priv;
	int i;

	debug("%s\n", __FUNCTION__);

	/* Delay to give time for recovery of mbufs */
	for (i = 0; i < 100; i++) {
		npe_poll(p_npe->eth_id);
		udelay(100);
	}

#if 0 /* test-only: probably have to deal with it when booting linux (for a clean state) */
	if (ixEthAccPortRxCallbackRegister(p_npe->eth_id, npe_rx_stop_callback,
					   (u32)p_npe) != IX_ETH_ACC_SUCCESS) {
		debug("Error registering rx callback!\n");
	}

	if (ixEthAccPortTxDoneCallbackRegister(p_npe->eth_id, npe_tx_stop_callback,
					       (u32)p_npe) != IX_ETH_ACC_SUCCESS) {
		debug("Error registering tx callback!\n");
	}

	if (ixEthAccPortDisable(p_npe->eth_id) != IX_ETH_ACC_SUCCESS) {
		debug("npe_stop: Error disabling NPEB!\n");
	}

	/* Delay to give time for recovery of mbufs */
	for (i = 0; i < 100; i++) {
		npe_poll(p_npe->eth_id);
		udelay(10000);
	}

	/*
	 * For U-Boot only, we are probably launching Linux or other OS that
	 * needs a clean slate for its NPE library.
	 */
#if 0 /* test-only */
	for (i = 0; i < IX_ETH_ACC_NUMBER_OF_PORTS; i++) {
		if (npe_used[i] && npe_exists[i])
			if (ixNpeDlNpeStopAndReset(__eth_to_npe(i)) != IX_SUCCESS)
				printf("Failed to stop and reset NPE B.\n");
	}
#endif

#endif
	p_npe->active = 0;
}


static int npe_send(struct eth_device *dev, void *packet, int len)
{
	struct npe *p_npe = (struct npe *)dev->priv;
	u8 *dest;
	int err;
	IX_OSAL_MBUF *m;

	debug("%s\n", __FUNCTION__);
	m = mbuf_dequeue(&p_npe->txQHead);
	dest = IX_OSAL_MBUF_MDATA(m);
	IX_OSAL_MBUF_PKT_LEN(m) = IX_OSAL_MBUF_MLEN(m) = len;
	IX_OSAL_MBUF_NEXT_PKT_IN_CHAIN_PTR(m) = NULL;

	memcpy(dest, (char *)packet, len);

	if ((err = ixEthAccPortTxFrameSubmit(p_npe->eth_id, m, IX_ETH_ACC_TX_DEFAULT_PRIORITY))
	    != IX_ETH_ACC_SUCCESS) {
		printf("npe_send: Can't submit frame. err[%d]\n", err);
		mbuf_enqueue(&p_npe->txQHead, m);
		return 0;
	}

#ifdef DEBUG_PRINT_TX_FRAMES
	{
		u8 *ptr = IX_OSAL_MBUF_MDATA(m);
		int i;

		for (i=0; i<IX_OSAL_MBUF_MLEN(m); i++) {
			printf("%02x ", *ptr++);
		}
		printf(" (tx-len=%d)\n", IX_OSAL_MBUF_MLEN(m));
	}
#endif

	npe_poll(p_npe->eth_id);

	return len;
}

static int npe_rx(struct eth_device *dev)
{
	struct npe *p_npe = (struct npe *)dev->priv;

	debug("%s\n", __FUNCTION__);
	npe_poll(p_npe->eth_id);

	debug("%s: rx_write=%d rx_read=%d\n", __FUNCTION__, p_npe->rx_write, p_npe->rx_read);
	while (p_npe->rx_write != p_npe->rx_read) {
		debug("Reading message #%d\n", p_npe->rx_read);
		NetReceive(NetRxPackets[p_npe->rx_read], p_npe->rx_len[p_npe->rx_read]);
		p_npe->rx_read++;
		if (p_npe->rx_read == PKTBUFSRX)
			p_npe->rx_read = 0;
	}

	return 0;
}

int npe_initialize(bd_t * bis)
{
	static int virgin = 0;
	struct eth_device *dev;
	int eth_num = 0;
	struct npe *p_npe = NULL;
	uchar enetaddr[6];

	for (eth_num = 0; eth_num < CONFIG_SYS_NPE_NUMS; eth_num++) {

		/* See if we can actually bring up the interface, otherwise, skip it */
#ifdef CONFIG_HAS_ETH1
		if (eth_num == 1) {
			if (!eth_getenv_enetaddr("eth1addr", enetaddr))
				continue;
		} else
#endif
			if (!eth_getenv_enetaddr("ethaddr", enetaddr))
				continue;

		/* Allocate device structure */
		dev = (struct eth_device *)malloc(sizeof(*dev));
		if (dev == NULL) {
			printf ("%s: Cannot allocate eth_device %d\n", __FUNCTION__, eth_num);
			return -1;
		}
		memset(dev, 0, sizeof(*dev));

		/* Allocate our private use data */
		p_npe = (struct npe *)malloc(sizeof(struct npe));
		if (p_npe == NULL) {
			printf("%s: Cannot allocate private hw data for eth_device %d",
			       __FUNCTION__, eth_num);
			free(dev);
			return -1;
		}
		memset(p_npe, 0, sizeof(struct npe));

		p_npe->eth_id = eth_num;
		memcpy(dev->enetaddr, enetaddr, 6);
#ifdef CONFIG_HAS_ETH1
		if (eth_num == 1)
			p_npe->phy_no = CONFIG_PHY1_ADDR;
		else
#endif
			p_npe->phy_no = CONFIG_PHY_ADDR;

		sprintf(dev->name, "NPE%d", eth_num);
		dev->priv = (void *)p_npe;
		dev->init = npe_init;
		dev->halt = npe_halt;
		dev->send = npe_send;
		dev->recv = npe_rx;

		p_npe->print_speed = 1;

		if (0 == virgin) {
			virgin = 1;

			if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP42X) {
				switch (ixFeatureCtrlProductIdRead() & IX_FEATURE_CTRL_SILICON_STEPPING_MASK) {
				case IX_FEATURE_CTRL_SILICON_TYPE_B0:
				default: /* newer than B0 */
					/*
					 * If it is B0 or newer Silicon, we
					 * only enable port when its
					 * corresponding Eth Coprocessor is
					 * available.
					 */
					if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
					    IX_FEATURE_CTRL_COMPONENT_ENABLED)
						npe_exists[IX_ETH_PORT_1] = true;

					if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
					    IX_FEATURE_CTRL_COMPONENT_ENABLED)
						npe_exists[IX_ETH_PORT_2] = true;
					break;
				case IX_FEATURE_CTRL_SILICON_TYPE_A0:
					/*
					 * If it is A0 Silicon, we enable both as both Eth Coprocessors
					 * are available.
					 */
					npe_exists[IX_ETH_PORT_1] = true;
					npe_exists[IX_ETH_PORT_2] = true;
					break;
				}
			} else if (ixFeatureCtrlDeviceRead() == IX_FEATURE_CTRL_DEVICE_TYPE_IXP46X) {
				if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH0) ==
				    IX_FEATURE_CTRL_COMPONENT_ENABLED)
					npe_exists[IX_ETH_PORT_1] = true;

				if (ixFeatureCtrlComponentCheck(IX_FEATURECTRL_ETH1) ==
				    IX_FEATURE_CTRL_COMPONENT_ENABLED)
					npe_exists[IX_ETH_PORT_2] = true;
			}

			npe_used[IX_ETH_PORT_1] = 1;
			npe_used[IX_ETH_PORT_2] = 1;

			npe_alloc_end = npe_alloc_pool + sizeof(npe_alloc_pool);
			npe_alloc_free = (u8 *)(((unsigned)npe_alloc_pool +
						 CONFIG_SYS_CACHELINE_SIZE - 1)
						& ~(CONFIG_SYS_CACHELINE_SIZE - 1));

			if (!npe_csr_load())
				return 0;
		}

		eth_register(dev);

#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
		miiphy_register(dev->name, npe_miiphy_read, npe_miiphy_write);
#endif

	}			/* end for each supported device */

	return 1;
}
