static int net_open(struct net_device *dev)
{
/* 注册中断 */
for (i = 2; i < CS8920_NO_INTS; i++) {
if ((1 << i) & lp->irq_map) {
if (request_irq(i, net_interrupt, 0, dev->name, dev) == 0) {
dev->irq = i;
write_irq(dev, lp->chip_type, i);
/* 这里只会申请了一个中断号,若申请成功则退出循环 */
break;
}
}
}
/* 如果允许DMA工作方式,首先为DMA发送分配数据缓冲区页面,如果分配不成功,则释放已申请的中断 */
#if ALLOW_DMAif (lp->use_dma) {
if (lp->isa_config & ANY_ISA_DMA) {
unsigned long flags;
lp->dma_buff = (unsigned char *)__get_dma_pages(GFP_KERNEL,
get_order(lp->dmasize * 1024));
if (!lp->dma_buff) {
printk(KERN_ERR "%s: cannot get %dK memory for DMA\n", dev->name, lp->dmasize);
goto release_irq;
}
/* 为设备申请DMA通道,如果申请成功则将DMA通道号写入DMA通道寄存器 */
memset(lp->dma_buff, 0, lp->dmasize * 1024);/* Why? */
if (request_dma(dev->dma, dev->name)) {
printk(KERN_ERR "%s: cannot get dma channel %d\n", dev->name, dev->dma);
goto release_irq;
}
write_dma(dev, lp->chip_type, dev->dma);
/* 设置DMA的配置信息,比如DMA发送的缓冲区起始地址,发送方式,一次DMA发送字节数等 */
lp->rx_dma_ptr = lp->dma_buff;
lp->end_dma_buff = lp->dma_buff + lp->dmasize*1024;
spin_lock_irqsave(&lp->lock, flags);
disable_dma(dev->dma);
clear_dma_ff(dev->dma);
set_dma_mode(dev->dma, DMA_RX_MODE); /* auto_init as well */
set_dma_addr(dev->dma, isa_virt_to_bus(lp->dma_buff));
set_dma_count(dev->dma, lp->dmasize*1024);
enable_dma(dev->dma);
spin_unlock_irqrestore(&lp->lock, flags);
}
}
#endif/* ALLOW_DMA */
/* set the Ethernet address */
for (i=0; i < ETH_ALEN/2; i++)
writereg(dev, PP_IA+i*2, dev->dev_addr[i*2] | (dev->dev_addr[i*2+1] << 8));
/* while we're testing the interface, leave interrupts disabled */
writereg(dev, PP_BusCTL, MEMORY_ON);
/* Turn on both receive and transmit operations */
writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) | SERIAL_RX_ON | SERIAL_TX_ON);
/* Receive only error free packets addressed to this card */
lp->rx_mode = 0;
writereg(dev, PP_RxCTL, DEF_RX_ACCEPT);
lp->curr_rx_cfg = RX_OK_ENBL | RX_CRC_ERROR_ENBL;
if (lp->isa_config & STREAM_TRANSFER)
lp->curr_rx_cfg |= RX_STREAM_ENBL;
#if ALLOW_DMAset_dma_cfg(dev);
#endif/* 配置接收寄存器 */
writereg(dev, PP_RxCFG, lp->curr_rx_cfg);
/* 配置发送寄存器 */
writereg(dev, PP_TxCFG, TX_LOST_CRS_ENBL | TX_SQE_ERROR_ENBL | TX_OK_ENBL |
TX_LATE_COL_ENBL | TX_JBR_ENBL | TX_ANY_COL_ENBL | TX_16_COL_ENBL);
/* 配置缓冲区寄存器 */
writereg(dev, PP_BufCFG, READY_FOR_TX_ENBL | RX_MISS_COUNT_OVRFLOW_ENBL |
#if ALLOW_DMAdma_bufcfg(dev) |
#endifTX_COL_COUNT_OVRFLOW_ENBL | TX_UNDERRUN_ENBL);
/* now that we've got our act together, enable everything */
writereg(dev, PP_BusCTL, ENABLE_IRQ
| (dev->mem_start?MEMORY_ON : 0) /* turn memory on */
#if ALLOW_DMA | dma_busctl(dev)
#endif );
/* 启动设备发送队列 */
netif_start_queue(dev);
if (net_debug > 1)
printk("cs89x0: net_open() succeeded\n");
return 0;
bad_out:
return ret;
}