您的位置 首页 FPGA

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

硬件平台:FL2440(s3c2440)内核版本:2.6.35主机平台:Ubuntu11.04内核版本:2.6.39原创作品,转载请标明出处http://blog.csdn.net/yming…

硬件渠道:FL2440(s3c2440

内核版别:2.6.35
主机渠道:Ubuntu11.04
内核版别:2.6.39
原创著作,转载请标明出处http://blog.csdn.net/yming0221/article/details/6609742
1、下图是DM9000的引脚图
2、这儿咱们结合详细的开发板FL2440
下面是FL2440和DM9000的引脚链接图
自己移植DM9000的时分将设备的资源界说放在了arch/arm/plat-s3c24xx/devs.c中,概况点击上一篇博文linux内核移植-移植2.6.35.4内核到s3c2440
下面是设备的资源界说
view plainprint?
static struct resource s3c_dm9000_resource[] = {
[0] = {
.start = S3C24XX_PA_DM9000,
.end = S3C24XX_PA_DM9000+ 0x3,
.flags = IORESOURCE_MEM
},
[1]={
.start = S3C24XX_PA_DM9000 + 0x4, //CMD pin is A2 0x20000304
.end = S3C24XX_PA_DM9000 + 0x4 + 0x7c, // 0x20000380
.flags = IORESOURCE_MEM
},
[2] = {
.start = IRQ_EINT7,
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ
},
};
这儿能够看到,DM9000网卡运用的地址空间资源在nGCS4地址区域,所以上图的DM9000地址使能引脚衔接nGCS4引脚。中止运用的是EINT7外部中止。
接着界说渠道数据和渠道设备,代码如下:
view plainprint?
static struct dm9000_plat_data s3c_device_dm9000_platdata = {
.flags= DM9000_PLATF_16BITONLY,
};
struct platform_device s3c_device_dm9000 = {
.name= “dm9000”, //设备名,该称号与渠道设备驱动中的称号共同
.id= 0,
.num_resources= ARRAY_SIZE(s3c_dm9000_resource),
.resource= s3c_dm9000_resource, //界说设备的资源
.dev= {
.platform_data = &s3c_device_dm9000_platdata, //界说渠道数据
}
};
最终导出函数符号,保存函数地址和称号
view plainprint?
EXPORT_SYMBOL(s3c_device_dm9000);
3、设备发动的初始化进程
view plainprint?
MACHINE_START(S3C2440, “SMDK2440”)
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.init_irq = s3c24xx_init_irq,
.map_io = smdk2440_map_io,
.init_machine = smdk2440_machine_init,//界说设备的初始化函数
.timer = &s3c24xx_timer,
MACHINE_END
而后会碑文下面函数
view plainprint?
static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_i2c0_set_platdata(NULL);
s3c24xx_ts_set_platdata(&smdk2410_ts_cfg);
platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}
下面是详细的设备列表
view plainprint?
static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_rtc,
&s3c24xx_uda134x,
&s3c_device_dm9000,
&s3c_device_adc,
&s3c_device_ts,
};
这样体系发动时,会给设备列表中的设备分配资源(地址资源和中止资源等)。
4、信息传输中的信息封装结构
4.1、sk_buff结构,界说在include/linux/skbuff.h中
view plainprint?
struct sk_buff {
struct sk_buff *next;
struct sk_buff *prev;
ktime_t tstamp;
struct sock *sk;
struct net_device *dev;
char cb[48] __aligned(8);
unsigned long _skb_refdst;
#ifdef CONFIG_XFRM
struct sec_path *sp;
#endif
unsigned int len,
data_len;
__u16 mac_len,
hdr_len;
union {
__wsum csum;
struct {
__u16 csum_start;
__u16 csum_offset;
};
};
__u32 priority;
kmemcheck_bitfield_begin(flags1);
__u8 local_df:1,
cloned:1,
ip_summed:2,
nohdr:1,
nfctinfo:3;
__u8 pkt_type:3,
fclone:2,
ipvs_property:1,
peeked:1,
nf_trace:1;
kmemcheck_bitfield_end(flags1);
__be16 protocol;
void (*destructor)(struct sk_buff *skb);
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct nf_conntrack *nfct;
struct sk_buff *nfct_reasm;
#endif
#ifdef CONFIG_BRIDGE_NETFILTER
struct nf_bridge_info *nf_bridge;
#endif
int skb_iif;
#ifdef CONFIG_NET_SCHED
__u16 tc_index;
#ifdef CONFIG_NET_CLS_ACT
__u16 tc_verd;
#endif
#endif
__u32 rxhash;
kmemcheck_bitfield_begin(flags2);
__u16 queue_mapping:16;
#ifdef CONFIG_IPV6_NDISC_NODETYPE
__u8 ndisc_nodetype:2,
deliver_no_wcard:1;
#else
__u8 deliver_no_wcard:1;
#endif
kmemcheck_bitfield_end(flags2);
#ifdef CONFIG_NET_DMA
dma_cookie_t dma_cookie;
#endif
#ifdef CONFIG_NETWORK_SECMARK
__u32 secmark;
#endif
union {
__u32 mark;
__u32 dropcount;
};
__u16 vlan_tci;
sk_buff_data_t transport_header;
sk_buff_data_t network_header;
sk_buff_data_t mac_header;
sk_buff_data_t tail;
sk_buff_data_t end;
unsigned char *head,
*data;
unsigned int truesize;
atomic_t users;
};
元素的意义如下(摘自内核,源码,版别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, dont 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中
如下:
view plainprint?
struct net_device {
char name[IFNAMSIZ];
struct pm_qos_request_list *pm_qos_req;
struct hlist_node name_hlist;
char *ifalias;
unsigned long mem_end;
unsigned long mem_start;
unsigned long base_addr;
unsigned int irq;
unsigned char if_port;
unsigned char dma;
unsigned long state;
struct list_head dev_list;
struct list_head napi_list;
struct list_head unreg_list;
unsigned long features;
#define NETIF_F_SG 1
#define NETIF_F_IP_CSUM 2
#define NETIF_F_NO_CSUM 4
#define NETIF_F_HW_CSUM 8
#define NETIF_F_IPV6_CSUM 16
#define NETIF_F_HIGHDMA 32
#define NETIF_F_FRAGLIST 64
#define NETIF_F_HW_VLAN_TX 128
#define NETIF_F_HW_VLAN_RX 256
#define NETIF_F_HW_VLAN_FILTER 512
#define NETIF_F_VLAN_CHALLENGED 1024
#define NETIF_F_GSO 2048
#define NETIF_F_LLTX 4096
#define NETIF_F_NETNS_LOCAL 8192
#define NETIF_F_GRO 16384
#define NETIF_F_LRO 32768
#define NETIF_F_FCOE_CRC (1 << 24)
#define NETIF_F_SCTP_CSUM (1 << 25)
#define NETIF_F_FCOE_MTU (1 << 26)
#define NETIF_F_NTUPLE (1 << 27)
#define NETIF_F_RXHASH (1 << 28)
#define NETIF_F_GSO_SHIFT 16
#define NETIF_F_GSO_MASK 0x00ff0000
#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
#define NETIF_F_UFO (SKB_GSO_UDP << NETIF_F_GSO_SHIFT)
#define NETIF_F_GSO_ROBUST (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
#define NETIF_F_TSO_ECN (SKB_GSO_TCP_ECN << NETIF_F_GSO_SHIFT)
#define NETIF_F_TSO6 (SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT)
#define NETIF_F_FSO (SKB_GSO_FCOE << NETIF_F_GSO_SHIFT)
#define NETIF_F_GSO_SOFTWARE (NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6)
#define NETIF_F_GEN_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
#define NETIF_F_V4_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)
#define NETIF_F_V6_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
#define NETIF_F_ALL_CSUM (NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)
#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \
NETIF_F_SG | NETIF_F_HIGHDMA | \
NETIF_F_FRAGLIST)
int ifindex;
int iflink;
struct net_device_stats stats;
#ifdef CONFIG_WIRELESS_EXT
const struct iw_handler_def * wireless_handlers;
struct iw_public_data * wireless_data;
#endif
const struct net_device_ops *netdev_ops;
const struct ethtool_ops *ethtool_ops;
const struct header_ops *header_ops;
unsigned int flags;
unsigned short gflags;
unsigned short priv_flags;
unsigned short padded;
unsigned char operstate;
unsigned char link_mode;
unsigned int mtu;
unsigned short type;
unsigned short hard_header_len;
unsigned short needed_headroom;
unsigned short needed_tailroom;
struct net_device *master;
unsigned char perm_addr[MAX_ADDR_LEN];
unsigned char addr_len;
unsigned short dev_id;
spinlock_t addr_list_lock;
struct netdev_hw_addr_list uc;
struct netdev_hw_addr_list mc;
int uc_promisc;
unsigned int promiscuity;
unsigned int allmulti;
#ifdef CONFIG_NET_DSA
void *dsa_ptr;
#endif
void *atalk_ptr;
void *ip_ptr;
void *dn_ptr;
void *ip6_ptr;
void *ec_ptr;
void *ax25_ptr;
struct wireless_dev *ieee80211_ptr;
unsigned long last_rx;
unsigned char *dev_addr;
struct netdev_hw_addr_list dev_addrs;
unsigned char broadcast[MAX_ADDR_LEN];
#ifdef CONFIG_RPS
struct kset *queues_kset;
struct netdev_rx_queue *_rx;
unsigned int num_rx_queues;
#endif
struct netdev_queue rx_queue;
struct netdev_queue *_tx ____cacheline_aligned_in_smp;
unsigned int num_tx_queues;
unsigned int real_num_tx_queues;
struct Qdisc *qdisc;
unsigned long tx_queue_len;
spinlock_t tx_global_lock;
unsigned long trans_start;
int watchdog_timeo;
struct timer_list watchdog_timer;
atomic_t refcnt ____cacheline_aligned_in_smp;
struct list_head todo_list;
struct hlist_node index_hlist;
struct list_head link_watch_list;
enum { NETREG_UNINITIALIZED=0,
NETREG_REGISTERED,
NETREG_UNREGISTERING,
NETREG_UNREGISTERED,
NETREG_RELEASED,
NETREG_DUMMY,
} reg_state:16;
enum {
RTNL_LINK_INITIALIZED,
RTNL_LINK_INITIALIZING,
} rtnl_link_state:16;
void (*destructor)(struct net_device *dev);
#ifdef CONFIG_NETPOLL
struct netpoll_info *npinfo;
#endif
#ifdef CONFIG_NET_NS
struct net *nd_net;
#endif
void *ml_priv;
struct net_bridge_port *br_port;
struct macvlan_port *macvlan_port;
struct garp_port *garp_port;
struct device dev;
const struct attribute_group *sysfs_groups[4];
const struct rtnl_link_ops *rtnl_link_ops;
unsigned long vlan_features;
#define GSO_MAX_SIZE 65536
unsigned int gso_max_size;
#ifdef CONFIG_DCB
const struct dcbnl_rtnl_ops *dcbnl_ops;
#endif
#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
unsigned int fcoe_ddp_xid;
#endif
struct ethtool_rx_ntuple_list ethtool_ntuple_list;
};
我还没有细细的剖析这个结构体,驱动程序在probe函数中运用register_netdev()注册该结构体指明的设备,将内核操作硬件的函数个内核联系起来。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/fpga/264506.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部