123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694 |
- /*
- * (C) Copyright 2005-2006
- * Stefan Roese, DENX Software Engineering, sr@denx.de.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
- #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>
- #ifdef CONFIG_IXP4XX_NPE
- 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 + CFG_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 + (CFG_CACHELINE_SIZE-1)) & ~(CFG_CACHELINE_SIZE-1);
- count++;
- if ((npe_alloc_free + size) < npe_alloc_end) {
- p = npe_alloc_free;
- npe_alloc_free += size;
- } else {
- printf("%s: 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__);
- miiphy_read (dev->name, p_npe->phy_no, PHY_BMSR, ®_short);
- /*
- * Wait if PHY is capable of autonegotiation and autonegotiation is not complete
- */
- if ((reg_short & PHY_BMSR_AUTN_ABLE) && !(reg_short & PHY_BMSR_AUTN_COMP)) {
- puts ("Waiting for PHY auto negotiation to complete");
- i = 0;
- while (!(reg_short & PHY_BMSR_AUTN_COMP)) {
- /*
- * Timeout reached ?
- */
- if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
- puts (" TIMEOUT !\n");
- break;
- }
- if ((i++ % 1000) == 0) {
- putc ('.');
- miiphy_read (dev->name, p_npe->phy_no, PHY_BMSR, ®_short);
- }
- udelay (1000); /* 1 ms */
- }
- puts (" done\n");
- udelay (500000); /* another 500 ms (results in faster booting) */
- }
- 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 +
- CFG_CACHELINE_SIZE - 1) & ~(CFG_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, volatile 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;
- for (eth_num = 0; eth_num < CFG_NPE_NUMS; eth_num++) {
- /* See if we can actually bring up the interface, otherwise, skip it */
- switch (eth_num) {
- default: /* fall through */
- case 0:
- if (memcmp (bis->bi_enetaddr, "\0\0\0\0\0\0", 6) == 0) {
- continue;
- }
- break;
- #ifdef CONFIG_HAS_ETH1
- case 1:
- if (memcmp (bis->bi_enet1addr, "\0\0\0\0\0\0", 6) == 0) {
- continue;
- }
- break;
- #endif
- }
- /* 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));
- switch (eth_num) {
- default: /* fall through */
- case 0:
- memcpy(dev->enetaddr, bis->bi_enetaddr, 6);
- p_npe->eth_id = 0;
- p_npe->phy_no = CONFIG_PHY_ADDR;
- break;
- #ifdef CONFIG_HAS_ETH1
- case 1:
- memcpy(dev->enetaddr, bis->bi_enet1addr, 6);
- p_npe->eth_id = 1;
- p_npe->phy_no = CONFIG_PHY1_ADDR;
- break;
- #endif
- }
- 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:
- /*
- * If it is B0 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 +
- CFG_CACHELINE_SIZE - 1)
- & ~(CFG_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;
- }
- #endif /* CONFIG_IXP4XX_NPE */
|