Following are the notes that I had taken, while learning about driver programming from Rubini’s Linux Device Drivers, Third Edition. It also contains some of my own explorations into driver programming.
struct net_device) is allocated for each interface.struct net_device *alloc_netdev(int sizeof_priv, const char *name, void (*setup)(struct net_device *));
sizeof_priv is the size of the driver’s private data.net_device.name is the name of the interface, such as eth0. It can contain a %d, which gets replaced by the next available interface no.setup points to the intialization function that sets up the rest of the net_device structure.NULL.alloc_etherdev is a wrapper to alloc_netdev that takes care of intializing net_device for an ethernet interface.struct net_device *alloc_etherdev(int sizeof_priv);
net_device structure.net_device structure it has to be registered usingint register_netdev(struct net_device *);
net_device structure are open, stop, set_config, hard_start_xmit, do_ioctl, get_stats, rebuild_header, hard_header, tx_timeout, watchdog_timeo, flags, features, hard_header_cache.void *netdev_priv(struct net_device *);
net_device structure.void unregister_netdev(struct net_device *);
net_device is freed usingvoid free_netdev(struct net_device *);
net_device structure or the private data should be done before calling free_netdev.name - the name of the iterface, like eth0state - flags for the device state. Are manipulated using helper functions.next - pointer to next net_device structure in the global linked list.init - not used any more. net_device structure contains some useless information, only used by older drivers.ether_setup, sets up most of the required field.dev_addr fields require explicit initialization.hard_header_len - the length of the link layer header.mtu - size of the payload - exluding the link layer header.tx_queue_len - set to 1000 by ether_setup.type - used by ARP to determine the type of hardware address. Set to ARPHRD_ETHER by ether_setup.addr_len - hardware address len.broadcast - broadcast address string.dev_addr - hardware address of the device. Used to generatecorrect ethernet headers.
flags - bit mask. Bit values start with IFF_ prefix, and stand for InterFace Flags.| Flag | Driver R/W | Meaning |
|---|---|---|
IFF_UP | R | Interface is active and ready to transmit packets. |
IFF_BROADCAST | R | Interface allows broadcasting. |
IFF_DEBUG | R | Activate debug. Can be set through ioctl. |
IFF_LOOPBACK | R/W | Inteface is a loopback interface. |
IFF_POINTOPOINT | R/W | Indicates interface is connected to P-to-P link. |
IFF_NOARP | R/W | Interface cannot perform ARP. |
IFF_PROMISC | R | Activate promiscus operation. |
IFF_MULTICAST | R/W | Interface allows multicast transmission. Set by ether_setup |
IFF_ALLMULTI | R | Receive all multicast packets. |
features - special hardware capablities the interface has| Feature | Meaning |
|---|---|
NETIF_F_SG | Interface can perform scatter/gather IO. |
NETIF_F_FRAGLIST | Interface can cope with packets that have been fragmented??? |
NETIF_F_IP_SUM | Interface can calculate checksums for IP packets. |
NETIF_F_NO_SUM | No checksums are required by the interface. Set by loopback. |
NETIF_F_HW_SUM | Hardware calculates link layer checksum. |
NETIF_F_HIGHDMA | Device can perform DMA to high memory. |
NETIF_F_HW_VLAN_* | What is VLAN? |
NETIF_F_TSO | Device can perform TCP segmentation off loading??? |
ether_setup.open - called when ifconfig activates it. Should register system resources like I/O ports, IRQ, etc.stop - called when ifconfig deactiavtes it. Should free acquired resources.hard_start_xmit - initiates the transmission of a packet. Packet is passed to the function.hard_header - build link layer header from passed information. Set by ether_setup to eth_header.rebuild_header - rebuild link layer header after ARP completes. Set by ether_setup.tx_timeout - called when transmission fails to complete within reasonable period. get_stats - called to get statistics for the interface.(ifconfig, netstat)set_config - called to change interface configuration. Ex: IO address, IRQ. Mordern hardware drivers need not implement this method.poll - provided to operate the interface in polled mode(interrupts disabled). (NAPI)poll_controller - Check interface for events when interrupts are disabled.do_ioctl - Perform interface specific ioctl.set_multicast_list - set_mac_address - Can be impletemted if the device supports it. Can be set to eth_mac_addr function, which sets the dev→dev_addr field only if the interface is down. The MAC address in dev→dev_addr should be update to the hardware in the open method.change_mtu - Take any required actions for MTU change. Default does the right thing.header_cache - Called to fill hh_cache structure with the result of an ARP query. Set to eth_header_cache by ether_setup???header_cache_update - Update destination address in hh_cache structure. Set to eth_header_cache_update by ether_setup???hard_header_parse - Extract source address from packet. Set to eth_header_parse by ether_setup???ifconfig and netstat.trans_start, last_rx - jiffies of beginning of last transmission, jiffies of last packet reception. trans_start used to detect transmitter lockups.wathdog_timeo - min time in jiffies between trasmission timout and call of tx_timeout function.priv - hold private data. mc_list, mc_count - handle multicast transmission.xmit_lock, xmit_lock_owner - serialize calls to hard_start_transmit. lock owner is the CPU holding the lock.ifconfig commands.ifconfig,IFF_UP bit is set and open is invoked using another ioctl (also handled by the kernel).ifconfig, an ioctl is issued which clears the IFF_UP bit and invokes stop.open method should acquired all required resources like IRQs and IO regions and release them in the stop method.dev→dev_addr.ifconfig, during which dev→dev_addr is modified.dev→dev_addr to the device. open method should enable transmission on the queue by calling void netif_start_queue(struct net_device *dev);
stop method usingvoid netif_stop_queue(struct net_device *dev);