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; }
static void reclaim_rx_buffers(struct macb_device *macb, unsigned int new_tail) { unsigned int i; i = macb->rx_tail; macb_invalidate_ring_desc(macb, RX); while (i > new_tail) { macb->rx_ring[i].addr &= ~RXADDR_USED; i++; if (i > MACB_RX_RING_SIZE) i = 0; } while (i < new_tail) { macb->rx_ring[i].addr &= ~RXADDR_USED; i++; } barrier(); macb_flush_ring_desc(macb, RX); macb->rx_tail = new_tail; }
static int _macb_init(struct macb_device *macb, const char *name) #endif { #ifdef CONFIG_DM_ETH struct macb_device *macb = dev_get_priv(dev); #endif 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 < MACB_RX_RING_SIZE; i++) { if (i == (MACB_RX_RING_SIZE - 1)) paddr |= RXADDR_WRAP; macb->rx_ring[i].addr = paddr; macb->rx_ring[i].ctrl = 0; paddr += 128; } macb_flush_ring_desc(macb, RX); macb_flush_rx_buffer(macb); for (i = 0; i < MACB_TX_RING_SIZE; i++) { macb->tx_ring[i].addr = 0; if (i == (MACB_TX_RING_SIZE - 1)) macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP; else macb->tx_ring[i].ctrl = TXBUF_USED; } macb_flush_ring_desc(macb, TX); macb->rx_tail = 0; macb->tx_head = 0; macb->tx_tail = 0; macb->next_rx_tail = 0; macb_writel(macb, RBQP, macb->rx_ring_dma); macb_writel(macb, TBQP, macb->tx_ring_dma); if (macb_is_gem(macb)) { /* Check the multi queue and initialize the queue for tx */ gmac_init_multi_queues(macb); /* * When the GMAC IP with GE feature, this bit is used to * select interface between RGMII and GMII. * When the GMAC IP without GE feature, this bit is used * to select interface between RMII and MII. */ #ifdef CONFIG_DM_ETH if ((macb->phy_interface == PHY_INTERFACE_MODE_RMII) || (macb->phy_interface == PHY_INTERFACE_MODE_RGMII)) gem_writel(macb, UR, GEM_BIT(RGMII)); else gem_writel(macb, UR, 0); #else #if defined(CONFIG_RGMII) || defined(CONFIG_RMII) gem_writel(macb, UR, GEM_BIT(RGMII)); #else gem_writel(macb, UR, 0); #endif #endif } else { /* choose RMII or MII mode. This depends on the board */ #ifdef CONFIG_DM_ETH #ifdef CONFIG_AT91FAMILY if (macb->phy_interface == PHY_INTERFACE_MODE_RMII) { macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN)); } else { macb_writel(macb, USRIO, MACB_BIT(CLKEN)); } #else if (macb->phy_interface == PHY_INTERFACE_MODE_RMII) macb_writel(macb, USRIO, 0); else macb_writel(macb, USRIO, MACB_BIT(MII)); #endif #else #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 */ #endif } #ifdef CONFIG_DM_ETH if (!macb_phy_init(dev, name)) #else if (!macb_phy_init(macb, name)) #endif return -1; /* Enable TX and RX */ macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE)); return 0; }
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 < MACB_RX_RING_SIZE; i++) { if (i == (MACB_RX_RING_SIZE - 1)) paddr |= RXADDR_WRAP; macb->rx_ring[i].addr = paddr; macb->rx_ring[i].ctrl = 0; paddr += 128; } macb_flush_ring_desc(macb, RX); macb_flush_rx_buffer(macb); for (i = 0; i < MACB_TX_RING_SIZE; i++) { macb->tx_ring[i].addr = 0; if (i == (MACB_TX_RING_SIZE - 1)) macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP; else macb->tx_ring[i].ctrl = TXBUF_USED; } macb_flush_ring_desc(macb, TX); macb->rx_tail = 0; macb->tx_head = 0; 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; }