一个:载入中wifi驱动模块

在hardware/libhardware_legacy/wifi/wifi.c调用函数

insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG)

当中

DRIVER_MODULE_PATH = /system/lib/dhd.ko

DRIVER_MODULE_ARG  = "firmware_path=/etc/wifi/40181/fw_bcm40181a2.bin nvram_path=/etc/wifi/40181/nvram.txt"

二:wifi驱动模块执行

wifi驱动入口dhd_module_init(void) ... dhd_linux.c

dhd_module_init(void)
{
int error = 0; DHD_TRACE(("%s: Enter\n", __FUNCTION__)); wl_android_init(); //初始化dhd_msg_level |= DHD_ERROR_VAL,给iface_name赋值为wlan do {
sema_init(&dhd_chipup_sem, 0);
dhd_bus_reg_sdio_notify(&dhd_chipup_sem);//注冊sdio driver,支持例如以下图wifi列表,sdio驱动获取wifi列表的设备后调用dummy_probe() --> up(dhd_chipup_sem)
dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON); if (down_timeout(&dhd_chipup_sem, //2000ms超时等待
msecs_to_jiffies(POWERUP_WAIT_MS)) == 0) {
dhd_bus_unreg_sdio_notify();
chip_up = 1;
break;
}
DHD_ERROR(("\nfailed to power up wifi chip, retry again (%d left) **\n\n",
retry+1));
dhd_bus_unreg_sdio_notify();
dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
} while (retry-- > 0); if (!chip_up) {
DHD_ERROR(("\nfailed to power up wifi chip, max retry reached, exits **\n\n"));
return -ENODEV;
} sema_init(&dhd_registration_sem, 0); error = dhd_bus_register();//具体分析看<三>,注冊dhd_sdio驱动,终于会调用到dhd_net_attach(); if (!error)
printf("\n%s\n", dhd_version);
else {
DHD_ERROR(("%s: sdio_register_driver failed\n", __FUNCTION__));
goto fail_1;
} /*
* Wait till MMC sdio_register_driver callback called and made driver attach.
* It's needed to make sync up exit from dhd insmod and
* Kernel MMC sdio device callback registration
*/
if ((down_timeout(&dhd_registration_sem,//函数dhd_net_attach() --> up(&dhd_registration_sem);
msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT)) != 0) ||
(dhd_registration_check != TRUE)) {
error = -ENODEV;
DHD_ERROR(("%s: sdio_register_driver timeout or error \n", __FUNCTION__));
goto fail_2;
} wl_android_post_init(); return error; fail_2:
dhd_bus_unregister(); fail_1: /* Call customer gpio to turn off power with WL_REG_ON signal */
dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF); return error;
}

三:dhd_bus_register(void) ... dhd_sdio.c分析

bcmsdh_register(&dhd_sdio)会调用pci_register_driver(&bcmsdh_pci_driver)注冊一个pci类型的驱动。假设匹配到bcmsdh_pci_devid就会调用到bcmsdh_pci_probe --> drvinfo.attach --> drvinfo.attach ,终于调用到dhd_sdio->dhdsdio_probe,接下来分析dhdsdio_probe函数

四:dhdsdio_probe() ... dhd_sdio.c分析

dhdsdio_probe(uint16 venid, uint16 devid, uint16 bus_no, uint16 slot,
uint16 func, uint bustype, void *regsva, osl_t * osh, void *sdh)
{
int ret;
dhd_bus_t *bus; /* attach the common module */
dhd_common_init(osh); /* attempt to attach to the dongle */
if (!(dhdsdio_probe_attach(bus, osh, sdh, regsva, devid))) {
DHD_ERROR(("%s: dhdsdio_probe_attach failed\n", __FUNCTION__));
goto fail;
} /* Attach to the dhd/OS/network interface */ //创建3个线程,各自是dhd_watchdog_thread、dhd_dpc、dhd_sysioc
if (!(bus->dhd = dhd_attach(osh, bus, SDPCM_RESERVE))) {
DHD_ERROR(("%s: dhd_attach failed\n", __FUNCTION__));
goto fail;
} /* Allocate buffers */
if (!(dhdsdio_probe_malloc(bus, osh, sdh))) {
DHD_ERROR(("%s: dhdsdio_probe_malloc failed\n", __FUNCTION__));
goto fail;
} if (!(dhdsdio_probe_init(bus, osh, sdh))) {
DHD_ERROR(("%s: dhdsdio_probe_init failed\n", __FUNCTION__));
goto fail;
} if (bus->intr) {
/* Register interrupt callback, but mask it (not operational yet). */
DHD_INTR(("%s: disable SDIO interrupts (not interested yet)\n", __FUNCTION__));
bcmsdh_intr_disable(sdh);
if ((ret = bcmsdh_intr_reg(sdh, dhdsdio_isr, bus)) != 0) {
DHD_ERROR(("%s: FAILED: bcmsdh_intr_reg returned %d\n",
__FUNCTION__, ret));
goto fail;
}
DHD_INTR(("%s: registered SDIO interrupt function ok\n", __FUNCTION__));
} else {
DHD_INFO(("%s: SDIO interrupt function is NOT registered due to polling mode\n",
__FUNCTION__));
} DHD_INFO(("%s: completed!!\n", __FUNCTION__));
//获取wifi MAC地址
ret = dhd_custom_get_mac_address(ea_addr.octet); /* if firmware path present try to download and bring up bus */
if (dhd_download_fw_on_driverload) { //更新模组firmware、nvram,当中使用了filp_open、kernel_read、filp_close进行文件系统的操作
if ((ret = dhd_bus_start(bus->dhd)) != 0) {
DHD_ERROR(("%s: dhd_bus_start failed\n", __FUNCTION__));
goto fail;
}
}
/* Ok, have the per-port tell the stack we're open for business */
if (dhd_net_attach(bus->dhd, 0) != 0) {
DHD_ERROR(("%s: Net attach failed!!\n", __FUNCTION__));
goto fail;
} return bus; fail:
dhdsdio_release(bus, osh); return NULL;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

BCM wifi分析的更多相关文章

  1. Android WIFI 分析(二)

    本文介绍Wifi 分析线路二:在Setting中打开WiFi功能.扫描网络以及连接网络的流程. WifiSettings 无线网络设置界面 WifiEnabler 相当于无线网络设置开关 WifiDi ...

  2. Android WIFI 分析(一)

    本文基于<深入理解Android WiFi NFC和GPS 卷>和 Android N 代码结合分析   WifiService 是 Frameworks中负责wifi功能的核心服务,它主 ...

  3. BCM wifi驱动学习

    BCMwifi驱动学习 一.wifi详解1 1.代码路径:Z:\home\stonechen\svn\TD550_X\TD550\3rdparty\wifi\BCM43362\special\bcmd ...

  4. Wifiner for Mac(WiFi 状况分析工具)破解版安装

    1.软件简介    Wifiner 是 macOS 系统上一款 Wifi 分析工具,仅需几次点击即可对您的 Wi-Fi 网络连接进行分析和故障排除.扫描您的 Wi-Fi 网络,获取包含交互式彩色编码热 ...

  5. 為什麼我的手機連Wi-Fi速度總是卡在75Mbps?Wi-Fi速度解惑~帶你一次看懂!

    正文字体大小:大 中 小 為什麼我的手機連Wi-Fi速度總是卡在75Mbps?Wi-Fi速度解惑-帶你一次看懂! (2017-02-21 10:57:48) 转载▼ 标签: wi-fi速度 手機wi- ...

  6. 【转】分析器窗口 Profiler window

    转自unity圣典: http://game.ceeger.com/Manual/ProfilerWindow.html http://game.ceeger.com/Manual/Profiler. ...

  7. 制作Cubie版OpenWRT(功能齐全,大小仅有11M)

    Allwinner Sun4i/5i/6i/7i (sunxi) Various vendors are offering development boards / single-board comp ...

  8. 物联网(莹石云)WIFI一键配置原理分析(zz)

    最近打算做一款自己的无线传输模块用来实现光伏电站的数据接入,希望可以尽量简化接入流程,其中wifi密码的配置就是一个比较麻烦的事情,想到最近使用萤石摄像头时,wifi密码配置似乎很简单,他们是怎么做到 ...

  9. android wifi ANR问题分析总结

    android wifi ANR问题分析总结 1 看看main进程阻塞在那里? 2 调用关系的函数阻塞在那里? 3 最终阻塞函数的阻塞前的log以及状态

随机推荐

  1. xcode-build/version-bump

    # xcode-build-bump.sh # @desc Auto-increment the build number every time the project is run. # @usag ...

  2. form里两个submit按钮,在onsubmit中判断哪个被点

    记下别人的解决方法(有效): 方法1:(已验证过) <form name="form1" onsubmit="show()"> ..... < ...

  3. haproxy timeout server 46000 后台超时时间

    [root@wx03 ~]# sh ./1.sh Wed Jul 6 19:54:40 CST 2016 <html><body><h1>504 Gateway T ...

  4. 基于visual Studio2013解决C语言竞赛题之1086任务分配

        题目 解决代码及点评 /************************************************************************/ /* ...

  5. 南京三星面试准备3--数组&基础数据结构

    1.用递归颠倒一个栈. void PushToBottom(stack<int> &mystack,int num) { if(mystack.size()==0) { mysta ...

  6. Streaming编程实例(c,c++,python等)

    1.概述 Hadoop Streaming是Hadoop提供的一个编程工具,它允许用户使用任何可执行文件或者脚本文件作为Mapper和Reducer,例如: 采用shell脚本语言中的一些命令作为ma ...

  7. C keyword register 并讨论共同使用嵌入式汇编

    C keyword register 并讨论共同使用嵌入式汇编 register 是C99 的keyword之中的一个. register 是储存类型之中的一个.这里仅讨论register 储存类型. ...

  8. smartforms初始化

    smartforms  第一次打开的页面是和prd环境下的一样,需要跑一个程序才能编辑

  9. mysql基础: mysql列类型--字符串

    mysql列类型:整型   http://blog.csdn.net/jk110333/article/details/9342283 mysql列类型--时间和日期  http://blog.csd ...

  10. CentOS5.6下安装Oracle10G软件 【保留报错经验】

    CentOS5.6下安装Oracle10G ****************************************************************************** ...