|
@@ -264,7 +264,8 @@ static void macb_handle_link_change(struct net_device *dev)
|
|
|
reg |= MACB_BIT(FD);
|
|
|
if (phydev->speed == SPEED_100)
|
|
|
reg |= MACB_BIT(SPD);
|
|
|
- if (phydev->speed == SPEED_1000)
|
|
|
+ if (phydev->speed == SPEED_1000 &&
|
|
|
+ bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE)
|
|
|
reg |= GEM_BIT(GBE);
|
|
|
|
|
|
macb_or_gem_writel(bp, NCFGR, reg);
|
|
@@ -337,7 +338,7 @@ static int macb_mii_probe(struct net_device *dev)
|
|
|
}
|
|
|
|
|
|
/* mask with MAC supported features */
|
|
|
- if (macb_is_gem(bp))
|
|
|
+ if (macb_is_gem(bp) && bp->caps & MACB_CAPS_GIGABIT_MODE_AVAILABLE)
|
|
|
phydev->supported &= PHY_GBIT_FEATURES;
|
|
|
else
|
|
|
phydev->supported &= PHY_BASIC_FEATURES;
|
|
@@ -1342,7 +1343,7 @@ static u32 macb_dbw(struct macb *bp)
|
|
|
/*
|
|
|
* Configure the receive DMA engine
|
|
|
* - use the correct receive buffer size
|
|
|
- * - set the possibility to use INCR16 bursts
|
|
|
+ * - set best burst length for DMA operations
|
|
|
* (if not supported by FIFO, it will fallback to default)
|
|
|
* - set both rx/tx packet buffers to full memory size
|
|
|
* These are configurable parameters for GEM.
|
|
@@ -1354,24 +1355,16 @@ static void macb_configure_dma(struct macb *bp)
|
|
|
if (macb_is_gem(bp)) {
|
|
|
dmacfg = gem_readl(bp, DMACFG) & ~GEM_BF(RXBS, -1L);
|
|
|
dmacfg |= GEM_BF(RXBS, bp->rx_buffer_size / RX_BUFFER_MULTIPLE);
|
|
|
- dmacfg |= GEM_BF(FBLDO, 16);
|
|
|
+ if (bp->dma_burst_length)
|
|
|
+ dmacfg = GEM_BFINS(FBLDO, bp->dma_burst_length, dmacfg);
|
|
|
dmacfg |= GEM_BIT(TXPBMS) | GEM_BF(RXBMS, -1L);
|
|
|
dmacfg &= ~GEM_BIT(ENDIA);
|
|
|
+ netdev_dbg(bp->dev, "Cadence configure DMA with 0x%08x\n",
|
|
|
+ dmacfg);
|
|
|
gem_writel(bp, DMACFG, dmacfg);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Configure peripheral capacities according to integration options used
|
|
|
- */
|
|
|
-static void macb_configure_caps(struct macb *bp)
|
|
|
-{
|
|
|
- if (macb_is_gem(bp)) {
|
|
|
- if (GEM_BFEXT(IRQCOR, gem_readl(bp, DCFG1)) == 0)
|
|
|
- bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
static void macb_init_hw(struct macb *bp)
|
|
|
{
|
|
|
u32 config;
|
|
@@ -1394,7 +1387,6 @@ static void macb_init_hw(struct macb *bp)
|
|
|
bp->duplex = DUPLEX_HALF;
|
|
|
|
|
|
macb_configure_dma(bp);
|
|
|
- macb_configure_caps(bp);
|
|
|
|
|
|
/* Initialize TX and RX buffers */
|
|
|
macb_writel(bp, RBQP, bp->rx_ring_dma);
|
|
@@ -1783,17 +1775,61 @@ static const struct net_device_ops macb_netdev_ops = {
|
|
|
};
|
|
|
|
|
|
#if defined(CONFIG_OF)
|
|
|
+static struct macb_config pc302gem_config = {
|
|
|
+ .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE,
|
|
|
+ .dma_burst_length = 16,
|
|
|
+};
|
|
|
+
|
|
|
static const struct of_device_id macb_dt_ids[] = {
|
|
|
{ .compatible = "cdns,at32ap7000-macb" },
|
|
|
{ .compatible = "cdns,at91sam9260-macb" },
|
|
|
{ .compatible = "cdns,macb" },
|
|
|
- { .compatible = "cdns,pc302-gem" },
|
|
|
- { .compatible = "cdns,gem" },
|
|
|
+ { .compatible = "cdns,pc302-gem", .data = &pc302gem_config },
|
|
|
+ { .compatible = "cdns,gem", .data = &pc302gem_config },
|
|
|
{ /* sentinel */ }
|
|
|
};
|
|
|
MODULE_DEVICE_TABLE(of, macb_dt_ids);
|
|
|
#endif
|
|
|
|
|
|
+/*
|
|
|
+ * Configure peripheral capacities according to device tree
|
|
|
+ * and integration options used
|
|
|
+ */
|
|
|
+static void macb_configure_caps(struct macb *bp)
|
|
|
+{
|
|
|
+ u32 dcfg;
|
|
|
+ const struct of_device_id *match;
|
|
|
+ const struct macb_config *config;
|
|
|
+
|
|
|
+ if (bp->pdev->dev.of_node) {
|
|
|
+ match = of_match_node(macb_dt_ids, bp->pdev->dev.of_node);
|
|
|
+ if (match && match->data) {
|
|
|
+ config = (const struct macb_config *)match->data;
|
|
|
+
|
|
|
+ bp->caps = config->caps;
|
|
|
+ /*
|
|
|
+ * As we have access to the matching node, configure
|
|
|
+ * DMA burst length as well
|
|
|
+ */
|
|
|
+ bp->dma_burst_length = config->dma_burst_length;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (MACB_BFEXT(IDNUM, macb_readl(bp, MID)) == 0x2)
|
|
|
+ bp->caps |= MACB_CAPS_MACB_IS_GEM;
|
|
|
+
|
|
|
+ if (macb_is_gem(bp)) {
|
|
|
+ dcfg = gem_readl(bp, DCFG1);
|
|
|
+ if (GEM_BFEXT(IRQCOR, dcfg) == 0)
|
|
|
+ bp->caps |= MACB_CAPS_ISR_CLEAR_ON_WRITE;
|
|
|
+ dcfg = gem_readl(bp, DCFG2);
|
|
|
+ if ((dcfg & (GEM_BIT(RX_PKT_BUFF) | GEM_BIT(TX_PKT_BUFF))) == 0)
|
|
|
+ bp->caps |= MACB_CAPS_FIFO_MODE;
|
|
|
+ }
|
|
|
+
|
|
|
+ netdev_dbg(bp->dev, "Cadence caps 0x%08x\n", bp->caps);
|
|
|
+}
|
|
|
+
|
|
|
static int __init macb_probe(struct platform_device *pdev)
|
|
|
{
|
|
|
struct macb_platform_data *pdata;
|
|
@@ -1897,6 +1933,9 @@ static int __init macb_probe(struct platform_device *pdev)
|
|
|
|
|
|
dev->base_addr = regs->start;
|
|
|
|
|
|
+ /* setup capacities */
|
|
|
+ macb_configure_caps(bp);
|
|
|
+
|
|
|
/* setup appropriated routines according to adapter type */
|
|
|
if (macb_is_gem(bp)) {
|
|
|
bp->macbgem_ops.mog_alloc_rx_buffers = gem_alloc_rx_buffers;
|