Chinaunix首页 | 论坛 | 博客
  • 博客访问: 39771
  • 博文数量: 18
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 0
  • 用 户 组: 普通用户
  • 注册时间: 2013-07-28 13:19
文章分类

全部博文(18)

文章存档

2014年(1)

2013年(17)

我的朋友

分类: LINUX

2013-10-23 14:58:15

硬件平台:FL2440s3c2440

内核版本:2.6.35

主机平台:Ubuntu11.04

内核版本:2.6.39

原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/6609742

1、下图是DM9000的引脚图

2、这里我们结合具体的开发板FL2440

下面是FL2440DM9000的引脚链接图

本人移植DM9000的时候将设备的资源定义放在了arch/arm/plat-s3c24xx/devs.c中,详情点击上一篇博文linux内核移植-移植2.6.35.4内核到s3c2440

下面是设备的资源定义

  1. /*DM9000*/  
  2. /* 定义该设备使用的资源 */  
  3. static struct resource s3c_dm9000_resource[] = {   
  4.         [0] = { /* 寄存器定义在mach-s3c2410/include/mach/map.h */  
  5.         .start = S3C24XX_PA_DM9000, /* 实际地址  0x20000300 */  
  6.         .end   = S3C24XX_PA_DM9000+ 0x3, /* 0x20000303 */  
  7.         .flags = IORESOURCE_MEM /* 资源标志为地址资源 */  
  8.         },   
  9.         [1]={   
  10.         .start = S3C24XX_PA_DM9000 + 0x4, //CMD pin is A2 0x20000304  
  11.         .end = S3C24XX_PA_DM9000 + 0x4 + 0x7c, // 0x20000380  
  12.         .flags = IORESOURCE_MEM /* 资源标志为地址资源 */  
  13.         },   
  14.         [2] = {   
  15.         .start = IRQ_EINT7, /* 中断为外部7号中断 */  
  16.         .end   = IRQ_EINT7, /* 中断为外部7号中断 */  
  17.         .flags = IORESOURCE_IRQ /* 资源标志为中断资源 */  
  18.         },   
  19. };   

这里可以看到,DM9000网卡使用的地址空间资源在nGCS4地址区域,所以上图的DM9000地址使能引脚连接nGCS4引脚。中断使用的是EINT7外部中断。

接着定义平台数据和平台设备,代码如下:

  1. /* 定义平台数据 */  
  2. static struct dm9000_plat_data s3c_device_dm9000_platdata = {   
  3.         .flags= DM9000_PLATF_16BITONLY,   
  4. };   
  5.   
  6. /* 定义平台设备 */  
  7. struct platform_device s3c_device_dm9000 = {   
  8.         .name= "dm9000"//设备名,该名称与平台设备驱动中的名称一致  
  9.         .id= 0,   
  10.         .num_resources= ARRAY_SIZE(s3c_dm9000_resource),   
  11.         .resource= s3c_dm9000_resource, //定义设备的资源  
  12.         .dev= {   
  13.                 .platform_data = &s3c_device_dm9000_platdata, //定义平台数据  
  14.          }   
  15. };   

最后导出函数符号,保存函数地址和名称

  1. EXPORT_SYMBOL(s3c_device_dm9000);  

3、设备启动的初始化过程

  1. MACHINE_START(S3C2440, "SMDK2440")  
  2.         /* Maintainer: Ben Dooks  */  
  3.         .phys_io        = S3C2410_PA_UART,  
  4.         .io_pg_offst    = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,  
  5.         .boot_params    = S3C2410_SDRAM_PA + 0x100,  
  6.   
  7.         .init_irq       = s3c24xx_init_irq,/* 初始化中断 */  
  8.         .map_io         = smdk2440_map_io,  
  9.         .init_machine   = smdk2440_machine_init,//定义设备的初始化函数  
  10.         .timer          = &s3c24xx_timer,  
  11. MACHINE_END  

而后会执行下面函数

  1. static void __init smdk2440_machine_init(void)  
  2. {  
  3.         s3c24xx_fb_set_platdata(&smdk2440_fb_info);  
  4.         s3c_i2c0_set_platdata(NULL);  
  5.           
  6.         s3c24xx_ts_set_platdata(&smdk2410_ts_cfg);/* Added by yan */  
  7.           
  8.         platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));/* 向平台中添加设备 */  
  9.         smdk_machine_init();  
  10. }  

下面是具体的设备列表

  1. static struct platform_device *smdk2440_devices[] __initdata = {  
  2.         &s3c_device_ohci,  
  3.         &s3c_device_lcd,/* ok */  
  4.         &s3c_device_wdt,/* ok */  
  5.         &s3c_device_i2c0,  
  6.         &s3c_device_iis,  
  7.         &s3c_device_rtc,/* ok */  
  8.         &s3c24xx_uda134x,  
  9.         &s3c_device_dm9000,  
  10.         &s3c_device_adc,/* ok */  
  11.         &s3c_device_ts,/* ok */  
  12.           
  13. };  

这样系统启动时,会给设备列表中的设备分配资源(地址资源和中断资源等)。

4、信息传输中的信息封装结构

4.1、sk_buff结构,定义在include/linux/skbuff.h

  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;  
  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. };  

元素的含义如下(摘自内核,源码,版本2.6.35.4
 *struct sk_buff - socket buffer
 * @next: Next buffer inlist
 * @prev: Previous buffer in list
 * @sk: Socketwe are owned by
 * @tstamp: Time we arrived
 * @dev:Device we arrived on/are leaving by
 * @transport_header:Transport layer header
 * @network_header: Network layerheader
 * @mac_header: Link layer header
 *@_skb_refdst: destination entry (with norefcount bit)
 * @sp:the security path, used for xfrm
 * @cb: Control buffer. Freefor use by every layer. Put private vars here
 * @len: Lengthof actual data
 * @data_len: Data length
 * @mac_len:Length of link layer header
 * @hdr_len: writable headerlength of cloned skb
 * @csum: Checksum (must includestart/offset pair)
 * @csum_start: Offset from skb->headwhere checksumming should start
 * @csum_offset: Offset fromcsum_start where checksum should be stored
 * @local_df:allow local fragmentation
 * @cloned: Head may be cloned(check refcnt to be sure)
 * @nohdr: Payload reference only,must not modify header
 * @pkt_type: Packet class
 *@fclone: skbuff clone status
 * @ip_summed: Driver fed us anIP checksum
 * @priority: Packet queueing priority
 *@users: User count - see {datagram,tcp}.c
 * @protocol:Packet protocol from driver
 * @truesize: Buffer size 
 *@head: Head of buffer
 * @data: Data head pointer
 *@tail: Tail pointer
 * @end: End pointer
 *@destructor: Destruct function
 * @mark: Generic packetmark
 * @nfct: Associated connection, if any
 *@ipvs_property: skbuff is owned by ipvs
 * @peeked: thispacket has been seen already, so stats have been
 * done forit, don't do them again
 * @nf_trace: netfilter packet traceflag
 * @nfctinfo: Relationship of this skb to theconnection
 * @nfct_reasm: netfilter conntrack re-assemblypointer
 * @nf_bridge: Saved data about a bridged frame - seebr_netfilter.c
 * @skb_iif: ifindex of device we arrivedon
 * @rxhash: the packet hash computed on receive
 *@queue_mapping: Queue mapping for multiqueue devices
 *@tc_index: Traffic control index
 * @tc_verd: traffic controlverdict
 * @ndisc_nodetype: router type (from link layer)
 *@dma_cookie: a cookie to one of several possible DMA operations
 *done by skb DMA functions
 * @secmark: security marking
 *@vlan_tci: vlan tag control information

关于sk_buff的更多分析见另一篇转载的博文http://blog.csdn.net/yming0221/article/details/6609734

4.2、net_device

关于net_device一个非常庞大的结构体,定义在/inlcude/linux/netdevice.h中

如下:

  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.      * 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   */  
  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 | NETIF_F_TSO6)  
  79.   
  80.   
  81. #define NETIF_F_GEN_CSUM    (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)  
  82. #define NETIF_F_V4_CSUM     (NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)  
  83. #define NETIF_F_V6_CSUM     (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)  
  84. #define NETIF_F_ALL_CSUM    (NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)  
  85.   
  86.     /* 
  87.      * If one device supports one of these features, then enable them 
  88.      * for all in netdev_increment_features. 
  89.      */  
  90. #define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \  
  91.                  NETIF_F_SG | NETIF_F_HIGHDMA |     \  
  92.                  NETIF_F_FRAGLIST)  
  93.   
  94.     /* Interface index. Unique device identifier    */  
  95.     int         ifindex;  
  96.     int         iflink;  
  97.   
  98.     struct net_device_stats stats;  
  99.   
  100. #ifdef CONFIG_WIRELESS_EXT  
  101.     /* List of functions to handle Wireless Extensions (instead of ioctl). 
  102.      * See  for details. Jean II */  
  103.     const struct iw_handler_def *   wireless_handlers;  
  104.     /* Instance data managed by the core of Wireless Extensions. */  
  105.     struct iw_public_data * wireless_data;  
  106. #endif  
  107.     /* Management operations */  
  108.     const struct net_device_ops *netdev_ops;  
  109.     const struct ethtool_ops *ethtool_ops;  
  110.   
  111.     /* Hardware header description */  
  112.     const struct header_ops *header_ops;  
  113.   
  114.     unsigned int        flags;  /* interface flags (a la BSD)   */  
  115.     unsigned short      gflags;  
  116.         unsigned short          priv_flags; /* Like 'flags' but invisible to userspace. */  
  117.     unsigned short      padded; /* How much padding added by alloc_netdev() */  
  118.   
  119.     unsigned char       operstate; /* RFC2863 operstate */  
  120.     unsigned char       link_mode; /* mapping policy to operstate */  
  121.   
  122.     unsigned int        mtu;    /* interface MTU value      */  
  123.     unsigned short      type;   /* interface hardware type  */  
  124.     unsigned short      hard_header_len;    /* hardware hdr length  */  
  125.   
  126.     /* extra head- and tailroom the hardware may need, but not in all cases 
  127.      * can this be guaranteed, especially tailroom. Some cases also use 
  128.      * LL_MAX_HEADER instead to allocate the skb. 
  129.      */  
  130.     unsigned short      needed_headroom;  
  131.     unsigned short      needed_tailroom;  
  132.   
  133.     struct net_device   *master; /* Pointer to master device of a group, 
  134.                       * which this device is member of. 
  135.                       */  
  136.   
  137.     /* Interface address info. */  
  138.     unsigned char       perm_addr[MAX_ADDR_LEN]; /* permanent hw address */  
  139.     unsigned char       addr_len;   /* hardware address length  */  
  140.     unsigned short          dev_id;     /* for shared network cards */  
  141.   
  142.     spinlock_t      addr_list_lock;  
  143.     struct netdev_hw_addr_list  uc; /* Unicast mac addresses */  
  144.     struct netdev_hw_addr_list  mc; /* Multicast mac addresses */  
  145.     int         uc_promisc;  
  146.     unsigned int        promiscuity;  
  147.     unsigned int        allmulti;  
  148.   
  149.   
  150.     /* Protocol specific pointers */  
  151.       
  152. #ifdef CONFIG_NET_DSA  
  153.     void            *dsa_ptr;   /* dsa specific data */  
  154. #endif  
  155.     void            *atalk_ptr; /* AppleTalk link   */  
  156.     void            *ip_ptr;    /* IPv4 specific data   */  
  157.     void                    *dn_ptr;        /* DECnet specific data */  
  158.     void                    *ip6_ptr;       /* IPv6 specific data */  
  159.     void            *ec_ptr;    /* Econet specific data */  
  160.     void            *ax25_ptr;  /* AX.25 specific data */  
  161.     struct wireless_dev *ieee80211_ptr; /* IEEE 802.11 specific data, 
  162.                            assign before registering */  
  163.   
  164. /* 
  165.  * Cache line mostly used on receive path (including eth_type_trans()) 
  166.  */  
  167.     unsigned long       last_rx;    /* Time of last Rx  */  
  168.     /* Interface address info used in eth_type_trans() */  
  169.     unsigned char       *dev_addr;  /* hw address, (before bcast 
  170.                            because most packets are 
  171.                            unicast) */  
  172.   
  173.     struct netdev_hw_addr_list  dev_addrs; /* list of device 
  174.                               hw addresses */  
  175.   
  176.     unsigned char       broadcast[MAX_ADDR_LEN];    /* hw bcast add */  
  177.   
  178. #ifdef CONFIG_RPS  
  179.     struct kset     *queues_kset;  
  180.   
  181.     struct netdev_rx_queue  *_rx;  
  182.   
  183.     /* Number of RX queues allocated at alloc_netdev_mq() time  */  
  184.     unsigned int        num_rx_queues;  
  185. #endif  
  186.   
  187.     struct netdev_queue rx_queue;  
  188.   
  189.     struct netdev_queue *_tx ____cacheline_aligned_in_smp;  
  190.   
  191.     /* Number of TX queues allocated at alloc_netdev_mq() time  */  
  192.     unsigned int        num_tx_queues;  
  193.   
  194.     /* Number of TX queues currently active in device  */  
  195.     unsigned int        real_num_tx_queues;  
  196.   
  197.     /* root qdisc from userspace point of view */  
  198.     struct Qdisc        *qdisc;  
  199.   
  200.     unsigned long       tx_queue_len;   /* Max frames per queue allowed */  
  201.     spinlock_t      tx_global_lock;  
  202. /* 
  203.  * One part is mostly used on xmit path (device) 
  204.  */  
  205.     /* These may be needed for future network-power-down code. */  
  206.   
  207.     /* 
  208.      * trans_start here is expensive for high speed devices on SMP, 
  209.      * please use netdev_queue->trans_start instead. 
  210.      */  
  211.     unsigned long       trans_start;    /* Time (in jiffies) of last Tx */  
  212.   
  213.     int         watchdog_timeo; /* used by dev_watchdog() */  
  214.     struct timer_list   watchdog_timer;  
  215.   
  216.     /* Number of references to this device */  
  217.     atomic_t        refcnt ____cacheline_aligned_in_smp;  
  218.   
  219.     /* delayed register/unregister */  
  220.     struct list_head    todo_list;  
  221.     /* device index hash chain */  
  222.     struct hlist_node   index_hlist;  
  223.   
  224.     struct list_head    link_watch_list;  
  225.   
  226.     /* register/unregister state machine */  
  227.     enum { NETREG_UNINITIALIZED=0,  
  228.            NETREG_REGISTERED,   /* completed register_netdevice */  
  229.            NETREG_UNREGISTERING,    /* called unregister_netdevice */  
  230.            NETREG_UNREGISTERED, /* completed unregister todo */  
  231.            NETREG_RELEASED,     /* called free_netdev */  
  232.            NETREG_DUMMY,        /* dummy device for NAPI poll */  
  233.     } reg_state:16;  
  234.   
  235.     enum {  
  236.         RTNL_LINK_INITIALIZED,  
  237.         RTNL_LINK_INITIALIZING,  
  238.     } rtnl_link_state:16;  
  239.   
  240.     /* Called from unregister, can be used to call free_netdev */  
  241.     void (*destructor)(struct net_device *dev);  
  242.   
  243. #ifdef CONFIG_NETPOLL  
  244.     struct netpoll_info *npinfo;  
  245. #endif  
  246.   
  247. #ifdef CONFIG_NET_NS  
  248.     /* Network namespace this network device is inside */  
  249.     struct net      *nd_net;  
  250. #endif  
  251.   
  252.     /* mid-layer private */  
  253.     void            *ml_priv;  
  254.   
  255.     /* bridge stuff */  
  256.     struct net_bridge_port  *br_port;  
  257.     /* macvlan */  
  258.     struct macvlan_port *macvlan_port;  
  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. };  

我还没有细细的分析这个结构体,驱动程序在probe函数中使用register_netdev()注册该结构体指明的设备,将内核操作硬件的函数个内核联系起来。


硬件平台:FL2440(s3c2440)

内核版本:2.6.35

主机平台:Ubuntu 11.04

内核版本:2.6.39

原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/6612623

下面开始分析具体的代码,这里由于使DM9000驱动更容易理解,在不影响基本的功能的前提下,这里将尽可能的简化该驱动(如:去掉该驱动中支持电源管理的功能)

分析该驱动

1、首先看一下该驱动的平台设备驱动的结构体定义

  1. /*平台设备驱动的结构体定义 
  2. *在该结构体中可以定义有关Power Management的管理函数 
  3. *该驱动中将其省略,侧重分析dm9000的基本原理 
  4. */  
  5. static struct platform_driver dm9000_driver = {  
  6.     .driver = {  
  7.         .name    = "dm9000",/* 该名称和系统初始化中,平台设备的名称一致 */  
  8.         .owner   = THIS_MODULE,  
  9.     },  
  10.     .probe   = dm9000_probe,/* 资源探测函数 */  
  11.     .remove  = __devexit_p(dm9000_drv_remove),/* 设备移除函数 */  
  12. };  
在执行insmod后内核自动那个执行下面的函数
  1. static int __init  
  2. dm9000_init(void)  
  3. {  
  4.     printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION);  
  5.   
  6.     return platform_driver_register(&dm9000_driver);  
  7. }  

调用函数platform_driver_register()函数注册驱动。

3、自动执行驱动的probe函数,进行资源的探测和申请资源。

其中BWSCON为总线宽度 等待控制寄存器


其中第[19:18]位的作用如下


下面函数中将两位设置为11,也就是WAIT使能,bank4使用UB/LB。

alloc_etherdev()函数分配一个网络设备的结构体,原型在include/linux/etherdevice.h

原型如下:

  1. extern struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count);  
  2. #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1)  
该函数中需要将获得的资源信息存储在一个结构体中,定义如下:

  1. /* Structure/enum declaration ------------------------------- */  
  2. typedef struct board_info {  
  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.     u16     tx_pkt_cnt;  
  9.     u16     queue_pkt_len;  
  10.     u16     queue_start_addr;  
  11.     u16     queue_ip_summed;  
  12.     u16     dbug_cnt;  
  13.     u8      io_mode;        /* 0:word, 2:byte */  
  14.     u8      phy_addr;  
  15.     u8      imr_all;  
  16.   
  17.     unsigned int    flags;  
  18.     unsigned int    in_suspend :1;  
  19.     unsigned int    wake_supported :1;  
  20.     int     debug_level;  
  21.   
  22.     enum dm9000_type type;  
  23.   
  24.     void (*inblk)(void __iomem *port, void *data, int length);  
  25.     void (*outblk)(void __iomem *port, void *data, int length);  
  26.     void (*dumpblk)(void __iomem *port, int length);  
  27.   
  28.     struct device   *dev;        /* parent device */  
  29.   
  30.     struct resource *addr_res;   /* resources found */  
  31.     struct resource *data_res;  
  32.     struct resource *addr_req;   /* resources requested */  
  33.     struct resource *data_req;  
  34.     struct resource *irq_res;  
  35.   
  36.     int      irq_wake;  
  37.   
  38.     struct mutex     addr_lock; /* phy and eeprom access lock */  
  39.   
  40.     struct delayed_work phy_poll;  
  41.     struct net_device  *ndev;  
  42.   
  43.     spinlock_t  lock;  
  44.   
  45.     struct mii_if_info mii;  
  46.     u32     msg_enable;  
  47.     u32     wake_state;  
  48.   
  49.     int     rx_csum;  
  50.     int     can_csum;  
  51.     int     ip_summed;  
  52. } board_info_t;  

下面是probe函数,

其中有个函数db = netdev_priv(ndev)

该函数实际上是返回网卡私有成员的数据结构地址

函数如下,定义在include/linux/net_device.h中

  1. static inline void *netdev_priv(const struct net_device *dev)  
  2. {  
  3.     return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN);  
  4. }  

  1. /* 
  2.  * Search DM9000 board, allocate space and register it 
  3.  */  
  4. static int __devinit  
  5. dm9000_probe(struct platform_device *pdev)  
  6. {  
  7.     struct dm9000_plat_data *pdata = pdev->dev.platform_data;  
  8.     struct board_info *db;  /* Point a board information structure */  
  9.     struct net_device *ndev;/* 网络设备 */  
  10.     const unsigned char *mac_src;  
  11.     int ret = 0;  
  12.     int iosize;  
  13.     int i;  
  14.     u32 id_val;  
  15.   
  16.     unsigned char ne_def_eth_mac_addr[]={0x00,0x12,0x34,0x56,0x80,0x49};/* 设定默认的mac地址 */  
  17.     static void *bwscon;/* 保存ioremap返回的寄存器的虚拟地址,下同 */  
  18.     static void *gpfcon;  
  19.     static void *extint0;  
  20.     static void *intmsk;  
  21.     /*Added by yan*/  
  22.     #define BWSCON           (0x48000000)  
  23.     #define GPFCON           (0x56000050)  
  24.     #define EXTINT0           (0x56000088)  
  25.     #define INTMSK           (0x4A000008)  
  26.   
  27.     bwscon=ioremap_nocache(BWSCON,0x0000004);  
  28.     gpfcon=ioremap_nocache(GPFCON,0x0000004);  
  29.     extint0=ioremap_nocache(EXTINT0,0x0000004);  
  30.     intmsk=ioremap_nocache(INTMSK,0x0000004);  
  31.   
  32.     writel( readl(bwscon)|0xc0000,bwscon);/* 将BWSCON寄存器[19:18]设置为11 */  
  33.     writel( (readl(gpfcon) & ~(0x3 << 14)) | (0x2 << 14), gpfcon); /* 设置GPF寄存器 */  
  34.     writel( readl(gpfcon) | (0x1 << 7), gpfcon); // Disable pull-up,不使能上拉  
  35.     writel( (readl(extint0) & ~(0xf << 28)) | (0x4 << 28), extint0); //rising edge,设置上升沿触发中断  
  36.     writel( (readl(intmsk))  & ~0x80, intmsk);/* 设置中断屏蔽寄存器 */  
  37.           
  38.     /*End of add*/  
  39.     /* Init network device */  
  40.     /* 使用alloc_etherdev()函数分配一个网络设备的结构体,原型在include/linux/etherdevice.h */  
  41.     ndev = alloc_etherdev(sizeof(struct board_info));  
  42.     if (!ndev) {  
  43.         dev_err(&pdev->dev, "could not allocate device.\n");  
  44.         return -ENOMEM;  
  45.     }  
  46.   
  47. /*通过SET_NETDEV_DEV(netdev, &pdev->dev)宏设置net_device.device->parent为当前的pci_device->device 
  48. *(这儿net_device包含的是device结构,而不是指针)。这样,就建立起了net_device到device的联系。 
  49. */  
  50.     SET_NETDEV_DEV(ndev, &pdev->dev);  
  51.   
  52.     dev_dbg(&pdev->dev, "dm9000_probe()\n");  
  53.   
  54.     /* setup board info structure */  
  55.     /* 下面都是设置board_info结构体 */  
  56.     db = netdev_priv(ndev);/* 返回dev->priv的地址 */  
  57.   
  58.     db->dev = &pdev->dev;  
  59.     db->ndev = ndev;  
  60.   
  61.     spin_lock_init(&db->lock);  
  62.     mutex_init(&db->addr_lock);  
  63.   
  64.     INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);  
  65.   
  66.     db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  
  67.     db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);  
  68.     db->irq_res  = platform_get_resource(pdev, IORESOURCE_IRQ, 0);  
  69.   
  70.     if (db->addr_res == NULL || db->data_res == NULL ||  
  71.         db->irq_res == NULL) {  
  72.         dev_err(db->dev, "insufficient resources\n");  
  73.         ret = -ENOENT;  
  74.         goto out;  
  75.     }  
  76.   
  77.     db->irq_wake = platform_get_irq(pdev, 1);  
  78.     if (db->irq_wake >= 0) {  
  79.         dev_dbg(db->dev, "wakeup irq %d\n", db->irq_wake);  
  80.   
  81.         ret = request_irq(db->irq_wake, dm9000_wol_interrupt,  
  82.                   IRQF_SHARED, dev_name(db->dev), ndev);  
  83.         if (ret) {  
  84.             dev_err(db->dev, "cannot get wakeup irq (%d)\n", ret);  
  85.         } else {  
  86.   
  87.             /* test to see if irq is really wakeup capable */  
  88.             ret = set_irq_wake(db->irq_wake, 1);  
  89.             if (ret) {  
  90.                 dev_err(db->dev, "irq %d cannot set wakeup (%d)\n",  
  91.                     db->irq_wake, ret);  
  92.                 ret = 0;  
  93.             } else {  
  94.                 set_irq_wake(db->irq_wake, 0);  
  95.                 db->wake_supported = 1;  
  96.             }  
  97.         }  
  98.     }  
  99.   
  100.     iosize = resource_size(db->addr_res);  
  101.     db->addr_req = request_mem_region(db->addr_res->start, iosize,  
  102.                       pdev->name);  
  103.   
  104.     if (db->addr_req == NULL) {  
  105.         dev_err(db->dev, "cannot claim address reg area\n");  
  106.         ret = -EIO;  
  107.         goto out;  
  108.     }  
  109.   
  110.     db->io_addr = ioremap(db->addr_res->start, iosize);  
  111.   
  112.     if (db->io_addr == NULL) {  
  113.         dev_err(db->dev, "failed to ioremap address reg\n");  
  114.         ret = -EINVAL;  
  115.         goto out;  
  116.     }  
  117.   
  118.     iosize = resource_size(db->data_res);  
  119.     db->data_req = request_mem_region(db->data_res->start, iosize,  
  120.                       pdev->name);  
  121.   
  122.     if (db->data_req == NULL) {  
  123.         dev_err(db->dev, "cannot claim data reg area\n");  
  124.         ret = -EIO;  
  125.         goto out;  
  126.     }  
  127.   
  128.     db->io_data = ioremap(db->data_res->start, iosize);  
  129.   
  130.     if (db->io_data == NULL) {  
  131.         dev_err(db->dev, "failed to ioremap data reg\n");  
  132.         ret = -EINVAL;  
  133.         goto out;  
  134.     }  
  135.     /* 设置结构体board_info结束 */  
  136.       
  137.     /* fill in parameters for net-dev structure */  
  138.     ndev->base_addr = (unsigned long)db->io_addr;/* 设置网络设备的地址 */  
  139.     ndev->irq    = db->irq_res->start;/* 设置网络设备的中断资源地址 */  
  140.   
  141.     /* ensure at least we have a default set of IO routines */  
  142.     dm9000_set_io(db, iosize);  
  143.   
  144.     /* check to see if anything is being over-ridden */  
  145.       
  146.     /*根据pdev->dev.platform_data的信息判断IO的宽度并设置相应的宽度*/  
  147.     if (pdata != NULL) {  
  148.         /* check to see if the driver wants to over-ride the 
  149.          * default IO width */  
  150.   
  151.         if (pdata->flags & DM9000_PLATF_8BITONLY)  
  152.             dm9000_set_io(db, 1);  
  153.   
  154.         if (pdata->flags & DM9000_PLATF_16BITONLY)  
  155.             dm9000_set_io(db, 2);  
  156.   
  157.         if (pdata->flags & DM9000_PLATF_32BITONLY)  
  158.             dm9000_set_io(db, 4);  
  159.   
  160.         /* check to see if there are any IO routine 
  161.          * over-rides */  
  162.   
  163.         if (pdata->inblk != NULL)  
  164.             db->inblk = pdata->inblk;  
  165.   
  166.         if (pdata->outblk != NULL)  
  167.             db->outblk = pdata->outblk;  
  168.   
  169.         if (pdata->dumpblk != NULL)  
  170.             db->dumpblk = pdata->dumpblk;  
  171.   
  172.         db->flags = pdata->flags;  
  173.     }  
  174.   
  175. #ifdef CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL  
  176.     db->flags |= DM9000_PLATF_SIMPLE_PHY;  
  177. #endif  
  178.   
  179.     dm9000_reset(db);/* 复位 */  
  180.   
  181.     /* try multiple times, DM9000 sometimes gets the read wrong */  
  182.     for (i = 0; i < 8; i++) {  
  183.         id_val  = ior(db, DM9000_VIDL);  
  184.         id_val |= (u32)ior(db, DM9000_VIDH) << 8;  
  185.         id_val |= (u32)ior(db, DM9000_PIDL) << 16;  
  186.         id_val |= (u32)ior(db, DM9000_PIDH) << 24;  
  187.   
  188.         if (id_val == DM9000_ID)  
  189.             break;  
  190.         dev_err(db->dev, "read wrong id 0x%08x\n", id_val);  
  191.     }  
  192.   
  193.     if (id_val != DM9000_ID) {  
  194.         dev_err(db->dev, "wrong id: 0x%08x\n", id_val);  
  195.         ret = -ENODEV;  
  196.         goto out;  
  197.     }  
  198.   
  199.     /* Identify what type of DM9000 we are working on */  
  200.   
  201.     id_val = ior(db, DM9000_CHIPR);  
  202.     dev_dbg(db->dev, "dm9000 revision 0x%02x\n", id_val);  
  203.   
  204.     switch (id_val) {  
  205.     case CHIPR_DM9000A:  
  206.         db->type = TYPE_DM9000A;  
  207.         break;  
  208.     case CHIPR_DM9000B:  
  209.         db->type = TYPE_DM9000B;  
  210.         break;  
  211.     default:  
  212.         dev_dbg(db->dev, "ID %02x => defaulting to DM9000E\n", id_val);  
  213.         db->type = TYPE_DM9000E;  
  214.     }  
  215.   
  216.     /* dm9000a/b are capable of hardware checksum offload */  
  217.     if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) {  
  218.         db->can_csum = 1;  
  219.         db->rx_csum = 1;  
  220.         ndev->features |= NETIF_F_IP_CSUM;  
  221.     }  
  222.   
  223.     /* from this point we assume that we have found a DM9000 */  
  224.   
  225.     /* driver system function */  
  226.     ether_setup(ndev);  
  227.   
  228.     ndev->netdev_ops = &dm9000_netdev_ops;  
  229.     ndev->watchdog_timeo = msecs_to_jiffies(watchdog);  
  230.     ndev->ethtool_ops    = &dm9000_ethtool_ops;  
  231.   
  232.     db->msg_enable       = NETIF_MSG_LINK;  
  233.     db->mii.phy_id_mask  = 0x1f;  
  234.     db->mii.reg_num_mask = 0x1f;  
  235.     db->mii.force_media  = 0;  
  236.     db->mii.full_duplex  = 0;  
  237.     db->mii.dev       = ndev;  
  238.     db->mii.mdio_read    = dm9000_phy_read;  
  239.     db->mii.mdio_write   = dm9000_phy_write;  
  240.   
  241.     mac_src = "eeprom";  
  242.   
  243.     /* try reading the node address from the attached EEPROM */  
  244.     for (i = 0; i < 6; i += 2)  
  245.         dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);  
  246.   
  247.     if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {  
  248.         mac_src = "platform data";  
  249.         memcpy(ndev->dev_addr, pdata->dev_addr, 6);  
  250.     }  
  251.   
  252.     if (!is_valid_ether_addr(ndev->dev_addr)) {  
  253.         /* try reading from mac */  
  254.           
  255.         mac_src = "chip";  
  256.         for (i = 0; i < 6; i++)  
  257.             ndev->dev_addr[i] = ne_def_eth_mac_addr[i];  
  258.     }  
  259.   
  260.     if (!is_valid_ether_addr(ndev->dev_addr))  
  261.         dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "  
  262.              "set using ifconfig\n", ndev->name);  
  263.   
  264.     /* 设置pdev->dev->driver_data为ndev,保存成平台设备总线上的数据,以后使用只需platform_get_drvdata()即可*/  
  265.     platform_set_drvdata(pdev, ndev);  
  266.       
  267.     /* 注册该网络设备 */  
  268.     ret = register_netdev(ndev);  
  269.   
  270.     if (ret == 0)  
  271.         printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %pM (%s)\n",  
  272.                ndev->name, dm9000_type_to_char(db->type),  
  273.                db->io_addr, db->io_data, ndev->irq,  
  274.                ndev->dev_addr, mac_src);  
  275.     return 0;  
  276.       
  277. /* 异常处理 */  
  278. out:  
  279.     dev_err(db->dev, "not found (%d).\n", ret);  
  280.   
  281.     dm9000_release_board(pdev, db);  
  282.     free_netdev(ndev);  
  283.   
  284.     return ret;  
  285. }  
这样,最后完成了网络设备的数据保存到总线上,将网络设备注册到内核。

4、设备的移除函数

  1. /* 该函数是将设备从内核中移除,释放资源,在移除设备驱动时执行 */  
  2. static int __devexit  
  3. dm9000_drv_remove(struct platform_device *pdev)  
  4. {  
  5.     struct net_device *ndev = platform_get_drvdata(pdev);/* 从总线获取probe函数保存到总线的设备信息 */  
  6.   
  7.     platform_set_drvdata(pdev, NULL);/* 释放pdev资源 */  
  8.   
  9.     unregister_netdev(ndev);/* 解除网络设备 */  
  10.     dm9000_release_board(pdev, (board_info_t *) netdev_priv(ndev));/* 释放该设备申请的IO资源 */  
  11.     free_netdev(ndev);      /* free device structure */  
  12.   
  13.     dev_dbg(&pdev->dev, "released and freed device\n");  
  14.     return 0;  


硬件平台:FL2440(s3c2440)

内核版本:2.6.35

主机平台:Ubuntu11.04

内核版本:2.6.39

交叉编译器:arm-linuc-gcc4.3.2

原创作品,转载请标明出处http://blog.csdn.net/yming0221/article/details/6615027

本文接上文

ARM-Linux驱动--DM9000网卡驱动分析(一)

ARM-Linux驱动--DM9000网卡驱动分析(二)

下面开始看网卡设备的打开、关闭函数和操作函数

  1. static const struct net_device_ops dm9000_netdev_ops = {  
  2.     .ndo_open       = dm9000_open,/* 打开设备函数 */  
  3.     .ndo_stop       = dm9000_stop,/* 关闭设备函数 */  
  4.     .ndo_start_xmit     = dm9000_start_xmit,/* 开始发送数据 */  
  5.     .ndo_tx_timeout     = dm9000_timeout,/* 发送超时 */  
  6.     .ndo_set_multicast_list = dm9000_hash_table,/* 设定多播列表 */  
  7.     .ndo_do_ioctl       = dm9000_ioctl,/* io操作函数 */  
  8.     .ndo_change_mtu     = eth_change_mtu,/* 改变MTU */  
  9.     .ndo_validate_addr  = eth_validate_addr,  
  10.     .ndo_set_mac_address    = eth_mac_addr,  
  11. #ifdef CONFIG_NET_POLL_CONTROLLER  
  12.     .ndo_poll_controller    = dm9000_poll_controller,  
  13. #endif  
  14. };  

1DM9000的打开函数

由于在函数alloc_netdev_mq()中分配net_device和网卡的私有数据是一起分配的,详见函数的实现

  1. struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,  
  2.         void (*setup)(struct net_device *), unsigned int queue_count)  
  3. {  
  4. ...................  
  5. alloc_size = sizeof(struct net_device);  
  6.     if (sizeof_priv) {  
  7.         /* ensure 32-byte alignment of private area */  
  8.         alloc_size = ALIGN(alloc_size, NETDEV_ALIGN);  
  9.         alloc_size += sizeof_priv;  
  10.     }  
  11.     /* ensure 32-byte alignment of whole construct */  
  12.     alloc_size += NETDEV_ALIGN - 1;  
  13.   
  14.     p = kzalloc(alloc_size, GFP_KERNEL);  
  15.     if (!p) {  
  16.         printk(KERN_ERR "alloc_netdev: Unable to allocate device.\n");  
  17.         return NULL;  
  18.     }  
  19.   
  20.     tx = kcalloc(queue_count, sizeof(struct netdev_queue), GFP_KERNEL);  
  21.     if (!tx) {  
  22.         printk(KERN_ERR "alloc_netdev: Unable to allocate "  
  23.                "tx qdiscs.\n");  
  24.         goto free_p;  
  25.     }  
  26.   
  27. #ifdef CONFIG_RPS  
  28.     rx = kcalloc(queue_count, sizeof(struct netdev_rx_queue), GFP_KERNEL);  
  29.     if (!rx) {  
  30.         printk(KERN_ERR "alloc_netdev: Unable to allocate "  
  31.                "rx queues.\n");  
  32.         goto free_tx;  
  33.     }  
  34. ..............  
  35. }  

    所以使用函数netdev_priv()函数返回的是网卡的私有数据的地址,函数的实现如下:

    1. /** 
    2.  *      netdev_priv - access network device private data 
    3.  *      @dev: network device 
    4.  * 
    5.  * Get network device private data 
    6.  */  
    7. static inline void *netdev_priv(const struct net_device *dev)  
    8. {  
    9.         return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN);  
    10. }  

    这样两者会同时生存和消失。

dm9000_open()函数

  1. /* 
  2.  *  Open the interface. 
  3.  *  The interface is opened whenever "ifconfig" actives it. 
  4.  */  
  5. static int  
  6. dm9000_open(struct net_device *dev)  
  7. {  
  8.         board_info_t *db = netdev_priv(dev);/* 返回board_info_t的地址 */  
  9.         unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;  
  10.   
  11.         if (netif_msg_ifup(db))  
  12.                 dev_dbg(db->dev, "enabling %s\n", dev->name);  
  13.   
  14.         /* If there is no IRQ type specified, default to something that 
  15.          * may work, and tell the user that this is a problem */  
  16.   
  17.         if (irqflags == IRQF_TRIGGER_NONE)  
  18.                 dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");  
  19.   
  20.         irqflags |= IRQF_SHARED;  
  21.           
  22.         /* 注册中断 */  
  23.         if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))  
  24.                 return -EAGAIN;  
  25.   
  26.         /* Initialize DM9000 board */  
  27.         dm9000_reset(db);/* 复位DM9000 */  
  28.         dm9000_init_dm9000(dev);/* 根据net_device的数据初始化DM9000 */  
  29.   
  30.         /* Init driver variable */  
  31.         db->dbug_cnt = 0;  
  32.   
  33.         mii_check_media(&db->mii, netif_msg_link(db), 1);/* 检测mii接口的状态 */  
  34.         netif_start_queue(dev);/* 用来告诉上层网络协定这个驱动程序还有空的缓冲区可用,请把下 一个封包送进来。*/  
  35.           
  36.         /*在probe函数中初始化的等待队列 INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);    
  37.         *初始化定时器,调用等待队列*/  
  38.         dm9000_schedule_poll(db);  
  39.   
  40.         return 0;  
  41. }  

    2、网卡关闭函数

    1. /* 
    2.  * Stop the interface. 
    3.  * The interface is stopped when it is brought. 
    4.  */  
    5. static int  
    6. dm9000_stop(struct net_device *ndev)  
    7. {  
    8.         board_info_t *db = netdev_priv(ndev);/* 同上,获取网卡的私有结构信息的地址 */  
    9.   
    10.         if (netif_msg_ifdown(db))  
    11.                 dev_dbg(db->dev, "shutting down %s\n", ndev->name);  
    12.   
    13.         cancel_delayed_work_sync(&db->phy_poll);/* 终止phy_poll队列中被延迟的任务 */  
    14.   
    15.         netif_stop_queue(ndev);/* 关闭发送队列 */  
    16.         netif_carrier_off(ndev);/*通知该内核设备载波丢失,大部分涉及实际的物理连接的网络技术提供有一个载波状态,载波存在说明硬件存在并准备好*/  
    17.   
    18.         /* free interrupt */  
    19.         free_irq(ndev->irq, ndev);/* 释放中断 */  
    20.   
    21.         dm9000_shutdown(ndev);/* 关闭DM9000网卡 */  
    22.   
    23.         return 0;  
    24. }  


    下面是调用的dm9000_shutdown(ndev)函数,该函数的功能是复位phy,配置寄存器GPR01,关闭dm9000电源,配置寄存器IMR71disable中断,配置寄存器RCRdisable接收

函数如下:

  1. static void  
  2. dm9000_shutdown(struct net_device *dev)  
  3. {  
  4.         board_info_t *db = netdev_priv(dev);/* 获取网卡私有信息的地址 */  
  5.   
  6.         /* RESET device */  
  7.         dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET ,复位PHY*/  
  8.         iow(db, DM9000_GPR, 0x01);      /* Power-Down PHY ,关闭PHY*/  
  9.         iow(db, DM9000_IMR, IMR_PAR);   /* Disable all interrupt ,关闭所有的中断*/  
  10.         iow(db, DM9000_RCR, 0x00);      /* Disable RX ,不再接受数据*/  
  11. }  


    3、接下来了解一下数据的发送函数dm9000_start_xmit

上图可以看出DM9000SRAM中地址0x00000x0BFFTXBuffer,从0x0C000x3FFFRXBuffer,包的有效数据必须提前放到TXBuffer缓冲区,使用端口命令来选择MWCMD寄存器。最后设置TXCR寄存器的bit[0]TXREQ来自动发送包。
发送包的步骤如下:

1)检查存储器宽度,通过读取ISRbit[7:6]来确定位数
2)写数据到TXSRAM
3)写传输长度到TXPLLTXPLH寄存器
4)设置TXCRbit[0]TXREQ来发送包

  1. /* 
  2.  *  Hardware start transmission. 
  3.  *  Send a packet to media from the upper layer. 
  4.  */  
  5. static int  
  6. dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)  
  7. {  
  8.         unsigned long flags;  
  9.         board_info_t *db = netdev_priv(dev);/* 获取网卡虽有信息的存储结构信息的地址 */  
  10.   
  11.         dm9000_dbg(db, 3, "%s:\n", __func__);  
  12.   
  13.         if (db->tx_pkt_cnt > 1)  
  14.                 return NETDEV_TX_BUSY;  
  15.   
  16.         spin_lock_irqsave(&db->lock, flags);/* 获得自旋锁 */  
  17.   
  18.         /* Move data to DM9000 TX RAM */  
  19.         /*MWCMD 即 Memory data write command with address increment Register(F8H) 
  20.         * 根据 IO 操作模式(8-bit or 16-bit)来增加写指针 1 或 2 
  21.         */  
  22.         writeb(DM9000_MWCMD, db->io_addr);  
  23.   
  24.         (db->outblk)(db->io_data, skb->data, skb->len);/* 将数据从sk_buff中copy到网卡的TX SRAM中 */  
  25.           
  26.         dev->stats.tx_bytes += skb->len;/* 统计发送的字节数 */  
  27.           
  28.         db->tx_pkt_cnt++;/* 待发送计数 */  
  29.         /* TX control: First packet immediately send, second packet queue */  
  30.         if (db->tx_pkt_cnt == 1) {  
  31.                 dm9000_send_packet(dev, skb->ip_summed, skb->len);/* 如果计数为1,直接发送 */  
  32.         } else {/* 如果是第2个,则 */  
  33.                 /* Second packet */  
  34.                 db->queue_pkt_len = skb->len;  
  35.                 db->queue_ip_summed = skb->ip_summed;  
  36.                 netif_stop_queue(dev);/* 告诉上层停止发送 */  
  37.         }  
  38.         spin_unlock_irqrestore(&db->lock, flags);/* 解锁 */  
  39.         /* free this SKB ,释放SKB*/  
  40.         dev_kfree_skb(skb);  
  41.   
  42.         return NETDEV_TX_OK;  
  43. }  

    上面函数调用下面的函数 dm9000_send_packet来发送数据

    1. static void dm9000_send_packet(struct net_device *dev,  
    2.                                int ip_summed,  
    3.                                u16 pkt_len)  
    4. {  
    5.         board_info_t *dm = to_dm9000_board(dev);  
    6.   
    7.         /* The DM9000 is not smart enough to leave fragmented packets alone. */  
    8.         if (dm->ip_summed != ip_summed) {  
    9.                 if (ip_summed == CHECKSUM_NONE)  
    10.                         iow(dm, DM9000_TCCR, 0);  
    11.                 else  
    12.                         iow(dm, DM9000_TCCR, TCCR_IP | TCCR_UDP | TCCR_TCP);  
    13.                 dm->ip_summed = ip_summed;  
    14.         }  
    15.   
    16.         /* Set TX length to DM9000 */  
    17.         /* 设置TX数据的长度到寄存器TXPLL和TXPLH */  
    18.         iow(dm, DM9000_TXPLL, pkt_len);  
    19.         iow(dm, DM9000_TXPLH, pkt_len >> 8);  
    20.   
    21.         /* Issue TX polling command */  
    22.         /* 设置发送控制寄存器的发送请求位 */  
    23.         iow(dm, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */  
    24. }  

5、下面看一下当一个数据包发送完成后的中断处理函数dm9000_tx_done

  1. /* 
  2.  * DM9000 interrupt handler 
  3.  * receive the packet to upper layer, free the transmitted packet 
  4.  */  
  5.   
  6. static void dm9000_tx_done(struct net_device *dev, board_info_t *db)  
  7. {  
  8.         int tx_status = ior(db, DM9000_NSR);    /* Got TX status */  
  9.   
  10.         if (tx_status & (NSR_TX2END | NSR_TX1END)) {/* 第一个或第二个数据包发送完毕 */  
  11.                 /* One packet sent complete */  
  12.                 db->tx_pkt_cnt--;/* 待发送的数据包个数减1 */  
  13.                 dev->stats.tx_packets++;/* 发送的数据包加1 */  
  14.   
  15.                 if (netif_msg_tx_done(db))  
  16.                         dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status);  
  17.   
  18.                 /* Queue packet check & send */  
  19.                 if (db->tx_pkt_cnt > 0)/* 如果还有数据包 */  
  20.                         dm9000_send_packet(dev, db->queue_ip_summed,  
  21.                                            db->queue_pkt_len);  
  22.                 netif_wake_queue(dev);/* 告诉内核,将数据包放入发生那个队列 */  
  23.         }  


硬件平台:FL2440 (S3C2440)

内核版本:2.6.35

主机平台:Ubuntu 11.04

内核版本:2.6.39

交叉编译器:arm-linux-gcc 4.3.2

原创作品,转载请标明出处

本文接上文

ARM-Linux驱动--DM9000网卡驱动分析(一)

ARM-Linux驱动--DM9000网卡驱动分析(二)

ARM-Linux驱动--DM9000网卡驱动分析(三)

1、接下来接着分析DM9000网卡驱动的数据接收函数

  1. /* 
  2.  *  Received a packet and pass to upper layer 
  3.  *  接收数据包,将数据包传递给上层 
  4.  */  
  5. static void  
  6. dm9000_rx(struct net_device *dev)  
  7. {  
  8.     board_info_t *db = netdev_priv(dev);/* 得到网卡私有信息数据结构的首地址 */  
  9.     struct dm9000_rxhdr rxhdr;/* 该结构体封装了dm9000接收的数据包信息 */  
  10.     struct sk_buff *skb;  
  11.     u8 rxbyte, *rdptr;  
  12.     bool GoodPacket;  
  13.     int RxLen;  
  14.   
  15.     /* Check packet ready or not */  
  16.     do {  
  17.         /* MRCMDX是内存数据预取读命令 */  
  18.         ior(db, DM9000_MRCMDX); /* Dummy read */  
  19.         /* Get most updated data */  
  20.         rxbyte = readb(db->io_data);  
  21.   
  22.         /* Status check: this byte must be 0 or 1 */  
  23.         /* DM9000_PKT_ERR          0x02 ,表示接收出错 */  
  24.         if (rxbyte & DM9000_PKT_ERR) {  
  25.             dev_warn(db->dev, "status check fail: %d\n", rxbyte);/* 输出提示信息 */  
  26.             iow(db, DM9000_RCR, 0x00);  /* Stop Device 关闭设备 */  
  27.             iow(db, DM9000_ISR, IMR_PAR);   /* Stop INT request 停止中断请求*/  
  28.             return;  
  29.         }  
  30.           
  31.         /* DM9000_PKT_RDY          0x01 没有准备好,直接返回*/  
  32.         if (!(rxbyte & DM9000_PKT_RDY))  
  33.             return;  
  34.   
  35.         /* A packet ready now  & Get status/length */  
  36.         GoodPacket = true;  
  37.         writeb(DM9000_MRCMD, db->io_addr);/* MRCMD是地址增加的数据读取命令 */  
  38.   
  39.         (db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));/* 读取数据,从RX_SRAM到 rxhdr结构体中*/  
  40.   
  41.         RxLen = le16_to_cpu(rxhdr.RxLen);  
  42.   
  43.         if (netif_msg_rx_status(db))  
  44.             dev_dbg(db->dev, "RX: status %02x, length %04x\n",  
  45.                 rxhdr.RxStatus, RxLen);  
  46.   
  47.         /* Packet Status check ,检查包的完整性*/  
  48.         if (RxLen < 0x40) {  
  49.             GoodPacket = false;  
  50.             if (netif_msg_rx_err(db))  
  51.                 dev_dbg(db->dev, "RX: Bad Packet (runt)\n");  
  52.         }  
  53.         /* 如果数据长度大于DM9000_PKT_MAX ,即 1536 */  
  54.         if (RxLen > DM9000_PKT_MAX) {  
  55.             dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen);  
  56.         }  
  57.   
  58.         /* rxhdr.RxStatus is identical to RSR register. */  
  59.         /* 这里也是包的检查 */  
  60.         if (rxhdr.RxStatus & (RSR_FOE | RSR_CE | RSR_AE |  
  61.                       RSR_PLE | RSR_RWTO |  
  62.                       RSR_LCS | RSR_RF)) {  
  63.             GoodPacket = false;  
  64.             if (rxhdr.RxStatus & RSR_FOE) {  
  65.                 if (netif_msg_rx_err(db))  
  66.                     dev_dbg(db->dev, "fifo error\n");  
  67.                 dev->stats.rx_fifo_errors++;  
  68.             }  
  69.             if (rxhdr.RxStatus & RSR_CE) {  
  70.                 if (netif_msg_rx_err(db))  
  71.                     dev_dbg(db->dev, "crc error\n");  
  72.                 dev->stats.rx_crc_errors++;  
  73.             }  
  74.             if (rxhdr.RxStatus & RSR_RF) {  
  75.                 if (netif_msg_rx_err(db))  
  76.                     dev_dbg(db->dev, "length error\n");  
  77.                 dev->stats.rx_length_errors++;  
  78.             }  
  79.         }  
  80.   
  81.         /* Move data from DM9000 ,从DM9000获取数据*/  
  82.         if (GoodPacket &&  
  83.             ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {  
  84.             skb_reserve(skb, 2);  
  85.             rdptr = (u8 *) skb_put(skb, RxLen - 4);  
  86.   
  87.             /* Read received packet from RX SRAM */  
  88.             /* 将RX SRAM中的数据读取到skbuff结构体 */  
  89.             (db->inblk)(db->io_data, rdptr, RxLen);  
  90.             dev->stats.rx_bytes += RxLen;  
  91.   
  92.             /* Pass to upper layer */  
  93.             skb->protocol = eth_type_trans(skb, dev);  
  94.             if (db->rx_csum) {  
  95.                 if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0)  
  96.                     skb->ip_summed = CHECKSUM_UNNECESSARY;  
  97.                 else  
  98.                     skb->ip_summed = CHECKSUM_NONE;  
  99.             }  
  100.             netif_rx(skb);/* 将skbuff结构体发送给上层 */  
  101.             dev->stats.rx_packets++;/* 计数增1 */  
  102.   
  103.         } else {  
  104.             /* need to dump the packet's data */  
  105.             /* 坏包,丢弃 */  
  106.             (db->dumpblk)(db->io_data, RxLen);  
  107.         }  
  108.     } while (rxbyte & DM9000_PKT_RDY);  
  109. }  
2、下面是完整的DM9000驱动代码,可以完整的查看
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include   
  6. #include   
  7. #include   
  8. #include   
  9. #include   
  10. #include   
  11. #include   
  12. #include   
  13. #include   
  14. #include   
  15. #include   
  16.   
  17. #include   
  18. #include   
  19. #include   
  20.   
  21. #include "dm9000.h"  
  22.   
  23. #include    
  24. #include   
  25. #include   
  26.   
  27. /* Board/System/Debug information/definition ---------------- */  
  28.   
  29. #define DM9000_PHY      0x40    /* PHY address 0x01 */  
  30.   
  31. #define CARDNAME    "dm9000"  
  32. #define DRV_VERSION "1.31"  
  33.   
  34. /* 
  35.  * Transmit timeout, default 5 seconds. 
  36.  */  
  37. static int watchdog = 5000;  
  38. module_param(watchdog, int, 0400);  
  39. MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");  
  40.   
  41. /* DM9000 register address locking. 
  42.  * 
  43.  * The DM9000 uses an address register to control where data written 
  44.  * to the data register goes. This means that the address register 
  45.  * must be preserved over interrupts or similar calls. 
  46.  * 
  47.  * During interrupt and other critical calls, a spinlock is used to 
  48.  * protect the system, but the calls themselves save the address 
  49.  * in the address register in case they are interrupting another 
  50.  * access to the device. 
  51.  * 
  52.  * For general accesses a lock is provided so that calls which are 
  53.  * allowed to sleep are serialised so that the address register does 
  54.  * not need to be saved. This lock also serves to serialise access 
  55.  * to the EEPROM and PHY access registers which are shared between 
  56.  * these two devices. 
  57.  */  
  58.   
  59. /* The driver supports the original DM9000E, and now the two newer 
  60.  * devices, DM9000A and DM9000B. 
  61.  */  
  62.   
  63. enum dm9000_type {  
  64.     TYPE_DM9000E,   /* original DM9000 */  
  65.     TYPE_DM9000A,  
  66.     TYPE_DM9000B  
  67. };  
  68.   
  69. /* Structure/enum declaration ------------------------------- */  
  70. typedef struct board_info {  
  71.   
  72.     void __iomem    *io_addr;   /* Register I/O base address */  
  73.     void __iomem    *io_data;   /* Data I/O address */  
  74.     u16      irq;       /* IRQ */  
  75.   
  76.     u16     tx_pkt_cnt;  
  77.     u16     queue_pkt_len;  
  78.     u16     queue_start_addr;  
  79.     u16     queue_ip_summed;  
  80.     u16     dbug_cnt;  
  81.     u8      io_mode;        /* 0:word, 2:byte */  
  82.     u8      phy_addr;  
  83.     u8      imr_all;  
  84.   
  85.     unsigned int    flags;  
  86.     unsigned int    in_suspend :1;  
  87.     unsigned int    wake_supported :1;  
  88.     int     debug_level;  
  89.   
  90.     enum dm9000_type type;  
  91.   
  92.     void (*inblk)(void __iomem *port, void *data, int length);  
  93.     void (*outblk)(void __iomem *port, void *data, int length);  
  94.     void (*dumpblk)(void __iomem *port, int length);  
  95.   
  96.     struct device   *dev;        /* parent device */  
  97.   
  98.     struct resource *addr_res;   /* resources found */  
  99.     struct resource *data_res;  
  100.     struct resource *addr_req;   /* resources requested */  
  101.     struct resource *data_req;  
  102.     struct resource *irq_res;  
  103.   
  104.     int      irq_wake;  
  105.   
  106.     struct mutex     addr_lock; /* phy and eeprom access lock */  
  107.   
  108.     struct delayed_work phy_poll;  
  109.     struct net_device  *ndev;  
  110.   
  111.     spinlock_t  lock;  
  112.   
  113.     struct mii_if_info mii;  
  114.     u32     msg_enable;  
  115.     u32     wake_state;  
  116.   
  117.     int     rx_csum;  
  118.     int     can_csum;  
  119.     int     ip_summed;  
  120. } board_info_t;  
  121.   
  122. /* debug code */  
  123.   
  124. #define dm9000_dbg(db, lev, msg...) do {        \  
  125.     if ((lev) < CONFIG_DM9000_DEBUGLEVEL &&      \  
  126.         (lev) < db->debug_level) {            \  
  127.         dev_dbg(db->dev, msg);           \  
  128.     }                       \  
  129. while (0)  
  130.   
  131. static inline board_info_t *to_dm9000_board(struct net_device *dev)  
  132. {  
  133.     return netdev_priv(dev);  
  134. }  
  135.   
  136. /* DM9000 network board routine ---------------------------- */  
  137.   
  138. static void  
  139. dm9000_reset(board_info_t * db)  
  140. {  
  141.     dev_dbg(db->dev, "resetting device\n");  
  142.   
  143.     /* RESET device */  
  144.     writeb(DM9000_NCR, db->io_addr);  
  145.     udelay(200);  
  146.     writeb(NCR_RST, db->io_data);  
  147.     udelay(200);  
  148. }  
  149.   
  150. /* 
  151.  *   Read a byte from I/O port 
  152.  */  
  153. static u8  
  154. ior(board_info_t * db, int reg)  
  155. {  
  156.     writeb(reg, db->io_addr);  
  157.     return readb(db->io_data);  
  158. }  
  159.   
  160. /* 
  161.  *   Write a byte to I/O port 
  162.  */  
  163.   
  164. static void  
  165. iow(board_info_t * db, int reg, int value)  
  166. {  
  167.     writeb(reg, db->io_addr);  
  168.     writeb(value, db->io_data);  
  169. }  
  170.   
  171. /* routines for sending block to chip */  
  172.   
  173. static void dm9000_outblk_8bit(void __iomem *reg, void *data, int count)  
  174. {  
  175.     writesb(reg, data, count);  
  176. }  
  177.   
  178. static void dm9000_outblk_16bit(void __iomem *reg, void *data, int count)  
  179. {  
  180.     writesw(reg, data, (count+1) >> 1);  
  181. }  
  182.   
  183. static void dm9000_outblk_32bit(void __iomem *reg, void *data, int count)  
  184. {  
  185.     writesl(reg, data, (count+3) >> 2);  
  186. }  
  187.   
  188. /* input block from chip to memory */  
  189.   
  190. static void dm9000_inblk_8bit(void __iomem *reg, void *data, int count)  
  191. {  
  192.     readsb(reg, data, count);  
  193. }  
  194.   
  195.   
  196. static void dm9000_inblk_16bit(void __iomem *reg, void *data, int count)  
  197. {  
  198.     readsw(reg, data, (count+1) >> 1);  
  199. }  
  200.   
  201. static void dm9000_inblk_32bit(void __iomem *reg, void *data, int count)  
  202. {  
  203.     readsl(reg, data, (count+3) >> 2);  
  204. }  
  205.   
  206. /* dump block from chip to null */  
  207.   
  208. static void dm9000_dumpblk_8bit(void __iomem *reg, int count)  
  209. {  
  210.     int i;  
  211.     int tmp;  
  212.   
  213.     for (i = 0; i < count; i++)  
  214.         tmp = readb(reg);  
  215. }  
  216.   
  217. static void dm9000_dumpblk_16bit(void __iomem *reg, int count)  
  218. {  
  219.     int i;  
  220.     int tmp;  
  221.   
  222.     count = (count + 1) >> 1;  
  223.   
  224.     for (i = 0; i < count; i++)  
  225.         tmp = readw(reg);  
  226. }  
  227.   
  228. static void dm9000_dumpblk_32bit(void __iomem *reg, int count)  
  229. {  
  230.     int i;  
  231.     int tmp;  
  232.   
  233.     count = (count + 3) >> 2;  
  234.   
  235.     for (i = 0; i < count; i++)  
  236.         tmp = readl(reg);  
  237. }  
  238.   
  239. /* dm9000_set_io 
  240.  * 
  241.  * select the specified set of io routines to use with the 
  242.  * device 
  243.  */  
  244.   
  245. static void dm9000_set_io(struct board_info *db, int byte_width)  
  246. {  
  247.     /* use the size of the data resource to work out what IO 
  248.      * routines we want to use 
  249.      */  
  250.   
  251.     switch (byte_width) {  
  252.     case 1:  
  253.         db->dumpblk = dm9000_dumpblk_8bit;  
  254.         db->outblk  = dm9000_outblk_8bit;  
  255.         db->inblk   = dm9000_inblk_8bit;  
  256.         break;  
  257.   
  258.   
  259.     case 3:  
  260.         dev_dbg(db->dev, ": 3 byte IO, falling back to 16bit\n");  
  261.     case 2:  
  262.         db->dumpblk = dm9000_dumpblk_16bit;  
  263.         db->outblk  = dm9000_outblk_16bit;  
  264.         db->inblk   = dm9000_inblk_16bit;  
  265.         break;  
  266.   
  267.     case 4:  
  268.     default:  
  269.         db->dumpblk = dm9000_dumpblk_32bit;  
  270.         db->outblk  = dm9000_outblk_32bit;  
  271.         db->inblk   = dm9000_inblk_32bit;  
  272.         break;  
  273.     }  
  274. }  
  275.   
  276. static void dm9000_schedule_poll(board_info_t *db)  
  277. {  
  278.     if (db->type == TYPE_DM9000E)  
  279.         schedule_delayed_work(&db->phy_poll, HZ * 2);  
  280. }  
  281.   
  282. static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd)  
  283. {  
  284.     board_info_t *dm = to_dm9000_board(dev);  
  285.   
  286.     if (!netif_running(dev))  
  287.         return -EINVAL;  
  288.   
  289.     return generic_mii_ioctl(&dm->mii, if_mii(req), cmd, NULL);  
  290. }  
  291.   
  292. static unsigned int  
  293. dm9000_read_locked(board_info_t *db, int reg)  
  294. {  
  295.     unsigned long flags;  
  296.     unsigned int ret;  
  297.   
  298.     spin_lock_irqsave(&db->lock, flags);  
  299.     ret = ior(db, reg);  
  300.     spin_unlock_irqrestore(&db->lock, flags);  
  301.   
  302.     return ret;  
  303. }  
  304.   
  305. static int dm9000_wait_eeprom(board_info_t *db)  
  306. {  
  307.     unsigned int status;  
  308.     int timeout = 8;    /* wait max 8msec */  
  309.   
  310.     /* The DM9000 data sheets say we should be able to 
  311.      * poll the ERRE bit in EPCR to wait for the EEPROM 
  312.      * operation. From testing several chips, this bit 
  313.      * does not seem to work. 
  314.      * 
  315.      * We attempt to use the bit, but fall back to the 
  316.      * timeout (which is why we do not return an error 
  317.      * on expiry) to say that the EEPROM operation has 
  318.      * completed. 
  319.      */  
  320.   
  321.     while (1) {  
  322.         status = dm9000_read_locked(db, DM9000_EPCR);  
  323.   
  324.         if ((status & EPCR_ERRE) == 0)  
  325.             break;  
  326.   
  327.         msleep(1);  
  328.   
  329.         if (timeout-- < 0) {  
  330.             dev_dbg(db->dev, "timeout waiting EEPROM\n");  
  331.             break;  
  332.         }  
  333.     }  
  334.   
  335.     return 0;  
  336. }  
  337.   
  338. /* 
  339.  *  Read a word data from EEPROM 
  340.  */  
  341. static void  
  342. dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)  
  343. {  
  344.     unsigned long flags;  
  345.   
  346.     if (db->flags & DM9000_PLATF_NO_EEPROM) {  
  347.         to[0] = 0xff;  
  348.         to[1] = 0xff;  
  349.         return;  
  350.     }  
  351.   
  352.     mutex_lock(&db->addr_lock);  
  353.   
  354.     spin_lock_irqsave(&db->lock, flags);  
  355.   
  356.     iow(db, DM9000_EPAR, offset);  
  357.     iow(db, DM9000_EPCR, EPCR_ERPRR);  
  358.   
  359.     spin_unlock_irqrestore(&db->lock, flags);  
  360.   
  361.     dm9000_wait_eeprom(db);  
  362.   
  363.     /* delay for at-least 150uS */  
  364.     msleep(1);  
  365.   
  366.     spin_lock_irqsave(&db->lock, flags);  
  367.   
  368.     iow(db, DM9000_EPCR, 0x0);  
  369.   
  370.     to[0] = ior(db, DM9000_EPDRL);  
  371.     to[1] = ior(db, DM9000_EPDRH);  
  372.   
  373.     spin_unlock_irqrestore(&db->lock, flags);  
  374.   
  375.     mutex_unlock(&db->addr_lock);  
  376. }  
  377.   
  378. /* 
  379.  * Write a word data to SROM 
  380.  */  
  381. static void  
  382. dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)  
  383. {  
  384.     unsigned long flags;  
  385.   
  386.     if (db->flags & DM9000_PLATF_NO_EEPROM)  
  387.         return;  
  388.   
  389.     mutex_lock(&db->addr_lock);  
  390.   
  391.     spin_lock_irqsave(&db->lock, flags);  
  392.     iow(db, DM9000_EPAR, offset);  
  393.     iow(db, DM9000_EPDRH, data[1]);  
  394.     iow(db, DM9000_EPDRL, data[0]);  
  395.     iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);  
  396.     spin_unlock_irqrestore(&db->lock, flags);  
  397.   
  398.     dm9000_wait_eeprom(db);  
  399.   
  400.     mdelay(1);  /* wait at least 150uS to clear */  
  401.   
  402.     spin_lock_irqsave(&db->lock, flags);  
  403.     iow(db, DM9000_EPCR, 0);  
  404.     spin_unlock_irqrestore(&db->lock, flags);  
  405.   
  406.     mutex_unlock(&db->addr_lock);  
  407. }  
  408.   
  409. /* ethtool ops */  
  410.   
  411. static void dm9000_get_drvinfo(struct net_device *dev,  
  412.                    struct ethtool_drvinfo *info)  
  413. {  
  414.     board_info_t *dm = to_dm9000_board(dev);  
  415.   
  416.     strcpy(info->driver, CARDNAME);  
  417.     strcpy(info->version, DRV_VERSION);  
  418.     strcpy(info->bus_info, to_platform_device(dm->dev)->name);  
  419. }  
  420.   
  421. static u32 dm9000_get_msglevel(struct net_device *dev)  
  422. {  
  423.     board_info_t *dm = to_dm9000_board(dev);  
  424.   
  425.     return dm->msg_enable;  
  426. }  
  427.   
  428. static void dm9000_set_msglevel(struct net_device *dev, u32 value)  
  429. {  
  430.     board_info_t *dm = to_dm9000_board(dev);  
  431.   
  432.     dm->msg_enable = value;  
  433. }  
  434.   
  435. static int dm9000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)  
  436. {  
  437.     board_info_t *dm = to_dm9000_board(dev);  
  438.   
  439.     mii_ethtool_gset(&dm->mii, cmd);  
  440.     return 0;  
  441. }  
  442.   
  443. static int dm9000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)  
  444. {  
  445.     board_info_t *dm = to_dm9000_board(dev);  
  446.   
  447.     return mii_ethtool_sset(&dm->mii, cmd);  
  448. }  
  449.   
  450. static int dm9000_nway_reset(struct net_device *dev)  
  451. {  
  452.     board_info_t *dm = to_dm9000_board(dev);  
  453.     return mii_nway_restart(&dm->mii);  
  454. }  
  455.   
  456. static uint32_t dm9000_get_rx_csum(struct net_device *dev)  
  457. {  
  458.     board_info_t *dm = to_dm9000_board(dev);  
  459.     return dm->rx_csum;  
  460. }  
  461.   
  462. static int dm9000_set_rx_csum_unlocked(struct net_device *dev, uint32_t data)  
  463. {  
  464.     board_info_t *dm = to_dm9000_board(dev);  
  465.   
  466.     if (dm->can_csum) {  
  467.         dm->rx_csum = data;  
  468.         iow(dm, DM9000_RCSR, dm->rx_csum ? RCSR_CSUM : 0);  
  469.   
  470.         return 0;  
  471.     }  
  472.   
  473.     return -EOPNOTSUPP;  
  474. }  
  475.   
  476. static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data)  
  477. {  
  478.     board_info_t *dm = to_dm9000_board(dev);  
  479.     unsigned long flags;  
  480.     int ret;  
  481.   
  482.     spin_lock_irqsave(&dm->lock, flags);  
  483.     ret = dm9000_set_rx_csum_unlocked(dev, data);  
  484.     spin_unlock_irqrestore(&dm->lock, flags);  
  485.   
  486.     return ret;  
  487. }  
  488.   
  489. static int dm9000_set_tx_csum(struct net_device *dev, uint32_t data)  
  490. {  
  491.     board_info_t *dm = to_dm9000_board(dev);  
  492.     int ret = -EOPNOTSUPP;  
  493.   
  494.     if (dm->can_csum)  
  495.         ret = ethtool_op_set_tx_csum(dev, data);  
  496.     return ret;  
  497. }  
  498.   
  499. static u32 dm9000_get_link(struct net_device *dev)  
  500. {  
  501.     board_info_t *dm = to_dm9000_board(dev);  
  502.     u32 ret;  
  503.   
  504.     if (dm->flags & DM9000_PLATF_EXT_PHY)  
  505.         ret = mii_link_ok(&dm->mii);  
  506.     else  
  507.         ret = dm9000_read_locked(dm, DM9000_NSR) & NSR_LINKST ? 1 : 0;  
  508.   
  509.     return ret;  
  510. }  
  511.   
  512. #define DM_EEPROM_MAGIC     (0x444D394B)  
  513.   
  514. static int dm9000_get_eeprom_len(struct net_device *dev)  
  515. {  
  516.     return 128;  
  517. }  
  518.   
  519. static int dm9000_get_eeprom(struct net_device *dev,  
  520.                  struct ethtool_eeprom *ee, u8 *data)  
  521. {  
  522.     board_info_t *dm = to_dm9000_board(dev);  
  523.     int offset = ee->offset;  
  524.     int len = ee->len;  
  525.     int i;  
  526.   
  527.     /* EEPROM access is aligned to two bytes */  
  528.   
  529.     if ((len & 1) != 0 || (offset & 1) != 0)  
  530.         return -EINVAL;  
  531.   
  532.     if (dm->flags & DM9000_PLATF_NO_EEPROM)  
  533.         return -ENOENT;  
  534.   
  535.     ee->magic = DM_EEPROM_MAGIC;  
  536.   
  537.     for (i = 0; i < len; i += 2)  
  538.         dm9000_read_eeprom(dm, (offset + i) / 2, data + i);  
  539.   
  540.     return 0;  
  541. }  
  542.   
  543. static int dm9000_set_eeprom(struct net_device *dev,  
  544.                  struct ethtool_eeprom *ee, u8 *data)  
  545. {  
  546.     board_info_t *dm = to_dm9000_board(dev);  
  547.     int offset = ee->offset;  
  548.     int len = ee->len;  
  549.     int i;  
  550.   
  551.     /* EEPROM access is aligned to two bytes */  
  552.   
  553.     if ((len & 1) != 0 || (offset & 1) != 0)  
  554.         return -EINVAL;  
  555.   
  556.     if (dm->flags & DM9000_PLATF_NO_EEPROM)  
  557.         return -ENOENT;  
  558.   
  559.     if (ee->magic != DM_EEPROM_MAGIC)  
  560.         return -EINVAL;  
  561.   
  562.     for (i = 0; i < len; i += 2)  
  563.         dm9000_write_eeprom(dm, (offset + i) / 2, data + i);  
  564.   
  565.     return 0;  
  566. }  
  567.   
  568. static void dm9000_get_wol(struct net_device *dev, struct ethtool_wolinfo *w)  
  569. {  
  570.     board_info_t *dm = to_dm9000_board(dev);  
  571.   
  572.     memset(w, 0, sizeof(struct ethtool_wolinfo));  
  573.   
  574.     /* note, we could probably support wake-phy too */  
  575.     w->supported = dm->wake_supported ? WAKE_MAGIC : 0;  
  576.     w->wolopts = dm->wake_state;  
  577. }  
  578.   
  579. static int dm9000_set_wol(struct net_device *dev, struct ethtool_wolinfo *w)  
  580. {  
  581.     board_info_t *dm = to_dm9000_board(dev);  
  582.     unsigned long flags;  
  583.     u32 opts = w->wolopts;  
  584.     u32 wcr = 0;  
  585.   
  586.     if (!dm->wake_supported)  
  587.         return -EOPNOTSUPP;  
  588.   
  589.     if (opts & ~WAKE_MAGIC)  
  590.         return -EINVAL;  
  591.   
  592.     if (opts & WAKE_MAGIC)  
  593.         wcr |= WCR_MAGICEN;  
  594.   
  595.     mutex_lock(&dm->addr_lock);  
  596.   
  597.     spin_lock_irqsave(&dm->lock, flags);  
  598.     iow(dm, DM9000_WCR, wcr);  
  599.     spin_unlock_irqrestore(&dm->lock, flags);  
  600.   
  601.     mutex_unlock(&dm->addr_lock);  
  602.   
  603.     if (dm->wake_state != opts) {  
  604.         /* change in wol state, update IRQ state */  
  605.   
  606.         if (!dm->wake_state)  
  607.             set_irq_wake(dm->irq_wake, 1);  
  608.         else if (dm->wake_state & !opts)  
  609.             set_irq_wake(dm->irq_wake, 0);  
  610.     }  
  611.   
  612.     dm->wake_state = opts;  
  613.     return 0;  
  614. }  
  615.   
  616. static const struct ethtool_ops dm9000_ethtool_ops = {  
  617.     .get_drvinfo        = dm9000_get_drvinfo,  
  618.     .get_settings       = dm9000_get_settings,  
  619.     .set_settings       = dm9000_set_settings,  
  620.     .get_msglevel       = dm9000_get_msglevel,  
  621.     .set_msglevel       = dm9000_set_msglevel,  
  622.     .nway_reset     = dm9000_nway_reset,  
  623.     .get_link       = dm9000_get_link,  
  624.     .get_wol        = dm9000_get_wol,  
  625.     .set_wol        = dm9000_set_wol,  
  626.     .get_eeprom_len     = dm9000_get_eeprom_len,  
  627.     .get_eeprom     = dm9000_get_eeprom,  
  628.     .set_eeprom     = dm9000_set_eeprom,  
  629.     .get_rx_csum        = dm9000_get_rx_csum,  
  630.     .set_rx_csum        = dm9000_set_rx_csum,  
  631.     .get_tx_csum        = ethtool_op_get_tx_csum,  
  632.     .set_tx_csum        = dm9000_set_tx_csum,  
  633. };  
  634.   
  635. static void dm9000_show_carrier(board_info_t *db,  
  636.                 unsigned carrier, unsigned nsr)  
  637. {  
  638.     struct net_device *ndev = db->ndev;  
  639.     unsigned ncr = dm9000_read_locked(db, DM9000_NCR);  
  640.   
  641.     if (carrier)  
  642.         dev_info(db->dev, "%s: link up, %dMbps, %s-duplex, no LPA\n",  
  643.              ndev->name, (nsr & NSR_SPEED) ? 10 : 100,  
  644.              (ncr & NCR_FDX) ? "full" : "half");  
  645.     else  
  646.         dev_info(db->dev, "%s: link down\n", ndev->name);  
  647. }  
  648.   
  649. static void  
  650. dm9000_poll_work(struct work_struct *w)  
  651. {  
  652.     struct delayed_work *dw = to_delayed_work(w);  
  653.     board_info_t *db = container_of(dw, board_info_t, phy_poll);  
  654.     struct net_device *ndev = db->ndev;  
  655.   
  656.     if (db->flags & DM9000_PLATF_SIMPLE_PHY &&  
  657.         !(db->flags & DM9000_PLATF_EXT_PHY)) {  
  658.         unsigned nsr = dm9000_read_locked(db, DM9000_NSR);  
  659.         unsigned old_carrier = netif_carrier_ok(ndev) ? 1 : 0;  
  660.         unsigned new_carrier;  
  661.   
  662.         new_carrier = (nsr & NSR_LINKST) ? 1 : 0;  
  663.   
  664.         if (old_carrier != new_carrier) {  
  665.             if (netif_msg_link(db))  
  666.                 dm9000_show_carrier(db, new_carrier, nsr);  
  667.   
  668.             if (!new_carrier)  
  669.                 netif_carrier_off(ndev);  
  670.             else  
  671.                 netif_carrier_on(ndev);  
  672.         }  
  673.     } else  
  674.         mii_check_media(&db->mii, netif_msg_link(db), 0);  
  675.       
  676.     if (netif_running(ndev))  
  677.         dm9000_schedule_poll(db);  
  678. }  
  679.   
  680. /* dm9000_release_board 
  681.  * 
  682.  * release a board, and any mapped resources 
  683.  */  
  684.   
  685. static void  
  686. dm9000_release_board(struct platform_device *pdev, struct board_info *db)  
  687. {  
  688.     /* unmap our resources */  
  689.   
  690.     iounmap(db->io_addr);  
  691.     iounmap(db->io_data);  
  692.   
  693.     /* release the resources */  
  694.   
  695.     release_resource(db->data_req);  
  696.     kfree(db->data_req);  
  697.   
  698.     release_resource(db->addr_req);  
  699.     kfree(db->addr_req);  
  700. }  
  701.   
  702. static unsigned char dm9000_type_to_char(enum dm9000_type type)  
  703. {  
  704.     switch (type) {  
  705.     case TYPE_DM9000E: return 'e';  
  706.     case TYPE_DM9000A: return 'a';  
  707.     case TYPE_DM9000B: return 'b';  
  708.     }  
  709.   
  710.     return '?';  
  711. }  
  712.   
  713. /* 
  714.  *  Set DM9000 multicast address 
  715.  */  
  716. static void  
  717. dm9000_hash_table_unlocked(struct net_device *dev)  
  718. {  
  719.     board_info_t *db = netdev_priv(dev);  
  720.     struct netdev_hw_addr *ha;  
  721.     int i, oft;  
  722.     u32 hash_val;  
  723.     u16 hash_table[4];  
  724.     u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN;  
  725.   
  726.     dm9000_dbg(db, 1, "entering %s\n", __func__);  
  727.   
  728.     for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)  
  729.         iow(db, oft, dev->dev_addr[i]);  
  730.   
  731.     /* Clear Hash Table */  
  732.     for (i = 0; i < 4; i++)  
  733.         hash_table[i] = 0x0;  
  734.   
  735.     /* broadcast address */  
  736.     hash_table[3] = 0x8000;  
  737.   
  738.     if (dev->flags & IFF_PROMISC)  
  739.         rcr |= RCR_PRMSC;  
  740.   
  741.     if (dev->flags & IFF_ALLMULTI)  
  742.         rcr |= RCR_ALL;  
  743.   
  744.     /* the multicast address in Hash Table : 64 bits */  
  745.     netdev_for_each_mc_addr(ha, dev) {  
  746.         hash_val = ether_crc_le(6, ha->addr) & 0x3f;  
  747.         hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);  
  748.     }  
  749.   
  750.     /* Write the hash table to MAC MD table */  
  751.     for (i = 0, oft = DM9000_MAR; i < 4; i++) {  
  752.         iow(db, oft++, hash_table[i]);  
  753.         iow(db, oft++, hash_table[i] >> 8);  
  754.     }  
  755.   
  756.     iow(db, DM9000_RCR, rcr);  
  757. }  
  758.   
  759. static void  
  760. dm9000_hash_table(struct net_device *dev)  
  761. {  
  762.     board_info_t *db = netdev_priv(dev);  
  763.     unsigned long flags;  
  764.   
  765.     spin_lock_irqsave(&db->lock, flags);  
  766.     dm9000_hash_table_unlocked(dev);  
  767.     spin_unlock_irqrestore(&db->lock, flags);  
  768. }  
  769.   
  770. /* 
  771.  * Initialize dm9000 board 
  772.  */  
  773. static void  
  774. dm9000_init_dm9000(struct net_device *dev)  
  775. {  
  776.     board_info_t *db = netdev_priv(dev);  
  777.     unsigned int imr;  
  778.     unsigned int ncr;  
  779.   
  780.     dm9000_dbg(db, 1, "entering %s\n", __func__);  
  781.   
  782.     /* I/O mode */  
  783.     db->io_mode = ior(db, DM9000_ISR) >> 6;    /* ISR bit7:6 keeps I/O mode */  
  784.   
  785.     /* Checksum mode */  
  786.     dm9000_set_rx_csum_unlocked(dev, db->rx_csum);  
  787.   
  788.     /* GPIO0 on pre-activate PHY */  
  789.     iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */  
  790.     iow(db, DM9000_GPCR, GPCR_GEP_CNTL);    /* Let GPIO0 output */  
  791.     iow(db, DM9000_GPR, 0); /* Enable PHY */  
  792.   
  793.     ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0;  
  794.   
  795.     /* if wol is needed, then always set NCR_WAKEEN otherwise we end 
  796.      * up dumping the wake events if we disable this. There is already 
  797.      * a wake-mask in DM9000_WCR */  
  798.     if (db->wake_supported)  
  799.         ncr |= NCR_WAKEEN;  
  800.   
  801.     iow(db, DM9000_NCR, ncr);  
  802.   
  803.     /* Program operating register */  
  804.     iow(db, DM9000_TCR, 0);         /* TX Polling clear */  
  805.     iow(db, DM9000_BPTR, 0x3f); /* Less 3Kb, 200us */  
  806.     iow(db, DM9000_FCR, 0xff);  /* Flow Control */  
  807.     iow(db, DM9000_SMCR, 0);        /* Special Mode */  
  808.     /* clear TX status */  
  809.     iow(db, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);  
  810.     iow(db, DM9000_ISR, ISR_CLR_STATUS); /* Clear interrupt status */  
  811.   
  812.     /* Set address filter table */  
  813.     dm9000_hash_table_unlocked(dev);  
  814.   
  815.     imr = IMR_PAR | IMR_PTM | IMR_PRM;  
  816.     if (db->type != TYPE_DM9000E)  
  817.         imr |= IMR_LNKCHNG;  
  818.   
  819.     db->imr_all = imr;  
  820.   
  821.     /* Enable TX/RX interrupt mask */  
  822.     iow(db, DM9000_IMR, imr);  
  823.   
  824.     /* Init Driver variable */  
  825.     db->tx_pkt_cnt = 0;  
  826.     db->queue_pkt_len = 0;  
  827.     dev->trans_start = jiffies;  
  828. }  
  829.   
  830. /* Our watchdog timed out. Called by the networking layer */  
  831. static void dm9000_timeout(struct net_device *dev)  
  832. {  
  833.     board_info_t *db = netdev_priv(dev);  
  834.     u8 reg_save;  
  835.     unsigned long flags;  
  836.   
  837.     /* Save previous register address */  
  838.     reg_save = readb(db->io_addr);  
  839.     spin_lock_irqsave(&db->lock, flags);  
  840.   
  841.     netif_stop_queue(dev);  
  842.     dm9000_reset(db);  
  843.     dm9000_init_dm9000(dev);  
  844.     /* We can accept TX packets again */  
  845.     dev->trans_start = jiffies; /* prevent tx timeout */  
  846.     netif_wake_queue(dev);  
  847.   
  848.     /* Restore previous register address */  
  849.     writeb(reg_save, db->io_addr);  
  850.     spin_unlock_irqrestore(&db->lock, flags);  
  851. }  
  852.   
  853. static void dm9000_send_packet(struct net_device *dev,  
  854.                    int ip_summed,  
  855.                    u16 pkt_len)  
  856. {  
  857.     board_info_t *dm = to_dm9000_board(dev);  
  858.   
  859.     /* The DM9000 is not smart enough to leave fragmented packets alone. */  
  860.     if (dm->ip_summed != ip_summed) {  
  861.         if (ip_summed == CHECKSUM_NONE)  
  862.             iow(dm, DM9000_TCCR, 0);  
  863.         else  
  864.             iow(dm, DM9000_TCCR, TCCR_IP | TCCR_UDP | TCCR_TCP);  
  865.         dm->ip_summed = ip_summed;  
  866.     }  
  867.   
  868.     /* Set TX length to DM9000 */  
  869.     /* 设置TX数据的长度到寄存器TXPLL和TXPLH */  
  870.     iow(dm, DM9000_TXPLL, pkt_len);  
  871.     iow(dm, DM9000_TXPLH, pkt_len >> 8);  
  872.   
  873.     /* Issue TX polling command */  
  874.     /* 设置发送控制寄存器的发送请求位 */  
  875.     iow(dm, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */  
  876. }  
  877.   
  878. /* 
  879.  *  Hardware start transmission. 
  880.  *  Send a packet to media from the upper layer. 
  881.  */  
  882. static int  
  883. dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)  
  884. {  
  885.     unsigned long flags;  
  886.     board_info_t *db = netdev_priv(dev);/* 获取网卡虽有信息的存储结构信息的地址 */  
  887.   
  888.     dm9000_dbg(db, 3, "%s:\n", __func__);  
  889.   
  890.     if (db->tx_pkt_cnt > 1)  
  891.         return NETDEV_TX_BUSY;  
  892.   
  893.     spin_lock_irqsave(&db->lock, flags);/* 获得自旋锁 */  
  894.   
  895.     /* Move data to DM9000 TX RAM */  
  896.     /*MWCMD 即 Memory data write command with address increment Register(F8H) 
  897.     * 根据 IO 操作模式(8-bit or 16-bit)来增加写指针 1 或 2 
  898.     */  
  899.     writeb(DM9000_MWCMD, db->io_addr);  
  900.   
  901.     (db->outblk)(db->io_data, skb->data, skb->len);/* 将数据从sk_buff中copy到网卡的TX SRAM中 */  
  902.       
  903.     dev->stats.tx_bytes += skb->len;/* 统计发送的字节数 */  
  904.       
  905.     db->tx_pkt_cnt++;/* 待发送计数 */  
  906.     /* TX control: First packet immediately send, second packet queue */  
  907.     if (db->tx_pkt_cnt == 1) {  
  908.         dm9000_send_packet(dev, skb->ip_summed, skb->len);/* 如果计数为1,直接发送 */  
  909.     } else {/* 如果是第2个,则 */  
  910.         /* Second packet */  
  911.         db->queue_pkt_len = skb->len;  
  912.         db->queue_ip_summed = skb->ip_summed;  
  913.         netif_stop_queue(dev);/* 告诉上层停止发送 */  
  914.     }  
  915.   
  916.     spin_unlock_irqrestore(&db->lock, flags);/* 解锁 */  
  917.   
  918.     /* free this SKB ,释放SKB*/  
  919.     dev_kfree_skb(skb);  
  920.   
  921.     return NETDEV_TX_OK;  
  922. }  
  923.   
  924. /* 
  925.  * DM9000 interrupt handler 
  926.  * receive the packet to upper layer, free the transmitted packet 
  927.  */  
  928.   
  929. static void dm9000_tx_done(struct net_device *dev, board_info_t *db)  
  930. {  
  931.     int tx_status = ior(db, DM9000_NSR);    /* Got TX status */  
  932.   
  933.     if (tx_status & (NSR_TX2END | NSR_TX1END)) {/* 第一个或第二个数据包发送完毕 */  
  934.         /* One packet sent complete */  
  935.         db->tx_pkt_cnt--;/* 待发送的数据包个数减1 */  
  936.         dev->stats.tx_packets++;/* 发送的数据包加1 */  
  937.   
  938.         if (netif_msg_tx_done(db))  
  939.             dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status);  
  940.   
  941.         /* Queue packet check & send */  
  942.         if (db->tx_pkt_cnt > 0)/* 如果还有数据包 */  
  943.             dm9000_send_packet(dev, db->queue_ip_summed,  
  944.                        db->queue_pkt_len);  
  945.         netif_wake_queue(dev);/* 告诉内核,将数据包放入发生那个队列 */  
  946.     }  
  947. }  
  948.   
  949. /* DM9000接收数据后的封装结构体,表示数据包的头4个字节 */  
  950. struct dm9000_rxhdr {  
  951.     u8  RxPktReady;  
  952.     u8  RxStatus;  
  953.     __le16  RxLen;  
  954. } __attribute__((__packed__));  
  955.   
  956. /* 
  957.  *  Received a packet and pass to upper layer 
  958.  *  接收数据包,将数据包传递给上层 
  959.  */  
  960. static void  
  961. dm9000_rx(struct net_device *dev)  
  962. {  
  963.     board_info_t *db = netdev_priv(dev);/* 得到网卡私有信息数据结构的首地址 */  
  964.     struct dm9000_rxhdr rxhdr;/* 该结构体封装了dm9000接收的数据包信息 */  
  965.     struct sk_buff *skb;  
  966.     u8 rxbyte, *rdptr;  
  967.     bool GoodPacket;  
  968.     int RxLen;  
  969.   
  970.     /* Check packet ready or not */  
  971.     do {  
  972.         /* MRCMDX是内存数据预取读命令 */  
  973.         ior(db, DM9000_MRCMDX); /* Dummy read */  
  974.         /* Get most updated data */  
  975.         rxbyte = readb(db->io_data);  
  976.   
  977.         /* Status check: this byte must be 0 or 1 */  
  978.         /* DM9000_PKT_ERR          0x02 ,表示接收出错 */  
  979.         if (rxbyte & DM9000_PKT_ERR) {  
  980.             dev_warn(db->dev, "status check fail: %d\n", rxbyte);/* 输出提示信息 */  
  981.             iow(db, DM9000_RCR, 0x00);  /* Stop Device 关闭设备 */  
  982.             iow(db, DM9000_ISR, IMR_PAR);   /* Stop INT request 停止中断请求*/  
  983.             return;  
  984.         }  
  985.           
  986.         /* DM9000_PKT_RDY          0x01 没有准备好,直接返回*/  
  987.         if (!(rxbyte & DM9000_PKT_RDY))  
  988.             return;  
  989.   
  990.         /* A packet ready now  & Get status/length */  
  991.         GoodPacket = true;  
  992.         writeb(DM9000_MRCMD, db->io_addr);/* MRCMD是地址增加的数据读取命令 */  
  993.   
  994.         (db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));/* 读取数据,从RX_SRAM到 rxhdr结构体中*/  
  995.   
  996.         RxLen = le16_to_cpu(rxhdr.RxLen);  
  997.   
  998.         if (netif_msg_rx_status(db))  
  999.             dev_dbg(db->dev, "RX: status %02x, length %04x\n",  
  1000.                 rxhdr.RxStatus, RxLen);  
  1001.   
  1002.         /* Packet Status check ,检查包的完整性*/  
  1003.         if (RxLen < 0x40) {  
  1004.             GoodPacket = false;  
  1005.             if (netif_msg_rx_err(db))  
  1006.                 dev_dbg(db->dev, "RX: Bad Packet (runt)\n");  
  1007.         }  
  1008.         /* 如果数据长度大于DM9000_PKT_MAX ,即 1536 */  
  1009.         if (RxLen > DM9000_PKT_MAX) {  
  1010.             dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen);  
  1011.         }  
  1012.   
  1013.         /* rxhdr.RxStatus is identical to RSR register. */  
  1014.         /* 这里也是包的检查 */  
  1015.         if (rxhdr.RxStatus & (RSR_FOE | RSR_CE | RSR_AE |  
  1016.                       RSR_PLE | RSR_RWTO |  
  1017.                       RSR_LCS | RSR_RF)) {  
  1018.             GoodPacket = false;  
  1019.             if (rxhdr.RxStatus & RSR_FOE) {  
  1020.                 if (netif_msg_rx_err(db))  
  1021.                     dev_dbg(db->dev, "fifo error\n");  
  1022.                 dev->stats.rx_fifo_errors++;  
  1023.             }  
  1024.             if (rxhdr.RxStatus & RSR_CE) {  
  1025.                 if (netif_msg_rx_err(db))  
  1026.                     dev_dbg(db->dev, "crc error\n");  
  1027.                 dev->stats.rx_crc_errors++;  
  1028.             }  
  1029.             if (rxhdr.RxStatus & RSR_RF) {  
  1030.                 if (netif_msg_rx_err(db))  
  1031.                     dev_dbg(db->dev, "length error\n");  
  1032.                 dev->stats.rx_length_errors++;  
  1033.             }  
  1034.         }  
  1035.   
  1036.         /* Move data from DM9000 ,从DM9000获取数据*/  
  1037.         if (GoodPacket &&  
  1038.             ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {  
  1039.             skb_reserve(skb, 2);  
  1040.             rdptr = (u8 *) skb_put(skb, RxLen - 4);  
  1041.   
  1042.             /* Read received packet from RX SRAM */  
  1043.             /* 将RX SRAM中的数据读取到skbuff结构体 */  
  1044.             (db->inblk)(db->io_data, rdptr, RxLen);  
  1045.             dev->stats.rx_bytes += RxLen;  
  1046.   
  1047.             /* Pass to upper layer */  
  1048.             skb->protocol = eth_type_trans(skb, dev);  
  1049.             if (db->rx_csum) {  
  1050.                 if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0)  
  1051.                     skb->ip_summed = CHECKSUM_UNNECESSARY;  
  1052.                 else  
  1053.                     skb->ip_summed = CHECKSUM_NONE;  
  1054.             }  
  1055.             netif_rx(skb);/* 将skbuff结构体发送给上层 */  
  1056.             dev->stats.rx_packets++;/* 计数增1 */  
  1057.   
  1058.         } else {  
  1059.             /* need to dump the packet's data */  
  1060.             /* 坏包,丢弃 */  
  1061.             (db->dumpblk)(db->io_data, RxLen);  
  1062.         }  
  1063.     } while (rxbyte & DM9000_PKT_RDY);  
  1064. }  
  1065.   
  1066. static irqreturn_t dm9000_interrupt(int irq, void *dev_id)  
  1067. {  
  1068.     struct net_device *dev = dev_id;  
  1069.     board_info_t *db = netdev_priv(dev);  
  1070.     int int_status;  
  1071.     unsigned long flags;  
  1072.     u8 reg_save;  
  1073.   
  1074.     dm9000_dbg(db, 3, "entering %s\n", __func__);  
  1075.   
  1076.     /* A real interrupt coming */  
  1077.   
  1078.     /* holders of db->lock must always block IRQs */  
  1079.     spin_lock_irqsave(&db->lock, flags);  
  1080.   
  1081.     /* Save previous register address */  
  1082.     reg_save = readb(db->io_addr);  
  1083.   
  1084.     /* Disable all interrupts */  
  1085.     iow(db, DM9000_IMR, IMR_PAR);  
  1086.   
  1087.     /* Got DM9000 interrupt status */  
  1088.     int_status = ior(db, DM9000_ISR);   /* Got ISR */  
  1089.     iow(db, DM9000_ISR, int_status);    /* Clear ISR status */  
  1090.   
  1091.     if (netif_msg_intr(db))  
  1092.         dev_dbg(db->dev, "interrupt status %02x\n", int_status);  
  1093.   
  1094.     /* Received the coming packet */  
  1095.     if (int_status & ISR_PRS)  
  1096.         dm9000_rx(dev);  
  1097.   
  1098.     /* Trnasmit Interrupt check */  
  1099.     if (int_status & ISR_PTS)  
  1100.         dm9000_tx_done(dev, db);  
  1101.   
  1102.     if (db->type != TYPE_DM9000E) {  
  1103.         if (int_status & ISR_LNKCHNG) {  
  1104.             /* fire a link-change request */  
  1105.             schedule_delayed_work(&db->phy_poll, 1);  
  1106.         }  
  1107.     }  
  1108.   
  1109.     /* Re-enable interrupt mask */  
  1110.     iow(db, DM9000_IMR, db->imr_all);  
  1111.   
  1112.     /* Restore previous register address */  
  1113.     writeb(reg_save, db->io_addr);  
  1114.   
  1115.     spin_unlock_irqrestore(&db->lock, flags);  
  1116.   
  1117.     return IRQ_HANDLED;  
  1118. }  
  1119.   
  1120. static irqreturn_t dm9000_wol_interrupt(int irq, void *dev_id)  
  1121. {  
  1122.     struct net_device *dev = dev_id;  
  1123.     board_info_t *db = netdev_priv(dev);  
  1124.     unsigned long flags;  
  1125.     unsigned nsr, wcr;  
  1126.   
  1127.     spin_lock_irqsave(&db->lock, flags);  
  1128.   
  1129.     nsr = ior(db, DM9000_NSR);  
  1130.     wcr = ior(db, DM9000_WCR);  
  1131.   
  1132.     dev_dbg(db->dev, "%s: NSR=0x%02x, WCR=0x%02x\n", __func__, nsr, wcr);  
  1133.   
  1134.     if (nsr & NSR_WAKEST) {  
  1135.         /* clear, so we can avoid */  
  1136.         iow(db, DM9000_NSR, NSR_WAKEST);  
  1137.   
  1138.         if (wcr & WCR_LINKST)  
  1139.             dev_info(db->dev, "wake by link status change\n");  
  1140.         if (wcr & WCR_SAMPLEST)  
  1141.             dev_info(db->dev, "wake by sample packet\n");  
  1142.         if (wcr & WCR_MAGICST )  
  1143.             dev_info(db->dev, "wake by magic packet\n");  
  1144.         if (!(wcr & (WCR_LINKST | WCR_SAMPLEST | WCR_MAGICST)))  
  1145.             dev_err(db->dev, "wake signalled with no reason? "  
  1146.                 "NSR=0x%02x, WSR=0x%02x\n", nsr, wcr);  
  1147.   
  1148.     }  
  1149.   
  1150.     spin_unlock_irqrestore(&db->lock, flags);  
  1151.   
  1152.     return (nsr & NSR_WAKEST) ? IRQ_HANDLED : IRQ_NONE;  
  1153. }  
  1154.   
  1155. #ifdef CONFIG_NET_POLL_CONTROLLER  
  1156. /* 
  1157.  *Used by netconsole 
  1158.  */  
  1159. static void dm9000_poll_controller(struct net_device *dev)  
  1160. {  
  1161.     disable_irq(dev->irq);  
  1162.     dm9000_interrupt(dev->irq, dev);  
  1163.     enable_irq(dev->irq);  
  1164. }  
  1165. #endif  
  1166.   
  1167. /* 
  1168.  *  Open the interface. 
  1169.  *  The interface is opened whenever "ifconfig" actives it. 
  1170.  */  
  1171. static int  
  1172. dm9000_open(struct net_device *dev)  
  1173. {  
  1174.     board_info_t *db = netdev_priv(dev);/* 返回board_info_t的地址 */  
  1175.     unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;  
  1176.   
  1177.     if (netif_msg_ifup(db))  
  1178.         dev_dbg(db->dev, "enabling %s\n", dev->name);  
  1179.   
  1180.     /* If there is no IRQ type specified, default to something that 
  1181.      * may work, and tell the user that this is a problem */  
  1182.   
  1183.     if (irqflags == IRQF_TRIGGER_NONE)  
  1184.         dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");  
  1185.   
  1186.     irqflags |= IRQF_SHARED;  
  1187.       
  1188.     /* 注册中断 */  
  1189.     if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))  
  1190.         return -EAGAIN;  
  1191.   
  1192.     /* Initialize DM9000 board */  
  1193.     dm9000_reset(db);/* 复位DM9000 */  
  1194.     dm9000_init_dm9000(dev);/* 根据net_device的数据初始化DM9000 */  
  1195.   
  1196.     /* Init driver variable */  
  1197.     db->dbug_cnt = 0;  
  1198.   
  1199.     mii_check_media(&db->mii, netif_msg_link(db), 1);/* 检测mii接口的状态 */  
  1200.     netif_start_queue(dev);/* 用来告诉上层网络协定这个驱动程序还有空的缓冲区可用,请把下 一个封包送进来。*/  
  1201.       
  1202.     /*在probe函数中初始化的等待队列 INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);    
  1203.     *初始化定时器,调用等待队列*/  
  1204.     dm9000_schedule_poll(db);  
  1205.   
  1206.     return 0;  
  1207. }  
  1208.   
  1209. /* 
  1210.  * Sleep, either by using msleep() or if we are suspending, then 
  1211.  * use mdelay() to sleep. 
  1212.  */  
  1213. static void dm9000_msleep(board_info_t *db, unsigned int ms)  
  1214. {  
  1215.     if (db->in_suspend)  
  1216.         mdelay(ms);  
  1217.     else  
  1218.         msleep(ms);  
  1219. }  
  1220.   
  1221. /* 
  1222.  *   Read a word from phyxcer 
  1223.  */  
  1224. static int  
  1225. dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)  
  1226. {  
  1227.     board_info_t *db = netdev_priv(dev);  
  1228.     unsigned long flags;  
  1229.     unsigned int reg_save;  
  1230.     int ret;  
  1231.   
  1232.     mutex_lock(&db->addr_lock);  
  1233.   
  1234.     spin_lock_irqsave(&db->lock,flags);  
  1235.   
  1236.     /* Save previous register address */  
  1237.     reg_save = readb(db->io_addr);  
  1238.   
  1239.     /* Fill the phyxcer register into REG_0C */  
  1240.     iow(db, DM9000_EPAR, DM9000_PHY | reg);  
  1241.   
  1242.     iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);   /* Issue phyxcer read command */  
  1243.   
  1244.     writeb(reg_save, db->io_addr);  
  1245.     spin_unlock_irqrestore(&db->lock,flags);  
  1246.   
  1247.     dm9000_msleep(db, 1);       /* Wait read complete */  
  1248.   
  1249.     spin_lock_irqsave(&db->lock,flags);  
  1250.     reg_save = readb(db->io_addr);  
  1251.   
  1252.     iow(db, DM9000_EPCR, 0x0);  /* Clear phyxcer read command */  
  1253.   
  1254.     /* The read data keeps on REG_0D & REG_0E */  
  1255.     ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);  
  1256.   
  1257.     /* restore the previous address */  
  1258.     writeb(reg_save, db->io_addr);  
  1259.     spin_unlock_irqrestore(&db->lock,flags);  
  1260.   
  1261.     mutex_unlock(&db->addr_lock);  
  1262.   
  1263.     dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);  
  1264.     return ret;  
  1265. }  
  1266.   
  1267. /* 
  1268.  *   Write a word to phyxcer 
  1269.  */  
  1270. static void  
  1271. dm9000_phy_write(struct net_device *dev,  
  1272.          int phyaddr_unused, int reg, int value)  
  1273. {  
  1274.     board_info_t *db = netdev_priv(dev);  
  1275.     unsigned long flags;  
  1276.     unsigned long reg_save;  
  1277.   
  1278.     dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);  
  1279.     mutex_lock(&db->addr_lock);  
  1280.   
  1281.     spin_lock_irqsave(&db->lock,flags);  
  1282.   
  1283.     /* Save previous register address */  
  1284.     reg_save = readb(db->io_addr);  
  1285.   
  1286.     /* Fill the phyxcer register into REG_0C */  
  1287.     iow(db, DM9000_EPAR, DM9000_PHY | reg);  
  1288.   
  1289.     /* Fill the written data into REG_0D & REG_0E */  
  1290.     iow(db, DM9000_EPDRL, value);  
  1291.     iow(db, DM9000_EPDRH, value >> 8);  
  1292.   
  1293.     iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);   /* Issue phyxcer write command */  
  1294.   
  1295.     writeb(reg_save, db->io_addr);  
  1296.     spin_unlock_irqrestore(&db->lock, flags);  
  1297.   
  1298.     dm9000_msleep(db, 1);       /* Wait write complete */  
  1299.   
  1300.     spin_lock_irqsave(&db->lock,flags);  
  1301.     reg_save = readb(db->io_addr);  
  1302.   
  1303.     iow(db, DM9000_EPCR, 0x0);  /* Clear phyxcer write command */  
  1304.   
  1305.     /* restore the previous address */  
  1306.     writeb(reg_save, db->io_addr);  
  1307.   
  1308.     spin_unlock_irqrestore(&db->lock, flags);  
  1309.     mutex_unlock(&db->addr_lock);  
  1310. }  
  1311.   
  1312. /* 复位 phy,配置寄存器GPR位0为1,关闭dm9000电源,配置寄存器IMR位7为1,disable中断,配置寄存器RCR,disable接收 */  
  1313. static void  
  1314. dm9000_shutdown(struct net_device *dev)  
  1315. {  
  1316.     board_info_t *db = netdev_priv(dev);/* 获取网卡私有信息的地址 */  
  1317.   
  1318.     /* RESET device */  
  1319.     dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET ,复位PHY*/  
  1320.     iow(db, DM9000_GPR, 0x01);  /* Power-Down PHY ,关闭PHY*/  
  1321.     iow(db, DM9000_IMR, IMR_PAR);   /* Disable all interrupt ,关闭所有的中断*/  
  1322.     iow(db, DM9000_RCR, 0x00);  /* Disable RX ,不再接受数据*/  
  1323. }  
  1324.   
  1325. /* 
  1326.  * Stop the interface. 
  1327.  * The interface is stopped when it is brought. 
  1328.  */  
  1329. static int  
  1330. dm9000_stop(struct net_device *ndev)  
  1331. {  
  1332.     board_info_t *db = netdev_priv(ndev);/* 同上,获取网卡的私有结构信息的地址 */  
  1333.   
  1334.     if (netif_msg_ifdown(db))  
  1335.         dev_dbg(db->dev, "shutting down %s\n", ndev->name);  
  1336.   
  1337.     cancel_delayed_work_sync(&db->phy_poll);/* 终止phy_poll队列中被延迟的任务 */  
  1338.   
  1339.     netif_stop_queue(ndev);/* 关闭发送队列 */  
  1340.     netif_carrier_off(ndev);/*通知该内核设备载波丢失,大部分涉及实际的物理连接的网络技术提供有一个载波状态,载波存在说明硬件存在并准备好*/  
  1341.   
  1342.     /* free interrupt */  
  1343.     free_irq(ndev->irq, ndev);/* 释放中断 */  
  1344.   
  1345.     dm9000_shutdown(ndev);/* 关闭DM9000网卡 */  
  1346.   
  1347.     return 0;  
  1348. }  
  1349.   
  1350. static const struct net_device_ops dm9000_netdev_ops = {  
  1351.     .ndo_open       = dm9000_open,/* 打开设备函数 */  
  1352.     .ndo_stop       = dm9000_stop,/* 关闭设备函数 */  
  1353.     .ndo_start_xmit     = dm9000_start_xmit,/* 开始发送数据 */  
  1354.     .ndo_tx_timeout     = dm9000_timeout,/* 发送超时 */  
  1355.     .ndo_set_multicast_list = dm9000_hash_table,/* 设定多播列表 */  
  1356.     .ndo_do_ioctl       = dm9000_ioctl,/* io操作函数 */  
  1357.     .ndo_change_mtu     = eth_change_mtu,/* 改变MTU */  
  1358.     .ndo_validate_addr  = eth_validate_addr,  
  1359.     .ndo_set_mac_address    = eth_mac_addr,  
  1360. #ifdef CONFIG_NET_POLL_CONTROLLER  
  1361.     .ndo_poll_controller    = dm9000_poll_controller,  
  1362. #endif  
  1363. };  
  1364.   
  1365. /* 
  1366.  * Search DM9000 board, allocate space and register it 
  1367.  */  
  1368. static int __devinit  
  1369. dm9000_probe(struct platform_device *pdev)  
  1370. {  
  1371.     struct dm9000_plat_data *pdata = pdev->dev.platform_data;  
  1372.     struct board_info *db;  /* Point a board information structure */  
  1373.     struct net_device *ndev;/* 网络设备 */  
  1374.     const unsigned char *mac_src;  
  1375.     int ret = 0;  
  1376.     int iosize;  
  1377.     int i;  
  1378.     u32 id_val;  
  1379.   
  1380.     unsigned char ne_def_eth_mac_addr[]={0x00,0x12,0x34,0x56,0x80,0x49};/* 设定默认的mac地址 */  
  1381.     static void *bwscon;/* 保存ioremap返回的寄存器的虚拟地址,下同 */  
  1382.     static void *gpfcon;  
  1383.     static void *extint0;  
  1384.     static void *intmsk;  
  1385.     /*Added by yan*/  
  1386.     #define BWSCON           (0x48000000)  
  1387.     #define GPFCON           (0x56000050)  
  1388.     #define EXTINT0           (0x56000088)  
  1389.     #define INTMSK           (0x4A000008)  
  1390.   
  1391.     bwscon=ioremap_nocache(BWSCON,0x0000004);  
  1392.     gpfcon=ioremap_nocache(GPFCON,0x0000004);  
  1393.     extint0=ioremap_nocache(EXTINT0,0x0000004);  
  1394.     intmsk=ioremap_nocache(INTMSK,0x0000004);  
  1395.   
  1396.     writel( readl(bwscon)|0xc0000,bwscon);/* 将BWSCON寄存器[19:18]设置为11 */  
  1397.     writel( (readl(gpfcon) & ~(0x3 << 14)) | (0x2 << 14), gpfcon); /* 设置GPF寄存器 */  
  1398.     writel( readl(gpfcon) | (0x1 << 7), gpfcon); // Disable pull-up,不使能上拉  
  1399.     writel( (readl(extint0) & ~(0xf << 28)) | (0x4 << 28), extint0); //rising edge,设置上升沿触发中断  
  1400.     writel( (readl(intmsk))  & ~0x80, intmsk);/* 设置中断屏蔽寄存器 */  
  1401.           
  1402.     /*End of add*/  
  1403.     /* Init network device */  
  1404.     /* 使用alloc_etherdev()函数分配一个网络设备的结构体,原型在include/linux/etherdevice.h */  
  1405.     ndev = alloc_etherdev(sizeof(struct board_info));  
  1406.     if (!ndev) {  
  1407.         dev_err(&pdev->dev, "could not allocate device.\n");  
  1408.         return -ENOMEM;  
  1409.     }  
  1410.   
  1411. /*通过SET_NETDEV_DEV(netdev, &pdev->dev)宏设置net_device.device->parent为当前的pci_device->device 
  1412. *(这儿net_device包含的是device结构,而不是指针)。这样,就建立起了net_device到device的联系。 
  1413. */  
  1414.     SET_NETDEV_DEV(ndev, &pdev->dev);  
  1415.   
  1416.     dev_dbg(&pdev->dev, "dm9000_probe()\n");  
  1417.   
  1418.     /* setup board info structure */  
  1419.     /* 下面都是设置board_info结构体 */  
  1420.     db = netdev_priv(ndev);/* 返回dev->priv的地址 */  
  1421.   
  1422.     db->dev = &pdev->dev;  
  1423.     db->ndev = ndev;  
  1424.   
  1425.     spin_lock_init(&db->lock);  
  1426.     mutex_init(&db->addr_lock);  
  1427.   
  1428.     INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);  
  1429.   
  1430.     db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  
  1431.     db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);  
  1432.     db->irq_res  = platform_get_resource(pdev, IORESOURCE_IRQ, 0);  
  1433.   
  1434.     if (db->addr_res == NULL || db->data_res == NULL ||  
  1435.         db->irq_res == NULL) {  
  1436.         dev_err(db->dev, "insufficient resources\n");  
  1437.         ret = -ENOENT;  
  1438.         goto out;  
  1439.     }  
  1440.   
  1441.     db->irq_wake = platform_get_irq(pdev, 1);  
  1442.     if (db->irq_wake >= 0) {  
  1443.         dev_dbg(db->dev, "wakeup irq %d\n", db->irq_wake);  
  1444.   
  1445.         ret = request_irq(db->irq_wake, dm9000_wol_interrupt,  
  1446.                   IRQF_SHARED, dev_name(db->dev), ndev);  
  1447.         if (ret) {  
  1448.             dev_err(db->dev, "cannot get wakeup irq (%d)\n", ret);  
  1449.         } else {  
  1450.   
  1451.             /* test to see if irq is really wakeup capable */  
  1452.             ret = set_irq_wake(db->irq_wake, 1);  
  1453.             if (ret) {  
  1454.                 dev_err(db->dev, "irq %d cannot set wakeup (%d)\n",  
  1455.                     db->irq_wake, ret);  
  1456.                 ret = 0;  
  1457.             } else {  
  1458.                 set_irq_wake(db->irq_wake, 0);  
  1459.                 db->wake_supported = 1;  
  1460.             }  
  1461.         }  
  1462.     }  
  1463.   
  1464.     iosize = resource_size(db->addr_res);  
  1465.     db->addr_req = request_mem_region(db->addr_res->start, iosize,  
  1466.                       pdev->name);  
  1467.   
  1468.     if (db->addr_req == NULL) {  
  1469.         dev_err(db->dev, "cannot claim address reg area\n");  
  1470.         ret = -EIO;  
  1471.         goto out;  
  1472.     }  
  1473.   
  1474.     db->io_addr = ioremap(db->addr_res->start, iosize);  
  1475.   
  1476.     if (db->io_addr == NULL) {  
  1477.         dev_err(db->dev, "failed to ioremap address reg\n");  
  1478.         ret = -EINVAL;  
  1479.         goto out;  
  1480.     }  
  1481.   
  1482.     iosize = resource_size(db->data_res);  
  1483.     db->data_req = request_mem_region(db->data_res->start, iosize,  
  1484.                       pdev->name);  
  1485.   
  1486.     if (db->data_req == NULL) {  
  1487.         dev_err(db->dev, "cannot claim data reg area\n");  
  1488.         ret = -EIO;  
  1489.         goto out;  
  1490.     }  
  1491.   
  1492.     db->io_data = ioremap(db->data_res->start, iosize);  
  1493.   
  1494.     if (db->io_data == NULL) {  
  1495.         dev_err(db->dev, "failed to ioremap data reg\n");  
  1496.         ret = -EINVAL;  
  1497.         goto out;  
  1498.     }  
  1499.     /* 设置结构体board_info结束 */  
  1500.       
  1501.     /* fill in parameters for net-dev structure */  
  1502.     ndev->base_addr = (unsigned long)db->io_addr;/* 设置网络设备的地址 */  
  1503.     ndev->irq    = db->irq_res->start;/* 设置网络设备的中断资源地址 */  
  1504.   
  1505.     /* ensure at least we have a default set of IO routines */  
  1506.     dm9000_set_io(db, iosize);  
  1507.   
  1508.     /* check to see if anything is being over-ridden */  
  1509.       
  1510.     /*根据pdev->dev.platform_data的信息判断IO的宽度并设置相应的宽度*/  
  1511.     if (pdata != NULL) {  
  1512.         /* check to see if the driver wants to over-ride the 
  1513.          * default IO width */  
  1514.   
  1515.         if (pdata->flags & DM9000_PLATF_8BITONLY)  
  1516.             dm9000_set_io(db, 1);  
  1517.   
  1518.         if (pdata->flags & DM9000_PLATF_16BITONLY)  
  1519.             dm9000_set_io(db, 2);  
  1520.   
  1521.         if (pdata->flags & DM9000_PLATF_32BITONLY)  
  1522.             dm9000_set_io(db, 4);  
  1523.   
  1524.         /* check to see if there are any IO routine 
  1525.          * over-rides */  
  1526.   
  1527.         if (pdata->inblk != NULL)  
  1528.             db->inblk = pdata->inblk;  
  1529.   
  1530.         if (pdata->outblk != NULL)  
  1531.             db->outblk = pdata->outblk;  
  1532.   
  1533.         if (pdata->dumpblk != NULL)  
  1534.             db->dumpblk = pdata->dumpblk;  
  1535.   
  1536.         db->flags = pdata->flags;  
  1537.     }  
  1538.   
  1539. #ifdef CONFIG_DM9000_FORCE_SIMPLE_PHY_POLL  
  1540.     db->flags |= DM9000_PLATF_SIMPLE_PHY;  
  1541. #endif  
  1542.   
  1543.     dm9000_reset(db);/* 复位 */  
  1544.   
  1545.     /* try multiple times, DM9000 sometimes gets the read wrong */  
  1546.     for (i = 0; i < 8; i++) {  
  1547.         id_val  = ior(db, DM9000_VIDL);  
  1548.         id_val |= (u32)ior(db, DM9000_VIDH) << 8;  
  1549.         id_val |= (u32)ior(db, DM9000_PIDL) << 16;  
  1550.         id_val |= (u32)ior(db, DM9000_PIDH) << 24;  
  1551.   
  1552.         if (id_val == DM9000_ID)  
  1553.             break;  
  1554.         dev_err(db->dev, "read wrong id 0x%08x\n", id_val);  
  1555.     }  
  1556.   
  1557.     if (id_val != DM9000_ID) {  
  1558.         dev_err(db->dev, "wrong id: 0x%08x\n", id_val);  
  1559.         ret = -ENODEV;  
  1560.         goto out;  
  1561.     }  
  1562.   
  1563.     /* Identify what type of DM9000 we are working on */  
  1564.   
  1565.     id_val = ior(db, DM9000_CHIPR);  
  1566.     dev_dbg(db->dev, "dm9000 revision 0x%02x\n", id_val);  
  1567.   
  1568.     switch (id_val) {  
  1569.     case CHIPR_DM9000A:  
  1570.         db->type = TYPE_DM9000A;  
  1571.         break;  
  1572.     case CHIPR_DM9000B:  
  1573.         db->type = TYPE_DM9000B;  
  1574.         break;  
  1575.     default:  
  1576.         dev_dbg(db->dev, "ID %02x => defaulting to DM9000E\n", id_val);  
  1577.         db->type = TYPE_DM9000E;  
  1578.     }  
  1579.   
  1580.     /* dm9000a/b are capable of hardware checksum offload */  
  1581.     if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) {  
  1582.         db->can_csum = 1;  
  1583.         db->rx_csum = 1;  
  1584.         ndev->features |= NETIF_F_IP_CSUM;  
  1585.     }  
  1586.   
  1587.     /* from this point we assume that we have found a DM9000 */  
  1588.   
  1589.     /* driver system function */  
  1590.     ether_setup(ndev);  
  1591.   
  1592.     ndev->netdev_ops = &dm9000_netdev_ops;  
  1593.     ndev->watchdog_timeo = msecs_to_jiffies(watchdog);  
  1594.     ndev->ethtool_ops    = &dm9000_ethtool_ops;  
  1595.   
  1596.     db->msg_enable       = NETIF_MSG_LINK;  
  1597.     db->mii.phy_id_mask  = 0x1f;  
  1598.     db->mii.reg_num_mask = 0x1f;  
  1599.     db->mii.force_media  = 0;  
  1600.     db->mii.full_duplex  = 0;  
  1601.     db->mii.dev       = ndev;  
  1602.     db->mii.mdio_read    = dm9000_phy_read;  
  1603.     db->mii.mdio_write   = dm9000_phy_write;  
  1604.   
  1605.     mac_src = "eeprom";  
  1606.   
  1607.     /* try reading the node address from the attached EEPROM */  
  1608.     for (i = 0; i < 6; i += 2)  
  1609.         dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);  
  1610.   
  1611.     if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {  
  1612.         mac_src = "platform data";  
  1613.         memcpy(ndev->dev_addr, pdata->dev_addr, 6);  
  1614.     }  
  1615.   
  1616.     if (!is_valid_ether_addr(ndev->dev_addr)) {  
  1617.         /* try reading from mac */  
  1618.           
  1619.         mac_src = "chip";  
  1620.         for (i = 0; i < 6; i++)  
  1621.             ndev->dev_addr[i] = ne_def_eth_mac_addr[i];  
  1622.     }  
  1623.   
  1624.     if (!is_valid_ether_addr(ndev->dev_addr))  
  1625.         dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "  
  1626.              "set using ifconfig\n", ndev->name);  
  1627.   
  1628.     /* 设置pdev->dev->driver_data为ndev,保存成平台设备总线上的数据,以后使用只需platform_get_drvdata()即可*/  
  1629.     platform_set_drvdata(pdev, ndev);  
  1630.       
  1631.     /* 注册该网络设备 */  
  1632.     ret = register_netdev(ndev);  
  1633.   
  1634.     if (ret == 0)  
  1635.         printk(KERN_INFO "%s: dm9000%c at %p,%p IRQ %d MAC: %pM (%s)\n",  
  1636.                ndev->name, dm9000_type_to_char(db->type),  
  1637.                db->io_addr, db->io_data, ndev->irq,  
  1638.                ndev->dev_addr, mac_src);  
  1639.     return 0;  
  1640.       
  1641. /* 异常处理 */  
  1642. out:  
  1643.     dev_err(db->dev, "not found (%d).\n", ret);  
  1644.   
  1645.     dm9000_release_board(pdev, db);  
  1646.     free_netdev(ndev);  
  1647.   
  1648.     return ret;  
  1649. }  
  1650.   
  1651. /* 该函数是将设备从内核中移除,释放资源,在移除设备驱动时执行 */  
  1652. static int __devexit  
  1653. dm9000_drv_remove(struct platform_device *pdev)  
  1654. {  
  1655.     struct net_device *ndev = platform_get_drvdata(pdev);/* 从总线获取probe函数保存到总线的设备信息 */  
  1656.   
  1657.     platform_set_drvdata(pdev, NULL);/* 释放pdev资源 */  
  1658.   
  1659.     unregister_netdev(ndev);/* 解除网络设备 */  
  1660.     dm9000_release_board(pdev, (board_info_t *) netdev_priv(ndev));/* 释放该设备申请的IO资源 */  
  1661.     free_netdev(ndev);      /* free device structure */  
  1662.   
  1663.     dev_dbg(&pdev->dev, "released and freed device\n");  
  1664.     return 0;  
  1665. }  
  1666.   
  1667. /*平台设备驱动的结构体定义 
  1668. *在该结构体中可以定义有关Power Management的管理函数 
  1669. *该驱动中将其省略,侧重分析dm9000的基本原理 
  1670. */  
  1671. static struct platform_driver dm9000_driver = {  
  1672.     .driver = {  
  1673.         .name    = "dm9000",/* 该名称和系统初始化中,平台设备的名称一致 */  
  1674.         .owner   = THIS_MODULE,  
  1675.     },  
  1676.     .probe   = dm9000_probe,/* 资源探测函数 */  
  1677.     .remove  = __devexit_p(dm9000_drv_remove),/* 设备移除函数 */  
  1678. };  
  1679.   
  1680. static int __init  
  1681. dm9000_init(void)  
  1682. {  
  1683.     printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION);  
  1684.   
  1685.     return platform_driver_register(&dm9000_driver);  
  1686. }  
  1687.   
  1688. static void __exit  
  1689. dm9000_cleanup(void)  
  1690. {  
  1691.     platform_driver_unregister(&dm9000_driver);  
  1692. }  
  1693.   
  1694. module_init(dm9000_init);  
  1695. module_exit(dm9000_cleanup);  
  1696.   
  1697. MODULE_AUTHOR("Modified by yan");  
  1698. MODULE_DESCRIPTION("Davicom DM9000 network driver");  
  1699. MODULE_LICENSE("GPL");  
  1700. MODULE_ALIAS("platform:dm9000"); 
阅读(1080) | 评论(0) | 转发(0) |
0

上一篇:C++中const用法总结 [转]

下一篇:/bin/sh: can

给主人留下些什么吧!~~