网卡驱动DM9000

分析内核版本:Linux 2.6.36.2。 分析网卡:DM9000

一、网络设备驱动程序分析。

1、Linux 网络设备驱动程序 分层:

Linux 网络设备驱动程序从上到下可分为4层,依次为:网络协议接口层、网络设备接口层、提供实际功能的设备 驱动功能层、以及  网络设备与媒介层。这4层作用如下:

1) 网络协议接口层:网络协议接口层想网络协议提供统一的数据包收发接口,不论是上层ARP,还是IP,都通过dev_queue_xmit() 函数收发数据,并通过netif_rx 函数

    接收数据。这一层的存在使得上层协议独立于具体的设备。

2)网络设备接口层:网络设备接口层向协议层接口层提供统一的用于描述具体网络设备属性 和 操作的结构体 net_device,该结构体是设备驱动功能层中各函数的容器,

    实际上,网络设备接口层从宏观上规划了具体操作硬件的设备驱动功能层的结构。

3)设备功能层:该层的各个函数是网络设备接口层net_device 数据结构具体成员,是驱使网络设备硬件完成相应动作的程序,它通过har_start_xmit() 函数启动发送操作,

    并通过网络设备上的中断触发接收操作。

4)网络设备 与 媒介层: 是完成数据包发送和接收的物理实体,包括网络适配器和具体的传输媒介,网络适配器被设备驱动功能层中的函数物理上驱动,对于Linux而言,

    网络设备和媒介都是可以虚拟的。

在设计具体的网络设备驱动程序是,我们需要完成的主要工作是编写设备驱动功能层 的 相关函数以以填充net_device 数据结构的内容并将net_device 注册入内核。

2、网络协议接口层程序分析:

1) int netif_xmit (struct sk_buff *skb);// 发送一个sk_buff 数据包

    int netif_rx (struct sk_buff *skb);   // 接收一个数据包

以上函数定义在 net/core/dev.c 中

sk_buff 结构体定义在 include/linux/skbuff.h 文件, 它的含义为“套接字缓冲区”,用于在Linux 网络子系统中个层之间传递数据,是Linux 网络子系统数据传递的“中枢神经”

2) 套接字缓冲区 sk_buff 结构体

[cpp]  view plain copy
  1. struct sk_buff {  
  2.     /* These two members must be first. */  
  3.     struct sk_buff      *next;  
  4.     struct sk_buff      *prev;  
  5.   
  6.     ktime_t         tstamp;  
  7.   
  8.     struct sock     *sk;  
  9.     struct net_device   *dev;  
  10.   
  11.     /* 
  12.      * This is the control buffer. It is free to use for every 
  13.      * layer. Please put your private variables there. If you 
  14.      * want to keep them across layers you have to do a skb_clone() 
  15.      * first. This is owned by whoever has the skb queued ATM. 
  16.      */  
  17.     char            cb[48] __aligned(8);  
  18.   
  19.     unsigned long       _skb_refdst;  
  20. #ifdef CONFIG_XFRM  
  21.     struct  sec_path    *sp;  
  22. #endif  
  23.     unsigned int        len,  
  24.                 data_len;  
  25.     __u16           mac_len,  
  26.                 hdr_len;  
  27.     union {  
  28.         __wsum      csum;  
  29.         struct {  
  30.             __u16   csum_start;  
  31.             __u16   csum_offset;  
  32.         };  
  33.     };  
  34.     __u32           priority;  
  35.     kmemcheck_bitfield_begin(flags1);  
  36.     __u8            local_df:1,  
  37.                 cloned:1,  
  38.                 ip_summed:2,  
  39.                 nohdr:1,  
  40.                 nfctinfo:3;  
  41.     __u8            pkt_type:3,  
  42.                 fclone:2,  
  43.                 ipvs_property:1,  
  44.                 peeked:1,  
  45.                 nf_trace:1;  
  46.     kmemcheck_bitfield_end(flags1);  
  47.     __be16          protocol;  
  48.   
  49.     void            (*destructor)(struct sk_buff *skb);  
  50. #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)  
  51.     struct nf_conntrack *nfct;  
  52.     struct sk_buff      *nfct_reasm;  
  53. #endif  
  54. #ifdef CONFIG_BRIDGE_NETFILTER  
  55.     struct nf_bridge_info   *nf_bridge;  
  56. #endif  
  57.   
  58.     int         skb_iif;  
  59. #ifdef CONFIG_NET_SCHED  
  60.     __u16           tc_index;   /* traffic control index */  
  61. #ifdef CONFIG_NET_CLS_ACT  
  62.     __u16           tc_verd;    /* traffic control verdict */  
  63. #endif  
  64. #endif  
  65.   
  66.     __u32           rxhash;  
  67.   
  68.     kmemcheck_bitfield_begin(flags2);  
  69.     __u16           queue_mapping:16;  
  70. #ifdef CONFIG_IPV6_NDISC_NODETYPE  
  71.     __u8            ndisc_nodetype:2,  
  72.                 deliver_no_wcard:1;  
  73. #else  
  74.     __u8            deliver_no_wcard:1;  
  75. #endif  
  76.     kmemcheck_bitfield_end(flags2);  
  77.   
  78.     /* 0/14 bit hole */  
  79.   
  80. #ifdef CONFIG_NET_DMA  
  81.     dma_cookie_t        dma_cookie;  
  82. #endif  
  83. #ifdef CONFIG_NETWORK_SECMARK  
  84.     __u32           secmark;  
  85. #endif  
  86.     union {  
  87.         __u32       mark;  
  88.         __u32       dropcount;  
  89.     };  
  90.   
  91.     __u16           vlan_tci;  
  92.   
  93.     sk_buff_data_t      transport_header;    // 传输层  
  94.     sk_buff_data_t      network_header;      // 网络层  
  95.     sk_buff_data_t      mac_header;          // MAC 层  
  96.     /* These elements must be at the end, see alloc_skb() for details.  */  
  97.     sk_buff_data_t      tail;  
  98.     sk_buff_data_t      end;  
  99.     unsigned char       *head,      // 缓冲区头指针  
  100.                 *data;      // 有效数据头指针  
  101.     unsigned int        truesize;  
  102.     atomic_t        users;  
  103. };  
3) 套接字 操作函数:

3.1) 分配 

struct sk_buff *alloc_skb(unsigned int len, gfp_t priority);

struct sk_buff *dev_alloc_skb (unsigned int len);

3.2) 释放

[cpp]  view plain copy
  1. <span style="color: rgb(51, 51, 51); font-family: Arial, Helvetica, sans-serif; font-size: 16px; white-space: normal; background-color: rgb(255, 255, 255); ">void kfree_skb ( struct sk_buff *skb);</span>  
[cpp]  view plain copy
  1. <span style="font-family: Arial, Helvetica, sans-serif; white-space: normal; background-color: rgb(255, 255, 255); ">void dev_kfree_skb(struct sk_buff *skb);</span>  


void dev_kfree_skb_irq (struct sk_buff  *skb);

void dev_kfree_skb_any (struct  sk_buff  *skb);

3.3) 变更

unsigned char *skb_put (struct sk_buff *skb, unsigned int len);

unsigned  char  *skb_push ( struct sk_buff *skb, unsigned int len);

static inline void skb_reserve (struct sk_buff *skb, int len);

4、 网络设备接口层

      网络设备接口层的主要功能是为各种网络设备定义了统一、抽象的数据结构 net_device 结构体。定义在 include/linux/netdevice.h 中

4.1)以下仅仅对 net_device 结构体 的一些关键成员进行标注和说明:

[cpp]  view plain copy
  1. struct net_device {  
  2.   
  3.     /* 
  4.      * This is the first field of the "visible" part of this structure 
  5.      * (i.e. as seen by users in the "Space.c" file).  It is the name 
  6.      * of the interface. 
  7.      */  
  8.     char            name[IFNAMSIZ];          // 全局信息 ,网络设备名称  
  9.   
  10.     struct pm_qos_request_list pm_qos_req;  
  11.   
  12.     /* device name hash chain */  
  13.     struct hlist_node   name_hlist;  
  14.     /* snmp alias */  
  15.     char            *ifalias;  
  16.   
  17.     /* 
  18.      *  I/O specific fields 
  19.      *  FIXME: Merge these and struct ifmap into one 
  20.      */  
  21.     unsigned long       mem_end;    /* shared mem end   */ // 硬件信息, 共享内存起始地址  
  22.     unsigned long       mem_start;  /* shared mem start */ // 共享内存结束地址  
  23.     unsigned long       base_addr;  /* device I/O address   */ // 设备I/O 基地址  
  24.     unsigned int        irq;        /* device IRQ number    */ // 设备中断号  
  25.   
  26.     /* 
  27.      *  Some hardware also needs these fields, but they are not 
  28.      *  part of the usual set specified in Space.c. 
  29.      */  
  30.   
  31.     unsigned char       if_port;    /* Selectable AUI, TP,..*/ // 指定设备使用的端口  
  32.     unsigned char       dma;        /* DMA channel      */  
  33.   
  34.     unsigned long       state;  
  35.   
  36.     struct list_head    dev_list;  
  37.     struct list_head    napi_list;  
  38.     struct list_head    unreg_list;  
  39.   
  40.     /* Net device features */  
  41.     unsigned long       features;  
  42. #define NETIF_F_SG      1   /* Scatter/gather IO. */  
  43. #define NETIF_F_IP_CSUM     2   /* Can checksum TCP/UDP over IPv4. */  
  44. #define NETIF_F_NO_CSUM     4   /* Does not require checksum. F.e. loopack. */  
  45. #define NETIF_F_HW_CSUM     8   /* Can checksum all the packets. */  
  46. #define NETIF_F_IPV6_CSUM   16  /* Can checksum TCP/UDP over IPV6 */  
  47. #define NETIF_F_HIGHDMA     32  /* Can DMA to high memory. */  
  48. #define NETIF_F_FRAGLIST    64  /* Scatter/gather IO. */  
  49. #define NETIF_F_HW_VLAN_TX  128 /* Transmit VLAN hw acceleration */  
  50. #define NETIF_F_HW_VLAN_RX  256 /* Receive VLAN hw acceleration */  
  51. #define NETIF_F_HW_VLAN_FILTER  512 /* Receive filtering on VLAN */  
  52. #define NETIF_F_VLAN_CHALLENGED 1024    /* Device cannot handle VLAN packets */  
  53. #define NETIF_F_GSO     2048    /* Enable software GSO. */  
  54. #define NETIF_F_LLTX        4096    /* LockLess TX - deprecated. Please */  
  55.                     /* do not use LLTX in new drivers */  
  56. #define NETIF_F_NETNS_LOCAL 8192    /* Does not change network namespaces */  
  57. #define NETIF_F_GRO     16384   /* Generic receive offload */  
  58. #define NETIF_F_LRO     32768   /* large receive offload */  
  59.   
  60. /* the GSO_MASK reserves bits 16 through 23 */  
  61. #define NETIF_F_FCOE_CRC    (1 << 24) /* FCoE CRC32 */  
  62. #define NETIF_F_SCTP_CSUM   (1 << 25) /* SCTP checksum offload */  
  63. #define NETIF_F_FCOE_MTU    (1 << 26) /* Supports max FCoE MTU, 2158 bytes*/  
  64. #define NETIF_F_NTUPLE      (1 << 27) /* N-tuple filters supported */  
  65. #define NETIF_F_RXHASH      (1 << 28) /* Receive hashing offload */  
  66.   
  67.     /* Segmentation offload features */  
  68. #define NETIF_F_GSO_SHIFT   16  
  69. #define NETIF_F_GSO_MASK    0x00ff0000  
  70. #define NETIF_F_TSO     (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)  
  71. #define NETIF_F_UFO     (SKB_GSO_UDP << NETIF_F_GSO_SHIFT)  
  72. #define NETIF_F_GSO_ROBUST  (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)  
  73. #define NETIF_F_TSO_ECN     (SKB_GSO_TCP_ECN << NETIF_F_GSO_SHIFT)  
  74. #define NETIF_F_TSO6        (SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT)  
  75. #define NETIF_F_FSO     (SKB_GSO_FCOE << NETIF_F_GSO_SHIFT)  
  76.   
  77.     /* List of features with software fallbacks. */  
  78. #define NETIF_F_GSO_SOFTWARE    (NETIF_F_TSO | NETIF_F_TSO_ECN | \  
  79.                  NETIF_F_TSO6 | NETIF_F_UFO)  
  80.   
  81.   
  82. #define NETIF_F_GEN_CSUM    (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)  
  83. #define NETIF_F_V4_CSUM     (NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)  
  84. #define NETIF_F_V6_CSUM     (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)  
  85. #define NETIF_F_ALL_CSUM    (NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)  
  86.   
  87.     /* 
  88.      * If one device supports one of these features, then enable them 
  89.      * for all in netdev_increment_features. 
  90.      */  
  91. #define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \  
  92.                  NETIF_F_SG | NETIF_F_HIGHDMA |     \  
  93.                  NETIF_F_FRAGLIST)  
  94.   
  95.     /* Interface index. Unique device identifier    */  
  96.     int         ifindex;  
  97.     int         iflink;  
  98.   
  99.     struct net_device_stats stats;  
  100.   
  101. #ifdef CONFIG_WIRELESS_EXT  
  102.     /* List of functions to handle Wireless Extensions (instead of ioctl). 
  103.      * See <net/iw_handler.h> for details. Jean II */  
  104.     const struct iw_handler_def *   wireless_handlers;  
  105.     /* Instance data managed by the core of Wireless Extensions. */  
  106.     struct iw_public_data * wireless_data;  
  107. #endif  
  108.     /* Management operations */  
  109.     const struct net_device_ops *netdev_ops;  
  110.     const struct ethtool_ops *ethtool_ops;  
  111.   
  112.     /* Hardware header description */  
  113.     const struct header_ops *header_ops;  
  114.   
  115.     unsigned int        flags;  /* interface flags (a la BSD)   */  
  116.     unsigned short      gflags;  
  117.         unsigned short          priv_flags; /* Like 'flags' but invisible to userspace. */  
  118.     unsigned short      padded; /* How much padding added by alloc_netdev() */  
  119.   
  120.     unsigned char       operstate; /* RFC2863 operstate */  
  121.     unsigned char       link_mode; /* mapping policy to operstate */  
  122.   
  123.     unsigned int        mtu;    /* interface MTU value      */         // 最大传输单元  
  124.     unsigned short      type;   /* interface hardware type  */         // 接口的硬件类型  
  125.     unsigned short      hard_header_len;    /* hardware hdr length  */ // 硬件报文头长度  
  126.   
  127.     /* extra head- and tailroom the hardware may need, but not in all cases 
  128.      * can this be guaranteed, especially tailroom. Some cases also use 
  129.      * LL_MAX_HEADER instead to allocate the skb. 
  130.      */  
  131.     unsigned short      needed_headroom;  
  132.     unsigned short      needed_tailroom;  
  133.   
  134.     struct net_device   *master; /* Pointer to master device of a group, 
  135.                       * which this device is member of. 
  136.                       */  
  137.   
  138.     /* Interface address info. */  
  139.     unsigned char       perm_addr[MAX_ADDR_LEN]; /* permanent hw address */  
  140.     unsigned char       addr_assign_type; /* hw address assignment type */  
  141.     unsigned char       addr_len;   /* hardware address length  */  
  142.     unsigned short          dev_id;     /* for shared network cards */  
  143.   
  144.     spinlock_t      addr_list_lock;  
  145.     struct netdev_hw_addr_list  uc; /* Unicast mac addresses */  
  146.     struct netdev_hw_addr_list  mc; /* Multicast mac addresses */  
  147.     int         uc_promisc;  
  148.     unsigned int        promiscuity;  
  149.     unsigned int        allmulti;  
  150.   
  151.   
  152.     /* Protocol specific pointers */  
  153.       
  154. #ifdef CONFIG_NET_DSA  
  155.     void            *dsa_ptr;   /* dsa specific data */  
  156. #endif  
  157.     void            *atalk_ptr; /* AppleTalk link   */  
  158.     void            *ip_ptr;    /* IPv4 specific data   */  
  159.     void                    *dn_ptr;        /* DECnet specific data */  
  160.     void                    *ip6_ptr;       /* IPv6 specific data */  
  161.     void            *ec_ptr;    /* Econet specific data */  
  162.     void            *ax25_ptr;  /* AX.25 specific data */  
  163.     struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data, 
  164.                            assign before registering */  
  165.   
  166. /* 
  167.  * Cache line mostly used on receive path (including eth_type_trans()) 
  168.  */  
  169.     unsigned long       last_rx;    /* Time of last Rx  */  
  170.     /* Interface address info used in eth_type_trans() */  
  171.     unsigned char       *dev_addr;  /* hw address, (before bcast 
  172.                            because most packets are 
  173.                            unicast) */  
  174.   
  175.     struct netdev_hw_addr_list  dev_addrs; /* list of device 
  176.                               hw addresses */  
  177.   
  178.     unsigned char       broadcast[MAX_ADDR_LEN];    /* hw bcast add */  // 广播地址  
  179.   
  180. #ifdef CONFIG_RPS  
  181.     struct kset     *queues_kset;  
  182.   
  183.     struct netdev_rx_queue  *_rx;  
  184.   
  185.     /* Number of RX queues allocated at alloc_netdev_mq() time  */  
  186.     unsigned int        num_rx_queues;  
  187. #endif  
  188.   
  189.     struct netdev_queue rx_queue;  
  190.     rx_handler_func_t   *rx_handler;  
  191.     void            *rx_handler_data;  
  192.   
  193.     struct netdev_queue *_tx ____cacheline_aligned_in_smp;  
  194.   
  195.     /* Number of TX queues allocated at alloc_netdev_mq() time  */  
  196.     unsigned int        num_tx_queues;  
  197.   
  198.     /* Number of TX queues currently active in device  */  
  199.     unsigned int        real_num_tx_queues;  
  200.   
  201.     /* root qdisc from userspace point of view */  
  202.     struct Qdisc        *qdisc;  
  203.   
  204.     unsigned long       tx_queue_len;   /* Max frames per queue allowed */  
  205.     spinlock_t      tx_global_lock;  
  206. /* 
  207.  * One part is mostly used on xmit path (device) 
  208.  */  
  209.     /* These may be needed for future network-power-down code. */  
  210.   
  211.     /* 
  212.      * trans_start here is expensive for high speed devices on SMP, 
  213.      * please use netdev_queue->trans_start instead. 
  214.      */  
  215.     unsigned long       trans_start;    /* Time (in jiffies) of last Tx */  
  216.   
  217.     int         watchdog_timeo; /* used by dev_watchdog() */  
  218.     struct timer_list   watchdog_timer;  
  219.   
  220.     /* Number of references to this device */  
  221.     atomic_t        refcnt ____cacheline_aligned_in_smp;  
  222.   
  223.     /* delayed register/unregister */  
  224.     struct list_head    todo_list;  
  225.     /* device index hash chain */  
  226.     struct hlist_node   index_hlist;  
  227.   
  228.     struct list_head    link_watch_list;  
  229.   
  230.     /* register/unregister state machine */  
  231.     enum { NETREG_UNINITIALIZED=0,  
  232.            NETREG_REGISTERED,   /* completed register_netdevice */  
  233.            NETREG_UNREGISTERING,    /* called unregister_netdevice */  
  234.            NETREG_UNREGISTERED, /* completed unregister todo */  
  235.            NETREG_RELEASED,     /* called free_netdev */  
  236.            NETREG_DUMMY,        /* dummy device for NAPI poll */  
  237.     } reg_state:16;  
  238.   
  239.     enum {  
  240.         RTNL_LINK_INITIALIZED,  
  241.         RTNL_LINK_INITIALIZING,  
  242.     } rtnl_link_state:16;  
  243.   
  244.     /* Called from unregister, can be used to call free_netdev */  
  245.     void (*destructor)(struct net_device *dev);  
  246.   
  247. #ifdef CONFIG_NETPOLL  
  248.     struct netpoll_info *npinfo;  
  249. #endif  
  250.   
  251. #ifdef CONFIG_NET_NS  
  252.     /* Network namespace this network device is inside */  
  253.     struct net      *nd_net;  
  254. #endif  
  255.   
  256.     /* mid-layer private */  
  257.     void            *ml_priv;  
  258.   
  259.     /* GARP */  
  260.     struct garp_port    *garp_port;  
  261.   
  262.     /* class/net/name entry */  
  263.     struct device       dev;  
  264.     /* space for optional device, statistics, and wireless sysfs groups */  
  265.     const struct attribute_group *sysfs_groups[4];  
  266.   
  267.     /* rtnetlink link ops */  
  268.     const struct rtnl_link_ops *rtnl_link_ops;  
  269.   
  270.     /* VLAN feature mask */  
  271.     unsigned long vlan_features;  
  272.   
  273.     /* for setting kernel sock attribute on TCP connection setup */  
  274. #define GSO_MAX_SIZE        65536  
  275.     unsigned int        gso_max_size;  
  276.   
  277. #ifdef CONFIG_DCB  
  278.     /* Data Center Bridging netlink ops */  
  279.     const struct dcbnl_rtnl_ops *dcbnl_ops;  
  280. #endif  
  281.   
  282. #if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)  
  283.     /* max exchange id for FCoE LRO by ddp */  
  284.     unsigned int        fcoe_ddp_xid;  
  285. #endif  
  286.     /* n-tuple filter list attached to this device */  
  287.     struct ethtool_rx_ntuple_list ethtool_ntuple_list;  
  288.   
  289.     /* phy device may attach itself for hardware timestamping */  
  290.     struct phy_device *phydev;  
  291. };  

4.2) 设备操作函数:部分定义在 include/linux/hdlc.h 中

[cpp]  view plain copy
  1. int (*open) (struct net_device *dev);  
  2. int (*stop) (struct net_device *dev);  
  3. int (*hard_start_xmit) (struct sk_buff *skb, struct net_device *dev);     
  4. //  hard_start_xmit() 函数会启动数据包的发送。当系统调用驱动程序的 hard_start_xmit() 函数时,需要向其传入一个sk_buff 结构体指针,  
  5. // 致使驱动程序能获得从上层传下来的数据包。  
  6.   
  7. void  (*tx_timeout) (struct net_device *dev);      // 时间超时函数  
  8. int  (*hard_header)  (struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len );  
  9. // hard_header() 函数完成硬件帧头填充,参数为sk_buff 指针,设备指针,协议类型,目的地址,源地址 和 数据长度。  
  10. struct net_device_stats* (*get_stats) (struct net_device *dev);     // 获取网络设备状态信息  
  11. int (*do_ioctl) (struct ent_device *dev, struct ifreq *ifr, int cmd);  //   do_ioctl() 函数用于进行设备特定的I/O 控制  
  12. int (*set_config) (struct net_device *dev, struct ifmap *map);    //  进行配置接口, 可用于改变设备的I/O 地址和中断号  
  13. int (*set_mac_address) (struct net_device *dev, void *addr);   // 用于设置设备 MAC 地址  


5、设备驱动功能层

net_device 结构的成员,(属性 和 函数指针)需要被设备驱动功能层的具体数值 和 函数赋予。 对具体的设备 xxx ,工程师应该编写设备功能层的函数,

这些函数如: xxx_open(). xxx_stop(),  xxx_tx(), xxx_hard_header(), xxx_get_stats(), xxxx_tx_timeout() 等。


6、 网络设备 与 媒介层

网络设备与媒介层 直接对应于实际的硬件设备,设计范例:

[cpp]  view plain copy
  1. /* 寄存器定义 */  
  2. #define DATA_REG 0x0004  
  3. #define CMD_REG 0x0008  
  4. /* 寄存器读写函数 */  
  5. static u16 xxx_readword( u32 base_addr, int portno)  
  6. {    ... . . .                         }  
  7. static void xxx_writeword(u32 base_addr, int portno , u16 value)  
  8. { .. . . . .                           }  


二、 DM9000 网卡驱动程序分析:

DM9000 驱动需要完成的工作 和 其对应的函数有:

1、 对网络设备驱动进行 注册 和 注销:

int register_netdevi( struct net_device *dev);

void  unregister_netdev ( struct net_device *dev);


2、 对网络设备进行初始化,初始化主要完成的工作为:

2.1) 进行硬件上的准备工作,检查网咯设备是否存在,如果存在,则检测设备所使用的硬件资源。

2.2) 进行软件接口上的准备工作,分配 net_device 结构体并对其数据 和 函数指针成员赋值。

2.3) 获得设备的私有信息指针 并初始化其个成员的值。


3、对对应的网络设备大打开 和释放

void netif_start_queue (struct net_device *dev);

void netif_stop_queue (struct net_device *dev);


4、进行数据发送, 发送数据流程如下:

(1) 网络设备驱动程序从上层协议传递过来的 sk_buff 参数获得数据包的有效数据 和 长度, 将有效数据放入临时缓冲区。

(2) 对于以太网,如果有效数据的长度小于以太网冲突检测所要求数据帧的最小长度,ETH_ZLEN,则给临时缓冲区末尾填充0.

(3) 设置硬件的寄存器, 驱使网络设备进行发送操作。


5、进行数据接收

     网络设备接收数据的主要方法是由中断引发中断处理函数,中断处理函数判断中断类型,如果为接收中断,则读取接收到

的数据, 分配 sk_buff 数据结构 和 数据缓冲区,将接收到的数据复制到数据缓冲区, 并调用netif_rx() 函数将 sk_buff 传递给

上层协议。


6、检查网络状态:

   网络适配器硬件电路可以检测出链路上是否有载波,,载波反映了网络的连接是否正常,网络设备驱动可以通过 netif_carrier_on() 

和 netif_carrier_off() 函数改变设备的连接状态, 如果驱动检测到连接状态发生了变化,也应该以 netif_carrier_on() 和 netif_carrier_off()

函数的形式来通知内核。也可以以 netif_carrier_of() 来检测载波信号是否存在。


7、对参数进行设置,和统计数据

    在网络设备的驱动程序中还提供一些方法供系统对设备的参数进行设置 或 读取设备相关的信息。


8、 DM9000 驱动源码主要函数分析:

[cpp]  view plain copy
  1. typedef struct board_info {                    /./  板载信息  
  2.   
  3.   
  4.     void __iomem    *io_addr;   /* Register I/O base address */  
  5.     void __iomem    *io_data;   /* Data I/O address */  
  6.     u16      irq;       /* IRQ */  
  7. }  
  8. static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd)            // ioctl 函数  
  9. {    
  10.     board_info_t *dm = to_dm9000_board(dev);  
  11.   
  12.   
  13.     if (!netif_running(dev))  
  14.         return -EINVAL;  
  15.   
  16.   
  17.     return generic_mii_ioctl(&dm->mii, if_mii(req), cmd, NULL);  
  18. }  
  19. dm9000_hash_table_unlocked(struct net_device *dev)                     // 设置 DM9000 广播地址  
  20. static void dm9000_timeout(struct net_device *dev)                          // 看门狗超时,网络层将调用该函数  
  21. {  
  22.     board_info_t *db = netdev_priv(dev);  
  23.     u8 reg_save;  
  24.     unsigned long flags;  
  25.   
  26.   
  27.     /* Save previous register address */  
  28.     reg_save = readb(db->io_addr);  
  29.     spin_lock_irqsave(&db->lock, flags);  
  30.   
  31.   
  32.     netif_stop_queue(dev);  
  33.     dm9000_reset(db);  
  34.     dm9000_init_dm9000(dev);  
  35.     /* We can accept TX packets again */  
  36.     dev->trans_start = jiffies; /* prevent tx timeout */  
  37.     netif_wake_queue(dev);  
  38.   
  39.   
  40.     /* Restore previous register address */  
  41.     writeb(reg_save, db->io_addr);  
  42.     spin_unlock_irqrestore(&db->lock, flags);  
  43. }  
  44. dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)  
  45. {  
  46.     /* Move data to DM9000 TX RAM */  
  47.     writeb(DM9000_MWCMD, db->io_addr);               // 将发送数据移至 DM9000 的 TX RAM  
  48. }  
  49. static void dm9000_tx_done ()                //  数据包发送完成  
  50. static void dm9000_rx(struct net_device *dev)              // 接收数据并传递给上层  
  51. static irqreturn _t dm9000_interrup()  
  52. {                    }  
  53. static int dm9000_open (struct net_device *dev)           // 打开网卡端口  
  54. {  
  55.   netif_static _queue (dev);  
  56. }  
  57.    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值