一:加载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(); <span style="font-size:12px;color:#3333ff;">//初始化dhd_msg_level |= DHD_ERROR_VAL,给iface_name赋值为wlan</span>
- do {
- sema_init(&dhd_chipup_sem, 0);
- dhd_bus_reg_sdio_notify(&dhd_chipup_sem); <span style="color:#3333ff;">//注册sdio driver,支持如下图wifi列表,sdio驱动获取wifi列表的设备后调用 //dummy_probe() --> up(</span><span style="color: rgb(51, 51, 255); font-family: Arial, Helvetica, sans-serif;">dhd_chipup_sem</span><span style="color: rgb(51, 51, 255); font-family: Arial, Helvetica, sans-serif;">);</span><span style="color:#3333ff;">
- </span> dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON);
- if (down_timeout(&dhd_chipup_sem, <span style="color:#3333ff;">//2000ms超时等待<span style="font-family: Arial, Helvetica, sans-serif;">dhd_chipup_sem</span></span>
- 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(); <span style="color:#3333ff;">//详细分析看<三>,注册dhd_sdio驱动,最终会调用到dhd_net_attach();</span>
- 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, <span style="color:#3333ff;">//函数dhd_net_attach() --> up(&dhd_registration_sem);</span>
- 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)分析
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