網路資料報收發流程 3 E1000網絡卡和DMA

2021-06-18 14:09:48 字數 3042 閱讀 4492

標籤:

資料報乙太網資料流

原文出處:

一、硬體布局

每個網絡卡(mac)都有自己的專用dma engine,如上圖的 tsec 和 e1000 網絡卡intel82546。

上圖中的紅色線就是乙太網資料流,dma與ddr打交道需要其他模組的協助,如tsec,pci controller

乙太網資料在 tsecddr pci_controllerddr

之間的流動,cpu的core是不需要介入的

只有在資料流動結束時(接收完、傳送完),dma engine才會以外部中斷的方式告訴cpu的core

二、dma engine

上面是dma engine的框圖,以接收為例:

1.在system memory中為dma開闢一端連續空間,用來bd陣列 (一致性dma記憶體)

bd是給dma engine使用的,所以不同的裝置,bd結構不同,但是大致都有狀態、長度、指標3個成員。

2.初始化bd陣列,status為e,length為0

在system memory中再開闢一塊一塊的記憶體,可以不連續,用來存放乙太網包

將這些記憶體塊的匯流排位址賦給buf(dma對映)

3.當mac接收乙太網資料流,放在了rx fifo中

4.當乙個乙太網包接收完全後,dma engine依次做以下事情

fetch bd:開始乙個個的遍歷bd陣列,直到當前bd狀態為empty為止

update bd:更新bd狀態為ready

move data:把資料從rx fifo中搬移到system memory中dma對映的部分

generate interrupt:資料搬移完了,產生外部中斷給cpu core

5.cpu core處理外部中斷,此時乙太網資料已經在system memory中dma對映的部分了

解除dma對映,更新bd狀態為empty

再開闢一端記憶體,將這塊記憶體的匯流排位址賦給bd的指標字段

三、核心中dma相關api

void *dma_alloc_cohrent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag);

功能:分配一致性dma記憶體,返回這塊記憶體的虛擬位址ea, 這塊記憶體的實體地址儲存在 dma_handle

dev: null也行

size: 分配空間的大小

dma_handle: 用來儲存記憶體的匯流排位址(實體地址)

注意:一致性dma對映,bd所佔記憶體就是靠dma_alloc_cohrent來分配的。

dma_addr_t *dma_map_single(struct device *dev, void *buffer, size_t size, enum dma_data_direction);

功能:將一塊連續的記憶體 buffer 對映為dma記憶體來使用。對映後,cpu不能再操作這塊 buffer

返回:這塊buffer的匯流排位址(實體地址)

dev: null也行

buffer: 一塊連續記憶體的虛擬位址ea

size: 連續記憶體的大小

dma_data_direction: dma資料流的方向

注意:流式dma對映,乙太網包所佔記憶體先通過kmalloc來分配,然後通過dma_map_single來對映給bd的

四、e1000驅動中的dma

網絡卡驅動中使用dma的套路差不多都一樣,以e1000驅動為例講一下(tsec驅動的dma見這裡)

4.1 載入e1000網絡卡驅動

e1000_probe()

4.1 啟動e1000網絡卡

e1000_open() //當使用者敲ifconfig up命令時,最終呼叫網絡卡驅動的open函式

-->e1000_setup_all_rx_resources(adapter)

-->e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]) 

//給rx bd分配一致性dma記憶體

rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);

-->e1000_configure(adapter)

-->e1000_configure_rx(adapter)

adapter->clean_rx = e1000_clean_rx_irq;

adapter->alloc_rx_buf = e1000_alloc_rx_buffers;

-->呼叫 adapter->alloc_rx_buf鉤子函式,即 e1000_alloc_rx_buffers

--> skb = netdev_alloc_skb(netdev, bufsz); //呼叫kmalloc新建乙個skb

buffer_info->dma = pci_map_single(pdev,

skb->data,

adapter->rx_buffer_len,

pci_dma_fromdevice); //給skb->data建立dma對映

rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);//初始化bd的buf指標

-->e1000_request_irq(adapter);

//掛rx 中斷isr函式為 e1000_intr()

最終bd資料結構應該是下面這個樣子

4.2 e1000的中斷

注意:e1000產生rx中斷時,乙太網資料報已經在系統記憶體中,即在skb->data裡面

下面的中斷處理過程就簡略了,詳細的看這裡

do_irq()

e1000_clean_rx_irq()

網路資料報收發流程 三 e1000網絡卡和DMA

from 一 硬體布局 每個網絡卡 mac 都有自己的專用dma engine,如上圖的 tsec 和 e1000 網絡卡intel82546。上圖中的紅色線就是乙太網資料流,dma與ddr打交道需要其他模組的協助,如tsec,pci controller 乙太網資料在tsecddr pci con...

網路資料報收發流程 二 不配置NAPI的情況

不配置napi的時候,網路裝置不使用自己的napi struct結構,所有網路裝置驅動都使用同乙個napi struct,即cpu私有變數 get cpu var softnet data backlog 每當收到資料報時,網路裝置驅動會把 get cpu var softnet data back...

網路資料報收發流程 2 不配置NAPI的情況

標籤 資料報網路 原文出處 不配置napi的時候,網路裝置不使用自己的napi struct結構,所有網路裝置驅動都使用同乙個napi struct,即cpu私有變數 get cpu var softnet data backlog 每當收到資料報時,網路裝置驅動會把 get cpu var sof...