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. }; 
### 查找 USB-WIFI232-B2 的硬件规格及驱动程序 对于特定型号的 USB 设备如 USB-WIFI232-B2,获取其详细的硬件规格和对应的驱动程序通常涉及几个方面的工作。 #### 确认设备信息 为了确保能够找到正确的驱动程序和支持文档,首先要确认设备的具体参数。可以通过命令 `lsusb` 来查看已连接至系统的 USB 设备列表及其供应商ID (Vendor ID, VID) 和产品ID (Product ID, PID)[^2]。这一步骤有助于精确匹配所需的资源。 #### 获取硬件规格 关于 USB-WIFI232-B2 这款产品的具体技术细节,建议访问制造商官方网站或查阅随附的产品手册。一般而言,这类 Wi-Fi 适配器会提供如下几项重要指标: - 支持的标准(例如 IEEE 802.11n) - 工作频段(2.4 GHz 或者双频) - 数据传输速率上限 - 接口类型(USB 2.0/3.0) 然而,由于缺乏直接针对此型号的确切资料链接,可能需要通过搜索引擎进一步查询或者联系销售商获取更详尽的信息。 #### 寻找并安装合适的驱动程序 当涉及到 Linux 平台上的兼容性和驱动加载时,可以采取以下措施来寻找适合的驱动解决方案: 1. **检查内建支持**:现代Linux发行版往往已经预装了许多常见的无线网卡驱动。尝试插入设备后运行 `dmesg | grep usb` 检查系统日志中是否有任何有关新接入设备的消息。 2. **第三方源码编译**:如果官方并未提供现成的支持,则可以从开源社区寻求帮助。像 Realtek、Ralink 等厂商可能会公开部分芯片组的相关驱动代码库。以MT7601U为例,在指定路径下的C文件定义了一系列受支持的VID/PID组合[^3]。因此,若能确定USB-WIFI232-B2 使用相同系列的控制器,那么按照相似的方式调整配置可能是可行的办法之一。 3. **利用现有项目成果**:有时候其他开发者也会分享他们为不同品牌但基于同一套方案设计出来的固件更新工具或是改进后的驱动版本。GitHub等平台上不乏这样的实例可供借鉴。 ```bash # 示例:假设找到了适用于该设备的驱动包,并放置于当前目录下解压 tar -xf driver-package.tar.gz cd driver-directory/ make && sudo make install ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值