1.特定结构体记录
struct e1000_rx_desc {
__le64 buffer_addr; /* Address of the descriptor's data buffer */
__le16 length; /* Length of data DMAed into data buffer */
__le16 csum; /* Packet checksum */
u8 status; /* Descriptor status */
u8 errors; /* Descriptor Errors */
__le16 special;
};
struct e1000_rx_buffer {
union {
struct page *page; /* jumbo: alloc_page */
u8 *data; /* else, netdev_alloc_frag */
} rxbuf;
dma_addr_t dma;
};
struct e1000_rx_ring {
/* pointer to the descriptor ring memory */
void *desc;
/* physical address of the descriptor ring */
dma_addr_t dma;
/* length of descriptor ring in bytes */
unsigned int size;
/* number of descriptors in the ring */
unsigned int count;
/* next descriptor to associate a buffer with */
unsigned int next_to_use;
/* next descriptor to check for DD status bit */
unsigned int next_to_clean;
/* array of buffer information structs */
struct e1000_rx_buffer *buffer_info;
struct sk_buff *rx_skb_top;
/* cpu for rx queue */
int cpu;
u16 rdh;
u16 rdt;
};
struct e1000_adapter {
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
u16 mng_vlan_id;
u32 bd_number;
u32 rx_buffer_len;
u32 wol;
u32 smartspeed;
u32 en_mng_pt;
u16 link_speed;
u16 link_duplex;
spinlock_t stats_lock;
unsigned int total_tx_bytes;
unsigned int total_tx_packets;
unsigned int total_rx_bytes;
unsigned int total_rx_packets;
/* Interrupt Throttle Rate */
u32 itr;
u32 itr_setting;
u16 tx_itr;
u16 rx_itr;
u8 fc_autoneg;
/* TX */
struct e1000_tx_ring *tx_ring; /* One per active queue */
unsigned int restart_queue;
u32 txd_cmd;
u32 tx_int_delay;
u32 tx_abs_int_delay;
u32 gotcl;
u64 gotcl_old;
u64 tpt_old;
u64 colc_old;
u32 tx_timeout_count;
u32 tx_fifo_head;
u32 tx_head_addr;
u32 tx_fifo_size;
u8 tx_timeout_factor;
atomic_t tx_fifo_stall;
bool pcix_82544;
bool detect_tx_hung;
bool dump_buffers;
/* RX */
bool (*clean_rx)(struct e1000_adapter *adapter,
struct e1000_rx_ring *rx_ring,
int *work_done, int work_to_do);
void (*alloc_rx_buf)(struct e1000_adapter *adapter,
struct e1000_rx_ring *rx_ring,
int cleaned_count);
struct e1000_rx_ring *rx_ring; /* One per active queue */
struct napi_struct napi;
int num_tx_queues;
int num_rx_queues;
u64 hw_csum_err;
u64 hw_csum_good;
u32 alloc_rx_buff_failed;
u32 rx_int_delay;
u32 rx_abs_int_delay;
bool rx_csum;
u32 gorcl;
u64 gorcl_old;
/* OS defined structs */
struct net_device *netdev;
struct pci_dev *pdev;
/* structs defined in e1000_hw.h */
struct e1000_hw hw;
struct e1000_hw_stats stats;
struct e1000_phy_info phy_info;
struct e1000_phy_stats phy_stats;
u32 test_icr;
struct e1000_tx_ring test_tx_ring;
struct e1000_rx_ring test_rx_ring;
int msg_enable;
/* to not mess up cache alignment, always add to the bottom */
bool tso_force;
bool smart_power_down; /* phy smart power down */
bool quad_port_a;
unsigned long flags;
u32 eeprom_wol;
/* for ioport free */
int bars;
int need_ioport;
bool discarding;
struct work_struct reset_task;
struct delayed_work watchdog_task;
struct delayed_work fifo_stall_task;
struct delayed_work phy_info_task;
};
2.e100网卡驱动代码流程
从下往上记录,有点反人类,但是懒得调整了
dma_map_single -> 将申请的 sk_buff 地址经过映射成 总线地址赋值给 e100_rx_buffer.dma ,使用 cpu_to_le64 转换后赋值给 e100_rx_desc.buffer_addr中
__netdev_alloc_frag_align -> sk_buff 内存申请
netdev_alloc_frag
e1000_frag_len
e1000_alloc_frag -> sk_buff 内存申请赋值到 data 中,该 data 会赋值给 e100_rx_buffer.rxbuf.data
alloc_rx_buf -> 遍历执行 alloc_rx_buf 方法
clean_rx <- e1000_clean_rx_irq -> 赋值给 clean_rx
alloc_rx_buf <- e1000_alloc_rx_buffers -> 赋值到 alloc_rx_buf
e1000_configure_rx -> rx 赋值
e1000_configure -> e100 配置
e1000_setup_rx_resources -> 分配一致性dma内存
e1000_setup_all_rx_resources -> 初步配置 e100_rx_ring
e1000_open
e1000_netdev_ops
整体的执行流程就是创建 sk_buff 以及对应的 dma address(为后续接收网络报文触发 dma 做准备),执行完成后的数据结构关联图如下图所示。
由于涉及CPU、DMA等,必然带来虚拟地址、物理地址以及总线地址的纠缠,另外还存在缓存不一致等等问题,感兴趣的可以参考附录中的参考(1)和(2)
参考博文: