Network packet sending and receiving process (iii): e1000 NIC and DMA

Source: Internet
Author: User

first, the hardware layout

each network card (MAC) has its own dedicated DMA Engine, such as the Tsec and e1000 Nic intel82546.
the Red line is the Ethernet data stream, and DMA deals with DDR requiring assistance from other modules, such as the TSEC,PCI controller
The flow of Ethernet data between tsec<-->ddr pci_controller<-->ddr , the core of the CPU does not need to be involved
DMA engine will tell the CPU's core in an external interrupt only when the data flow is finished (Received and sent out)

Second, DMA Engine

above is a block diagram of the DMA engine to receive as an example:
1. Open a contiguous space for the DMA in system memory for the BD array (consistent DMA memory)
BD is used for DMA engine, so different devices, BD structure is different, but roughly all have a state, length, pointer 3 members.

2. Initialize the BD array, the status is e,length to 0
another piece of memory in the system memory, can be discontinuous, to store the Ethernet packet
Assign the bus address of these memory blocks to the BUF (DMA map)

3. when the MAC receives the Ethernet data stream, it is placed in the RX FIFO

4. when an Ethernet packet is fully received, the DMA engine does the following things in turn
FETCH BD: Begins a traversal of the BD array until the current BD status is empty
UPDATE BD: updating BD status to ready
move data: The part of the DMA mapping that is moved from the RX FIFO to the system memory
generate interrupt: Data is moved and external interrupts are generated to the CPU core

5.CPU core handles external interrupts, at which time Ethernet data is already part of the DMA map in system memory
Unblock DMA mapping, update BD status to empty
then open up one end of memory and assign the bus address of this memory to the BD's pointer field

Third, the DMA-related API in the kernel

void *dma_alloc_cohrent(struct device *dev, size_t size, dma_addr_t *dma_handle, int flag);
function: Assign consistent DMA memory, return the virtual address of this block of memory EA, the physical address of this memory is saved in Dma_handle
Dev:null, too.
Size: Space Allocated
Dma_handle: The bus address (physical address) used to save memory
Note: Consistent DMA mapping ,BD accounts for the memory is allocated by Dma_alloc_cohrent .

dma_addr_t *dma_map_single (struct device *dev, void *buffer, size_t size, enum dma_data_direction);
function: A contiguous memory buffer is mapped to DMA memory for use. After mapping, the CPU can no longer manipulate this buffer
Return: The bus address of this buffer (physical address)
Dev:null, too.
Buffer: Virtual address of a contiguous memory ea
Size: Amount of contiguous memory
DMA_DATA_DIRECTION:DMA the direction of the data stream
Note: streaming DMA mapping , the memory of the Ethernet packet is first allocated via Kmalloc , and then mapped to the BD by Dma_map_single

Iv. DMA in the e1000 drive

the use of DMA in the network card driver is almost the same routine, take the e1000 driver as an example (TSEC-driven DMA see here)

4.1 load e1000 nic driver

E1000_probe () { //primary is the initialization of the hook function
Netdev = alloc_etherdev (sizeof (struct e1000_adapter));
Netdev->open = &E1000_open; //Important
netdev->stop = &e1000_close;
netdev->hard_start_xmit = &e1000_xmit_frame;
netdev->get_stats = &e1000_get_stats;
netdev->set_multicast_list = &e1000_set_multi;
netdev->set_mac_address = &e1000_set_mac;
NETDEV->CHANGE_MTU = &e1000_change_mtu;
Netdev->do_ioctl = &e1000_ioctl;
E1000_set_ethtool_ops (Netdev);
netdev->tx_timeout = &e1000_tx_timeout;
Netdev->watchdog_timeo = 5 * HZ;
#ifdef CONFIG_E1000_NAPI
Netif_napi_add (Netdev, &adapter->napi, E1000_clean, 64); //Important
#endif
}

4.1 Starting the e1000 Nic

e1000_open() ///When the user knocks the ifconfig up command, the final call to the NIC-driven open function
-->e1000_setup_all_rx_resources (Adapter)
-->e1000_setup_rx_resources (adapter, &adapter->rx_ring[i])
//Assign consistent DMA memory to RX BD
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;
--Call the Adapter->alloc_rx_buf hook function, which is e1000_alloc_rx_buffers
- -SKB = NETDEV_ALLOC_SKB (Netdev, Bufsz); //Call Kmalloc to create a new SKB
BUFFER_INFO->DMA = Pci_map_single (Pdev,
Skb->data,
Adapter->rx_buffer_len,
Pci_dma_fromdevice); Creating a DMA mapping for Skb->data
rx_desc->buffer_addr = cpu_to_le64 (BUFFER_INFO->DMA); //Initialize BD's buf pointer
-->E1000_REQUEST_IRQ (adapter);
//Hang Rx Interrupt ISR function for e1000_intr ()

the final BD data structure should look like this
      
interruption of 4.2 e1000

Note: When the e1000 generates a RX interrupt, the Ethernet packet is already in system memory, which is inside the Skb->data
the following interrupt processing process is brief, look at the details here
Do_irq ()
{
Interrupt Top Half
Call the RX interrupt function of the e1000 NIC e1000_intr ()
Trigger Soft Interrupt (using NAPI)
interrupt the lower half of the
call all handler of soft interrupts in turn
in Net_rx_action, the e1000 napi_struct.poll () hook function is eventually called, which is E1000_clean
E1000_clean () Final call to E1000_clean_rx_irq ()
}

E1000_clean_rx_irq ()
{
Rx_desc = E1000_rx_desc (*rx_ring, i); //Get RX BD
status = rx_desc->status;
SKB = buffer_info->skb;
buffer_info->skb = NULL;

Pci_unmap_single (Pdev, //de-skb->data DMA mapping
BUFFER_INFO->DMA,
Buffer_info->length,
pci_dma_fromdevice);
length = le16_to_cpu (rx_desc->length);
Length-= 4; ///Ethernet packet FCS check it off.
skb_put (SKB, length);
Skb->protocol = Eth_type_trans (SKB, Netdev);
NETIF_RECEIVE_SKB (SKB); //SKB entering the protocol stack
}

Reprinted from Http://blog.chinaunix.net/uid-24148050-id-1667017.html

Network packet sending and receiving process (iii): e1000 NIC and DMA

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.