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

📄 405gp_enet.c.svn-base

📁 u-boot for S3c2443 processor
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
	}	/* set up interrupt handler */	/* setup interrupt controler to take interrupts from the MAL &	   EMAC */	mtdcr (uicsr, 0xffffffff);	/* clear pending interrupts */	mtdcr (uicer, mfdcr (uicer) | MAL_UIC_DEF | EMAC_UIC_DEF);	/* 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);	/* Set EMAC IER */	emac_ier = EMAC_ISR_PTLE | EMAC_ISR_BFCS |		EMAC_ISR_PTLE | EMAC_ISR_ORE  | EMAC_ISR_IRE;	if (speed == _100BASET)		emac_ier = emac_ier | EMAC_ISR_SYE;	out32 (EMAC_ISR, 0xffffffff);	/* clear pending interrupts */	out32 (EMAC_IER, emac_ier);	mtmsr (msr);				/* enable interrupts again */	bis_save = bis;	first_init = 1;	return (1);}static int ppc_4xx_eth_send (struct eth_device *dev, volatile void *ptr, int len){	struct enet_frame *ef_ptr;	ulong time_start, time_now;	unsigned long temp_txm0;	ef_ptr = (struct enet_frame *) ptr;	/*-----------------------------------------------------------------------+	 *  Copy in our address into the frame.	 *-----------------------------------------------------------------------*/	(void) memcpy (ef_ptr->source_addr, emac_hwd_addr, ENET_ADDR_LENGTH);	/*-----------------------------------------------------------------------+	 * If frame is too long or too short, modify length.	 *-----------------------------------------------------------------------*/	if (len > ENET_MAX_MTU)		len = ENET_MAX_MTU;	/*   memcpy ((void *) &tx_buff[tx_slot], (const void *) ptr, len); */	memcpy ((void *) txbuf_ptr, (const void *) ptr, len);	/*-----------------------------------------------------------------------+	 * set TX Buffer busy, and send it	 *-----------------------------------------------------------------------*/	tx[tx_slot].ctrl = (MAL_TX_CTRL_LAST |			    EMAC_TX_CTRL_GFCS | EMAC_TX_CTRL_GP) &		~(EMAC_TX_CTRL_ISA | EMAC_TX_CTRL_RSA);	if ((NUM_TX_BUFF - 1) == tx_slot)		tx[tx_slot].ctrl |= MAL_TX_CTRL_WRAP;	tx[tx_slot].data_len = (short) len;	tx[tx_slot].ctrl |= MAL_TX_CTRL_READY;    __asm__ volatile ("eieio");	out32 (EMAC_TXM0, in32 (EMAC_TXM0) | EMAC_TXM0_GNP0);#ifdef INFO_405_ENET	packetSent++;#endif	/*-----------------------------------------------------------------------+	 * poll unitl the packet is sent and then make sure it is OK	 *-----------------------------------------------------------------------*/	time_start = get_timer (0);	while (1) {		temp_txm0 = in32 (EMAC_TXM0);		/* loop until either TINT turns on or 3 seconds elapse */		if ((temp_txm0 & EMAC_TXM0_GNP0) != 0) {			/* transmit is done, so now check for errors			 * If there is an error, an interrupt should			 * happen when we return			 */			time_now = get_timer (0);			if ((time_now - time_start) > 3000) {				return (-1);			}		} else {			return (len);		}	}}#if defined(CONFIG_440)/*-----------------------------------------------------------------------------+| EnetInt.| EnetInt is the interrupt handler.  It will determine the| cause of the interrupt and call the apporpriate servive| routine.+-----------------------------------------------------------------------------*/int enetInt (){	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_uic0msr, my_uic1msr;	/* enter loop that stays in interrupt code until nothing to service */	do {		serviced = 0;		my_uic0msr = mfdcr (uic0msr);		my_uic1msr = mfdcr (uic1msr);		if (!(my_uic0msr & UIC_MRE)		    && !(my_uic1msr & (UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE))) {			/* not for us */			return (rc);		}		/* get and clear controller status interrupts */		/* look at Mal and EMAC interrupts */		if ((my_uic0msr & UIC_MRE)		    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {			/* we have a MAL interrupt */			mal_isr = mfdcr (malesr);			/* look for mal error */			if (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE)) {				mal_err (mal_isr, my_uic0msr, MAL_UIC_DEF, MAL_UIC_ERR);				serviced = 1;				rc = 0;			}		}		if (UIC_ETH0 & my_uic1msr) {	/* look for EMAC errors */			emac_isr = in32 (EMAC_ISR);			if ((emac_ier & emac_isr) != 0) {				emac_err (emac_isr);				serviced = 1;				rc = 0;			}		}		if ((emac_ier & emac_isr)		    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {			mtdcr (uic0sr, UIC_MRE); /* Clear */			mtdcr (uic1sr, UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */			return (rc);		/* we had errors so get out */		}		/* 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) != 0) {	/* call emac routine for channel 0 */				/* clear EOB				   mtdcr(malrxeobisr, mal_rx_eob); */				enet_rcv (emac_isr);				/* indicate that we serviced an interrupt */				serviced = 1;				rc = 0;			}		}		mtdcr (uic0sr, UIC_MRE); /* Clear */		mtdcr (uic1sr, UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */	} while (serviced);	return (rc);}#else /* CONFIG_440 *//*-----------------------------------------------------------------------------+ * EnetInt. * EnetInt is the interrupt handler.  It will determine the * cause of the interrupt and call the apporpriate servive * routine. *-----------------------------------------------------------------------------*/int enetInt (){	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;	/* 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 (mal_isr, my_uicmsr, MAL_UIC_DEF, MAL_UIC_ERR);				serviced = 1;				rc = 0;			}		}		if ((EMAC_UIC_DEF & my_uicmsr) != 0) {	/* look for EMAC errors */			emac_isr = in32 (EMAC_ISR);			if ((emac_ier & emac_isr) != 0) {				emac_err (emac_isr);				serviced = 1;				rc = 0;			}		}		if (((emac_ier & emac_isr) != 0) | ((MAL_UIC_ERR & my_uicmsr) != 0)) {			mtdcr (uicsr, MAL_UIC_DEF | EMAC_UIC_DEF); /* Clear */			return (rc);		/* we had errors so get out */		}		/* handle MAL RX EOB  interupt from a receive */		/* check for EOB on valid channels            */		if ((my_uicmsr & UIC_MAL_RXEOB) != 0) {			mal_rx_eob = mfdcr (malrxeobisr);			if ((mal_rx_eob & 0x80000000) != 0) {	/* call emac routine for channel 0 */				/* clear EOB				   mtdcr(malrxeobisr, mal_rx_eob); */				enet_rcv (emac_isr);				/* indicate that we serviced an interrupt */				serviced = 1;				rc = 0;			}		}		mtdcr (uicsr, MAL_UIC_DEF | EMAC_UIC_DEF);	/* Clear */	}	while (serviced);	return (rc);}#endif /* CONFIG_440 *//*-----------------------------------------------------------------------------+ *  MAL Error Routine *-----------------------------------------------------------------------------*/static void mal_err (unsigned long isr, unsigned long uic, unsigned long maldef,	      unsigned long mal_errr){	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);#else#if 0	/*	 * MAL error is RX DE error (out of rx buffers)! This is OK here, upon	 * many incoming packets with only 4 rx buffers.	 */	printf ("M");			/* just to see something upon mal error */#endif#endif	eth_init (bis_save);		/* start again... */}/*-----------------------------------------------------------------------------+ *  EMAC Error Routine *-----------------------------------------------------------------------------*/static void emac_err (unsigned long isr){	printf ("EMAC error occured.... ISR = %lx\n", isr);	out32 (EMAC_ISR, isr);}/*-----------------------------------------------------------------------------+ *  enet_rcv() handles the ethernet receive data *-----------------------------------------------------------------------------*/static void enet_rcv (unsigned long malisr){	struct enet_frame *ef_ptr;	unsigned long data_len;	unsigned long rx_eob_isr;	int handled = 0;	int i;	int loop_count = 0;	rx_eob_isr = mfdcr (malrxeobisr);	if ((0x80000000 >> (EMAC_RXCHL - 1)) & rx_eob_isr) {		/* clear EOB */		mtdcr (malrxeobisr, rx_eob_isr);		/* EMAC RX done */		while (1) {				/* do all */			i = rx_slot;			if ((MAL_RX_CTRL_EMPTY & rx[i].ctrl)			    || (loop_count >= NUM_RX_BUFF))				break;			loop_count++;			rx_slot++;			if (NUM_RX_BUFF == rx_slot)				rx_slot = 0;			handled++;			data_len = (unsigned long) 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 & rx[i].ctrl) {	/* Check Errors */						data_len = 0;						stats.rx_err_log[rx_err_index] = rx[i].ctrl;						rx_err_index++;						if (rx_err_index == MAX_ERR_LOG)							rx_err_index = 0;					}	/* emac_erros         */				}		/* data_len < max mtu */			}			/* if data_len        */			if (!data_len) {	/* no data */				rx[i].ctrl |= MAL_RX_CTRL_EMPTY;	/* Free Recv Buffer */				stats.emac.data_len_err++;	/* Error at Rx */			}			/* !data_len */			/* AS.HARNOIS */			/* Check if user has already eaten buffer */			/* if not => ERROR */			else if (rx_ready[rx_i_index] != -1) {				if (is_receiving)					printf ("ERROR : Receive buffers are full!\n");				break;			} else {				stats.emac.rx_frames++;				stats.emac.rx += data_len;				ef_ptr = (struct enet_frame *) rx[i].data_ptr;#ifdef INFO_405_ENET				packetReceived++;#endif				/* AS.HARNOIS				 * use ring buffer				 */				rx_ready[rx_i_index] = i;				rx_i_index++;				if (NUM_RX_BUFF == rx_i_index)					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;	is_receiving = 1;			/* tell driver */	for (;;) {		/* AS.HARNOIS		 * use ring buffer and		 * get index from rx buffer desciptor queue		 */		user_index = rx_ready[rx_u_index];		if (user_index == -1) {			length = -1;			break;	/* nothing received - leave for() loop */		}		msr = mfmsr ();		mtmsr (msr & ~(MSR_EE));		length = 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 */		rx[user_index].ctrl |= MAL_RX_CTRL_EMPTY;		/* Free rx buffer descriptor queue */		rx_ready[rx_u_index] = -1;		rx_u_index++;		if (NUM_RX_BUFF == rx_u_index)			rx_u_index = 0;#ifdef INFO_405_ENET		packetHandled++;#endif		mtmsr (msr);			/* Enable IRQ's */	}	is_receiving = 0;			/* tell driver */	return length;}#if defined(CONFIG_NET_MULTI)int ppc_4xx_eth_initialize(bd_t *bis){	struct eth_device *dev;	int                eth_num = 0;	dev = malloc (sizeof *dev);	if (dev == NULL) {		printf(__FUNCTION__ ": Cannot allocate eth_device\n");		return (-1);	}	sprintf(dev->name, "ppc_4xx_eth%d", eth_num);	dev->priv = (void *) eth_num;	dev->init = ppc_4xx_eth_init;	dev->halt = ppc_4xx_eth_halt;	dev->send = ppc_4xx_eth_send;	dev->recv = ppc_4xx_eth_rx;	eth_register (dev);}#else /* !defined(CONFIG_NET_MULTI) */void eth_halt (void){	ppc_4xx_eth_halt(NULL);}int eth_init (bd_t *bis){	return (ppc_4xx_eth_init(NULL, bis));}int eth_send(volatile void *packet, int length){	return (ppc_4xx_eth_send(NULL, packet, length));}int eth_rx(void){	return (ppc_4xx_eth_rx(NULL));}#endif /* !defined(CONFIG_NET_MULTI) */#endif	/* CONFIG_405GP */

⌨️ 快捷键说明

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