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

📄 keymile_hdlc_enet.c

📁 uboot200903最新版本的通用uboot
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * (C) Copyright 2008 * Gary Jennejohn, DENX Software Engineering GmbH, garyj@denx.de. * * Based in part on cpu/mpc8260/ether_scc.c. * * 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 */#include <common.h>#include <malloc.h>#include <net.h>#ifdef CONFIG_KEYMILE_HDLC_ENET#ifdef TEST_IT#include <command.h>#endif#include "keymile_hdlc_enet.h"extern char keymile_slot;	/* our slot number in the backplane *//* Allow up to about 50 ms for sending */#define TOUT_LOOP	50000/* * Since, except during initialization, ethact is always HDLC ETHERNET * while we're in the driver, just use serial_printf() everywhere for * output.  This avoids possible conflicts when netconsole is being * used. */#define dprintf(fmt, args...)	serial_printf(fmt, ##args)/* Cannot use the storage from net.c because we allocate larger buffers */static volatile uchar MyPktBuf[HDLC_PKTBUFSRX * PKT_MAXBLR_SIZE + PKTALIGN];static volatile uchar *MyRxPackets[HDLC_PKTBUFSRX]; /* Receive packet */static unsigned int keymile_rxIdx;	/* index of the current RX buffer */static IPaddr_t cachedNumbers[CACHEDNUMBERS]; /* 4 bytes per entry */void initCachedNumbers(int);/*  * SCC Ethernet Tx and Rx buffer descriptors allocated at the  *  immr->udata_bd address on Dual-Port RAM  * Provide for Double Buffering  */typedef volatile struct CommonBufferDescriptor {    cbd_t txbd;			/* Tx BD */    cbd_t rxbd[HDLC_PKTBUFSRX];	/* Rx BD */} RTXBD;/* * This must be extern because it is allocated in DPRAM using CPM-sepcific * code. */static RTXBD *rtx;static int keymile_hdlc_enet_send(struct eth_device *, volatile void *, int);static int keymile_hdlc_enet_recv(struct eth_device *);void keymile_hdlc_enet_init_bds(RTXBD *);extern int keymile_hdlc_enet_init(struct eth_device *, bd_t *);extern void keymile_hdlc_enet_halt(struct eth_device *);/* flags in the buffer descriptor not defined anywhere else */#define BD_SC_CT	BD_SC_CD#define BD_SC_CR	0x04#define BD_SC_DE	0x80#ifndef BD_SC_TC#define BD_SC_TC	((ushort)0x0400)	/* Transmit CRC */#endif#define BD_SC_FIRST	BD_SC_TC#define BD_SC_STATS (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_CR | BD_SC_CD \		| BD_SC_OV | BD_SC_DE)#if defined(TEST_RX) || defined(TEST_TX) || defined(TEST_IT)static void hexdump(unsigned char *buf, int len){	int i;	const int bytesPerLine = 32;	if (len > 4 * bytesPerLine)		len = 4 * bytesPerLine;	dprintf("\t address: %08x\n", (unsigned int)buf);	for (i = 0; i < len; i++) {		if (i % bytesPerLine == 0)			dprintf("%04x: ", (unsigned short)i);		dprintf("%02x ", buf[i]);		if ((i + 1) % bytesPerLine == 0) {			dprintf("\n");			continue;		}		if ((i + 1) % 8 == 0)			printf(" ");	}	if (len % bytesPerLine)		dprintf("\n");}#endifint keymile_hdlc_enet_initialize(bd_t *bis){	struct eth_device *dev;	dev = (struct eth_device *) malloc(sizeof *dev);	memset(dev, 0, sizeof *dev);#ifdef TEST_IT	seth = dev;#endif	sprintf(dev->name, "HDLC ETHERNET");	dev->init   = keymile_hdlc_enet_init;	dev->halt   = keymile_hdlc_enet_halt;	dev->send   = keymile_hdlc_enet_send;	dev->recv   = keymile_hdlc_enet_recv;	eth_register(dev);	return 1;}/* * This is called from the board-specific driver after rtx is allocated. */void keymile_hdlc_enet_init_bds(RTXBD *board_rtx){	volatile cbd_t *bdp;	int i;	rtx = board_rtx;	keymile_rxIdx = 0;	/*	 * Initialize the buffer descriptors.	 */	bdp = &rtx->txbd;	bdp->cbd_sc = 0;	bdp->cbd_bufaddr = 0;	bdp->cbd_sc = BD_SC_WRAP;	/*	 *	Setup RX packet buffers, aligned correctly.	 *	Borrowed from net/net.c.	 */	MyRxPackets[0] = &MyPktBuf[0] + (PKTALIGN - 1);	MyRxPackets[0] -= (ulong)MyRxPackets[0] % PKTALIGN;	for (i = 1; i < HDLC_PKTBUFSRX; i++)		MyRxPackets[i] = MyRxPackets[0] + i * PKT_MAXBLR_SIZE;	bdp = &rtx->rxbd[0];	for (i = 0; i < HDLC_PKTBUFSRX; i++) {		bdp->cbd_sc = BD_SC_EMPTY;		/* Leave space at the start for INET header. */		bdp->cbd_bufaddr = (unsigned int)(MyRxPackets[i] +			INET_HDR_ALIGN);		bdp++;	}	bdp--;	bdp->cbd_sc |= BD_SC_WRAP;}/* * This returns the current port number for NETCONSOLE.  If nc_port * in netconsole.c weren't declared static we wouldn't need this. */static short get_netcons_port(void){	char *p;	short nc_port;	nc_port = 6666; /* default */	p = getenv("ncip");	if (p != NULL) {		p = strchr(p, ':');		if (p != NULL)			nc_port = simple_strtoul(p + 1, NULL, 10);	}	return htons(nc_port);}/* * Read the port numbers from the variables */void initCachedNumbers(int verbose){	char *str;	ushort port;	/* already in network order */	cachedNumbers[IP_ADDR] = getenv_IPaddr("ipaddr");	/* already in network order */	cachedNumbers[IP_SERVER] = getenv_IPaddr("serverip");	str = getenv("tftpsrcp");	if (str != NULL) {		/* avoid doing htons() again and again */		port = htons((ushort)simple_strtol(str, NULL, 10));		cachedNumbers[TFTP_SRC_PORT] = port;	} else		/* this can never be a valid port number */		cachedNumbers[TFTP_SRC_PORT] = (ulong)-1;	str = getenv("tftpdstp");	if (str != NULL) {		/* avoid doing htons() again and again */		port = htons((ushort)simple_strtol(str, NULL, 10));		cachedNumbers[TFTP_DST_PORT] = port;	} else		/* this is the default value */		cachedNumbers[TFTP_DST_PORT] = htons(WELL_KNOWN_PORT);	/* already in network order */	cachedNumbers[NETCONS_PORT] = get_netcons_port();	if (verbose) {		dprintf("\nIP Number Initialization:\n");		dprintf(" ip address          %08lx\n", cachedNumbers[IP_ADDR]);		dprintf(" server ip address   %08lx\n",			cachedNumbers[IP_SERVER]);		dprintf(" tftp client port    %ld\n",			cachedNumbers[TFTP_SRC_PORT]);		dprintf(" tftp server port    %ld\n",			cachedNumbers[TFTP_DST_PORT]);		dprintf(" netcons port        %ld\n",			cachedNumbers[NETCONS_PORT]);		dprintf(" slot number (hex)   %02x\n", keymile_slot);	}}static void keymile_hdlc_enet_doarp(volatile void *packet, int len){	ARP_t *arp;	IPaddr_t src_ip; /* U-Boot's IP */	IPaddr_t dest_ip; /* the mgcoge's IP */	unsigned char *packet_copy = malloc(len);	/*	 * Handling an ARP request means that a new transfer has started.	 * Update our cached parameters now.	 */	initCachedNumbers(0); /* may reinit port numbers */	/* special handling required for ARP */	arp = (ARP_t *)(packet + ETHER_HDR_SIZE);	/*	 *	XXXX	 * This is pretty dirty!  NetReceive only uses	 * a few fields when handling an ARP reply, so	 * we only modify those here.  This could	 * result in catastrophic failure at a later	 * time if the handler is modified!	 */	arp->ar_op = htons(ARPOP_REPLY);	/* save his/our IP */	src_ip = NetReadIP(&arp->ar_data[6]);	dest_ip = NetReadIP(&arp->ar_data[16]);	/* copy target IP to source IP */	NetCopyIP(&arp->ar_data[6], &dest_ip);	/* copy our IP to the right place */	NetCopyIP(&arp->ar_data[16], &src_ip);	/* always use 0x7f as the MAC for the coge */	arp->ar_data[0] = HDLC_UACUA;	/*	 * copy the packet	 * if NetReceive wants to write to stdout, it may overwrite packet	 * especially if stdout is set to nc!	 *	 * However, if the malloc() above fails then we can still try the	 * original packet, rather than causing the transfer to fail.	 */	if (packet_copy != NULL) {		memcpy(packet_copy, (char *)packet, len);		NetReceive(packet_copy, len);		free(packet_copy);	} else		NetReceive(packet, len);}/* * NOTE all callers ignore the returned value! * At the moment this only handles ARP Requests, TFTP and NETCONSOLE. */static int keymile_hdlc_enet_send(struct eth_device *dev, volatile void *packet,	int len){	int j;	uint data_addr;	int data_len;	struct icn_hdr header;	struct icn_frame *frame;	Ethernet_t *et;	ARP_t *arp;	IP_t *ip;	if (len > (MAX_FRAME_LENGTH - sizeof(header)))		return -1;	frame = NULL;

⌨️ 快捷键说明

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