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

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学习记录

你可能感兴趣的:(子类__WiFi)