湛江网站制作推广,商场设计图片,aws注册wordpress,专业做视频的网站有哪些内容1、无线网络驱动(ath9k_htc) ath9k_htc是一个基于USB接口的SoftMAC无线网络适配器。为了其驱动能正常工作#xff0c;首先必须调用usb_register来注册驱动定义的usb_driver#xff0c;以借助USB Core的力量来处理与USB协议相关的事件。其代码如下#xff1a;[cpp] view plai… 1、无线网络驱动(ath9k_htc)
ath9k_htc是一个基于USB接口的SoftMAC无线网络适配器。为了其驱动能正常工作首先必须调用usb_register来注册驱动定义的usb_driver以借助USB Core的力量来处理与USB协议相关的事件。其代码如下[cpp] view plaincopy 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的调用。 [cpp] view plaincopy 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中其定义如下所示 [cpp] view plaincopy 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中的定义如下所示 [cpp] view plaincopy tatic 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参数。其具体定义如下 [cpp] view plaincopy 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: [cpp] view plaincopy 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层接口定义如下 [cpp] view plaincopy 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层接口定义如下 [cpp] view plaincopy 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, }; 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 [cpp] view plaincopy 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_SYSCTL ip_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_MULTICAST if (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; }