Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Anatolij Gustschin and committed by
David S. Miller
60ab4361 fcb6a1c8

+95 -21
+7 -3
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 + 7 + config FS_ENET_MPC5121_FEC 8 + def_bool y if (FS_ENET && PPC_MPC512x) 9 + select FS_ENET_HAS_FEC 6 10 7 11 config FS_ENET_HAS_SCC 8 12 bool "Chip has an SCC usable for ethernet" ··· 20 16 21 17 config FS_ENET_HAS_FEC 22 18 bool "Chip has an FEC usable for ethernet" 23 - depends on FS_ENET && CPM1 19 + depends on FS_ENET && (CPM1 || FS_ENET_MPC5121_FEC) 24 20 select FS_ENET_MDIO_FEC 25 21 default y 26 22 27 23 config FS_ENET_MDIO_FEC 28 24 tristate "MDIO driver for FEC" 29 - depends on FS_ENET && CPM1 25 + depends on FS_ENET && (CPM1 || FS_ENET_MPC5121_FEC) 30 26 31 27 config FS_ENET_MDIO_FCC 32 28 tristate "MDIO driver for FCC"
+7
drivers/net/fs_enet/fs_enet-main.c
··· 1094 1094 }, 1095 1095 #endif 1096 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 1104 .compatible = "fsl,pq1-fec-enet", 1099 1105 .data = (void *)&fs_fec_ops, 1100 1106 }, 1107 + #endif 1101 1108 #endif 1102 1109 {} 1103 1110 };
+48 -1
drivers/net/fs_enet/fs_enet.h
··· 13 13 14 14 #ifdef CONFIG_CPM1 15 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 */ 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 16 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
+31 -15
drivers/net/fs_enet/mac-fec.c
··· 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 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 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 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; ··· 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; ··· 301 297 /* 302 298 * Enable big endian and don't care about SDMA FC. 303 299 */ 300 + #ifdef CONFIG_FS_ENET_MPC5121_FEC 301 + FS(fecp, dma_control, 0xC0000000); 302 + #else 304 303 FW(fecp, fun_code, 0x78000000); 304 + #endif 305 305 306 306 /* 307 307 * Set MII speed. ··· 316 308 * Clear any outstanding interrupt. 317 309 */ 318 310 FW(fecp, ievent, 0xffc0); 311 + #ifndef CONFIG_FS_ENET_MPC5121_FEC 319 312 FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29); 320 313 321 314 FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */ 315 + #else 316 + /* 317 + * Only set MII mode - do not touch maximum frame length 318 + * configured before. 319 + */ 320 + FS(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); 321 + #endif 322 322 /* 323 323 * adjust to duplex mode 324 324 */ ··· 355 339 { 356 340 struct fs_enet_private *fep = netdev_priv(dev); 357 341 const struct fs_platform_info *fpi = fep->fpi; 358 - fec_t __iomem *fecp = fep->fec.fecp; 342 + struct fec __iomem *fecp = fep->fec.fecp; 359 343 360 344 struct fec_info* feci= fep->phydev->bus->priv; 361 345 ··· 391 375 static void napi_clear_rx_event(struct net_device *dev) 392 376 { 393 377 struct fs_enet_private *fep = netdev_priv(dev); 394 - fec_t __iomem *fecp = fep->fec.fecp; 378 + struct fec __iomem *fecp = fep->fec.fecp; 395 379 396 380 FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK); 397 381 } ··· 399 383 static void napi_enable_rx(struct net_device *dev) 400 384 { 401 385 struct fs_enet_private *fep = netdev_priv(dev); 402 - fec_t __iomem *fecp = fep->fec.fecp; 386 + struct fec __iomem *fecp = fep->fec.fecp; 403 387 404 388 FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK); 405 389 } ··· 407 391 static void napi_disable_rx(struct net_device *dev) 408 392 { 409 393 struct fs_enet_private *fep = netdev_priv(dev); 410 - fec_t __iomem *fecp = fep->fec.fecp; 394 + struct fec __iomem *fecp = fep->fec.fecp; 411 395 412 396 FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK); 413 397 } ··· 415 399 static void rx_bd_done(struct net_device *dev) 416 400 { 417 401 struct fs_enet_private *fep = netdev_priv(dev); 418 - fec_t __iomem *fecp = fep->fec.fecp; 402 + struct fec __iomem *fecp = fep->fec.fecp; 419 403 420 404 FW(fecp, r_des_active, 0x01000000); 421 405 } ··· 423 407 static void tx_kickstart(struct net_device *dev) 424 408 { 425 409 struct fs_enet_private *fep = netdev_priv(dev); 426 - fec_t __iomem *fecp = fep->fec.fecp; 410 + struct fec __iomem *fecp = fep->fec.fecp; 427 411 428 412 FW(fecp, x_des_active, 0x01000000); 429 413 } ··· 431 415 static u32 get_int_events(struct net_device *dev) 432 416 { 433 417 struct fs_enet_private *fep = netdev_priv(dev); 434 - fec_t __iomem *fecp = fep->fec.fecp; 418 + struct fec __iomem *fecp = fep->fec.fecp; 435 419 436 420 return FR(fecp, ievent) & FR(fecp, imask); 437 421 } ··· 439 423 static void clear_int_events(struct net_device *dev, u32 int_events) 440 424 { 441 425 struct fs_enet_private *fep = netdev_priv(dev); 442 - fec_t __iomem *fecp = fep->fec.fecp; 426 + struct fec __iomem *fecp = fep->fec.fecp; 443 427 444 428 FW(fecp, ievent, int_events); 445 429 } ··· 455 439 { 456 440 struct fs_enet_private *fep = netdev_priv(dev); 457 441 458 - if (*sizep < sizeof(fec_t)) 442 + if (*sizep < sizeof(struct fec)) 459 443 return -EINVAL; 460 444 461 - memcpy_fromio(p, fep->fec.fecp, sizeof(fec_t)); 445 + memcpy_fromio(p, fep->fec.fecp, sizeof(struct fec)); 462 446 463 447 return 0; 464 448 } 465 449 466 450 static int get_regs_len(struct net_device *dev) 467 451 { 468 - return sizeof(fec_t); 452 + return sizeof(struct fec); 469 453 } 470 454 471 455 static void tx_restart(struct net_device *dev)
+2 -2
drivers/net/fs_enet/mii-fec.c
··· 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 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 */