Article Title: Linux NIC Driver Details. Linux is a technology channel of the IT lab in China. Includes basic categories such as desktop applications, Linux system management, kernel research, embedded systems, and open source.
When a computer on the network is preparing to send data, his network adapter starts to work. First, the chip of the network adapter monitors whether data is flowing on the network. If not, he then sends the data to the network, with a very small latency between listening and sending. During this time, it is also possible that other computers on the network are also preparing to send data, and no data is flowing on the network. Therefore, two or more data may be sent to the network together, the NIC chip of the computer that sends the data must verify the returned data after the data is sent. If the data is found to be inconsistent with the sent data, a collision occurs, therefore, the number of computers in an Ethernet network should not be too large. It will not only increase the number of broadcast packets in the network, but also increase the number of packet collisions.
After receiving a complete packet, the NIC chip of our computer notifies the 8259 interrupt controller at one pin of the chip, and the Interrupt Controller then sends an interrupt to the CPU, the CPU then calls the NIC Interrupt Routine, for example:
DOS is like this.
Shield all interrupts (cli)
Push any register
Because the interrupt vector is in the segment 0
So xor ax, ax
Mov ds, ax
Mul ax, interrupt number
In this case, the [ax] offset of the data segment is the pointer of the Interrupt Routine. call [ax] To the Interrupt Routine... (DOS is a relatively distant thing. I describe his principle. Of course it is not that simple. If the netizen is interested in describing the above principles in detail, I am grateful for correcting or replacing what I wrote)
In short, in this routine, the CPU will call the elintr Interrupt Routine, and the unit parameter is the number of the NIC (because in the computer, you may have installed several NICs with the same number of NICS). elintr is used to read data from the NIC's data storage and read the pre-allocated data buffer during Nic initialization, the called function only has elread. Similarly, elread only calls one elget function. the elread function is simple, that is, calling elget. elget is a little more complicated. It involves allocating mbuf to the core memory. mbuf is a terrible thing, as STEVEN wrote, in order to save the "huge" 4 M memory at that time, at the cost of performance, mbuf has come up with this mbuf stuff, And mbuf must understand it. Although there are not many macro and function calls in the device driver, however, in the later IP protocol, TCP involves many aspects.
Data transmission is similar to receiving. After data is stored in the mbuf chain in the upper-layer protocol, the el_start function is called, this function places the data in the mbuf chain to the sending queue buffer el_pktbuf of the NIC, and then calls the el_xmit function, this function transfers the data in the buffer el_pktbuf of the sending queue to the data storage of the NIC. in my opinion, there are more memory copies in the middle. In the el_start function, data in mbuf should be directly transferred to the NIC's data storage, which will greatly improve the performance, because in the driver design, it is best to reduce a large amount of memory copies, it takes too much time.
*/
/* FreeBSD's 3COM Ethernet device driver */
/* This header file is generated when the core is compiled */
# Include "el. h"/* these three files are the header files generated during compilation. The content is a constant of the custom core */
# Include "opt_inet.h"
# Include "opt_ipx.h"
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include /* This header file is a register constant of the 3COM card */
/* For debugging convenience */
# Ifdef EL_DEBUG
# Define dprintf (x) printf x/* If DEBUG debugging is defined, print it to the screen */
# Else
# Define dprintf (x)
# Endif
/* Softc structure. The structure of each network adapter is different. It is mainly because the first member must be an Ethernet shared structure arpcom */
Static struct el_softc {
Struct arpcom;/* Ethernet public part */
U_short el_base;/* Basic Input/Output address */
Char el_pktbuf [EL_BUFSIZ];/* frame buffer size: 2048 */
} El_softc [NEL];/* NEL is defined in el. h, that is, the header file generated during compilation, which indicates the number of supported NICs */
/*
Let's look at the arpcom structure.
* This structure is shared by Ethernet device drivers and ARP programs.
Struct arpcom {
/*
* The ifnet structure must be at the first position in this structure.
/
Struct ifnet ac_if;
U_char ac_enaddr [6];/* Ethernet hardware address/
Int ac_multicnt;/* Number of multicast address lists/
Void * ac_netgraph;/* netgraph node information, that is, what we call PPPoE, that is,/
};
*/
/* Some function declarations */
Static int el_attach (struct isa_device *);/* Step 2: Fill in the relevant data structure */
Static void el_init (void *);/* Needless to say, it is initialization and called after probe and attach */
Static int el_ioctl (struct ifnet *, u_long, caddr_t);/* control the function tree pointer of the NIC */
Static int el_probe (struct isa_device *);/* Step 1: Test the program. Check whether the card exists and whether it is in the correct position .*/
Static void el_start (struct ifnet *);/* output data packets from the hardware interface */
Static void el_reset (void *);/* reset the interface of this routine. Call it in el_watchdog */
Static void el_watchdog (struct ifnet *);/* this function is generally used to call a package if it is not sent out within a certain period of time.
This function is not supported in the driver, which is included in my rtl8139 Description */
Static void el_stop (void *);/* Stop interface, which is called in el_ioctl () and el_reset */
Static int el_xmit (struct el_softc *, int);/* put the data packet in the chip and send it to Ethernet */
Static ointhand2_t elintr;/* Interrupt Routine */
Static _ inline void elread (struct el_softc *, caddr_t, int);/* Transfer packets to higher-level protocols for processing, that is, ether_input () routines. elintr () calls */
Static struct mbuf * elget (caddr_t, int, struct ifnet *);/* download data packets from the NIC. len indicates the data length, and the local Ethernet header is separated */
Static _ inline void el_hardreset (void *);/* This is a sub-program to reset the hardware .*/
/* Prepare the isa_driver structure for autoconf */
/* Isa_driver structure description:
This structure is used in the isa_device.h header file.
[1] [2] [3] [4] [5] Next page