Reprinted from: http://my.csdn.net/weiqing1981127
A Network Device Driven Fundamentals
1. Basic Theory of Ethernet
Ethernet is a kind of LAN, it uses the carrier to listen to multi-channel access and Collision detection technology (CSMA/CD), and at the rate of 10m/s run on a variety of types of cable, commonly used network card chip has DM9000, DM9161, CS8900 chip.
The topology of Ethernet has bus and star, and the working mode of Ethernet is half-duplex and full-duplex. The current twisted pair is the most common transmission medium of Ethernet, it is used to connect from the host to the hub or switch, the fiber is mainly used for cascade between the switch and the switch to the router to the point link.
In the LAN, multiple nodes are shared transmission media, which must have a mechanism to determine a moment, which device occupies the transmission media to transfer data, so the link layer of the LAN should have the function of media access control, that is, the data link layer is divided into Logical Link Control LLC sub-layer and media access control Mac Sublayer.
The frame structure of Ethernet is mainly Ethernet II, Ethernet 802.3raw, Ethernet802.3sap, Ethernet802.3snap
The Ethernet controller implements the MAC layer function and must be used in conjunction with the PHY (physical layer transceiver), which is related to the OSI Data link layer, which implements the physical layer functionality. The MII (Media agnostic Interface) is a standard interface for connecting Fast Ethernet Mac and PHY, and the Ethernet device driver communicates with PHY via MII to configure parameters such as PHY ID, rate, duplex mode, and so on.
2. Linux network-driven hierarchy
Linux network drive can be divided into four layers, namely network protocol interface layer, network equipment interface layer, device drive function layer and device physical media layer, the kernel is through the dev_base as the head pointer to the device chain list to manage all network equipment. The programming of network device driver is mainly the initialization of network equipment Net_device and the function of sending and receiving packets.
Network Protocol Interface Layer
The main function of the network protocol interface layer is to provide a transparent packet sending and receiving interface to the upper level protocol, and when the API or IP of the upper layer needs to send the packet, it will call the Dev_queue_xmit function of the network protocol interface layer to send a content of sk_buff data. When the upper layer receives data for a packet, it is done by passing a pointer to the NETIF_RX function with a SK_BUFF data structure. The Sk_buff socket buffer provides an efficient buffer processing and flow control mechanism for the Linux network layer, and when the packet is sent, the network processing module of the Linux kernel must establish a packet sk_buff that needs to be transmitted, and then submit the Sk_buff to the lower layer at Sk_ The buff adds different protocol headers until it is sent to the network device. Similarly, when a network device receives a packet from a network medium, it must remove the different protocol headers before handing them over to the user.
The following is a partial struct member definition for Sk_buff
struct Sk_buff {
......
unsigned int len,
Data_len;
__u16 Mac_len,
Hdr_len;
sk_buff_data_t Transport_header; The head of the Transport layer
sk_buff_data_t Network_header; The head of the network layer
sk_buff_data_t Mac_header; The head of the MAC layer
sk_buff_data_t tail; Tail pointers for valid data
sk_buff_data_t end;
unsigned char *head,//head of entire buffer
*data; Header pointers for valid data
unsigned int truesize;
atomic_t users;
};
For Sk_buff operations, in addition to allocation and release, you need to know the following functions: Add data skb_put at the end of the buffer, add data skb_push at the beginning of the buffer, remove the data skb_pull at the beginning of the buffer, and adjust the head skb_reserve of the entire buffer.
Network Device Interface Layer
The interface layer of network equipment mainly defines a unified and abstract net_device for the changeable network, and realizes the unification of many kinds of hardware at the software level. The network device driver mainly fills the members of the Net_device and registers the Net_device to implement the hardware operation function and the kernel's hook-up. Typically, the network device driver accepts data in an interrupt manner, while the Net_device defines Poll_controller as a purely polling interface, and because the broadband interface receives thousands of packets per second, if the use of interrupts can cause system performance degradation, To improve the performance of Linux on broadband systems, network subsystem developers have created a polling-based approach to receiving data from the Napi (New API), whose data-receiving process is "incoming interrupt arrival-shutdown receive interrupt-Receive all data by polling-open receive interrupt-Receive interrupt coming ...", Functions associated with Napi are added Napi, enable Napi, dispatch Napi, the specific function is netif_napi_add,napi_enable,napi_schedule. Finally, it is important to note that for NAPI mode and interrupt mode to receive data, there are some differences in the driver design, such as the Napi method is to use the NETIF_RECEIVE_SKB function to pass the packet to the kernel, instead of using the NETIF_RX function.
Device-driven functional layer
For specific devices, engineers should implement functions such as open,stop,tx,hard_header,get_stats,tx_timeout,interruppt in Net_device.
Network Device Media Layer
The media layer of the network device directly corresponds to the actual hardware device, we need to define a set of functions that read and write the internal registers of the device, such as Ior,iow.
Two Network device-driven porting
Below we mainly explain the mini2440-based DM9000 NIC driver porting
First look at the connotation DM9000 code in/DRIVER/NET/DM9000.C
View/driver/net/makefile
obj-$ (config_dm9000) + = DM9000.O
View/driver/net/konfig
Menuconfig net_ethernet
BOOL "Ethernet (100Mbit)"
Config DM9000
TriState "DM9000 Support"
Depends on ARM | | BLACKFIN | | Mips
Select CRC32
Select MII
So when configuring the kernel make menuconfig, this item needs to be checked.
According to the Development Board circuit diagram know DM9000 Aen port to nGCS4, while DM9000 int port to irq_eint7, in addition DM9000 cmd port to LADDR2, finally found DM9000 on the data line is SD0-SD15, That is, the number of digits in the data line is 16 bits.
According to the assignment of the mini2440 address space and the definition of the chip-selection signal, the starting address of the corresponding space of the pin nGCS4 is 0x20000000, which is controlled by the system address line. At the same time we know that DM9000 uses the interrupt number is irq_eint7. In addition, the CMD signal on the DM9000 is the control of the address port or the data port, if CMD is 0, that is, LADDR2 0 means access to the address register, when CMD is 1, that is, LADDR2 1 means access to the data register.
Below we carry out the DM9000-driven porting, add the following code in the MACH-MINI2440.C
#include <linux/dm9000.h>
#define MACH_MINI2440_DM9K_BASE (S3C2410_CS4 + 0x300)
static struct resource mini2440_dm9k_resource[] = {
[0] = {//Address port
. Start = Mach_mini2440_dm9k_base,
. end = Mach_mini2440_dm9k_base + 3,
. Flags = Ioresource_mem
},
[1] = {//Data port
. Start = Mach_mini2440_dm9k_base + 4,
. end = Mach_mini2440_dm9k_base + 7,
. Flags = Ioresource_mem
},
[2] = {//interrupt number
. Start = Irq_eint7,
. end = Irq_eint7,
. Flags = IORESOURCE_IRQ | ioresource_irq_highedge,//High-level triggering
}
};
static struct Dm9000_plat_data Mini2440_dm9k_pdata = {
The number of digits in the data line is 16 bits, and no e2prom is used
. Flags = (Dm9000_platf_16bitonly | Dm9000_platf_no_eeprom),
. dev_addr = {0x08,0x90,0x90,0x90,0x90,0x90},//mac address
};
static struct Platform_device Mini2440_device_eth = {
. Name = "dm9000",//device name
. id =-1,
. num_resources = Array_size (Mini2440_dm9k_resource),
. Resource = Mini2440_dm9k_resource,//Resources
. Dev = {
. Platform_data = &mini2440_dm9k_pdata,//Private data
},
};
Finally, add the following code in the mini2440 BSP file mach-mini2440.c
static struct Platform_device *mini2440_devices[] __initdata = {
......
& Mini2440_device_eth,//Add
};
This completes the kernel image generation kernel after the migration is complete.
Network device drivers under Linux (i)