diff options
author | Nicolas Ferre <nicolas.ferre@atmel.com> | 2014-07-24 13:50:58 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-24 23:39:55 -0700 |
commit | e175587f4d32de27182f5d28d70734b1e812905d (patch) | |
tree | c2a50bc09a82b225128d363b66d01ab10b6801f1 /drivers/net/ethernet/cadence/macb.c | |
parent | ef492001214ba250b3bd18a7a346a047fe079449 (diff) |
net/macb: configure for FIFO mode and non-gigabit
This addition will also allow to configure DMA burst length.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/cadence/macb.c')
-rw-r--r-- | drivers/net/ethernet/cadence/macb.c | 75 |
1 files changed, 57 insertions, 18 deletions
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index e9daa072ebb..91870e92073 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -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; |