3.8 Ethernet Initialization
As part of cpu_startup, the kernel locates any attached network devices. The details of this process are beyond the scope of this text. Once a device is identified, a device-specific initialization function is called. Figure 3.24 shows the initialization functions for our three sample interfaces.
Figure 3.24. Network interface initialization functions.
Each device driver for a network interface initializes a specialized ifnet structure and calls if_attach to insert the structure into the linked list of interfaces. The le_softc structure shown in Figure 3.25 is the specialized ifnet structure for our sample Ethernet driver (Figure 3.20).
Figure 3.25. le_softc structure.
An array of le_softc structures (with NLE elements) is declared in if_le.c. Each structure starts with sc_ac, an arpcom structure common to all Ethernet interfaces, followed by device-specific members. The sc_if and sc_addr macros simplify access to the ifnet structure and Ethernet address within the arpcom structure, sc_ac, shown in Figure 3.26.
Figure 3.26. arpcom structure.
The first member of the arpcom structure, ac_if, is an ifnet structure as shown in Figure 3.20. ac_enaddr is the Ethernet hardware address copied by the LANCE device driver from the hardware when the kernel locates the device during cpu_startup. For our sample driver, this occurs in the leattach function (Figure 3.27). ac_ipaddr is the last IP address assigned to the device. We discuss address assignment in Section 6.6, where we'll see that an interface can have several IP addresses. See also Exercise 6.3. ac_multiaddrs is a list of Ethernet multicast addresses represented by ether_multi structures. ac_multicnt counts the entries in the list. The multicast list is discussed in Chapter 12.
Figure 3.27. leattach function.
Figure 3.27 shows the initialization code for the LANCE Ethernet driver.
The kernel calls leattach once for each LANCE card it finds in the system.
The single argument points to an hp_device structure, which contains HP-specific information since this driver is written for an HP workstation.
le points to the specialized ifnet structure for the card (Figure 3.20) and ifp points to the first member of that structure, sc_if, a generic ifnet structure. The device-specific initializations are not included in Figure 3.27 and are not discussed in this text.
Copy the hardware address from the device
For the LANCE device, the Ethernet address assigned by the manufacturer is copied from the device to sc_addr (which is sc_ac.ac_enaddr—see Figure 3.26) one nibble (4 bits) at a time in this for loop.
lestd is a device-specific table of offsets to locate information relative to hp_addr, which points to LANCE-specific information.
The complete address is output to the console by the printf statement to indicate that the device exists and is is operational.
Initialize the ifnet structure
leattach copies the device unit number from the hp_device structure into if_unit to identify multiple interfaces of the same type. if_name is "le" for this device; if_mtu is 1500 bytes (ETHERMTU), the maximum transmission unit for Ethernet; if_init, if_reset, if_ioctl, if_output, and if_start all point to device-specific implementations of the generic functions that control the network interface. Section 4.1 describes these functions.
All Ethernet devices support IFF_BROADCAST. The LANCE device does not receive its own transmissions, so IFF_SIMPLEX is set. The driver and hardware supports multicasting so IFF_MULTICAST is also set.
bpfattach registers the interface with BPF and is described with Figure 31.8. The if_attach function inserts the initialized ifnet structure into the linked list of interfaces (Section 3.11).