Commit 60ab4361adc188fb47da1c4892cc7a2bb621efef

Authored by Anatolij Gustschin
Committed by David S. Miller
1 parent fcb6a1c83e

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>

Showing 5 changed files with 95 additions and 21 deletions Side-by-side Diff

drivers/net/fs_enet/Kconfig
1 1 config FS_ENET
2 2 tristate "Freescale Ethernet Driver"
3   - depends on CPM1 || CPM2
  3 + depends on CPM1 || CPM2 || PPC_MPC512x
4 4 select MII
5 5 select PHYLIB
6 6  
  7 +config FS_ENET_MPC5121_FEC
  8 + def_bool y if (FS_ENET && PPC_MPC512x)
  9 + select FS_ENET_HAS_FEC
  10 +
7 11 config FS_ENET_HAS_SCC
8 12 bool "Chip has an SCC usable for ethernet"
9 13 depends on FS_ENET && (CPM1 || CPM2)
10 14  
... ... @@ -16,13 +20,13 @@
16 20  
17 21 config FS_ENET_HAS_FEC
18 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 24 select FS_ENET_MDIO_FEC
21 25 default y
22 26  
23 27 config FS_ENET_MDIO_FEC
24 28 tristate "MDIO driver for FEC"
25   - depends on FS_ENET && CPM1
  29 + depends on FS_ENET && (CPM1 || FS_ENET_MPC5121_FEC)
26 30  
27 31 config FS_ENET_MDIO_FCC
28 32 tristate "MDIO driver for FCC"
drivers/net/fs_enet/fs_enet-main.c
... ... @@ -1094,10 +1094,17 @@
1094 1094 },
1095 1095 #endif
1096 1096 #ifdef CONFIG_FS_ENET_HAS_FEC
  1097 +#ifdef CONFIG_FS_ENET_MPC5121_FEC
1097 1098 {
  1099 + .compatible = "fsl,mpc5121-fec",
  1100 + .data = (void *)&fs_fec_ops,
  1101 + },
  1102 +#else
  1103 + {
1098 1104 .compatible = "fsl,pq1-fec-enet",
1099 1105 .data = (void *)&fs_fec_ops,
1100 1106 },
  1107 +#endif
1101 1108 #endif
1102 1109 {}
1103 1110 };
drivers/net/fs_enet/fs_enet.h
... ... @@ -13,9 +13,56 @@
13 13  
14 14 #ifdef CONFIG_CPM1
15 15 #include <asm/cpm1.h>
  16 +#endif
16 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 */
  23 +struct 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
  63 +
17 64 struct fec_info {
18   - fec_t __iomem *fecp;
  65 + struct fec __iomem *fecp;
19 66 u32 mii_speed;
20 67 };
21 68 #endif
drivers/net/fs_enet/mac-fec.c
... ... @@ -80,7 +80,7 @@
80 80 */
81 81 #define FEC_RESET_DELAY 50
82 82  
83   -static int whack_reset(fec_t __iomem *fecp)
  83 +static int whack_reset(struct fec __iomem *fecp)
84 84 {
85 85 int i;
86 86  
... ... @@ -168,7 +168,7 @@
168 168 static void set_promiscuous_mode(struct net_device *dev)
169 169 {
170 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 173 FS(fecp, r_cntrl, FEC_RCNTRL_PROM);
174 174 }
... ... @@ -216,7 +216,7 @@
216 216 static void set_multicast_finish(struct net_device *dev)
217 217 {
218 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 221 /* if all multi or too many multicasts; just enable all */
222 222 if ((dev->flags & IFF_ALLMULTI) != 0 ||
... ... @@ -246,7 +246,7 @@
246 246 static void restart(struct net_device *dev)
247 247 {
248 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 250 const struct fs_platform_info *fpi = fep->fpi;
251 251 dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
252 252 int r;
253 253  
... ... @@ -280,7 +280,11 @@
280 280 * Set maximum receive buffer size.
281 281 */
282 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 286 FW(fecp, r_hash, PKT_MAXBUF_SIZE);
  287 +#endif
284 288  
285 289 /* get physical address */
286 290 rx_bd_base_phys = fep->ring_mem_addr;
287 291  
... ... @@ -297,7 +301,11 @@
297 301 /*
298 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 307 FW(fecp, fun_code, 0x78000000);
  308 +#endif
301 309  
302 310 /*
303 311 * Set MII speed.
304 312  
305 313  
... ... @@ -308,10 +316,18 @@
308 316 * Clear any outstanding interrupt.
309 317 */
310 318 FW(fecp, ievent, 0xffc0);
  319 +#ifndef CONFIG_FS_ENET_MPC5121_FEC
311 320 FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29);
312 321  
313 322 FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
  323 +#else
314 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
  330 + /*
315 331 * adjust to duplex mode
316 332 */
317 333 if (fep->phydev->duplex) {
... ... @@ -339,7 +355,7 @@
339 355 {
340 356 struct fs_enet_private *fep = netdev_priv(dev);
341 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 360 struct fec_info* feci= fep->phydev->bus->priv;
345 361  
... ... @@ -375,7 +391,7 @@
375 391 static void napi_clear_rx_event(struct net_device *dev)
376 392 {
377 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 396 FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK);
381 397 }
... ... @@ -383,7 +399,7 @@
383 399 static void napi_enable_rx(struct net_device *dev)
384 400 {
385 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 404 FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
389 405 }
... ... @@ -391,7 +407,7 @@
391 407 static void napi_disable_rx(struct net_device *dev)
392 408 {
393 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 412 FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
397 413 }
... ... @@ -399,7 +415,7 @@
399 415 static void rx_bd_done(struct net_device *dev)
400 416 {
401 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 420 FW(fecp, r_des_active, 0x01000000);
405 421 }
... ... @@ -407,7 +423,7 @@
407 423 static void tx_kickstart(struct net_device *dev)
408 424 {
409 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 428 FW(fecp, x_des_active, 0x01000000);
413 429 }
... ... @@ -415,7 +431,7 @@
415 431 static u32 get_int_events(struct net_device *dev)
416 432 {
417 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 436 return FR(fecp, ievent) & FR(fecp, imask);
421 437 }
... ... @@ -423,7 +439,7 @@
423 439 static void clear_int_events(struct net_device *dev, u32 int_events)
424 440 {
425 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 444 FW(fecp, ievent, int_events);
429 445 }
430 446  
431 447  
... ... @@ -439,17 +455,17 @@
439 455 {
440 456 struct fs_enet_private *fep = netdev_priv(dev);
441 457  
442   - if (*sizep < sizeof(fec_t))
  458 + if (*sizep < sizeof(struct fec))
443 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 463 return 0;
448 464 }
449 465  
450 466 static int get_regs_len(struct net_device *dev)
451 467 {
452   - return sizeof(fec_t);
  468 + return sizeof(struct fec);
453 469 }
454 470  
455 471 static void tx_restart(struct net_device *dev)
drivers/net/fs_enet/mii-fec.c
... ... @@ -52,7 +52,7 @@
52 52 static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
53 53 {
54 54 struct fec_info* fec = bus->priv;
55   - fec_t __iomem *fecp = fec->fecp;
  55 + struct fec __iomem *fecp = fec->fecp;
56 56 int i, ret = -1;
57 57  
58 58 BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
... ... @@ -75,7 +75,7 @@
75 75 static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
76 76 {
77 77 struct fec_info* fec = bus->priv;
78   - fec_t __iomem *fecp = fec->fecp;
  78 + struct fec __iomem *fecp = fec->fecp;
79 79 int i;
80 80  
81 81 /* this must never happen */