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

📄 dm9000x.c.maceeprom

📁 一个嵌入linux下s3c2410通过i2c读写eerom的驱动程序和应用程序。
💻 MACEEPROM
📖 第 1 页 / 共 4 页
字号:
/*  dm9000.c: Version 1.1 09/11/2001          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.  Author: Sten Wang, 886-3-5798797-8517, E-mail: sten_wang@davicom.com.tw  Date:   10/28,1998  (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) | NFv1.00               modify by simon 2001.9.5                        change for kernel 2.4.x    v1.1   11/09/2001      fix force mode bug             */#if defined(MODVERSIONS)#include <linux/modversions.h>#endif				#include <linux/module.h>//#include <linux/ioport.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/version.h>//#include <asm/dma.h>#include <linux/spinlock.h>//#include <asm/init.h>#include <linux/init.h>   //modify asm/init.h as linux/init.h#include <linux/delay.h>//#include <asm/coldfire.h>  //note//#include <asm/mcfsim.h>	//note #include <linux/types.h>#include <linux/mm.h>	#include <linux/blkdev.h>#include <asm/io.h>//HHTECH EEPROM#include <linux/kernel.h>#include <linux/signal.h>#include <linux/sched.h>#include <linux/timer.h>#include <linux/interrupt.h>#include <asm/irq.h>#include <linux/vmalloc.h>#include "khead.h"#define IICNETBUFSIZE 0x20#define BIT_IIC		(0x1 << 27)#define rGPECON		(*(volatile unsigned long *)net_r_GPECON)#define rGPEUP		(*(volatile unsigned long *)net_r_GPEUP)#define rIICCON		(*(volatile unsigned long *)net_r_IICCON)#define rIICSTAT	(*(volatile unsigned long *)net_r_IICSTAT)#define rIICADD		(*(volatile unsigned long *)net_r_IICADD)#define rIICDS		(*(volatile unsigned long *)net_r_IICDS)#define WRDATA		(1)#define POLLACK		(2)#define RDDATA		(3)#define SETRDADDR	(4)#define Uart_Printf	PDEBUG#define U8		unsigned char#define U32		unsigned intstatic unsigned char net_iicData[IICNETBUFSIZE];static volatile int net_iicDataCount;static volatile int net_iicStatus;static volatile int net_iicMode;static int net_iicPt;void net_init_iic(void);void net_iic_read(U32 slvaddr,U32 addr,U8 *buffer,U32 length);void net_run_iicpoll(void);void net_iicpoll(void);int net_address_map(void);unsigned long net_r_GPECON,net_r_GPEUP;unsigned long net_r_IICCON,net_r_IICSTAT,net_r_IICADD,net_r_IICDS;//*********************[ address_map ]*********************************int net_address_map(void){        net_r_GPECON        =__ioremap(0x56000040,4,0);        net_r_GPEUP         =__ioremap(0x56000048,4,0);        net_r_IICCON        =__ioremap(0x54000000,4,0);        net_r_IICSTAT       =__ioremap(0x54000004,4,0);        net_r_IICADD        =__ioremap(0x54000008,4,0);        net_r_IICDS         =__ioremap(0x5400000c,4,0);                                                                                        return 0;}//*********************[ Delay ]*********************************void net_delay(int times){        udelay(1000);}//************************[ _Rd2410Iic ]********************************void net_iic_read(U32 slvAddr,U32 addr,U8 *buffer,U32 length){     //X1227 Random read && Sequential read     int i = 0;     PDEBUG("read---->0\n");    net_iicMode      = SETRDADDR;    net_iicPt        = 0;    net_iicData[0]   = addr/256;    net_iicData[1]   = addr;    net_iicDataCount = 2;                                                                                    rIICDS   = slvAddr&0xfe;    rIICSTAT = 0xf0;                    //MasTx,Start                                                                                    //Clearing the pending bit isn't needed because the pending bit has been cleared.    while(net_iicDataCount!=-1)        net_run_iicpoll();    net_iicMode      = RDDATA;    net_iicPt        = 1;    net_iicDataCount = length;                                                                                    rIICDS   = slvAddr|0x01;    rIICSTAT = 0xb0;                    //Master Rx,Start    rIICCON  = 0xaf;                    //Resumes IIC operation.    while(net_iicDataCount!=-1)        net_run_iicpoll();                                                                                //    printk("In the Read Function\n");                                                                                    for(i = 0; i<length;i++)    {                buffer[i] = net_iicData[i+2];//              printk("The read num %d is %x\n",i,_iicData[i+2]);    }}//**********************[ Run_IicPoll ]*********************************void net_run_iicpoll(void){    if(rIICCON & 0x10)       net_iicpoll();}//**********************[IicPoll ]**************************************void net_iicpoll(void){    U32 iicSt,i;                                                                                    iicSt = rIICSTAT;    if(iicSt & 0x8){        PDEBUG("bus arbitration is failed\n");                        }   //When bus arbitration is failed.    if(iicSt & 0x4){        PDEBUG("matched\n");        }                   //When a slave address is matched with IICADD    if(iicSt & 0x2){        PDEBUG("slave address 0000000b\n");        }                   //When a slave address is 0000000b    if(iicSt & 0x1){        PDEBUG("Ack isn't received\n");        }                   //When ACK isn't received                                                                                    switch(net_iicMode)    {        case POLLACK:                PDEBUG("poll--ACK\n");            net_iicStatus = iicSt;            break;                                                                                        case RDDATA:              PDEBUG("read--ACK\n");            if((net_iicDataCount--)==0)            {                net_iicData[net_iicPt++] = rIICDS;                                                                                                rIICSTAT = 0x90;                //Stop MasRx condition                rIICCON  = 0xaf;                //Resumes IIC operation.                net_delay(1);                       //Wait until stop condtion is in effect.                                                //Too long time...                                                //The pending bit will not be set after issuing stop condition.                break;            }            net_iicData[net_iicPt++] = rIICDS;                        //The last data has to be read with no ack.            if((net_iicDataCount)==0)                rIICCON = 0x2f;                 //Resumes IIC operation with NOACK.            else                rIICCON = 0xaf;                 //Resumes IIC operation with ACK            break;                                                                                        case WRDATA:                PDEBUG("write--ACK\n");            if((net_iicDataCount--)==0)            {                rIICSTAT = 0xd0;                //stop MasTx condition                rIICCON  = 0xaf;                //resumes IIC operation.                net_delay(1);                       //wait until stop condtion is in effect.                       //The pending bit will not be set after issuing stop condition.                break;            }                PDEBUG("poll--->write\n");            rIICDS = net_iicData[net_iicPt++];            for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL            rIICCON = 0xaf;                     //resumes IIC operation.            break;                                                                                        case SETRDADDR:                PDEBUG("SETRDADDR\n");            if((net_iicDataCount--)==0)            {                break;                  //IIC operation is stopped because of IICCON[4]            }            rIICDS = net_iicData[net_iicPt++];            for(i=0;i<10;i++);          //for setup time until rising edge of IICSCL            rIICCON = 0xaf;             //resumes IIC operation.            break;                                                                                        default:            break;    }}void net_init_iic(void){        net_address_map();                                                                                        rGPEUP  |= 0xc000;                  //Pull-up disable        rGPECON |= 0xa00000;                //GPE15:IICSDA , GPE14:IICSCL                                                                                        //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16        rIICCON  = (1<<7) | (0<<6) | (1<<5) | (0xf);                                                                                        rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)}/////////////////////////////////////////////////////////////////////////////#undef outb#undef outw#undef inb#undef inw/* HHTECH  DMA */#define MBAR_ADDR       0x10000000#define MBAR2_ADDR      0x80000000#define MCF5249_MPARK		0x0C#define MCF5249_DMAROUTE	0x188#define MCF5249_DSAR2		0x380		#define MCF5249_DDAR2		0x384#define MCF5249_DCR2		0x388#define MCF5249_DBCR2		0x38C#define MCF5249_DSR2		0x390		#define MCF5249_DIVR2		0x394		#define MCF5249_DSAR3		0x3C0		#define MCF5249_DDAR3		0x3C4#define MCF5249_DCR3		0x3C8#define MCF5249_DBCR3		0x3CC#define MCF5249_DSR3		0x3D0		#define MCF5249_DIVR3		0x3D4		#define DCR_START		0x00010000#define DSR_DONE		0x01/* Board/System/Debug information/definition ---------------- */#define DM9000_ID	0x90000A46#define DM9000_REG00	0x00#define DM9000_REG05	0x30	/* SKIP_CRC/SKIP_LONG */#define DM9000_REG08	0x27#define DM9000_REG09	0x38#define DM9000_REG0A	0x08#define DM9000_REGFF	0x83	/* IMR */#define DM9000_PHY	0x40	/* PHY address 0x01 */#define DM9000_PKT_MAX	1536	/* Received packet max size */#define DM9000_PKT_RDY	0x01	/* Packet ready to receive */#define DM9000_BASE_ADDR_ETH1	0x08000000  //nGCS1#define DM9000_BASE_ADDR_ETH2   0x40000000#define DM9000_BASE_ADDR_ETH3   0x50000000#define DM9000_MIN_IO_ETH1	DM9000_BASE_ADDR_ETH1+0x300#define DM9000_MIN_IO_ETH2      DM9000_BASE_ADDR_ETH2+0x300#define DM9000_MIN_IO_ETH3      DM9000_BASE_ADDR_ETH3+0x300#define DM9000_MAX_IO	DM9000_BASE_ADDR+0x370#define DM9000_INT_MII	0x00#define DM9000_EXT_MII	0x80#define DM9000_VID_L	0x28#define DM9000_VID_H	0x29#define DM9000_PID_L	0x2A#define DM9000_PID_H	0x2B#define DM9801_NOISE_FLOOR	0x08#define DM9802_NOISE_FLOOR	0x05#define DMFE_SUCC       0#define MAX_PACKET_SIZE 1514#define DMFE_MAX_MULTICAST 14#define DMFE_TIMER_WUT  jiffies+(HZ*2)	/* timer wakeup time : 2 second */#define DMFE_TX_TIMEOUT (HZ*2)	/* tx packet time-out time 1.5 s" */#undef DM9000_DEBUG	//#define DM9000_DEBUG#if defined(DM9000_DEBUG)#define DMFE_DBUG(dbug_now, msg, vaule) if (dmfe_debug ) printk(KERN_ERR "dmfe: %s %x\n", msg, vaule)#else#define DMFE_DBUG(dbug_now, msg, vaule) #endif#if LINUX_VERSION_CODE < 0x20300#define DEVICE device#else#define DEVICE net_device#endifenum DM9000_PHY_mode {	DM9000_10MHD = 0, DM9000_100MHD = 1, DM9000_10MFD = 4,	DM9000_100MFD = 5, DM9000_AUTO = 8, DM9000_1M_HPNA =0x10 };enum DM9000_NIC_TYPE {	FASTETHER_NIC = 0, HOMERUN_NIC = 1, LONGRUN_NIC = 2 };/* Structure/enum declaration ------------------------------- */typedef struct board_info {	struct DEVICE *next_dev;	/* next device */	u32 runt_length_counter;	/* counter: RX length < 64byte */ 	u32 long_length_counter;	/* counter: RX length > 1514byte */ 	u32 reset_counter;		/* counter: RESET */ 	u32 reset_tx_timeout;		/* RESET caused by TX Timeout */ 	u32 reset_rx_status;		/* RESET caused by RX Statsus wrong */ 	u32 ioaddr;			/* Register I/O base address */	u32 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 reg0, reg5, reg8, reg9, rega;	/* registers saved */	u8 op_mode;			/* PHY operation mode */	u8 io_mode;			/* 0:word, 2:byte */	u8 phy_addr;	u8 link_failed;			/* Ever link failed */	u8 device_wait_reset;		/* device state */	u8 nic_type;			/* NIC type */	struct timer_list timer;	/*struct enet_statistics stats;*/ /* statistic counter */         //mark by simon 2001.9.4	struct net_device_stats stats; // add by simon 2001.9.4 for kernel 2.4	unsigned char srom[128];	spinlock_t lock; //add by simon 2001.9.4} board_info_t;/* Global variable declaration ----------------------------- */static int dmfe_debug = 1;static struct DEVICE * dmfe_root_dev = NULL;      /* First device *//* For module input parameter */static int debug = 0;static int mode = DM9000_AUTO;static int media_mode = DM9000_AUTO;static u8 reg5 = DM9000_REG05;static u8 reg8 = DM9000_REG08;static u8 reg9 = DM9000_REG09;static u8 rega = DM9000_REG0A;static u8 nfloor = 0;unsigned long CrcTable[256] = {   0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL,   0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L,   0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L,   0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L,   0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL,   0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L,   0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL,

⌨️ 快捷键说明

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