net: e1000: Fix build warnings for 32-bit
[oweals/u-boot.git] / drivers / net / macb.c
index 750331d0540fc188400dde49b9732e08f80b367d..a5c188066ca5822627f44e6fbc3473242d99b299 100644 (file)
@@ -51,6 +51,11 @@ struct macb_dma_desc {
        u32     ctrl;
 };
 
+#define DMA_DESC_BYTES(n)      (n * sizeof(struct macb_dma_desc))
+#define MACB_TX_DMA_DESC_SIZE  (DMA_DESC_BYTES(MACB_TX_RING_SIZE))
+#define MACB_RX_DMA_DESC_SIZE  (DMA_DESC_BYTES(MACB_RX_RING_SIZE))
+#define MACB_TX_DUMMY_DMA_DESC_SIZE    (DMA_DESC_BYTES(1))
+
 #define RXADDR_USED            0x00000001
 #define RXADDR_WRAP            0x00000002
 
@@ -89,6 +94,9 @@ struct macb_device {
        unsigned long           rx_ring_dma;
        unsigned long           tx_ring_dma;
 
+       struct macb_dma_desc    *dummy_desc;
+       unsigned long           dummy_desc_dma;
+
        const struct device     *dev;
        struct eth_device       netdev;
        unsigned short          phy_addr;
@@ -194,6 +202,39 @@ int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value)
 }
 #endif
 
+#define RX     1
+#define TX     0
+static inline void macb_invalidate_ring_desc(struct macb_device *macb, bool rx)
+{
+       if (rx)
+               invalidate_dcache_range(macb->rx_ring_dma, macb->rx_ring_dma +
+                       MACB_RX_DMA_DESC_SIZE);
+       else
+               invalidate_dcache_range(macb->tx_ring_dma, macb->tx_ring_dma +
+                       MACB_TX_DMA_DESC_SIZE);
+}
+
+static inline void macb_flush_ring_desc(struct macb_device *macb, bool rx)
+{
+       if (rx)
+               flush_dcache_range(macb->rx_ring_dma, macb->rx_ring_dma +
+                       MACB_RX_DMA_DESC_SIZE);
+       else
+               flush_dcache_range(macb->tx_ring_dma, macb->tx_ring_dma +
+                       MACB_TX_DMA_DESC_SIZE);
+}
+
+static inline void macb_flush_rx_buffer(struct macb_device *macb)
+{
+       flush_dcache_range(macb->rx_buffer_dma, macb->rx_buffer_dma +
+                               MACB_RX_BUFFER_SIZE);
+}
+
+static inline void macb_invalidate_rx_buffer(struct macb_device *macb)
+{
+       invalidate_dcache_range(macb->rx_buffer_dma, macb->rx_buffer_dma +
+                               MACB_RX_BUFFER_SIZE);
+}
 
 #if defined(CONFIG_CMD_NET)
 
@@ -218,6 +259,9 @@ static int macb_send(struct eth_device *netdev, void *packet, int length)
        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));
 
        /*
@@ -226,6 +270,7 @@ static int macb_send(struct eth_device *netdev, void *packet, int length)
         */
        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;
@@ -254,6 +299,8 @@ static void reclaim_rx_buffers(struct macb_device *macb,
        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++;
@@ -267,6 +314,7 @@ static void reclaim_rx_buffers(struct macb_device *macb,
        }
 
        barrier();
+       macb_flush_ring_desc(macb, RX);
        macb->rx_tail = new_tail;
 }
 
@@ -280,6 +328,8 @@ static int macb_recv(struct eth_device *netdev)
        u32 status;
 
        for (;;) {
+               macb_invalidate_ring_desc(macb, RX);
+
                if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
                        return -1;
 
@@ -293,20 +343,22 @@ static int macb_recv(struct eth_device *netdev)
                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],
+                               memcpy((void *)net_rx_packets[0],
                                       buffer, headlen);
-                               memcpy((void *)NetRxPackets[0] + headlen,
+                               memcpy((void *)net_rx_packets[0] + headlen,
                                       macb->rx_buffer, taillen);
-                               buffer = (void *)NetRxPackets[0];
+                               buffer = (void *)net_rx_packets[0];
                        }
 
-                       NetReceive(buffer, length);
+                       net_process_received_packet(buffer, length);
                        if (++rx_tail >= MACB_RX_RING_SIZE)
                                rx_tail = 0;
                        reclaim_rx_buffers(macb, rx_tail);
@@ -431,31 +483,22 @@ static int macb_phy_init(struct macb_device *macb)
        /* First check for GMAC */
        if (macb_is_gem(macb)) {
                lpa = macb_mdio_read(macb, MII_STAT1000);
-               if (lpa & (1 << 11)) {
-                       speed = 1000;
-                       duplex = 1;
-               } else {
-                      if (lpa & (1 << 10)) {
-                               speed = 1000;
-                               duplex = 1;
-                       } else {
-                               speed = 0;
-                       }
-               }
 
-               if (speed == 1000) {
-                       printf("%s: link up, %dMbps %s-duplex (lpa: 0x%04x)\n",
+               if (lpa & (LPA_1000FULL | LPA_1000HALF)) {
+                       duplex = ((lpa & LPA_1000FULL) ? 1 : 0);
+
+                       printf("%s: link up, 1000Mbps %s-duplex (lpa: 0x%04x)\n",
                               netdev->name,
-                              speed,
                               duplex ? "full" : "half",
                               lpa);
 
                        ncfgr = macb_readl(macb, NCFGR);
-                       ncfgr &= ~(GEM_BIT(GBE) | MACB_BIT(SPD) | MACB_BIT(FD));
-                       if (speed)
-                               ncfgr |= GEM_BIT(GBE);
+                       ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+                       ncfgr |= GEM_BIT(GBE);
+
                        if (duplex)
                                ncfgr |= MACB_BIT(FD);
+
                        macb_writel(macb, NCFGR, ncfgr);
 
                        return 1;
@@ -476,7 +519,7 @@ static int macb_phy_init(struct macb_device *macb)
               lpa);
 
        ncfgr = macb_readl(macb, NCFGR);
-       ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+       ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD) | GEM_BIT(GBE));
        if (speed)
                ncfgr |= MACB_BIT(SPD);
        if (duplex)
@@ -486,6 +529,30 @@ static int macb_phy_init(struct macb_device *macb)
        return 1;
 }
 
+static int gmac_init_multi_queues(struct macb_device *macb)
+{
+       int i, num_queues = 1;
+       u32 queue_mask;
+
+       /* bit 0 is never set but queue 0 always exists */
+       queue_mask = gem_readl(macb, DCFG6) & 0xff;
+       queue_mask |= 0x1;
+
+       for (i = 1; i < MACB_MAX_QUEUES; i++)
+               if (queue_mask & (1 << i))
+                       num_queues++;
+
+       macb->dummy_desc->ctrl = TXBUF_USED;
+       macb->dummy_desc->addr = 0;
+       flush_dcache_range(macb->dummy_desc_dma, macb->dummy_desc_dma +
+                       MACB_TX_DUMMY_DMA_DESC_SIZE);
+
+       for (i = 1; i < num_queues; i++)
+               gem_writel_queue_TBQP(macb, macb->dummy_desc_dma, i - 1);
+
+       return 0;
+}
+
 static int macb_init(struct eth_device *netdev, bd_t *bd)
 {
        struct macb_device *macb = to_macb(netdev);
@@ -506,6 +573,9 @@ static int macb_init(struct eth_device *netdev, bd_t *bd)
                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))
@@ -513,6 +583,8 @@ static int macb_init(struct eth_device *netdev, bd_t *bd)
                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;
@@ -521,7 +593,16 @@ static int macb_init(struct eth_device *netdev, bd_t *bd)
        macb_writel(macb, TBQP, macb->tx_ring_dma);
 
        if (macb_is_gem(macb)) {
-#ifdef CONFIG_RGMII
+               /* 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.
+                */
+#if defined(CONFIG_RGMII) || defined(CONFIG_RMII)
                gem_writel(macb, UR, GEM_BIT(RGMII));
 #else
                gem_writel(macb, UR, 0);
@@ -658,12 +739,14 @@ int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
 
        macb->rx_buffer = dma_alloc_coherent(MACB_RX_BUFFER_SIZE,
                                             &macb->rx_buffer_dma);
-       macb->rx_ring = dma_alloc_coherent(MACB_RX_RING_SIZE
-                                          * sizeof(struct macb_dma_desc),
+       macb->rx_ring = dma_alloc_coherent(MACB_RX_DMA_DESC_SIZE,
                                           &macb->rx_ring_dma);
-       macb->tx_ring = dma_alloc_coherent(MACB_TX_RING_SIZE
-                                          * sizeof(struct macb_dma_desc),
+       macb->tx_ring = dma_alloc_coherent(MACB_TX_DMA_DESC_SIZE,
                                           &macb->tx_ring_dma);
+       macb->dummy_desc = dma_alloc_coherent(MACB_TX_DUMMY_DMA_DESC_SIZE,
+                                          &macb->dummy_desc_dma);
+
+       /* TODO: we need check the rx/tx_ring_dma is dcache line aligned */
 
        macb->regs = regs;
        macb->phy_addr = phy_addr;