示例#1
0
文件: macb.c 项目: chendian/uboot
static int macb_recv(struct eth_device *netdev)
{
	struct macb_device *macb = to_macb(netdev);
	unsigned int rx_tail = macb->rx_tail;
	void *buffer;
	int length;
	int wrapped = 0;
	u32 status;
        
                
	for (;;) {
		macb_invalidate_ring_desc(macb, RX);

		if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
			return -1;

		status = macb->rx_ring[rx_tail].ctrl;
		if (status & RXBUF_FRAME_START) {
			if (rx_tail != macb->rx_tail)
				reclaim_rx_buffers(macb, rx_tail);
			wrapped = 0;
		}

		if (status & RXBUF_FRAME_END) {
			buffer = macb->rx_buffer + 128 * macb->rx_tail;
			length = status & RXBUF_FRMLEN_MASK;

			macb_invalidate_rx_buffer(macb);
			if (wrapped) {
				unsigned int headlen, taillen;

				headlen = 128 * (MACB_RX_RING_SIZE
						 - macb->rx_tail);
				taillen = length - headlen;
				memcpy((void *)NetRxPackets[0],
				       buffer, headlen);
				memcpy((void *)NetRxPackets[0] + headlen,
				       macb->rx_buffer, taillen);
				buffer = (void *)NetRxPackets[0];
			}

			NetReceive(buffer, length);
			if (++rx_tail >= MACB_RX_RING_SIZE)
				rx_tail = 0;
			reclaim_rx_buffers(macb, rx_tail);
		} else {
			if (++rx_tail >= MACB_RX_RING_SIZE) {
				wrapped = 1;
				rx_tail = 0;
			}
		}
		barrier();
	} 
	return 0;
}
示例#2
0
文件: macb.c 项目: chendian/uboot
static int macb_send(struct eth_device *netdev, void *packet, int length)
{
	struct macb_device *macb = to_macb(netdev);
	unsigned long paddr, ctrl;
	unsigned int tx_head = macb->tx_head;
	int i;
         
	paddr = dma_map_single(packet, length, DMA_TO_DEVICE);

	ctrl = length & TXBUF_FRMLEN_MASK;
	ctrl |= TXBUF_FRAME_END;
	if (tx_head == (MACB_TX_RING_SIZE - 1)) {
		ctrl |= TXBUF_WRAP;
		macb->tx_head = 0;
	} else {
		macb->tx_head++;
	}

	macb->tx_ring[tx_head].ctrl = ctrl;
	macb->tx_ring[tx_head].addr = paddr;
	barrier();
	macb_flush_ring_desc(macb, TX);
	/* Do we need check paddr and length is dcache line aligned? */
	flush_dcache_range(paddr, paddr + length);
	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));

	/*
	 * I guess this is necessary because the networking core may
	 * re-use the transmit buffer as soon as we return...
	 */
	for (i = 0; i <= MACB_TX_TIMEOUT; i++) {
		barrier();
		macb_invalidate_ring_desc(macb, TX);
		ctrl = macb->tx_ring[tx_head].ctrl;
		if (ctrl & TXBUF_USED)
			break;
		udelay(1);
	}

	dma_unmap_single(packet, length, paddr);

	if (i <= MACB_TX_TIMEOUT) {
		if (ctrl & TXBUF_UNDERRUN)
			printf("%s: TX underrun\n", netdev->name);
		if (ctrl & TXBUF_EXHAUSTED)
			printf("%s: TX buffers exhausted in mid frame\n",
			       netdev->name);
	} else {
		printf("%s: TX timeout\n", netdev->name);
	}

	/* No one cares anyway */ 
	return 0;
}
示例#3
0
int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value)
{
	struct eth_device *dev = eth_get_dev_by_name(devname);
	struct macb_device *macb = to_macb(dev);

	if ( macb->phy_addr != phy_adr )
		return -1;

	macb_mdio_write(macb, reg, value);

	return 0;
}
示例#4
0
文件: macb.c 项目: DFE/u-boot
int macb_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value)
{
	struct eth_device *dev = eth_get_dev_by_name(devname);
	struct macb_device *macb = to_macb(dev);

	if ( macb->phy_addr != phy_adr )
		return -1;

	arch_get_mdio_control(devname);
	*value = macb_mdio_read(macb, reg);

	return 0;
}
示例#5
0
文件: macb.c 项目: DFE/u-boot
static int macb_write_hwaddr(struct eth_device *dev)
{
	struct macb_device *macb = to_macb(dev);
	u32 hwaddr_bottom;
	u16 hwaddr_top;

	/* set hardware address */
	hwaddr_bottom = dev->enetaddr[0] | dev->enetaddr[1] << 8 |
			dev->enetaddr[2] << 16 | dev->enetaddr[3] << 24;
	macb_writel(macb, SA1B, hwaddr_bottom);
	hwaddr_top = dev->enetaddr[4] | dev->enetaddr[5] << 8;
	macb_writel(macb, SA1T, hwaddr_top);
	return 0;
}
示例#6
0
文件: macb.c 项目: DFE/u-boot
static void macb_halt(struct eth_device *netdev)
{
	struct macb_device *macb = to_macb(netdev);
	u32 ncr, tsr;

	/* Halt the controller and wait for any ongoing transmission to end. */
	ncr = macb_readl(macb, NCR);
	ncr |= MACB_BIT(THALT);
	macb_writel(macb, NCR, ncr);

	do {
		tsr = macb_readl(macb, TSR);
	} while (tsr & MACB_BIT(TGO));

	/* Disable TX and RX, and clear statistics */
	macb_writel(macb, NCR, MACB_BIT(CLRSTAT));
}
示例#7
0
static int macb_recv(struct eth_device *netdev)
{
	struct macb_device *macb = to_macb(netdev);
	uchar *packet;
	int length;

	macb->wrapped = false;
	for (;;) {
		macb->next_rx_tail = macb->rx_tail;
		length = _macb_recv(macb, &packet);
		if (length >= 0) {
			net_process_received_packet(packet, length);
			reclaim_rx_buffers(macb, macb->next_rx_tail);
		} else if (length < 0) {
			return length;
		}
	}
}
示例#8
0
int macb_miiphy_write(struct mii_dev *bus, int phy_adr, int devad, int reg,
		      u16 value)
{
#ifdef CONFIG_DM_ETH
	struct udevice *dev = eth_get_dev_by_name(bus->name);
	struct macb_device *macb = dev_get_priv(dev);
#else
	struct eth_device *dev = eth_get_dev_by_name(bus->name);
	struct macb_device *macb = to_macb(dev);
#endif

	if (macb->phy_addr != phy_adr)
		return -1;

	arch_get_mdio_control(bus->name);
	macb_mdio_write(macb, reg, value);

	return 0;
}
示例#9
0
int macb_miiphy_read(struct mii_dev *bus, int phy_adr, int devad, int reg)
{
	u16 value = 0;
#ifdef CONFIG_DM_ETH
	struct udevice *dev = eth_get_dev_by_name(bus->name);
	struct macb_device *macb = dev_get_priv(dev);
#else
	struct eth_device *dev = eth_get_dev_by_name(bus->name);
	struct macb_device *macb = to_macb(dev);
#endif

	if (macb->phy_addr != phy_adr)
		return -1;

	arch_get_mdio_control(bus->name);
	value = macb_mdio_read(macb, reg);

	return value;
}
示例#10
0
static int macb_write_hwaddr(struct eth_device *netdev)
{
	struct macb_device *macb = to_macb(netdev);

	return _macb_write_hwaddr(macb, netdev->enetaddr);
}
示例#11
0
static void macb_halt(struct eth_device *netdev)
{
	struct macb_device *macb = to_macb(netdev);

	return _macb_halt(macb);
}
示例#12
0
static int macb_init(struct eth_device *netdev, bd_t *bd)
{
	struct macb_device *macb = to_macb(netdev);

	return _macb_init(macb, netdev->name);
}
示例#13
0
static int macb_send(struct eth_device *netdev, void *packet, int length)
{
	struct macb_device *macb = to_macb(netdev);

	return _macb_send(macb, netdev->name, packet, length);
}
示例#14
0
文件: macb.c 项目: DFE/u-boot
static int macb_init(struct eth_device *netdev, bd_t *bd)
{
	struct macb_device *macb = to_macb(netdev);
	unsigned long paddr;
	int i;

	/*
	 * macb_halt should have been called at some point before now,
	 * so we'll assume the controller is idle.
	 */

	/* initialize DMA descriptors */
	paddr = macb->rx_buffer_dma;
	for (i = 0; i < CONFIG_SYS_MACB_RX_RING_SIZE; i++) {
		if (i == (CONFIG_SYS_MACB_RX_RING_SIZE - 1))
			paddr |= RXADDR_WRAP;
		macb->rx_ring[i].addr = paddr;
		macb->rx_ring[i].ctrl = 0;
		paddr += 128;
	}
	for (i = 0; i < CONFIG_SYS_MACB_TX_RING_SIZE; i++) {
		macb->tx_ring[i].addr = 0;
		if (i == (CONFIG_SYS_MACB_TX_RING_SIZE - 1))
			macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP;
		else
			macb->tx_ring[i].ctrl = TXBUF_USED;
	}
	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;

	macb_writel(macb, RBQP, macb->rx_ring_dma);
	macb_writel(macb, TBQP, macb->tx_ring_dma);

	if (macb_is_gem(macb)) {
#ifdef CONFIG_RGMII
		gem_writel(macb, UR, GEM_BIT(RGMII));
#else
		gem_writel(macb, UR, 0);
#endif
	} else {
	/* choose RMII or MII mode. This depends on the board */
#ifdef CONFIG_RMII
#ifdef CONFIG_AT91FAMILY
	macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN));
#else
	macb_writel(macb, USRIO, 0);
#endif
#else
#ifdef CONFIG_AT91FAMILY
	macb_writel(macb, USRIO, MACB_BIT(CLKEN));
#else
	macb_writel(macb, USRIO, MACB_BIT(MII));
#endif
#endif /* CONFIG_RMII */
	}

	if (!macb_phy_init(macb))
		return -1;

	/* Enable TX and RX */
	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE));

	return 0;
}
示例#15
0
static int macb_init(struct eth_device *netdev, bd_t *bd)
{
	struct macb_device *macb = to_macb(netdev);
	unsigned long paddr;
	u32 hwaddr_bottom;
	u16 hwaddr_top;
	int i;

	/*
	 * macb_halt should have been called at some point before now,
	 * so we'll assume the controller is idle.
	 */

	/* initialize DMA descriptors */
	paddr = macb->rx_buffer_dma;
	for (i = 0; i < CONFIG_SYS_MACB_RX_RING_SIZE; i++) {
		if (i == (CONFIG_SYS_MACB_RX_RING_SIZE - 1))
			paddr |= RXADDR_WRAP;
		macb->rx_ring[i].addr = paddr;
		macb->rx_ring[i].ctrl = 0;
		paddr += 128;
	}
	for (i = 0; i < CONFIG_SYS_MACB_TX_RING_SIZE; i++) {
		macb->tx_ring[i].addr = 0;
		if (i == (CONFIG_SYS_MACB_TX_RING_SIZE - 1))
			macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP;
		else
			macb->tx_ring[i].ctrl = TXBUF_USED;
	}
	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;

	macb_writel(macb, RBQP, macb->rx_ring_dma);
	macb_writel(macb, TBQP, macb->tx_ring_dma);

	/* set hardware address */
	hwaddr_bottom = cpu_to_le32(*((u32 *)netdev->enetaddr));
	macb_writel(macb, SA1B, hwaddr_bottom);
	hwaddr_top = cpu_to_le16(*((u16 *)(netdev->enetaddr + 4)));
	macb_writel(macb, SA1T, hwaddr_top);

	/* choose RMII or MII mode. This depends on the board */
#ifdef CONFIG_RMII
#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \
    defined(CONFIG_AT91SAM9263)
	macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN));
#else
	macb_writel(macb, USRIO, 0);
#endif
#else
#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \
    defined(CONFIG_AT91SAM9263)
	macb_writel(macb, USRIO, MACB_BIT(CLKEN));
#else
	macb_writel(macb, USRIO, MACB_BIT(MII));
#endif
#endif /* CONFIG_RMII */

	if (!macb_phy_init(macb))
		return -1;

	/* Enable TX and RX */
	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE));

	return 0;
}