One: in-load WiFi driver module
Calling functions in Hardware/libhardware_legacy/wifi/wifi.c
Insmod (Driver_module_path, Driver_module_arg)
Of
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"
Two:WiFi driver Module execution
WiFi Driver Entry dhd_module_init (void) ... dhd_linux.c
Dhd_module_init (void) {int error = 0;dhd_trace (("%s:enter\n", __function__)); Wl_android_init ();//Initialize Dhd_msg_level |= Dhd_error_val, assigning Iface_name to Wlando {sema_init (&dhd_chipup_sem, 0);d hd_bus_reg_sdio_notify (&dhd_chipup_ SEM);//Register SDIO driver, support for example with WiFi list, Sdio drive to get WiFi list device after call Dummy_probe ()--Up (Dhd_chipup_sem) dhd_customer_g Pio_wlan_ctrl (wlan_power_on); if (Down_timeout (&dhd_chipup_sem,//2000ms timeout wait msecs_to_jiffies (powerup_wait_ms)) = = 0) {Dhd_bus_unreg_sdio_ Notify (); chip_up = 1;break;} Dhd_error ("\nfailed to power up Wi-Fi chip, retry again (%d left) **\n\n", retry+1));d hd_bus_unreg_sdio_notify ();d hd_ 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"), retur N-enodev;} Sema_init (&dhd_registration_sem, 0); error = Dhd_bus_register ();//specific analysis see < three;, register Dhd_sdio driver, will finally call to 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 do sync up exit from DHD insmod and * Kernel MMC Sdio Device Callback Registration */if ((down_timeout (&dhd_registration_sem,//function 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;}
Three:dhd_bus_register (void) ... dhd_sdio.c analysis
Bcmsdh_register (&dhd_sdio) calls Pci_register_driver (&bcmsdh_pci_driver) to register a PCI type driver. Assuming that the match to Bcmsdh_pci_devid will be called to Bcmsdh_pci_probe---Drvinfo.attach--and Drvinfo.attach, finally call to Dhd_sdio->dhdsdio_ Probe, next analyze the dhdsdio_probe function
Four:dhdsdio_probe () ... dhd_sdio.c Analysis
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 *//create 3 threads, each dhd_watchdog_thread, DHD_DPC, DHD_SYSIOCIF (! 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 Interr Upts (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__)); Get WiFi MAC address 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) {//update module firmware, NVRAM, using Filp_open, Kernel_read, filp_close for file system operation if (ret = Dhd_bus_start (BUS->DHD))! = 0) {Dhd_error (("%s:dhd_bus_start failed\n", __function__)); goto fail;}} /* Ok, 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;}
Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.
BCM WiFi Analysis