2.1 Structure of the Network Driver
All Linux network drivers follow common interfaces. The object-oriented method is used in the design.
A device is an object (device structure) with its own data and methods. For each device
When the method is called, the first parameter is the device object itself. In this way, you can access yourself.
(Similar to this reference during object-oriented programming ).
The most basic methods for a network device are initialization, sending, and receiving.
----------------------------------------
| Deliver packets | receive packets queue |
| (Dev_queue_xmit () | them (netif_rx () |
----------------------------------------
| /\\
\\/ |
-------------------------------------------------------
| Methods and variables (initialize, open, close, hard_xmit, |
| Interrupt handler, config, resources, status...) |
-------------------------------------------------------
| /\\
\\/ |
---------------------------------------
| Send to hardware | CE from hardware |
---------------------------------------
| /\\
\\/ |
-----------------------------------------------------
| Hardware media |
-----------------------------------------------------
The initialization program completes hardware initialization, variable initialization in device, and system resource application. Send
The program is automatically called when data is sent at the upper-layer protocol layer of the driver. Generally, the error message is not sent to the driver.
Instead, the hardware sending function is used to send data directly. Generally
Hardware interruption notification. In the interrupt handler, enter the hardware frame information in a skbuff structure, and then call netif_rx () to send it to the upper layer for processing.
2.2 Basic Methods for network drivers
As an object, network devices provide some methods for the system to access. These methods provide unified interfaces,
The hardware details are masked, so that the system accesses various network devices in a unified manner.
Unrelated.
The following describes the most basic methods.
2.2.1 initialization (initialize)
The driver must have an initialization method. When the driver is loaded into the system
Initial program. It does the following work. Detection device. In the initialization program, you can
The feature checks whether the hardware exists and then determines whether to start the driver. Configure and initialize the hardware. In
In the initialization program, you can complete the configuration of hardware resources, such as plug-and-play hardware.
(Linux kernel does not support the PNP function. You can complete this function in the driver.
Yes ). After you configure or negotiate the resources used by the hardware, you can apply for these resources from the system. Some resources are
Shared with other devices, such as interrupted devices. Some cannot be shared, such as Io and DMA. Next, you need to start
Modify the variables in the device structure. Finally, you can get the hardware started.
2.2.2 open)
This method is called when the network device is activated in the network device driver.
State from down --> up ). So in fact, a lot of work in initialize can be done here. For example
Source Application, hardware activation. If Dev-> open returns non-0 (error), the hardware status is down.
Another function of the open method is to prevent the driver from being uninstalled when it is loaded as a module.
The device is on. Call the mod_inc_use_count macro in the open method.
2.2.3 stop)
The close method is opposite to the open method. Some resources can be released to reduce the burden on the system. Close is in
Called when the device status changes from up to down. In addition, if the driver is mounted as a module, close
Mod_dec_use_count should be called to reduce the number of times the device is referenced so that the driver can be detached.
In addition, the close method must return success (0 = success ).
2.2.4 send (hard_start_xmit)
All network device drivers must use this method. When the system calls the xmit of the driver
The sent data is placed in a sk_buff structure. A general driver sends data to hardware.
Some special devices, such as loopback, make the data into a receiver and send it back to the system, or
The dummy device directly discards data.
If the request is sent successfully, sk_buff is released in the hard_start_xmit method, and 0 is returned (sent successfully ). If
Unable to process the device temporarily. For example, if the hardware is busy, 1 is returned. If Dev-> tbusy is set to non-0, the system
If the hardware is too busy, it will not be sent again until Dev-> tbusy is set to 0. Tbusy 0 tasks are generally interrupted
Complete. The hardware is interrupted after sending. In this case, you can set tbusy to 0 and use mark_bh () for calling.
The system can send messages again. If the message fails to be sent, you can leave Dev-> tbusy as a non-0 value.
The system will try again. If hard_start_xmit fails to be sent, do not release sk_buff.
The transmitted data in sk_buff already contains the frame header required by the hardware. Therefore, it is not required in the sending method.
To populate the hardware frame header, the data can be directly submitted to the hardware for sending. Sk_buff is locked ),
Make sure that other programs do not access it.
2.2.5 receive)
The driver does not have a receiving method. If data is received, the driver notifies the system.
Generally, an interruption occurs when the device receives the data. In the Interrupt Processing Program, the driver requests a piece of data.
Sk_buff (SKB): read data from the hardware and place it in the applied buffer zone. Enter sk_buff.
. SKB-> Dev = Dev, determine the protocol type of the received frame, and enter SKB-> Protocol
). Point the pointer SKB-> Mac. Raw to hardware data and then discard the hardware frame header (skb_pull ). Also
Set SKB-> pkt_type to indicate the second (Link Layer) data type. It can be of the following types:
Packet_broadcast: Link Layer Broadcast
Packet_multicast: Layer Multicast
Packet_self: The frame sent to you.
Packet_otherhost: The frame sent to someone else (this frame will be available in the listening mode)
Finally, call netif_rx () to send the data to the protocol layer. Put the data in the netif_rx () into the processing queue and return
The actual processing is to reduce the interruption time after the interruption is returned. After calling netif_rx,
The driver cannot access the data buffer SKB.
2.2.6 hardware frame header (hard_header)
Hardware usually adds its own hardware frame header before sending upper-layer data, such as Ethernet)
There is a 14-byte frame header. This frame header is added before the upper-layer IP address, IPX, and other data packets. Driver provision
A hard_header method. The protocol layer (IP, IPX, ARP, etc.) calls this program before sending data.
The length of the hardware frame header must be set to Dev-> hard_header_len, so that the protocol layer retains the data.
The space of the hardware frame header. In this way, the hard_header program only needs to call skb_push and correctly fill in the hardware frame header.
Yes.
When the protocol layer calls the hard_header, the transmitted parameters include (2.0.xx): Data sk_buff,
Device pointer, protocol, Destination Address (daddr), source address (saddr), Data Length (LEN ). Data
Do not use the parameters in sk_buff because the data may not be fully organized when calling the hard_header.
If saddr is null, the default address is used ). If daddr is null, the protocol layer does not know the hardware
. If the hardware frame header is fully filled in the hard_header, the number of bytes added is returned. If the hardware frame
The information in the header is incomplete (for example, if daddr is null, but the destination hardware address is required in the frame header. Typical situation
If IP Address Resolution (ARP) is required for Ethernet, the number of negative bytes is returned. Hard_header returns a negative number
The protocol layer will further build the header. Currently, ARP is used in Linux.
(If the hard_header returns positive, Dev-> ARP = 1, it indicates no ARP is required, negative is returned, Dev-> ARP = 0,
ARP ).
The call to hard_header is included in the handler at each protocol layer. For example, ip_output.
2.2.7 Address Resolution (xarp)
Some networks have hardware addresses (such as Ethernet) and need to know the target hardware when sending hardware frames.
Address. In this way, the upper-Layer Protocol address (IP, IPX) and hardware address are required. This corresponds to the address
Resolved. The device that requires ARP will call the rebuild_header of the driver before sending it.
Method. The main parameters of the call include the pointer to the hardware frame header and the protocol layer address. If the driver can
If the hardware address is parsed, 1 is returned. If not, 0 is returned.
The rebuild_header is called in do_dev_queue_xmit () of net/CORE/dev. C.
2.2.8 parameter settings and statistics
The driver also provides methods for the system to set and read device parameters. Average
Only the root user can set the device parameters. The settings are as follows:
Dev-> set_mac_address ()
When the ioctl type is siocsifhwaddr, you need to set the MAC address of the device. Average
Setting MAC addresses does not make much sense.
Dev-> set_config ()