14.1 网络设备驱动结构

  • 网络协议接口层:硬件无关,标准收发函数dev_queue_xmit()和netif_rx();  注意,netif_rx是将接收到的数据给上层,有时也在驱动收到数据以后调用。
  • 网络设备接口层,net_device,统一接口名称,使上层独立于具体硬件。
  • 设备驱动功能层,实现net_device的各成员
  • 物理层

在整个以太网架构里,有两个数据结构非常重要,即sk_buff和net_device,后面两节有说明。

还有一些与内核交互的函数,需要掌握,如netif_start_queue(),netif_stop_queue(),netif_wakeup_queue(),netif_rx(),netif_carrier_on/off_ok()

14.1.1 sk_buff

  以太网各层之间用sk_buff结构体传递数据,该结构体是很多函数的形参。

  1. #include <linux/skbuff.h>
  2.  
  3. /**
  4. * struct sk_buff - socket buffer
  5. * @next: Next buffer in list
  6. * @prev: Previous buffer in list
  7. * @tstamp: Time we arrived
  8. * @sk: Socket we are owned by
  9. * @dev: Device we arrived on/are leaving by
  10. * @cb: Control buffer. Free for use by every layer. Put private vars here
  11. * @_skb_refdst: destination entry (with norefcount bit)
  12. * @sp: the security path, used for xfrm
  13. * @len: Length of actual data
  14. * @data_len: Data length
  15. * @mac_len: Length of link layer header
  16. * @hdr_len: writable header length of cloned skb
  17. * @csum: Checksum (must include start/offset pair)
  18. * @csum_start: Offset from skb->head where checksumming should start
  19. * @csum_offset: Offset from csum_start where checksum should be stored
  20. * @priority: Packet queueing priority
  21. * @local_df: allow local fragmentation
  22. * @cloned: Head may be cloned (check refcnt to be sure)
  23. * @ip_summed: Driver fed us an IP checksum
  24. * @nohdr: Payload reference only, must not modify header
  25. * @nfctinfo: Relationship of this skb to the connection
  26. * @pkt_type: Packet class
  27. * @fclone: skbuff clone status
  28. * @ipvs_property: skbuff is owned by ipvs
  29. * @peeked: this packet has been seen already, so stats have been
  30. * done for it, don't do them again
  31. * @nf_trace: netfilter packet trace flag
  32. * @protocol: Packet protocol from driver
  33. * @destructor: Destruct function
  34. * @nfct: Associated connection, if any
  35. * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c
  36. * @skb_iif: ifindex of device we arrived on
  37. * @tc_index: Traffic control index
  38. * @tc_verd: traffic control verdict
  39. * @rxhash: the packet hash computed on receive
  40. * @queue_mapping: Queue mapping for multiqueue devices
  41. * @ndisc_nodetype: router type (from link layer)
  42. * @ooo_okay: allow the mapping of a socket to a queue to be changed
  43. * @l4_rxhash: indicate rxhash is a canonical 4-tuple hash over transport
  44. * ports.
  45. * @wifi_acked_valid: wifi_acked was set
  46. * @wifi_acked: whether frame was acked on wifi or not
  47. * @no_fcs: Request NIC to treat last 4 bytes as Ethernet FCS
  48. * @dma_cookie: a cookie to one of several possible DMA operations
  49. * done by skb DMA functions
  50. * @napi_id: id of the NAPI struct this skb came from
  51. * @secmark: security marking
  52. * @mark: Generic packet mark
  53. * @dropcount: total number of sk_receive_queue overflows
  54. * @vlan_proto: vlan encapsulation protocol
  55. * @vlan_tci: vlan tag control information
  56. * @inner_protocol: Protocol (encapsulation)
  57. * @inner_transport_header: Inner transport layer header (encapsulation)
  58. * @inner_network_header: Network layer header (encapsulation)
  59. * @inner_mac_header: Link layer header (encapsulation)
  60. * @transport_header: Transport layer header
  61. * @network_header: Network layer header
  62. * @mac_header: Link layer header
  63. * @tail: Tail pointer
  64. * @end: End pointer
  65. * @head: Head of buffer
  66. * @data: Data head pointer
  67. * @truesize: Buffer size
  68. * @users: User count - see {datagram,tcp}.c
  69. */
  70.  
  71. struct sk_buff {
  72. /* These two members must be first. */
  73. struct sk_buff *next;
  74. struct sk_buff *prev;
  75.  
  76. ktime_t tstamp;
  77.  
  78. struct sock *sk;
  79. struct net_device *dev;
  80.  
  81. /*
  82. * This is the control buffer. It is free to use for every
  83. * layer. Please put your private variables there. If you
  84. * want to keep them across layers you have to do a skb_clone()
  85. * first. This is owned by whoever has the skb queued ATM.
  86. */
  87. char cb[] __aligned();
  88.  
  89. unsigned long _skb_refdst;
  90. #ifdef CONFIG_XFRM
  91. struct sec_path *sp;
  92. #endif
  93. unsigned int len,    // data段的长度
  94. data_len;
  95. __u16 mac_len,
  96. hdr_len;
  97. union {
  98. __wsum csum;
  99. struct {
  100. __u16 csum_start;
  101. __u16 csum_offset;
  102. };
  103. };
  104. __u32 priority;
  105. kmemcheck_bitfield_begin(flags1);
  106. __u8 local_df:,
  107. cloned:,
  108. ip_summed:,
  109. nohdr:,
  110. nfctinfo:;
  111. __u8 pkt_type:,
  112. fclone:,
  113. ipvs_property:,
  114. peeked:,
  115. nf_trace:;
  116. kmemcheck_bitfield_end(flags1);
  117. __be16 protocol;
  118.  
  119. void (*destructor)(struct sk_buff *skb);
  120. #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
  121. struct nf_conntrack *nfct;
  122. #endif
  123. #ifdef CONFIG_BRIDGE_NETFILTER
  124. struct nf_bridge_info *nf_bridge;
  125. #endif
  126.  
  127. int skb_iif;
  128.  
  129. __u32 rxhash;
  130.  
  131. __be16 vlan_proto;
  132. __u16 vlan_tci;
  133.  
  134. #ifdef CONFIG_NET_SCHED
  135. __u16 tc_index; /* traffic control index */
  136. #ifdef CONFIG_NET_CLS_ACT
  137. __u16 tc_verd; /* traffic control verdict */
  138. #endif
  139. #endif
  140.  
  141. __u16 queue_mapping;
  142. kmemcheck_bitfield_begin(flags2);
  143. #ifdef CONFIG_IPV6_NDISC_NODETYPE
  144. __u8 ndisc_nodetype:;
  145. #endif
  146. __u8 pfmemalloc:;
  147. __u8 ooo_okay:;
  148. __u8 l4_rxhash:;
  149. __u8 wifi_acked_valid:;
  150. __u8 wifi_acked:;
  151. __u8 no_fcs:;
  152. __u8 head_frag:;
  153. /* Encapsulation protocol and NIC drivers should use
  154. * this flag to indicate to each other if the skb contains
  155. * encapsulated packet or not and maybe use the inner packet
  156. * headers if needed
  157. */
  158. __u8 encapsulation:;
  159. /* 6/8 bit hole (depending on ndisc_nodetype presence) */
  160. kmemcheck_bitfield_end(flags2);
  161.  
  162. #if defined CONFIG_NET_DMA || defined CONFIG_NET_RX_BUSY_POLL
  163. union {
  164. unsigned int napi_id;
  165. dma_cookie_t dma_cookie;
  166. };
  167. #endif
  168. #ifdef CONFIG_NETWORK_SECMARK
  169. __u32 secmark;
  170. #endif
  171. union {
  172. __u32 mark;
  173. __u32 dropcount;
  174. __u32 reserved_tailroom;
  175. };
  176.  
  177. __be16 inner_protocol;
  178. __u16 inner_transport_header;
  179. __u16 inner_network_header;
  180. __u16 inner_mac_header;
  181. __u16 transport_header;
  182. __u16 network_header;
  183. __u16 mac_header;
  184. /* These elements must be at the end, see alloc_skb() for details. */
  185. sk_buff_data_t tail;
  186. sk_buff_data_t end;
  187. unsigned char *head,
  188. *data;
  189. unsigned int truesize;
  190. atomic_t users;
  191. };

  • 接收时,各层去掉自己的协议,把数据给上层;
  • 发送时,各层添加自己的协议,最终给物理网口。
  • 上图指针可以动态调整,下面是若干函数
  1. /** tail后移,即在data中增加数据
  2. * skb_put - add data to a buffer
  3. * @skb: buffer to use
  4. * @len: amount of data to add
  5. *
  6. * This function extends the used data area of the buffer. If this would
  7. * exceed the total buffer size the kernel will panic. A pointer to the
  8. * first byte of the extra data is returned.
  9. */
  10. unsigned char *skb_put(struct sk_buff *skb, unsigned int len)
  11. {
  12. unsigned char *tmp = skb_tail_pointer(skb);
  13. SKB_LINEAR_ASSERT(skb);
  14. skb->tail += len;
  15. skb->len += len;
  16. if (unlikely(skb->tail > skb->end))
  17. skb_over_panic(skb, len, __builtin_return_address());
  18. return tmp;
  19. }
  20.  
  21. /**
  22. * skb_push - add data to the start of a buffer,data前移
  23. * @skb: buffer to use
  24. * @len: amount of data to add
  25. *
  26. * This function extends the used data area of the buffer at the buffer
  27. * start. If this would exceed the total buffer headroom the kernel will
  28. * panic. A pointer to the first byte of the extra data is returned.
  29. */
  30. unsigned char *skb_push(struct sk_buff *skb, unsigned int len)
  31. {
  32. skb->data -= len;
  33. skb->len += len;
  34. if (unlikely(skb->data<skb->head))
  35. skb_under_panic(skb, len, __builtin_return_address());
  36. return skb->data;
  37. }
  38.  
  39. /**
  40. * skb_pull - remove data from the start of a buffer,data后移
  41. * @skb: buffer to use
  42. * @len: amount of data to remove
  43. *
  44. * This function removes data from the start of a buffer, returning
  45. * the memory to the headroom. A pointer to the next data in the buffer
  46. * is returned. Once the data has been pulled future pushes will overwrite
  47. * the old data.
  48. */
  49. unsigned char *skb_pull(struct sk_buff *skb, unsigned int len)
  50. {
  51. return skb_pull_inline(skb, len);
  52. }
  53.  
  54. static inline unsigned char *skb_pull_inline(struct sk_buff *skb, unsigned int len)
  55. {
  56. return unlikely(len > skb->len) ? NULL : __skb_pull(skb, len);
  57. }
  58.  
  59. static inline unsigned char *__skb_pull(struct sk_buff *skb, unsigned int len)
  60. {
  61. skb->len -= len;
  62. BUG_ON(skb->len < skb->data_len);
  63. return skb->data += len;
  64. }
  65. /**
  66. * skb_reserve - adjust headroom
  67. * @skb: buffer to alter
  68. * @len: bytes to move
  69. *
  70. * Increase the headroom of an empty &sk_buff by reducing the tail
  71. * room. This is only allowed for an empty buffer.
  72. */
  73. static inline void skb_reserve(struct sk_buff *skb, int len)
  74. {
  75. skb->data += len;
  76. skb->tail += len;
  77. }
  78.  
  79. // 例子:
    skb=alloc_skb(len+headspace, GFP_KERNEL);  // 分配
    skb_reserve(skb, headspace);          // tail=data=起始位置+headspace
    skb_put(skb,len);                // tail += len
    memcpy_fromfs(skb->data,data,len);
    pass_to_m_protocol(skb);
  • sk_buff的动态分配和释放

  1. static inline struct sk_buff *alloc_skb(unsigned int size,
  2. gfp_t priority);/* legacy helper around netdev_alloc_skb() */
  3. static inline struct sk_buff *dev_alloc_skb(unsigned int length);void kfree_skb(struct sk_buff *skb);
    void dev_kfree_skb)(struct sk_buff * skb);
  4.  
  5. /*
  6. * It is not allowed to call kfree_skb() or consume_skb() from hardware
  7. * interrupt context or with hardware interrupts being disabled.
  8. * (in_irq() || irqs_disabled())
  9. *
  10. * We provide four helpers that can be used in following contexts :
  11. *
  12. * dev_kfree_skb_irq(skb) when caller drops a packet from irq context,
  13. * replacing kfree_skb(skb)
  14. *
  15. * dev_consume_skb_irq(skb) when caller consumes a packet from irq context.
  16. * Typically used in place of consume_skb(skb) in TX completion path
  17. *
  18. * dev_kfree_skb_any(skb) when caller doesn't know its current irq context,
  19. * replacing kfree_skb(skb)
  20. *
  21. * dev_consume_skb_any(skb) when caller doesn't know its current irq context,
  22. * and consumed a packet. Used in place of consume_skb(skb)
  23. */
  24. static inline void dev_kfree_skb_irq(struct sk_buff *skb);
  25. static inline void dev_kfree_skb_any(struct sk_buff *skb);

14.1.2 net_device

net_device有点类似字符设备中的file_opretions,里面定义了很多标准成员函数,驱动需要实现里面的函数。

  1. /*
  2. * The DEVICE structure.
  3. * Actually, this whole structure is a big mistake. It mixes I/O
  4. * data with strictly "high-level" data, and it has to know about
  5. * almost every data structure used in the INET module.
  6. *
  7. * FIXME: cleanup struct net_device such that network protocol info
  8. * moves out.
  9. */
  10.  
  11. struct net_device {
  12.  
  13. /*
  14. * This is the first field of the "visible" part of this structure
  15. * (i.e. as seen by users in the "Space.c" file). It is the name
  16. * of the interface.
  17. */
  18. char name[IFNAMSIZ];      /* device name hash chain, please keep it close to name[] */
  19. struct hlist_node name_hlist;
  20.  
  21. /* snmp alias */
  22. char *ifalias;
  23.  
  24. /*
  25. * I/O specific fields
  26. * FIXME: Merge these and struct ifmap into one
  27. */
  28. unsigned long mem_end; /* shared mem end */
  29. unsigned long mem_start; /* shared mem start */
  30. unsigned long base_addr; /* device I/O address */
  31. int irq; /* device IRQ number */
  32.  
  33. /*
  34. * Some hardware also needs these fields, but they are not
  35. * part of the usual set specified in Space.c.
  36. */
  37.  
  38. unsigned long state;
  39.  
  40. struct list_head dev_list;
  41. struct list_head napi_list;
  42. struct list_head unreg_list;
  43. struct list_head close_list;
  44.  
  45. /* directly linked devices, like slaves for bonding */
  46. struct {
  47. struct list_head upper;
  48. struct list_head lower;
  49. } adj_list;
  50.  
  51. /* all linked devices, *including* neighbours */
  52. struct {
  53. struct list_head upper;
  54. struct list_head lower;
  55. } all_adj_list;
  56.  
  57. /* currently active device features */
  58. netdev_features_t features;
  59. /* user-changeable features */
  60. netdev_features_t hw_features;
  61. /* user-requested features */
  62. netdev_features_t wanted_features;
  63. /* mask of features inheritable by VLAN devices */
  64. netdev_features_t vlan_features;
  65. /* mask of features inherited by encapsulating devices
  66. * This field indicates what encapsulation offloads
  67. * the hardware is capable of doing, and drivers will
  68. * need to set them appropriately.
  69. */
  70. netdev_features_t hw_enc_features;
  71. /* mask of fetures inheritable by MPLS */
  72. netdev_features_t mpls_features;
  73.  
  74. /* Interface index. Unique device identifier */
  75. int ifindex;
  76. int iflink;
  77.  
  78. struct net_device_stats stats;  // 各种统计信息
  79. atomic_long_t rx_dropped; /* dropped packets by core network
  80. * Do not use this in drivers.
  81. */
  82.  
  83. #ifdef CONFIG_WIRELESS_EXT
  84. /* List of functions to handle Wireless Extensions (instead of ioctl).
  85. * See <net/iw_handler.h> for details. Jean II */
  86. const struct iw_handler_def * wireless_handlers;
  87. /* Instance data managed by the core of Wireless Extensions. */
  88. struct iw_public_data * wireless_data;
  89. #endif
  90. /* Management operations */
  91. const struct net_device_ops *netdev_ops;  // 具体函数,需驱动填充
  92. const struct ethtool_ops *ethtool_ops;
  93. const struct forwarding_accel_ops *fwd_ops;
  94.  
  95. /* Hardware header description */
  96. const struct header_ops *header_ops;
  97.  
  98. unsigned int flags; /* interface flags (a la BSD) ,接口标记,以IFF_开头,说明设备接口的能力和特性*/
  99. unsigned int priv_flags; /* Like 'flags' but invisible to userspace.
  100. * See if.h for definitions. */
  101. unsigned short gflags;
  102. unsigned short padded; /* How much padding added by alloc_netdev() */
  103.  
  104. unsigned char operstate; /* RFC2863 operstate */
  105. unsigned char link_mode; /* mapping policy to operstate */
  106.  
  107. unsigned char if_port; /* Selectable AUI, TP,..*/
  108. unsigned char dma; /* DMA channel */
  109.  
  110. unsigned int mtu; /* interface MTU value,最单传输单元 */
  111. unsigned short type; /* interface hardware type,硬件类型 */
  112. unsigned short hard_header_len; /* hardware hdr length,Dmac+Smac+type=14 */
  113.  
  114. /* extra head- and tailroom the hardware may need, but not in all cases
  115. * can this be guaranteed, especially tailroom. Some cases also use
  116. * LL_MAX_HEADER instead to allocate the skb.
  117. */
  118. unsigned short needed_headroom;
  119. unsigned short needed_tailroom;
  120.  
  121. /* Interface address info. */
  122. unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */
  123. unsigned char addr_assign_type; /* hw address assignment type */
  124. unsigned char addr_len; /* hardware address length */
  125. unsigned short neigh_priv_len;
  126. unsigned short dev_id; /* Used to differentiate devices
  127. * that share the same link
  128. * layer address
  129. */
  130. spinlock_t addr_list_lock;
  131. struct netdev_hw_addr_list uc; /* Unicast mac addresses */
  132. struct netdev_hw_addr_list mc; /* Multicast mac addresses */
  133. struct netdev_hw_addr_list dev_addrs; /* list of device
  134. * hw addresses
  135. */
  136. #ifdef CONFIG_SYSFS
  137. struct kset *queues_kset;
  138. #endif
  139.  
  140. bool uc_promisc;
  141. unsigned int promiscuity;
  142. unsigned int allmulti;
  143.  
  144. /* Protocol specific pointers */
  145.  
  146. #if IS_ENABLED(CONFIG_VLAN_8021Q)
  147. struct vlan_info __rcu *vlan_info; /* VLAN info */
  148. #endif
  149. #if IS_ENABLED(CONFIG_NET_DSA)
  150. struct dsa_switch_tree *dsa_ptr; /* dsa specific data */
  151. #endif
  152. #if IS_ENABLED(CONFIG_TIPC)
  153. struct tipc_bearer __rcu *tipc_ptr; /* TIPC specific data */
  154. #endif
  155. void *atalk_ptr; /* AppleTalk link */
  156. struct in_device __rcu *ip_ptr; /* IPv4 specific data */
  157. struct dn_dev __rcu *dn_ptr; /* DECnet specific data */
  158. struct inet6_dev __rcu *ip6_ptr; /* IPv6 specific data */
  159. void *ax25_ptr; /* AX.25 specific data */
  160. struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data,
  161. assign before registering */
  162.  
  163. /*
  164. * Cache lines mostly used on receive path (including eth_type_trans())
  165. */
  166. unsigned long last_rx; /* Time of last Rx
  167. * This should not be set in
  168. * drivers, unless really needed,
  169. * because network stack (bonding)
  170. * use it if/when necessary, to
  171. * avoid dirtying this cache line.
  172. */
  173.  
  174. /* Interface address info used in eth_type_trans() */
  175. unsigned char *dev_addr; /* hw address, (before bcast
  176. because most packets are
  177. unicast) */
  178.  
  179. #ifdef CONFIG_SYSFS
  180. struct netdev_rx_queue *_rx;
  181.  
  182. /* Number of RX queues allocated at register_netdev() time */
  183. unsigned int num_rx_queues;
  184.  
  185. /* Number of RX queues currently active in device */
  186. unsigned int real_num_rx_queues;
  187.  
  188. #endif
  189.  
  190. rx_handler_func_t __rcu *rx_handler;
  191. void __rcu *rx_handler_data;
  192.  
  193. struct netdev_queue __rcu *ingress_queue;
  194. unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
  195.  
  196. /*
  197. * Cache lines mostly used on transmit path
  198. */
  199. struct netdev_queue *_tx ____cacheline_aligned_in_smp;
  200.  
  201. /* Number of TX queues allocated at alloc_netdev_mq() time */
  202. unsigned int num_tx_queues;
  203.  
  204. /* Number of TX queues currently active in device */
  205. unsigned int real_num_tx_queues;
  206.  
  207. /* root qdisc from userspace point of view */
  208. struct Qdisc *qdisc;
  209.  
  210. unsigned long tx_queue_len; /* Max frames per queue allowed */
  211. spinlock_t tx_global_lock;
  212.  
  213. #ifdef CONFIG_XPS
  214. struct xps_dev_maps __rcu *xps_maps;
  215. #endif
  216. #ifdef CONFIG_RFS_ACCEL
  217. /* CPU reverse-mapping for RX completion interrupts, indexed
  218. * by RX queue number. Assigned by driver. This must only be
  219. * set if the ndo_rx_flow_steer operation is defined. */
  220. struct cpu_rmap *rx_cpu_rmap;
  221. #endif
  222.  
  223. /* These may be needed for future network-power-down code. */
  224.  
  225. /*
  226. * trans_start here is expensive for high speed devices on SMP,
  227. * please use netdev_queue->trans_start instead.
  228. */
  229. unsigned long trans_start; /* Time (in jiffies) of last Tx */
  230.  
  231. int watchdog_timeo; /* used by dev_watchdog() */
  232. struct timer_list watchdog_timer;
  233.  
  234. /* Number of references to this device */
  235. int __percpu *pcpu_refcnt;
  236.  
  237. /* delayed register/unregister */
  238. struct list_head todo_list;
  239. /* device index hash chain */
  240. struct hlist_node index_hlist;
  241.  
  242. struct list_head link_watch_list;
  243.  
  244. /* register/unregister state machine */
  245. enum { NETREG_UNINITIALIZED=,
  246. NETREG_REGISTERED, /* completed register_netdevice */
  247. NETREG_UNREGISTERING, /* called unregister_netdevice */
  248. NETREG_UNREGISTERED, /* completed unregister todo */
  249. NETREG_RELEASED, /* called free_netdev */
  250. NETREG_DUMMY, /* dummy device for NAPI poll */
  251. } reg_state:;
  252.  
  253. bool dismantle; /* device is going do be freed */
  254.  
  255. enum {
  256. RTNL_LINK_INITIALIZED,
  257. RTNL_LINK_INITIALIZING,
  258. } rtnl_link_state:;
  259.  
  260. /* Called from unregister, can be used to call free_netdev */
  261. void (*destructor)(struct net_device *dev);
  262.  
  263. #ifdef CONFIG_NETPOLL
  264. struct netpoll_info __rcu *npinfo;
  265. #endif
  266.  
  267. #ifdef CONFIG_NET_NS
  268. /* Network namespace this network device is inside */
  269. struct net *nd_net;
  270. #endif
  271.  
  272. /* mid-layer private */
  273. union {
  274. void *ml_priv;
  275. struct pcpu_lstats __percpu *lstats; /* loopback stats */
  276. struct pcpu_sw_netstats __percpu *tstats;
  277. struct pcpu_dstats __percpu *dstats; /* dummy stats */
  278. struct pcpu_vstats __percpu *vstats; /* veth stats */
  279. };
  280. /* GARP */
  281. struct garp_port __rcu *garp_port;
  282. /* MRP */
  283. struct mrp_port __rcu *mrp_port;
  284.  
  285. /* class/net/name entry */
  286. struct device dev;
  287. /* space for optional device, statistics, and wireless sysfs groups */
  288. const struct attribute_group *sysfs_groups[];
  289. /* space for optional per-rx queue attributes */
  290. const struct attribute_group *sysfs_rx_queue_group;
  291.  
  292. /* rtnetlink link ops */
  293. const struct rtnl_link_ops *rtnl_link_ops;
  294.  
  295. /* for setting kernel sock attribute on TCP connection setup */
  296. #define GSO_MAX_SIZE 65536
  297. unsigned int gso_max_size;
  298. #define GSO_MAX_SEGS 65535
  299. u16 gso_max_segs;
  300.  
  301. #ifdef CONFIG_DCB
  302. /* Data Center Bridging netlink ops */
  303. const struct dcbnl_rtnl_ops *dcbnl_ops;
  304. #endif
  305. u8 num_tc;
  306. struct netdev_tc_txq tc_to_txq[TC_MAX_QUEUE];
  307. u8 prio_tc_map[TC_BITMASK + ];
  308.  
  309. #if IS_ENABLED(CONFIG_FCOE)
  310. /* max exchange id for FCoE LRO by ddp */
  311. unsigned int fcoe_ddp_xid;
  312. #endif
  313. #if IS_ENABLED(CONFIG_CGROUP_NET_PRIO)
  314. struct netprio_map __rcu *priomap;
  315. #endif
  316. /* phy device may attach itself for hardware timestamping */
  317. struct phy_device *phydev;
  318.  
  319. struct lock_class_key *qdisc_tx_busylock;
  320.  
  321. /* group the device belongs to */
  322. int group;
  323.  
  324. struct pm_qos_request pm_qos_req;
  325. };

* Standard interface flags (netdevice->flags). */
#define IFF_UP 0x1 /* interface is up */
#define IFF_BROADCAST 0x2 /* broadcast address valid */
#define IFF_DEBUG 0x4 /* turn on debugging */
#define IFF_LOOPBACK 0x8 /* is a loopback net */
#define IFF_POINTOPOINT 0x10 /* interface is has p-p link */
#define IFF_NOTRAILERS 0x20 /* avoid use of trailers */
#define IFF_RUNNING 0x40 /* interface RFC2863 OPER_UP */
#define IFF_NOARP 0x80 /* no ARP protocol */
#define IFF_PROMISC 0x100 /* receive all packets */
#define IFF_ALLMULTI 0x200 /* receive all multicast packets*/

#define IFF_MASTER 0x400 /* master of a load balancer */
#define IFF_SLAVE 0x800 /* slave of a load balancer */

#define IFF_MULTICAST 0x1000 /* Supports multicast */

#define IFF_PORTSEL 0x2000 /* can set media type */

#define IFF_AUTOMEDIA 0x4000 /* auto media select active */
#define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses*/

  1.  

#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
#define IFF_DORMANT 0x20000 /* driver signals dormant */

  1.  

#define IFF_ECHO 0x40000 /* echo sent packets */

  1.  

#define IFF_VOLATILE (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_ECHO|\
IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)

  1.  

/* Private (from user) interface flags (netdevice->priv_flags). */
#define IFF_802_1Q_VLAN 0x1 /* 802.1Q VLAN device. */
#define IFF_EBRIDGE 0x2 /* Ethernet bridging device. */
#define IFF_SLAVE_INACTIVE 0x4 /* bonding slave not the curr. active */
#define IFF_MASTER_8023AD 0x8 /* bonding master, 802.3ad. */
#define IFF_MASTER_ALB 0x10 /* bonding master, balance-alb. */
#define IFF_BONDING 0x20 /* bonding master or slave */
#define IFF_SLAVE_NEEDARP 0x40 /* need ARPs for validation */
#define IFF_ISATAP 0x80 /* ISATAP interface (RFC4214) */
#define IFF_MASTER_ARPMON 0x100 /* bonding master, ARP mon in use */
#define IFF_WAN_HDLC 0x200 /* WAN HDLC device */
#define IFF_XMIT_DST_RELEASE 0x400 /* dev_hard_start_xmit() is allowed to
* release skb->dst
*/
#define IFF_DONT_BRIDGE 0x800 /* disallow bridging this ether dev */
#define IFF_DISABLE_NETPOLL 0x1000 /* disable netpoll at run-time */
#define IFF_MACVLAN_PORT 0x2000 /* device used as macvlan port */
#define IFF_BRIDGE_PORT 0x4000 /* device used as bridge port */
#define IFF_OVS_DATAPATH 0x8000 /* device used as Open vSwitch
* datapath port */
#define IFF_TX_SKB_SHARING 0x10000 /* The interface supports sharing
* skbs on transmit */
#define IFF_UNICAST_FLT 0x20000 /* Supports unicast filtering */
#define IFF_TEAM_PORT 0x40000 /* device used as team port */
#define IFF_SUPP_NOFCS 0x80000 /* device supports sending custom FCS */
#define IFF_LIVE_ADDR_CHANGE 0x100000 /* device supports hardware address
* change when it's running */
#define IFF_MACVLAN 0x200000 /* Macvlan device */

net_device中的一个重要结构体是net_device_ops,驱动需要填充里面的成员。

  1. /*
  2. * This structure defines the management hooks for network devices.
  3. * The following hooks can be defined; unless noted otherwise, they are
  4. * optional and can be filled with a null pointer.
  5. *
  6. * int (*ndo_init)(struct net_device *dev);
  7. * This function is called once when network device is registered.
  8. * The network device can use this to any late stage initializaton
  9. * or semantic validattion. It can fail with an error code which will
  10. * be propogated back to register_netdev
  11. *
  12. * void (*ndo_uninit)(struct net_device *dev);
  13. * This function is called when device is unregistered or when registration
  14. * fails. It is not called if init fails.
  15. *
  16. * int (*ndo_open)(struct net_device *dev);一般在次获取设备需要的IO地址、IRQ、DMA通道等
  17. * This function is called when network device transistions to the up
  18. * state.
  19. *
  20. * int (*ndo_stop)(struct net_device *dev);
  21. * This function is called when network device transistions to the down
  22. * state.
  23. *
  24. * netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb,
  25. * struct net_device *dev);
  26. * Called when a packet needs to be transmitted.
  27. * Must return NETDEV_TX_OK , NETDEV_TX_BUSY.
  28. * (can also return NETDEV_TX_LOCKED iff NETIF_F_LLTX)
  29. * Required can not be NULL.  不能为空,必须实现,启动发送
  30. *
  31. * u16 (*ndo_select_queue)(struct net_device *dev, struct sk_buff *skb,
  32. * void *accel_priv, select_queue_fallback_t fallback);
  33. * Called to decide which queue to when device supports multiple
  34. * transmit queues.
  35. *
  36. * void (*ndo_change_rx_flags)(struct net_device *dev, int flags);
  37. * This function is called to allow device receiver to make
  38. * changes to configuration when multicast or promiscious is enabled.
  39. *
  40. * void (*ndo_set_rx_mode)(struct net_device *dev);
  41. * This function is called device changes address list filtering.
  42. * If driver handles unicast address filtering, it should set
  43. * IFF_UNICAST_FLT to its priv_flags.
  44. *
  45. * int (*ndo_set_mac_address)(struct net_device *dev, void *addr);
  46. * This function is called when the Media Access Control address
  47. * needs to be changed. If this interface is not defined, the
  48. * mac address can not be changed.
  49. *
  50. * int (*ndo_validate_addr)(struct net_device *dev);
  51. * Test if Media Access Control address is valid for the device.
  52. *
  53. * int (*ndo_do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
  54. * Called when a user request an ioctl which can't be handled by
  55. * the generic interface code. If not defined ioctl's return
  56. * not supported error code.
  57. *
  58. * int (*ndo_set_config)(struct net_device *dev, struct ifmap *map);
  59. * Used to set network devices bus interface parameters. This interface
  60. * is retained for legacy reason, new devices should use the bus
  61. * interface (PCI) for low level management.  配置接口,也可以改变设备IO地址和中断号
  62. *
  63. * int (*ndo_change_mtu)(struct net_device *dev, int new_mtu);
  64. * Called when a user wants to change the Maximum Transfer Unit
  65. * of a device. If not defined, any request to change MTU will
  66. * will return an error.
  67. *
  68. * void (*ndo_tx_timeout)(struct net_device *dev);
  69. * Callback uses when the transmitter has not made any progress
  70. * for dev->watchdog ticks. 发送超时以后调用
  71. *
  72. * struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev,
  73. * struct rtnl_link_stats64 *storage);
  74. * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);    返回的结构体包含若干统计信息
  75. * Called when a user wants to get the network device usage
  76. * statistics. Drivers must do one of the following:
  77. * 1. Define @ndo_get_stats64 to fill in a zero-initialised
  78. * rtnl_link_stats64 structure passed by the caller.
  79. * 2. Define @ndo_get_stats to update a net_device_stats structure
  80. * (which should normally be dev->stats) and return a pointer to
  81. * it. The structure may be changed asynchronously only if each
  82. * field is written atomically.
  83. * 3. Update dev->stats asynchronously and atomically, and define
  84. * neither operation.
  85. *
  86. * int (*ndo_vlan_rx_add_vid)(struct net_device *dev, __be16 proto, u16t vid);
  87. * If device support VLAN filtering this function is called when a
  88. * VLAN id is registered.
  89. *
  90. * int (*ndo_vlan_rx_kill_vid)(struct net_device *dev, unsigned short vid);
  91. * If device support VLAN filtering this function is called when a
  92. * VLAN id is unregistered.
  93. *
  94. * void (*ndo_poll_controller)(struct net_device *dev);
  95. *
  96. * SR-IOV management functions.
  97. * int (*ndo_set_vf_mac)(struct net_device *dev, int vf, u8* mac);
  98. * int (*ndo_set_vf_vlan)(struct net_device *dev, int vf, u16 vlan, u8 qos);
  99. * int (*ndo_set_vf_tx_rate)(struct net_device *dev, int vf, int rate);
  100. * int (*ndo_set_vf_spoofchk)(struct net_device *dev, int vf, bool setting);
  101. * int (*ndo_get_vf_config)(struct net_device *dev,
  102. * int vf, struct ifla_vf_info *ivf);
  103. * int (*ndo_set_vf_link_state)(struct net_device *dev, int vf, int link_state);
  104. * int (*ndo_set_vf_port)(struct net_device *dev, int vf,
  105. * struct nlattr *port[]);
  106. * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
  107. * int (*ndo_setup_tc)(struct net_device *dev, u8 tc)
  108. * Called to setup 'tc' number of traffic classes in the net device. This
  109. * is always called from the stack with the rtnl lock held and netif tx
  110. * queues stopped. This allows the netdevice to perform queue management
  111. * safely.
  112. *
  113. * Fiber Channel over Ethernet (FCoE) offload functions.
  114. * int (*ndo_fcoe_enable)(struct net_device *dev);
  115. * Called when the FCoE protocol stack wants to start using LLD for FCoE
  116. * so the underlying device can perform whatever needed configuration or
  117. * initialization to support acceleration of FCoE traffic.
  118. *
  119. * int (*ndo_fcoe_disable)(struct net_device *dev);
  120. * Called when the FCoE protocol stack wants to stop using LLD for FCoE
  121. * so the underlying device can perform whatever needed clean-ups to
  122. * stop supporting acceleration of FCoE traffic.
  123. *
  124. * int (*ndo_fcoe_ddp_setup)(struct net_device *dev, u16 xid,
  125. * struct scatterlist *sgl, unsigned int sgc);
  126. * Called when the FCoE Initiator wants to initialize an I/O that
  127. * is a possible candidate for Direct Data Placement (DDP). The LLD can
  128. * perform necessary setup and returns 1 to indicate the device is set up
  129. * successfully to perform DDP on this I/O, otherwise this returns 0.
  130. *
  131. * int (*ndo_fcoe_ddp_done)(struct net_device *dev, u16 xid);
  132. * Called when the FCoE Initiator/Target is done with the DDPed I/O as
  133. * indicated by the FC exchange id 'xid', so the underlying device can
  134. * clean up and reuse resources for later DDP requests.
  135. *
  136. * int (*ndo_fcoe_ddp_target)(struct net_device *dev, u16 xid,
  137. * struct scatterlist *sgl, unsigned int sgc);
  138. * Called when the FCoE Target wants to initialize an I/O that
  139. * is a possible candidate for Direct Data Placement (DDP). The LLD can
  140. * perform necessary setup and returns 1 to indicate the device is set up
  141. * successfully to perform DDP on this I/O, otherwise this returns 0.
  142. *
  143. * int (*ndo_fcoe_get_hbainfo)(struct net_device *dev,
  144. * struct netdev_fcoe_hbainfo *hbainfo);
  145. * Called when the FCoE Protocol stack wants information on the underlying
  146. * device. This information is utilized by the FCoE protocol stack to
  147. * register attributes with Fiber Channel management service as per the
  148. * FC-GS Fabric Device Management Information(FDMI) specification.
  149. *
  150. * int (*ndo_fcoe_get_wwn)(struct net_device *dev, u64 *wwn, int type);
  151. * Called when the underlying device wants to override default World Wide
  152. * Name (WWN) generation mechanism in FCoE protocol stack to pass its own
  153. * World Wide Port Name (WWPN) or World Wide Node Name (WWNN) to the FCoE
  154. * protocol stack to use.
  155. *
  156. * RFS acceleration.
  157. * int (*ndo_rx_flow_steer)(struct net_device *dev, const struct sk_buff *skb,
  158. * u16 rxq_index, u32 flow_id);
  159. * Set hardware filter for RFS. rxq_index is the target queue index;
  160. * flow_id is a flow ID to be passed to rps_may_expire_flow() later.
  161. * Return the filter ID on success, or a negative error code.
  162. *
  163. * Slave management functions (for bridge, bonding, etc).
  164. * int (*ndo_add_slave)(struct net_device *dev, struct net_device *slave_dev);
  165. * Called to make another netdev an underling.
  166. *
  167. * int (*ndo_del_slave)(struct net_device *dev, struct net_device *slave_dev);
  168. * Called to release previously enslaved netdev.
  169. *
  170. * Feature/offload setting functions.
  171. * netdev_features_t (*ndo_fix_features)(struct net_device *dev,
  172. * netdev_features_t features);
  173. * Adjusts the requested feature flags according to device-specific
  174. * constraints, and returns the resulting flags. Must not modify
  175. * the device state.
  176. *
  177. * int (*ndo_set_features)(struct net_device *dev, netdev_features_t features);
  178. * Called to update device configuration to new features. Passed
  179. * feature set might be less than what was returned by ndo_fix_features()).
  180. * Must return >0 or -errno if it changed dev->features itself.
  181. *
  182. * int (*ndo_fdb_add)(struct ndmsg *ndm, struct nlattr *tb[],
  183. * struct net_device *dev,
  184. * const unsigned char *addr, u16 flags)
  185. * Adds an FDB entry to dev for addr.
  186. * int (*ndo_fdb_del)(struct ndmsg *ndm, struct nlattr *tb[],
  187. * struct net_device *dev,
  188. * const unsigned char *addr)
  189. * Deletes the FDB entry from dev coresponding to addr.
  190. * int (*ndo_fdb_dump)(struct sk_buff *skb, struct netlink_callback *cb,
  191. * struct net_device *dev, int idx)
  192. * Used to add FDB entries to dump requests. Implementers should add
  193. * entries to skb and update idx with the number of entries.
  194. *
  195. * int (*ndo_bridge_setlink)(struct net_device *dev, struct nlmsghdr *nlh)
  196. * int (*ndo_bridge_getlink)(struct sk_buff *skb, u32 pid, u32 seq,
  197. * struct net_device *dev, u32 filter_mask)
  198. *
  199. * int (*ndo_change_carrier)(struct net_device *dev, bool new_carrier);
  200. * Called to change device carrier. Soft-devices (like dummy, team, etc)
  201. * which do not represent real hardware may define this to allow their
  202. * userspace components to manage their virtual carrier state. Devices
  203. * that determine carrier state from physical hardware properties (eg
  204. * network cables) or protocol-dependent mechanisms (eg
  205. * USB_CDC_NOTIFY_NETWORK_CONNECTION) should NOT implement this function.
  206. *
  207. * int (*ndo_get_phys_port_id)(struct net_device *dev,
  208. * struct netdev_phys_port_id *ppid);
  209. * Called to get ID of physical port of this device. If driver does
  210. * not implement this, it is assumed that the hw is not able to have
  211. * multiple net devices on single physical port.
  212. *
  213. * void (*ndo_add_vxlan_port)(struct net_device *dev,
  214. * sa_family_t sa_family, __be16 port);
  215. * Called by vxlan to notiy a driver about the UDP port and socket
  216. * address family that vxlan is listnening to. It is called only when
  217. * a new port starts listening. The operation is protected by the
  218. * vxlan_net->sock_lock.
  219. *
  220. * void (*ndo_del_vxlan_port)(struct net_device *dev,
  221. * sa_family_t sa_family, __be16 port);
  222. * Called by vxlan to notify the driver about a UDP port and socket
  223. * address family that vxlan is not listening to anymore. The operation
  224. * is protected by the vxlan_net->sock_lock.
  225. *
  226. * void* (*ndo_dfwd_add_station)(struct net_device *pdev,
  227. * struct net_device *dev)
  228. * Called by upper layer devices to accelerate switching or other
  229. * station functionality into hardware. 'pdev is the lowerdev
  230. * to use for the offload and 'dev' is the net device that will
  231. * back the offload. Returns a pointer to the private structure
  232. * the upper layer will maintain.
  233. * void (*ndo_dfwd_del_station)(struct net_device *pdev, void *priv)
  234. * Called by upper layer device to delete the station created
  235. * by 'ndo_dfwd_add_station'. 'pdev' is the net device backing
  236. * the station and priv is the structure returned by the add
  237. * operation.
  238. * netdev_tx_t (*ndo_dfwd_start_xmit)(struct sk_buff *skb,
  239. * struct net_device *dev,
  240. * void *priv);
  241. * Callback to use for xmit over the accelerated station. This
  242. * is used in place of ndo_start_xmit on accelerated net
  243. * devices.
  244. */
  245. struct net_device_ops {
  246. int (*ndo_init)(struct net_device *dev);
  247. void (*ndo_uninit)(struct net_device *dev);
  248. int (*ndo_open)(struct net_device *dev);
  249. int (*ndo_stop)(struct net_device *dev);
  250. netdev_tx_t (*ndo_start_xmit) (struct sk_buff *skb,
  251. struct net_device *dev);
  252. u16 (*ndo_select_queue)(struct net_device *dev,
  253. struct sk_buff *skb,
  254. void *accel_priv,
  255. select_queue_fallback_t fallback);
  256. void (*ndo_change_rx_flags)(struct net_device *dev,
  257. int flags);
  258. void (*ndo_set_rx_mode)(struct net_device *dev);
  259. int (*ndo_set_mac_address)(struct net_device *dev,
  260. void *addr);
  261. int (*ndo_validate_addr)(struct net_device *dev);
  262. int (*ndo_do_ioctl)(struct net_device *dev,
  263. struct ifreq *ifr, int cmd);
  264. int (*ndo_set_config)(struct net_device *dev,
  265. struct ifmap *map);
  266. int (*ndo_change_mtu)(struct net_device *dev,
  267. int new_mtu);
  268. int (*ndo_neigh_setup)(struct net_device *dev,
  269. struct neigh_parms *);
  270. void (*ndo_tx_timeout) (struct net_device *dev);
  271.  
  272. struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev,
  273. struct rtnl_link_stats64 *storage);
  274. struct net_device_stats* (*ndo_get_stats)(struct net_device *dev);
  275.  
  276. int (*ndo_vlan_rx_add_vid)(struct net_device *dev,
  277. __be16 proto, u16 vid);
  278. int (*ndo_vlan_rx_kill_vid)(struct net_device *dev,
  279. __be16 proto, u16 vid);
  280. #ifdef CONFIG_NET_POLL_CONTROLLER
  281. void (*ndo_poll_controller)(struct net_device *dev);
  282. int (*ndo_netpoll_setup)(struct net_device *dev,
  283. struct netpoll_info *info,
  284. gfp_t gfp);
  285. void (*ndo_netpoll_cleanup)(struct net_device *dev);
  286. #endif
  287. #ifdef CONFIG_NET_RX_BUSY_POLL
  288. int (*ndo_busy_poll)(struct napi_struct *dev);
  289. #endif
  290. int (*ndo_set_vf_mac)(struct net_device *dev,
  291. int queue, u8 *mac);
  292. int (*ndo_set_vf_vlan)(struct net_device *dev,
  293. int queue, u16 vlan, u8 qos);
  294. int (*ndo_set_vf_tx_rate)(struct net_device *dev,
  295. int vf, int rate);
  296. int (*ndo_set_vf_spoofchk)(struct net_device *dev,
  297. int vf, bool setting);
  298. int (*ndo_get_vf_config)(struct net_device *dev,
  299. int vf,
  300. struct ifla_vf_info *ivf);
  301. int (*ndo_set_vf_link_state)(struct net_device *dev,
  302. int vf, int link_state);
  303. int (*ndo_set_vf_port)(struct net_device *dev,
  304. int vf,
  305. struct nlattr *port[]);
  306. int (*ndo_get_vf_port)(struct net_device *dev,
  307. int vf, struct sk_buff *skb);
  308. int (*ndo_setup_tc)(struct net_device *dev, u8 tc);
  309. #if IS_ENABLED(CONFIG_FCOE)
  310. int (*ndo_fcoe_enable)(struct net_device *dev);
  311. int (*ndo_fcoe_disable)(struct net_device *dev);
  312. int (*ndo_fcoe_ddp_setup)(struct net_device *dev,
  313. u16 xid,
  314. struct scatterlist *sgl,
  315. unsigned int sgc);
  316. int (*ndo_fcoe_ddp_done)(struct net_device *dev,
  317. u16 xid);
  318. int (*ndo_fcoe_ddp_target)(struct net_device *dev,
  319. u16 xid,
  320. struct scatterlist *sgl,
  321. unsigned int sgc);
  322. int (*ndo_fcoe_get_hbainfo)(struct net_device *dev,
  323. struct netdev_fcoe_hbainfo *hbainfo);
  324. #endif
  325.  
  326. #if IS_ENABLED(CONFIG_LIBFCOE)
  327. #define NETDEV_FCOE_WWNN 0
  328. #define NETDEV_FCOE_WWPN 1
  329. int (*ndo_fcoe_get_wwn)(struct net_device *dev,
  330. u64 *wwn, int type);
  331. #endif
  332.  
  333. #ifdef CONFIG_RFS_ACCEL
  334. int (*ndo_rx_flow_steer)(struct net_device *dev,
  335. const struct sk_buff *skb,
  336. u16 rxq_index,
  337. u32 flow_id);
  338. #endif
  339. int (*ndo_add_slave)(struct net_device *dev,
  340. struct net_device *slave_dev);
  341. int (*ndo_del_slave)(struct net_device *dev,
  342. struct net_device *slave_dev);
  343. netdev_features_t (*ndo_fix_features)(struct net_device *dev,
  344. netdev_features_t features);
  345. int (*ndo_set_features)(struct net_device *dev,
  346. netdev_features_t features);
  347. int (*ndo_neigh_construct)(struct neighbour *n);
  348. void (*ndo_neigh_destroy)(struct neighbour *n);
  349.  
  350. int (*ndo_fdb_add)(struct ndmsg *ndm,
  351. struct nlattr *tb[],
  352. struct net_device *dev,
  353. const unsigned char *addr,
  354. u16 flags);
  355. int (*ndo_fdb_del)(struct ndmsg *ndm,
  356. struct nlattr *tb[],
  357. struct net_device *dev,
  358. const unsigned char *addr);
  359. int (*ndo_fdb_dump)(struct sk_buff *skb,
  360. struct netlink_callback *cb,
  361. struct net_device *dev,
  362. int idx);
  363.  
  364. int (*ndo_bridge_setlink)(struct net_device *dev,
  365. struct nlmsghdr *nlh);
  366. int (*ndo_bridge_getlink)(struct sk_buff *skb,
  367. u32 pid, u32 seq,
  368. struct net_device *dev,
  369. u32 filter_mask);
  370. int (*ndo_bridge_dellink)(struct net_device *dev,
  371. struct nlmsghdr *nlh);
  372. int (*ndo_change_carrier)(struct net_device *dev,
  373. bool new_carrier);
  374. int (*ndo_get_phys_port_id)(struct net_device *dev,
  375. struct netdev_phys_port_id *ppid);
  376. void (*ndo_add_vxlan_port)(struct net_device *dev,
  377. sa_family_t sa_family,
  378. __be16 port);
  379. void (*ndo_del_vxlan_port)(struct net_device *dev,
  380. sa_family_t sa_family,
  381. __be16 port);
  382.  
  383. void* (*ndo_dfwd_add_station)(struct net_device *pdev,
  384. struct net_device *dev);
  385. void (*ndo_dfwd_del_station)(struct net_device *pdev,
  386. void *priv);
  387.  
  388. netdev_tx_t (*ndo_dfwd_start_xmit) (struct sk_buff *skb,
  389. struct net_device *dev,
  390. void *priv);
  391. };

14.2 注册与注销

14.2.1 注册与注销

register时,net_device的net_device_ops的ndo_init()会执行。

  1. /**
  2. * register_netdev - register a network device
  3. * @dev: device to register
  4. *
  5. * Take a completed network device structure and add it to the kernel
  6. * interfaces. A %NETDEV_REGISTER message is sent to the netdev notifier
  7. * chain. 0 is returned on success. A negative errno code is returned
  8. * on a failure to set up the device, or if the name is a duplicate.
  9. *
  10. * This is a wrapper around register_netdevice that takes the rtnl semaphore
  11. * and expands the device name if you passed a format string to
  12. * alloc_netdev.
  13. */
  14. int register_netdev(struct net_device *dev);
  15.  
  16. /**
  17. * unregister_netdev - remove device from the kernel
  18. * @dev: device
  19. *
  20. * This function shuts down a device interface and removes it
  21. * from the kernel tables.
  22. *
  23. * This is just a wrapper for unregister_netdevice that takes
  24. * the rtnl semaphore. In general you want to use this and not
  25. * unregister_netdevice.
  26. */
  27. void unregister_netdev(struct net_device *dev);

14.2.2 申请和释放

可以自己定义net_device结构体,也可以动态申请和释放空间。

  1. // sizeof_priv是自定义数据结构的大小
    // setup是动态申请后,自动执行的初始化函数,下面两个ether申请函数,都有默认的setup函数
    #define alloc_netdev(sizeof_priv, name, setup) \
  2. alloc_netdev_mqs(sizeof_priv, name, setup, , )
  3. #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1)
  4. #define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count)
  5.  
  6. /**
  7. * alloc_etherdev_mqs - Allocates and sets up an Ethernet device
  8. * @sizeof_priv: Size of additional driver-private structure to be allocated
  9. * for this Ethernet device
  10. * @txqs: The number of TX queues this device has.
  11. * @rxqs: The number of RX queues this device has.
  12. *
  13. * Fill in the fields of the device structure with Ethernet-generic
  14. * values. Basically does everything except registering the device.
  15. *
  16. * Constructs a new net device, complete with a private data area of
  17. * size (sizeof_priv). A 32-byte (not bit) alignment is enforced for
  18. * this private data area.
  19. */
  20.  
  21. struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs,
  22. unsigned int rxqs)
  23. {
  24. return alloc_netdev_mqs(sizeof_priv, "eth%d", ether_setup, txqs, rxqs);
  25. }
  26.  
  27. /**
  28. * alloc_netdev_mqs - allocate network device
  29. * @sizeof_priv: size of private data to allocate space for
  30. * @name: device name format string
  31. * @setup: callback to initialize device
  32. * @txqs: the number of TX subqueues to allocate
  33. * @rxqs: the number of RX subqueues to allocate
  34. *
  35. * Allocates a struct net_device with private data area for driver use
  36. * and performs basic initialization. Also allocates subqueue structs
  37. * for each queue on the device.
  38. */
  39. struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
  40. void (*setup)(struct net_device *),
  41. unsigned int txqs, unsigned int rxqs)
  42. {
  43. struct net_device *dev;
  44. size_t alloc_size;
  45. struct net_device *p;
  46.  
  47. BUG_ON(strlen(name) >= sizeof(dev->name));
  48.  
  49. if (txqs < ) {
  50. pr_err("alloc_netdev: Unable to allocate device with zero queues\n");
  51. return NULL;
  52. }
  53.  
  54. #ifdef CONFIG_SYSFS
  55. if (rxqs < ) {
  56. pr_err("alloc_netdev: Unable to allocate device with zero RX queues\n");
  57. return NULL;
  58. }
  59. #endif
  60.  
  61. alloc_size = sizeof(struct net_device);
  62. if (sizeof_priv) {
  63. /* ensure 32-byte alignment of private area */
  64. alloc_size = ALIGN(alloc_size, NETDEV_ALIGN);
  65. alloc_size += sizeof_priv;
  66. }
  67. /* ensure 32-byte alignment of whole construct */
  68. alloc_size += NETDEV_ALIGN - ;
  69.  
  70. p = kzalloc(alloc_size, GFP_KERNEL | __GFP_NOWARN | __GFP_REPEAT);
  71. if (!p)
  72. p = vzalloc(alloc_size);
  73. if (!p)
  74. return NULL;
  75.  
  76. dev = PTR_ALIGN(p, NETDEV_ALIGN);
  77. dev->padded = (char *)dev - (char *)p;
  78.  
  79. dev->pcpu_refcnt = alloc_percpu(int);
  80. if (!dev->pcpu_refcnt)
  81. goto free_dev;
  82.  
  83. if (dev_addr_init(dev))
  84. goto free_pcpu;
  85.  
  86. dev_mc_init(dev);
  87. dev_uc_init(dev);
  88.  
  89. dev_net_set(dev, &init_net);
  90.  
  91. dev->gso_max_size = GSO_MAX_SIZE;
  92. dev->gso_max_segs = GSO_MAX_SEGS;
  93.  
  94. INIT_LIST_HEAD(&dev->napi_list);
  95. INIT_LIST_HEAD(&dev->unreg_list);
  96. INIT_LIST_HEAD(&dev->close_list);
  97. INIT_LIST_HEAD(&dev->link_watch_list);
  98. INIT_LIST_HEAD(&dev->adj_list.upper);
  99. INIT_LIST_HEAD(&dev->adj_list.lower);
  100. INIT_LIST_HEAD(&dev->all_adj_list.upper);
  101. INIT_LIST_HEAD(&dev->all_adj_list.lower);
  102. dev->priv_flags = IFF_XMIT_DST_RELEASE;
  103. setup(dev);
  104.  
  105. dev->num_tx_queues = txqs;
  106. dev->real_num_tx_queues = txqs;
  107. if (netif_alloc_netdev_queues(dev))
  108. goto free_all;
  109.  
  110. #ifdef CONFIG_SYSFS
  111. dev->num_rx_queues = rxqs;
  112. dev->real_num_rx_queues = rxqs;
  113. if (netif_alloc_rx_queues(dev))
  114. goto free_all;
  115. #endif
  116.  
  117. strcpy(dev->name, name);
  118. dev->group = INIT_NETDEV_GROUP;
  119. if (!dev->ethtool_ops)
  120. dev->ethtool_ops = &default_ethtool_ops;
  121. return dev;
  122.  
  123. free_all:
  124. free_netdev(dev);
  125. return NULL;
  126.  
  127. free_pcpu:
  128. free_percpu(dev->pcpu_refcnt);
  129. netif_free_tx_queues(dev);
  130. #ifdef CONFIG_SYSFS
  131. kfree(dev->_rx);
  132. #endif
  133.  
  134. free_dev:
  135. netdev_freemem(dev);
  136. return NULL;
  137. }
  138.  
  139. // 释放net_device
    void free_netdev(struct net_device *dev);

模板:

  1. static int xxx_register(void)
  2. {
  3. ...
  4.  
  5. /* 分配 net_device 结构体并对其成员赋值 */
  6. xxx_dev = alloc_netdev(sizeof(struct xxx_priv), "sn%d", xxx_init);
  7. if (xxx_dev == NULL)
  8. ... /* 分配 net_device 失败 */
  9.  
  10. /* 注册 net_device 结构体 */
  11. if ((result = register_netdev(xxx_dev)))
  12. ...
  13. }
  14.  
  15. static void xxx_unregister(void)
  16. {
  17. ...
  18. /* 注销 net_device 结构体 */
  19. unregister_netdev(xxx_dev);
  20. /* 释放 net_device 结构体 */
  21. free_netdev(xxx_dev);
  22. }

14.3 初始化ndo_init()

向内核register时,ndo_init()函数会被执行。

  1. int register_netdev(struct net_device *dev)
  2. {
  3. int err;
  4.  
  5. rtnl_lock();
  6. err = register_netdevice(dev);
  7. rtnl_unlock();
  8. return err;
  9. }
  10.  
  11. int register_netdevice(struct net_device *dev)
  12. {
  13. ...
  14. /* Init, if this function is available */
  15. if (dev->netdev_ops->ndo_init) {
  16. ret = dev->netdev_ops->ndo_init(dev);
  17. if (ret) {
  18. if (ret > )
  19. ret = -EIO;
  20. goto out;
  21. }
  22. }
  23. ...
  24. }

ndo_init()要干的事:

  • 准备硬件
  • 初始化net_device结构体的相关内容
  • 获取私有指针,并初始化

ndo_init()模板:

  1. xxx_netdev_ops.ndo_init = xxx_init;
  1. void xxx_init(struct net_device *dev)
  2. {
  3. /* 设备的私有信息结构体 */
  4. struct xxx_priv *priv;
  5.  
  6. /* 检查设备是否存在和设备所使用的硬件资源 */
  7. xxx_hw_init();
  8.  
  9. /* 初始化以太网设备的公用成员 */
  10. ether_setup(dev);
  11.  
  12. /* 设置设备的成员函数指针 */
  13. ndev->netdev_ops = &xxx_netdev_ops;
  14. ndev->ethtool_ops = &xxx_ethtool_ops;
  15. dev->watchdog_timeo = timeout;
  16.  
  17. /* 取得私有信息, 并初始化它 */
  18. priv = netdev_priv(dev);
  19. ... /* 初始化设备私有数据区 */
  20. }

14.4 打开和释放ndo_open()/ndo_stop()

ndo_open()的工作:

  • 使能硬件资源,申请IO区域、中断和DMA通道等;
  • 调用netif_start_queue()函数,激活设备发送队列

ndo_stop()的工作:

  • 调用netif_stop_queue()函数,停止设备发送队列
  • 释放IO区域、中断和DMA资源  
  1. 原来这两个函数只针对 tx queue
    /**
  2. * netif_start_queue - allow transmit
  3. * @dev: network device
  4. *
  5. * Allow upper layers to call the device hard_start_xmit routine.
  6. */
  7. static inline void netif_start_queue(struct net_device *dev)
  8. {
  9. netif_tx_start_queue(netdev_get_tx_queue(dev, ));
  10. }
  11. /**
  12. * netif_stop_queue - stop transmitted packets
  13. * @dev: network device
  14. *
  15. * Stop upper layers calling the device hard_start_xmit routine.
  16. * Used for flow control when transmit resources are unavailable.
  17. */
  18. static inline void netif_stop_queue(struct net_device *dev)
  19. {
  20. netif_tx_stop_queue(netdev_get_tx_queue(dev, ));
  21. }

/**
* netif_wake_queue - restart transmit
* @dev: network device
*
* Allow upper layers to call the device hard_start_xmit routine.
* Used for flow control when transmit resources are available.
*/
static inline void netif_wake_queue(struct net_device *dev)
{
  netif_tx_wake_queue(netdev_get_tx_queue(dev, 0));
}

  1.  

模板:

  1.  
  1. xxx_netdev_ops.ndo_open = xxx_open;
  1. xxx_netdev_ops.ndo_stop = xxx_stop;
  1. static int xxx_open(struct net_device *dev)
  2. {
  3. /* 申请端口、 IRQ 等, 类似于 fops->open */
  4. ret = request_irq(dev->irq, &xxx_interrupt, , dev->name, dev);
  5. ...
  6. netif_start_queue(dev);
  7. ...
  8. }
  9.  
  10. static int xxx_stop(struct net_device *dev)
  11. {
  12. /* 释放端口、 IRQ 等, 类似于 fops->close */
  13. free_irq(dev->irq, dev);
  14. ...
  15. netif_stop_queue(dev); /* can't transmit any more */
  16. ...
  17. }

14.5 发送 ndo_start_xmit()/ndo_tx_timeout()

ndo_start_xmit()主要流程:

  • 解析sk_buff,缓存有效数据
  • 校验数据长度,若小于ETH_ZLEN(60,不包含FCS),则尾部填充0
  • 控制硬件发送数据
  1. int xxx_tx(struct sk_buff *skb, struct net_device *dev)
  2. {
  3. int len;
  4. char *data, shortpkt[ETH_ZLEN];
  5. if (xxx_send_available(...)) { /* 发送队列未满, 可以发送 */
  6. /* 获得有效数据指针和长度 */
  7. data = skb->data;
  8. len = skb->len;
  9. if (len < ETH_ZLEN) {
  10.   /* 如果帧长小于以太网帧最小长度, 补 0 */
  11.   memset(shortpkt, , ETH_ZLEN);
  12.    memcpy(shortpkt, skb->data, skb->len);
  13.   len = ETH_ZLEN;
  14.    data = shortpkt;
         }
  15.  
  16.    dev->trans_start = jiffies; /* 记录发送时间戳 */
  17.  
  18.    if (avail) {/* 设置硬件寄存器, 让硬件把数据包发送出去 */
  19.   xxx_hw_tx(data, len, dev);
  20.   } else {
  21.   netif_stop_queue(dev);  // 不一定非要这么搞,返回busy也可以,如果调用了,需要在TX结束中断或者超时中断里唤醒
  22.   ...
  23.   }
  24.   }
    }
  25.  
  26. void xxx_tx_timeout(struct net_device *dev)
    {
      ...
      netif_wake_queue(dev); /* 重新启动设备发送队列 */
  27. }

14.6 接收

没有固定形式,在需要的地方调用netif_rx()即可。

  1. static void xxx_interrupt(int irq, void *dev_id)
  2. {
  3. ...
  4. switch (status &ISQ_EVENT_MASK) {
  5. case ISQ_RECEIVER_EVENT:
  6. /* 获取数据包 */
  7. xxx_rx(dev);
  8. break;
  9. /* 其他类型的中断 */
  10. }
  11. }
  12.  
  13. static void xxx_rx(struct xxx_device *dev)
  14. {
  15. ...
  16. length = get_rev_len (...);
  17. /* 分配新的套接字缓冲区 */
  18. skb = dev_alloc_skb(length + );
  19.  
  20. skb_reserve(skb, ); /* 对齐 */
  21. skb->dev = dev;
  22.  
  23. /* 读取硬件上接收到的数据 */
  24. insw(ioaddr + RX_FRAME_PORT, skb_put(skb, length), length >> );
  25. if (length &)
  26. skb->data[length - ] = inw(ioaddr + RX_FRAME_PORT);
  27.  
  28. /* 获取上层协议类型 */
  29. skb->protocol = eth_type_trans(skb, dev);
  30.  
  31. /* 把数据包交给上层 */
  32. netif_rx(skb);
  33.  
  34. /* 记录接收时间戳 */
  35. dev->last_rx = jiffies;
  36. ...
  37. }

14.7 连接状态

一般在定时中断里,检查并更新连接状态。

  1. static inline bool netif_carrier_ok(const struct net_device *dev);  // 连接是否ok
  2. void netif_carrier_on(struct net_device *dev);              // 改变连接状态,on
  3. void netif_carrier_off(struct net_device *dev);             // 改变连接状态,off

14.8 参数设置和统计数据

参数设置可以通过ioctl(),传入的描述符为socket,linux对命令做了统一规定,如下:

  1. /*路径: include/uapi/linux/sockios.h */
  2. /*
  3. * INET An implementation of the TCP/IP protocol suite for the LINUX
  4. * operating system. INET is implemented using the BSD Socket
  5. * interface as the means of communication with the user level.
  6. *
  7. * Definitions of the socket-level I/O control calls.
  8. *
  9. * Version: @(#)sockios.h 1.0.2 03/09/93
  10. *
  11. * Authors: Ross Biro
  12. * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version
  17. * 2 of the License, or (at your option) any later version.
  18. */
  19. #ifndef _LINUX_SOCKIOS_H
  20. #define _LINUX_SOCKIOS_H
  21.  
  22. #include <asm/sockios.h>
  23.  
  24. /* Linux-specific socket ioctls */
  25. #define SIOCINQ FIONREAD
  26. #define SIOCOUTQ TIOCOUTQ /* output queue size (not sent + not acked) */
  27.  
  28. /* Routing table calls. */
  29. #define SIOCADDRT 0x890B /* add routing table entry */
  30. #define SIOCDELRT 0x890C /* delete routing table entry */
  31. #define SIOCRTMSG 0x890D /* call to routing system */
  32.  
  33. /* Socket configuration controls. */
  34. #define SIOCGIFNAME 0x8910 /* get iface name */
  35. #define SIOCSIFLINK 0x8911 /* set iface channel */
  36. #define SIOCGIFCONF 0x8912 /* get iface list */
  37. #define SIOCGIFFLAGS 0x8913 /* get flags */
  38. #define SIOCSIFFLAGS 0x8914 /* set flags */
  39. #define SIOCGIFADDR 0x8915 /* get PA address */
  40. #define SIOCSIFADDR 0x8916 /* set PA address */
  41. #define SIOCGIFDSTADDR 0x8917 /* get remote PA address */
  42. #define SIOCSIFDSTADDR 0x8918 /* set remote PA address */
  43. #define SIOCGIFBRDADDR 0x8919 /* get broadcast PA address */
  44. #define SIOCSIFBRDADDR 0x891a /* set broadcast PA address */
  45. #define SIOCGIFNETMASK 0x891b /* get network PA mask */
  46. #define SIOCSIFNETMASK 0x891c /* set network PA mask */
  47. #define SIOCGIFMETRIC 0x891d /* get metric */
  48. #define SIOCSIFMETRIC 0x891e /* set metric */
  49. #define SIOCGIFMEM 0x891f /* get memory address (BSD) */
  50. #define SIOCSIFMEM 0x8920 /* set memory address (BSD) */
  51. #define SIOCGIFMTU 0x8921 /* get MTU size */
  52. #define SIOCSIFMTU 0x8922 /* set MTU size */
  53. #define SIOCSIFNAME 0x8923 /* set interface name */
  54. #define SIOCSIFHWADDR 0x8924 /* set hardware address */
  55. #define SIOCGIFENCAP 0x8925 /* get/set encapsulations */
  56. #define SIOCSIFENCAP 0x8926
  57. #define SIOCGIFHWADDR 0x8927 /* Get hardware address */
  58. #define SIOCGIFSLAVE 0x8929 /* Driver slaving support */
  59. #define SIOCSIFSLAVE 0x8930
  60. #define SIOCADDMULTI 0x8931 /* Multicast address lists */
  61. #define SIOCDELMULTI 0x8932
  62. #define SIOCGIFINDEX 0x8933 /* name -> if_index mapping */
  63. #define SIOGIFINDEX SIOCGIFINDEX /* misprint compatibility :-) */
  64. #define SIOCSIFPFLAGS 0x8934 /* set/get extended flags set */
  65. #define SIOCGIFPFLAGS 0x8935
  66. #define SIOCDIFADDR 0x8936 /* delete PA address */
  67. #define SIOCSIFHWBROADCAST 0x8937 /* set hardware broadcast addr */
  68. #define SIOCGIFCOUNT 0x8938 /* get number of devices */
  69.  
  70. #define SIOCGIFBR 0x8940 /* Bridging support */
  71. #define SIOCSIFBR 0x8941 /* Set bridging options */
  72.  
  73. #define SIOCGIFTXQLEN 0x8942 /* Get the tx queue length */
  74. #define SIOCSIFTXQLEN 0x8943 /* Set the tx queue length */
  75.  
  76. /* SIOCGIFDIVERT was: 0x8944 Frame diversion support */
  77. /* SIOCSIFDIVERT was: 0x8945 Set frame diversion options */
  78.  
  79. #define SIOCETHTOOL 0x8946 /* Ethtool interface */
  80.  
  81. #define SIOCGMIIPHY 0x8947 /* Get address of MII PHY in use. */
  82. #define SIOCGMIIREG 0x8948 /* Read MII PHY register. */
  83. #define SIOCSMIIREG 0x8949 /* Write MII PHY register. */
  84.  
  85. #define SIOCWANDEV 0x894A /* get/set netdev parameters */
  86.  
  87. #define SIOCOUTQNSD 0x894B /* output queue size (not sent only) */
  88.  
  89. /* ARP cache control calls. */
  90. /* 0x8950 - 0x8952 * obsolete calls, don't re-use */
  91. #define SIOCDARP 0x8953 /* delete ARP table entry */
  92. #define SIOCGARP 0x8954 /* get ARP table entry */
  93. #define SIOCSARP 0x8955 /* set ARP table entry */
  94.  
  95. /* RARP cache control calls. */
  96. #define SIOCDRARP 0x8960 /* delete RARP table entry */
  97. #define SIOCGRARP 0x8961 /* get RARP table entry */
  98. #define SIOCSRARP 0x8962 /* set RARP table entry */
  99.  
  100. /* Driver configuration calls */
  101.  
  102. #define SIOCGIFMAP 0x8970 /* Get device parameters */
  103. #define SIOCSIFMAP 0x8971 /* Set device parameters */
  104.  
  105. /* DLCI configuration calls */
  106.  
  107. #define SIOCADDDLCI 0x8980 /* Create new DLCI device */
  108. #define SIOCDELDLCI 0x8981 /* Delete DLCI device */
  109.  
  110. #define SIOCGIFVLAN 0x8982 /* 802.1Q VLAN support */
  111. #define SIOCSIFVLAN 0x8983 /* Set 802.1Q VLAN options */
  112.  
  113. /* bonding calls */
  114.  
  115. #define SIOCBONDENSLAVE 0x8990 /* enslave a device to the bond */
  116. #define SIOCBONDRELEASE 0x8991 /* release a slave from the bond*/
  117. #define SIOCBONDSETHWADDR 0x8992 /* set the hw addr of the bond */
  118. #define SIOCBONDSLAVEINFOQUERY 0x8993 /* rtn info about slave state */
  119. #define SIOCBONDINFOQUERY 0x8994 /* rtn info about bond state */
  120. #define SIOCBONDCHANGEACTIVE 0x8995 /* update to a new active slave */
  121.  
  122. /* bridge calls */
  123. #define SIOCBRADDBR 0x89a0 /* create new bridge device */
  124. #define SIOCBRDELBR 0x89a1 /* remove bridge device */
  125. #define SIOCBRADDIF 0x89a2 /* add interface to bridge */
  126. #define SIOCBRDELIF 0x89a3 /* remove interface from bridge */
  127.  
  128. /* hardware time stamping: parameters in linux/net_tstamp.h */
  129. #define SIOCSHWTSTAMP 0x89b0 /* set and get config */
  130. #define SIOCGHWTSTAMP 0x89b1 /* get config */
  131.  
  132. /* Device private ioctl calls */
  133.  
  134. /*
  135. * These 16 ioctls are available to devices via the do_ioctl() device
  136. * vector. Each device should include this file and redefine these names
  137. * as their own. Because these are device dependent it is a good idea
  138. * _NOT_ to issue them to random objects and hope.
  139. *
  140. * THESE IOCTLS ARE _DEPRECATED_ AND WILL DISAPPEAR IN 2.5.X -DaveM
  141. */
  142.  
  143. #define SIOCDEVPRIVATE 0x89F0 /* to 89FF */
  144.  
  145. /*
  146. * These 16 ioctl calls are protocol private
  147. */
  148.  
  149. #define SIOCPROTOPRIVATE 0x89E0 /* to 89EF */
  150. #endif /* _LINUX_SOCKIOS_H */
  1. ndo_get_stats()模板,在程序合适的地方对各种计数进行设置即可。
  1. struct net_device_stats *xxx_stats(struct net_device *dev)
  2. {

  3. return &dev->stats;
  4. }
  5.  
  6. struct net_device_stats
  7. {
  8. unsigned long rx_packets; /* 收到的数据包数 */
  9. unsigned long tx_packets; /* 发送的数据包数 */
  10. unsigned long rx_bytes; /* 收到的字节数 */
  11. unsigned long tx_bytes; /* 发送的字节数 */
  12. unsigned long rx_errors; /* 收到的错误数据包数 */
  13. unsigned long tx_errors; /* 发生发送错误的数据包数 */
  14. ...
  15. };

14.9 DM9000实例

14.10 总结

《linux设备驱动开发详解》笔记——14 linux网络设备驱动的更多相关文章

  1. linux设备驱动开发详解 笔记

      在目录的 Makefile 中关于 RTC_DRV_S3C 的编译脚本为: obj -$(CONFIG_RTC_DRV_S3C) += rtc-s3c.o 上述脚本意味着如果 RTC_DRV_S3 ...

  2. Linux设备驱动开发详解-Note(11)--- Linux 文件系统与设备文件系统(3)

    Linux 文件系统与设备文件系统(3) 成于坚持,败于止步 sysfs 文件系统与 Linux 设备模型 1.sysfs 文件系统 Linux 2.6 内核引入了 sysfs 文件系统,sysfs ...

  3. Linux设备驱动开发详解-Note(5)---Linux 内核及内核编程(1)

    Linux 内核及内核编程(1) 成于坚持,败于止步 Linux 2.6 内核的特点 Linux 2.6 相对于 Linux 2.4 有相当大的改进,主要体现在如下几个方面. 1.新的调度器 2.6 ...

  4. Linux设备驱动开发详解

    Linux设备驱动开发详解 http://download.csdn.net/detail/wuyouzi067/9581380

  5. 嵌入式Linux应用程序开发详解------(创建守护进程)

    嵌入式Linux应用程序开发详解 华清远见 本文只是阅读文摘. 创建一个守护进程的步骤: 1.创建一个子进程,然后退出父进程: 2.在子进程中使用创建新会话---setsid(): 3.改变当前工作目 ...

  6. 《linux设备驱动开发详解》笔记——6字符设备驱动

    6.1 字符设备驱动结构 先看看字符设备驱动的架构: 6.1.1 cdev cdev结构体是字符设备的核心数据结构,用于描述一个字符设备,cdev定义如下: #include <linux/cd ...

  7. 《linux设备驱动开发详解》笔记——10中断与时钟

    10.1 中断与定时器 中断一般有如下类型: 内部中断和外部中断:内部中断来自CPU,例如软件中断指令.溢出.除0错误等:外部中断有外部设备触发 可屏蔽中断和不可屏蔽中断 向量中断和非向量中断,ARM ...

  8. 《linux设备驱动开发详解》笔记——8阻塞与非阻塞IO

    8.1 阻塞与非阻塞IO 8.1.0 概述 阻塞:访问设备时,若不能获取资源,则进程挂起,进入睡眠状态:也就是进入等待队列 非阻塞:不能获取资源时,不睡眠,要么退出.要么一直查询:直接退出且无资源时, ...

  9. 《Linux设备驱动开发详解(第2版)》配套视频登录51cto教育频道

    http://edu.51cto.com/course/course_id-379-page-1.html http://edu.51cto.com/course/course_id-379-page ...

随机推荐

  1. php:比较两个txt文件,格式如下,分别取出a.txt有的b.txt没有的,b.txt有的a.txt没有的及两个都有的

    <?php /*比较两个txt文件,格式如下,分别取出a.txt有的b.txt没有的,b.txt有的a.txt没有的及两个都有的 * a.txt: * A * B * C * D * b.txt ...

  2. Identity Service

    Identity Service - 解析微软微服务架构eShopOnContainers(二)   接上一篇,众所周知一个网站的用户登录是非常重要,一站式的登录(SSO)也成了大家讨论的热点.微软在 ...

  3. Core中使用Razor视图引擎渲染视图为字符串 阅读目录

    Core中使用Razor视图引擎渲染视图为字符串 } <!DOCTYPE html> <html> <head> <title>Render view ...

  4. PIX 防火墙

    ---恢复内容开始--- 一 , PIX 防火墙的认识 PIX 是cisco 的硬件防火墙 硬件防火墙的工作速度快,使用方便. PIX 有很多型号,并发连接数是PIX防火墙的重要参数   PIX 25 ...

  5. Win10+VirtualBox+Openstack Mitaka

    首先VirtualBox安装的话,没有什么可演示的,去官网(https://www.virtualbox.org/wiki/Downloads)下载,或者可以去(https://www.virtual ...

  6. restful 风格 加上springmvc

    一.spring 版本:spring-framework-3.2.7.RELEASE 二.所需其它Jar包: 三.主要代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...

  7. Ubuntu常用指令集

    Ubuntu Linux 操作系统常用命令详细介绍 ( 1)Udo apt-get install 软件名 安装软件命令 sudo nautilus 打开文件(有 root 权限)su root 切换 ...

  8. Linux大棚版vimrc配置

    Linux大棚版vimrc配置—V2.0版本,如下: [shell] $cat .vimrc “== “Author :roc “Website:roclinux.cn “Version:2.0 “= ...

  9. mysql 存储过程变量及循环的使用

    1.用游标循环 BEGIN -- 定义变量 -- 定义done DECLARE done INT; -- 定义 ammeter_id_bl DECLARE ammeter_id_bl DOUBLE; ...

  10. C#、VSTO讀取Excel類

    之前寫的類存在Excel進程不能結束的Bug,重寫ExcelReader類,類實例清理時Excel進程自動結束. class ExcelReader { // Excel Object public ...