skyprince 发表于 2009-08-10 11:52

请教:网卡驱动报文发送理解,谢谢

查看tg3驱动源码,对报文发送部分不太理解。
1、pci_map_single这个函数是要实现什么功能?把要发送的报文数据DMA到网卡设备上吗?
2、tg3_set_txd函数又实现了什么功能呢?

谢谢。

static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
……
mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);

        tp->tx_buffers.skb = skb;
        pci_unmap_addr_set(&tp->tx_buffers, mapping, mapping);

        tg3_set_txd(tp, entry, mapping, len, base_flags,
                  (skb_shinfo(skb)->nr_frags == 0) | (mss << 1));

        entry = NEXT_TX(entry);
……
}

eexplorer 发表于 2009-08-10 12:40

回复 #1 skyprince 的帖子

> 查看tg3驱动源码,对报文发送部分不太理解。
> 1、pci_map_single这个函数是要实现什么功能?把要发送的报文数据DMA到网卡设备上吗?

在作dma之前,需要进行一次从kernel的virtual address到dma address的mapping,设备上的dma engine需要使用dma address进行memory copy (从physical memory -> device)。
同时,在pci_map_single的时候,还会涉及到cache flush的问题,一旦map好以后,设备就可以访问物理内存的内容,所以需要把cache中的内容flush到memory中,保证device读到的是最新的data。由于x86 cpu在硬件上会保证cache coherence,所以并没有cache flush的操作。

> 2、tg3_set_txd函数又实现了什么功能呢?
没看过tg3,但是一般就是在tx ring buffer中找到一个free的tx slot, 根据得到的dma_address和数据长度,设置这个tx slot。device在得到这些信息后,就可以启动dma engine,把数据从host memroy中copy到device on-board memory中,然后在发送出去。

skyprince 发表于 2009-08-10 16:07

非常感谢eexplorer的解答。

是不是可以这样理解 pci_map_single 只是执行了地址映射,还没有执行实际的 memory copy操作。
到了tg3_set_txd函数时,才触发memory copy操作?

那启动DMA操作的主体是网卡还是驱动呢?是网卡实现将数据从 physical memory -> device。还是由驱动来完成?

eexplorer 发表于 2009-08-10 16:41

回复 #3 skyprince 的帖子

> 是不是可以这样理解 pci_map_single 只是执行了地址映射,还没有执行实际的 memory copy操
> 作。到了tg3_set_txd函数时,才触发memory copy操作?

memory copy 是由网卡上的dma engine发起的,是有硬件自动完成的,是一个异步操作。驱动的作用是把网卡dma engine作memory copy所需要的信息填好并通知网卡(tg3_set_txd)

finalfantasy000 发表于 2009-08-10 19:22

原帖由 eexplorer 于 2009-8-10 12:40 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
> 查看tg3驱动源码,对报文发送部分不太理解。
> 1、pci_map_single这个函数是要实现什么功能?把要发送的报文数据DMA到网卡设备上吗?

在作dma之前,需要进行一次从kernel的virtual address到dma address的 ...

cache是指哪儿的cache?CPU的么?还是网卡上面的buffer

emmoblin 发表于 2009-08-10 23:08

cache应该是内存上的dma 环行缓冲区

eexplorer 发表于 2009-08-11 09:37

原帖由 finalfantasy000 于 2009-8-10 19:22 发表 http://linux.chinaunix.net/bbs/images/common/back.gif


cache是指哪儿的cache?CPU的么?还是网卡上面的buffer

cache是cpu的cache, 这里涉及到cpu cache和 physical memory之间一致性的问题,因为网卡的dma engine是直接访问physical memory的。

在cpu准备好data buffer以后,需要flush cache以保证网卡的dma engine访问到的memory中的数据是最新的 -> pci_map_single
同时在收包时,网卡的dma engine会把受到的数据直接copy到memory中,这是如果cpu要访问的话,必须先invalidate 自己cache中对应这块memory的内容,以免从cache中读取旧的数据 -> pci_unmap_single

因为x86都是硬件帮你做掉了,所以这两个函数里并没有涉及到cpu cache的操作。

[ 本帖最后由 eexplorer 于 2009-8-11 09:39 编辑 ]

dreamice 发表于 2009-08-11 09:44

回复 #7 eexplorer 的帖子

这个cache是一个硬件层面的cache吧

eexplorer 发表于 2009-08-11 10:38

原帖由 dreamice 于 2009-8-11 09:44 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
这个cache是一个硬件层面的cache吧

是的,是指cpu上的cache (L1, L2...)。
刚才查了一下,好像arm需要显式的flush/invalidate cache (arm不熟,请有经验的同学确认一下。。。)

Cyberman.Wu 发表于 2009-08-13 14:42

1、这个问题2楼已经讲得很清楚了,直接的DMA是外设做的。这个实际上是所谓DMA基本上都是外设直接访问内存,而此时CPU如果只支持一些运算或只使用Cache数据,两者可以并行执行,从而提高时间。某些CPU中会集成一些DMA Engine,也许它可以用来做主动DMA,但这种架构比较少见。

2. 这个函数实际上是填写网卡和驱动共用的一个DMA描述符缓冲区,它本身还是在系统内存中,不过是一块Coherent DMA。真正通知网卡数据准备好了是在tg3_start_xmit->tw32_tx_mbox中写网卡的寄存器,里面的写操作触发网卡开始工作,首先检查描述符的ring buffer,然后根据描述处理数据。这个其实是很常见的一种设计。
页: [1] 2
查看完整版本: 请教:网卡驱动报文发送理解,谢谢