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

📄 davicom.c

📁 i386的bootloader源码grub
💻 C
📖 第 1 页 / 共 2 页
字号:
/*      DAVICOM DM9009/DM9102/DM9102A Etherboot Driver	V1.00    This driver was ported from Marty Conner's Tulip Etherboot driver.     Thanks Marty Connor (mdc@thinguin.org)     You can get Tulip driver source file from this URL:    "http://etherboot.sourceforge..net/#Distribution"        This davicom etherboot driver supports DM9009/DM9102/DM9102A/    DM9102A+DM9801/DM9102A+DM9802 NICs.    This software may be used and distributed according to the terms    of the GNU Public License, incorporated herein by reference.*//*********************************************************************//* Revision History                                                  *//*********************************************************************//*  19 OCT 2000  Sten     1.00			Different half and full duplex mode			Do the different programming for DM9801/DM9802  12 OCT 2000  Sten     0.90			This driver was ported from tulip driver and it 			has the following difference.			Changed symbol tulip/TULIP to davicom/DAVICOM			Deleted some code that did not use in this driver.			Used chain-strcture to replace ring structure			for both TX/RX descriptor.			Allocated two tx descriptor.			According current media mode to set operating 			register(CR6)*//*********************************************************************//* Declarations                                                      *//*********************************************************************/#include "etherboot.h"#include "nic.h"#include "pci.h"#include "cards.h"#undef DAVICOM_DEBUG#undef DAVICOM_DEBUG_WHERE#define TX_TIME_OUT       2*TICKS_PER_SECtypedef unsigned char  u8;typedef   signed char  s8;typedef unsigned short u16;typedef   signed short s16;typedef unsigned int   u32;typedef   signed int   s32;/* Register offsets for davicom device */enum davicom_offsets {   CSR0=0,     CSR1=0x08,  CSR2=0x10,  CSR3=0x18,  CSR4=0x20,  CSR5=0x28,   CSR6=0x30,  CSR7=0x38,  CSR8=0x40,  CSR9=0x48, CSR10=0x50, CSR11=0x58,  CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0};/* EEPROM Address width definitions */#define EEPROM_ADDRLEN 6#define EEPROM_SIZE    32              /* 1 << EEPROM_ADDRLEN *//* Used to be 128, but we only need to read enough to get the MAC   address at bytes 20..25 *//* Data Read from the EEPROM */static unsigned char ee_data[EEPROM_SIZE];/* The EEPROM commands include the alway-set leading bit. */#define EE_WRITE_CMD    (5 << addr_len)#define EE_READ_CMD     (6 << addr_len)#define EE_ERASE_CMD    (7 << addr_len)/* EEPROM_Ctrl bits. */#define EE_SHIFT_CLK    0x02    /* EEPROM shift clock. */#define EE_CS           0x01    /* EEPROM chip select. */#define EE_DATA_WRITE   0x04    /* EEPROM chip data in. */#define EE_WRITE_0      0x01#define EE_WRITE_1      0x05#define EE_DATA_READ    0x08    /* EEPROM chip data out. */#define EE_ENB          (0x4800 | EE_CS)/* Sten 10/11 for phyxcer */#define PHY_DATA_0	0x0#define PHY_DATA_1	0x20000#define MDCLKH		0x10000/* Delay between EEPROM clock transitions.  Even at 33Mhz current PCI   implementations don't overrun the EEPROM clock.  We add a bus   turn-around to insure that this remains true.  */#define eeprom_delay()  inl(ee_addr)/* helpful macro if on a big_endian machine for changing byte order.   not strictly needed on Intel */#define le16_to_cpu(val) (val)/* transmit and receive descriptor format */struct txdesc {  volatile unsigned long   status;         /* owner, status */  unsigned long   buf1sz:11,      /* size of buffer 1 */    buf2sz:11,                    /* size of buffer 2 */    control:10;                   /* control bits */  const unsigned char *buf1addr;  /* buffer 1 address */  const unsigned char *buf2addr;  /* buffer 2 address */};struct rxdesc {  volatile unsigned long   status;         /* owner, status */  unsigned long   buf1sz:11,      /* size of buffer 1 */    buf2sz:11,                    /* size of buffer 2 */    control:10;                   /* control bits */  unsigned char   *buf1addr;      /* buffer 1 address */  unsigned char   *buf2addr;      /* buffer 2 address */};/* Size of transmit and receive buffers */#define BUFLEN 1536/*********************************************************************//* Global Storage                                                    *//*********************************************************************//* PCI Bus parameters */static unsigned short vendor, dev_id;static unsigned long ioaddr;/* Note: transmit and receive buffers must be longword aligned and   longword divisable *//* transmit descriptor and buffer */#define NTXD 2static struct txdesc txd[NTXD] __attribute__ ((aligned(4)));#ifdef	USE_LOWMEM_BUFFER#define txb ((char *)0x10000 - BUFLEN)#elsestatic unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));#endif/* receive descriptor(s) and buffer(s) */#define NRXD 4static struct rxdesc rxd[NRXD] __attribute__ ((aligned(4)));#ifdef	USE_LOWMEM_BUFFER#define rxb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)#elsestatic unsigned char rxb[NRXD * BUFLEN] __attribute__ ((aligned(4)));#endifstatic int rxd_tail;static int TxPtr;/*********************************************************************//* Function Prototypes                                               *//*********************************************************************/static void whereami(const char *str);static int read_eeprom(unsigned long ioaddr, int location, int addr_len);struct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,			struct pci_device *pci);static void davicom_init_chain(struct nic *nic);	/* Sten 10/9 */static void davicom_reset(struct nic *nic);static void davicom_transmit(struct nic *nic, const char *d, unsigned int t,			   unsigned int s, const char *p);static int davicom_poll(struct nic *nic);static void davicom_disable(struct nic *nic);static void whereami (const char *str);#ifdef	DAVICOM_DEBUGstatic void davicom_more(void);#endif /* DAVICOM_DEBUG */static void davicom_wait(unsigned int nticks);static int phy_read(int);static void phy_write(int, u16);static void phy_write_1bit(u32, u32);static int phy_read_1bit(u32);static void davicom_media_chk(struct nic *);/*********************************************************************//* Utility Routines                                                  *//*********************************************************************/static inline void whereami (const char *str){#ifdef	DAVICOM_DEBUG_WHERE  printf("%s\n", str);  /* sleep(2); */#endif}#ifdef	DAVICOM_DEBUGstatic void davicom_more(){  printf("\n\n-- more --");  while (!iskey())    /* wait */;  getchar();  printf("\n\n");}#endif /* DAVICOM_DEBUG */static void davicom_wait(unsigned int nticks){  unsigned int to = currticks() + nticks;  while (currticks() < to)    /* wait */ ;}/*********************************************************************//* For DAVICOM phyxcer register by MII interface		     *//*********************************************************************//*  Read a word data from phy register*/static int phy_read(int location){ int i, phy_addr=1; u16 phy_data; u32 io_dcr9; whereami("phy_read\n"); io_dcr9 = ioaddr + CSR9; /* Send 33 synchronization clock to Phy controller */ for (i=0; i<34; i++)     phy_write_1bit(io_dcr9, PHY_DATA_1); /* Send start command(01) to Phy */ phy_write_1bit(io_dcr9, PHY_DATA_0); phy_write_1bit(io_dcr9, PHY_DATA_1); /* Send read command(10) to Phy */ phy_write_1bit(io_dcr9, PHY_DATA_1); phy_write_1bit(io_dcr9, PHY_DATA_0); /* Send Phy addres */ for (i=0x10; i>0; i=i>>1)     phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);    /* Send register addres */ for (i=0x10; i>0; i=i>>1)     phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0); /* Skip transition state */ phy_read_1bit(io_dcr9); /* read 16bit data */ for (phy_data=0, i=0; i<16; i++) {   phy_data<<=1;   phy_data|=phy_read_1bit(io_dcr9); } return phy_data;}/*  Write a word to Phy register*/static void phy_write(int location, u16 phy_data){ u16 i, phy_addr=1; u32 io_dcr9;  whereami("phy_write\n"); io_dcr9 = ioaddr + CSR9; /* Send 33 synchronization clock to Phy controller */ for (i=0; i<34; i++)   phy_write_1bit(io_dcr9, PHY_DATA_1); /* Send start command(01) to Phy */ phy_write_1bit(io_dcr9, PHY_DATA_0); phy_write_1bit(io_dcr9, PHY_DATA_1); /* Send write command(01) to Phy */ phy_write_1bit(io_dcr9, PHY_DATA_0); phy_write_1bit(io_dcr9, PHY_DATA_1); /* Send Phy addres */ for (i=0x10; i>0; i=i>>1)   phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0); /* Send register addres */ for (i=0x10; i>0; i=i>>1)   phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0); /* written trasnition */ phy_write_1bit(io_dcr9, PHY_DATA_1); phy_write_1bit(io_dcr9, PHY_DATA_0); /* Write a word data to PHY controller */ for (i=0x8000; i>0; i>>=1)   phy_write_1bit(io_dcr9, phy_data&i ? PHY_DATA_1: PHY_DATA_0);}/*  Write one bit data to Phy Controller*/static void phy_write_1bit(u32 ee_addr, u32 phy_data){ whereami("phy_write_1bit\n"); outl(phy_data, ee_addr);                        /* MII Clock Low */ eeprom_delay(); outl(phy_data|MDCLKH, ee_addr);                 /* MII Clock High */ eeprom_delay(); outl(phy_data, ee_addr);                        /* MII Clock Low */ eeprom_delay();}/*  Read one bit phy data from PHY controller*/static int phy_read_1bit(u32 ee_addr){ int phy_data; whereami("phy_read_1bit\n"); outl(0x50000, ee_addr); eeprom_delay(); phy_data=(inl(ee_addr)>>19) & 0x1; outl(0x40000, ee_addr); eeprom_delay(); return phy_data;}/*  DM9801/DM9802 present check and program */static void HPNA_process(void){ if ( (phy_read(3) & 0xfff0) == 0xb900 ) {   if ( phy_read(31) == 0x4404 ) {     /* DM9801 present */     if (phy_read(3) == 0xb901)

⌨️ 快捷键说明

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