/* * This is the control buffer. It is free to use for every * layer. Please put your private variables there. If you * want to keep them across layers you have to do a skb_clone() * first. This is owned by whoever has the skb queued ATM. */ char cb[48];
/* Get the HEAD */ skb = kmem_cache_alloc(cache, gfp_mask & ~__GFP_DMA); if (!skb) goto out;
/* Get the DATA. Size must match skb_add_mtu(). */ size = SKB_DATA_ALIGN(size); data = kmalloc_track_caller(size + sizeof(struct skb_shared_info), gfp_mask); if (!data) goto nodata;
/* * This is the first field of the "visible" part of this structure * (i.e. as seen by users in the "Space.c" file). It is the name * the interface. */ // 设备的名称(如,eth0) char name[IFNAMSIZ]; /* device name hash chain */ structhlist_nodename_hlist;
/* * I/O specific fields * FIXME: Merge these and struct ifmap into one */ // 描述设备所用的共享内存,用于设备与内核沟通 // 其初始化和访问只会在设备驱动程序内进行 unsignedlong mem_end; /* shared mem end */ unsignedlong mem_start; /* shared mem start */ // 设备自由内存映射到 I/O 内存的起始地址 unsignedlong base_addr; /* device I/O address */ // 设备用于与内核对话的中断编号,此值可由多个设备共享 // 驱动程序使用 request_irq 函数分配此变量,使用 free_irq 释放 unsignedint irq; /* device IRQ number */
/* * Some hardware also needs these fields, but they are not * part of the usual set specified in Space.c. */ // 此接口所使用的端口类型 unsignedchar if_port; /* Selectable AUI, TP,..*/ // 设备所使用的 DMA 通道 unsignedchar dma; /* DMA channel */
// 由网络队列子系统所使用的一组标识 unsignedlong state;
structnet_device *next; /* The device initialization function. Called only once. */ int (*init)(struct net_device *dev);
/* ------- Fields preinitialized in Space.c finish here ------- */
/* Net device features */ // 存储其他一些设备功能 // 可报告适配卡的功能,以便于CPU通信, // 如适配卡能够对高端内存做 DMA 或者硬件能否对所有封包做校验和工作 unsignedlong features; #define NETIF_F_SG 1 /* Scatter/gather IO. */ #define NETIF_F_IP_CSUM 2 /* Can checksum only TCP/UDP over IPv4. */ #define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */ #define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */ #define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */ #define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */ #define NETIF_F_HW_VLAN_TX 128 /* Transmit VLAN hw acceleration */ #define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */ #define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */ #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */ #define NETIF_F_GSO 2048 /* Enable software GSO. */ #define NETIF_F_LLTX 4096 /* LockLess TX */
/* Interface index. Unique device identifier */ // UID,当设备以 dev_new_index 注册时分派给每个设备 int ifindex; // 由(虚拟)隧道设备使用,可用于标识抵达隧道另一端的真实设备 int iflink;
// 设备驱动程序所收集的一些统计数据,可以使用用户控件程序显示,如 ifconfig, ip structnet_device_stats* (*get_stats)(structnet_device *dev);
/* List of functions to handle Wireless Extensions (instead of ioctl). * See <net/iw_handler.h> for details. Jean II */ // 其它无线设备使用的参数和函数指针 conststructiw_handler_def * wireless_handlers; /* Instance data managed by the core of Wireless Extensions. */ structiw_public_data * wireless_data;
/* * This marks the end of the "visible" part of the structure. All * fields hereafter are internal to the system, and may change at * will (read: may be cleaned up at will). */
// 某些位代表网络设备的功能(如 IFF_MULTICAST) // 其他位代表状态的改变(如 IFF_UP, IFF_RUNNING) unsignedint flags; /* interface flags (a la BSD) */ // 几乎不再使用 unsignedshort gflags; // 存储用户空间不可见的标识 // 由 VLAN 和 Bridge 虚拟设备使用 unsignedshort priv_flags; /* Like 'flags' but invisible to userspace. */ unsignedshort padded; /* How much padding added by alloc_netdev() */
// 指向此设备的 dev_mc_list 结构列表表头的指针 structdev_mc_list *mc_list;/* Multicast mac addresses */ // 此设备的多播地址数目 int mc_count; /* Number of installed mcasts */ // 混杂模式,计数器,对此字段的操作使用 `dev_set_promiscuity` 函数实现 // 非零时,flags 的 IFF_PROMISC 标识位也会设置 int promiscuity; // 设置或清除 flags 中表示该设备是否监听所有地址的标识 int allmulti;
/* Protocol specific pointers */ // 指向特定协议专用的数据结构,每个数据结构都包含一些该协议私有的参数 void *atalk_ptr; /* AppleTalk link */ // 指向一个类型为 in_device 的数据结构 void *ip_ptr; /* IPv4 specific data */ void *dn_ptr; /* DECnet specific data */ void *ip6_ptr; /* IPv6 specific data */ void *ec_ptr; /* Econet specific data */ void *ax25_ptr; /* AX.25 specific data */
/* * Cache line mostly used on receive path (including eth_type_trans()) */ structlist_headpoll_list ____cacheline_aligned_in_smp; /* Link to poll list */
int (*poll) (struct net_device *dev, int *quota); int quota; int weight; // 最后一个封包到达的时间 unsignedlong last_rx; /* Time of last Rx */ /* Interface address info used in eth_type_trans() */ // 设备链路层地址 unsignedchar dev_addr[MAX_ADDR_LEN]; /* hw address, (before bcast because most packets are unicast) */
/* * One part is mostly used on xmit path (device) */ /* hard_start_xmit synchronizer */ spinlock_t _xmit_lock ____cacheline_aligned_in_smp; /* cpu id of processor entered to hard_start_xmit or -1, if nobody entered there. */ int xmit_lock_owner; void *priv; /* pointer to private data */ // 传输一个帧 int (*hard_start_xmit) (struct sk_buff *skb, struct net_device *dev); /* These may be needed for future network-power-down code. */ // 最近的一个帧传输启动的时间 unsignedlong trans_start; /* Time (in jiffies) of last Tx */
// 定时器 int watchdog_timeo; /* used by dev_watchdog() */ structtimer_listwatchdog_timer;
/* * refcnt is a very hot point, so align it on SMP */ /* Number of references to this device */ // 引用计数 atomic_t refcnt ____cacheline_aligned_in_smp;
/* register/unregister state machine */ enum { NETREG_UNINITIALIZED=0, NETREG_REGISTERED, /* completed register_netdevice */ NETREG_UNREGISTERING, /* called unregister_netdevice */ NETREG_UNREGISTERED, /* completed unregister todo */ NETREG_RELEASED, /* called free_netdev */ } reg_state; // 设备的注册状态
/* Called after device is detached from network. */ void (*uninit)(struct net_device *dev); /* Called after last user reference disappears. */ void (*destructor)(struct net_device *dev);
/* Pointers to interface service routines. */ int (*open)(struct net_device *dev); int (*stop)(struct net_device *dev); #define HAVE_NETDEV_POLL int (*hard_header) (struct sk_buff *skb, struct net_device *dev, unsignedshort type, void *daddr, void *saddr, unsigned len); int (*rebuild_header)(struct sk_buff *skb); #define HAVE_MULTICAST void (*set_multicast_list)(struct net_device *dev); #define HAVE_SET_MAC_ADDR // 改变设备的 MAC 地址 int (*set_mac_address)(struct net_device *dev, void *addr); #define HAVE_PRIVATE_IOCTL // ioctl 是系统调用,用于向设备发出命令 int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd); #define HAVE_SET_CONFIG // 配置驱动程序参数,如硬件参数 irq, id_addr, if_port int (*set_config)(struct net_device *dev, struct ifmap *map); #define HAVE_HEADER_CACHE int (*hard_header_cache)(struct neighbour *neigh, struct hh_cache *hh); void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsignedchar * haddr); #define HAVE_CHANGE_MTU // 改变设备的 MTU 值 int (*change_mtu)(struct net_device *dev, int new_mtu);
#ifdef CONFIG_NET_DIVERT /* this will get initialized at each interface type init routine */ // 分流器,允许改变输入的封包的源和目的地址 structdivert_blk *divert; #endif/* CONFIG_NET_DIVERT */
/* class/net/name entry */ // 由新的通用内核驱动程序基础架构使用 structclass_deviceclass_dev; /* space for optional statistics and wireless sysfs groups */ structattribute_group *sysfs_groups[3]; };