模块加载
dhd_module_init()
->wl_android_init() |设置wifi名称 wlan0
->dhd_customer_gpio_wlan_ctrl(2)
-> bcm_wlan_power_off()在platform device端
-> bcm_wlan_power_on()在platform device端
->wl_android_wifictrl_func_add() //if defined CONFIG_WIFI_CONTROL_FUNC
->wifi_add_dev()
->platform_driver_register() |name “bcmdhd_wlan” or “bcm4329_wlan”
->wifi_probe()
->wifi_set_power(1,0) |power on
->wifi_set_carddetect() |sdio detect
->dhd_bus_register()
->bcmsdh_register()
->sdio_function_init() // 申请gInstance
->sdio_register_driver(&bcmsdh_sdmmc_driver)
->bcmsdh_sdmmc_probe()
->bcmsdh_probe()
-> down_timeout(&dhd_registration_sem)//等待sdio_register_driver callback called and made driver attach
->wl_android_post_init() //if defined WL_CFG80211
->dhd_dev_init_ioctl()
->dhd_preinit_ioctls()
模块卸载
dhd_module_cleanup()
-> dhd_bus_unregister()
-> bcmsdh_unregister()
-> sdio_function_cleanup()
-> sdio_unregister_driver(&bcmsdh_sdmmc_driver)
-> driver_unregister()
-> kfree(gInstance)
-> wl_android_wifictrl_func_del() //if defined CONFIG_WIFI_CONTROL_FUNC
-> wl_android_exit()
-> dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF)
bcmsdh_sdmmc_probe 执行
---------------------------
在sdio_register_driver注册成功后会调用:
bcmsdh_sdmmc_driver->bcmsdh_sdmmc_probe() 可以在此函数中打印更多的信息
bcmsdh_sdmmc_probe()
->bcmsdh_probe(&func->dev) //bcmsdh_probe(&sdmmc_dev) 针对于Function 2
->osl_attach ?? (linux_osl.c)
->bcmsdh_attach(osh, (void *)r->start,,(void **)®s, irq) //关键全局变量l_bcmsdh
->sdioh_attach() (bcmsdh_sdmmc.c)
->sdio_claim_host(gInstance->func[1])//初始化F1
->sdio_claim_host(gInstance->func[2])//初始化F2
->sdioh_sdmmc_card_enablefuncs(sd) 读取CIS等信息,使能F1
->bcmsdh_query_device(sdh) //Read the vendor/device ID from the CIS
->drvinfo.attach() 也就是调用dhdsdio_probe() (dhd_sdio.c)
->dhd_common_init 初始化debug等级信息,以及Firmware和nvram文件路径设置为0
//->dhd_osl_attach()
->dhdsdio_probe_attach() //attempt to attach to the dongle 读F0~F2 CIS信息
->dhd_attach() //Attach to the dhd/OS/network interface
->dhdsdio_probe_malloc() //Allocate memory for receiving or data buffer.
->dhdsdio_probe_init()
->bcmsdh_intr_disable() //Disable the interrupt
->bcmsdh_intr_reg(,dhdsdio_isr,) //Register interrupt callback
->dhd_bus_start() //if firmware path present try to download and bring up bus, 启动watchdog
->dhd_bus_download_firmware()
->dhd_bus_init
->dhd_prot_init
->dhd_preinit_ioctls //初始化PM mode等。
->dhd_net_attach(bus->dhd,0) // have the per-port tell the stack we're open for business
->register_netdev(net)
设置接口函数dhd_open,dhd_close等
注册netdev_ops = dhd_ops_pri
net->ndo_do_ioctl = dhd_ioctl_entry;
注册net->wireless_handlers = wl_iw_handler_def
设置g_dhd_registration_status
->register_netdevice()
up信号量dhd_registration_sem。此时dhd_module_init()将返回正确!!
----------------------------------
中断处理相关:
dhdsdio_isr
bcmsdh_intr_disable()
sdioh_sdmmc_devintr_off 利用host->ops->enable_sdio_irq进行操作?具体什么函数还需要查找。
dhdsdio_dpc //主要操作dhd_bus_t结构体
dhdsdio_clkctl
dhdsdio_hostmail
dhdsdio_readframes //如果需要就读
dhd_bcmsdh_recv_buf //Read Ahead
check the HD+SW heaser.
check the channel P20(Porting Guide)
dhd_bcmsdh_recv_buf //Read PKG
----------------------------------
SIOCDEVPRIVATE 0x89F0
SIOCIWFIRST 0x8B00
SIOCIWLAST 0x8BFF
SIOCIWFIRSTPRIV 0x8BE0
SIOCIWLASTPRIV 0x8BFF
sock_ioctl()
(if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) ||
(if defined CONFIG_WEXT_CORE &&if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) )
->dev_ioctl()
If (cmd >= SIOCDEVPRIVATE &&cmd <= SIOCDEVPRIVATE + 15)
->dev_load(net, ifr.ifr_name);
->dev_ifsioc()
->ops->ndo_do_ioctl(dev, ifr, cmd)//执行dhd_ioctl_entry()函数
if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
-> wext_handle_ioctl(net, &ifr, cmd, arg);
->wext_ioctl_dispatch()
->dev_load(net, ifr->ifr_name);
->wireless_process_ioctl (net, ifr, cmd, info, standard, private);
//new api
->handler = get_handler(dev, cmd); //From net->wireless_handlers =wl_iw_handler_def
->ioctl_standard_call() | ioctl_private_call
//old api
->dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd)
IOControl
dhd_ioctl_entry 在dhd_net_attach中注册,dhd_ops_pri或dhd_ops_virt中
如果是标准的IOCTOL [SIOCIWFIRST, SIOCIWLAST],则调用wl_iw_ioctl
否则,拷贝wl_ioctl_t到内核空间(copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t)))
如果是DHD_IOCTL_MAGIC,不需要dongle执行,则执行dhd_ioctl //check for local dhd ioctl and handle it
否则 dhd_prot_ioctl
检查目前状态是否为Pending,即上个命令是否执行完成。
dhdcdc_set_ioctl() //Set Command
dhdcdc_query_ioctl() //Query Command
加入CDC header
dhdcdc_msg
dhd_bus_txctl //发送
dhdsdio_clkctl //确认SDIO Clock,此时会产生中断。
dhd_bcmsdh_send_buf