zoukankan      html  css  js  c++  java
  • 在全志平台调试博通的wifi驱动(类似ap6212)【转】

    转自: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.4drivers etwirelesscmdhddhd_gpio.c
    bcm_wlan_set_carddetect()调用sunxi_mci_rescan_card(sdc_id, 1);

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

    五.    linux-3.4drivers etwirelesscmdhddhd_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.4drivers etwirelesscmdhddhd_sdio.c
    dhdsdio_probe()函数继续深入初始化。这个函数里面有个变量dhd_download_fw_on_driverload,决定函数初始化流程,需要
    修改为TRUE。

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

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

    驱动要加载固件,需要文件系统,所以驱动最好是做成ko。
    硬件上,模块没有中断脚,所以需要设置为poll方式。
    linux-3.4drivers etwirelesscmdhddhd_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

  • 相关阅读:
    VOJ 1049送给圣诞夜的礼物——矩阵快速幂模板
    梅森旋转算法
    C语言实验二——位运算
    C语言实验1—— C中的指针和结构体
    Leonardo的笔记本LA 3641——置换的乘法
    ngnix
    centos Linux 常用命令汇总
    vimrc 避免中文乱码配置
    PHP
    批量修改文件权限 和所有者 chown nobody:nobody * -R chmod 775 * -R
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/4835821.html
Copyright © 2011-2022 走看看