1. kernel/arch/arm/mach-xxx/Baord-product-xx.c 里面定义了wifi的平台设备 ,
static struct platform_device xx_wifi = {
.name = "bcm4330_wlan",
.id = -1,
.dev = {
.platform_data = &xx_wifi_control,
},
};
厂商的驱动 是
static struct platform_driver wifi_device = {
.probe = wifi_probe,
.remove = wifi_remove,
.suspend = wifi_suspend,
.resume = wifi_resume,
.driver = {
.name = "bcm4330_wlan",
}
};
首先,厂商的驱动在加载过程中会去 通过GPIO 给wlan芯片 上电.
然后,上面的驱动和设备,他们通过设备模型 match 成功(根据.name字段) 去调用wifi_probe,然后去调用 xx_wifi_set_carddetect
2. xx_wifi_set_carddetect 最中会调用mmc 里面的mmc_rescan, 给host 上电,sdio主要初始化主要工作是在mmc_attach_sdio()中完成, 匹配电压,分配mmc_card数据结构,然后吧该结构add 到bus
3. 经过mmc_rescan后,就有了sdio_funcs (是个device) 在设备模型中了,在wlan driver 的moudle init 时 dhd_module_init() --> dhd_bus_register(), 去注册 sdio_driver bcmsdh_sdmmc_driver, 这过程中,会吧 dhd_sdio {dhdsdio_probe,dhdsdio_disconnect } 注册,当sdio_driver和 sdio_funcs 匹配成功后,会去调用 bcmsdh_sdmmc_probe
--> dhdsdio_probe
4. dhdsdio_probe 会去,new net_device 和attach操作,吧该网络设备和wlan 设备绑定。注意这个时候 因为 dhd_download_fw_on_driverload == false,所以不会去调用 dhd_bus_start()
/* if firmware path present try to download and bring up bus */
if (dhd_download_fw_on_driverload && (ret = dhd_bus_start(bus->dhd)) != 0) {
DHD_ERROR(("%s: dhd_bus_start failed
", __FUNCTION__));
if (ret == BCME_NOTUP)
goto fail;
}
FW 加载过程,
1.start supplicant之前 relaod fw, 通过moudle参数机制,吧fw 路径更新到下面sys 文件
/sys/module/wlan/parameters/fwpath
case CMD_START_SUPPLICANT:
try {
mNwService.wifiFirmwareReload(mInterfaceName, "STA");
} catch (Exception e) {
loge("Failed to reload STA firmware " + e);
// continue
}
try {
//A runtime crash can leave the interface up and
//this affects connectivity when supplicant starts up.
//Ensure interface is down before a supplicant start.
mNwService.setInterfaceDown(mInterfaceName);
//Set privacy extensions
mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
} catch (RemoteException re) {
loge("Unable to change interface settings: " + re);
} catch (IllegalStateException ie) {
loge("Unable to change interface settings: " + ie);
}
mSupConfig.checkSupplicantConf();
2. supplicant开启过程中,会去 open刚刚new的网络设备,最终会调用到dhd_open(), 真正去load fw. dhdh_open() -> dhd_bus_start()
详细过程 wpa_supplicant_init_iface() --> wpa_drv_init() --> wpa_driver_nl80211_finish_drv_init() --> linux_set_iface_flags() --> ioctl(sock, SIOCSIFFLAGS, &ifr) ...... ...... >
dev_ifsioc() in dev.c --> __dev_change_flags() --> __dev_open()