Commit 60ab4361adc188fb47da1c4892cc7a2bb621efef
Committed by
David S. Miller
1 parent
fcb6a1c83e
Exists in
master
and in
7 other branches
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 */ |