RK3368 默认支持的WiFi芯片为AP6XXX系列,此芯片还默认支持BT。
可以先看看原理图里面的的情况,方便我们理解其在代码里面的配置情况
WiFi 设备配置:
./rockchip/rk3368/*/rk3368-p9.dts
此配置为WiFi kernel驱动在初始化时使用,包括芯片类型,ref voltage为1800mv, wake up irq为GPIO_AC
tiVE_HIGH
device/rockchip/rk3368/*/rockchip_defconfig
此文件有kernel相关的WiFi相关配置,只有打开这些配置,真正WiFi驱动才能初始化。
打开配置:CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP
表示WiFi驱动是built in的,而且是在内核启动之后才开始加载驱动。
接下来来看看代码里面WiFi驱动加载的地方:
//drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c
int rockchip_wifi_init_module_rkwifi(void)
{
struct task_struct *kthread = NULL;
kthread = kthread_run(wifi_init_thread, NULL, "wifi_init_thread");
if (IS_ERR(kthread))
pr_err("create wifi_init_thread failed.n");
return 0;
}
void rockchip_wifi_exit_module_rkwifi(void)
{
dhd_module_exit();
}
#ifdef CONFIG_WIFI_BUILD_MODULE
module_init(rockchip_wifi_init_module_rkwifi);
module_exit(rockchip_wifi_exit_module_rkwifi);
#else
#ifdef CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP
late_initcall(rockchip_wifi_init_module_rkwifi);
module_exit(rockchip_wifi_exit_module_rkwifi);
#else
module_init(rockchip_wifi_init_module_rkwifi);
module_exit(rockchip_wifi_exit_module_rkwifi);
#endif
由于上面定义了CONFIG_WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP, 那么rockchip_wifi_init_module_rkwifi()就会被调用
rockchip_wifi_init_module_rkwifi,从这个起点开始,我们来看看WiFi的整个初始化流程:
以上流程图涉及的源码目录:
drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/
net/rfkill/rfkill-wlan.c
drivers/mmc/core/host.c
drivers/mmc/core/sdio_bus.c
看完整个流程图,我们再结合看下机器启动时的kernel messages就很轻松了:
[ 15.354355] dhd_bus_devreset: == WLAN ON ==
[ 15.354456] F1 signature read @0x18000000=0x15294345
[ 15.356829] F1 signature OK, socitype:0x1 chip:0x4345 rev:0x9 pkg:0x2
[ 15.357223] DHD: dongle ram size is set to 819200(orig 819200) at 0x198000
[ 15.357292] dhd_bus_set_default_min_res_mask: Unhandled chip id
[ 15.358149] dhd_os_open_image: /system/etc/firmware/config.txt (50 bytes) open success
[ 15.359381] dhd_conf_read_pkt_filter: dhd_master_mode = 1
[ 15.359413] dhd_conf_read_pkt_filter: magic_pkt_filter_add = 141 0 1 12
[ 15.359437] Final fw_path=/system/etc/firmware/fw_bcm43456c5_ag.bin
[ 15.359445] Final nv_path=/system/etc/firmware/nvram_ap6256.txt
[ 15.359452] Final clm_path=/system/etc/firmware/clm_bcmdhd.blob
[ 15.359459] Final conf_path=/system/etc/firmware/config.txt
[ 15.359467] dhd_set_bus_params: set use_rxchain 0
[ 15.359474] dhd_set_bus_params: set txglomsize 36
[ 15.360352] dhd_os_open_image: /system/etc/firmware/fw_bcm43456c5_ag.bin (482927 bytes) open success
[ 15.436124] dhd_os_open_image: /system/etc/firmware/nvram_ap6256.txt (2424 bytes) open success
[ 15.437012] NVRAM version: AP6256_NVRAM_V1.2_09202018.txt
[ 15.437561] dhdsdio_write_vars: Download, Upload and compare of NVRAM succeeded.
[ 15.518743] dhd_bus_init: enable 0x06, ready 0x06 (waited 0us)
[ 15.519082] bcmsdh_oob_intr_register: HW_OOB irq=152 flags=0x4
[ 15.519421] dhd_get_memdump_info: File [/data/misc/wifi/.memdump.info] doesn't exist
[ 15.519430] dhd_get_memdump_info: MEMDUMP ENABLED = 2
[ 15.520414] Disable tdls_auto_op failed. -1
[ 15.520424] dhd_preinit_ioctls: Set tcpack_sup_mode 0
[ 15.520433] dhd_tcpack_suppress_set 352: already set to 0
[ 15.520446] wifi_platform_get_mac_addr
[ 15.520453] ======== dhd_wlan_get_mac_addr ========
[ 15.520462] [WLAN_RFKILL]: rockchip_wifi_mac_addr: enter.
[ 15.520471] [WLAN_RFKILL]: get_wifi_addr_vendor: rk_vendor_read wifi mac address failed (-1)
[ 15.520479] dhd_preinit_ioctls: can't get custom MAC address, ret=-1
[ 15.520804] dhd_apply_default_clm: Ignore clm file /system/etc/firmware/clm_bcmdhd.blob
[ 15.522459] Firmware up: op_mode=0x0005, MAC=c0:84:7d:ad:ba:30
[ 15.522478] dhd_conf_set_country: set country CN, revision 38
[ 15.545118] Country code: CN (CN/38)
[ 15.545855] dhd_conf_set_intiovar: set roam_off 1
[ 15.557139] Driver: 1.579.77.41.2 (r)
[ 15.557139] Firmware: wl0: Jun 16 2017 12:38:26 version 7.45.96.2 (66c4e21@sh-git) (r) FWID 01-1813af84
[ 15.557139] CLM: 9.2.9
[ 15.557412] dhd_txglom_enable: enable 1
[ 15.557424] dhd_conf_set_txglom_params: txglomsize=36, deferred_tx_len=36, bus_txglom=-1
[ 15.557433] dhd_conf_set_txglom_params: tx_in_rx=1, txinrx_thres=-1, dhd_txminmax=1
[ 15.557440] dhd_conf_set_txglom_params: tx_max_offset=0, txctl_tmo_fix=5
[ 15.557450] sdioh_set_mode: set txglom_mode to copy
[ 15.557464] dhd_conf_get_disable_proptx: fw_proptx=1, disable_proptx=-1
[ 15.560040] dhd_wlfc_hostreorder_init(): successful bdcv2 tlv signaling, 64
[ 15.560255] dhd_conf_set_intiovar: set ampdu_hostreorder 1
[ 15.561450] dhd_pno_init: Support Android Location Service
[ 15.580174] CFG80211-ERROR) wl_cfg80211_event : Event handler is not created
[ 15.582405] rtt_do_get_ioctl: failed to send getbuf proxd iovar (CMD ID : 1), status=-23
[ 15.582439] dhd_rtt_init : FTM is not supported
[ 15.582449] dhd_preinit_ioctls: SensorHub diabled 0
[ 15.583222] dhd_preinit_ioctls failed to set ShubHub disable
[ 15.585071] wl_android_wifi_on: Success
[ 15.613745] dhd_open: Exit ret=0
[ 15.627265] init: Starting service 'p2p_supplicant'...
[ 15.853910] P2P interface registered
[ 15.853965] wl_cfgp2p_add_p2p_disc_if: wdev: ffffffc0f532a400, wdev->net: (null)
[ 15.870543] WLC_E_IF: NO_IF set, event Ignored
[ 15.871833] P2P interface started
因为大部分WiFi是通过模拟SD卡来操作的,所以里面还会牵涉MMC驱动,
整个初始化过程复杂缠绕,备注以下几点:
1、WiFi驱动是通过一个单独的线程wifi_init_thread去加载,这样可以减少开机阻塞的时间;
2、adapter->wifi_plat_data=dhd_wlan_control 是在wifi_ctrlfunc_register_drv中进行初始化的,后面的set_power和set_carddetect钩子函数都是在这里进行调用的;
3、sdio总线驱动检测到的id和bcmsdh_sdmmc_ids表里的匹配才会调用probe函数;
4、dhd_update_fw_nv_path固件和配置存放在/system/etc/firmware/路径下,所以如果我们有WiFi相关的配置文件,直接编译拷贝到这个目录即可
5、在wl_cfg80211_attach调用wl_cfg80211_attach_p2p进行p2p初始化,可以看到最后log打印P2P interface started
原作者:b178903294