DM9000C U-BOOT驱动分析(二)

初始化DM9000C流程

static int dm9000_init(struct eth_device *dev, bd_t *bd)

{

int i, oft, lnk;

u8 io_mode;

struct board_info *db = &dm9000_info;


DM9000_DBG("%s\n", __func__);


一部分初始化流程和reset流程相同,详见以下分析

dm9000_reset();


没有检测到DM9000C,返回

if (dm9000_probe() < 0)

return -1;


自动侦测IO bus模式,8bit 或者 16bit

io_mode = DM9000_ior(DM9000_ISR) >> 6;


8bit 与 16bit模式IO读写接口不同

switch (io_mode) {

case 0x0:  /* 16-bit mode */

printf("DM9000: running in 16 bit mode\n");

db->outblk    = dm9000_outblk_16bit;

db->inblk     = dm9000_inblk_16bit;

db->rx_status = dm9000_rx_status_16bit;

break;

case 0x01:  /* 32-bit mode */

printf("DM9000: running in 32 bit mode\n");

db->outblk    = dm9000_outblk_32bit;

db->inblk     = dm9000_inblk_32bit;

db->rx_status = dm9000_rx_status_32bit;

break;

case 0x02: /* 8 bit mode */

printf("DM9000: running in 8 bit mode\n");

db->outblk    = dm9000_outblk_8bit;

db->inblk     = dm9000_inblk_8bit;

db->rx_status = dm9000_rx_status_8bit;

break;

default:

/* Assume 8 bit mode, will probably not work anyway */

printf("DM9000: Undefined IO-mode:0x%x\n", io_mode);

db->outblk    = dm9000_outblk_8bit;

db->inblk     = dm9000_inblk_8bit;

db->rx_status = dm9000_rx_status_8bit;

break;

}


初始化NCR寄存器值0

DM9000_iow(DM9000_NCR, 0x0);

发送寄存器位清零

DM9000_iow(DM9000_TCR, 0);

/* Less 3Kb, 200us */

DM9000_iow(DM9000_BPTR, BPTR_BPHW(3) | BPTR_JPT_600US);

流控设置

DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));

/* SH FIXME: This looks strange! Flow Control */

DM9000_iow(DM9000_FCR, 0x0);

/* Special Mode */

DM9000_iow(DM9000_SMCR, 0);

清零发送状态值

DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);

清除中断寄存器标志位

DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);


printf("MAC: %pM\n", dev->enetaddr);


设置MAC地址

for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)

DM9000_iow(oft, dev->enetaddr[i]);

for (i = 0, oft = 0x16; i < 8; i++, oft++)

DM9000_iow(oft, 0xff);


确认MAC地址设置正确

for (i = 0, oft = 0x10; i < 6; i++, oft++)

DM9000_DBG("%02x:", DM9000_ior(oft));

DM9000_DBG("\n");


激活DM9000C,开始接收数据包

DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);

使能中断状态位

DM9000_iow(DM9000_IMR, IMR_PAR);


i = 0;

while (!(dm9000_phy_read(1) & 0x20)) {/* autonegation complete bit */

udelay(1000);

i++;

if (i == 10000) {

printf("could not establish link\n");

return 0;

}

}


检测link状态

lnk = dm9000_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");

return 0;

}



static void

dm9000_reset(void)

{

DM9000_DBG("resetting DM9000\n");


/* Reset DM9000,

  see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */


所有GPIO确认为输出状态

DM9000_iow(DM9000_GPCR, GPCR_GPIO0_OUT);

内部PHY上电激活

DM9000_iow(DM9000_GPR, 0);

软件复位

DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST));


do {

DM9000_DBG("resetting the DM9000, 1st reset\n");

udelay(25); /* Wait at least 20 us */

} while (DM9000_ior(DM9000_NCR) & 1);


DM9000_iow(DM9000_NCR, 0);

DM9000_iow(DM9000_NCR, (NCR_LBK_INT_MAC | NCR_RST)); /* Issue a second reset */


do {

DM9000_DBG("resetting the DM9000, 2nd reset\n");

udelay(25); /* Wait at least 20 us */

} while (DM9000_ior(DM9000_NCR) & 1);


检查DM9000C  ID号是否正确

if ((DM9000_ior(DM9000_PIDL) != 0x0) ||

   (DM9000_ior(DM9000_PIDH) != 0x90))

printf("ERROR: resetting DM9000 -> not responding\n");

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值