<1>控制位(empty flag/own bit):descriptor empty/owned by DMA or not,该位域描述的是descriptor对CPU/DMA的有效性。empty_flag和own_bit是站在不同角度对控制状态的同功描述,empty表示descriptor上尚无数据(包)。对于RX,descriptor empty(owned by DMA)表示亟待DMA搬运数据进来挂到该descriptor的DMA缓存上;对于TX,descriptor empty(not owned by DMA)表示亟待CPU往descriptor上挂载待发送的数据包。下文主要基于DMAown_bit分析控制位,读者可自行做等价转换。
<2>数据包地址(data buffer address):该指针指向DMA传输时的源端或目的端内存区,有的地方称之为DMA缓存。DMA缓存是数据包的终极归宿,即cluster的数据区(mBlk::mBlkHdr.mData inVxWorks, sk_buff.data in Linux)。
<3>数据包长度(packet length):rx/tx数据包的有效长度。
<4>环尾标(wrap bit):wrap bit of the last descriptor,该位域标记最后一个描述符,用于判断溢出(rx overflow)。站在“环”的角度分析,也可以理解为按照数组索引的回环点。
DMA描述符数组hw_desc[]的地址是DMA映射的虚拟地址,它是描述符环的基地址,需要配置到SoC芯片的相关DMA寄存器中,例如AR9331Datasheet中的DMARXDESCR(Pointer to Rx Descrpitor)和DMATXDESCR_Q0(Descriptor Address for Queue 0 Tx)。很显然,这个数组需要分配或转换到非缓存的区段(例如MIPS中的kseg1段)。但每个描述符所指向的DMA缓存(desc buffer)通常是分配在缓存的区段(例如MIPS中的kseg0段),使用cache主要是出于访存性能考虑。
软件描述符(s/w descriptor)
硬件描述符(h/w descriptor)更多的关注分组(例如以太网帧)的传输,而缺乏对数据包或数据链的软件组织层次关怀。数据包在网络协议栈各层之间流动时,软件层面需要维系完整的数据链信息,包括横向的包内分片(fragment)和纵向的多包链化(chain),以便进行链接跟踪(conntrack)。以网卡为例,NIC的ISR中首先会创建一个buf(mBlk/mbuf in VxWorksor or sk_buff in Linux),分组的内容将被封装到这个buf结构体中,进而调用相应函数(END_RCV_RTN_CALL(END_OBJ*,M_BLK_ID)in VxWorks or netif_rx(sk_buff*)in Linux)将数据包推送到网络子系统(TCP/IP协议栈)中的高层代码中。
DMA描述符数组(DMA Descriptor Array/Ring/Chain)是一个形如unsigned long* hw_desc[DESC_NUM]的指针数组,每个指针(hw_desc)指向一个描述符。这个描述符是由硬件定义的,其数据结构一般由datasheet或sdk定义。
硬件描述符(h/w descriptor)
硬件描述符通常包含以下五个部分:
<1>控制位(empty flag/own bit):descriptor empty/owned by DMA or not,该位域描述的是descriptor对CPU/DMA的有效性。empty_flag和own_bit是站在不同角度对控制状态的同功描述,empty表示descriptor上尚无数据(包)。对于RX,descriptor empty(owned by DMA)表示亟待DMA搬运数据进来挂到该descriptor的DMA缓存上;对于TX,descriptor empty(not owned by DMA)表示亟待CPU往descriptor上挂载待发送的数据包。下文主要基于DMAown_bit分析控制位,读者可自行做等价转换。
<2>数据包地址(data buffer address):该指针指向DMA传输时的源端或目的端内存区,有的地方称之为DMA缓存。DMA缓存是数据包的终极归宿,即cluster的数据区(mBlk::mBlkHdr.mData inVxWorks, sk_buff.data in Linux)。
<3>数据包长度(packet length):rx/tx数据包的有效长度。
<4>环尾标(wrap bit):wrap bit of the last descriptor,该位域标记最后一个描述符,用于判断溢出(rx overflow)。站在“环”的角度分析,也可以理解为按照数组索引的回环点。
<5>环链结(next pointer):该指针指向下一个描述符。尽管分配的DMA描述符数组已经是线性存储,但是硬件总是习惯按照地址来查找下一个描述符。软件则更习惯在RX ISR中使用数组索引来遍历描述符环上待收割(reap)的数据包。
有的地方称之为BD(Buffer Descriptor),由于是hardware specific,故开发者一般无需修改h/w descriptor数据结构。
DMA描述符数组hw_desc[]的地址是DMA映射的虚拟地址,它是描述符环的基地址,需要配置到SoC芯片的相关DMA寄存器中,例如AR9331Datasheet中的DMARXDESCR(Pointer to Rx Descrpitor)和DMATXDESCR_Q0(Descriptor Address for Queue 0 Tx)。很显然,这个数组需要分配或转换到非缓存的区段(例如MIPS中的kseg1段)。但每个描述符所指向的DMA缓存(desc buffer)通常是分配在缓存的区段(例如MIPS中的kseg0段),使用cache主要是出于访存性能考虑。
软件描述符(s/w descriptor)
硬件描述符(h/w descriptor)更多的关注分组(例如以太网帧)的传输,而缺乏对数据包或数据链的软件组织层次关怀。数据包在网络协议栈各层之间流动时,软件层面需要维系完整的数据链信息,包括横向的包内分片(fragment)和纵向的多包链化(chain),以便进行链接跟踪(conntrack)。以网卡为例,NIC的ISR中首先会创建一个buf(mBlk/mbuf in VxWorksor or sk_buff in Linux),分组的内容将被封装到这个buf结构体中,进而调用相应函数(END_RCV_RTN_CALL(END_OBJ*,M_BLK_ID)in VxWorks or netif_rx(sk_buff*)in Linux)将数据包推送到网络子系统(TCP/IP协议栈)中的高层代码中。
数据包以mBlk或sk_buff的形式在协议栈之间流动,因此在软件层面,往往根据信息组织的完整性需要对h/w descriptor进行适当地扩展。通常,s/w descriptor是h/w descriptor的Container。除了数据包的组织扩展以外,也可以根据需要增加一些描述信息和维护信息,例如可添加用于跟踪tx timeout的timestamp。
评分
查看全部评分