网络设备驱动的注册与注销由 register_netdev( ) 和 unregister_netdev( ) 函数完成,这两个函数的原型为:
int register_netdev(struct net_device *dev); void unregister_netdev(struct net_device *dev);
这两个函数都接收一个 net_device 结构体指针为参数,可见 net_device 数据结构在网络设备驱动中的核心地位。
net_device 的生成和成员的赋值并不一定要由我们亲自动手逐个完成,可以利用如下宏帮助填充:
#define alloc_netdev(sizeof_priv, name, name_assign_type, setup) \ alloc_netdev_mqs(sizeof_priv, name, name_assign_type, setup, 1, 1) #define alloc_netdev_mq(sizeof_priv, name, name_assign_type, setup, count) \ alloc_netdev_mqs(sizeof_priv, name, name_assign_type, setup, count, count)
#define alloc_etherdev(sizeof_priv) \
alloc_etherdev_mq(sizeof_priv, 1) #define alloc_etherdev_mq(sizeof_priv, count) \
alloc_etherdev_mqs(sizeof_priv, count, count)
alloc_etherdev_mq 宏引用的 alloc_etherdev_mqs( ) 函数的原型为:
struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, unsigned int rxqs);
alloc_netdev 以及 alloc_netdev_mq 宏引用的 alloc_netdev_mqs( ) 函数的原型为:
struct net_device *alloc_netdev_mqs(int sizeof_priv,
const char *name, unsigned char name_assign_type, void (*setup)(struct net_device *), unsigned int txqs, unsigned int rxqs);
alloc_netdev_mqs( ) 函数生成一个 net_device 结构体,对其成员赋值并返回该结构体的指针。第一个参数为设备私有成员大小,第二个参数为设备名, 第三个参数为 net_device 的 setup( ) 函数指针,第四、五个参数为要分配的发送和接收子队列的数量。
setup( ) 接收的参数也为 struct net_device 指针,用于预置 net_device 成员的值。
free_netdev( ) 完成与 alloc_netdev( ) 和 alloc_etherdev( ) 函数相反的功能,即释放 net_device 结构体的函数:
void free_netdev(struct net_device *dev);
net_device 结构体的分配 和 网络设备驱动的注册 需在网络设备驱动程序初始化时进行,而 net_device 结构体的释放 和 网络设备驱动的注销 在设备或驱动被移除的时候执行,如下所示:
/* * 网络设备驱动程序的注册和注销 * */ static int xxx_register(void) { ``` /* 分配 net_device 结构体并对其成员赋值 */ xxx_dev = alloc_netdev(sizeof(struct xxx_priv), "sn%d", xxx_init); if (xxx_dev == NULL) ``` /* 分配 net_device 失败 */ /* 注册 net_device 结构体 */ if ((result = register_netdev(xxx_dev))) ``` } static void xxx_unregister(void) { ``` /* 注销 net_device 结构体 */ unregister_netdev(xxx_dev); /* 释放 net_device 结构体 */ free_netdev(xxx_dev); }