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

📄 440gx_enet.c.svn-base

📁 u-boot for S3c2443 processor
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
					emac_err (dev, emac_isr);					serviced = 1;					rc = 0;				}			}			if ((hw_p->emac_ier & emac_isr)			    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {				mtdcr (uic0sr, UIC_MRE | UIC_MTE);	/* Clear */				mtdcr (uic1sr, UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */				return (rc);	/* we had errors so get out */			}		}		if (hw_p->devnum == 1) {			if (UIC_ETH1 & my_uic1msr) {	/* 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)			    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {				mtdcr (uic0sr, UIC_MRE | UIC_MTE);	/* Clear */				mtdcr (uic1sr, UIC_ETH1 | UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */				return (rc);	/* we had errors so get out */			}		}#if defined (CONFIG_440_GX)		if (hw_p->devnum == 2) {			if (UIC_ETH2 & my_uic2msr) {	/* 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)			    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {				mtdcr (uic0sr, UIC_MRE | UIC_MTE);	/* Clear */				mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */				mtdcr (uic2sr, UIC_ETH2);				return (rc);	/* we had errors so get out */			}		}		if (hw_p->devnum == 3) {			if (UIC_ETH3 & my_uic2msr) {	/* 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)			    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {				mtdcr (uic0sr, UIC_MRE | UIC_MTE);	/* Clear */				mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */				mtdcr (uic2sr, UIC_ETH3);				return (rc);	/* we had errors so get out */			}		}#endif /* CONFIG_440_GX */		/* 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_440_GX)		case 2:			mtdcr (uic2sr, UIC_ETH2);			break;		case 3:			mtdcr (uic2sr, UIC_ETH3);			break;#endif /* CONFIG_440_GX */		default:			break;		}	} while (serviced);	return (rc);}/*-----------------------------------------------------------------------------+ *  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_440GX_HW_PST hw_p = dev->priv;	mtdcr (malesr, isr);	/* clear interrupt */	/* clear DE interrupt */	mtdcr (maltxdeir, 0xC0000000);	mtdcr (malrxdeir, 0x80000000);#ifdef INFO_440_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_440GX_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_440GX_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_440_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_440x_eth_rx (struct eth_device *dev){	int length;	int user_index;	unsigned long msr;	EMAC_440GX_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_440_ENET		hw_p->stats.pkts_handled++;#endif		mtmsr (msr);	/* Enable IRQ's */	}	hw_p->is_receiving = 0;	/* tell driver */	return length;}int ppc_440x_eth_initialize (bd_t * bis){	static int virgin = 0;	unsigned long pfc1;	struct eth_device *dev;	int eth_num = 0;	EMAC_440GX_HW_PST hw = NULL;	mfsdr (sdr_pfc1, pfc1);	pfc1 &= ~(0x01e00000);	pfc1 |= 0x01200000;	mtsdr (sdr_pfc1, pfc1);	/* set phy num and mode */	bis->bi_phynum[0] = CONFIG_PHY_ADDR;	bis->bi_phynum[1] = CONFIG_PHY1_ADDR;	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;	for (eth_num = 0; eth_num < EMAC_NUM_DEV; eth_num++) {		/* See if we can actually bring up the interface, otherwise, skip it */		switch (eth_num) {		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;		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;		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;		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;		default:			if (memcmp (bis->bi_enetaddr, "\0\0\0\0\0\0", 6) == 0) {				bis->bi_phymode[eth_num] = BI_PHYMODE_NONE;				continue;			}			break;		}		/* Allocate device structure */		dev = (struct eth_device *) malloc (sizeof (*dev));		if (dev == NULL) {			printf ("ppc_440x_eth_initialize: "				"Cannot allocate eth_device %d\n", eth_num);			return (-1);		}		/* Allocate our private use data */		hw = (EMAC_440GX_HW_PST) malloc (sizeof (*hw));		if (hw == NULL) {			printf ("ppc_440x_eth_initialize: "				"Cannot allocate private hw data for eth_device %d",				eth_num);			free (dev);			return (-1);		}		switch (eth_num) {		case 0:			hw->hw_addr = 0;			memcpy (dev->enetaddr, bis->bi_enetaddr, 6);			break;		case 1:			hw->hw_addr = 0x100;			memcpy (dev->enetaddr, bis->bi_enet1addr, 6);			break;		case 2:			hw->hw_addr = 0x400;			memcpy (dev->enetaddr, bis->bi_enet2addr, 6);			break;		case 3:			hw->hw_addr = 0x600;			memcpy (dev->enetaddr, bis->bi_enet3addr, 6);			break;		default:			hw->hw_addr = 0;			memcpy (dev->enetaddr, bis->bi_enetaddr, 6);			break;		}		hw->devnum = eth_num;		sprintf (dev->name, "ppc_440x_eth%d", eth_num);		dev->priv = (void *) hw;		dev->init = ppc_440x_eth_init;		dev->halt = ppc_440x_eth_halt;		dev->send = ppc_440x_eth_send;		dev->recv = ppc_440x_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;		}		eth_register (dev);	}			/* end for each supported device */	return (1);}#endif /* CONFIG_440 && CONFIG_NET_MULTI */

⌨️ 快捷键说明

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