📄 dm9000x.c.maceeprom
字号:
/* 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 + -