linux网络设备驱动程序,Linux协议栈--网络设备驱动程序

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值