绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
【原】Linux-千兆网卡驱动实现机制浅析(3)
2020-06-15 16:47:28
5.  发送与接收数据包
数据包的发送:
 图5-1 发送数据包的结构图及相互关系
      根据发送队列数num_tx_queues建立相应的发送缓冲区结构e1000_tx_ring,在该结构中有描述该区域的指向e1000_tx_desc结构的desc,该缓冲区指向的dma总线地址,用于接收硬件传送来的用e1000_buffer结构描述的缓冲块数组buffer_info[],另外的几个参数则主要用于描述这些缓冲块,其中count表示缓冲块的个数,next_to_use和next_to_clean主要描述缓冲块的使用状态,如已经接收接收了数据的位置及准备接收的位置,当有新的数据包要发送时,首先由上层协议调用e1000_xmit_frame(),在该函数中接着调用e1000_tx_queue()根据相应的参数找到缓冲块存放,缓冲块的初始化则由函数e1000_tx_map()实现。buffer_info指向的环形缓冲块区域主要用来接收总线地址映射来的数据包,所有的缓冲块用next_to_match连接成一个环,每个缓冲块用结构体e1000_buffer表示,在该结构中,skb存放数据包的内容,dma表示该数据包所在的总线地址。此处使用函数pci_map_single()进行流式映射,的映射方向为PCI_DMA_TODEVICE,控制总线会把虚拟地址空间所指内容映射到总线地址,然后将该内容由网卡传送出去。发送数据包的相关结构图及相互关系如图5-1所示。
     e1000_tx_ring结构中的desc所指向的buffer_addr记录了每次发送的缓冲块所映射的总线地址,即buffer_addr记录的是总线地址。而desc本是一个虚拟地址,该虚拟地址是通过pci_alloc_consistent()映射的发送缓冲区的地址,其与DMA缓冲区中的一段总线地址相对应,该总线地址由e1000_tx_ring结构中的dma成员保存,这种映射关系在对开启网卡时就实现了,其与在发送数据包时映射的总线地址有区别,后者是在发送时动态进行的。
数据包的接收
         图5-2 接收数据包的结构图及相互关系
      根据接收队列数num_rx_queues建立相应的接收缓冲区结构e1000_rx_ring,在该结构中有描述该区域的指向e1000_rx_desc结构的desc,该缓冲区指向的dma总线地址,用于接收硬件传送来的用e1000_buffer结构描述的缓冲块数组buffer_info[],另外的几个参数则主要用于描述这些缓冲块,其中count表示缓冲块的个数,next_to_use和next_to_clean主要描述缓冲块的使用状态,如已经接收接收了数据的位置及准备接收的位置,当有新的数据包要到来时,则根据这两个参数找到相应的区域存放。对于需要分片接收的数据包则利用了ps_page和ps_page_dma来实现,参数cpu指定了该接收缓冲队列所属的处理器。
总线地址与要发送的虚拟地址间的映射方向为PCI_DMA_FROMDEVICE,控制总线会把总线地址的内容映射到虚拟地址空间内。接收数据包的相关结构图及相互关系如图5-2所示。
     当有新的数据包到达时,首先触动中断处理函数e1000_intr(),在函数中会为新来的数据包在缓冲块数组buffer_info中找到一个新的缓冲块位置,并完成e1000_buffer结构的赋值。数据包的接收其实就是将总线地址指向的内容拷贝到skb中,然后根据skb中的协议将其传给相应的上层协议的接收函数。

文章来源CU社区:【原】Linux-千兆网卡驱动实现机制浅析



分享好友

分享这个小栈给你的朋友们,一起进步吧。

内核源码
创建时间:2020-05-18 13:36:55
内核源码精华帖内容汇总
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

技术专家

查看更多
  • 飘絮絮絮丶
    专家
戳我,来吐槽~