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

📄 tsi108_eth.c

📁 U-boot源码 ARM7启动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	printf ("%s link is up", dev->name);	phy_spec_status = read_phy (ETH_BASE, phy_addr, MV1111_SPEC_STAT_REG);	if (phy_spec_status & SPEC_STAT_RESOLVED) {		switch (phy_speed) {		case LINK_SPEED_1000:			printf (", 1000 Mbps");			break;		case LINK_SPEED_100:			printf (", 100 Mbps");			break;		case LINK_SPEED_10:			printf (", 10 Mbps");			break;		}		if (phy_duplex == LINK_DUPLEX_FULL)			printf (", Full duplex");		else			printf (", Half duplex");	}	printf ("\n");#endif	dump_phy_regs (TBI_ADDR);	if (speed)		*speed = phy_speed;	if (duplex)		*duplex = phy_duplex;	return 1;}/* * External interface * * register the tsi108 ethernet controllers with the multi-ethernet system */int tsi108_eth_initialize (bd_t * bis){	struct eth_device *dev;	int index;	for (index = 0; index < CONFIG_TSI108_ETH_NUM_PORTS; index++) {		dev = (struct eth_device *)malloc(sizeof(struct eth_device));		sprintf (dev->name, "TSI108_eth%d", index);		dev->iobase = ETH_BASE + (index * ETH_PORT_OFFSET);		dev->priv = (void *)(phy_address[index]);		dev->init = tsi108_eth_probe;		dev->halt = tsi108_eth_halt;		dev->send = tsi108_eth_send;		dev->recv = tsi108_eth_recv;		eth_register(dev);	}	return index;}/* * probe for and initialize a single ethernet interface */static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis){	unsigned long base;	unsigned long value;	int index;	struct dma_descriptor *tx_descr;	struct dma_descriptor *rx_descr;	int speed;	int duplex;	base = dev->iobase;	reg_PORT_CONTROL(base) = PORT_CONTROL_STE | PORT_CONTROL_BPT;	/* Bring DMA/FIFO out of reset. */	reg_TX_CONFIG(base) = 0x00000000;	reg_RX_CONFIG(base) = 0x00000000;	reg_TX_THRESHOLDS(base) = (192 << 16) | 192;	reg_RX_THRESHOLDS(base) = (192 << 16) | 112;	/* Bring MAC out of reset. */	reg_MAC_CONFIG_1(base) = 0x00000000;	/* DMA MAC configuration. */	reg_MAC_CONFIG_1(base) =	    MAC_CONFIG_1_RX_ENABLE | MAC_CONFIG_1_TX_ENABLE;	reg_MII_MGMT_CONFIG(base) = MII_MGMT_CONFIG_NO_PREAMBLE;	reg_MAXIMUM_FRAME_LENGTH(base) = RX_BUFFER_SIZE;	/* Note: Early tsi108 manual did not have correct byte order	 * for the station address.*/	reg_STATION_ADDRESS_1(base) = (dev->enetaddr[5] << 24) |	    (dev->enetaddr[4] << 16) |	    (dev->enetaddr[3] << 8) | (dev->enetaddr[2] << 0);	reg_STATION_ADDRESS_2(base) = (dev->enetaddr[1] << 24) |	    (dev->enetaddr[0] << 16);	if (marvell_88e_phy_config(dev, &speed, &duplex) == 0)		return 0;	value =	    MAC_CONFIG_2_PREAMBLE_LENGTH(7) | MAC_CONFIG_2_PAD_CRC |	    MAC_CONFIG_2_CRC_ENABLE;	if (speed == LINK_SPEED_1000)		value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_BYTE);	else {		value |= MAC_CONFIG_2_INTERFACE_MODE(INTERFACE_MODE_NIBBLE);		reg_PORT_CONTROL(base) |= PORT_CONTROL_SPD;	}	if (duplex == LINK_DUPLEX_FULL) {		value |= MAC_CONFIG_2_FULL_DUPLEX;		reg_PORT_CONTROL(base) &= ~PORT_CONTROL_BPT;	} else		reg_PORT_CONTROL(base) |= PORT_CONTROL_BPT;	reg_MAC_CONFIG_2(base) = value;	reg_RX_CONFIG(base) = RX_CONFIG_SE;	reg_RX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY;	reg_RX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY;	/* initialize the RX DMA descriptors */	rx_descr = &rx_descr_array[0];	rx_descr_current = rx_descr;	for (index = 0; index < NUM_RX_DESC; index++) {		/* make sure the receive buffers are not in cache */		invalidate_dcache_range((unsigned long)NetRxPackets[index],					(unsigned long)NetRxPackets[index] +					RX_BUFFER_SIZE);		rx_descr->start_addr0 =		    cpu_to_le32((vuint32) NetRxPackets[index]);		rx_descr->start_addr1 = 0;		rx_descr->next_descr_addr0 =		    cpu_to_le32((vuint32) (rx_descr + 1));		rx_descr->next_descr_addr1 = 0;		rx_descr->vlan_byte_count = 0;		rx_descr->config_status = cpu_to_le32((RX_BUFFER_SIZE << 16) |						      DMA_DESCR_RX_OWNER);		rx_descr++;	}	rx_descr--;	rx_descr->next_descr_addr0 = 0;	rx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);	/* Push the descriptors to RAM so the ethernet DMA can see them */	invalidate_dcache_range((unsigned long)rx_descr_array,				(unsigned long)rx_descr_array +				sizeof(rx_descr_array));	/* enable RX queue */	reg_RX_CONTROL(base) = TX_CONTROL_GO | 0x01;	reg_RX_QUEUE_0_PTR_LOW(base) = (u32) rx_descr_current;	/* enable receive DMA */	reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID;	reg_TX_QUEUE_0_CONFIG(base) = OCN_PORT_MEMORY;	reg_TX_QUEUE_0_BUF_CONFIG(base) = OCN_PORT_MEMORY;	/* initialize the TX DMA descriptor */	tx_descr = &tx_descriptor;	tx_descr->start_addr0 = 0;	tx_descr->start_addr1 = 0;	tx_descr->next_descr_addr0 = 0;	tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);	tx_descr->vlan_byte_count = 0;	tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OK |					      DMA_DESCR_TX_SOF |					      DMA_DESCR_TX_EOF);	/* enable TX queue */	reg_TX_CONTROL(base) = TX_CONTROL_GO | 0x01;	return 1;}/* * send a packet */static int tsi108_eth_send (struct eth_device *dev,			   volatile void *packet, int length){	unsigned long base;	int timeout;	struct dma_descriptor *tx_descr;	unsigned long status;	base = dev->iobase;	tx_descr = &tx_descriptor;	/* Wait until the last packet has been transmitted. */	timeout = 0;	do {		/* make sure we see the changes made by the DMA engine */		invalidate_dcache_range((unsigned long)tx_descr,					(unsigned long)tx_descr +					sizeof(struct dma_descriptor));		if (timeout != 0)			udelay (15);		if (++timeout > 10000) {			tx_diag_regs(base);			debug_lev(1,				  "ERROR: timeout waiting for last transmit packet to be sent\n");			return 0;		}	} while (tx_descr->config_status & cpu_to_le32(DMA_DESCR_TX_OWNER));	status = le32_to_cpu(tx_descr->config_status);	if ((status & DMA_DESCR_TX_OK) == 0) {#ifdef TX_PRINT_ERRORS		printf ("TX packet error: 0x%08x\n    %s%s%s%s\n", status,		       status & DMA_DESCR_TX_OK ? "tx error, " : "",		       status & DMA_DESCR_TX_RETRY_LIMIT ?		       "retry limit reached, " : "",		       status & DMA_DESCR_TX_UNDERRUN ? "underrun, " : "",		       status & DMA_DESCR_TX_LATE_COLLISION ? "late collision, "		       : "");#endif	}	debug_lev (9, "sending packet %d\n", length);	tx_descr->start_addr0 = cpu_to_le32((vuint32) packet);	tx_descr->start_addr1 = 0;	tx_descr->next_descr_addr0 = 0;	tx_descr->next_descr_addr1 = cpu_to_le32(DMA_DESCR_LAST);	tx_descr->vlan_byte_count = cpu_to_le32(length);	tx_descr->config_status = cpu_to_le32(DMA_DESCR_TX_OWNER |					      DMA_DESCR_TX_CRC |					      DMA_DESCR_TX_PAD |					      DMA_DESCR_TX_SOF |					      DMA_DESCR_TX_EOF);	invalidate_dcache_range((unsigned long)tx_descr,				(unsigned long)tx_descr +				sizeof(struct dma_descriptor));	invalidate_dcache_range((unsigned long)packet,				(unsigned long)packet + length);	reg_TX_QUEUE_0_PTR_LOW(base) = (u32) tx_descr;	reg_TX_QUEUE_0_PTR_HIGH(base) = TX_QUEUE_0_PTR_HIGH_VALID;	return length;}/* * Check for received packets and send them up the protocal stack */static int tsi108_eth_recv (struct eth_device *dev){	struct dma_descriptor *rx_descr;	unsigned long base;	int length = 0;	unsigned long status;	volatile uchar *buffer;	base = dev->iobase;	/* make sure we see the changes made by the DMA engine */	invalidate_dcache_range ((unsigned long)rx_descr_array,				(unsigned long)rx_descr_array +				sizeof(rx_descr_array));	/* process all of the received packets */	rx_descr = rx_descr_current;	while ((rx_descr->config_status & cpu_to_le32(DMA_DESCR_RX_OWNER)) == 0) {		/* check for error */		status = le32_to_cpu(rx_descr->config_status);		if (status & DMA_DESCR_RX_BAD_FRAME) {#ifdef RX_PRINT_ERRORS			printf ("RX packet error: 0x%08x\n    %s%s%s%s%s%s\n",			       status,			       status & DMA_DESCR_RX_FRAME_IS_TYPE ? "too big, "			       : "",			       status & DMA_DESCR_RX_SHORT_FRAME ? "too short, "			       : "",			       status & DMA_DESCR_RX_BAD_FRAME ? "bad frame, " :			       "",			       status & DMA_DESCR_RX_OVERRUN ? "overrun, " : "",			       status & DMA_DESCR_RX_MAX_FRAME_LEN ?			       "max length, " : "",			       status & DMA_DESCR_RX_CRC_ERROR ? "CRC error, " :			       "");#endif		} else {			length =			    le32_to_cpu(rx_descr->vlan_byte_count) & 0xFFFF;			/*** process packet ***/			buffer =			    (volatile uchar			     *)(le32_to_cpu (rx_descr->start_addr0));			NetReceive (buffer, length);			invalidate_dcache_range ((unsigned long)buffer,						(unsigned long)buffer +						RX_BUFFER_SIZE);		}		/* Give this buffer back to the DMA engine */		rx_descr->vlan_byte_count = 0;		rx_descr->config_status = cpu_to_le32 ((RX_BUFFER_SIZE << 16) |						      DMA_DESCR_RX_OWNER);		/* move descriptor pointer forward */		rx_descr =		    (struct dma_descriptor		     *)(le32_to_cpu (rx_descr->next_descr_addr0));		if (rx_descr == 0)			rx_descr = &rx_descr_array[0];	}	/* remember where we are for next time */	rx_descr_current = rx_descr;	/* If the DMA engine has reached the end of the queue	 * start over at the begining */	if (reg_RX_EXTENDED_STATUS(base) & RX_EXTENDED_STATUS_EOQ_0) {		reg_RX_EXTENDED_STATUS(base) = RX_EXTENDED_STATUS_EOQ_0;		reg_RX_QUEUE_0_PTR_LOW(base) = (u32) & rx_descr_array[0];		reg_RX_QUEUE_0_PTR_HIGH(base) = RX_QUEUE_0_PTR_HIGH_VALID;	}	return length;}/* * disable an ethernet interface */static void tsi108_eth_halt (struct eth_device *dev){	unsigned long base;	base = dev->iobase;	/* Put DMA/FIFO into reset state. */	reg_TX_CONFIG(base) = TX_CONFIG_RST;	reg_RX_CONFIG(base) = RX_CONFIG_RST;	/* Put MAC into reset state. */	reg_MAC_CONFIG_1(base) = MAC_CONFIG_1_SOFT_RESET;}#endif

⌨️ 快捷键说明

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