分类: 嵌入式
2009-07-30 17:29:42
由于sbc2410x开发板支持的是cs8900,而EdukitIV使用的是DM9000AEP网卡芯片,所以要如果要实现对与DM9000AEP的支持需要对U-boot的代码做一些适当的修改。
/*
* Hardware drivers
*/
//#define CONFIG_DRIVER_CS8900 0 /* we have a CS8900 on-board */
//#define CS8900_BASE 0x20100000
//#define CS8900_BUS16 1 /* the Linux driver does accesses as shorts */
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x20000000
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA 0x20100000
#define CONFIG_DM9000_USE_16BIT
#define CONFIG_DM9000_DEBUG
......
/*修改启动参数,使能通过tftp引导内核,使用yaffs文件系统*/
#define CONFIG_BOOTDELAY 3
#define CONFIG_BOOTARGS "console=ttySAC1 root=/dev/mtdblock/3 rootfstype=yaffs"
/*使用yaffs文件系统*/
#define CONFIG_ETHADDR 08:00:3e:26:
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR 192.168.2.201
/*设置开发板ip地址*/
#define CONFIG_SERVERIP 192.168.2.34
/*设置tftp服务器ip地址*/
/*#define CONFIG_BOOTFILE "uImage" */
#define CONFIG_BOOTCOMMAND "tftp 30800000 uImage\; bootm"
在EdukitIV中,有两个网卡,分别位于核心板和主板上。
其中:
主板网卡的I/O地址为:0x20000000,data地址为:0x20000000。
核心板网卡的I/O地址为:0x10000000,data地址为:0x10000002。
......
#ifdef CONFIG_DRIVER_CS8900
extern void cs8900_get_enetaddr (uchar * addr);
#endif
#ifdef CONFIG_DRIVER_DM9000
extern int eth_init(bd_t *bd);
#endif
......
#ifdef CONFIG_DRIVER_CS8900
cs8900_get_enetaddr (gd->bd->bi_enetaddr);
#endif
#ifdef CONFIG_DRIVER_DM9000
eth_init(gd->bd);
#endif
......
......
/* For module input parameter */
//static int media_mode = DM9000_AUTO;
static int media_mode = DM9000_100MFD; /*use full duplex mode */
static u8 nfloor = 0;
......
void eth_halt(void);
void eth_halt_true(void);
static int dm9000_probe(void);
......
#ifdef CONFIG_DM9000_DEBUG
static void
dump_regs(void)
{
DM9000_DBG("\n");
DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(0));
DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(1));
DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(2));
DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(3));
DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4));
DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(5));
DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(6));
// DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(ISR));
DM9000_DBG("\n");
}
#endif /* */
......
int
eth_init(bd_t * bd)
{
int i, oft, lnk;
DM9000_DBG("eth_init()\n");
// eth_halt_true();
/* RESET device */
dm9000_reset();
dm9000_probe();
/* NIC Type: FASTETHER, HOMERUN, LONGRUN */
// identify_nic();
/* GPIO0 on pre-activate PHY */
DM9000_iow(DM9000_GPR, 0x00); /*REG_
/* copy from set_PHY_mode, do not set phy mode */
DM9000_iow(DM9000_GPCR, 0x01); /* Let GPIO0 output */
DM9000_iow(DM9000_GPR, 0x00); /* Enable PHY */
/* Set PHY */
// set_PHY_mode();
/* Program operating register */
// DM9000_iow(DM9000_NCR, 0x0); /* only intern phy supported by now */
DM9000_iow(DM9000_TCR, 0); /* TX Polling clear */
DM9000_iow(DM9000_BPTR, 0x
DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); /* Flow Control : High/Low Water */
DM9000_iow(DM9000_FCR, 0x0); /* SH FIXME: This looks strange! Flow Control */
DM9000_iow(DM9000_SMCR, 0); /* Special Mode */
DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* clear TX status */
DM9000_iow(DM9000_ISR, 0x
/* Set Node address */
// for (i = 0; i < 6; i++)
// ((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);
if (is_zero_ether_addr(bd->bi_enetaddr) ||
is_multicast_ether_addr(bd->bi_enetaddr)) {
......
#if 0
i = 0;
while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */
udelay(1000);
i++;
if (i == 10000) {
printf("could not establish link\n");
return 0;
}
}
#endif
#if 0
/* see what we've got */
lnk = phy_read(17) >> 12;
printf("operating at ");
switch (lnk) {
case 1:
printf("
break;
case 2:
printf("
break;
case 4:
printf("
break;
case 8:
printf("
break;
default:
printf("unknown: %d ", lnk);
break;
}
printf("mode\n");
#endif
printf("operating at
return 0;
}
......
/*
Stop the interface.
The interface is stopped when it is brought.
*/
void eth_halt(void){}
void
eth_halt_true(void)
{
DM9000_DBG("eth_halt\n");
/* RESET devie */
phy_write(0, 0x8000); /* PHY RESET */
DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */
DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */
DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */
}
......
/* Check packet ready or not */
DM9000_ior(DM9000_MRRH);
DM9000_ior(DM9000_MRRL); //must add this two read
DM9000_ior(DM9000_MRCMDX); /* Dummy read */
rxbyte = DM9000_inb(DM9000_DATA); /* Got most updated data */
/* Status check: this byte must be 0 or 1 */
if (rxbyte > 1) {
DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */
DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */
DM9000_DBG("rx status check: %d\n", rxbyte);
return;
}
......
/*
Read a word from phyxcer
*/
static u16
phy_read(int reg)
{
u16 val;
/* Fill the phyxcer register into REG_
DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
DM9000_iow(DM9000_EPCR, 0xc); /* Issue phyxcer read command */
// udelay(100); /* Wait read complete */ //weiyan
udelay(1000); /* Wait read complete */
DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer read command */
val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);
/* The read data keeps on REG_0D & REG_0E */
DM9000_DBG("phy_read(%d): %d\n", reg, val);
return val;
}
/*
Write a word to phyxcer
*/
static void
phy_write(int reg, u16 value)
{
/* Fill the phyxcer register into REG_
DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
/* Fill the written data into REG_0D & REG_0E */
DM9000_iow(DM9000_EPDRL, (value & 0xff));
DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));
DM9000_iow(DM9000_EPCR, 0xa); /* Issue phyxcer write command */
// udelay(500); /* Wait write complete */ /
udelay(1000); /* Wait write complete */
DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer write command */
DM9000_DBG("phy_write(reg:%d, value:%d)\n", reg, value);
}
#endif /* CONFIG_DRIVER_DM9000 */