《Linux network driver development Training lab book》
https://bootlin.com/doc/legacy/network-drivers/network-drivers-lab.pdf
Registering a network interface
Obviously, the first and simplest step, is to register a network interface in the module initialization function, and to remove in the
module cleanup function.
In the initialization function, use alloc_etherdev() to create a net_device structure, set its netdev_ops member to an empty
net_device_ops structure, and register the interface using register_netdev().
In the cleanup function, use unregister_netdev() and free_netdev() to remove the interface and free the memory. If you load this module, a new eth0 network interface should appear in the target system.
Integration in the driver model
With the driver model, devices are not registered in the module initialization function.
Rather, the module registers a PCI driver, a platform driver, a USB driver, etc. at initialization time, and the driver model infrastructure will call a probe() method when a device handled by our driver is detected.
So, let's integrate our driver in this kernel framework:
• Define a platform_driver structure, set the remove and probe members so that they point to two new functions with
the proper prototype, and define the driver members to the following substructure:
.driver = {
.name = “macb”,
.owner = THIS_MODULE,
}
• In the module initialization function, remove the existing code register the platform driver with platform_driver_register()
• In the module cleanup function, remove the existing code and call platform_driver_unregister().
• Implement the netdrv_probe() function. It must do the same as the previous initialization function (alloc_etherdev() and
register_netdev()), but must also ◦ Connect the network device (struct net_device) to the underlying platform device. This is done using SET_NETDEV_DEV(dev, & pdev> dev) where dev is the struct net_device representing the network interface, and pdev the platform device passed as argument to the probe() method
◦ Set the platform device driver data pointer to the network device, using platform_set_drvdata(pdev, dev) Both these calls allows to have cross-references between the structure representing the network interface (highlevel) and the structure representing the platform device (low-level)
• Implement the netdrv_remove() function. It must do the same as the previous module cleanup function. This function
receives as argument a platform_device pointer, and not the struct net_device pointer. So how do we get the struct net_device pointer? By using the platform device driver data, that we set in the probe() function:
struct net_device *dev = platform_get_drvdata(pdev)
After unregistering the network device (unregister_netdev()), reset the platform device driver data using platform_set_drvdata(pdev, NULL) and free the network device structure (free_netdev()).
Once everything is implemented, compile your module, transfer it to the target and load it. Does the eth0 interface appear as it used to do? It shouldn't! Let's see why in the next section.
........