⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 npe.c

📁 Uboot源码,非常通用的bootloader.适用于各种平台的Linux系统引导.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * (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_NPEstatic 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);		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -