⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dm9000.c

📁 dm9000aep linux2.6驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *   dm9000.c: Version 1.2 03/18/2003 * *         A Davicom DM9000 ISA NIC fast Ethernet driver for Linux. * 	Copyright (C) 1997  Sten Wang * * 	This program is free software; you can redistribute it and/or * 	modify it under the terms of the GNU General Public License * 	as published by the Free Software Foundation; either version 2 * 	of the License, or (at your option) any later version. * * 	This program is distributed in the hope that it will be useful, * 	but WITHOUT ANY WARRANTY; without even the implied warranty of * 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * 	GNU General Public License for more details. * *   (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved. * * V0.11	06/20/2001	REG_0A bit3=1, default enable BP with DA match * 	06/22/2001 	Support DM9801 progrmming * 	 	 	E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000 * 		 	E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200 * 		     		R17 = (R17 & 0xfff0) | NF + 3 * 		 	E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200 * 		     		R17 = (R17 & 0xfff0) | NF * * v1.00               	modify by simon 2001.9.5 *                         change for kernel 2.4.x * * v1.1   11/09/2001      	fix force mode bug * * v1.2   03/18/2003       Weilun Huang <weilun_huang@davicom.com.tw>: * 			Fixed phy reset. * 			Added tx/rx 32 bit mode. * 			Cleaned up for kernel merge. * *        03/03/2004    Sascha Hauer <s.hauer@pengutronix.de> *                      Port to 2.6 kernel * *	  24-Sep-2004   Ben Dooks <ben@simtec.co.uk> *			Cleanup of code to remove ifdefs *			Allowed platform device data to influence access width *			Reformatting areas of code * *        17-Mar-2005   Sascha Hauer <s.hauer@pengutronix.de> *                      * removed 2.4 style module parameters *                      * removed removed unused stat counter and fixed *                        net_device_stats *                      * introduced tx_timeout function *                      * reworked locking * *	  01-Jul-2005   Ben Dooks <ben@simtec.co.uk> *			* fixed spinlock call without pointer *			* ensure spinlock is initialised */#include <linux/module.h>#include <linux/ioport.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/init.h>#include <linux/skbuff.h>#include <linux/version.h>#include <linux/spinlock.h>#include <linux/crc32.h>#include <linux/mii.h>#include <linux/dm9000.h>#include <linux/delay.h>#include <asm/delay.h>#include <asm/irq.h>#include <asm/io.h>//add by yf 20080623 start#include <asm/arch/regs-serial.h>#include <asm/arch/regs-clock.h>#include <asm/arch/regs-gpio.h>#include <asm/arch/regs-mem.h>#include <asm/arch/regs-dsc.h>#include <asm/arch/regs-irq.h>#include <asm-arm/arch/irqs.h> //end add by yf 20080623#include "dm9000.h"/* Board/System/Debug information/definition ---------------- */#define DM9000_PHY		0x40	/* PHY address 0x01 */#define TRUE			1#define FALSE		0	#define FULL 2#define HALF 1#define CARDNAME "dm9000"#define PFX CARDNAME ": "#define DM9000_TIMER_WUT  jiffies+(HZ*2)	/* timer wakeup time : 2 second */#define DM9000_DEBUG 0#if DM9000_DEBUG > 2#define PRINTK3(args...)  printk(CARDNAME ": " args)#else#define PRINTK3(args...)  do { } while(0)#endif#if DM9000_DEBUG > 1#define PRINTK2(args...)  printk(CARDNAME ": " args)#else#define PRINTK2(args...)  do { } while(0)#endif#if DM9000_DEBUG > 0#define PRINTK1(args...)  printk(CARDNAME ": " args)#define PRINTK(args...)   printk(CARDNAME ": " args)#else#define PRINTK1(args...)  do { } while(0)#define PRINTK(args...)   printk(KERN_DEBUG args)#endif/* * Transmit timeout, default 5 seconds. */static int watchdog = 5000;module_param(watchdog, int, 0400);MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");enum DM9000_PHY_mode {	DM9000_10MHD   = 0, 	DM9000_100MHD  = 1, 	DM9000_10MFD   = 4,	DM9000_100MFD  = 5, 	DM9000_AUTO    = 8, };/* For module input parameter *///static int mode       = DM9000_AUTO;static int media_mode = DM9000_AUTO;/* 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 dbug_cnt;	u8 op_mode;		/* PHY operation mode *///add by yf 20080704	u8 io_mode;		/* 0:word, 2:byte */	//u8 Speed;			/* current speed */	u8 phy_addr;	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 resource	*addr_res;   /* resources found */	struct resource *data_res;	struct resource	*addr_req;   /* resources requested */	struct resource *data_req;	struct resource *irq_res;	struct timer_list timer;	struct net_device_stats stats;	unsigned char srom[128];	spinlock_t lock;	struct mii_if_info mii;	u32 msg_enable;} board_info_t;/* function declaration ------------------------------------- */static int dm9000_probe(struct device *);static int dm9000_open(struct net_device *);static int dm9000_start_xmit(struct sk_buff *, struct net_device *);static int dm9000_stop(struct net_device *);static void dm9000_timer(unsigned long);static void dm9000_init_dm9000(struct net_device *);static struct net_device_stats *dm9000_get_stats(struct net_device *);static irqreturn_t dm9000_interrupt(int, void *, struct pt_regs *);static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg);static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg,			   int value);//static u16 read_srom_word(board_info_t *, int);static void dm9000_rx(struct net_device *);static void dm9000_hash_table(struct net_device *);static void dm9000_cpu_init(void);static void set_PHY_mode(struct net_device *dev);//#define DM9000_PROGRAM_EEPROM#ifdef DM9000_PROGRAM_EEPROMstatic void program_eeprom(board_info_t * db);#endif/* DM9000 network board routine ---------------------------- *///add by yf 20080704 startstatic void set_PHY_mode(struct net_device *dev){       board_info_t *db = (board_info_t *) dev->priv;	u16 phy_reg0 = 0x1200;		/* Auto-negotiation & Restart Auto-negotiation */	u16 phy_reg4 = 0x01E1 | 0x0400 ;		/* Default flow control disable*/	if ( !(db->op_mode & DM9000_AUTO) ) // op_mode didn't auto sense */	{ 		switch(db->op_mode) {			case DM9000_10MHD:  				phy_reg4 = 0x21;                         	phy_reg0 = 0x1000;					   break;			case DM9000_10MFD:  				phy_reg4 = 0x41; 				phy_reg0 = 0x1100;                                	   break;			case DM9000_100MHD: 				phy_reg4 = 0x81; 				phy_reg0 = 0x3000;				    	   break;			case DM9000_100MFD:				phy_reg4 = 0x101; 				phy_reg0 = 0x3100;				   	   break;			default: 					   break;		} // end of switch	} // end of if	dm9000_phy_write(dev, 0, 0, phy_reg0);	dm9000_phy_write(dev, 0, 4, phy_reg4);}//add by yf 20080704 endstatic voiddm9000_reset(board_info_t * db){	PRINTK1("dm9000x: resetting\n");	/* RESET device */	writeb(DM9000_NCR, db->io_addr);	udelay(200);	writeb(NCR_RST, db->io_data);	udelay(200);}static void dm9000_cpu_init(void){      /*bwscon: 16bit , wait:yes,  */      writel( (readl(S3C2410_BWSCON) & (~(0xf<<12) ) ) |(S3C2410_BWSCON_DW3_16)\                                   ,   S3C2410_BWSCON );  				      // |S3C2410_BWSCON_WS3,   S3C2410_BWSCON );     /*dsc1: 8ma */    writel( (readl(S3C2440_DSC1) & (~(0x3<<8) ) ) |(S3C2440_DSC1_CS3_8mA) ,  S3C2440_DSC1 ); 					      s3c2410_gpio_cfgpin(S3C2410_GPG0 , S3C2410_GPG0_EINT8);//       writel( (readl(S3C2410_EXTINT1) & (~(1 << 5) ) )  ,  S3C2410_EXTINT1 );//Rising edge triggered   //  writel( (readl(S3C2410_INTMOD) & (~(1 << 5) ) )  ,  S3C2410_INTMOD );//EINT8--23 :IRQ mode	      writel( (readl(S3C2410_INTMSK) & (~(1 << 8) ) )  ,  S3C2410_INTMSK ); //enable eint8     // udelay(10);   writel( S3C2410_BANKCON_Tacc3,  S3C2410_BANKCON3 );  // bankcon3设定顺序必须在dsc和bswcon之后   //udelay(10);}/* *   Read a byte from I/O port */static u8ior(board_info_t * db, int reg){	writeb(reg, db->io_addr);	return readb(db->io_data);}/* *   Write a byte to I/O port */static voidiow(board_info_t * db, int reg, int value){	writeb(reg, db->io_addr);	writeb(value, db->io_data);}/* routines for sending block to chip */static void dm9000_outblk_8bit(void __iomem *reg, void *data, int count){	writesb(reg, data, count);}static void dm9000_outblk_16bit(void __iomem *reg, void *data, int count){	writesw(reg, data, (count+1) >> 1);}static void dm9000_outblk_32bit(void __iomem *reg, void *data, int count){	writesl(reg, data, (count+3) >> 2);}/* input block from chip to memory */static void dm9000_inblk_8bit(void __iomem *reg, void *data, int count){	readsb(reg, data, count);}static void dm9000_inblk_16bit(void __iomem *reg, void *data, int count){	readsw(reg, data, (count+1) >> 1);}static void dm9000_inblk_32bit(void __iomem *reg, void *data, int count){	readsl(reg, data, (count+3) >> 2);}/* dump block from chip to null */static void dm9000_dumpblk_8bit(void __iomem *reg, int count){	int i;	int tmp;	for (i = 0; i < count; i++)		tmp = readb(reg);}static void dm9000_dumpblk_16bit(void __iomem *reg, int count){	int i;	int tmp;	count = (count + 1) >> 1;	for (i = 0; i < count; i++)		tmp = readw(reg);}static void dm9000_dumpblk_32bit(void __iomem *reg, int count){	int i;	int tmp;	count = (count + 3) >> 2;	for (i = 0; i < count; i++)		tmp = readl(reg);}/* dm9000_set_io * * select the specified set of io routines to use with the * device */static void dm9000_set_io(struct board_info *db, int byte_width){	/* use the size of the data resource to work out what IO	 * routines we want to use	 */	switch (byte_width) {	case 1:		db->dumpblk = dm9000_dumpblk_8bit;		db->outblk  = dm9000_outblk_8bit;		db->inblk   = dm9000_inblk_8bit;		break;	case 2:		db->dumpblk = dm9000_dumpblk_16bit;		db->outblk  = dm9000_outblk_16bit;		db->inblk   = dm9000_inblk_16bit;		break;	case 3:		printk(KERN_ERR PFX ": 3 byte IO, falling back to 16bit\n");		db->dumpblk = dm9000_dumpblk_16bit;		db->outblk  = dm9000_outblk_16bit;		db->inblk   = dm9000_inblk_16bit;		break;	case 4:	default:		db->dumpblk = dm9000_dumpblk_32bit;		db->outblk  = dm9000_outblk_32bit;		db->inblk   = dm9000_inblk_32bit;		break;	}}/* Our watchdog timed out. Called by the networking layer */static void dm9000_timeout(struct net_device *dev){	board_info_t *db = (board_info_t *) dev->priv;	u8 reg_save;	unsigned long flags;	/* Save previous register address */	reg_save = readb(db->io_addr);	spin_lock_irqsave(&db->lock,flags);	netif_stop_queue(dev);	dm9000_reset(db);	dm9000_init_dm9000(dev);	/* We can accept TX packets again */	dev->trans_start = jiffies;	netif_wake_queue(dev);	/* Restore previous register address */	writeb(reg_save, db->io_addr);	spin_unlock_irqrestore(&db->lock,flags);}/* dm9000_release_board * * release a board, and any mapped resources */static voiddm9000_release_board(struct platform_device *pdev, struct board_info *db){	if (db->data_res == NULL) {		if (db->addr_res != NULL)			release_mem_region((unsigned long)db->io_addr, 4);		return;	}	/* unmap our resources */	iounmap(db->io_addr);	iounmap(db->io_data);	/* release the resources */	if (db->data_req != NULL) {		release_resource(db->data_req);		kfree(db->data_req);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -