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

📄 greth.c

📁 uboot详细解读可用启动引导LINUX2.6内核
💻 C
📖 第 1 页 / 共 2 页
字号:
		      (dev->gb << 8) | (dev->sp << 7) | (dev->fd << 4));	return 0;}void greth_halt(struct eth_device *dev){	greth_priv *greth;	greth_regs *regs;	int i;#ifdef DEBUG	printf("greth_halt\n");#endif	if (!dev || !dev->priv)		return;	greth = dev->priv;	regs = greth->regs;	if (!regs)		return;	/* disable receiver/transmitter by clearing the enable bits */	GRETH_REGANDIN(&regs->control, ~(GRETH_RXEN | GRETH_TXEN));	/* reset rx/tx descriptors */	if (greth->rxbd_base) {		for (i = 0; i < GRETH_RXBD_CNT; i++) {			greth->rxbd_base[i].stat =			    (i >= (GRETH_RXBD_CNT - 1)) ? GRETH_BD_WR : 0;		}	}	if (greth->txbd_base) {		for (i = 0; i < GRETH_TXBD_CNT; i++) {			greth->txbd_base[i].stat =			    (i >= (GRETH_TXBD_CNT - 1)) ? GRETH_BD_WR : 0;		}	}}int greth_send(struct eth_device *dev, volatile void *eth_data, int data_length){	greth_priv *greth = dev->priv;	greth_regs *regs = greth->regs;	greth_bd *txbd;	void *txbuf;	unsigned int status;#ifdef DEBUG	printf("greth_send\n");#endif	/* send data, wait for data to be sent, then return */	if (((unsigned int)eth_data & (GRETH_BUF_ALIGN - 1))	    && !greth->gbit_mac) {		/* data not aligned as needed by GRETH 10/100, solve this by allocating 4 byte aligned buffer		 * and copy data to before giving it to GRETH.		 */		if (!greth->txbuf) {			greth->txbuf = malloc(GRETH_RXBUF_SIZE);#ifdef DEBUG			printf("GRETH: allocated aligned tx-buf\n");#endif		}		txbuf = greth->txbuf;		/* copy data info buffer */		memcpy((char *)txbuf, (char *)eth_data, data_length);		/* keep buffer to next time */	} else {		txbuf = (void *)eth_data;	}	/* get descriptor to use, only 1 supported... hehe easy */	txbd = greth->txbd_base;	/* setup descriptor to wrap around to it self */	txbd->addr = (unsigned int)txbuf;	txbd->stat = GRETH_BD_EN | GRETH_BD_WR | data_length;	/* Remind Core which descriptor to use when sending */	GRETH_REGSAVE(&regs->tx_desc_p, (unsigned int)txbd);	/* initate send by enabling transmitter */	GRETH_REGORIN(&regs->control, GRETH_TXEN);	/* Wait for data to be sent */	while ((status = GRETH_REGLOAD(&txbd->stat)) & GRETH_BD_EN) {		;	}	/* was the packet transmitted succesfully? */	if (status & GRETH_TXBD_ERR_AL) {		greth->stats.tx_limit_errors++;	}	if (status & GRETH_TXBD_ERR_UE) {		greth->stats.tx_underrun_errors++;	}	if (status & GRETH_TXBD_ERR_LC) {		greth->stats.tx_latecol_errors++;	}	if (status &	    (GRETH_TXBD_ERR_LC | GRETH_TXBD_ERR_UE | GRETH_TXBD_ERR_AL)) {		/* any error */		greth->stats.tx_errors++;		return -1;	}	/* bump tx packet counter */	greth->stats.tx_packets++;	/* return succefully */	return 0;}int greth_recv(struct eth_device *dev){	greth_priv *greth = dev->priv;	greth_regs *regs = greth->regs;	greth_bd *rxbd;	unsigned int status, len = 0, bad;	unsigned char *d;	int enable = 0;	int i;#ifdef DEBUG/*	printf("greth_recv\n"); */#endif	/* Receive One packet only, but clear as many error packets as there are	 * available.	 */	{		/* current receive descriptor */		rxbd = greth->rxbd_curr;		/* get status of next received packet */		status = GRETH_REGLOAD(&rxbd->stat);		bad = 0;		/* stop if no more packets received */		if (status & GRETH_BD_EN) {			goto done;		}#ifdef DEBUG		printf("greth_recv: packet 0x%lx, 0x%lx, len: %d\n",		       (unsigned int)rxbd, status, status & GRETH_BD_LEN);#endif		/* Check status for errors.		 */		if (status & GRETH_RXBD_ERR_FT) {			greth->stats.rx_length_errors++;			bad = 1;		}		if (status & (GRETH_RXBD_ERR_AE | GRETH_RXBD_ERR_OE)) {			greth->stats.rx_frame_errors++;			bad = 1;		}		if (status & GRETH_RXBD_ERR_CRC) {			greth->stats.rx_crc_errors++;			bad = 1;		}		if (bad) {			greth->stats.rx_errors++;			printf			    ("greth_recv: Bad packet (%d, %d, %d, 0x%08x, %d)\n",			     greth->stats.rx_length_errors,			     greth->stats.rx_frame_errors,			     greth->stats.rx_crc_errors, status,			     greth->stats.rx_packets);			/* print all rx descriptors */			for (i = 0; i < GRETH_RXBD_CNT; i++) {				printf("[%d]: Stat=0x%lx, Addr=0x%lx\n", i,				       GRETH_REGLOAD(&greth->rxbd_base[i].stat),				       GRETH_REGLOAD(&greth->rxbd_base[i].						     addr));			}		} else {			/* Process the incoming packet. */			len = status & GRETH_BD_LEN;			d = (char *)rxbd->addr;#ifdef DEBUG			printf			    ("greth_recv: new packet, length: %d. data: %x %x %x %x %x %x %x %x\n",			     len, d[0], d[1], d[2], d[3], d[4], d[5], d[6],			     d[7]);#endif			/* flush all data cache to make sure we're not reading old packet data */			sparc_dcache_flush_all();			/* pass packet on to network subsystem */			NetReceive((void *)d, len);			/* bump stats counters */			greth->stats.rx_packets++;			/* bad is now 0 ==> will stop loop */		}		/* reenable descriptor to receive more packet with this descriptor, wrap around if needed */		rxbd->stat =		    GRETH_BD_EN |		    (((unsigned int)greth->rxbd_curr >=		      (unsigned int)greth->rxbd_max) ? GRETH_BD_WR : 0);		enable = 1;		/* increase index */		greth->rxbd_curr =		    ((unsigned int)greth->rxbd_curr >=		     (unsigned int)greth->rxbd_max) ? greth->		    rxbd_base : (greth->rxbd_curr + 1);	};	if (enable) {		GRETH_REGORIN(&regs->control, GRETH_RXEN);	}      done:	/* return positive length of packet or 0 if non recieved */	return len;}void greth_set_hwaddr(greth_priv * greth, unsigned char *mac){	/* save new MAC address */	greth->dev->enetaddr[0] = greth->hwaddr[0] = mac[0];	greth->dev->enetaddr[1] = greth->hwaddr[1] = mac[1];	greth->dev->enetaddr[2] = greth->hwaddr[2] = mac[2];	greth->dev->enetaddr[3] = greth->hwaddr[3] = mac[3];	greth->dev->enetaddr[4] = greth->hwaddr[4] = mac[4];	greth->dev->enetaddr[5] = greth->hwaddr[5] = mac[5];	greth->regs->esa_msb = (mac[0] << 8) | mac[1];	greth->regs->esa_lsb =	    (mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5];#ifdef DEBUG	printf("GRETH: New MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",	       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);#endif}int greth_initialize(bd_t * bis){	greth_priv *greth;	ambapp_apbdev apbdev;	struct eth_device *dev;	int i;	char *addr_str, *end;	unsigned char addr[6];#ifdef DEBUG	printf("Scanning for GRETH\n");#endif	/* Find Device & IRQ via AMBA Plug&Play information */	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_ETHMAC, &apbdev) != 1) {		return -1;	/* GRETH not found */	}	greth = (greth_priv *) malloc(sizeof(greth_priv));	dev = (struct eth_device *)malloc(sizeof(struct eth_device));	memset(dev, 0, sizeof(struct eth_device));	memset(greth, 0, sizeof(greth_priv));	greth->regs = (greth_regs *) apbdev.address;	greth->irq = apbdev.irq;#ifdef DEBUG	printf("Found GRETH at 0x%lx, irq %d\n", greth->regs, greth->irq);#endif	dev->priv = (void *)greth;	dev->iobase = (unsigned int)greth->regs;	dev->init = greth_init;	dev->halt = greth_halt;	dev->send = greth_send;	dev->recv = greth_recv;	greth->dev = dev;	/* Reset Core */	GRETH_REGSAVE(&greth->regs->control, GRETH_RESET);	/* Wait for core to finish reset cycle */	while (GRETH_REGLOAD(&greth->regs->control) & GRETH_RESET) ;	/* Get the phy address which assumed to have been set	   correctly with the reset value in hardware */	greth->phyaddr = (GRETH_REGLOAD(&greth->regs->mdio) >> 11) & 0x1F;	/* Check if mac is gigabit capable */	greth->gbit_mac = (GRETH_REGLOAD(&greth->regs->control) >> 27) & 1;	/* Make descriptor string */	if (greth->gbit_mac) {		sprintf(dev->name, "GRETH 10/100/GB");	} else {		sprintf(dev->name, "GRETH 10/100");	}	/* initiate PHY, select speed/duplex depending on connected PHY */	if (greth_init_phy(greth, bis)) {		/* Failed to init PHY (timedout) */		return -1;	}	/* Register Device to EtherNet subsystem  */	eth_register(dev);	/* Get MAC address */	if ((addr_str = getenv("ethaddr")) != NULL) {		for (i = 0; i < 6; i++) {			addr[i] =			    addr_str ? simple_strtoul(addr_str, &end, 16) : 0;			if (addr_str) {				addr_str = (*end) ? end + 1 : end;			}		}	} else {		/* HW Address not found in environment, Set default HW address */		addr[0] = GRETH_HWADDR_0;	/* MSB */		addr[1] = GRETH_HWADDR_1;		addr[2] = GRETH_HWADDR_2;		addr[3] = GRETH_HWADDR_3;		addr[4] = GRETH_HWADDR_4;		addr[5] = GRETH_HWADDR_5;	/* LSB */	}	/* set and remember MAC address */	greth_set_hwaddr(greth, addr);	return 1;}

⌨️ 快捷键说明

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