OpenHarmony实战:瑞芯微RK3566移植案例(下)
OpenHarmony实战:瑞芯微RK3566移植案例(中)
WIFI
整改思路及实现流程
整改思路
接下来熟悉HCS文件的格式以及"HDF WIFI”核心驱动框架的代码启动初始化过程,参考hi3881的代码进行改造。
HDF WiFi框架总体框架图
WLAN驱动架构组成:
ap6256驱动代码流程分析
驱动模块初始化流程分析
Ap6256 是一款SDIO设备WiFi模组驱动,使用标准Linux的SDIO设备驱动。内核模块初始化入口module_init()调用dhd_wifi_platform_load_sdio()函数进行初始化工作,这里调用wifi_platform_set_power()进行GPIO上电,调用dhd_wlan_set_carddetect()进行探测SDIO设备卡,最后调用sdio_register_driver(&bcmsdh_sdmmc_driver);进行SDIO设备驱动的注册,SDIO总线已经检测到WiFi模块设备,根据设备号和厂商号与该设备驱动匹配, 所以立即回调该驱动的bcmsdh_sdmmc_probe()函数,这里进行WiFi模组芯片的初始化工作,最后创建net_device网络接口wlan0,然后注册到Linux内核协议栈中。
下面对其中比较重要的函数进行举例分析:
(1) dhd_bus_register函数,主要实现sdio设备的注册,通过回调dhd_sdio中的相关函数,对wifi模块进行驱动注册等相关操作。
其中函数bcmsdh_register将静态结构体变量dhd_sdio赋值给静态结构体drvinfo,然后通过函数bcmsdh_register_client_driver调用函数sdio_register_driver向系统注册sdio接口驱动。
当sdio设备与sdio总线进行匹配后,会回调函数bcmsdh_sdmmc_probe,函数bcmsdh_sdmmc_probe会进一步回调dhd_sdio结构体中的成员函数dhdsdio_probe。
(2) dhdsdio_probe函数,主要实现net_device对象(wlan0)的创建,以及wireless_dev对象创建,并与net_device对象的成员ieee80211_ptr进行关联,给net_device对象的操作方法成员netdev_ops赋值,最后将net_device对象注册到协议栈中。
- 创建net_device网络接口wlan0对象
dhd_allocate_if()会调用alloc_etherdev()创建net_device对象,即wlan0网络接口。wl_cfg80211_attach()会创建wireless_dev对象,并将wireless_dev对象赋值给net_device对象的成员ieee80211_ptr。
- 将wlan0注册到内核协议栈
调用dhd_register_if()函数,这里将net_device_ops操作方法的实例dhd_ops_pri赋值给net_device对象的成员netdev_ops,然后调用register_netdev(net);将net_device对象wlan0网络接口注册到协议栈。
整改代码适配HDF WiFi框架
对于系统WiFi功能的使用,需要实现AP模式、STA模式、P2P三种主流模式,这里使用wpa_supplicant应用程序通过HDF WiFi框架与WiFi驱动进行交互,实现STA模式和P2P模式的功能,使用hostapd应用程序通过HDF WiFi框架与WiFi驱动进行交互,实现AP模式和P2P模式的功能。
Ap6256 WiFi6内核驱动依赖platform能力,主要包括SDIO总线的通讯能力;与用户态通信依赖HDF WiFi框架的能力,在确保上述能力功能正常后,即可开始本次WiFi驱动的HDF适配移植工作。本文档基于已经开源的rk3568开源版代码为基础版本,来进行此次移植。
适配移植ap6256 WiFi驱动涉及到的文件和目录如下:
3.1 WIFI相关的HDF框架编译控制宏
ap6256采用的是sdio总线,涉及到的通用编译控制宏如下:
CONFIG_DRIVERS_HDF_PLATFORM_SDIO=y
CONFIG_DRIVERS_HDF_PLATFORM_MMC=y
CONFIG_DRIVERS_HDF_WIFI=y
CONFIG_DRIVERS_HDF_STORAGE=y
3.2 具体WiFi设备驱动编译控制宏
涉及到wifi设备驱动的编译控制宏位于drivers/adapter/khdf/linux/model/network/wifi/Kconfig中,其中主要涉及到编译控制宏如下:
CONFIG_DRIVERS_HDF_NETDEV_EXT=y
CONFIG_AP6XXX_WIFI6_HDF=y
编译控制选项CONFIG_AP6XXX_WIFI6_HDF,内容如下:
config AP6XXX_WIFI6_HDF
tristate "support ap6xxx wifi6(80211ax) HDF"
depends on DRIVERS_HDF_WIFI
select CFG80211
select MAC80211
select DRIVERS_HDF_NETDEV_EXT
help
This driver supports wifi6 for ap6xxx HDF chipset.
This driver uses the kernel's wireless extensions subsystem.
If you choose to build a module, it'll be called dhd. Say M if unsure.
NOTE:此处为了保证框架侧与社区代码一致,不建议修改,设置CONFIG_AP6XXX_WIFI6_HDF的配置即可。
3.3 修改编译规则Makefile文件,添加ap6256驱动的源码位置
在drivers/adapter/khdf/linux/model/network/wifi/vendor/Makefile文件,添加如下内容:
ifneq ($(CONFIG_AP6XXX_WIFI6_HDF),)
#RKWIFI_PATH := (HDFVENDORPREFIX)/device/(���������������)/������/(product_company)/$(product_device)/wifi
RKWIFI_PATH := $(HDF_VENDOR_PREFIX)/device/kaihong/rk3568-khdvk/wifi //修改添加部分
obj-(CONFIGAP6XXXWIFI6HDF)+=(��������6�������6���)+=(RKWIFI_PATH)/
endif
ap6256驱动源码就位于源码/device/kaihong/rk3568-khdvk/wifi中,另外再根据ap6256的编译规则,修改wifi中的Makefile。
NOTE:此处也不建议修改,源码就位于device/(productcompany)/(��������������)/(product_device)/wifi中,但此处不能获取(productcompany)与(��������������)与(product_device)的值,还需要社区进行完善
WiFi驱动源码目录
驱动代码编译规则修改
参考device/kaihong/rk3568-khdvk/wifi/Makefile文件,内容如下:
obj-$(CONFIG_AP6XXX_WIFI6_HDF) += bcmdhd_hdf/
NOTE:可以修改目标规则指向不同的wifi驱动代码。
原生驱动代码存放于:
device/kaihong/rk3568-khdvk/patches/kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/
在原生驱动上修改编译规则Makefile文件
由于驱动中添加了HDF框架代码,其中涉及到头文件位于drivers目录中,需要将相关路径加入编译规则中,主要是修改两点:
(1) 引用drivers/hdf/khdf/model/network/wifi/hdfwifi.mk中规则,在Makefile中添加语句如下:
include drivers/hdf/khdf/model/network/wifi/hdfwifi.mk
(2) 将hdfwifi.mk中涉及到的头文件定义添加到编译规则中,方便编译时引用,添加语句如下:
EXTRA_CFLAGS += $(HDF_FRAMEWORKS_INC) \
$(HDF_WIFI_FRAMEWORKS_INC) \
$(HDF_WIFI_ADAPTER_INC) \
$(HDF_WIFI_VENDOR_INC) \
$(SECURE_LIB_INC)
NOTE:如果有其他编译要求,可以修改Makefile中的相关规则
3.4.4 在原生驱动上增加以及修改的HDF驱动代码文件位于:
device/kaihong/rk3568-khdvk/wifi/bcmdhd_hdf/
目录结构:
./device/kaihong/rk3568-khdvk/wifi/bcmdhd_hdf/hdf
├── hdf_bdh_mac80211.c
├── hdf_driver_bdh_register.c
├── hdfinit_bdh.c
├── hdf_mac80211_ap.c
├── hdf_mac80211_sta.c
├── hdf_mac80211_sta.h
├── hdf_mac80211_sta_event.c
├── hdf_mac80211_sta_event.h
├── hdf_mac80211_p2p.c
├── hdf_public_ap6256.h
├── net_bdh_adpater.c
├── net_bdh_adpater.h
其中hdf_bdh_mac80211.c主要对g_bdh6_baseOps所需函数的填充,hdf_mac80211_ap.c主要对g_bdh6_staOps所需函数进行填充,hdf_mac80211_sta.c主要对g_bdh6_staOps所需函数进行填充,hdf_mac80211_p2p.c主要对g_bdh6_p2pOps所需函数进行填充,在drivers/framework/include/wifi/wifi_mac80211_ops.h里有对wifi基本功能所需api的说明。
驱动文件编写
HDF WLAN驱动框架由Module、NetDevice、NetBuf、BUS、HAL、Client 和 Message 这七个部分组成。开发者在WiFi驱动HDF适配过程中主要实现以下几部分功能:
适配HDF WLAN框架的驱动模块初始化
代码流程框图如下:
HDF代码入口
HDF代码入口位于device/kaihong/rk3568-khdvk/wifi/bcmdhd_hdf/hdf_driver_bdh_register.c
struct HdfDriverEntry g_hdfBdh6ChipEntry = {
.moduleVersion = 1,
.Bind = HdfWlanBDH6DriverBind,
.Init = HdfWlanBDH6ChipDriverInit,
.Release = HdfWlanBDH6ChipRelease,
.moduleName = "HDF_WLAN_CHIPS"
};
HDF_INIT(g_hdfBdh6Chip