]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - drivers/net/macb.c
net: Add support for Marvell 88E1510 PHY
[karo-tx-uboot.git] / drivers / net / macb.c
index 9c2ff487a709f57eae7caa6df51a8dce7292f2cd..58b1e74db84f426d96bde8cbe08af1422011ee44 100644 (file)
@@ -54,6 +54,7 @@ struct macb_dma_desc {
 #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
@@ -93,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;
@@ -347,14 +351,14 @@ static int macb_recv(struct eth_device *netdev)
                                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);
@@ -419,6 +423,15 @@ static int macb_phy_find(struct macb_device *macb)
 }
 #endif /* CONFIG_MACB_SEARCH_PHY */
 
+#ifdef CONFIG_PHYLIB
+#define gbit_phy_support(p)    ((p)->supported &                       \
+                                       (SUPPORTED_1000baseT_Full |     \
+                                       SUPPORTED_1000baseT_Half))
+#elif defined(CONFIG_RGMII) || defined(CONFIG_GMII)
+#define gbit_phy_support(p)    1
+#else
+#define gbit_phy_support(p)    0
+#endif
 
 static int macb_phy_init(struct macb_device *macb)
 {
@@ -478,26 +491,28 @@ 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 (gbit_phy_support(phydev)) {
+                       lpa = macb_mdio_read(macb, MII_STAT1000);
 
-               if (lpa & (LPA_1000FULL | LPA_1000HALF)) {
-                       duplex = ((lpa & LPA_1000FULL) ? 1 : 0);
+                       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,
-                              duplex ? "full" : "half",
-                              lpa);
+                               printf("%s: link up, 1000Mbps %s-duplex (lpa: 0x%04x)\n",
+                                       netdev->name,
+                                       duplex ? "full" : "half",
+                                       lpa);
 
-                       ncfgr = macb_readl(macb, NCFGR);
-                       ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
-                       ncfgr |= GEM_BIT(GBE);
+                               ncfgr = macb_readl(macb, NCFGR);
+                               ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+                               ncfgr |= GEM_BIT(GBE);
 
-                       if (duplex)
-                               ncfgr |= MACB_BIT(FD);
+                               if (duplex)
+                                       ncfgr |= MACB_BIT(FD);
 
-                       macb_writel(macb, NCFGR, ncfgr);
+                               macb_writel(macb, NCFGR, ncfgr);
 
-                       return 1;
+                               return 1;
+                       }
                }
        }
 
@@ -515,7 +530,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)
@@ -525,7 +540,30 @@ static int macb_phy_init(struct macb_device *macb)
        return 1;
 }
 
-static int macb_write_hwaddr(struct eth_device *dev);
+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);
@@ -566,6 +604,9 @@ static int macb_init(struct eth_device *netdev, bd_t *bd)
        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.
@@ -594,14 +635,6 @@ static int macb_init(struct eth_device *netdev, bd_t *bd)
 #endif /* CONFIG_RMII */
        }
 
-       /* update the ethaddr */
-       if (is_valid_ether_addr(netdev->enetaddr)) {
-               macb_write_hwaddr(netdev);
-       } else {
-               printf("%s: mac address is not valid\n", netdev->name);
-               return -1;
-       }
-
        if (!macb_phy_init(macb))
                return -1;
 
@@ -721,6 +754,8 @@ int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
                                           &macb->rx_ring_dma);
        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 */