Linux Wireless架構總結

來源:互聯網
上載者:User
文章目錄
  • 2.1 各層間關鍵資料介面
1.  無線網路驅動(ath9k_htc)

     ath9k_htc是一個基於USB介面的SoftMAC無線網路適配器。為了其驅動能正常工作,首先必須調用usb_register來註冊驅動定義的usb_driver,以藉助USB Core的力量來處理與USB協議相關的事件。其代碼如下:

static struct usb_driver ath9k_hif_usb_driver = {.name = KBUILD_MODNAME,.probe = ath9k_hif_usb_probe,.disconnect = ath9k_hif_usb_disconnect,#ifdef CONFIG_PM.suspend = ath9k_hif_usb_suspend,.resume = ath9k_hif_usb_resume,.reset_resume = ath9k_hif_usb_resume,#endif.id_table = ath9k_hif_usb_ids,.soft_unbind = 1,};

2. 關鍵資料結構

1) struct ieee80211_hw: 它包含802.11 PHY的配置硬體資訊。


2.1 各層間關鍵資料介面


3. USB無線適配器枚舉過程 

     當此基於USB介面的無線網路適配器被枚舉時,ath9k_hif_usb_probe將被調用。其調用流程如所示:


3.1 struct ieee80211_ops 執行個體 ath9k_htc_ops(驅動實現)

       ath9k_htc_ops: mac80211通過這些回呼函數回調driver的處理函數。ath9k_htc為了接受mac80211的管理,它必須首先向mac80211註冊,以申明自己的存在,從而可以接受mac80211的調用。

struct ieee80211_ops ath9k_htc_ops = {.tx                 = ath9k_htc_tx,  // 發送mac80211要求發送的幀.start              = ath9k_htc_start, // 第一個被attach到此硬體的net_device被enable之前被調用,之後,可以接收幀資料.stop               = ath9k_htc_stop,  // 最後一個被attach到此硬體的net_device被disable之後被調用,之後,不可以接收幀資料.add_interface      = ath9k_htc_add_interface, // 當一個被attach到此硬體的net_device被enable時被調用.remove_interface   = ath9k_htc_remove_interface, // 通知driver一個介面將要going down.config             = ath9k_htc_config,           // mac802.11調用它修改硬體設定.configure_filter   = ath9k_htc_configure_filter, // 配置裝置的接收過濾器.sta_add            = ath9k_htc_sta_add,.sta_remove         = ath9k_htc_sta_remove,.conf_tx            = ath9k_htc_conf_tx,.bss_info_changed   = ath9k_htc_bss_info_changed,.set_key            = ath9k_htc_set_key,.get_tsf            = ath9k_htc_get_tsf,.set_tsf            = ath9k_htc_set_tsf,.reset_tsf          = ath9k_htc_reset_tsf,.ampdu_action       = ath9k_htc_ampdu_action,.sw_scan_start      = ath9k_htc_sw_scan_start,.sw_scan_complete   = ath9k_htc_sw_scan_complete,.set_rts_threshold  = ath9k_htc_set_rts_threshold,.rfkill_poll        = ath9k_htc_rfkill_poll_state,.set_coverage_class = ath9k_htc_set_coverage_class,.set_bitrate_mask   = ath9k_htc_set_bitrate_mask,};

3.2 struct cfg80211_ops 執行個體 mac80211_config_ops(mac80211實現)  

   cfg80211_ops定義了無線配置的操作,在它的增加虛擬介面(ieee80211_add_iface)中,它將建立並註冊net_device。在mac80211中,其定義如下所示:

struct cfg80211_ops mac80211_config_ops = {.add_virtual_intf = ieee80211_add_iface, //使用給定的名字建立一個"虛擬介面",在wiphy的命名空間中建立net_device並返回.del_virtual_intf = ieee80211_del_iface, //刪除由ifindex指定的"虛擬介面".change_virtual_intf = ieee80211_change_iface,.add_key = ieee80211_add_key,.del_key = ieee80211_del_key,.get_key = ieee80211_get_key,.set_default_key = ieee80211_config_default_key,.set_default_mgmt_key = ieee80211_config_default_mgmt_key,.add_beacon = ieee80211_add_beacon,.set_beacon = ieee80211_set_beacon,.del_beacon = ieee80211_del_beacon,.add_station = ieee80211_add_station,.del_station = ieee80211_del_station,.change_station = ieee80211_change_station,.get_station = ieee80211_get_station,.dump_station = ieee80211_dump_station,.dump_survey = ieee80211_dump_survey,#ifdef CONFIG_MAC80211_MESH.add_mpath = ieee80211_add_mpath,.del_mpath = ieee80211_del_mpath,.change_mpath = ieee80211_change_mpath,.get_mpath = ieee80211_get_mpath,.dump_mpath = ieee80211_dump_mpath,.update_mesh_config = ieee80211_update_mesh_config,.get_mesh_config = ieee80211_get_mesh_config,.join_mesh = ieee80211_join_mesh,.leave_mesh = ieee80211_leave_mesh,#endif.change_bss = ieee80211_change_bss,.set_txq_params = ieee80211_set_txq_params,.set_channel = ieee80211_set_channel,.suspend = ieee80211_suspend,.resume = ieee80211_resume,.scan = ieee80211_scan,.sched_scan_start = ieee80211_sched_scan_start,.sched_scan_stop = ieee80211_sched_scan_stop,.auth = ieee80211_auth,.assoc = ieee80211_assoc,.deauth = ieee80211_deauth,.disassoc = ieee80211_disassoc,.join_ibss = ieee80211_join_ibss,.leave_ibss = ieee80211_leave_ibss,.set_wiphy_params = ieee80211_set_wiphy_params,.set_tx_power = ieee80211_set_tx_power,.get_tx_power = ieee80211_get_tx_power,.set_wds_peer = ieee80211_set_wds_peer,.rfkill_poll = ieee80211_rfkill_poll,CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd).set_power_mgmt = ieee80211_set_power_mgmt,.set_bitrate_mask = ieee80211_set_bitrate_mask,.remain_on_channel = ieee80211_remain_on_channel,.cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,.mgmt_tx = ieee80211_mgmt_tx,.mgmt_tx_cancel_wait = ieee80211_mgmt_tx_cancel_wait,.set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,.mgmt_frame_register = ieee80211_mgmt_frame_register,.set_antenna = ieee80211_set_antenna,.get_antenna = ieee80211_get_antenna,.set_ringparam = ieee80211_set_ringparam,.get_ringparam = ieee80211_get_ringparam,}

3.3 struct iw_handler_def  執行個體 cfg80211_wext_handler(wireless實現)

      cfg80211_wext_handler實現了wext要求的ioctl操作,將通過net_device->wireless_handlers->standard[ioctl cmd- SIOCIWFIRST]來進行調用。在net/wireless/wext-compat.c中的定義如下所示:

static const iw_handler cfg80211_handlers[] = {[IW_IOCTL_IDX(SIOCGIWNAME)]= (iw_handler) cfg80211_wext_giwname,[IW_IOCTL_IDX(SIOCSIWFREQ)]= (iw_handler) cfg80211_wext_siwfreq,[IW_IOCTL_IDX(SIOCGIWFREQ)]= (iw_handler) cfg80211_wext_giwfreq,[IW_IOCTL_IDX(SIOCSIWMODE)]= (iw_handler) cfg80211_wext_siwmode,[IW_IOCTL_IDX(SIOCGIWMODE)]= (iw_handler) cfg80211_wext_giwmode,[IW_IOCTL_IDX(SIOCGIWRANGE)]= (iw_handler) cfg80211_wext_giwrange,[IW_IOCTL_IDX(SIOCSIWAP)]= (iw_handler) cfg80211_wext_siwap,[IW_IOCTL_IDX(SIOCGIWAP)]= (iw_handler) cfg80211_wext_giwap,[IW_IOCTL_IDX(SIOCSIWMLME)]= (iw_handler) cfg80211_wext_siwmlme,[IW_IOCTL_IDX(SIOCSIWSCAN)]= (iw_handler) cfg80211_wext_siwscan,[IW_IOCTL_IDX(SIOCGIWSCAN)]= (iw_handler) cfg80211_wext_giwscan,[IW_IOCTL_IDX(SIOCSIWESSID)]= (iw_handler) cfg80211_wext_siwessid,[IW_IOCTL_IDX(SIOCGIWESSID)]= (iw_handler) cfg80211_wext_giwessid,[IW_IOCTL_IDX(SIOCSIWRATE)]= (iw_handler) cfg80211_wext_siwrate,[IW_IOCTL_IDX(SIOCGIWRATE)]= (iw_handler) cfg80211_wext_giwrate,[IW_IOCTL_IDX(SIOCSIWRTS)]= (iw_handler) cfg80211_wext_siwrts,[IW_IOCTL_IDX(SIOCGIWRTS)]= (iw_handler) cfg80211_wext_giwrts,[IW_IOCTL_IDX(SIOCSIWFRAG)]= (iw_handler) cfg80211_wext_siwfrag,[IW_IOCTL_IDX(SIOCGIWFRAG)]= (iw_handler) cfg80211_wext_giwfrag,[IW_IOCTL_IDX(SIOCSIWTXPOW)]= (iw_handler) cfg80211_wext_siwtxpower,[IW_IOCTL_IDX(SIOCGIWTXPOW)]= (iw_handler) cfg80211_wext_giwtxpower,[IW_IOCTL_IDX(SIOCSIWRETRY)]= (iw_handler) cfg80211_wext_siwretry,[IW_IOCTL_IDX(SIOCGIWRETRY)]= (iw_handler) cfg80211_wext_giwretry,[IW_IOCTL_IDX(SIOCSIWENCODE)]= (iw_handler) cfg80211_wext_siwencode,[IW_IOCTL_IDX(SIOCGIWENCODE)]= (iw_handler) cfg80211_wext_giwencode,[IW_IOCTL_IDX(SIOCSIWPOWER)]= (iw_handler) cfg80211_wext_siwpower,[IW_IOCTL_IDX(SIOCGIWPOWER)]= (iw_handler) cfg80211_wext_giwpower,[IW_IOCTL_IDX(SIOCSIWGENIE)]= (iw_handler) cfg80211_wext_siwgenie,[IW_IOCTL_IDX(SIOCSIWAUTH)]= (iw_handler) cfg80211_wext_siwauth,[IW_IOCTL_IDX(SIOCGIWAUTH)]= (iw_handler) cfg80211_wext_giwauth,[IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= (iw_handler) cfg80211_wext_siwencodeext,[IW_IOCTL_IDX(SIOCSIWPMKSA)]= (iw_handler) cfg80211_wext_siwpmksa,  [IW_IOCTL_IDX(SIOCSIWPRIV)] = (iw_handler)cfg80211_wext_setpriv};const struct iw_handler_def cfg80211_wext_handler = {.num_standard= ARRAY_SIZE(cfg80211_handlers),.standard= cfg80211_handlers,.get_wireless_stats = cfg80211_wireless_stats,}

4. 建立並註冊net_device

             當執行mac80211_config_ops-> ieee80211_add_iface時,它將建立net_device和對應的ieee80211_sub_if_data, 然後主要做了以下幾件事:

        1) 把net_device對應的名字增加到/sys/class/net/目錄下   

        2) 把新建立的net_device插入到init_net->dev_base_head中

        3) 通知上層協議,有一個新的net_device出現了,大家可以使用它了

        4) 把新建立的ieee80211_sub_if_data增加到ieee80211_local的interfaces列表中        

        其流程如所示:


        mac80211中定義的net_device_ops ieee80211_dataif_ops,以下這些方法,都有一個struct net_device參數。其具體定義如下:   

static const struct net_device_ops ieee80211_dataif_ops = {.ndo_open= ieee80211_open,              // net_device變換到 UP 時被調用.ndo_stop= ieee80211_stop,              // net_device變換到 Down 時被調用.ndo_uninit= ieee80211_teardown_sdata,    // 取消註冊或註冊失敗時調用.ndo_start_xmit= ieee80211_subif_start_xmit,  // 需要發送包時被調用.ndo_set_multicast_list = ieee80211_set_multicast_list,// 多播地址清單變化時被調用.ndo_change_mtu = ieee80211_change_mtu,        // 當使用者想改變一個裝置的MTU時被調用.ndo_set_mac_address = ieee80211_change_mac,        // mac地址需要改變時被調用.ndo_select_queue= ieee80211_netdev_select_queue, //當net_device支援多個發送隊列時,用來決定使用哪個隊列};

  mac80211中初始化net_device->netdev_ops:

static void ieee80211_if_setup(struct net_device *dev){ether_setup(dev);dev->priv_flags &= ~IFF_TX_SKB_SHARING;dev->netdev_ops = &ieee80211_dataif_ops;dev->destructor = free_netdev;}

5. 資料接收(Data RX)流程

   資料接收流程如所示:


IP層與TCP/UDP層介面定義如下:

static const struct net_protocol tcp_protocol = {.handler =tcp_v4_rcv,.err_handler =tcp_v4_err,.gso_send_check = tcp_v4_gso_send_check,.gso_segment =tcp_tso_segment,.gro_receive =tcp4_gro_receive,.gro_complete =tcp4_gro_complete,.no_policy =1,.netns_ok =1,};static const struct net_protocol udp_protocol = {.handler =udp_rcv,.err_handler =udp_err,.gso_send_check = udp4_ufo_send_check,.gso_segment = udp4_ufo_fragment,.no_policy =1,.netns_ok =1,};static const struct net_protocol icmp_protocol = {.handler =icmp_rcv,.err_handler =ping_err,.no_policy =1,.netns_ok =1,};

IP層與net/core層介面定義如下:

static struct packet_type ip_packet_type __read_mostly = {.type = cpu_to_be16(ETH_P_IP),.func = ip_rcv,.gso_send_check = inet_gso_send_check,.gso_segment = inet_gso_segment,.gro_receive = inet_gro_receive,.gro_complete = inet_gro_complete,};


接收下半部stack如下所示:

[  336.646628] [<c07d8b24>] (tcp_rcv_established+0x648/0x9b0) from [<c07e04cc>] (tcp_v4_do_rcv+0x74/0x2a8)[  336.646661] [<c07e04cc>] (tcp_v4_do_rcv+0x74/0x2a8) from [<c07e0c40>] (tcp_v4_rcv+0x540/0x908)[  336.646678] [<c07e0c40>] (tcp_v4_rcv+0x540/0x908) from [<c07c23d4>] (ip_local_deliver_finish+0x158/0x318)[  336.646694] [<c07c23d4>] (ip_local_deliver_finish+0x158/0x318) from [<c07c1e44>] (ip_rcv_finish+0x420/0x440)[  336.646715] [<c07c1e44>] (ip_rcv_finish+0x420/0x440) from [<c0772dcc>] (__netif_receive_skb+0x4d0/0x534)[  336.646730] [<c0772dcc>] (__netif_receive_skb+0x4d0/0x534) from [<c0774434>] (netif_receive_skb+0x9c/0xb4)[  336.646752] [<c0774434>] (netif_receive_skb+0x9c/0xb4) from [<c08b8e6c>] (ieee80211_deliver_skb+0x134/0x164)[  336.646769] [<c08b8e6c>] (ieee80211_deliver_skb+0x134/0x164) from [<c08b9ed8>] (ieee80211_rx_handlers+0x103c/0x1978)[  336.646785] [<c08b9ed8>] (ieee80211_rx_handlers+0x103c/0x1978) from [<c08baf10>] (ieee80211_prepare_and_rx_handle+0x6fc/0x788)[  336.646802] [<c08baf10>] (ieee80211_prepare_and_rx_handle+0x6fc/0x788) from [<c08bb920>] (ieee80211_rx+0x908/0x988)[  336.646819] [<c08bb920>] (ieee80211_rx+0x908/0x988) from [<c068a578>] (ath9k_rx_tasklet+0x4e4/0x54c)[  336.646835] [<c068a578>] (ath9k_rx_tasklet+0x4e4/0x54c) from [<c0467d98>] (tasklet_action+0xa8/0x14c)[  336.646850] [<c0467d98>] (tasklet_action+0xa8/0x14c) from [<c0468144>] (__do_softirq+0x88/0x158)[  336.646863] [<c0468144>] (__do_softirq+0x88/0x158) from [<c0468414>] (irq_exit+0x48/0xac)[  336.646882] [<c0468414>] (irq_exit+0x48/0xac) from [<c04313c0>] (do_local_timer+0x50/0x80)[  336.646898] [<c04313c0>] (do_local_timer+0x50/0x80) from [<c0436708>] (__irq_svc+0x48/0xe0)

6. 資料發送(Data TX)流珵

   資料發送流程如所示:


上半部分涉及到的相關代碼如下所示(以上流程主要通過dump_stack擷取):

     net/socket.c
     net/ipv4/af_net.c
     net/ipv4/tcp.c
     net/ipv4/tcp_output.c
     net/ipv4/ip_output.c
     net/core/neighbour.c
     net/core/dev.c

7. INET初始化

    INET為Linux OS實現了TCP/IP協議集,它使用BSD Socket介面作為與User通訊的方式。其初始化代碼如下所示:

    代碼位於:net/ipv4/af_inet.c。

static int __init inet_init(void){struct sk_buff *dummy_skb;struct inet_protosw *q;struct list_head *r;int rc = -EINVAL;BUILD_BUG_ON(sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb));sysctl_local_reserved_ports = kzalloc(65536 / 8, GFP_KERNEL);if (!sysctl_local_reserved_ports)goto out;rc = proto_register(&tcp_prot, 1);if (rc)goto out_free_reserved_ports;rc = proto_register(&udp_prot, 1);if (rc)goto out_unregister_tcp_proto;rc = proto_register(&raw_prot, 1);if (rc)goto out_unregister_udp_proto;rc = proto_register(&ping_prot, 1);if (rc)goto out_unregister_raw_proto;/* *Tell SOCKET that we are alive... */(void)sock_register(&inet_family_ops);#ifdef CONFIG_SYSCTLip_static_sysctl_init();#endif/* *Add all the base protocols. */if (inet_add_protocol(&icmp_protocol, IPPROTO_ICMP) < 0)printk(KERN_CRIT "inet_init: Cannot add ICMP protocol\n");if (inet_add_protocol(&udp_protocol, IPPROTO_UDP) < 0)printk(KERN_CRIT "inet_init: Cannot add UDP protocol\n");if (inet_add_protocol(&tcp_protocol, IPPROTO_TCP) < 0)printk(KERN_CRIT "inet_init: Cannot add TCP protocol\n");#ifdef CONFIG_IP_MULTICASTif (inet_add_protocol(&igmp_protocol, IPPROTO_IGMP) < 0)printk(KERN_CRIT "inet_init: Cannot add IGMP protocol\n");#endif/* Register the socket-side information for inet_create. */for (r = &inetsw[0]; r < &inetsw[SOCK_MAX]; ++r)INIT_LIST_HEAD(r);for (q = inetsw_array; q < &inetsw_array[INETSW_ARRAY_LEN]; ++q)inet_register_protosw(q);/* *Set the ARP module up */arp_init();/* *Set the IP module up */ip_init();tcp_v4_init();/* Setup TCP slab cache for open requests. */tcp_init();/* Setup UDP memory threshold */udp_init();/* Add UDP-Lite (RFC 3828) */udplite4_register();ping_init();/* *Set the ICMP layer up */if (icmp_init() < 0)panic("Failed to create the ICMP control socket.\n");/* *Initialise the multicast router */#if defined(CONFIG_IP_MROUTE)if (ip_mr_init())printk(KERN_CRIT "inet_init: Cannot init ipv4 mroute\n");#endif/* *Initialise per-cpu ipv4 mibs */if (init_ipv4_mibs())printk(KERN_CRIT "inet_init: Cannot init ipv4 mibs\n");ipv4_proc_init();ipfrag_init();dev_add_pack(&ip_packet_type);rc = 0;out:return rc;out_unregister_raw_proto:proto_unregister(&raw_prot);out_unregister_udp_proto:proto_unregister(&udp_prot);out_unregister_tcp_proto:proto_unregister(&tcp_prot);out_free_reserved_ports:kfree(sysctl_local_reserved_ports);goto out;}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.