stmmac 描述符(Descriptors)
stmmac的描述符有两个个模式,分别是ring模式和chain模式,根据特性的不同支持,描述符又有以下3个形式norm、Alternate 、 Enhanced。下面主要讲下ring模式下的Enhanced描述符结构,以及比较重要的位。stmmac的收发的描述符相同位的含义有些差别,所以我们分开分析下描述符的初始化
0.描述符几个关键要素
-
OWN,用来表示描述符的状态,相当于Intel网卡里的DD位
-
buf地址,指明网卡将收到的数据包放到哪里
-
状态信息
-
术语
OWN:当此位置位时,表明这个描述符是属于DMA的,DMA可以访问。在host设置好接收、发送描述符后把OWN置位,DMA会自动的把收到的描述符放到描述符指定的地址并把OWN复位,表示数据包以及放到host的内存了,此时host可以进行包处理。
ring:是指描述符在内存中的排布,ring模式所有的描述符都在连续的物理内存上
chain :是指描述符在内存中的排布,chain模式下描述符地址不再连续,下一个描述符的物理地址由描述符中的DES3指明
Receive Descriptor
接收描述符的结构如下图。如果没有开启extend status和timestamp则只需要关注DES0~DES3,此时描述符大小为16Byte
对于接收描述符的初始化以下步骤是必要的
- 申请一块内存连续内存内存地址要对齐到stmmac的bus wide,内存大小为N*32Byte。这块内存用来存放N个接收描述符。
- 获取这块内存起始地址的物理地址A。
- 将物理地址A写入到DMA的3号寄存器(Receive Descriptor List Address Register)
- 申请N块内存,并获得每块内存的起始物理地址,分别填入到每个描述符的RDES2,同时将这块内存的大小写入到描述符的RDES1[12:0]
- 把每个填写好RDES2和RDES1[12:0]描述符的OWN位置位
- 在填充最后一个描述符时还需要将RDES0的[8]置位,让网卡知道这是最后一个描述符了,网卡在处理完这个描述符后会自动跳转到第一个去
Transmit Descriptor
发送描述符的结构如下图
对于发送描述符的初始化只需要将OWN位复位即可,下面讲下要发包时对描述符的初始化
- 获取数据包起始地址的物理地址,将物理地址填入到TDES2,并将需要发送的数据大小写入到TDES1[12:0]
- 如果数据包大小小于8K则将TDES0[29]、TDES0[28]置位,这两位分别是LS(Last Segment)、FS(First Segment)
- 如果数据包大小大于8K则需要填写使用多个描述符,在最后一个将LS置位
- 填写完毕后把OWN位置位
- 向DMA的1号寄存器写入任意数,启动DMA的发送
注意
以上填入DES2的物理地址需要是32位的物理地址