FreeBSD ixgbe网卡驱动相关数据结构讲解

前言

此文是5、6年前维护网卡驱动和优化时记录总结,当时10G设备绝对主流,1G网卡还分单队列和多队列两种,几年过去网络设备上40G网卡大行其道,100G网卡也是纷至沓来,但不管带宽如何升级,其实现原理类似。

正传

ixgbe.h 定义的 的相关结构:

/*

  • The transmit ring, one per queue
    */
    struct tx_ring {
    struct adapter *adapter;
    struct mbuf *m_prev;
    struct mtx tx_mtx;
    u32 me;
    u16 queue_status;
    u16 queue_full;
    int watchdog_time;
    union ixgbe_adv_tx_desc *tx_base; —>这是网卡真正是识别的discripter. 由ixgbe_dma_malloc函数分配4096个描述符(存储在连续的物理地址上), 该字段存储的是物理地址,在ixgbe_xmit的时候 操作 tx_base[i].read.buffer_addr = mbuf->m_data &~ DMAP_MIN_ADDRESS, 由此让网卡能够知道发送位置
    struct ixgbe_dma_alloc txdma;
    u32 next_avail_desc;
    u32 next_to_clean;
    struct ixgbe_tx_buf *tx_buffers; —>和描述符一样也是申请4096个,但是该成员是被用来操作驱动代码里面的mbuf的, 如在ixgbe_xmit里面tx_buffers[i]->m_head = mbuf(传进来的mbuf) 记录要发送的mbuf, 然后在ixgbe_txeof里面 把已经发送出去的mbuf内存回收,m_freem(tx_buffers[i]->m_head)
    volatile u16 tx_avail
    u32 txd_cmd;
    bus_dma_tag_t txtag;
    char mtx_name[16];

    u32 bytes; /* used for AIM /
    u32 packets;
    /
    Soft Stats */
    u64 no_desc_avail;
    u64 total_packets;
    };

/*

  • The Receive ring, one per rx queue
    */
    struct rx_ring {
    struct adapter *adapter;
    struct mtx rx_mtx;
    u32 me;
    union ixgbe_adv_rx_desc *rx_base;-------------->这是网卡真正是识别的discripter. 由ixgbe_dma_malloc函数分配4096个描述符(存储在连续的物理地址上), 该字段存储的是物理地址,在setup和 refresh的时候 操作 rx_base[i].read.pkt_addr = mbuf->m_data &~ DMAP_MIN_ADDRESS, 由此让网卡能够找到接收位置, 在ixgbe_rxeof里面 通过rx_base[i] 拿到要处理的描述符,判断 vtag 类的信息 和 接收是否完成等
    struct ixgbe_dma_alloc rxdma;
    struct lro_ctrl lro;
    bool lro_enabled;
    bool hdr_split;
    bool hw_rsc;
    bool discard;
    u32 next_to_refresh;
    u32 next_to_check;
    char mtx_name[16];
    struct ixgbe_rx_buf *rx_buffers; ----------------->和描述符一样也是申请4096个,但是该成员是被用来操作驱动代码里面的mbuf的, 如在ixgbe_rxeof里面 通过拿到 rx_buffers[i] 一下就拿到了一个mbuf, 这个mbuf就是送给协议栈处理的mbuf.
    bus_dma_tag_t htag;
    bus_dma_tag_t ptag;

    u32 bytes; /* Used for AIM calc */
    u32 packets;

};

struct ixgbe_tx_buf {
u32 eop_index;
struct mbuf *m_head;
bus_dmamap_t map;
};

struct ixgbe_rx_buf {
struct mbuf *m_head;
struct mbuf *m_pack;
struct mbuf *fmp;
bus_dmamap_t hmap;
bus_dmamap_t pmap;
};

struct adapter {
/*
** Queues:
** This is the irq holder, it has 网卡有多少个队列就有多少个该结构, 每个队列是与IRQ一对一的,且这里说的 RX/TX pair 是指针, 指向的是在rx_rings/tx_rings 分配的内容的
** and RX/TX pair or rings associated
** with it.
*/
struct ix_queue *queues; ===============>假设16个队列的IXGBE来说就是分配16个该结构

 /*
 * Transmit rings:
 *     Allocated at run time, an array of rings.
 */
 struct tx_ring          *tx_rings;  ===============>假设16个队列的IXGBE来说就是分配16个该结构
 int               num_tx_desc;

 /*
 * Receive rings:
 *     Allocated at run time, an array of rings.
 */
 struct rx_ring          *rx_rings; ===============>假设16个队列的IXGBE来说就是分配16个该结构

}

struct ix_queue {
struct adapter adapter;
u32 msix; /
This queue’s MSIX vector /
u32 eims; /
This queue’s EIMS bit */
u32 eitr_setting;
u32 stress_ticks;
struct resource *res;
void *tag;
struct tx_ring *txr; /一个队列结构上挂着两个方向的ring/ ==========>用adaptor里面的 tx_rings 来初始化这里的txr
struct rx_ring *rxr;/这个指针将在ixgbe_allocate_queues中赋值成在此函数中malloc出来的adapter->rx/tx_rings/
struct task que_task;
struct taskqueue *tq;
u64 irqs;
u64 stress_out;
};

/无论igb和ixgbe用多少个队列,一块物理的网卡只有一个adapter,起多队列的特性都是包含在adapter中的/

ixgbe_allocate_queues(){
malloc出来num_queues个ix_queue队列==>adapter->queues = malloc();
…tx_rings==>adapter->tx_rings = malloc(*num_queues);
…rx_rings==>adapter->rx_rings = malloc(*num_queues);

 /*对每个(共num_queues个,每个队列上都有rx/tx_ring,其实就相当于多个队列的em(em是FreeBSD下1G网卡的驱动命名主要的网卡类型是8254x, 82571/2/4等)网卡实现)tx/rx_ring 根据*/
 
 for (i = 0; i < adapter->num_queues; i++) {
      que = &adapter->queues[i];
      que->adapter = adapter;
      que->txr = &adapter->tx_rings[i];
      que->rxr = &adapter->rx_rings[i];
 }

}

以上相关结构关联图:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值