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

📄 405gp_enet.c

📁 U-Boot1.1.2是最为常用的嵌入式系统Bootloader
💻 C
📖 第 1 页 / 共 3 页
字号:
				serviced = 1;				rc = 0;			}		}		/* port by port dispatch of emac interrupts */		if ((SEL_UIC_DEF(hw_p->devnum) & my_uicmsr) != 0) {	/* look for EMAC errors */			emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);			if ((hw_p->emac_ier & emac_isr) != 0) {				emac_err (dev, emac_isr);				serviced = 1;				rc = 0;			}		}		if (((hw_p->emac_ier & emac_isr) != 0) || ((MAL_UIC_ERR & my_uicmsr) != 0)) {			mtdcr (uicsr, MAL_UIC_DEF | SEL_UIC_DEF(hw_p->devnum)); /* Clear */			return (rc);		/* we had errors so get out */		}		/* handle MAX TX EOB interrupt from a tx */		if (my_uicmsr & UIC_MAL_TXEOB) {			mal_rx_eob = mfdcr (maltxeobisr);			mtdcr (maltxeobisr, mal_rx_eob);			mtdcr (uicsr, UIC_MAL_TXEOB);		}		/* handle MAL RX EOB  interupt from a receive */		/* check for EOB on valid channels	      */		if (my_uicmsr & UIC_MAL_RXEOB)		{			mal_rx_eob = mfdcr (malrxeobisr);			if ((mal_rx_eob & (0x80000000 >> hw_p->devnum)) != 0) {	/* call emac routine for channel x */				/* clear EOB				 mtdcr(malrxeobisr, mal_rx_eob); */				enet_rcv (dev, emac_isr);				/* indicate that we serviced an interrupt */				serviced = 1;				rc = 0;			}		}		mtdcr (uicsr, MAL_UIC_DEF|EMAC_UIC_DEF|EMAC_UIC_DEF1);	/* Clear */	}	while (serviced);	return (rc);}#endif/*-----------------------------------------------------------------------------+ *  MAL Error Routine *-----------------------------------------------------------------------------*/static void mal_err (struct eth_device *dev, unsigned long isr,		     unsigned long uic, unsigned long maldef,		     unsigned long mal_errr){	EMAC_405_HW_PST hw_p = dev->priv;	mtdcr (malesr, isr);	/* clear interrupt */	/* clear DE interrupt */	mtdcr (maltxdeir, 0xC0000000);	mtdcr (malrxdeir, 0x80000000);#ifdef INFO_405_ENET	printf ("\nMAL error occured.... ISR = %lx UIC = = %lx  MAL_DEF = %lx  MAL_ERR= %lx \n", isr, uic, maldef, mal_errr);#endif	eth_init (hw_p->bis);	/* start again... */}/*-----------------------------------------------------------------------------+ *  EMAC Error Routine *-----------------------------------------------------------------------------*/static void emac_err (struct eth_device *dev, unsigned long isr){	EMAC_405_HW_PST hw_p = dev->priv;	printf ("EMAC%d error occured.... ISR = %lx\n", hw_p->devnum, isr);	out32 (EMAC_ISR + hw_p->hw_addr, isr);}/*-----------------------------------------------------------------------------+ *  enet_rcv() handles the ethernet receive data *-----------------------------------------------------------------------------*/static void enet_rcv (struct eth_device *dev, unsigned long malisr){	struct enet_frame *ef_ptr;	unsigned long data_len;	unsigned long rx_eob_isr;	EMAC_405_HW_PST hw_p = dev->priv;	int handled = 0;	int i;	int loop_count = 0;	rx_eob_isr = mfdcr (malrxeobisr);	if ((0x80000000 >> hw_p->devnum) & rx_eob_isr) {		/* clear EOB */		mtdcr (malrxeobisr, rx_eob_isr);		/* EMAC RX done */		while (1) {	/* do all */			i = hw_p->rx_slot;			if ((MAL_RX_CTRL_EMPTY & hw_p->rx[i].ctrl)			    || (loop_count >= NUM_RX_BUFF))				break;			loop_count++;			hw_p->rx_slot++;			if (NUM_RX_BUFF == hw_p->rx_slot)				hw_p->rx_slot = 0;			handled++;			data_len = (unsigned long) hw_p->rx[i].data_len;	/* Get len */			if (data_len) {				if (data_len > ENET_MAX_MTU)	/* Check len */					data_len = 0;				else {					if (EMAC_RX_ERRORS & hw_p->rx[i].ctrl) {	/* Check Errors */						data_len = 0;						hw_p->stats.rx_err_log[hw_p->								       rx_err_index]							= hw_p->rx[i].ctrl;						hw_p->rx_err_index++;						if (hw_p->rx_err_index ==						    MAX_ERR_LOG)							hw_p->rx_err_index =								0;					}	/* emac_erros */				}	/* data_len < max mtu */			}	/* if data_len */			if (!data_len) {	/* no data */				hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY;	/* Free Recv Buffer */				hw_p->stats.data_len_err++;	/* Error at Rx */			}			/* !data_len */			/* AS.HARNOIS */			/* Check if user has already eaten buffer */			/* if not => ERROR */			else if (hw_p->rx_ready[hw_p->rx_i_index] != -1) {				if (hw_p->is_receiving)					printf ("ERROR : Receive buffers are full!\n");				break;			} else {				hw_p->stats.rx_frames++;				hw_p->stats.rx += data_len;				ef_ptr = (struct enet_frame *) hw_p->rx[i].					data_ptr;#ifdef INFO_405_ENET				hw_p->stats.pkts_rx++;#endif				/* AS.HARNOIS				 * use ring buffer				 */				hw_p->rx_ready[hw_p->rx_i_index] = i;				hw_p->rx_i_index++;				if (NUM_RX_BUFF == hw_p->rx_i_index)					hw_p->rx_i_index = 0;				/* printf("X");  /|* test-only *|/ */				/*  AS.HARNOIS				 * free receive buffer only when				 * buffer has been handled (eth_rx)				 rx[i].ctrl |= MAL_RX_CTRL_EMPTY;				 */			}	/* if data_len */		}		/* while */	}			/* if EMACK_RXCHL */}static int ppc_4xx_eth_rx (struct eth_device *dev){	int length;	int user_index;	unsigned long msr;	EMAC_405_HW_PST hw_p = dev->priv;	hw_p->is_receiving = 1;	/* tell driver */	for (;;) {		/* AS.HARNOIS		 * use ring buffer and		 * get index from rx buffer desciptor queue		 */		user_index = hw_p->rx_ready[hw_p->rx_u_index];		if (user_index == -1) {			length = -1;			break;	/* nothing received - leave for() loop */		}		msr = mfmsr ();		mtmsr (msr & ~(MSR_EE));		length = hw_p->rx[user_index].data_len;		/* Pass the packet up to the protocol layers. */		/*       NetReceive(NetRxPackets[rxIdx], length - 4); */		/*       NetReceive(NetRxPackets[i], length); */		NetReceive (NetRxPackets[user_index], length - 4);		/* Free Recv Buffer */		hw_p->rx[user_index].ctrl |= MAL_RX_CTRL_EMPTY;		/* Free rx buffer descriptor queue */		hw_p->rx_ready[hw_p->rx_u_index] = -1;		hw_p->rx_u_index++;		if (NUM_RX_BUFF == hw_p->rx_u_index)			hw_p->rx_u_index = 0;#ifdef INFO_405_ENET		hw_p->stats.pkts_handled++;#endif		mtmsr (msr);	/* Enable IRQ's */	}	hw_p->is_receiving = 0;	/* tell driver */	return length;}static int virgin = 0;int ppc_4xx_eth_initialize (bd_t * bis){	struct eth_device *dev;	int eth_num = 0;	EMAC_405_HW_PST hw = NULL;	for (eth_num = 0; eth_num < EMAC_NUM_DEV; eth_num++) {		/* Allocate device structure */		dev = (struct eth_device *) malloc (sizeof (*dev));		if (dev == NULL) {			printf ("ppc_405x_eth_initialize: "				"Cannot allocate eth_device %d\n", eth_num);			return (-1);		}		memset(dev, 0, sizeof(*dev));		/* Allocate our private use data */		hw = (EMAC_405_HW_PST) malloc (sizeof (*hw));		if (hw == NULL) {			printf ("ppc_405x_eth_initialize: "				"Cannot allocate private hw data for eth_device %d",				eth_num);			free (dev);			return (-1);		}		memset(hw, 0, sizeof(*hw));		switch (eth_num) {		case 0:			hw->hw_addr = 0;			memcpy (dev->enetaddr, bis->bi_enetaddr, 6);			break;#if defined(CONFIG_NET_MULTI)		case 1:			hw->hw_addr = 0x100;			memcpy (dev->enetaddr, bis->bi_enet1addr, 6);			break;#endif		default:			hw->hw_addr = 0;			memcpy (dev->enetaddr, bis->bi_enetaddr, 6);			break;		}		hw->devnum = eth_num;		hw->print_speed = 1;		sprintf (dev->name, "ppc_405x_eth%d", eth_num);		dev->priv = (void *) hw;		dev->init = ppc_4xx_eth_init;		dev->halt = ppc_4xx_eth_halt;		dev->send = ppc_4xx_eth_send;		dev->recv = ppc_4xx_eth_rx;		if (0 == virgin) {			/* set the MAL IER ??? names may change with new spec ??? */			mal_ier =				MAL_IER_DE | MAL_IER_NE | MAL_IER_TE |				MAL_IER_OPBE | MAL_IER_PLBE;			mtdcr (malesr, 0xffffffff);	/* clear pending interrupts */			mtdcr (maltxdeir, 0xffffffff);	/* clear pending interrupts */			mtdcr (malrxdeir, 0xffffffff);	/* clear pending interrupts */			mtdcr (malier, mal_ier);#if defined(CONFIG_405EP)			/* 405EP has one EWU interrupt */			irq_install_handler (VECNUM_EWU0,					     (interrupt_handler_t *) enetInt,					     dev);#endif			/* install MAL interrupt handler */			irq_install_handler (VECNUM_MS,					     (interrupt_handler_t *) enetInt,					     dev);			irq_install_handler (VECNUM_MTE,					     (interrupt_handler_t *) enetInt,					     dev);			irq_install_handler (VECNUM_MRE,					     (interrupt_handler_t *) enetInt,					     dev);			irq_install_handler (VECNUM_TXDE,					     (interrupt_handler_t *) enetInt,					     dev);			irq_install_handler (VECNUM_RXDE,					     (interrupt_handler_t *) enetInt,					     dev);			virgin = 1;		}#if defined(CONFIG_NET_MULTI)		eth_register (dev);#else		emac0_dev = dev;#endif	}			/* end for each supported device */	return (1);}#if !defined(CONFIG_NET_MULTI)void eth_halt (void) {	if (emac0_dev) {		ppc_4xx_eth_halt(emac0_dev);		free(emac0_dev);		emac0_dev = NULL;	}}int eth_init (bd_t *bis){	ppc_4xx_eth_initialize(bis);	return(ppc_4xx_eth_init(emac0_dev, bis));}int eth_send(volatile void *packet, int length){	return (ppc_4xx_eth_send(emac0_dev, packet, length));}int eth_rx(void){	return (ppc_4xx_eth_rx(emac0_dev));}#endif#endif /* CONFIG_405 */

⌨️ 快捷键说明

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