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

📄 4xx_enet.c

📁 linux下的BOOT程序原码,有需要的可以来下,保证好用
💻 C
📖 第 1 页 / 共 3 页
字号:
		/* handle MAX TX EOB interrupt from a tx */		if (my_uic0msr & UIC_MTE) {			mal_rx_eob = mfdcr (maltxeobisr);			mtdcr (maltxeobisr, mal_rx_eob);			mtdcr (UIC0SR, UIC_MTE);		}		/* handle MAL RX EOB  interupt from a receive */		/* check for EOB on valid channels	      */		if (my_uic0msr & UIC_MRE) {			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 (UIC0SR, UIC_MRE);	/* Clear */		mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */		switch (hw_p->devnum) {		case 0:			mtdcr (uic1sr, UIC_ETH0);			break;		case 1:			mtdcr (uic1sr, UIC_ETH1);			break;#if defined (CONFIG_440GX)		case 2:			mtdcr (uic2sr, UIC_ETH2);			break;		case 3:			mtdcr (uic2sr, UIC_ETH3);			break;#endif /* CONFIG_440GX */		default:			break;		}	} while (serviced);	return (rc);}#else /* CONFIG_440 */int enetInt (struct eth_device *dev){	int serviced;	int rc = -1;		/* default to not us */	unsigned long mal_isr;	unsigned long emac_isr = 0;	unsigned long mal_rx_eob;	unsigned long my_uicmsr;	EMAC_4XX_HW_PST hw_p;	/*	 * Because the mal is generic, we need to get the current	 * eth device	 */#if defined(CONFIG_NET_MULTI)	dev = eth_get_dev();#else	dev = emac0_dev;#endif	hw_p = dev->priv;	/* enter loop that stays in interrupt code until nothing to service */	do {		serviced = 0;		my_uicmsr = mfdcr (uicmsr);		if ((my_uicmsr & (MAL_UIC_DEF | EMAC_UIC_DEF)) == 0) {	/* not for us */			return (rc);		}		/* get and clear controller status interrupts */		/* look at Mal and EMAC interrupts */		if ((MAL_UIC_DEF & my_uicmsr) != 0) {	/* we have a MAL interrupt */			mal_isr = mfdcr (malesr);			/* look for mal error */			if ((my_uicmsr & MAL_UIC_ERR) != 0) {				mal_err (dev, mal_isr, my_uicmsr, MAL_UIC_DEF, MAL_UIC_ERR);				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 /* CONFIG_440 *//*-----------------------------------------------------------------------------+ *  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_4XX_HW_PST hw_p = dev->priv;	mtdcr (malesr, isr);	/* clear interrupt */	/* clear DE interrupt */	mtdcr (maltxdeir, 0xC0000000);	mtdcr (malrxdeir, 0x80000000);#ifdef INFO_4XX_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_4XX_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_4XX_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_4XX_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;				/*  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_4XX_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_4XX_ENET		hw_p->stats.pkts_handled++;#endif		mtmsr (msr);	/* Enable IRQ's */	}	hw_p->is_receiving = 0; /* tell driver */	return length;}int ppc_4xx_eth_initialize (bd_t * bis){	static int virgin = 0;	struct eth_device *dev;	int eth_num = 0;	EMAC_4XX_HW_PST hw = NULL;#if defined(CONFIG_440GX)	unsigned long pfc1;	mfsdr (sdr_pfc1, pfc1);	pfc1 &= ~(0x01e00000);	pfc1 |= 0x01200000;	mtsdr (sdr_pfc1, pfc1);#endif	/* set phy num and mode */	bis->bi_phynum[0] = CONFIG_PHY_ADDR;#if defined(CONFIG_PHY1_ADDR)	bis->bi_phynum[1] = CONFIG_PHY1_ADDR;#endif#if defined(CONFIG_440GX)	bis->bi_phynum[2] = CONFIG_PHY2_ADDR;	bis->bi_phynum[3] = CONFIG_PHY3_ADDR;	bis->bi_phymode[0] = 0;	bis->bi_phymode[1] = 0;	bis->bi_phymode[2] = 2;	bis->bi_phymode[3] = 2;#if defined (CONFIG_440GX)	ppc_4xx_eth_setup_bridge(0, bis);#endif#endif	for (eth_num = 0; eth_num < LAST_EMAC_NUM; 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) {				bis->bi_phymode[eth_num] = BI_PHYMODE_NONE;				continue;			}			break;#ifdef CONFIG_HAS_ETH1		case 1:			if (memcmp (bis->bi_enet1addr, "\0\0\0\0\0\0", 6) == 0) {				bis->bi_phymode[eth_num] = BI_PHYMODE_NONE;				continue;			}			break;#endif#ifdef CONFIG_HAS_ETH2		case 2:			if (memcmp (bis->bi_enet2addr, "\0\0\0\0\0\0", 6) == 0) {				bis->bi_phymode[eth_num] = BI_PHYMODE_NONE;				continue;			}			break;#endif#ifdef CONFIG_HAS_ETH3		case 3:			if (memcmp (bis->bi_enet3addr, "\0\0\0\0\0\0", 6) == 0) {				bis->bi_phymode[eth_num] = BI_PHYMODE_NONE;				continue;			}			break;#endif		}		/* Allocate device structure */		dev = (struct eth_device *) malloc (sizeof (*dev));		if (dev == NULL) {			printf ("ppc_4xx_eth_initialize: "				"Cannot allocate eth_device %d\n", eth_num);			return (-1);		}		memset(dev, 0, sizeof(*dev));		/* Allocate our private use data */		hw = (EMAC_4XX_HW_PST) malloc (sizeof (*hw));		if (hw == NULL) {			printf ("ppc_4xx_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) {		default:		/* fall through */		case 0:			hw->hw_addr = 0;			memcpy (dev->enetaddr, bis->bi_enetaddr, 6);			break;#ifdef CONFIG_HAS_ETH1		case 1:			hw->hw_addr = 0x100;			memcpy (dev->enetaddr, bis->bi_enet1addr, 6);			break;#endif#ifdef CONFIG_HAS_ETH2		case 2:			hw->hw_addr = 0x400;			memcpy (dev->enetaddr, bis->bi_enet2addr, 6);			break;#endif#ifdef CONFIG_HAS_ETH3		case 3:			hw->hw_addr = 0x600;			memcpy (dev->enetaddr, bis->bi_enet3addr, 6);			break;#endif		}		hw->devnum = eth_num;		hw->print_speed = 1;		sprintf (dev->name, "ppc_4xx_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);			/* 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#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)		miiphy_register (dev->name,				 emac4xx_miiphy_read, emac4xx_miiphy_write);#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);	if (emac0_dev) {		return ppc_4xx_eth_init(emac0_dev, bis);	} else {		printf("ERROR: ethaddr not set!\n");		return -1;	}}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));}int emac4xx_miiphy_initialize (bd_t * bis){#if defined(CONFIG_MII) || (CONFIG_COMMANDS & CFG_CMD_MII)	miiphy_register ("ppc_4xx_eth0",			 emac4xx_miiphy_read, emac4xx_miiphy_write);#endif	return 0;}#endif /* !defined(CONFIG_NET_MULTI) */#endif /* #if (CONFIG_COMMANDS & CFG_CMD_NET) */

⌨️ 快捷键说明

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