linux内核网络6,Linux内核网络数据发送(六)——网络设备驱动

1. 前言

本文主要介绍设备通过 DMA 从 RAM 中读取数据并将其发送到网络,主要分析dev_hard_start_xmit 通过调用 ndo_start_xmit来发送数据的过程。

2. 驱动回调函数注册

驱动程序实现了一系列方法来支持设备操作,例如:

发送数据(ndo_start_xmit)

获取统计信息(ndo_get_stats64)

处理设备 ioctls(ndo_do_ioctl)

这些方法通过一个 struct net_device_ops 实例导出。看igb 驱动程序中这些操作:

static const struct net_device_ops igb_netdev_ops = {

.ndo_open = igb_open,

.ndo_stop = igb_close,

.ndo_start_xmit = igb_xmit_frame,

.ndo_get_stats64 = igb_get_stats64,

/* ... more fields ... */

};

这个 igb_netdev_ops 变量在 igb_probe函数中注册给设备:

static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

{

/* ... lots of other stuff ... */

netdev->netdev_ops = &igb_netdev_ops;

/* ... more code ... */

}

3. ndo_start_xmit 发送数据

上层的网络栈通过 struct net_device_ops 实例里的回调函数,调用驱动程序来执行各种操作。正如我们之前看到的,qdisc 代码调用 ndo_start_xmit 将数据传递给驱动程序进行发送。对于大多数硬件设备,都是在保持一个锁时调用 ndo_start_xmit 函数。

在 igb 设备驱动程序中,ndo_start_xmit 字段初始化为 igb_xmit_frame 函数,所以接下来从 igb_xmit_frame 开始,查看该驱动程序是如何发送数据的。在 drivers/net/ethernet/intel/igb/igb_main.c中,以下代码在整个执行过程中都 hold 着一个锁:

netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,

struct igb_ring *tx_ring)

{

struct igb_tx_buffer *first;

int tso;

u32 tx_flags = 0;

u16 count = TXD_USE_COUNT(skb_headlen(skb));

__be16 protocol = vlan_get_protocol(skb);

u8 hdr_len = 0;

/* need: 1 descriptor per page * PAGE_SIZE/IGB_MAX_DATA_PER_TXD,* + 1 desc for skb_headlen/IGB_MAX_DATA_PER_TXD,* + 2 desc gap to keep tail from touching head,* + 1 desc for context descriptor,* otherwise try next time*/

if (NETDEV_FRAG_PAGE_MAX_SIZE > IGB_MAX_DATA_PER_TXD) {

unsigned short f;

for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)

count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);

} else {

count += skb_shinfo(skb)->nr_frags;

}

函数首先使用 TXD_USER_COUNT 宏来计算发

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值