BCM4329 Diver 分析

 

 

模块加载

 

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 **)&regs, 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等级信息,以及Firmwarenvram文件路径设置为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_pridhd_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

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值