152 lines
3.7 KiB
C
152 lines
3.7 KiB
C
|
/*
|
||
|
* FEC instantatiation file for NETTA
|
||
|
*/
|
||
|
|
||
|
#include <linux/kernel.h>
|
||
|
#include <linux/types.h>
|
||
|
#include <linux/string.h>
|
||
|
#include <linux/ptrace.h>
|
||
|
#include <linux/errno.h>
|
||
|
#include <linux/ioport.h>
|
||
|
#include <linux/slab.h>
|
||
|
#include <linux/interrupt.h>
|
||
|
#include <linux/pci.h>
|
||
|
#include <linux/init.h>
|
||
|
#include <linux/delay.h>
|
||
|
#include <linux/netdevice.h>
|
||
|
#include <linux/etherdevice.h>
|
||
|
#include <linux/skbuff.h>
|
||
|
#include <linux/spinlock.h>
|
||
|
#include <linux/mii.h>
|
||
|
#include <linux/ethtool.h>
|
||
|
#include <linux/bitops.h>
|
||
|
|
||
|
#include <asm/8xx_immap.h>
|
||
|
#include <asm/pgtable.h>
|
||
|
#include <asm/mpc8xx.h>
|
||
|
#include <asm/irq.h>
|
||
|
#include <asm/uaccess.h>
|
||
|
#include <asm/commproc.h>
|
||
|
|
||
|
#include "fec_8xx.h"
|
||
|
|
||
|
/*************************************************/
|
||
|
|
||
|
static struct fec_platform_info fec1_info = {
|
||
|
.fec_no = 0,
|
||
|
.use_mdio = 1,
|
||
|
.phy_addr = 8,
|
||
|
.fec_irq = SIU_LEVEL1,
|
||
|
.phy_irq = CPM_IRQ_OFFSET + CPMVEC_PIO_PC6,
|
||
|
.rx_ring = 128,
|
||
|
.tx_ring = 16,
|
||
|
.rx_copybreak = 240,
|
||
|
.use_napi = 1,
|
||
|
.napi_weight = 17,
|
||
|
};
|
||
|
|
||
|
static struct fec_platform_info fec2_info = {
|
||
|
.fec_no = 1,
|
||
|
.use_mdio = 1,
|
||
|
.phy_addr = 2,
|
||
|
.fec_irq = SIU_LEVEL3,
|
||
|
.phy_irq = CPM_IRQ_OFFSET + CPMVEC_PIO_PC7,
|
||
|
.rx_ring = 128,
|
||
|
.tx_ring = 16,
|
||
|
.rx_copybreak = 240,
|
||
|
.use_napi = 1,
|
||
|
.napi_weight = 17,
|
||
|
};
|
||
|
|
||
|
static struct net_device *fec1_dev;
|
||
|
static struct net_device *fec2_dev;
|
||
|
|
||
|
/* XXX custom u-boot & Linux startup needed */
|
||
|
extern const char *__fw_getenv(const char *var);
|
||
|
|
||
|
/* access ports */
|
||
|
#define setbits32(_addr, _v) __fec_out32(&(_addr), __fec_in32(&(_addr)) | (_v))
|
||
|
#define clrbits32(_addr, _v) __fec_out32(&(_addr), __fec_in32(&(_addr)) & ~(_v))
|
||
|
|
||
|
#define setbits16(_addr, _v) __fec_out16(&(_addr), __fec_in16(&(_addr)) | (_v))
|
||
|
#define clrbits16(_addr, _v) __fec_out16(&(_addr), __fec_in16(&(_addr)) & ~(_v))
|
||
|
|
||
|
int fec_8xx_platform_init(void)
|
||
|
{
|
||
|
immap_t *immap = (immap_t *)IMAP_ADDR;
|
||
|
bd_t *bd = (bd_t *) __res;
|
||
|
const char *s;
|
||
|
char *e;
|
||
|
int i;
|
||
|
|
||
|
/* use MDC for MII */
|
||
|
setbits16(immap->im_ioport.iop_pdpar, 0x0080);
|
||
|
clrbits16(immap->im_ioport.iop_pddir, 0x0080);
|
||
|
|
||
|
/* configure FEC1 pins */
|
||
|
setbits16(immap->im_ioport.iop_papar, 0xe810);
|
||
|
setbits16(immap->im_ioport.iop_padir, 0x0810);
|
||
|
clrbits16(immap->im_ioport.iop_padir, 0xe000);
|
||
|
|
||
|
setbits32(immap->im_cpm.cp_pbpar, 0x00000001);
|
||
|
clrbits32(immap->im_cpm.cp_pbdir, 0x00000001);
|
||
|
|
||
|
setbits32(immap->im_cpm.cp_cptr, 0x00000100);
|
||
|
clrbits32(immap->im_cpm.cp_cptr, 0x00000050);
|
||
|
|
||
|
clrbits16(immap->im_ioport.iop_pcpar, 0x0200);
|
||
|
clrbits16(immap->im_ioport.iop_pcdir, 0x0200);
|
||
|
clrbits16(immap->im_ioport.iop_pcso, 0x0200);
|
||
|
setbits16(immap->im_ioport.iop_pcint, 0x0200);
|
||
|
|
||
|
/* configure FEC2 pins */
|
||
|
setbits32(immap->im_cpm.cp_pepar, 0x00039620);
|
||
|
setbits32(immap->im_cpm.cp_pedir, 0x00039620);
|
||
|
setbits32(immap->im_cpm.cp_peso, 0x00031000);
|
||
|
clrbits32(immap->im_cpm.cp_peso, 0x00008620);
|
||
|
|
||
|
setbits32(immap->im_cpm.cp_cptr, 0x00000080);
|
||
|
clrbits32(immap->im_cpm.cp_cptr, 0x00000028);
|
||
|
|
||
|
clrbits16(immap->im_ioport.iop_pcpar, 0x0200);
|
||
|
clrbits16(immap->im_ioport.iop_pcdir, 0x0200);
|
||
|
clrbits16(immap->im_ioport.iop_pcso, 0x0200);
|
||
|
setbits16(immap->im_ioport.iop_pcint, 0x0200);
|
||
|
|
||
|
/* fill up */
|
||
|
fec1_info.sys_clk = bd->bi_intfreq;
|
||
|
fec2_info.sys_clk = bd->bi_intfreq;
|
||
|
|
||
|
s = __fw_getenv("ethaddr");
|
||
|
if (s != NULL) {
|
||
|
for (i = 0; i < 6; i++) {
|
||
|
fec1_info.macaddr[i] = simple_strtoul(s, &e, 16);
|
||
|
if (*e)
|
||
|
s = e + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
s = __fw_getenv("eth1addr");
|
||
|
if (s != NULL) {
|
||
|
for (i = 0; i < 6; i++) {
|
||
|
fec2_info.macaddr[i] = simple_strtoul(s, &e, 16);
|
||
|
if (*e)
|
||
|
s = e + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fec_8xx_init_one(&fec1_info, &fec1_dev);
|
||
|
fec_8xx_init_one(&fec2_info, &fec2_dev);
|
||
|
|
||
|
return fec1_dev != NULL && fec2_dev != NULL ? 0 : -1;
|
||
|
}
|
||
|
|
||
|
void fec_8xx_platform_cleanup(void)
|
||
|
{
|
||
|
if (fec2_dev != NULL)
|
||
|
fec_8xx_cleanup_one(fec2_dev);
|
||
|
|
||
|
if (fec1_dev != NULL)
|
||
|
fec_8xx_cleanup_one(fec1_dev);
|
||
|
}
|