aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/cadence
diff options
context:
space:
mode:
authorJamie Iles <jamie.iles@mathembedded.com>2011-11-08 05:12:32 -0500
committerJamie Iles <jamie@jamieiles.com>2011-11-22 10:21:17 -0500
commitf75ba50bdc2bcfab591bdf903312557033d0ac68 (patch)
tree4ccc618be2fb9f998eed75549ca69b31712b0d0e /drivers/net/ethernet/cadence
parentc220f8cd01198552a616c4216f2a8e719fdb5fd9 (diff)
macb: initial support for Cadence GEM
The Cadence GEM is based on the MACB Ethernet controller but has a few small changes with regards to register and bitfield placement. This patch detects the presence of a GEM by reading the module ID register and setting a flag appropriately. This handles the new HW address, USRIO and hash register base register locations in GEM. v3: - convert to macb_is_gem() inline rather than storing a boolean flag - handle rx_overrun stats for gem Acked-by: David S. Miller <davem@davemloft.net> Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com> Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Signed-off-by: Jamie Iles <jamie@jamieiles.com> Tested-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'drivers/net/ethernet/cadence')
-rw-r--r--drivers/net/ethernet/cadence/Kconfig16
-rw-r--r--drivers/net/ethernet/cadence/macb.c43
-rw-r--r--drivers/net/ethernet/cadence/macb.h61
3 files changed, 94 insertions, 26 deletions
diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig
index 98849a1fc749..a2e150059bc7 100644
--- a/drivers/net/ethernet/cadence/Kconfig
+++ b/drivers/net/ethernet/cadence/Kconfig
@@ -5,8 +5,8 @@
5config HAVE_NET_MACB 5config HAVE_NET_MACB
6 bool 6 bool
7 7
8config NET_ATMEL 8config NET_CADENCE
9 bool "Atmel devices" 9 bool "Cadence devices"
10 depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200) 10 depends on HAVE_NET_MACB || (ARM && ARCH_AT91RM9200)
11 ---help--- 11 ---help---
12 If you have a network (Ethernet) card belonging to this class, say Y. 12 If you have a network (Ethernet) card belonging to this class, say Y.
@@ -20,7 +20,7 @@ config NET_ATMEL
20 the remaining Atmel network card questions. If you say Y, you will be 20 the remaining Atmel network card questions. If you say Y, you will be
21 asked for your specific card in the following questions. 21 asked for your specific card in the following questions.
22 22
23if NET_ATMEL 23if NET_CADENCE
24 24
25config ARM_AT91_ETHER 25config ARM_AT91_ETHER
26 tristate "AT91RM9200 Ethernet support" 26 tristate "AT91RM9200 Ethernet support"
@@ -32,14 +32,16 @@ config ARM_AT91_ETHER
32 ethernet support, then you should always answer Y to this. 32 ethernet support, then you should always answer Y to this.
33 33
34config MACB 34config MACB
35 tristate "Atmel MACB support" 35 tristate "Cadence MACB/GEM support"
36 depends on HAVE_NET_MACB 36 depends on HAVE_NET_MACB
37 select PHYLIB 37 select PHYLIB
38 ---help--- 38 ---help---
39 The Atmel MACB ethernet interface is found on many AT32 and AT91 39 The Cadence MACB ethernet interface is found on many Atmel AT32 and
40 parts. Say Y to include support for the MACB chip. 40 AT91 parts. This driver also supports the Cadence GEM (Gigabit
41 Ethernet MAC found in some ARM SoC devices). Note: the Gigabit mode
42 is not yet supported. Say Y to include support for the MACB/GEM chip.
41 43
42 To compile this driver as a module, choose M here: the module 44 To compile this driver as a module, choose M here: the module
43 will be called macb. 45 will be called macb.
44 46
45endif # NET_ATMEL 47endif # NET_CADENCE
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index aa1d597091a8..4e61a8610d6a 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Atmel MACB Ethernet Controller driver 2 * Cadence MACB/GEM Ethernet Controller driver
3 * 3 *
4 * Copyright (C) 2004-2006 Atmel Corporation 4 * Copyright (C) 2004-2006 Atmel Corporation
5 * 5 *
@@ -59,9 +59,9 @@ static void __macb_set_hwaddr(struct macb *bp)
59 u16 top; 59 u16 top;
60 60
61 bottom = cpu_to_le32(*((u32 *)bp->dev->dev_addr)); 61 bottom = cpu_to_le32(*((u32 *)bp->dev->dev_addr));
62 macb_writel(bp, SA1B, bottom); 62 macb_or_gem_writel(bp, SA1B, bottom);
63 top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4))); 63 top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4)));
64 macb_writel(bp, SA1T, top); 64 macb_or_gem_writel(bp, SA1T, top);
65} 65}
66 66
67static void __init macb_get_hwaddr(struct macb *bp) 67static void __init macb_get_hwaddr(struct macb *bp)
@@ -70,8 +70,8 @@ static void __init macb_get_hwaddr(struct macb *bp)
70 u16 top; 70 u16 top;
71 u8 addr[6]; 71 u8 addr[6];
72 72
73 bottom = macb_readl(bp, SA1B); 73 bottom = macb_or_gem_readl(bp, SA1B);
74 top = macb_readl(bp, SA1T); 74 top = macb_or_gem_readl(bp, SA1T);
75 75
76 addr[0] = bottom & 0xff; 76 addr[0] = bottom & 0xff;
77 addr[1] = (bottom >> 8) & 0xff; 77 addr[1] = (bottom >> 8) & 0xff;
@@ -580,7 +580,10 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
580 580
581 if (status & MACB_BIT(ISR_ROVR)) { 581 if (status & MACB_BIT(ISR_ROVR)) {
582 /* We missed at least one packet */ 582 /* We missed at least one packet */
583 bp->hw_stats.rx_overruns++; 583 if (macb_is_gem(bp))
584 bp->hw_stats.gem.rx_overruns++;
585 else
586 bp->hw_stats.macb.rx_overruns++;
584 } 587 }
585 588
586 if (status & MACB_BIT(HRESP)) { 589 if (status & MACB_BIT(HRESP)) {
@@ -902,8 +905,8 @@ static void macb_sethashtable(struct net_device *dev)
902 mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); 905 mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
903 } 906 }
904 907
905 macb_writel(bp, HRB, mc_filter[0]); 908 macb_or_gem_writel(bp, HRB, mc_filter[0]);
906 macb_writel(bp, HRT, mc_filter[1]); 909 macb_or_gem_writel(bp, HRT, mc_filter[1]);
907} 910}
908 911
909/* 912/*
@@ -925,8 +928,8 @@ static void macb_set_rx_mode(struct net_device *dev)
925 928
926 if (dev->flags & IFF_ALLMULTI) { 929 if (dev->flags & IFF_ALLMULTI) {
927 /* Enable all multicast mode */ 930 /* Enable all multicast mode */
928 macb_writel(bp, HRB, -1); 931 macb_or_gem_writel(bp, HRB, -1);
929 macb_writel(bp, HRT, -1); 932 macb_or_gem_writel(bp, HRT, -1);
930 cfg |= MACB_BIT(NCFGR_MTI); 933 cfg |= MACB_BIT(NCFGR_MTI);
931 } else if (!netdev_mc_empty(dev)) { 934 } else if (!netdev_mc_empty(dev)) {
932 /* Enable specific multicasts */ 935 /* Enable specific multicasts */
@@ -934,8 +937,8 @@ static void macb_set_rx_mode(struct net_device *dev)
934 cfg |= MACB_BIT(NCFGR_MTI); 937 cfg |= MACB_BIT(NCFGR_MTI);
935 } else if (dev->flags & (~IFF_ALLMULTI)) { 938 } else if (dev->flags & (~IFF_ALLMULTI)) {
936 /* Disable all multicast mode */ 939 /* Disable all multicast mode */
937 macb_writel(bp, HRB, 0); 940 macb_or_gem_writel(bp, HRB, 0);
938 macb_writel(bp, HRT, 0); 941 macb_or_gem_writel(bp, HRT, 0);
939 cfg &= ~MACB_BIT(NCFGR_MTI); 942 cfg &= ~MACB_BIT(NCFGR_MTI);
940 } 943 }
941 944
@@ -1196,15 +1199,16 @@ static int __init macb_probe(struct platform_device *pdev)
1196 1199
1197 if (pdata && pdata->is_rmii) 1200 if (pdata && pdata->is_rmii)
1198#if defined(CONFIG_ARCH_AT91) 1201#if defined(CONFIG_ARCH_AT91)
1199 macb_writel(bp, USRIO, (MACB_BIT(RMII) | MACB_BIT(CLKEN)) ); 1202 macb_or_gem_writel(bp, USRIO, (MACB_BIT(RMII) |
1203 MACB_BIT(CLKEN)));
1200#else 1204#else
1201 macb_writel(bp, USRIO, 0); 1205 macb_or_gem_writel(bp, USRIO, 0);
1202#endif 1206#endif
1203 else 1207 else
1204#if defined(CONFIG_ARCH_AT91) 1208#if defined(CONFIG_ARCH_AT91)
1205 macb_writel(bp, USRIO, MACB_BIT(CLKEN)); 1209 macb_or_gem_writel(bp, USRIO, MACB_BIT(CLKEN));
1206#else 1210#else
1207 macb_writel(bp, USRIO, MACB_BIT(MII)); 1211 macb_or_gem_writel(bp, USRIO, MACB_BIT(MII));
1208#endif 1212#endif
1209 1213
1210 bp->tx_pending = DEF_TX_RING_PENDING; 1214 bp->tx_pending = DEF_TX_RING_PENDING;
@@ -1221,8 +1225,9 @@ static int __init macb_probe(struct platform_device *pdev)
1221 1225
1222 platform_set_drvdata(pdev, dev); 1226 platform_set_drvdata(pdev, dev);
1223 1227
1224 netdev_info(dev, "Atmel MACB at 0x%08lx irq %d (%pM)\n", 1228 netdev_info(dev, "Cadence %s at 0x%08lx irq %d (%pM)\n",
1225 dev->base_addr, dev->irq, dev->dev_addr); 1229 macb_is_gem(bp) ? "GEM" : "MACB", dev->base_addr,
1230 dev->irq, dev->dev_addr);
1226 1231
1227 phydev = bp->phy_dev; 1232 phydev = bp->phy_dev;
1228 netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", 1233 netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
@@ -1332,6 +1337,6 @@ module_init(macb_init);
1332module_exit(macb_exit); 1337module_exit(macb_exit);
1333 1338
1334MODULE_LICENSE("GPL"); 1339MODULE_LICENSE("GPL");
1335MODULE_DESCRIPTION("Atmel MACB Ethernet driver"); 1340MODULE_DESCRIPTION("Cadence MACB/GEM Ethernet driver");
1336MODULE_AUTHOR("Haavard Skinnemoen (Atmel)"); 1341MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
1337MODULE_ALIAS("platform:macb"); 1342MODULE_ALIAS("platform:macb");
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index d3212f6db703..d50057c244b2 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -59,6 +59,15 @@
59#define MACB_TPQ 0x00bc 59#define MACB_TPQ 0x00bc
60#define MACB_USRIO 0x00c0 60#define MACB_USRIO 0x00c0
61#define MACB_WOL 0x00c4 61#define MACB_WOL 0x00c4
62#define MACB_MID 0x00fc
63
64/* GEM register offsets. */
65#define GEM_NCFGR 0x0004
66#define GEM_USRIO 0x000c
67#define GEM_HRB 0x0080
68#define GEM_HRT 0x0084
69#define GEM_SA1B 0x0088
70#define GEM_SA1T 0x008C
62 71
63/* Bitfields in NCR */ 72/* Bitfields in NCR */
64#define MACB_LB_OFFSET 0 73#define MACB_LB_OFFSET 0
@@ -228,6 +237,12 @@
228#define MACB_WOL_MTI_OFFSET 19 237#define MACB_WOL_MTI_OFFSET 19
229#define MACB_WOL_MTI_SIZE 1 238#define MACB_WOL_MTI_SIZE 1
230 239
240/* Bitfields in MID */
241#define MACB_IDNUM_OFFSET 16
242#define MACB_IDNUM_SIZE 16
243#define MACB_REV_OFFSET 0
244#define MACB_REV_SIZE 16
245
231/* Constants for CLK */ 246/* Constants for CLK */
232#define MACB_CLK_DIV8 0 247#define MACB_CLK_DIV8 0
233#define MACB_CLK_DIV16 1 248#define MACB_CLK_DIV16 1
@@ -254,11 +269,52 @@
254 << MACB_##name##_OFFSET)) \ 269 << MACB_##name##_OFFSET)) \
255 | MACB_BF(name,value)) 270 | MACB_BF(name,value))
256 271
272#define GEM_BIT(name) \
273 (1 << GEM_##name##_OFFSET)
274#define GEM_BF(name, value) \
275 (((value) & ((1 << GEM_##name##_SIZE) - 1)) \
276 << GEM_##name##_OFFSET)
277#define GEM_BFEXT(name, value)\
278 (((value) >> GEM_##name##_OFFSET) \
279 & ((1 << GEM_##name##_SIZE) - 1))
280#define GEM_BFINS(name, value, old) \
281 (((old) & ~(((1 << GEM_##name##_SIZE) - 1) \
282 << GEM_##name##_OFFSET)) \
283 | GEM_BF(name, value))
284
257/* Register access macros */ 285/* Register access macros */
258#define macb_readl(port,reg) \ 286#define macb_readl(port,reg) \
259 __raw_readl((port)->regs + MACB_##reg) 287 __raw_readl((port)->regs + MACB_##reg)
260#define macb_writel(port,reg,value) \ 288#define macb_writel(port,reg,value) \
261 __raw_writel((value), (port)->regs + MACB_##reg) 289 __raw_writel((value), (port)->regs + MACB_##reg)
290#define gem_readl(port, reg) \
291 __raw_readl((port)->regs + GEM_##reg)
292#define gem_writel(port, reg, value) \
293 __raw_writel((value), (port)->regs + GEM_##reg)
294
295/*
296 * Conditional GEM/MACB macros. These perform the operation to the correct
297 * register dependent on whether the device is a GEM or a MACB. For registers
298 * and bitfields that are common across both devices, use macb_{read,write}l
299 * to avoid the cost of the conditional.
300 */
301#define macb_or_gem_writel(__bp, __reg, __value) \
302 ({ \
303 if (macb_is_gem((__bp))) \
304 gem_writel((__bp), __reg, __value); \
305 else \
306 macb_writel((__bp), __reg, __value); \
307 })
308
309#define macb_or_gem_readl(__bp, __reg) \
310 ({ \
311 u32 __v; \
312 if (macb_is_gem((__bp))) \
313 __v = gem_readl((__bp), __reg); \
314 else \
315 __v = macb_readl((__bp), __reg); \
316 __v; \
317 })
262 318
263struct dma_desc { 319struct dma_desc {
264 u32 addr; 320 u32 addr;
@@ -391,4 +447,9 @@ struct macb {
391 unsigned int duplex; 447 unsigned int duplex;
392}; 448};
393 449
450static inline bool macb_is_gem(struct macb *bp)
451{
452 return MACB_BFEXT(IDNUM, macb_readl(bp, MID)) == 0x2;
453}
454
394#endif /* _MACB_H */ 455#endif /* _MACB_H */