LAN9221网卡驱动之二 NAPI接收
来源:互联网 发布:淘宝卖家如何退保证金 编辑:程序博客网 时间:2024/05/16 19:34
转载请注明出处:http://blog.csdn.net/qq405180763/article/details/8800391
LAN9221采用NAPI方式读取网卡缓存内数据。当接主机收大量网络数据时,网卡中断触发驱动程序接收数据,驱动程序被触发后调用轮询函数,在轮询函数里接收固定个数据包后,固定个数据为budget,一般是轮询注册函数netif_napi_add的第三个参数weight,如果数据还没接收完毕,则中断再次被触发(中断标志位没有被清除),继续轮询接收数据,知道数据被完全接收完毕,则在轮询函数里将中断标志位清楚,关闭轮询函数,重新使能中断接收下一组数据。NAPI的好处就是既避免了在接收大量数据时频繁的中断,又不必因为轮询而耗费大量CPU资源,结合了中断和轮询的优点。
static int smsc911x_poll(struct napi_struct *napi, int budget){ struct smsc911x_data *pdata = container_of(napi, struct smsc911x_data, napi); struct net_device *dev = pdata->dev; int npackets = 0; while (npackets < budget) { /*不管数据是否接收完毕,每个中断最多轮询budget=16次, 因为中断被清零,如果还有数据则会再次触发中断*/ unsigned int pktlength; unsigned int pktwords; struct sk_buff *skb; unsigned int rxstat = smsc911x_rx_get_rxstatus(pdata); if (!rxstat) { unsigned int temp; /* We processed all packets available. Tell NAPI it can * stop polling then re-enable rx interrupts */ smsc911x_reg_write(pdata, INT_STS, INT_STS_RSFL_); /*清数据接收中断*/ napi_complete(napi); temp = smsc911x_reg_read(pdata, INT_EN); temp |= INT_EN_RSFL_EN_; smsc911x_reg_write(pdata, INT_EN, temp); /*数据接收完,关闭轮询,从新使能数据接收中断*/ break; } /* Count packet for NAPI scheduling, even if it has an error. * Error packets still require cycles to discard */ npackets++; pktlength = ((rxstat & 0x3FFF0000) >> 16); pktwords = (pktlength + NET_IP_ALIGN + 3) >> 2; /*获取数据包长度,并计算按字读取的长度*/ smsc911x_rx_counterrors(dev, rxstat); if (unlikely(rxstat & RX_STS_ES_)) { SMSC_WARNING(RX_ERR, "Discarding packet with error bit set"); /* Packet has an error, discard it and continue with * the next */ smsc911x_rx_fastforward(pdata, pktwords); dev->stats.rx_dropped++; continue; } skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN); /*mac头是14个字节,而紧接着的IP头要求14字节对齐,所以多申请两个字节,保证IP16字节对齐*/ if (unlikely(!skb)) { SMSC_WARNING(RX_ERR, "Unable to allocate skb for rx packet"); /* Drop the packet and stop this polling iteration */ smsc911x_rx_fastforward(pdata, pktwords); dev->stats.rx_dropped++; break; } skb->data = skb->head; /*空头*/ skb_reset_tail_pointer(skb); /*空数据*/ /* Align IP on 16B boundary */ skb_reserve(skb, NET_IP_ALIGN); /*调节data的位置,使IP按16字节对齐*/ skb_put(skb, pktlength - 4); /*将tail指针往后拉,接着就把数据拷贝到skb缓存中*/ smsc911x_rx_readfifo(pdata, (unsigned int *)skb->head, pktwords);/*强制转换成unsigned int,每加一次跳四个字节*/ skb->protocol = eth_type_trans(skb, dev); /*使skb->mac_header指向mac协议头, skb->data后移14字节,剥离mac头*/ skb->ip_summed = CHECKSUM_NONE; netif_receive_skb(skb); /*将skb发往上一层*/ /* Update counters */ dev->stats.rx_packets++; dev->stats.rx_bytes += (pktlength - 4); } /* Return total received packets */ return npackets;}
- LAN9221网卡驱动之二 NAPI接收
- LAN9221网卡驱动之三 接收/发送完成中断
- LAN9221网卡驱动分析之一 发送数据
- Linux NAPI/非NAPI 网卡驱动部分
- linux napi网卡驱动原理
- 网卡驱动4-做一个与外界交互的虚拟网卡3(调用真实网卡接收数据以及napi使用)
- linux网卡驱动的NAPI技术分析
- Linux内核分析 - 网络[二]:网卡驱动接收报文
- Linux内核分析 - 网络[二]:网卡驱动接收报文
- Linux内核分析 - 网络[二]:网卡驱动接收报文
- Linux内核分析 - 网络[二]:网卡驱动接收报文
- e1000 网卡使用NAPI
- 网卡驱动(二)
- 数据报的接收过程详解---从网卡到L3层(非NAPI,即接收数据采用中断方式)
- 数据报的接收过程详解---从网卡到L3层(非NAPI,即接收数据采用中断方式)
- 网卡驱动的数据包发送接收
- linux网卡驱动开发二之结构体
- intel e1000 网卡 napi分析
- 读书笔记-Don't Make Me Think(Steve Krug)
- 一道腾讯实习笔试题
- 23种设计模式(2):工厂方法模式
- JSP之【include】指令
- 23种设计模式(3):抽象工厂模式
- LAN9221网卡驱动之二 NAPI接收
- VS2010自定义消息
- 2011年企业软件行业回顾和发展
- 《TCP/IP协议》第三章 IP:网际协议
- Qlikview+nPrinting
- C#常用控件操作大全
- 23种设计模式(4):建造者模式
- jQuery源码分析-extend函数
- QLineEdit输入检查 hasacceptableinput