现在我们来看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; }