现在我们来看dm9000a的open函数:
/*
* Open the interface.
* The interface is opened whenever "ifconfig" actives it.
当使用ifconfig激活该网络接口时调用
*/
static int
dm9000_open(struct net_device *dev)
{
board_info_t *db = dev->priv;
unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
if (netif_msg_ifup(db))
dev_dbg(db->dev, "enabling %s\n", dev->name);
/* If there is no IRQ type specified, default to something that
* may work, and tell the user that this is a problem */
if (irqflags == IRQF_TRIGGER_NONE)
dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
irqflags |= IRQF_SHARED;
/*申请中断资源,注册中断函数*/
if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
return -EAGAIN;
/*复位DM9000芯片*/
dm9000_reset(db);
/*初始化DM9000的寄存器*/
dm9000_init_dm9000(dev);
/* Init driver variable */
db->dbug_cnt = 0;
/*检查链路载波状况*/
mii_check_media(&db->mii, netif_msg_link(db), 1);
/*启动发送队列*/
netif_start_queue(dev);
/*之前在probe函数中调用 INIT_DELAYED_WORK初始化了工作队列,
并关联了一个操作函数dm9000_poll_work(),此时运行
dm9000_schedule_poll来调用这个函数*/
dm9000_schedule_poll(db);
return 0;
}
static void
dm9000_reset(board_info_t * db)
{
dev_dbg(db->dev, "resetting device\n");
/* RESET device *//*指定DM9000当前的命令寄存器是NCR*/
writeb(DM9000_NCR, db->io_addr);
udelay(200);
/*向NCR寄存器写入复位标志,芯片复位*/
writeb(NCR_RST, db->io_data);
udelay(200);
}
/*
* Initilize dm9000 board
配置DM9000芯片内部寄存器,使其能工作
*/
static void
dm9000_init_dm9000(struct net_device *dev)
{
board_info_t *db = dev->priv;
unsigned int imr;
dm9000_dbg(db, 1, "entering %s\n", __func__);
/* I/O mode
检查当前芯片的总线带宽8bit,16bit,32bit
芯片的总线带宽由硬件走线决定*/
db->io_mode = ior(db, DM9000_ISR) >> 6; /* ISR bit7:6 keeps I/O mode */
/* GPIO0 on pre-activate PHY
启动PHY*/
iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */
iow(db, DM9000_GPCR, GPCR_GEP_CNTL); /* Let GPIO0 output */
iow(db, DM9000_GPR, 0); /* Enable PHY */
if (db->flags & DM9000_PLATF_EXT_PHY)
iow(db, DM9000_NCR, NCR_EXT_PHY);
/* Program operating register */
/*清除发送配置选项*/
iow(db, DM9000_TCR, 0); /* TX Polling clear */
iow(db, DM9000_BPTR, 0x3f); /* Less 3Kb, 200us */
iow(db, DM9000_FCR, 0xff); /* Flow Control */
iow(db, DM9000_SMCR, 0); /* Special Mode */
/* clear TX status */
/*清除发送标志位*/
iow(db, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
/*清除中断标志位*/
iow(db, DM9000_ISR, ISR_CLR_STATUS); /* Clear interrupt status */
/* Set address filter table */
dm9000_hash_table(dev);
imr = IMR_PAR | IMR_PTM | IMR_PRM;
if (db->type != TYPE_DM9000E)
imr |= IMR_LNKCHNG;
db->imr_all = imr;
/* Enable TX/RX interrupt mask
使用发送,接收中断。SRAM缓冲区指针自动回0*/
iow(db, DM9000_IMR, imr);
/* Init Driver variable */
db->tx_pkt_cnt = 0;
db->queue_pkt_len = 0;
dev->trans_start = 0;
}