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,
-
.start = ath9k_htc_start,
-
.stop = ath9k_htc_stop,
-
.add_interface = ath9k_htc_add_interface,
-
.remove_interface = ath9k_htc_remove_interface,
-
.config = ath9k_htc_config,
-
.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,
-
.del_virtual_intf = ieee80211_del_iface,
-
.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,
-
.ndo_stop = ieee80211_stop,
-
.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,
-
.ndo_set_mac_address = ieee80211_change_mac,
-
.ndo_select_queue = ieee80211_netdev_select_queue,
-
};
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] [] (tcp_rcv_established+0x648/0x9b0) from [] (tcp_v4_do_rcv+0x74/0x2a8)
-
[ 336.646661] [] (tcp_v4_do_rcv+0x74/0x2a8) from [] (tcp_v4_rcv+0x540/0x908)
-
[ 336.646678] [] (tcp_v4_rcv+0x540/0x908) from [] (ip_local_deliver_finish+0x158/0x318)
-
[ 336.646694] [] (ip_local_deliver_finish+0x158/0x318) from [] (ip_rcv_finish+0x420/0x440)
-
[ 336.646715] [] (ip_rcv_finish+0x420/0x440) from [] (__netif_receive_skb+0x4d0/0x534)
-
[ 336.646730] [] (__netif_receive_skb+0x4d0/0x534) from [] (netif_receive_skb+0x9c/0xb4)
-
[ 336.646752] [] (netif_receive_skb+0x9c/0xb4) from [] (ieee80211_deliver_skb+0x134/0x164)
-
[ 336.646769] [] (ieee80211_deliver_skb+0x134/0x164) from [] (ieee80211_rx_handlers+0x103c/0x1978)
-
[ 336.646785] [] (ieee80211_rx_handlers+0x103c/0x1978) from [] (ieee80211_prepare_and_rx_handle+0x6fc/0x788)
-
[ 336.646802] [] (ieee80211_prepare_and_rx_handle+0x6fc/0x788) from [] (ieee80211_rx+0x908/0x988)
-
[ 336.646819] [] (ieee80211_rx+0x908/0x988) from [] (ath9k_rx_tasklet+0x4e4/0x54c)
-
[ 336.646835] [] (ath9k_rx_tasklet+0x4e4/0x54c) from [] (tasklet_action+0xa8/0x14c)
-
[ 336.646850] [] (tasklet_action+0xa8/0x14c) from [] (__do_softirq+0x88/0x158)
-
[ 336.646863] [] (__do_softirq+0x88/0x158) from [] (irq_exit+0x48/0xac)
-
[ 336.646882] [] (irq_exit+0x48/0xac) from [] (do_local_timer+0x50/0x80)
-
[ 336.646898] [] (do_local_timer+0x50/0x80) from [] (__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。
阅读(2123) | 评论(0) | 转发(0) |