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

📄 405gp_enet.c

📁 U-Boot1.1.2是最为常用的嵌入式系统Bootloader
💻 C
📖 第 1 页 / 共 3 页
字号:
	hw_p->alloc_rx_buf =		(mal_desc_t *) malloc ((sizeof (mal_desc_t) * NUM_RX_BUFF) +				       ((2 * CFG_CACHELINE_SIZE) - 2));	if (((int) hw_p->alloc_rx_buf & CACHELINE_MASK) != 0) {		hw_p->rx =			(mal_desc_t *) ((int) hw_p->alloc_rx_buf +					CFG_CACHELINE_SIZE -					((int) hw_p->					 alloc_rx_buf & CACHELINE_MASK));	} else {		hw_p->rx = hw_p->alloc_rx_buf;	}	for (i = 0; i < NUM_TX_BUFF; i++) {		hw_p->tx[i].ctrl = 0;		hw_p->tx[i].data_len = 0;		if (hw_p->first_init == 0)			hw_p->txbuf_ptr =				(char *) malloc (ENET_MAX_MTU_ALIGNED);		hw_p->tx[i].data_ptr = hw_p->txbuf_ptr;		if ((NUM_TX_BUFF - 1) == i)			hw_p->tx[i].ctrl |= MAL_TX_CTRL_WRAP;		hw_p->tx_run[i] = -1;#if 0		printf ("TX_BUFF %d @ 0x%08lx\n", i,			(ulong) hw_p->tx[i].data_ptr);#endif	}	for (i = 0; i < NUM_RX_BUFF; i++) {		hw_p->rx[i].ctrl = 0;		hw_p->rx[i].data_len = 0;		/*       rx[i].data_ptr = (char *) &rx_buff[i]; */		hw_p->rx[i].data_ptr = (char *) NetRxPackets[i];		if ((NUM_RX_BUFF - 1) == i)			hw_p->rx[i].ctrl |= MAL_RX_CTRL_WRAP;		hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR;		hw_p->rx_ready[i] = -1;#if 0		printf ("RX_BUFF %d @ 0x%08lx\n", i, (ulong) rx[i].data_ptr);#endif	}	reg = 0x00000000;	reg |= dev->enetaddr[0];	/* set high address */	reg = reg << 8;	reg |= dev->enetaddr[1];	out32 (EMAC_IAH + hw_p->hw_addr, reg);	reg = 0x00000000;	reg |= dev->enetaddr[2];	/* set low address  */	reg = reg << 8;	reg |= dev->enetaddr[3];	reg = reg << 8;	reg |= dev->enetaddr[4];	reg = reg << 8;	reg |= dev->enetaddr[5];	out32 (EMAC_IAL + hw_p->hw_addr, reg);	switch (devnum) {#if defined(CONFIG_NET_MULTI)	case 1:		/* setup MAL tx & rx channel pointers */		/* For 405EP, the EMAC1 tx channel 0 is MAL tx channel 2 */		mtdcr (maltxctp2r, hw_p->tx);		mtdcr (malrxctp1r, hw_p->rx);		/* set RX buffer size */		mtdcr (malrcbs1, ENET_MAX_MTU_ALIGNED / 16);		break;#endif	case 0:	default:		/* setup MAL tx & rx channel pointers */		mtdcr (maltxctp0r, hw_p->tx);		mtdcr (malrxctp0r, hw_p->rx);		/* set RX buffer size */		mtdcr (malrcbs0, ENET_MAX_MTU_ALIGNED / 16);		break;	}	/* Enable MAL transmit and receive channels */	mtdcr (maltxcasr, (MAL_TXRX_CASR >> (hw_p->devnum * 2)));	mtdcr (malrxcasr, (MAL_TXRX_CASR >> hw_p->devnum));	/* set transmit enable & receive enable */	out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_TXE | EMAC_M0_RXE);	/* set receive fifo to 4k and tx fifo to 2k */	mode_reg = in32 (EMAC_M1 + hw_p->hw_addr);	mode_reg |= EMAC_M1_RFS_4K | EMAC_M1_TX_FIFO_2K;	/* set speed */	if (speed == _100BASET)		mode_reg = mode_reg | EMAC_M1_MF_100MBPS | EMAC_M1_IST;	else		mode_reg = mode_reg & ~0x00C00000;	/* 10 MBPS */	if (duplex == FULL)		mode_reg = mode_reg | 0x80000000 | EMAC_M1_IST;	out32 (EMAC_M1 + hw_p->hw_addr, mode_reg);#if defined(CONFIG_440)	/* set speed in the ZMII bridge */	if (speed == _100BASET)		out32(ZMII_SSR, in32(ZMII_SSR) | 0x10000000);	else		out32(ZMII_SSR, in32(ZMII_SSR) & ~0x10000000);#endif	/* Enable broadcast and indvidual address */	/* TBS: enabling runts as some misbehaved nics will send runts */	out32 (EMAC_RXM + hw_p->hw_addr, EMAC_RMR_BAE | EMAC_RMR_IAE);	/* we probably need to set the tx mode1 reg? maybe at tx time */	/* set transmit request threshold register */	out32 (EMAC_TRTR + hw_p->hw_addr, 0x18000000);	/* 256 byte threshold */#if defined(CONFIG_440)	/* 440GP has a 64 byte burst length */	out32 (EMAC_RX_HI_LO_WMARK + hw_p->hw_addr, 0x0f002000);	out32 (EMAC_TXM1 + hw_p->hw_addr, 0xf8640000);#else	/* 405s have a 16 byte burst length */	out32 (EMAC_RX_HI_LO_WMARK + hw_p->hw_addr, 0x0f002000);#endif	/* Frame gap set */	out32 (EMAC_I_FRAME_GAP_REG + hw_p->hw_addr, 0x00000008);	/* Set EMAC IER */	hw_p->emac_ier = EMAC_ISR_PTLE | EMAC_ISR_BFCS |		EMAC_ISR_ORE | EMAC_ISR_IRE;	if (speed == _100BASET)		hw_p->emac_ier = hw_p->emac_ier | EMAC_ISR_SYE;	out32 (EMAC_ISR + hw_p->hw_addr, 0xffffffff);	/* clear pending interrupts */	out32 (EMAC_IER + hw_p->hw_addr, hw_p->emac_ier);	if (hw_p->first_init == 0) {		/*		 * Connect interrupt service routines		 */#if !defined(CONFIG_405EP)		/* 405EP has one EWU interrupt */		irq_install_handler (VECNUM_EWU0 + (hw_p->devnum * 2),				     (interrupt_handler_t *) enetInt, dev);#endif		irq_install_handler (VECNUM_ETH0 + (hw_p->devnum * 2),				     (interrupt_handler_t *) enetInt, dev);	}	mtmsr (msr);		/* enable interrupts again */	hw_p->bis = bis;	hw_p->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;	EMAC_405_HW_PST hw_p = dev->priv;	ef_ptr = (struct enet_frame *) ptr;	/*-----------------------------------------------------------------------+	 *  Copy in our address into the frame.	 *-----------------------------------------------------------------------*/	(void) memcpy (ef_ptr->source_addr, dev->enetaddr, ENET_ADDR_LENGTH);	/*-----------------------------------------------------------------------+	 * If frame is too long or too short, modify length.	 *-----------------------------------------------------------------------*/	/* TBS: where does the fragment go???? */	if (len > ENET_MAX_MTU)		len = ENET_MAX_MTU;	/*   memcpy ((void *) &tx_buff[tx_slot], (const void *) ptr, len); */	memcpy ((void *) hw_p->txbuf_ptr, (const void *) ptr, len);	/*-----------------------------------------------------------------------+	 * set TX Buffer busy, and send it	 *-----------------------------------------------------------------------*/	hw_p->tx[hw_p->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) == hw_p->tx_slot)		hw_p->tx[hw_p->tx_slot].ctrl |= MAL_TX_CTRL_WRAP;	hw_p->tx[hw_p->tx_slot].data_len = (short) len;	hw_p->tx[hw_p->tx_slot].ctrl |= MAL_TX_CTRL_READY;	__asm__ volatile ("eieio");	out32 (EMAC_TXM0 + hw_p->hw_addr,	       in32 (EMAC_TXM0 + hw_p->hw_addr) | EMAC_TXM0_GNP0);#ifdef INFO_405_ENET	hw_p->stats.pkts_tx++;#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 + hw_p->hw_addr);		/* 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)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_uic0msr, my_uic1msr;	EMAC_405_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_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 (dev, 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 + 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); /* 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 >> hw_p->devnum)) != 0) {	/* call emac routine for channel 0 */				/* 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_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */	} 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_405_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);

⌨️ 快捷键说明

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