82599网卡驱动rx descriptor结构体分析

82599 datasheet: 7.1.6  节    大概位于314页

对驱动的理解关键是对数据结构的理解。

The 82599 posts receive packets into data buffers in system memory.

The following controls are provided for the data buffers:

? The SRRCTL[n].BSIZEPACKET field defines the data buffer size. See section

Section 7.1.2for packet filtering by size.

? The SRRCTL.BSIZEHEADER field defines the size of the buffers allocated to headers

(advanced descriptors only).

Each queue is provided with a separate SRRCTL register.

Receive memory buffer addresses are word (2x byte) aligned (both data and headers).

每个queue都有单独的SRRCTL寄存器

n表示的是queue id

rx packet或者header buffer的内存地址必须两字节对齐,这样的话可以保证地址的最低位(LSB)为0.

结构体的声明如下:

/* Receive Descriptor - Advanced */

union ixgbe_adv_rx_desc {

struct {

__le64 pkt_addr; /* Packet
buffer address */

__le64 hdr_addr; /* Header
buffer address */

} read;

struct {

struct {

union {

__le32 data;

struct {

__le16 pkt_info; /*
RSS, Pkt type */

__le16 hdr_info; /*
Splithdr, hdrlen */

} hs_rss;

} lo_dword;

union {

__le32 rss; /*
RSS Hash */

struct {

__le16 ip_id; /*
IP id */

__le16 csum; /*
Packet Checksum */

} csum_ip;

} hi_dword;

} lower;

struct {

__le32 status_error; /*
ext status/error */

__le16 length; /*
Packet length */

__le16 vlan; /*
VLAN tag */

} upper;

} wb;  /* writeback */

};

根据datasheet来看这个union结构体,这个union包括两个struct,一个是

struct {

__le64 pkt_addr; /* Packet buffer address */

__le64 hdr_addr; /* Header buffer address */

} read;

这个struct对应的datasheet中的table 7-15:

       63                                                                                                                                1      0
 0                             Packet Buffer Address [63:1]     A0
 8                           Header Buffer Address [63:1]     DD

这个数据结构是在驱动中修改的。就两个64bit地址。这两个地址都是物理地址,当一个数据包接收完成时,驱动就将对应的存放当前数据包的dma ring buffer的物理地址写到这个数据结构中。

header buffer的物理地址的最低位被用来表示当前的buffer是否可用。

DD的意思是Descriptor Done。

驱动每次要接收数据包的时候就检查这个DD是不是1,如果是1, 那么这个描述符对应的packet buffer中就有一个新来的数据包,然后就取出来数据包,取完之后就设置为0,这样硬件下次就可以继续使用。如果检查发现DD为0,驱动会认为当前packet fifo为空,没有新的数据包了。直接就会返回。

网卡每次来了新的数据包,就检查当前这个buffer的DD位是否为0,如果为0那么表示当前buffer可以使用,就让DMA将数据包copy到这个buffer中,设置DD为1,这样驱动就可以根据DD 1读取这个新来的数据包了。如果硬件检查为1,那么硬件就认为fifo满了,可能直接就将这个包给丢弃掉了。

典型的生产者---消费者模型。

在驱动代码中并没有发现单独的代码来设置DD为0。这是因为结构体中的这两个物理地址必须2字节对齐,也就是说最低位一定是0.所以直接通过下面的地址写回就可以置0了,不需要再单独的设置一下。

rxdp->read.hdr_addr = dma_addr;

rxdp->read.pkt_addr = dma_addr;

下面接着分析union中的另一个结构体:

完整修订整理版请前往个人blog阅读:82599 advanced receive descriptor 详解

时间: 2025-01-15 11:50:32

82599网卡驱动rx descriptor结构体分析的相关文章

FFmpeg: AVPacket 结构体分析

AVPacket是FFmpeg中很重要的一个数据结构,它保存了解封装之后,解码之前的数据(注意:仍然是压缩后的数据)和关于这些数据的一些附加信息,如显示时间戳(pts).解码时间戳(dts).数据时长,所在媒体流的索引等.对于视频来说,AVPacket通常包含一个压缩的Frame,而音频(Audio)则有可能包含多个压缩的Frame.并且,一个Packet有可能是空的,不包含任何压缩数据,只含有side data(side data,容器提供的关于Packet的一些附加信息.例如,在编码结束的时

转 kobject结构体分析

转载自:http://blog.csdn.net/zhoujiaxq/article/details/7646050 未知作者,以及源地址 ,敬请谅解. kobject是组成设备device.驱动driver.总线bus.class的基本结构. 如果把前者看成基类,则后者均为它的派生产物. device.driver.bus.class构成了设备模型,而kobject内嵌于其中,将这些设备模型的部件组织起来,并形成了sysfs文件系统.kobject就是device.driver.bus.cla

AVPicture结构体分析

/** * Picture data structure. * * Up to four components can be stored into it, the last component is * alpha. */ typedef struct AVPicture { uint8_t *data[AV_NUM_DATA_POINTERS]; ///< pointers to the image data planes int linesize[AV_NUM_DATA_POINTERS]

FFMPEG结构体分析:AVFrame(解码后的数据)

https://blog.csdn.net/jxcr1984/article/details/52766524 本文转自: http://blog.csdn.net/leixiaohua1020/article/details/14214577 /*   *雷霄骅   *[email protected]   *中国传媒大学/数字电视技术   */   /**   * Audio Video Frame.   * New fields can be added to the end of AVF

Windows驱动开发-_DRIVER_OBJECT结构体

每个驱动程序会有唯一的驱动对象与之对应,并且这个驱动对象是在驱动加载的时候,被内核中的对象管理程序所创建的,内核对一个驱动只加载一个实例,是由内核中的I/O管理器负责加载的,驱动程序需要在DriverEntry中初始化该驱动对象. _DRIVER_OBJECT结构体源码 typedef struct _DRIVER_OBJECT { CSHORT Type; CSHORT Size; //每个驱动程序有一个或多个设备对象,每个设备对象都有一个指针指向下一个设备对象,最后一个设备对象指向空.此处是

Windows驱动开发-Device结构体

每个驱动程序会创建一个或多个设备对象,每个设备对象都会有一个指针指向下一个设备对象 Device结构体源码 typedef struct DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT) _DEVICE_OBJECT { CSHORT Type; USHORT Size; LONG ReferenceCount; struct _DRIVER_OBJECT *DriverObject; struct _DEVICE_OBJECT *NextDevice; s

libevent源码分析1 ----evnet相关结构体分析

位于代码event-internal.h中. event_base类似事件的集合,你创建一个事件,必须将该事件指定一个集合. struct event_base { 50     const struct eventop *evsel; /*evsel和evbase就类比与类和对象之间的关系,evbase是evsel的 51     一个具体实现,指在这里使用的复用模型*/ 52     void *evbase; 53     /*这个event_base所关注的事件数目*/ 54     i

Linux中ifreq 结构体分析和使用

结构原型: struct ifreq{#define IFHWADDRLEN 6 union {  char ifrn_name[IFNAMSIZ];   } ifr_ifrn;  union {  struct sockaddr ifru_addr;  struct sockaddr ifru_dstaddr;  struct sockaddr ifru_broadaddr;  struct sockaddr ifru_netmask;  struct  sockaddr ifru_hwadd

Linux中ifreq 结构体分析和使用 及其在项目中的简单应用

[基础知识说明] 结构原型: /* * Interface request structure used for socket * ioctl's.  All interface ioctl's must have parameter * definitions which begin with ifr_name.  The * remainder may be interface specific. */ struct ifreq {#define IFHWADDRLEN 6 union {