历史上的今天
返回首页

历史上的今天

今天是:2024年11月09日(星期六)

正在发生

2021年11月09日 | Mini2440 DM9000 驱动分析(一)

2021-11-09 来源:eefocus

硬件特性


Mini2440开发板上DM9000的电气连接和Mach-mini2440.c文件的关系:

PW_RST 连接到复位按键,复位按键按下,低电平触发重新初始化,初始化完成后5us后可以使用(The DM9000 is ready after 5us when this pin deasserted )

CMD 连接到s3c2440 的ADD2 pin


INT 连接到s3c2440 的EINT7/GPF7,将中断控制端口


LINK_ACT 连接到网络接口的GLEDK pin,连接到LINK LED,这样网卡上面的灯才可以亮

LINK_O、WAKEUP、SPEED100# 这三个pin并联之后连接的网络接口的YLEDK pin

AEN 连接到s3c2440 的nGCS4/GPA15 pin


IOR# 连接到s3c2440 的nOE pin

IOW# 连接到s3c2440 的 nWE pin

IOWAIT 直接通过电阻借电源,即高电平

TXO-、TXO+、RX-、RX+ 直接接到网络端口用于数据收发

SD0-15 连接到s3c2440 的DATA0-15


其中片选信号AEN使用了nGCS4,所以网卡的内存区域在BANK4,也就是从地址0x20000000开始。


DM9000的TXD[2:0]作为strap pin在电路图中是空接的,所以IO base是300H。


中断使用了EINT7。

代码如下:


/* DM9000AEP 10/100 ethernet controller */

#define MACH_MINI2440_DM9K_BASE (S3C2410_CS4 + 0x300)

 

static struct resource mini2440_dm9k_resource[] = {

        [0] = {

                .start = MACH_MINI2440_DM9K_BASE,

                .end   = MACH_MINI2440_DM9K_BASE + 3,

                .flags = IORESOURCE_MEM

        },

        [1] = {

                .start = MACH_MINI2440_DM9K_BASE + 4,

                .end   = MACH_MINI2440_DM9K_BASE + 7,

                .flags = IORESOURCE_MEM

        },

        [2] = {

                .start = IRQ_EINT7,

                .end   = IRQ_EINT7,

                .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE,

        }

};

 

/*

 *  * The DM9000 has no eeprom, and it's MAC address is set by

 *   * the bootloader before starting the kernel.

 *    */

static struct dm9000_plat_data mini2440_dm9k_pdata = {

        .flags          = (DM9000_PLATF_16BITONLY | DM9000_PLATF_NO_EEPROM),

};

 

static struct platform_device mini2440_device_eth = {

        .name           = "dm9000",

        .id             = -1,

        .num_resources  = ARRAY_SIZE(mini2440_dm9k_resource),

        .resource       = mini2440_dm9k_resource,

        .dev            = {

                .platform_data  = &mini2440_dm9k_pdata,

        },

};

研究net driver首先就要先了解一下网络驱动编写的一个基本架构


两个重要的结构体简单介绍:sk_buff和net_device


sk_buff

如果把网络传输看成是运送货物的话,那么sk_buff就是这个“货物”了,所有经手这个货物的人都要干点什么事儿,要么加个包装,要么印个戳儿等等。收货的时候就要拆掉这些包装,得到我们需要的货物(payload data)。没有货物你还运输什么呢?由此可见sk_buff的重要性了。


关于sk_buff的详细介绍和几个操作它的函数,参考:“linux内核sk_buff的结构分析” http://www.linuxidc.com/Linux/2011-07/39163.htm,写得非常明白了。赞一个~


net_device


又是一个庞大的结构体。好吧,我承认我从来就没有看全过这个结构体。它在内核中就是指代了一个网络设备。驱动程序需要在探测的时候分配并初始化这个结构体,然后使用register_netdev来注册它,这样就可以把操作硬件的函数与内核挂接在一起。

对于我们来说probe是一切一切的开始,看看dm9000驱动probe需要用要的结构体


board_info

/* Structure/enum declaration ------------------------------- */

typedef struct board_info {

 

void __iomem *io_addr; /* Register I/O base address */

void __iomem *io_data; /* Data I/O address */

u16 irq; /* IRQ */

 

u16 tx_pkt_cnt;

u16 queue_pkt_len;

u16 queue_start_addr;

u16 queue_ip_summed;

u16 dbug_cnt;

u8 io_mode; /* 0:word, 2:byte */

u8 phy_addr;

u8 imr_all;

 

unsigned int flags;

unsigned int in_suspend :1;

int debug_level;

 

enum dm9000_type type;

 

void (*inblk)(void __iomem *port, void *data, int length);

void (*outblk)(void __iomem *port, void *data, int length);

void (*dumpblk)(void __iomem *port, int length);

 

struct device *dev;      /* parent device */

 

struct resource *addr_res;   /* resources found */

struct resource *data_res;

struct resource *addr_req;   /* resources requested */

struct resource *data_req;

struct resource *irq_res;

 

struct mutex addr_lock; /* phy and eeprom access lock */

 

struct delayed_work phy_poll;

struct net_device  *ndev;

 

spinlock_t lock;

 

struct mii_if_info mii;

u32 msg_enable;

 

int rx_csum;

int can_csum;

int ip_summed;

} board_info_t;

其中有两个很重要的结构体 net_device 和 mii_if_info


mii_if_info

struct mii_if_info {

int phy_id;

int advertising;

int phy_id_mask;

int reg_num_mask;

 

unsigned int full_duplex : 1; /* is full duplex? */

unsigned int force_media : 1; /* is autoneg. disabled? */

unsigned int supports_gmii : 1; /* are GMII registers supported? */

 

struct net_device *dev;

int (*mdio_read) (struct net_device *dev, int phy_id, int location);

void (*mdio_write) (struct net_device *dev, int phy_id, int location, int val);

};

net_device 

/*

 * The DEVICE structure.

 * Actually, this whole structure is a big mistake.  It mixes I/O

 * data with strictly "high-level" data, and it has to know about

 * almost every data structure used in the INET module.

 *

 * FIXME: cleanup struct net_device such that network protocol info

 * moves out.

 */

 

struct net_device

{

 

/*

* This is the first field of the "visible" part of this structure

* (i.e. as seen by users in the "Space.c" file).  It is the name

* the interface.

*/

char name[IFNAMSIZ];

/* device name hash chain */

struct hlist_node name_hlist;

/* snmp alias */

char *ifalias;

 

/*

* I/O specific fields

* FIXME: Merge these and struct ifmap into one

*/

unsigned long mem_end; /* shared mem end */

unsigned long mem_start; /* shared mem start */

unsigned long base_addr; /* device I/O address */

unsigned int irq; /* device IRQ number */

 

/*

* Some hardware also needs these fields, but they are not

* part of the usual set specified in Space.c.

*/

 

unsigned char if_port; /* Selectable AUI, TP,..*/

unsigned char dma; /* DMA channel */

 

unsigned long state;

 

struct list_head dev_list;

struct list_head napi_list;

 

/* Net device features */

unsigned long features;

#define NETIF_F_SG 1 /* Scatter/gather IO. */

#define NETIF_F_IP_CSUM 2 /* Can checksum TCP/UDP over IPv4. */

#define NETIF_F_NO_CSUM 4 /* Does not require checksum. F.e. loopack. */

#define NETIF_F_HW_CSUM 8 /* Can checksum all the packets. */

#define NETIF_F_IPV6_CSUM 16 /* Can checksum TCP/UDP over IPV6 */

#define NETIF_F_HIGHDMA 32 /* Can DMA to high memory. */

#define NETIF_F_FRAGLIST 64 /* Scatter/gather IO. */

#define NETIF_F_HW_VLAN_TX 128 /* Transmit VLAN hw acceleration */

#define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */

#define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */

#define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */

#define NETIF_F_GSO 2048 /* Enable software GSO. */

#define NETIF_F_LLTX 4096 /* LockLess TX - deprecated. Please */

/* do not use LLTX in new drivers */

#define NETIF_F_NETNS_LOCAL 8192 /* Does not change network namespaces */

#define NETIF_F_GRO 16384 /* Generic receive offload */

#define NETIF_F_LRO 32768 /* large receive offload */

 

/* the GSO_MASK reserves bits 16 through 23 */

#define NETIF_F_FCOE_CRC (1 << 24) /* FCoE CRC32 */

#define NETIF_F_SCTP_CSUM (1 << 25) /* SCTP checksum offload */

#define NETIF_F_FCOE_MTU (1 << 26) /* Supports max FCoE MTU, 2158 bytes*/

 

/* Segmentation offload features */

#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)

 

/* List of features with software fallbacks. */

#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)

 

/*

* If one device supports one of these features, then enable them

* for all in netdev_increment_features.

*/

#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST |

NETIF_F_SG | NETIF_F_HIGHDMA |

NETIF_F_FRAGLIST)

 

/* Interface index. Unique device identifier */

int ifindex;

int iflink;

 

struct net_device_stats stats;

 

#ifdef CONFIG_WIRELESS_EXT

/* List of functions to handle Wireless Extensions (instead of ioctl).

* See for details. Jean II */

const struct iw_handler_def * wireless_handlers;

/* Instance data managed by the core of Wireless Extensions. */

struct iw_public_data * wireless_data;

#endif

/* Management operations */

const struct net_device_ops *netdev_ops;

const struct ethtool_ops *ethtool_ops;

 

/* Hardware header description */

const struct header_ops *header_ops;

 

unsigned int flags; /* interface flags (a la BSD) */

unsigned short gflags;

        unsigned short          priv_flags; /* Like 'flags' but invisible to userspace. */

unsigned short padded; /* How much padding added by alloc_netdev() */

 

unsigned char operstate; /* RFC2863 operstate */

unsigned char link_mode; /* mapping policy to operstate */

 

unsigned mtu; /* interface MTU value */

unsigned short type; /* interface hardware type */

unsigned short hard_header_len; /* hardware hdr length */

 

/* extra head- and tailroom the hardware may need, but not in all cases

* can this be guaranteed, especially tailroom. Some cases also use

推荐阅读

史海拾趣

Fuji Electric Co Ltd公司的发展小趣事

以下是五个关于Fuji Electric Co., Ltd.(富士电机)公司发展起来的相关故事,每个故事均基于事实描述,并尽量保持字数在500字以上:

1. 创立与早期发展

Fuji Electric Co., Ltd.(富士电机)成立于1923年,是古河电器工业与德国西门子资本技术合作的产物。公司最初以电气机器制造为主,迅速在日本市场站稳脚跟。在成立初期,富士电机便致力于技术创新和产品质量的提升,逐渐在电机制造领域建立了良好的声誉。通过不断的技术积累和市场拓展,富士电机逐渐成长为日本电机行业的领军企业之一。

2. 多元化战略的实施

随着市场的不断变化和技术的不断进步,富士电机开始实施多元化战略。公司不仅继续深耕电机制造领域,还积极拓展至电子设备、零售终端设备等多个领域。通过并购和内部孵化等方式,富士电机成功进入了多个新兴市场,并在这些领域取得了显著成就。例如,在自动贩卖机领域,富士电机凭借其先进的技术和卓越的产品质量,占据了日本国内第一的市场份额。

3. 国际市场的开拓

富士电机深知国际市场的重要性,因此一直致力于海外市场的拓展。公司通过在海外设立分支机构、与当地企业合作等方式,成功将产品和服务推向了全球市场。在国际市场上,富士电机凭借其高品质的产品和专业的服务赢得了广泛的认可和好评。同时,公司还积极参与国际标准的制定和推广工作,提升了自身的国际影响力。

4. 技术创新与研发实力的提升

技术创新是富士电机持续发展的重要动力。公司不断加大研发投入力度,建立了完善的技术创新体系。通过自主研发和合作研发等方式,富士电机在多个技术领域取得了重大突破。例如,在电力电子、自动化控制等领域,富士电机推出了多款具有自主知识产权的创新产品和技术解决方案。这些创新成果不仅提升了公司的核心竞争力还推动了整个行业的发展。

5. 数字化转型与智能化升级

面对数字化转型的浪潮富士电机积极应对挑战并抓住机遇。公司开始推进数字化转型和智能化升级工作通过引入先进的数字化技术和智能化设备提升生产效率和产品质量。同时富士电机还加强了对大数据、云计算等前沿技术的研发和应用推动了公司业务的智能化发展。这些举措不仅提升了公司的市场竞争力还为公司未来的可持续发展奠定了坚实基础。

Electronicon Kondensatoren GmbH公司的发展小趣事

随着全球市场的不断变化和发展,ELECTRONICON积极实施国际化战略,拓展海外市场。公司在全球范围内建立了完善的销售和服务网络,为客户提供及时、高效的服务。未来,ELECTRONICON将继续秉承“质量为本、客户至上”的经营理念,不断创新和发展,为电子行业的繁荣做出更大的贡献。

Davico Industrial Ltd公司的发展小趣事

随着全球市场的不断变化和发展,ELECTRONICON积极实施国际化战略,拓展海外市场。公司在全球范围内建立了完善的销售和服务网络,为客户提供及时、高效的服务。未来,ELECTRONICON将继续秉承“质量为本、客户至上”的经营理念,不断创新和发展,为电子行业的繁荣做出更大的贡献。

EnerSys公司的发展小趣事

进入21世纪后,EnerSys加快了其收购与整合的步伐。2000年底,EnerSys收购了Yuasa Corporation(Japan)在北美和南美的储能和动力电池业务。随后,公司又陆续收购了Energy Storage Group of Invensys plc.和FIAMM, S.p.A.的动力电池业务。这些收购不仅扩大了EnerSys的市场份额,还增强了其在专业镍基电池、锂电池、铅酸电池和工业电池领域的技术实力。

ARCOTRONICS公司的发展小趣事

随着技术实力的不断提升,ARCOTRONICS公司开始将目光投向国际市场。公司制定了一系列国际化战略,积极参与国际电子展会,与全球各地的合作伙伴建立紧密的合作关系。通过不断拓展市场,ARCOTRONICS公司的产品逐渐在国际上获得了广泛的认可,公司也因此成为了全球电子行业的重要参与者。

Hitron公司的发展小趣事

在电子行业的早期,ARCOTRONICS公司凭借其卓越的研发团队,成功开发出一种新型的高效能电子元件。这一技术突破不仅大幅提升了电子设备的性能,还降低了生产成本,使公司在市场上迅速获得了竞争优势。这一技术突破为ARCOTRONICS公司奠定了坚实的基石,为其后续发展打下了坚实的基础。

问答坊 | AI 解惑

基于FPGA的PCI总线接口设计

摘 要 :PCI是一种高性能的局部总线规范,可实现各种功能标准的PCI总线卡。本文简要介绍了PCI总线的特点、信号与命令,提出了一种利用高速FPGA实现PCI总线接口的设计方案。 关键词 :PCI总线;信号;命令;协议 在现代数据采集及处理系统中,ISA ...…

查看全部问答>

插补算法

插补算法!!!!!!!!!!!!!!!!…

查看全部问答>

数字信号处理的FPGA实现(好书共享)

数字信号处理的FPGA实现(好书共享)…

查看全部问答>

关于步进电机的疑问

我想在坐标(X1,Y1),(X2,Y2)之间走一条直线,但我不知道怎么编写程序的,还有它与电机的步数有什么样的关系呢?知道的告诉我,谢谢。…

查看全部问答>

DZK后缀的文件用什么软件开

DZK,HZK后缀的文件用什么软件开。…

查看全部问答>

理解下一代数据采集技术

  来源:NI : 理解下一代数据采集技术——USB和Wi-Fi数据采集的优势美国国家仪器有限公司 Graham Green过去20年中,数据采集从一种应用有限的技术已经发展为可适用于各种高性能测量应用的平台。通过软件为核心的图形化编程和基于PC的模 ...…

查看全部问答>

arm9 自己编译的2.6.12内核 屏幕整体左移

我买了一块 LJD-2440 带一块CT35T触摸屏 自己用厂家提供的Linux2.6.12包编译内核成功 跟光盘上带的官方编译的内核大小差了几百字节 将zImage 烧到NAND FLASH后启动系统 发现一切似乎正常  屏幕整体向左上偏移 分别用3.4.1和3.3. ...…

查看全部问答>

关于没有通电的FPGA自动工作的奇怪现象

这几天在工作中遇到一个很奇怪的现象。我有一块FPGA的板子(I/O使用+3.3V,内核使用+1.2V),但是使用时我没有对它进行供电,而是将这块板子的信号地和另一块板子连接起来,从另一块板子上引出一个+3.3V接到FPGA的随意一个I/O管脚,此时FPGA及其外 ...…

查看全部问答>

求一张PCB图,原理图已给出,急!急!急!

毕业论文要求一张PCB图,原理图已有,全自动应急灯的、、、急!急!急! 求帮忙...........联系QQ:339739667、:carnation:…

查看全部问答>

launchpad 按键控制LED

void main( void ){   // Stop watchdog timer to prevent time out reset  WDTCTL = WDTPW + WDTHOLD;    P1DIR |= BIT0 | BIT6;  //俩灯配置为输出    P1DIR &= ~BIT3;     ...…

查看全部问答>