iPXE
davicom.c
Go to the documentation of this file.
00001 #ifdef ALLMULTI
00002 #error multicast support is not yet implemented
00003 #endif
00004 /*  
00005     DAVICOM DM9009/DM9102/DM9102A Etherboot Driver      V1.00
00006 
00007     This driver was ported from Marty Connor's Tulip Etherboot driver. 
00008     Thanks Marty Connor (mdc@etherboot.org) 
00009 
00010     This davicom etherboot driver supports DM9009/DM9102/DM9102A/
00011     DM9102A+DM9801/DM9102A+DM9802 NICs.
00012 
00013     This software may be used and distributed according to the terms
00014     of the GNU Public License, incorporated herein by reference.
00015 
00016 */
00017 
00018 FILE_LICENCE ( GPL_ANY );
00019 
00020 /*********************************************************************/
00021 /* Revision History                                                  */
00022 /*********************************************************************/
00023 
00024 /*
00025   19 OCT 2000  Sten     1.00
00026                         Different half and full duplex mode
00027                         Do the different programming for DM9801/DM9802
00028 
00029   12 OCT 2000  Sten     0.90
00030                         This driver was ported from tulip driver and it 
00031                         has the following difference.
00032                         Changed symbol tulip/TULIP to davicom/DAVICOM
00033                         Deleted some code that did not use in this driver.
00034                         Used chain-strcture to replace ring structure
00035                         for both TX/RX descriptor.
00036                         Allocated two tx descriptor.
00037                         According current media mode to set operating 
00038                         register(CR6)
00039 */
00040 
00041 
00042 /*********************************************************************/
00043 /* Declarations                                                      */
00044 /*********************************************************************/
00045 
00046 #include "etherboot.h"
00047 #include "nic.h"
00048 #include <ipxe/pci.h>
00049 #include <ipxe/ethernet.h>
00050 
00051 #define TX_TIME_OUT       2*TICKS_PER_SEC
00052 
00053 /* Register offsets for davicom device */
00054 enum davicom_offsets {
00055    CSR0=0,     CSR1=0x08,  CSR2=0x10,  CSR3=0x18,  CSR4=0x20,  CSR5=0x28,
00056    CSR6=0x30,  CSR7=0x38,  CSR8=0x40,  CSR9=0x48, CSR10=0x50, CSR11=0x58,
00057   CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0
00058 };
00059 
00060 /* EEPROM Address width definitions */
00061 #define EEPROM_ADDRLEN 6
00062 #define EEPROM_SIZE    32              /* 1 << EEPROM_ADDRLEN */
00063 /* Used to be 128, but we only need to read enough to get the MAC
00064    address at bytes 20..25 */
00065 
00066 /* Data Read from the EEPROM */
00067 static unsigned char ee_data[EEPROM_SIZE];
00068 
00069 /* The EEPROM commands include the alway-set leading bit. */
00070 #define EE_WRITE_CMD    (5 << addr_len)
00071 #define EE_READ_CMD     (6 << addr_len)
00072 #define EE_ERASE_CMD    (7 << addr_len)
00073 
00074 /* EEPROM_Ctrl bits. */
00075 #define EE_SHIFT_CLK    0x02    /* EEPROM shift clock. */
00076 #define EE_CS           0x01    /* EEPROM chip select. */
00077 #define EE_DATA_WRITE   0x04    /* EEPROM chip data in. */
00078 #define EE_WRITE_0      0x01
00079 #define EE_WRITE_1      0x05
00080 #define EE_DATA_READ    0x08    /* EEPROM chip data out. */
00081 #define EE_ENB          (0x4800 | EE_CS)
00082 
00083 /* Sten 10/11 for phyxcer */
00084 #define PHY_DATA_0      0x0
00085 #define PHY_DATA_1      0x20000
00086 #define MDCLKH          0x10000
00087 
00088 /* Delay between EEPROM clock transitions.  Even at 33Mhz current PCI
00089    implementations don't overrun the EEPROM clock.  We add a bus
00090    turn-around to insure that this remains true.  */
00091 #define eeprom_delay()  inl(ee_addr)
00092 
00093 /* helpful macro if on a big_endian machine for changing byte order.
00094    not strictly needed on Intel
00095    Already defined in Etherboot includes
00096 #define le16_to_cpu(val) (val)
00097 */
00098 
00099 /* transmit and receive descriptor format */
00100 struct txdesc {
00101   volatile unsigned long   status;         /* owner, status */
00102   unsigned long   buf1sz:11,      /* size of buffer 1 */
00103     buf2sz:11,                    /* size of buffer 2 */
00104     control:10;                   /* control bits */
00105   const unsigned char *buf1addr;  /* buffer 1 address */
00106   const unsigned char *buf2addr;  /* buffer 2 address */
00107 };
00108 
00109 struct rxdesc {
00110   volatile unsigned long   status;         /* owner, status */
00111   unsigned long   buf1sz:11,      /* size of buffer 1 */
00112     buf2sz:11,                    /* size of buffer 2 */
00113     control:10;                   /* control bits */
00114   unsigned char   *buf1addr;      /* buffer 1 address */
00115   unsigned char   *buf2addr;      /* buffer 2 address */
00116 };
00117 
00118 /* Size of transmit and receive buffers */
00119 #define BUFLEN 1536
00120 
00121 /*********************************************************************/
00122 /* Global Storage                                                    */
00123 /*********************************************************************/
00124 
00125 static struct nic_operations davicom_operations;
00126 
00127 /* PCI Bus parameters */
00128 static unsigned short vendor, dev_id;
00129 static unsigned long ioaddr;
00130 
00131 /* Note: transmit and receive buffers must be longword aligned and
00132    longword divisable */
00133 
00134 /* transmit descriptor and buffer */
00135 #define NTXD 2
00136 #define NRXD 4
00137 struct {
00138         struct txdesc txd[NTXD] __attribute__ ((aligned(4)));
00139         unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));
00140         struct rxdesc rxd[NRXD] __attribute__ ((aligned(4)));
00141         unsigned char rxb[NRXD * BUFLEN] __attribute__ ((aligned(4)));
00142 } davicom_bufs __shared;
00143 #define txd davicom_bufs.txd
00144 #define txb davicom_bufs.txb
00145 #define rxd davicom_bufs.rxd
00146 #define rxb davicom_bufs.rxb
00147 static int rxd_tail;
00148 static int TxPtr;
00149 
00150 
00151 /*********************************************************************/
00152 /* Function Prototypes                                               */
00153 /*********************************************************************/
00154 static void whereami(const char *str);
00155 static int read_eeprom(unsigned long ioaddr, int location, int addr_len);
00156 static int davicom_probe(struct nic *nic,struct pci_device *pci);
00157 static void davicom_init_chain(struct nic *nic);        /* Sten 10/9 */
00158 static void davicom_reset(struct nic *nic);
00159 static void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
00160                            unsigned int s, const char *p);
00161 static int davicom_poll(struct nic *nic, int retrieve);
00162 static void davicom_disable(struct nic *nic);
00163 static void davicom_wait(unsigned int nticks);
00164 static int phy_read(int);
00165 static void phy_write(int, u16);
00166 static void phy_write_1bit(u32, u32);
00167 static int phy_read_1bit(u32);
00168 static void davicom_media_chk(struct nic *);
00169 
00170 
00171 /*********************************************************************/
00172 /* Utility Routines                                                  */
00173 /*********************************************************************/
00174 static inline void whereami(const char *str)
00175 {
00176   DBGP("%s\n", str);
00177   /* sleep(2); */
00178 }
00179 
00180 static void davicom_wait(unsigned int nticks)
00181 {
00182   unsigned int to = currticks() + nticks;
00183   while (currticks() < to)
00184     /* wait */ ;
00185 }
00186 
00187 
00188 /*********************************************************************/
00189 /* For DAVICOM phyxcer register by MII interface                     */
00190 /*********************************************************************/
00191 /*
00192   Read a word data from phy register
00193 */
00194 static int phy_read(int location)
00195 {
00196  int i, phy_addr=1;
00197  u16 phy_data;
00198  u32 io_dcr9;
00199 
00200  whereami("phy_read\n");
00201 
00202  io_dcr9 = ioaddr + CSR9;
00203 
00204  /* Send 33 synchronization clock to Phy controller */
00205  for (i=0; i<34; i++)
00206      phy_write_1bit(io_dcr9, PHY_DATA_1);
00207 
00208  /* Send start command(01) to Phy */
00209  phy_write_1bit(io_dcr9, PHY_DATA_0);
00210  phy_write_1bit(io_dcr9, PHY_DATA_1);
00211 
00212  /* Send read command(10) to Phy */
00213  phy_write_1bit(io_dcr9, PHY_DATA_1);
00214  phy_write_1bit(io_dcr9, PHY_DATA_0);
00215 
00216  /* Send Phy address */
00217  for (i=0x10; i>0; i=i>>1)
00218      phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);
00219    
00220  /* Send register address */
00221  for (i=0x10; i>0; i=i>>1)
00222      phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0);
00223 
00224  /* Skip transition state */
00225  phy_read_1bit(io_dcr9);
00226 
00227  /* read 16bit data */
00228  for (phy_data=0, i=0; i<16; i++) {
00229    phy_data<<=1;
00230    phy_data|=phy_read_1bit(io_dcr9);
00231  }
00232 
00233  return phy_data;
00234 }
00235 
00236 /*
00237   Write a word to Phy register
00238 */
00239 static void phy_write(int location, u16 phy_data)
00240 {
00241  u16 i, phy_addr=1;
00242  u32 io_dcr9; 
00243 
00244  whereami("phy_write\n");
00245 
00246  io_dcr9 = ioaddr + CSR9;
00247 
00248  /* Send 33 synchronization clock to Phy controller */
00249  for (i=0; i<34; i++)
00250    phy_write_1bit(io_dcr9, PHY_DATA_1);
00251 
00252  /* Send start command(01) to Phy */
00253  phy_write_1bit(io_dcr9, PHY_DATA_0);
00254  phy_write_1bit(io_dcr9, PHY_DATA_1);
00255 
00256  /* Send write command(01) to Phy */
00257  phy_write_1bit(io_dcr9, PHY_DATA_0);
00258  phy_write_1bit(io_dcr9, PHY_DATA_1);
00259 
00260  /* Send Phy address */
00261  for (i=0x10; i>0; i=i>>1)
00262    phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);
00263 
00264  /* Send register address */
00265  for (i=0x10; i>0; i=i>>1)
00266    phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0);
00267 
00268  /* written trasnition */
00269  phy_write_1bit(io_dcr9, PHY_DATA_1);
00270  phy_write_1bit(io_dcr9, PHY_DATA_0);
00271 
00272  /* Write a word data to PHY controller */
00273  for (i=0x8000; i>0; i>>=1)
00274    phy_write_1bit(io_dcr9, phy_data&i ? PHY_DATA_1: PHY_DATA_0);
00275 }
00276 
00277 /*
00278   Write one bit data to Phy Controller
00279 */
00280 static void phy_write_1bit(u32 ee_addr, u32 phy_data)
00281 {
00282  whereami("phy_write_1bit\n");
00283  outl(phy_data, ee_addr);                        /* MII Clock Low */
00284  eeprom_delay();
00285  outl(phy_data|MDCLKH, ee_addr);                 /* MII Clock High */
00286  eeprom_delay();
00287  outl(phy_data, ee_addr);                        /* MII Clock Low */
00288  eeprom_delay();
00289 }
00290 
00291 /*
00292   Read one bit phy data from PHY controller
00293 */
00294 static int phy_read_1bit(u32 ee_addr)
00295 {
00296  int phy_data;
00297 
00298  whereami("phy_read_1bit\n");
00299 
00300  outl(0x50000, ee_addr);
00301  eeprom_delay();
00302 
00303  phy_data=(inl(ee_addr)>>19) & 0x1;
00304 
00305  outl(0x40000, ee_addr);
00306  eeprom_delay();
00307 
00308  return phy_data;
00309 }
00310 
00311 /*
00312   DM9801/DM9802 present check and program 
00313 */
00314 static void HPNA_process(void)
00315 {
00316 
00317  if ( (phy_read(3) & 0xfff0) == 0xb900 ) {
00318    if ( phy_read(31) == 0x4404 ) {
00319      /* DM9801 present */
00320      if (phy_read(3) == 0xb901)
00321        phy_write(16, 0x5);      /* DM9801 E4 */
00322      else
00323        phy_write(16, 0x1005); /* DM9801 E3 and others */
00324      phy_write(25, ((phy_read(24) + 3) & 0xff) | 0xf000);
00325    } else {
00326      /* DM9802 present */
00327      phy_write(16, 0x5);
00328      phy_write(25, (phy_read(25) & 0xff00) + 2);
00329    }
00330  }
00331 }
00332 
00333 /*
00334   Sense media mode and set CR6
00335 */
00336 static void davicom_media_chk(struct nic * nic __unused)
00337 {
00338   unsigned long to, csr6;
00339 
00340   csr6 = 0x00200000;    /* SF */
00341   outl(csr6, ioaddr + CSR6);
00342 
00343 #define PCI_VENDOR_ID_DAVICOM           0x1282
00344 #define PCI_DEVICE_ID_DM9009            0x9009
00345   if (vendor == PCI_VENDOR_ID_DAVICOM && dev_id == PCI_DEVICE_ID_DM9009) {
00346     /* Set to 10BaseT mode for DM9009 */
00347     phy_write(0, 0);
00348   } else {
00349     /* For DM9102/DM9102A */
00350     to = currticks() + 2 * TICKS_PER_SEC;
00351     while ( ((phy_read(1) & 0x24)!=0x24) && (currticks() < to))
00352       /* wait */ ;
00353 
00354     if ( (phy_read(1) & 0x24) == 0x24 ) {
00355       if (phy_read(17) & 0xa000)  
00356         csr6 |= 0x00000200;     /* Full Duplex mode */
00357     } else
00358       csr6 |= 0x00040000; /* Select DM9801/DM9802 when Ethernet link failed */
00359   }
00360 
00361   /* set the chip's operating mode */
00362   outl(csr6, ioaddr + CSR6);
00363 
00364   /* DM9801/DM9802 present check & program */
00365   if (csr6 & 0x40000)
00366     HPNA_process();
00367 }
00368 
00369 
00370 /*********************************************************************/
00371 /* EEPROM Reading Code                                               */
00372 /*********************************************************************/
00373 /* EEPROM routines adapted from the Linux Tulip Code */
00374 /* Reading a serial EEPROM is a "bit" grungy, but we work our way
00375    through:->.
00376 */
00377 static int read_eeprom(unsigned long ioaddr, int location, int addr_len)
00378 {
00379   int i;
00380   unsigned short retval = 0;
00381   long ee_addr = ioaddr + CSR9;
00382   int read_cmd = location | EE_READ_CMD;
00383 
00384   whereami("read_eeprom\n");
00385 
00386   outl(EE_ENB & ~EE_CS, ee_addr);
00387   outl(EE_ENB, ee_addr);
00388 
00389   /* Shift the read command bits out. */
00390   for (i = 4 + addr_len; i >= 0; i--) {
00391     short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
00392     outl(EE_ENB | dataval, ee_addr);
00393     eeprom_delay();
00394     outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
00395     eeprom_delay();
00396   }
00397   outl(EE_ENB, ee_addr);
00398 
00399   for (i = 16; i > 0; i--) {
00400     outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
00401     eeprom_delay();
00402     retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
00403     outl(EE_ENB, ee_addr);
00404     eeprom_delay();
00405   }
00406 
00407   /* Terminate the EEPROM access. */
00408   outl(EE_ENB & ~EE_CS, ee_addr);
00409   return retval;
00410 }
00411 
00412 /*********************************************************************/
00413 /* davicom_init_chain - setup the tx and rx descriptors                */
00414 /* Sten 10/9                                                         */
00415 /*********************************************************************/
00416 static void davicom_init_chain(struct nic *nic)
00417 {
00418   int i;
00419 
00420   /* setup the transmit descriptor */
00421   /* Sten: Set 2 TX descriptor but use one TX buffer because
00422            it transmit a packet and wait complete every time. */
00423   for (i=0; i<NTXD; i++) {
00424     txd[i].buf1addr = (void *)virt_to_bus(&txb[0]);     /* Used same TX buffer */
00425     txd[i].buf2addr = (void *)virt_to_bus(&txd[i+1]);   /*  Point to Next TX desc */
00426     txd[i].buf1sz   = 0;
00427     txd[i].buf2sz   = 0;
00428     txd[i].control  = 0x184;           /* Begin/End/Chain */
00429     txd[i].status   = 0x00000000;      /* give ownership to Host */
00430   }
00431 
00432   /* construct perfect filter frame with mac address as first match
00433      and broadcast address for all others */
00434   for (i=0; i<192; i++) txb[i] = 0xFF;
00435   txb[0] = nic->node_addr[0];
00436   txb[1] = nic->node_addr[1];
00437   txb[4] = nic->node_addr[2];
00438   txb[5] = nic->node_addr[3];
00439   txb[8] = nic->node_addr[4];
00440   txb[9] = nic->node_addr[5];
00441 
00442   /* setup receive descriptor */
00443   for (i=0; i<NRXD; i++) {
00444     rxd[i].buf1addr = (void *)virt_to_bus(&rxb[i * BUFLEN]);
00445     rxd[i].buf2addr = (void *)virt_to_bus(&rxd[i+1]); /* Point to Next RX desc */
00446     rxd[i].buf1sz   = BUFLEN;
00447     rxd[i].buf2sz   = 0;        /* not used */
00448     rxd[i].control  = 0x4;              /* Chain Structure */
00449     rxd[i].status   = 0x80000000;   /* give ownership to device */
00450   }
00451 
00452   /* Chain the last descriptor to first */
00453   txd[NTXD - 1].buf2addr = (void *)virt_to_bus(&txd[0]);
00454   rxd[NRXD - 1].buf2addr = (void *)virt_to_bus(&rxd[0]);
00455   TxPtr = 0;
00456   rxd_tail = 0;
00457 }
00458 
00459 
00460 /*********************************************************************/
00461 /* davicom_reset - Reset adapter                                         */
00462 /*********************************************************************/
00463 static void davicom_reset(struct nic *nic)
00464 {
00465   unsigned long to;
00466 
00467   whereami("davicom_reset\n");
00468 
00469   /* Stop Tx and RX */
00470   outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
00471 
00472   /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
00473   outl(0x00000001, ioaddr + CSR0);
00474 
00475   davicom_wait(TICKS_PER_SEC);
00476 
00477   /* TX/RX descriptor burst */
00478   outl(0x0C00000, ioaddr + CSR0);       /* Sten 10/9 */
00479 
00480   /* set up transmit and receive descriptors */
00481   davicom_init_chain(nic);      /* Sten 10/9 */
00482 
00483   /* Point to receive descriptor */
00484   outl(virt_to_bus(&rxd[0]), ioaddr + CSR3);
00485   outl(virt_to_bus(&txd[0]), ioaddr + CSR4);    /* Sten 10/9 */
00486 
00487   /* According phyxcer media mode to set CR6,
00488      DM9102/A phyxcer can auto-detect media mode */
00489   davicom_media_chk(nic);
00490 
00491   /* Prepare Setup Frame Sten 10/9 */
00492   txd[TxPtr].buf1sz = 192;
00493   txd[TxPtr].control = 0x024;           /* SF/CE */
00494   txd[TxPtr].status = 0x80000000;       /* Give ownership to device */
00495 
00496   /* Start Tx */
00497   outl(inl(ioaddr + CSR6) | 0x00002000, ioaddr + CSR6);
00498   /* immediate transmit demand */
00499   outl(0, ioaddr + CSR1);
00500 
00501   to = currticks() + TX_TIME_OUT;
00502   while ((txd[TxPtr].status & 0x80000000) && (currticks() < to)) /* Sten 10/9 */
00503     /* wait */ ;
00504 
00505   if (currticks() >= to) {
00506     DBG ("TX Setup Timeout!\n");
00507   }
00508   /* Point to next TX descriptor */
00509  TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr;   /* Sten 10/9 */
00510 
00511   DBG("txd.status = %lX\n", txd[TxPtr].status);
00512   DBG("ticks = %ld\n", currticks() - (to - TX_TIME_OUT));
00513   DBG_MORE();
00514 
00515   /* enable RX */
00516   outl(inl(ioaddr + CSR6) | 0x00000002, ioaddr + CSR6);
00517   /* immediate poll demand */
00518   outl(0, ioaddr + CSR2);
00519 }
00520 
00521 
00522 /*********************************************************************/
00523 /* eth_transmit - Transmit a frame                                   */
00524 /*********************************************************************/
00525 static void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
00526                            unsigned int s, const char *p)
00527 {
00528   unsigned long to;
00529 
00530   whereami("davicom_transmit\n");
00531 
00532   /* Stop Tx */
00533   /* outl(inl(ioaddr + CSR6) & ~0x00002000, ioaddr + CSR6); */
00534 
00535   /* setup ethernet header */
00536   memcpy(&txb[0], d, ETH_ALEN); /* DA 6byte */
00537   memcpy(&txb[ETH_ALEN], nic->node_addr, ETH_ALEN); /* SA 6byte*/
00538   txb[ETH_ALEN*2] = (t >> 8) & 0xFF; /* Frame type: 2byte */
00539   txb[ETH_ALEN*2+1] = t & 0xFF;
00540   memcpy(&txb[ETH_HLEN], p, s); /* Frame data */
00541 
00542   /* setup the transmit descriptor */
00543   txd[TxPtr].buf1sz   = ETH_HLEN+s;
00544   txd[TxPtr].control  = 0x00000184;      /* LS+FS+CE */
00545   txd[TxPtr].status   = 0x80000000;      /* give ownership to device */
00546 
00547   /* immediate transmit demand */
00548   outl(0, ioaddr + CSR1);
00549 
00550   to = currticks() + TX_TIME_OUT;
00551   while ((txd[TxPtr].status & 0x80000000) && (currticks() < to))
00552     /* wait */ ;
00553 
00554   if (currticks() >= to) {
00555     DBG ("TX Timeout!\n");
00556   }
00557  
00558   /* Point to next TX descriptor */
00559   TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr;  /* Sten 10/9 */
00560 
00561 }
00562 
00563 /*********************************************************************/
00564 /* eth_poll - Wait for a frame                                       */
00565 /*********************************************************************/
00566 static int davicom_poll(struct nic *nic, int retrieve)
00567 {
00568   whereami("davicom_poll\n");
00569 
00570   if (rxd[rxd_tail].status & 0x80000000)
00571     return 0;
00572 
00573   if ( ! retrieve ) return 1;
00574 
00575   whereami("davicom_poll got one\n");
00576 
00577   nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16;
00578 
00579   if( rxd[rxd_tail].status & 0x00008000){
00580       rxd[rxd_tail].status = 0x80000000;
00581       rxd_tail++;
00582       if (rxd_tail == NRXD) rxd_tail = 0;
00583       return 0;
00584   }
00585 
00586   /* copy packet to working buffer */
00587   /* XXX - this copy could be avoided with a little more work
00588      but for now we are content with it because the optimised
00589      memcpy is quite fast */
00590 
00591   memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen);
00592 
00593   /* return the descriptor and buffer to receive ring */
00594   rxd[rxd_tail].status = 0x80000000;
00595   rxd_tail++;
00596   if (rxd_tail == NRXD) rxd_tail = 0;
00597 
00598   return 1;
00599 }
00600 
00601 /*********************************************************************/
00602 /* eth_disable - Disable the interface                               */
00603 /*********************************************************************/
00604 static void davicom_disable ( struct nic *nic ) {
00605 
00606   whereami("davicom_disable\n");
00607 
00608   davicom_reset(nic);
00609 
00610   /* disable interrupts */
00611   outl(0x00000000, ioaddr + CSR7);
00612 
00613   /* Stop the chip's Tx and Rx processes. */
00614   outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
00615 
00616   /* Clear the missed-packet counter. */
00617   inl(ioaddr + CSR8);
00618 }
00619 
00620 
00621 /*********************************************************************/
00622 /* eth_irq - enable, disable and force interrupts                    */
00623 /*********************************************************************/
00624 static void davicom_irq(struct nic *nic __unused, irq_action_t action __unused)
00625 {
00626   switch ( action ) {
00627   case DISABLE :
00628     break;
00629   case ENABLE :
00630     break;
00631   case FORCE :
00632     break;
00633   }
00634 }
00635 
00636 
00637 /*********************************************************************/
00638 /* eth_probe - Look for an adapter                                   */
00639 /*********************************************************************/
00640 static int davicom_probe ( struct nic *nic, struct pci_device *pci ) {
00641 
00642   unsigned int i;
00643 
00644   whereami("davicom_probe\n");
00645 
00646   if (pci->ioaddr == 0)
00647     return 0;
00648 
00649   vendor  = pci->vendor;
00650   dev_id  = pci->device;
00651   ioaddr  = pci->ioaddr;
00652 
00653   nic->ioaddr = pci->ioaddr;
00654   nic->irqno = 0;
00655 
00656   /* wakeup chip */
00657   pci_write_config_dword(pci, 0x40, 0x00000000);
00658 
00659   /* Stop the chip's Tx and Rx processes. */
00660   outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
00661 
00662   /* Clear the missed-packet counter. */
00663   inl(ioaddr + CSR8);
00664 
00665   /* Get MAC Address */
00666   /* read EEPROM data */
00667   for (i = 0; i < sizeof(ee_data)/2; i++)
00668     ((unsigned short *)ee_data)[i] =
00669         le16_to_cpu(read_eeprom(ioaddr, i, EEPROM_ADDRLEN));
00670 
00671   /* extract MAC address from EEPROM buffer */
00672   for (i=0; i<ETH_ALEN; i++)
00673     nic->node_addr[i] = ee_data[20+i];
00674 
00675   DBG ( "Davicom %s at IOADDR %4.4lx\n", eth_ntoa ( nic->node_addr ), ioaddr );
00676 
00677   /* initialize device */
00678   davicom_reset(nic);
00679   nic->nic_op   = &davicom_operations;
00680   return 1;
00681 }
00682 
00683 static struct nic_operations davicom_operations = {
00684         .connect        = dummy_connect,
00685         .poll           = davicom_poll,
00686         .transmit       = davicom_transmit,
00687         .irq            = davicom_irq,
00688 
00689 };
00690 
00691 static struct pci_device_id davicom_nics[] = {
00692 PCI_ROM(0x1282, 0x9100, "davicom9100", "Davicom 9100", 0),
00693 PCI_ROM(0x1282, 0x9102, "davicom9102", "Davicom 9102", 0),
00694 PCI_ROM(0x1282, 0x9009, "davicom9009", "Davicom 9009", 0),
00695 PCI_ROM(0x1282, 0x9132, "davicom9132", "Davicom 9132", 0),      /* Needs probably some fixing */
00696 };
00697 
00698 PCI_DRIVER ( davicom_driver, davicom_nics, PCI_NO_CLASS );
00699 
00700 DRIVER ( "DAVICOM", nic_driver, pci_driver, davicom_driver,
00701          davicom_probe, davicom_disable );
00702 
00703 /*
00704  * Local variables:
00705  *  c-basic-offset: 8
00706  *  c-indent-level: 8
00707  *  tab-width: 8
00708  * End:
00709  */