LAN9221采用NAPI方式读取网卡缓存内数据

主机收大量网络数据时,网卡中断触发驱动程序接收数据,驱动程序被触发后调用轮询函数,在轮询函数里接收固定个数据包后,固定个数据为budget,一般是轮询注册函数netif_napi_add的第三个参数weight,如果数据还没接收完毕,则中断再次被触发(中断标志位没有被清除),继续轮询接收数据,直到数据被接收完毕,则在轮询函数里将中断标志位清楚,关闭轮询函数,重新使能中断接收下一组数据。

NAPI的好处就是既避免了在接收大量数据时频繁的中断,又不必因为轮询而耗费大量CPU资源,结合了中断和轮询的优点。

static int smsc911x_poll(struct napi_struct *napi, int budget)

  1. struct smsc911x_data *pdata =  
  2.   container_of(napi, struct smsc911x_data, napi);  
  3.  struct net_device *dev = pdata->dev; 
  1. while (npackets < budget) { /*不管数据是否接收完毕,每个中断最多轮询budget=16次, 因为中断被清零,如果还有数据则会再次触发中断*/ 
  2. smsc911x_reg_write(pdata, INT_STS, INT_STS_RSFL_); /*清数据接收中断*/
  3. smsc911x_reg_write(pdata, INT_EN, temp); /*数据接收完,关闭轮询,重新使能数据接收中断*/

      pktwords = (pktlength + NET_IP_ALIGN + 3) >> 2; /*获取数据包长度,并计算按字读取的长度,左移2相当于除以4,结果为字的个数*/

      skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN);  /*mac头是14个字节,而紧接着的IP头要求16字节对齐,所以多申请2个字节,保证IP16字节对齐*/  

 

  1. skb_reserve(skb, NET_IP_ALIGN); /*调节data的位置,使IP按16字节对齐*/  
  2.   skb_put(skb, pktlength - 4); /*将tail指针往后拉,接着就把数据拷贝到skb缓存中*/
  3. netif_receive_skb(skb); /*将skb发往上一层*/ 

 

posted @ 2015-05-19 10:49  polo2013  阅读(457)  评论(0)    收藏  举报