`
tomhibolu
  • 浏览: 1375772 次
文章分类
社区版块
存档分类
最新评论

Linux驱动修炼之道-DM9000A网卡驱动框架源码分析(下)

 
阅读更多

努力成为linux kernel hacker的人李万鹏原创作品,为梦而战。转载请标明出处

http://blog.csdn.net/woshixingaaa/archive/2011/06/18/6552911.aspx

这里主要讨论中断处理和数据的发送和接收,这个也是网卡驱动最重要的部分了。

中断处理函数:
发生中断的情况有3中:1)接收到数据2)发送完数据3)链路状态改变

下面说一下DM9000A中的存储部分,DM9000A内部有一个4K Dword SRAM,其中3KB是作为发送,16KB作为接收,如下图所示。其中0x0000~0x0BFF是传说中的TX buffer(TX buffer中只能存放两个包),0x0C00~0x3FFF是RX buffer。因此在写内存操作时,当IMR的第7位被设置,如果到达了地址的结尾比如到了3KB,则回卷到0。相似的方式,在读操作中,当IMR的第7位被设置如果到达了地址的结尾比如16K,则回卷到0x0C00。

那么传说中的发送函数又是哪个呢,在probe函数里进行了初始化函数指针操作。

可以看到当上层调用hard_start_xmit时,在我们的驱动程序中实际调用的是dm9000_start_xmit,下面来分析一dm9000_start_xmit的源码。

发送函数:

下面来看一下刚才提到的那个超时函数,发送超时函数:

这个函数首先停止了发送队列,然后复位dm9000,初始化dm9000,重新设置了时间戳,然后唤醒发送队列,通知网络子系统可再次传输数据包。

发送完成后的中断处理函数:

接收函数:
每接受到一个包,DM9000都会在包的前面加上4个字节,"01H",status与RSR(RX Status Register)的内容相同,"LENL"(数据包长度低位位),"LENH"(数据包长度高8位)。所以首先要读取这4个字节来确定数据包的状态,第一个字节"01H"表示接下来的是有效的数据包,"00H"表示没有数据包,若为其他值则表示网卡没有正确初始化,需要从新初始化。这4个字节封装在一起:

清晰一些如下图:

接收函数如下:

如下图链路层包的传输过程:

在netif_rx中会调用napi_schedule,然后该函数又会去调用__napi_schedule()。在函数__napi_schedule()中会去调用设备的poll函数,它是设备自己注册的。在设备的poll函数中,会去调用netif_receive_skb函数,在该函数中有下面一条语句pt_prev->func,此处的func为一个函数指针,在之前的注册中设置为ip_rcv。因此,就完成了从链路层上传到网络层的这一个过程了。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics