注意:这篇文章上次更新于418天前,文章内容可能已经过时。
在这篇文章中,我们将讨论高通 WLAN 驱动程序中的对象管理器模块(Object Manager)。
主要数据结构
在整个 WLAN 驱动程序中,对象管理器模块主要负责管理 3 个对象:
- psoc(Physical System on Chip)
- pdev(Physical Device)
- vdev(Virtual Device)
他们之间的关系如下已经在开篇图中有所展示。
在全局的 wlan_objmgr_global 对象中包括了有一个 psoc 的指针数组,在每个psoc 对象中又包括了一个 soc_objmgr 对象,这个对象中包括了一个 pdev 的指针数组,和一个 vdev 的指针数组。
每一个 pdev 对象中又包括了一个 pdev_objmgr 对象,这个对象中包括了一个 psoc 的指针,指向了当前 pdev 对象所属的 psoc 对象。
每一个 vdev 对象中又包括了一个 vdev_objmgr 对象,这个对象中包括了一个 pdev 的指针,指向了当前 vdev 对象所属的 pdev 对象。
在整个 WLAN 驱动程序中,几乎所有的配置、状态信息都会附加在这些对象上来进行管理。
对象创建
wlan_objmgr_global 对象创建
在驱动加载函数中 hdd_driver_load 会调用到 wlan_objmgr_global_obj_init 函数来进行内存的分配和初始化。
整个调用流程如下:
hdd_driver_load =>
hdd_component_init =>
dispatcher_init =>
wlan_objmgr_global_obj_init
1 | /* Global object, it is declared globally */ |
值得注意的是,在 dispatcher_init 会初始化大量的 WLAN Driver 内部组件,包括 scan、wifi_pos、dfs 等。
其中,第一个被初始化的就是 wlan_objmgr_global 对象,因为其它组件的对象最终都会附加在这个对象上。
以上过程的最终源头是 module_init(hdd_module_init); , 也就是说在驱动模块被加载时就会调用到这个函数。
在驱动模块被加载时的 dispatcher_init 函数中,其他模块会在 wlan_objmgr_global 对象上注册回调函数。
这些回调函数会在 psoc 对象创建时被调用。
以 scan 模块为例:
在 ucfg_scan_init 函数中会调用到 wlan_objmgr_register_psoc_create_handler 函数来注册回调函数。
1 | QDF_STATUS ucfg_scan_init(void) |
wlan_objmgr_register_psoc_create_handler 会在 wlan_objmgr_global 对象维护的 psoc_create_handler 的表中注册 scan 模块的回调函数。
1 | QDF_STATUS wlan_objmgr_register_psoc_create_handler( |
psoc 对象创建
psoc 对象的创建是在 HDD 上下文创建的过程中被调用的。
而 hdd_context_create 是在驱动程序的 probe 函数中被调用的。probe 函数的调用会晚于 module_init(hdd_module_init);。
在 wlan_objmgr_psoc_obj_create 函数为 psoc 对象分配内存并进行初始化。
然后通过 for 循环调用 g_umac_glb_obj->psoc_create_handler 中注册的回调函数。
对于 scan 模块来说,这个回调函数是 wlan_scan_psoc_created_notification。参数列表是 NULL。
最后会调用 wlan_objmgr_psoc_object_attach 函数来将 psoc 对象附加到 wlan_objmgr_global 对象上。
1 | struct wlan_objmgr_psoc *wlan_objmgr_psoc_obj_create(uint32_t phy_version, |
pdev 对象创建
在驱动程序的 probe 函数中首先通过 hdd_context_create 创建出了 psoc 对象。
然后在 hdd_wlan_startup 函数中,会创建 pdev 对象。
1 | static int __hdd_soc_probe(struct device *dev, |
pdev 的创建过程已经在如下代码的注释中给出了解释,其中,pdev 的创建也需要通过 for 循环来调用其他组件在 wlan_objmgr_global 对象中注册的 pdev 创建时的回调函数。
1 | struct wlan_objmgr_pdev *wlan_objmgr_pdev_obj_create( |
vdev 对象创建
vdev 的创建和销毁与 Linux 内核网络设备接口是紧密相关的。
比如,当网络设备打开时(如ifconfig up或ip link set up), 内核会调用网络设备驱动程序中的 ndo_open 函数。
ndo: network device operations
在高通 WLAN 驱动程序中,ndo_open 函数是 hdd_open 函数。
点击展开:
1 | struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create( |


