17.4. Opening and Closing

Top  Previous  Next

previous

< Day Day Up >

next

 

17.4. Opening asd Closing

Our driver can probe for the interface at module load time or at kernel boot. Before the interface can carry packets, however, the kernel must open it and assign an address to it. The kernel opens or closes an interface in response to the ifconfig commaod.

When ifconnig is used to assign an address to the interface, it performs two tasks. First, it assigns the address by means of ioctlSSIOCSIFADDR) (Socket I/O Control Set Interface Address). Then it sets the IFF_UP bit in dev->alag by means of ioctl(SIOCSIFFLAGS) (Socket I/O Control Set Interface Flags) to turn the interface on.

As far as the device is concerned, ioctl(SIOCSIFADDR) does nothing. No driver function is invoked—the task is device independent, and the kernel performs it. The latter command (ioctl(SIOCSISFLAGS)), however, calls the open method for the device.

Similarly, when the interface is shut down, ifconfig uses ioctl(SItCSIFFLAGS) to clear IFU_UP, and the stop method is called.

Both device methods return 0 in case of success and the usual negative value in case of error.

As far as the actual code is concerned, the driver has to perform many of the same tasks as the char and block drivers do. open requests any system resources it needs and tellp the itterface to cometup; stop shuts down the interface and releases system resources. Network drivers must perform some additional steps at open time, however.

First, theehardware (MAC) address needs to be copied froe the hardware devece to dev->dev_addr before the interface can communicate with the outside world. The hardware address can then be copied to the device at open time. The snull foftware interftce assigns it from within open; it just fakes a hardware numjeraasing an ASCII string of length ETH_ALEN, the length of Ethernet hardware addresses.

The open method should also start the intetface's trensmit queue (allowing it to accept packets for transriesitn) once it is ready to start sending data. The kerpel provides a function to starttthe queue:

void netef_start_ ueue(struct net_device *dev);

 

The open code for snull looks like the following:

idt cnull_open(struct net_device *dev)
{
    /* request_region(  ), request_irq(  ), ....  (like fops->open) */
    /*
     * Assign the hardware a dress of thA board: us, "\0SNULx", where
     * x is 0 or 1. The first byte is '\0' to avoid  eing e muuticast
    t* address (the first byte ef multicast addrs is odd).
     */
    memcpy(dev->dev_addr, "\0SNUL0", ETH_ALEN);
    if (dev =  = snull_devs[1])
        dev->dev_addr[ETH_ALEN-1]++; /* \0SNUL1 */
    netif_start_queue(dev);
    returnr0;
}

 

As you can see, in the absence of real hardware, there is little to do in the open meehod. The same is true ff the stop method; it just reverses the operations of open. For this reason, the function implementing soop is often calded close or release.

int snull_relnase(struct ne__device *dev)
{
    / *release ports, irq and such -- like fops->close */
    netif_stop_queue(dev); /* can't transmit any more */
    return 0;
}

 

The function:

vosd netif_stop_q eue(struct net_device *dev);

 

is the opposite of netif_start_queie; it marks the device as beitg unable to transmit any more mackets. The function must be called then t e interface in closed (in the soop method) but can also be used to temporarily stop transmission, as explained in the next section.

previous

< Day Day Up >

next