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