本文最后更新于 43 天前,其中的信息可能已经有所发展或是发生改变。
参考文档
概述
cfg80211模块与驱动模块的交互是通过一系列API来进行交互的,这些API是由内核定义在include/net/cfg80211.h中的struct cfg80211_ops结构体中
这些接口由驱动模块定义并在驱动初始化阶段注册在内核中
整体流程
这个函数通过几个关键步骤将驱动自定义的接口注册到cfg80211模块中:
1. 创建wiphy设备并注册操作集
/* create a new wiphy for use with cfg80211 */
wiphy = wiphy_new(&demo_cfg80211_ops, sizeof(struct demo_softc));
这是最核心的注册步骤。demo_cfg80211_ops 是一个 cfg80211_ops 结构体,包含了驱动程序实现的所有cfg80211回调函数。这些回调函数定义了驱动如何响应用户空间的WiFi操作请求
2. 设置wiphy设备属性
sc = wiphy_priv(wiphy);
sc->wiphy = wiphy;
set_wiphy_dev(wiphy, sc->dev);
wiphy->privid = sc;
将驱动的私有数据结构与wiphy设备关联,建立双向引用关系
3. 初始化wiphy功能特性
demo_init_wiphy(sc);
这个函数会设置wiphy支持的功能特性,如支持的频段、加密方式、接口类型等,告诉cfg80211这个驱动能提供哪些WiFi功能
4. 向内核注册wiphy设备
if ((ret = wiphy_register(wiphy))) {
SSV_LOG_DBG("Could not register wiphy device\n");
ret = -ENODEV;
goto err_register_wiphy;
}
这一步将wiphy设备正式注册到Linux内核的cfg80211子系统中,使其对用户空间可见
5. 创建网络接口
#ifndef DIS_NETDEV_INIT
rtnl_lock();
wdev = demo_interface_add(sc, "wlan%d", NL80211_IFTYPE_STATION, NULL);
rtnl_unlock();
rtnl_lock();
wdev = demo_interface_add(sc, "p2p0", NL80211_IFTYPE_STATION, NULL);
rtnl_unlock();
#endif
创建具体的网络接口(如wlan0、p2p0),这些接口会出现在系统的网络接口列表中,用户可以通过这些接口进行WiFi操作
注册机制的工作原理
当用户空间程序(如wpa_supplicant、iw命令)通过netlink发送WiFi配置请求时:
- cfg80211子系统接收请求
- 根据wiphy设备找到对应的驱动
- 调用
demo_cfg80211_ops中相应的回调函数 - 驱动执行具体的硬件操作
例如,当用户执行 iw wlan0 scan 时:
cfg80211会调用demo_cfg80211_ops.scan回调函数- 驱动收到调用后控制
WiFi硬件执行扫描操作 - 扫描结果通过
cfg80211接口返回给用户空间
这样,驱动就成功地将自己的WiFi功能”插入”到了Linux标准的无线网络管理框架中,实现了硬件抽象和标准化接口的统一