在全志平台调试博通的wifi驱动(类似ap6212)【转】

简介: 转自:http://blog.csdn.net/fenzhi1988/article/details/44809779 调试驱动之前,首先先看看驱动代码,了解代码大致工作流程,再根据硬件配置驱动,比如硬件上面没有 中断脚,就不要在驱动里面配置中断方式。

转自:http://blog.csdn.net/fenzhi1988/article/details/44809779

调试驱动之前,首先先看看驱动代码,了解代码大致工作流程,再根据硬件配置驱动,比如硬件上面没有

中断脚,就不要在驱动里面配置中断方式。

bcmdhd驱动代码分析:

一. dhd_linux.c 
dhd_module_init为驱动模块初始化函数。
初始化函数调用dhd_linux_platdev.c中dhd_wifi_platform_register_drv查找设备,注册驱动等。
 

二.   dhd_linux_platdev.c
        cfg_multichip=FALSE,所以dhd_wifi_platform_register_drv直接调用wifi_ctrlfunc_register_drv。

       wifi_ctrlfunc_register_drv中先调用bus_find_device寻找平台设备,如果寻找到,接下来就会调用
platform_driver_register来注册平台设备驱动。注册完,就会调用平台驱动的probe函数进行驱动后
续初始化,但是这两个平台设备都没有注册。
        初始化wifi_adapter_info_t,把这个adapter传递给全局变量dhd_wifi_platdata,供其他函数使用。
使用dhd_wlan_control全局变量初始化adapter中的wifi_plat_data成员,而dhd_wlan_control全局变量
在下面调用dhd_gpio.c中的bcm_wlan_set_plat_data()初始化,dhd_wlan_control全局变量保存
set_power/set_carddetect/mem_prealloc这些底层控制接口。
       最后调用dhd_wifi_platform_load()->dhd_wifi_platform_load_sdio()
     dhd_wifi_platform_load_sdio()中,开始进行sdio设备枚举,adapter只有一个。尝试3次枚举,dhd_bus_reg_sdio_notify()
注册一个 dummy_sdmmc 驱动,其probe函数释放一个信号量,再调用wifi_platform_set_power()。
wifi_platform_set_power()函数调用adapter成员wifi_plat_data中的set_power开启模块电源,set_power已
经初始化为dhd_gpio.c的bcm_wlan_set_power(),bcm_wlan_set_power()只是设置引脚电平。
wifi_platform_set_power()函数调用成功,调用wifi_platform_bus_enumerate(adapter, TRUE);这个函
数调用adapter成员wifi_plat_data中的set_carddetect,真正调用的是dhd_gpio.c的bcm_wlan_set_carddetect()

三.    linux-3.4\drivers\net\wireless\bcmdhd\dhd_gpio.c
bcm_wlan_set_carddetect()调用sunxi_mci_rescan_card(sdc_id, 1);

四.   linux-3.4\drivers\mmc\host\sunxi-mci.c
sunxi_mci_rescan_card()函数软设置指定host的sdio卡可见,再调用mmc_detect_change()触发mmc探测历程。
如果发现总线上有设备,会调用上面的dummy驱动的probe函数释放信号量,在dhd_wifi_platform_load_sdio()中
等待的信号量就会成功唤醒,并跳出循环。

五.    linux-3.4\drivers\net\wireless\bcmdhd\dhd_linux_platdev.c
dhd_wifi_platform_load_sdio()跳出循环之后,继续调用dhd_bus_register()->bcmsdh_register()->bcmsdh_register_client_driver()
->sdio_register_driver()
sdio_register_driver()注册名为bcmsdh_sdmmc的驱动,此驱动注册注册完成,即进入bcmsdh_sdmmc_probe()。最后调用
sdioh_probe()进行真正的驱动初始化。sdioh_probe()->bcmsdh_probe()->drvinfo.probe()
drvinfo在bcmsdh_register()初始化。bcmsdh_register()调用处为dhd_bus_register()函数,设置为dhd_sdio变量,所以
drvinfo.probe()调用的是dhdsdio_probe()函数。

六.    linux-3.4\drivers\net\wireless\bcmdhd\dhd_sdio.c
dhdsdio_probe()函数继续深入初始化。这个函数里面有个变量dhd_download_fw_on_driverload,决定函数初始化流程,需要
修改为TRUE。

后面的代码越来越接近真正网络注册,基本上,到这里都比较正常,驱动差不多就可以顺利加载了,至于加载后出错的问题,很大原因是驱动没有

配置好,一般调试成熟的驱动代码或是其他代码的时候,首先要怀疑自己是不是正确的进行了配置。

 

驱动要加载固件,需要文件系统,所以驱动最好是做成ko。
硬件上,模块没有中断脚,所以需要设置为poll方式。
linux-3.4\drivers\net\wireless\bcmdhd\dhd_linux.c中修改dhd_poll,dhd_intr

 

开始调试

* 没有在系统配置文件里面声明sdio1有效,导致驱动不执行sdio相关probe函数
 在sys_config.fex声明sdio1有效。
* wifi_pm模块初始化太迟导致wifi模块不能正确获取电源相关操作资源。
 在wifi模块初始化之前直接调用wifi_pm模块初始化函数进行初始化。
* 修改module_num为8,在wifi_pm.c的函数wifi_pm_power里面case 7:后面增加case 8:
* module_pm模块初始化太迟,导致wifi模块不能正确获取电源相关操作资源。
 使用fs_initcall_sync提前初始化。
* 去掉wifi驱动Mafile中的-DOOB_INTR_ONLY

【作者】 张昺华
【新浪微博】 张昺华--sky
【twitter】 @sky2030_
【facebook】 张昺华 zhangbinghua
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
目录
相关文章
|
Linux 开发工具 内存技术
国产之路:复旦微zynq调试笔记2--PL网口
PL侧的网口需求相较于PS部分还是有一定区别的,主要需要添加axi ethernet 的移植
1708 0
|
6天前
|
Linux Android开发
全志平台A40I : I2C通讯问题调试笔记
全志平台A40I : I2C通讯问题调试笔记
31 0
|
8月前
|
安全 数据可视化 物联网
米尔电子新出的这款车规级芯片的T507开发板老牛逼了! 安排!
米尔电子新出的这款车规级芯片的T507开发板老牛逼了! 安排!
137 0
|
8月前
|
编解码 监控 安全
Android平台GB28181设备接入技术探讨
在此之前,我们先对协议规范做个简单了解:GB28181协议是一种用于视频监控系统互联互通的国际标准,它定义了视频监控系统中的设备间如何进行通信、交换数据和协调控制。以下是GB28181协议的一些主要内容:
|
存储 运维 内存技术
vFW设备开局升级操作指北
vFW设备开局升级操作指北
vFW设备开局升级操作指北
西门子S7-1200的功能与特点,应用范围有哪些
今天开始我们来学习西门子S7-1200,S7-1200是西门子公司新推出的一款面向离散自动化系统和独立自动化系统的低端PLC。
西门子S7-1200的功能与特点,应用范围有哪些
|
物联网
启明云端分享:一款基于瑞芯微PX30核心板的配套功能底板
IDO-EVB3022-V1.0是一款基于瑞芯微PX30核心板(我司核心板料号为IDO-SOM3022-V1.0)的配套功能底板。底板采用 DDR3 内存金手指 204P 插座作为核心板安装接口,其外围具有网口、串口、USB 接口、LVDS 接口等。可适用于工业主机,物联网设备,医疗健康设备, 广告一体机,互动自助终端,教学实验平台,显示控制,车载安防等多个领域 。
174 0
启明云端分享:一款基于瑞芯微PX30核心板的配套功能底板