fec_8xx-netta.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * FEC instantatiation file for NETTA
  3. */
  4. #include <linux/config.h>
  5. #include <linux/kernel.h>
  6. #include <linux/types.h>
  7. #include <linux/sched.h>
  8. #include <linux/string.h>
  9. #include <linux/ptrace.h>
  10. #include <linux/errno.h>
  11. #include <linux/ioport.h>
  12. #include <linux/slab.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/pci.h>
  15. #include <linux/init.h>
  16. #include <linux/delay.h>
  17. #include <linux/netdevice.h>
  18. #include <linux/etherdevice.h>
  19. #include <linux/skbuff.h>
  20. #include <linux/spinlock.h>
  21. #include <linux/mii.h>
  22. #include <linux/ethtool.h>
  23. #include <linux/bitops.h>
  24. #include <asm/8xx_immap.h>
  25. #include <asm/pgtable.h>
  26. #include <asm/mpc8xx.h>
  27. #include <asm/irq.h>
  28. #include <asm/uaccess.h>
  29. #include <asm/commproc.h>
  30. #include "fec_8xx.h"
  31. /*************************************************/
  32. static struct fec_platform_info fec1_info = {
  33. .fec_no = 0,
  34. .use_mdio = 1,
  35. .phy_addr = 8,
  36. .fec_irq = SIU_LEVEL1,
  37. .phy_irq = CPM_IRQ_OFFSET + CPMVEC_PIO_PC6,
  38. .rx_ring = 128,
  39. .tx_ring = 16,
  40. .rx_copybreak = 240,
  41. .use_napi = 1,
  42. .napi_weight = 17,
  43. };
  44. static struct fec_platform_info fec2_info = {
  45. .fec_no = 1,
  46. .use_mdio = 1,
  47. .phy_addr = 2,
  48. .fec_irq = SIU_LEVEL3,
  49. .phy_irq = CPM_IRQ_OFFSET + CPMVEC_PIO_PC7,
  50. .rx_ring = 128,
  51. .tx_ring = 16,
  52. .rx_copybreak = 240,
  53. .use_napi = 1,
  54. .napi_weight = 17,
  55. };
  56. static struct net_device *fec1_dev;
  57. static struct net_device *fec2_dev;
  58. /* XXX custom u-boot & Linux startup needed */
  59. extern const char *__fw_getenv(const char *var);
  60. /* access ports */
  61. #define setbits32(_addr, _v) __fec_out32(&(_addr), __fec_in32(&(_addr)) | (_v))
  62. #define clrbits32(_addr, _v) __fec_out32(&(_addr), __fec_in32(&(_addr)) & ~(_v))
  63. #define setbits16(_addr, _v) __fec_out16(&(_addr), __fec_in16(&(_addr)) | (_v))
  64. #define clrbits16(_addr, _v) __fec_out16(&(_addr), __fec_in16(&(_addr)) & ~(_v))
  65. int fec_8xx_platform_init(void)
  66. {
  67. immap_t *immap = (immap_t *)IMAP_ADDR;
  68. bd_t *bd = (bd_t *) __res;
  69. const char *s;
  70. char *e;
  71. int i;
  72. /* use MDC for MII */
  73. setbits16(immap->im_ioport.iop_pdpar, 0x0080);
  74. clrbits16(immap->im_ioport.iop_pddir, 0x0080);
  75. /* configure FEC1 pins */
  76. setbits16(immap->im_ioport.iop_papar, 0xe810);
  77. setbits16(immap->im_ioport.iop_padir, 0x0810);
  78. clrbits16(immap->im_ioport.iop_padir, 0xe000);
  79. setbits32(immap->im_cpm.cp_pbpar, 0x00000001);
  80. clrbits32(immap->im_cpm.cp_pbdir, 0x00000001);
  81. setbits32(immap->im_cpm.cp_cptr, 0x00000100);
  82. clrbits32(immap->im_cpm.cp_cptr, 0x00000050);
  83. clrbits16(immap->im_ioport.iop_pcpar, 0x0200);
  84. clrbits16(immap->im_ioport.iop_pcdir, 0x0200);
  85. clrbits16(immap->im_ioport.iop_pcso, 0x0200);
  86. setbits16(immap->im_ioport.iop_pcint, 0x0200);
  87. /* configure FEC2 pins */
  88. setbits32(immap->im_cpm.cp_pepar, 0x00039620);
  89. setbits32(immap->im_cpm.cp_pedir, 0x00039620);
  90. setbits32(immap->im_cpm.cp_peso, 0x00031000);
  91. clrbits32(immap->im_cpm.cp_peso, 0x00008620);
  92. setbits32(immap->im_cpm.cp_cptr, 0x00000080);
  93. clrbits32(immap->im_cpm.cp_cptr, 0x00000028);
  94. clrbits16(immap->im_ioport.iop_pcpar, 0x0200);
  95. clrbits16(immap->im_ioport.iop_pcdir, 0x0200);
  96. clrbits16(immap->im_ioport.iop_pcso, 0x0200);
  97. setbits16(immap->im_ioport.iop_pcint, 0x0200);
  98. /* fill up */
  99. fec1_info.sys_clk = bd->bi_intfreq;
  100. fec2_info.sys_clk = bd->bi_intfreq;
  101. s = __fw_getenv("ethaddr");
  102. if (s != NULL) {
  103. for (i = 0; i < 6; i++) {
  104. fec1_info.macaddr[i] = simple_strtoul(s, &e, 16);
  105. if (*e)
  106. s = e + 1;
  107. }
  108. }
  109. s = __fw_getenv("eth1addr");
  110. if (s != NULL) {
  111. for (i = 0; i < 6; i++) {
  112. fec2_info.macaddr[i] = simple_strtoul(s, &e, 16);
  113. if (*e)
  114. s = e + 1;
  115. }
  116. }
  117. fec_8xx_init_one(&fec1_info, &fec1_dev);
  118. fec_8xx_init_one(&fec2_info, &fec2_dev);
  119. return fec1_dev != NULL && fec2_dev != NULL ? 0 : -1;
  120. }
  121. void fec_8xx_platform_cleanup(void)
  122. {
  123. if (fec2_dev != NULL)
  124. fec_8xx_cleanup_one(fec2_dev);
  125. if (fec1_dev != NULL)
  126. fec_8xx_cleanup_one(fec1_dev);
  127. }