aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnatolij Gustschin <agust@denx.de>2010-02-26 07:00:48 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-27 05:34:35 -0500
commit60ab4361adc188fb47da1c4892cc7a2bb621efef (patch)
tree7949c204769f3bf400f9c4806082a122bc6e8e79
parentfcb6a1c83e48c30ff99624e9c46ce301707ede05 (diff)
fs_enet: Add support for MPC512x to fs_enet driver
Extend the fs_enet driver to support MPC512x FEC. Enable it with CONFIG_FS_ENET_MPC5121_FEC option. Signed-off-by: John Rigby <jcrigby@gmail.com> Signed-off-by: Piotr Ziecik <kosmo@semihalf.com> Signed-off-by: Wolfgang Denk <wd@denx.de> Signed-off-by: Anatolij Gustschin <agust@denx.de> Acked-by: Grant Likely <grant.likely@secretlab.ca> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/fs_enet/Kconfig10
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c7
-rw-r--r--drivers/net/fs_enet/fs_enet.h49
-rw-r--r--drivers/net/fs_enet/mac-fec.c46
-rw-r--r--drivers/net/fs_enet/mii-fec.c4
5 files changed, 95 insertions, 21 deletions
diff --git a/drivers/net/fs_enet/Kconfig b/drivers/net/fs_enet/Kconfig
index 562ea68ed99b..fc073b5a38c7 100644
--- a/drivers/net/fs_enet/Kconfig
+++ b/drivers/net/fs_enet/Kconfig
@@ -1,9 +1,13 @@
1config FS_ENET 1config FS_ENET
2 tristate "Freescale Ethernet Driver" 2 tristate "Freescale Ethernet Driver"
3 depends on CPM1 || CPM2 3 depends on CPM1 || CPM2 || PPC_MPC512x
4 select MII 4 select MII
5 select PHYLIB 5 select PHYLIB
6 6
7config FS_ENET_MPC5121_FEC
8 def_bool y if (FS_ENET && PPC_MPC512x)
9 select FS_ENET_HAS_FEC
10
7config FS_ENET_HAS_SCC 11config FS_ENET_HAS_SCC
8 bool "Chip has an SCC usable for ethernet" 12 bool "Chip has an SCC usable for ethernet"
9 depends on FS_ENET && (CPM1 || CPM2) 13 depends on FS_ENET && (CPM1 || CPM2)
@@ -16,13 +20,13 @@ config FS_ENET_HAS_FCC
16 20
17config FS_ENET_HAS_FEC 21config FS_ENET_HAS_FEC
18 bool "Chip has an FEC usable for ethernet" 22 bool "Chip has an FEC usable for ethernet"
19 depends on FS_ENET && CPM1 23 depends on FS_ENET && (CPM1 || FS_ENET_MPC5121_FEC)
20 select FS_ENET_MDIO_FEC 24 select FS_ENET_MDIO_FEC
21 default y 25 default y
22 26
23config FS_ENET_MDIO_FEC 27config FS_ENET_MDIO_FEC
24 tristate "MDIO driver for FEC" 28 tristate "MDIO driver for FEC"
25 depends on FS_ENET && CPM1 29 depends on FS_ENET && (CPM1 || FS_ENET_MPC5121_FEC)
26 30
27config FS_ENET_MDIO_FCC 31config FS_ENET_MDIO_FCC
28 tristate "MDIO driver for FCC" 32 tristate "MDIO driver for FCC"
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index c34a7e0a28ed..4297021214d1 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -1094,11 +1094,18 @@ static struct of_device_id fs_enet_match[] = {
1094 }, 1094 },
1095#endif 1095#endif
1096#ifdef CONFIG_FS_ENET_HAS_FEC 1096#ifdef CONFIG_FS_ENET_HAS_FEC
1097#ifdef CONFIG_FS_ENET_MPC5121_FEC
1098 {
1099 .compatible = "fsl,mpc5121-fec",
1100 .data = (void *)&fs_fec_ops,
1101 },
1102#else
1097 { 1103 {
1098 .compatible = "fsl,pq1-fec-enet", 1104 .compatible = "fsl,pq1-fec-enet",
1099 .data = (void *)&fs_fec_ops, 1105 .data = (void *)&fs_fec_ops,
1100 }, 1106 },
1101#endif 1107#endif
1108#endif
1102 {} 1109 {}
1103}; 1110};
1104MODULE_DEVICE_TABLE(of, fs_enet_match); 1111MODULE_DEVICE_TABLE(of, fs_enet_match);
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index ef01e09781a5..1ece4b1a689e 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -13,9 +13,56 @@
13 13
14#ifdef CONFIG_CPM1 14#ifdef CONFIG_CPM1
15#include <asm/cpm1.h> 15#include <asm/cpm1.h>
16#endif
17
18#if defined(CONFIG_FS_ENET_HAS_FEC)
19#include <asm/cpm.h>
20
21#if defined(CONFIG_FS_ENET_MPC5121_FEC)
22/* MPC5121 FEC has different register layout */
23struct fec {
24 u32 fec_reserved0;
25 u32 fec_ievent; /* Interrupt event reg */
26 u32 fec_imask; /* Interrupt mask reg */
27 u32 fec_reserved1;
28 u32 fec_r_des_active; /* Receive descriptor reg */
29 u32 fec_x_des_active; /* Transmit descriptor reg */
30 u32 fec_reserved2[3];
31 u32 fec_ecntrl; /* Ethernet control reg */
32 u32 fec_reserved3[6];
33 u32 fec_mii_data; /* MII manage frame reg */
34 u32 fec_mii_speed; /* MII speed control reg */
35 u32 fec_reserved4[7];
36 u32 fec_mib_ctrlstat; /* MIB control/status reg */
37 u32 fec_reserved5[7];
38 u32 fec_r_cntrl; /* Receive control reg */
39 u32 fec_reserved6[15];
40 u32 fec_x_cntrl; /* Transmit Control reg */
41 u32 fec_reserved7[7];
42 u32 fec_addr_low; /* Low 32bits MAC address */
43 u32 fec_addr_high; /* High 16bits MAC address */
44 u32 fec_opd; /* Opcode + Pause duration */
45 u32 fec_reserved8[10];
46 u32 fec_hash_table_high; /* High 32bits hash table */
47 u32 fec_hash_table_low; /* Low 32bits hash table */
48 u32 fec_grp_hash_table_high; /* High 32bits hash table */
49 u32 fec_grp_hash_table_low; /* Low 32bits hash table */
50 u32 fec_reserved9[7];
51 u32 fec_x_wmrk; /* FIFO transmit water mark */
52 u32 fec_reserved10;
53 u32 fec_r_bound; /* FIFO receive bound reg */
54 u32 fec_r_fstart; /* FIFO receive start reg */
55 u32 fec_reserved11[11];
56 u32 fec_r_des_start; /* Receive descriptor ring */
57 u32 fec_x_des_start; /* Transmit descriptor ring */
58 u32 fec_r_buff_size; /* Maximum receive buff size */
59 u32 fec_reserved12[26];
60 u32 fec_dma_control; /* DMA Endian and other ctrl */
61};
62#endif
16 63
17struct fec_info { 64struct fec_info {
18 fec_t __iomem *fecp; 65 struct fec __iomem *fecp;
19 u32 mii_speed; 66 u32 mii_speed;
20}; 67};
21#endif 68#endif
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index 8a632f668c1f..cd2c6cca5f24 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -80,7 +80,7 @@
80 */ 80 */
81#define FEC_RESET_DELAY 50 81#define FEC_RESET_DELAY 50
82 82
83static int whack_reset(fec_t __iomem *fecp) 83static int whack_reset(struct fec __iomem *fecp)
84{ 84{
85 int i; 85 int i;
86 86
@@ -168,7 +168,7 @@ static void cleanup_data(struct net_device *dev)
168static void set_promiscuous_mode(struct net_device *dev) 168static void set_promiscuous_mode(struct net_device *dev)
169{ 169{
170 struct fs_enet_private *fep = netdev_priv(dev); 170 struct fs_enet_private *fep = netdev_priv(dev);
171 fec_t __iomem *fecp = fep->fec.fecp; 171 struct fec __iomem *fecp = fep->fec.fecp;
172 172
173 FS(fecp, r_cntrl, FEC_RCNTRL_PROM); 173 FS(fecp, r_cntrl, FEC_RCNTRL_PROM);
174} 174}
@@ -216,7 +216,7 @@ static void set_multicast_one(struct net_device *dev, const u8 *mac)
216static void set_multicast_finish(struct net_device *dev) 216static void set_multicast_finish(struct net_device *dev)
217{ 217{
218 struct fs_enet_private *fep = netdev_priv(dev); 218 struct fs_enet_private *fep = netdev_priv(dev);
219 fec_t __iomem *fecp = fep->fec.fecp; 219 struct fec __iomem *fecp = fep->fec.fecp;
220 220
221 /* if all multi or too many multicasts; just enable all */ 221 /* if all multi or too many multicasts; just enable all */
222 if ((dev->flags & IFF_ALLMULTI) != 0 || 222 if ((dev->flags & IFF_ALLMULTI) != 0 ||
@@ -246,7 +246,7 @@ static void set_multicast_list(struct net_device *dev)
246static void restart(struct net_device *dev) 246static void restart(struct net_device *dev)
247{ 247{
248 struct fs_enet_private *fep = netdev_priv(dev); 248 struct fs_enet_private *fep = netdev_priv(dev);
249 fec_t __iomem *fecp = fep->fec.fecp; 249 struct fec __iomem *fecp = fep->fec.fecp;
250 const struct fs_platform_info *fpi = fep->fpi; 250 const struct fs_platform_info *fpi = fep->fpi;
251 dma_addr_t rx_bd_base_phys, tx_bd_base_phys; 251 dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
252 int r; 252 int r;
@@ -280,7 +280,11 @@ static void restart(struct net_device *dev)
280 * Set maximum receive buffer size. 280 * Set maximum receive buffer size.
281 */ 281 */
282 FW(fecp, r_buff_size, PKT_MAXBLR_SIZE); 282 FW(fecp, r_buff_size, PKT_MAXBLR_SIZE);
283#ifdef CONFIG_FS_ENET_MPC5121_FEC
284 FW(fecp, r_cntrl, PKT_MAXBUF_SIZE << 16);
285#else
283 FW(fecp, r_hash, PKT_MAXBUF_SIZE); 286 FW(fecp, r_hash, PKT_MAXBUF_SIZE);
287#endif
284 288
285 /* get physical address */ 289 /* get physical address */
286 rx_bd_base_phys = fep->ring_mem_addr; 290 rx_bd_base_phys = fep->ring_mem_addr;
@@ -297,7 +301,11 @@ static void restart(struct net_device *dev)
297 /* 301 /*
298 * Enable big endian and don't care about SDMA FC. 302 * Enable big endian and don't care about SDMA FC.
299 */ 303 */
304#ifdef CONFIG_FS_ENET_MPC5121_FEC
305 FS(fecp, dma_control, 0xC0000000);
306#else
300 FW(fecp, fun_code, 0x78000000); 307 FW(fecp, fun_code, 0x78000000);
308#endif
301 309
302 /* 310 /*
303 * Set MII speed. 311 * Set MII speed.
@@ -308,9 +316,17 @@ static void restart(struct net_device *dev)
308 * Clear any outstanding interrupt. 316 * Clear any outstanding interrupt.
309 */ 317 */
310 FW(fecp, ievent, 0xffc0); 318 FW(fecp, ievent, 0xffc0);
319#ifndef CONFIG_FS_ENET_MPC5121_FEC
311 FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29); 320 FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29);
312 321
313 FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ 322 FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
323#else
324 /*
325 * Only set MII mode - do not touch maximum frame length
326 * configured before.
327 */
328 FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE);
329#endif
314 /* 330 /*
315 * adjust to duplex mode 331 * adjust to duplex mode
316 */ 332 */
@@ -339,7 +355,7 @@ static void stop(struct net_device *dev)
339{ 355{
340 struct fs_enet_private *fep = netdev_priv(dev); 356 struct fs_enet_private *fep = netdev_priv(dev);
341 const struct fs_platform_info *fpi = fep->fpi; 357 const struct fs_platform_info *fpi = fep->fpi;
342 fec_t __iomem *fecp = fep->fec.fecp; 358 struct fec __iomem *fecp = fep->fec.fecp;
343 359
344 struct fec_info* feci= fep->phydev->bus->priv; 360 struct fec_info* feci= fep->phydev->bus->priv;
345 361
@@ -375,7 +391,7 @@ static void stop(struct net_device *dev)
375static void napi_clear_rx_event(struct net_device *dev) 391static void napi_clear_rx_event(struct net_device *dev)
376{ 392{
377 struct fs_enet_private *fep = netdev_priv(dev); 393 struct fs_enet_private *fep = netdev_priv(dev);
378 fec_t __iomem *fecp = fep->fec.fecp; 394 struct fec __iomem *fecp = fep->fec.fecp;
379 395
380 FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK); 396 FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK);
381} 397}
@@ -383,7 +399,7 @@ static void napi_clear_rx_event(struct net_device *dev)
383static void napi_enable_rx(struct net_device *dev) 399static void napi_enable_rx(struct net_device *dev)
384{ 400{
385 struct fs_enet_private *fep = netdev_priv(dev); 401 struct fs_enet_private *fep = netdev_priv(dev);
386 fec_t __iomem *fecp = fep->fec.fecp; 402 struct fec __iomem *fecp = fep->fec.fecp;
387 403
388 FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK); 404 FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
389} 405}
@@ -391,7 +407,7 @@ static void napi_enable_rx(struct net_device *dev)
391static void napi_disable_rx(struct net_device *dev) 407static void napi_disable_rx(struct net_device *dev)
392{ 408{
393 struct fs_enet_private *fep = netdev_priv(dev); 409 struct fs_enet_private *fep = netdev_priv(dev);
394 fec_t __iomem *fecp = fep->fec.fecp; 410 struct fec __iomem *fecp = fep->fec.fecp;
395 411
396 FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK); 412 FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
397} 413}
@@ -399,7 +415,7 @@ static void napi_disable_rx(struct net_device *dev)
399static void rx_bd_done(struct net_device *dev) 415static void rx_bd_done(struct net_device *dev)
400{ 416{
401 struct fs_enet_private *fep = netdev_priv(dev); 417 struct fs_enet_private *fep = netdev_priv(dev);
402 fec_t __iomem *fecp = fep->fec.fecp; 418 struct fec __iomem *fecp = fep->fec.fecp;
403 419
404 FW(fecp, r_des_active, 0x01000000); 420 FW(fecp, r_des_active, 0x01000000);
405} 421}
@@ -407,7 +423,7 @@ static void rx_bd_done(struct net_device *dev)
407static void tx_kickstart(struct net_device *dev) 423static void tx_kickstart(struct net_device *dev)
408{ 424{
409 struct fs_enet_private *fep = netdev_priv(dev); 425 struct fs_enet_private *fep = netdev_priv(dev);
410 fec_t __iomem *fecp = fep->fec.fecp; 426 struct fec __iomem *fecp = fep->fec.fecp;
411 427
412 FW(fecp, x_des_active, 0x01000000); 428 FW(fecp, x_des_active, 0x01000000);
413} 429}
@@ -415,7 +431,7 @@ static void tx_kickstart(struct net_device *dev)
415static u32 get_int_events(struct net_device *dev) 431static u32 get_int_events(struct net_device *dev)
416{ 432{
417 struct fs_enet_private *fep = netdev_priv(dev); 433 struct fs_enet_private *fep = netdev_priv(dev);
418 fec_t __iomem *fecp = fep->fec.fecp; 434 struct fec __iomem *fecp = fep->fec.fecp;
419 435
420 return FR(fecp, ievent) & FR(fecp, imask); 436 return FR(fecp, ievent) & FR(fecp, imask);
421} 437}
@@ -423,7 +439,7 @@ static u32 get_int_events(struct net_device *dev)
423static void clear_int_events(struct net_device *dev, u32 int_events) 439static void clear_int_events(struct net_device *dev, u32 int_events)
424{ 440{
425 struct fs_enet_private *fep = netdev_priv(dev); 441 struct fs_enet_private *fep = netdev_priv(dev);
426 fec_t __iomem *fecp = fep->fec.fecp; 442 struct fec __iomem *fecp = fep->fec.fecp;
427 443
428 FW(fecp, ievent, int_events); 444 FW(fecp, ievent, int_events);
429} 445}
@@ -439,17 +455,17 @@ static int get_regs(struct net_device *dev, void *p, int *sizep)
439{ 455{
440 struct fs_enet_private *fep = netdev_priv(dev); 456 struct fs_enet_private *fep = netdev_priv(dev);
441 457
442 if (*sizep < sizeof(fec_t)) 458 if (*sizep < sizeof(struct fec))
443 return -EINVAL; 459 return -EINVAL;
444 460
445 memcpy_fromio(p, fep->fec.fecp, sizeof(fec_t)); 461 memcpy_fromio(p, fep->fec.fecp, sizeof(struct fec));
446 462
447 return 0; 463 return 0;
448} 464}
449 465
450static int get_regs_len(struct net_device *dev) 466static int get_regs_len(struct net_device *dev)
451{ 467{
452 return sizeof(fec_t); 468 return sizeof(struct fec);
453} 469}
454 470
455static void tx_restart(struct net_device *dev) 471static void tx_restart(struct net_device *dev)
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 96eba4280c5c..5944b65082cb 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -52,7 +52,7 @@
52static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location) 52static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
53{ 53{
54 struct fec_info* fec = bus->priv; 54 struct fec_info* fec = bus->priv;
55 fec_t __iomem *fecp = fec->fecp; 55 struct fec __iomem *fecp = fec->fecp;
56 int i, ret = -1; 56 int i, ret = -1;
57 57
58 BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0); 58 BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
@@ -75,7 +75,7 @@ static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
75static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val) 75static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
76{ 76{
77 struct fec_info* fec = bus->priv; 77 struct fec_info* fec = bus->priv;
78 fec_t __iomem *fecp = fec->fecp; 78 struct fec __iomem *fecp = fec->fecp;
79 int i; 79 int i;
80 80
81 /* this must never happen */ 81 /* this must never happen */