Chinaunix首页 | 论坛 | 博客
  • 博客访问: 90586
  • 博文数量: 19
  • 博客积分: 760
  • 博客等级: 军士长
  • 技术积分: 260
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-30 16:30
文章存档

2011年(1)

2009年(18)

我的朋友

分类: 嵌入式

2009-07-30 17:29:42

1        修改U-boot文件,以支持DM9000AEP

由于sbc2410x开发板支持的是cs8900,而EdukitIV使用的是DM9000AEP网卡芯片,所以要如果要实现对与DM9000AEP的支持需要对U-boot的代码做一些适当的修改。

3.1        修改include/configs/edukit2410.h文件

/*

 * 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:0a:5b

#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地址为:0x20000000data地址为:0x20000000

        核心板网卡的I/O地址为:0x10000000data地址为:0x10000002

3.2        修改lib_arm/board.c文件

......

#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

 

......

 

3.3        修改drivers\net\dm9000x.c文件

......

/* 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_1F bit0 activate phyxcer */

 

        /* 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, 0x3f);  /* Less 3Kb, 200us */

        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, 0x0f);   /* Clear interrupt status */

 

        /* 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("10M half duplex ");

                break;

        case 2:

                printf("10M full duplex ");

                break;

        case 4:

                printf("100M half duplex ");

                break;

        case 8:

                printf("100M full duplex ");

                break;

        default:

                printf("unknown: %d ", lnk);

                break;

        }

        printf("mode\n");

#endif

       printf("operating at 100M full duplex mode\n");

        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_0C */

        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_0C */

        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 */

阅读(1833) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~