BCM wifi分析
一个:载入中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分析的更多相关文章
- Android WIFI 分析(二)
本文介绍Wifi 分析线路二:在Setting中打开WiFi功能.扫描网络以及连接网络的流程. WifiSettings 无线网络设置界面 WifiEnabler 相当于无线网络设置开关 WifiDi ...
- Android WIFI 分析(一)
本文基于<深入理解Android WiFi NFC和GPS 卷>和 Android N 代码结合分析 WifiService 是 Frameworks中负责wifi功能的核心服务,它主 ...
- BCM wifi驱动学习
BCMwifi驱动学习 一.wifi详解1 1.代码路径:Z:\home\stonechen\svn\TD550_X\TD550\3rdparty\wifi\BCM43362\special\bcmd ...
- Wifiner for Mac(WiFi 状况分析工具)破解版安装
1.软件简介 Wifiner 是 macOS 系统上一款 Wifi 分析工具,仅需几次点击即可对您的 Wi-Fi 网络连接进行分析和故障排除.扫描您的 Wi-Fi 网络,获取包含交互式彩色编码热 ...
- 為什麼我的手機連Wi-Fi速度總是卡在75Mbps?Wi-Fi速度解惑~帶你一次看懂!
正文字体大小:大 中 小 為什麼我的手機連Wi-Fi速度總是卡在75Mbps?Wi-Fi速度解惑-帶你一次看懂! (2017-02-21 10:57:48) 转载▼ 标签: wi-fi速度 手機wi- ...
- 【转】分析器窗口 Profiler window
转自unity圣典: http://game.ceeger.com/Manual/ProfilerWindow.html http://game.ceeger.com/Manual/Profiler. ...
- 制作Cubie版OpenWRT(功能齐全,大小仅有11M)
Allwinner Sun4i/5i/6i/7i (sunxi) Various vendors are offering development boards / single-board comp ...
- 物联网(莹石云)WIFI一键配置原理分析(zz)
最近打算做一款自己的无线传输模块用来实现光伏电站的数据接入,希望可以尽量简化接入流程,其中wifi密码的配置就是一个比较麻烦的事情,想到最近使用萤石摄像头时,wifi密码配置似乎很简单,他们是怎么做到 ...
- android wifi ANR问题分析总结
android wifi ANR问题分析总结 1 看看main进程阻塞在那里? 2 调用关系的函数阻塞在那里? 3 最终阻塞函数的阻塞前的log以及状态
随机推荐
- PHP学习之-面向对象
PHP学习之-面向对象 1.什么是对象 "世界万物皆对象",一切可以被抽象出来的东西都是对象.像花,草.看不到的"概念"都是对象. 2.对象的基本组成 a.属性 ...
- 九度OnlineJudge之1014:排名
题目描述: 今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑每题的分值,所以并不是最后的排名.给定录取分数线,请你写程序找出最后通过分数线的考生,并将他 ...
- Thinkphp入门 一 (45)
原文:Thinkphp入门 一 (45) 什么是框架? 就是一堆代码的集合,这些代码可以有变量.常量.函数.类等等.这些代码彼此紧密联系,彼此有合作关系.里边还有设计模式:MVC.单例.工厂等等. 为 ...
- 在springmvc中配置jedis(转)
主要学习https://github.com/thinkgem/jeesite.一下代码均参考于此并稍作修改. 1.jedis 首先,需要添加jedis: <!--jedis--> < ...
- 特殊的Windows消息
WM_CREATE消息 该消息是Windows发送给视图的第一个消息.由于当应用程序框架调用Create函数时该消息就会被发送,而此时窗口创建还未完成,窗口还不可见,因此在控制函数OnCreate内部 ...
- isHiden和isVisible的区别(isVisible更可靠)
之前一直对isHiden和isVisible的区别比较模糊,都是乱用的.今天因需要仔细看了一下. 1.isHiden只是返回部件的隐藏属性,并不能表示部件当前的真实状态.比如A部件有个子部件B,而A处 ...
- Android菜鸟的成长笔记(12)——Handler、Loop、MessageQueue
原文:[置顶] Android菜鸟的成长笔记(12)——Handler.Loop.MessageQueue 当一个程序第一次启动时,Android会启动一条主线程(Main Thread),主线程主要 ...
- Swift - 复杂数据类型说明(数组,字典,结构体,枚举)
1,数组 - Array 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 var types ...
- linux 配置 mail server
一.配置yum安装工具 ① 进入yum目录 [root@bj ~]# cd /etc/yum.repos.d ② 配置yum.repo [root@bj yum.repos.d]# cprhel- ...
- OpenJDK1.8.0 源码解析————HashMap的实现(二)
上一篇文章介绍了HashMap的一部分的知识,算是为下面HashMap的进一步学习做准备吧. 然后写的时候一直在思考的一个问题是,这方面的知识网上的资料也是一抓一大把,即使是这样我为什么还要花费时间去 ...