Linux USB-Wifi Driver

1. USB设备枚举过程

    设备在插入USB 接口到设备成功找到它自己的驱动这一过程为:当把USB 设备插到USB 接口上后,USB中央控制器会检测到有设备插入USB 接口了,Linux 内核会给设备分配一个数据结构来代表这个设备,Linux 会分配一个structusb_device 数据结构来代表该设备,该数据结构记录设备的一些属性及数据。并把该数据结构挂载到一个全局的USB 设备链上。在这一期间主机通过0号端点得知了设备的一些信息,并知道了设备的厂家号和产品号。然后到一个全局的USB驱动链上查找(通过调用驱动的probe函数来询问),看看哪个驱动程序支持的设备列表中有该设备的厂家号和产品号。当找到后设备就和驱动匹配上了。

 

2. 关键数据结构

1) structcfg80211_ops :backend description forwireless configuration
2) struct wiphy:wireless hardware description

3) struct ieee80211_ops:callbacks frommac80211 to the driver

4) struct ieee80211_hw:hardwareinformation and state

5) struct ieee80211_channel:channeldefinition

6) struct usb_driver:identifies USBinterface driver to usbcore

 

 3.USB-Wifi驱动架构

   USB-Wifi驱动架构如下图所示:

 

 1) ieee802.11 协议层

    Linux Kernel中有ieee802.11 协议子层,各个不同型号的硬件设备驱动程序都是实现ieee80211_ops数据结构中的函数,例如打开是start()函数,发送是tx()函数,关闭是stop()函数,睡眠是suspend函数,唤醒是resume函数等。

    其代码位于: kernel/net/mac80211

2) USB无线网卡驱动层

    由上图可见,USB无线网卡驱动层位于USB与802.11协议层之间,为了使其可正常工作,它必须搞好上下级关系:

    a) 向USB Core注册USB驱动,通过USB通道收发数据

     b)向ieee802.11注册ieee80211_ops,以供ieee80211随时召唤,然后通过USB通道进行数据传输

       

3.1 向USBCore注册USB驱动      

      向USB Core注册USB驱动,通过USB通道收发数据,如我的代码为:      

             kernel/drivers/net/wireless/ath/ath9k/hif_usb.c

[cpp]  viewplain copy
  1. static struct usb_driver ath9k_hif_usb_driver //USB 驱动  
  2.     .name KBUILD_MODNAME,  
  3.     .probe ath9k_hif_usb_probe,  
  4.     .disconnect ath9k_hif_usb_disconnect,  
  5. #ifdef CONFIG_PM  
  6.     .suspend ath9k_hif_usb_suspend,  
  7.     .resume ath9k_hif_usb_resume,  
  8.     .reset_resume ath9k_hif_usb_resume,  
  9. #endif  
  10.     .id_table ath9k_hif_usb_ids,  
  11.     .soft_unbind 1,  
  12. };  
  13.   
  14. int ath9k_hif_usb_init(void 
  15.  
  16.     return usb_register(&ath9k_hif_usb_driver); // 把driver注册到USB驱动链中  
  17.  
  18.   
  19. void ath9k_hif_usb_exit(void 
  20.  
  21.     usb_deregister(&ath9k_hif_usb_driver);  // 把driver从USB驱动链中删除  
  22.  

    

3.2向ieee802.11注册ieee80211_ops

     向ieee802.11注册ieee80211_ops,以供ieee80211随时召唤,然后通过USB通道进行数据传输,如我的代码为:
在kernel/drivers/net/wireless/ath/ath9k/htc_drv_main.c中定义了ath9k_htc_ops,其详细定义如下: 

[cpp]  viewplain copy
  1. struct ieee80211_ops ath9k_htc_ops  
  2.  .tx                 ath9k_htc_tx,  
  3.  .start              ath9k_htc_start,  
  4.  .stop               ath9k_htc_stop,  
  5.  .add_interface      ath9k_htc_add_interface,  
  6.  .remove_interface   ath9k_htc_remove_interface,  
  7.  .config             ath9k_htc_config,  
  8.  .configure_filter   ath9k_htc_configure_filter,  
  9.  .sta_add            ath9k_htc_sta_add,  
  10.  .sta_remove         ath9k_htc_sta_remove,  
  11.  .conf_tx            ath9k_htc_conf_tx,  
  12.  .bss_info_changed   ath9k_htc_bss_info_changed,  
  13.  .set_key            ath9k_htc_set_key,  
  14.  .get_tsf            ath9k_htc_get_tsf,  
  15.  .set_tsf            ath9k_htc_set_tsf,  
  16.  .reset_tsf          ath9k_htc_reset_tsf,  
  17.  .ampdu_action       ath9k_htc_ampdu_action,  
  18.  .sw_scan_start      ath9k_htc_sw_scan_start,  
  19.  .sw_scan_complete   ath9k_htc_sw_scan_complete,  
  20.  .set_rts_threshold  ath9k_htc_set_rts_threshold,  
  21.  .rfkill_poll        ath9k_htc_rfkill_poll_state,  
  22.  .set_coverage_class ath9k_htc_set_coverage_class,  
  23.  .set_bitrate_mask   ath9k_htc_set_bitrate_mask,  
  24. };  
  25.   
  26.    

 

      ath9k_htc_ops注册流程如下图所示:

      

   ieee80211_alloc_hw()函数是即分配了802.11协议层需要的内存结构,又顺便分配了驱动的私有数据结构,该函数分配的内存结构如下图所示: 

[cpp]  viewplain copy
  1.   

 

4. Wifi工作流程

4.1 Wifi打开基本流程

   Wifi打开基本流程如下图所示:

 

4.2Wifi关闭基本流程

     Wifi关闭基本流程如下图所示:

 

 

4.3Wifi待机和唤醒流程

 

 

 

 5.注册ieee80211_class

 

   其详细代码如下:

net/wireless/sysfs.c

[cpp]  viewplain copy
  1. struct class ieee80211_class  
  2.     .name "ieee80211" 
  3.     .owner THIS_MODULE,  
  4.     .dev_release wiphy_dev_release,  
  5.     .dev_attrs ieee80211_dev_attrs,  
  6. #ifdef CONFIG_HOTPLUG  
  7.     .dev_uevent wiphy_uevent,  
  8. #endif  
  9.     .suspend wiphy_suspend,  // Suspend Wifi  
  10.     .resume wiphy_resume,    // Resume Wifi  
  11.     .ns_type &net_ns_type_operations,  
  12.     .namespace wiphy_namespace,  
  13. };  
  14.   
  15. int wiphy_sysfs_init(void 
  16.  
  17.     return class_register(&ieee80211_class);  
  18.  
  19.   
  20. void wiphy_sysfs_exit(void 
  21.  
  22.     class_unregister(&ieee80211_class);  
  23.  

它需要调用的structcfg80211_ops定义如下:

net/mac80211/cfg.c

[cpp]  viewplain copy
  1. struct cfg80211_ops mac80211_config_ops  
  2.     .add_virtual_intf ieee80211_add_iface,  
  3.     .del_virtual_intf ieee80211_del_iface,  
  4.     .change_virtual_intf ieee80211_change_iface,  
  5.     .add_key ieee80211_add_key,  
  6.     .del_key ieee80211_del_key,  
  7.     .get_key ieee80211_get_key,  
  8.     .set_default_key ieee80211_config_default_key,  
  9.     .set_default_mgmt_key ieee80211_config_default_mgmt_key,  
  10.     .add_beacon ieee80211_add_beacon,  
  11.     .set_beacon ieee80211_set_beacon,  
  12.     .del_beacon ieee80211_del_beacon,  
  13.     .add_station ieee80211_add_station,  
  14.     .del_station ieee80211_del_station,  
  15.     .change_station ieee80211_change_station,  
  16.     .get_station ieee80211_get_station,  
  17.     .dump_station ieee80211_dump_station,  
  18.     .dump_survey ieee80211_dump_survey,  
  19. #ifdef CONFIG_MAC80211_MESH  
  20.     .add_mpath ieee80211_add_mpath,  
  21.     .del_mpath ieee80211_del_mpath,  
  22.     .change_mpath ieee80211_change_mpath,  
  23.     .get_mpath ieee80211_get_mpath,  
  24.     .dump_mpath ieee80211_dump_mpath,  
  25.     .update_mesh_config ieee80211_update_mesh_config,  
  26.     .get_mesh_config ieee80211_get_mesh_config,  
  27.     .join_mesh ieee80211_join_mesh,  
  28.     .leave_mesh ieee80211_leave_mesh,  
  29. #endif  
  30.     .change_bss ieee80211_change_bss,  
  31.     .set_txq_params ieee80211_set_txq_params,  
  32.     .set_channel ieee80211_set_channel,  
  33.     .suspend ieee80211_suspend,  
  34.     .resume ieee80211_resume,  
  35.     .scan ieee80211_scan,  
  36.     .sched_scan_start ieee80211_sched_scan_start,  
  37.     .sched_scan_stop ieee80211_sched_scan_stop,  
  38.     .auth ieee80211_auth,  
  39.     .assoc ieee80211_assoc,  
  40.     .deauth ieee80211_deauth,  
  41.     .disassoc ieee80211_disassoc,  
  42.     .join_ibss ieee80211_join_ibss,  
  43.     .leave_ibss ieee80211_leave_ibss,  
  44.     .set_wiphy_params ieee80211_set_wiphy_params,  
  45.     .set_tx_power ieee80211_set_tx_power,  
  46.     .get_tx_power ieee80211_get_tx_power,  
  47.     .set_wds_peer ieee80211_set_wds_peer,  
  48.     .rfkill_poll ieee80211_rfkill_poll,  
  49.     CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)  
  50.     .set_power_mgmt ieee80211_set_power_mgmt,  
  51.     .set_bitrate_mask ieee80211_set_bitrate_mask,  
  52.     .remain_on_channel ieee80211_remain_on_channel,  
  53.     .cancel_remain_on_channel ieee80211_cancel_remain_on_channel,  
  54.     .mgmt_tx ieee80211_mgmt_tx,  
  55.     .mgmt_tx_cancel_wait ieee80211_mgmt_tx_cancel_wait,  
  56.     .set_cqm_rssi_config ieee80211_set_cqm_rssi_config,  
  57.     .mgmt_frame_register ieee80211_mgmt_frame_register,  
  58.     .set_antenna ieee80211_set_antenna,  
  59.     .get_antenna ieee80211_get_antenna,  
  60.     .set_ringparam ieee80211_set_ringparam,  
  61.     .get_ringparam ieee80211_get_ringparam,  
  62. }; 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值