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>
This commit is contained in:
Nicolas Ferre 2014-07-24 13:50:58 +02:00 committed by David S. Miller
parent ef49200121
commit e175587f4d
2 changed files with 74 additions and 20 deletions

View File

@ -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;

View File

@ -305,6 +305,12 @@
#define GEM_DBWDEF_OFFSET 25
#define GEM_DBWDEF_SIZE 3
/* Bitfields in DCFG2. */
#define GEM_RX_PKT_BUFF_OFFSET 20
#define GEM_RX_PKT_BUFF_SIZE 1
#define GEM_TX_PKT_BUFF_OFFSET 21
#define GEM_TX_PKT_BUFF_SIZE 1
/* Constants for CLK */
#define MACB_CLK_DIV8 0
#define MACB_CLK_DIV16 1
@ -326,7 +332,10 @@
#define MACB_MAN_CODE 2
/* Capability mask bits */
#define MACB_CAPS_ISR_CLEAR_ON_WRITE 0x1
#define MACB_CAPS_ISR_CLEAR_ON_WRITE 0x00000001
#define MACB_CAPS_FIFO_MODE 0x10000000
#define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000
#define MACB_CAPS_MACB_IS_GEM 0x80000000
/* Bit manipulation macros */
#define MACB_BIT(name) \
@ -554,6 +563,11 @@ struct macb_or_gem_ops {
int (*mog_rx)(struct macb *bp, int budget);
};
struct macb_config {
u32 caps;
unsigned int dma_burst_length;
};
struct macb {
void __iomem *regs;
@ -595,6 +609,7 @@ struct macb {
unsigned int duplex;
u32 caps;
unsigned int dma_burst_length;
phy_interface_t phy_interface;
@ -615,7 +630,7 @@ void macb_get_hwaddr(struct macb *bp);
static inline bool macb_is_gem(struct macb *bp)
{
return MACB_BFEXT(IDNUM, macb_readl(bp, MID)) == 0x2;
return !!(bp->caps & MACB_CAPS_MACB_IS_GEM);
}
#endif /* _MACB_H */