您的位置:首页 > 移动开发 > Android开发

[RK3288][Android6.0] USB WiFi驱动流程小结

2017-08-31 17:23 801 查看
Platform: Rockchip

OS: Android 6.0

Kernel: 3.10.92

使用的是RTL8188EU, usb接口。

这是网友寄给我的模块,正好没调试过rtl8188eu,又是usb接口,遗憾的是只改了dts配置就能工作了。

rtl8188eu驱动路径:

kernel/drivers/net/wireless/rockchip_wlan/rtl8188eu/

驱动加载过程:

rockchip_wifi_init_module_rtkwifi -> usb_intf.c

  get_wifi_chip_type //之前有分析过ap6335,这里有互斥判断,因此ap6xxx和rtlxxx只能加载其中一个

  rockchip_wifi_power rfkill-wlan.c  //wlan电源模块调用

  rtw_drv_entry ->

    dump_drv_version //打印驱动版本

    rtw_drv_proc_init //proc/net下创建目录rtl8188eu,可查询的内容定义在drv_proc_hdls数组中

    rtw_ndev_notifier_register //网络设备状态变化会收到通知,对应的回调函数是rtw_ndev_notifier_call()

    usb_register //注册到usb core中管理

    //注册usb枚举成功会调用其probe(),这里对应的是rtw_drv_init()

    rtw_drv_init ->

      rtw_usb_if1_init ->
        rtw_zvmalloc  //分配adapter

        rtw_init_netdev -> //注册网络设备需要构建一个struct net_device

          rtw_alloc_etherdev //分配struct net_device

          pnetdev->netdev_ops = &rtw_netdev_ops;
//对应net_device_ops,后续的open/start/ioctl都会通过它调用
rtw_wdev_alloc-> //和80211协议相关,这里即cfg80211
 wiphy_new //分配一个cfg80211框架需要的struct wiphy,对应ops是rtw_cfg80211_ops
 set_wiphy_dev
 wiphy_register  //注册
   rtw_set_hal_ops-> //中间还加了层hal
     rtl8188eu_set_hal_ops ->
       pHalFunc->hal_init = &rtl8188eu_hal_init; //各个函数指针定义
   rtw_hal_read_chip_info//获取efuse,eeprom数据和mac address
   rtw_init_drv_sw//初始化各个默认值
   rtw_macaddr_cfg//set mac addr

      rtw_drv_register_netdev ->

        _rtw_drv_register_netdev ->

          register_netdev //注册网络设备

      hostapd_mode_init //hostapd初始化及注册

打开流程:

netdev_open -> os_intf.c

  _netdev_open ->

    rtw_hal_init ->

      padapter->HalFunc.hal_init -> //加载驱动的时候有初始化

        rtl8188eu_hal_init ->

          _InitPowerOn_8188EU //init power

          _InitRFType  //设置RF类型

          rtl8188e_FirmwareDownload //下载firmware

      init_hw_mlme_ext -> //初始化mlme

        init_hw_mlme_ext ->

          rtw_hal_set_chnl_bw ->

            padapter->HalFunc.set_chnl_bw_handler ->

              PHY_SetSwChnlBWMode8188E

    rtw_start_drv_threads

    padapter->intf_start ->

      usb_intf_start -> //start usb interface

        rtw_hal_inirp_init ->

          rtl8188eu_inirp_init ->

            usb_read_port ->

              rtl8188eu_init_recvbuf //初始化接收buffer

              usb_fill_bulk_urb //填充urb,usb模块的标准做法,对应的触发函数是usb_read_port_complete()

              usb_submit_urb //然后再提交到usb模块

接收数据流程:

usb_read_port_complete -> usb中断触发会调用

  skb_put //准备数据

  skb_queue_tail //收到的数据入队,队列是rx_skb_queue,接下来tasklet会处理

  tasklet_schedule -> //tasklet名字是recv_tasklet

    rtl8188eu_recv_tasklet -> Rtl8188eu_recv.c

      skb_dequeue //循环取出除队列rx_skb_queue里的内容,取完为止

      recvbuf2recvframe  -> //数据转换成frame

        rtw_recv_entry ->

          recv_func -> 

            recv_func_prehandle ->

              validate_recv_frame -> //根据wifi type分别处理

                validate_recv_data_frame -> 比如WIFI_DATA_TYPE

      skb_queue_tail  //入到队列free_recv_skb_queue中

   rtw_read_port //继续读

没看出来数据是如何处理后往上送的

发送:

ndo_start_xmit ->

  rtw_xmit_entry ->

    _rtw_xmit_entry ->

      rtw_xmit ->

        rtw_hal_xmit ->

          padapter->HalFunc.hal_xmit ->

            rtl8188eu_hal_xmit ->

              pre_xmitframe ->

                rtw_alloc_xmitbuf

                rtw_xmitframe_enqueue -> 

                  rtw_xmit_classifier ->

                    rtw_list_insert_tail //入队

最终通过usb部分因为代码太纷杂就没继续花时间看了,虽然xmit thread没有编译进去,不过过程可以做参考。

rtw_xmit_thread ->

  rtw_hal_xmit_thread_handler ->

    padapter->HalFunc.xmit_thread_handler ->

      rtl8188eu_xmit_buf_handler ->

        dequeue_pending_xmitbuf //取buffer

        rtw_write_port ->

          _rtw_write_port ->

            pintfhdl->io_ops._write_port ->
//这里用来不同接口实现,如sdio/usb

              usb_write_port -> //通过usb协议写

参考:
RLT USB WiFi驱动源码分析(Type A)
和菜鸟一起学linux之wifi学习记录


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: