Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

eexpress.c

Go to the documentation of this file.
00001 /* Intel EtherExpress 16 device driver for Linux
00002  *
00003  * Written by John Sullivan, 1995
00004  *  based on original code by Donald Becker, with changes by
00005  *  Alan Cox and Pauline Middelink.
00006  *
00007  * Support for 8-bit mode by Zoltan Szilagyi <zoltans@cs.arizona.edu>
00008  *
00009  * Many modifications, and currently maintained, by
00010  *  Philip Blundell <Philip.Blundell@pobox.com>
00011  * Added the Compaq LTE  Alan Cox <alan@redhat.com>
00012  *
00013  * Note - this driver is experimental still - it has problems on faster
00014  * machines. Someone needs to sit down and go through it line by line with
00015  * a databook...
00016  */
00017 
00018 /* The EtherExpress 16 is a fairly simple card, based on a shared-memory
00019  * design using the i82586 Ethernet coprocessor.  It bears no relationship,
00020  * as far as I know, to the similarly-named "EtherExpress Pro" range.
00021  *
00022  * Historically, Linux support for these cards has been very bad.  However,
00023  * things seem to be getting better slowly.
00024  */
00025 
00026 /* If your card is confused about what sort of interface it has (eg it
00027  * persistently reports "10baseT" when none is fitted), running 'SOFTSET /BART'
00028  * or 'SOFTSET /LISA' from DOS seems to help.
00029  */
00030 
00031 /* Here's the scoop on memory mapping.
00032  *
00033  * There are three ways to access EtherExpress card memory: either using the
00034  * shared-memory mapping, or using PIO through the dataport, or using PIO
00035  * through the "shadow memory" ports.
00036  *
00037  * The shadow memory system works by having the card map some of its memory
00038  * as follows:
00039  *
00040  * (the low five bits of the SMPTR are ignored)
00041  *
00042  *  base+0x4000..400f      memory at SMPTR+0..15
00043  *  base+0x8000..800f      memory at SMPTR+16..31
00044  *  base+0xc000..c007      dubious stuff (memory at SMPTR+16..23 apparently)
00045  *  base+0xc008..c00f      memory at 0x0008..0x000f
00046  *
00047  * This last set (the one at c008) is particularly handy because the SCB
00048  * lives at 0x0008.  So that set of ports gives us easy random access to data
00049  * in the SCB without having to mess around setting up pointers and the like.
00050  * We always use this method to access the SCB (via the scb_xx() functions).
00051  *
00052  * Dataport access works by aiming the appropriate (read or write) pointer
00053  * at the first address you're interested in, and then reading or writing from
00054  * the dataport.  The pointers auto-increment after each transfer.  We use
00055  * this for data transfer.
00056  *
00057  * We don't use the shared-memory system because it allegedly doesn't work on
00058  * all cards, and because it's a bit more prone to go wrong (it's one more
00059  * thing to configure...).
00060  */
00061 
00062 /* Known bugs:
00063  *
00064  * - The card seems to want to give us two interrupts every time something
00065  *   happens, where just one would be better.
00066  */
00067 
00068 /*
00069  *
00070  * Note by Zoltan Szilagyi 10-12-96:
00071  *
00072  * I've succeeded in eliminating the "CU wedged" messages, and hence the
00073  * lockups, which were only occurring with cards running in 8-bit mode ("force
00074  * 8-bit operation" in Intel's SoftSet utility). This version of the driver
00075  * sets the 82586 and the ASIC to 8-bit mode at startup; it also stops the
00076  * CU before submitting a packet for transmission, and then restarts it as soon
00077  * as the process of handing the packet is complete. This is definitely an
00078  * unnecessary slowdown if the card is running in 16-bit mode; therefore one
00079  * should detect 16-bit vs 8-bit mode from the EEPROM settings and act 
00080  * accordingly. In 8-bit mode with this bugfix I'm getting about 150 K/s for
00081  * ftp's, which is significantly better than I get in DOS, so the overhead of
00082  * stopping and restarting the CU with each transmit is not prohibitive in
00083  * practice.
00084  *
00085  * Update by David Woodhouse 11/5/99:
00086  *
00087  * I've seen "CU wedged" messages in 16-bit mode, on the Alpha architecture.
00088  * I assume that this is because 16-bit accesses are actually handled as two
00089  * 8-bit accesses.
00090  */
00091 
00092 #ifdef __alpha__
00093 #define LOCKUP16 1
00094 #endif
00095 #ifndef LOCKUP16
00096 #define LOCKUP16 0
00097 #endif
00098   
00099 #include <linux/config.h>
00100 #include <linux/module.h>
00101 
00102 #include <linux/kernel.h>
00103 #include <linux/sched.h>
00104 #include <linux/types.h>
00105 #include <linux/fcntl.h>
00106 #include <linux/interrupt.h>
00107 #include <linux/ptrace.h>
00108 #include <linux/ioport.h>
00109 #include <linux/string.h>
00110 #include <linux/in.h>
00111 #include <asm/system.h>
00112 #include <asm/bitops.h>
00113 #include <asm/io.h>
00114 #include <asm/irq.h>
00115 #include <linux/delay.h>
00116 #include <linux/errno.h>
00117 #include <linux/init.h>
00118 
00119 #include <linux/netdevice.h>
00120 #include <linux/etherdevice.h>
00121 #include <linux/skbuff.h>
00122 #include <linux/malloc.h>
00123 
00124 #include <asm/spinlock.h>
00125 
00126 #ifndef NET_DEBUG
00127 #define NET_DEBUG 4
00128 #endif
00129 
00130 #include "eexpress.h"
00131 
00132 #define EEXP_IO_EXTENT  16
00133 
00134 /*
00135  * Private data declarations
00136  */
00137 
00138 struct net_local
00139 {
00140         struct net_device_stats stats;
00141         unsigned long last_tx;       /* jiffies when last transmit started */
00142         unsigned long init_time;     /* jiffies when eexp_hw_init586 called */
00143         unsigned short rx_first;     /* first rx buf, same as RX_BUF_START */
00144         unsigned short rx_last;      /* last rx buf */
00145         unsigned short rx_ptr;       /* first rx buf to look at */
00146         unsigned short tx_head;      /* next free tx buf */
00147         unsigned short tx_reap;      /* first in-use tx buf */
00148         unsigned short tx_tail;      /* previous tx buf to tx_head */
00149         unsigned short tx_link;      /* last known-executing tx buf */
00150         unsigned short last_tx_restart;   /* set to tx_link when we
00151                                              restart the CU */
00152         unsigned char started;
00153         unsigned short rx_buf_start;
00154         unsigned short rx_buf_end;
00155         unsigned short num_tx_bufs;
00156         unsigned short num_rx_bufs;
00157         unsigned char width;         /* 0 for 16bit, 1 for 8bit */
00158         unsigned char was_promisc;
00159         unsigned char old_mc_count;
00160         spinlock_t lock;
00161 };
00162 
00163 /* This is the code and data that is downloaded to the EtherExpress card's
00164  * memory at boot time.
00165  */
00166 
00167 static unsigned short start_code[] = {
00168 /* 0x0000 */
00169         0x0001,                 /* ISCP: busy - cleared after reset */
00170         0x0008,0x0000,0x0000,   /* offset,address (lo,hi) of SCB */
00171 
00172         0x0000,0x0000,          /* SCB: status, commands */
00173         0x0000,0x0000,          /* links to first command block,
00174                                    first receive descriptor */
00175         0x0000,0x0000,          /* CRC error, alignment error counts */
00176         0x0000,0x0000,          /* out of resources, overrun error counts */
00177 
00178         0x0000,0x0000,          /* pad */
00179         0x0000,0x0000,
00180 
00181 /* 0x20 -- start of 82586 CU program */
00182 #define CONF_LINK 0x20
00183         0x0000,Cmd_Config,      
00184         0x0032,                 /* link to next command */
00185         0x080c,                 /* 12 bytes follow : fifo threshold=8 */
00186         0x2e40,                 /* don't rx bad frames
00187                                  * SRDY/ARDY => ext. sync. : preamble len=8
00188                                  * take addresses from data buffers
00189                                  * 6 bytes/address
00190                                  */
00191         0x6000,                 /* default backoff method & priority
00192                                  * interframe spacing = 0x60 */
00193         0xf200,                 /* slot time=0x200 
00194                                  * max collision retry = 0xf */
00195 #define CONF_PROMISC  0x2e
00196         0x0000,                 /* no HDLC : normal CRC : enable broadcast 
00197                                  * disable promiscuous/multicast modes */
00198         0x003c,                 /* minimum frame length = 60 octets) */
00199 
00200         0x0000,Cmd_SetAddr,
00201         0x003e,                 /* link to next command */
00202 #define CONF_HWADDR  0x38
00203         0x0000,0x0000,0x0000,   /* hardware address placed here */
00204 
00205         0x0000,Cmd_MCast,
00206         0x0076,                 /* link to next command */
00207 #define CONF_NR_MULTICAST 0x44
00208         0x0000,                 /* number of multicast addresses */
00209 #define CONF_MULTICAST 0x46
00210         0x0000, 0x0000, 0x0000, /* some addresses */
00211         0x0000, 0x0000, 0x0000,
00212         0x0000, 0x0000, 0x0000,
00213         0x0000, 0x0000, 0x0000,
00214         0x0000, 0x0000, 0x0000,
00215         0x0000, 0x0000, 0x0000,
00216         0x0000, 0x0000, 0x0000,
00217         0x0000, 0x0000, 0x0000,
00218 
00219 #define CONF_DIAG_RESULT  0x76
00220         0x0000, Cmd_Diag,
00221         0x007c,                 /* link to next command */
00222 
00223         0x0000,Cmd_TDR|Cmd_INT,
00224         0x0084,
00225 #define CONF_TDR_RESULT  0x82
00226         0x0000,
00227 
00228         0x0000,Cmd_END|Cmd_Nop, /* end of configure sequence */
00229         0x0084                  /* dummy link */
00230 };
00231 
00232 /* maps irq number to EtherExpress magic value */
00233 static char irqrmap[] = { 0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0 };
00234 
00235 /*
00236  * Prototypes for Linux interface
00237  */
00238 
00239 extern int express_probe(struct device *dev);
00240 static int eexp_open(struct device *dev);
00241 static int eexp_close(struct device *dev);
00242 static struct net_device_stats *eexp_stats(struct device *dev);
00243 static int eexp_xmit(struct sk_buff *buf, struct device *dev);
00244 
00245 static void eexp_irq(int irq, void *dev_addr, struct pt_regs *regs);
00246 static void eexp_set_multicast(struct device *dev);
00247 
00248 /*
00249  * Prototypes for hardware access functions
00250  */
00251 
00252 static void eexp_hw_rx_pio(struct device *dev);
00253 static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf,
00254                        unsigned short len);
00255 static int eexp_hw_probe(struct device *dev,unsigned short ioaddr);
00256 static unsigned short eexp_hw_readeeprom(unsigned short ioaddr,
00257                                          unsigned char location);
00258 
00259 static unsigned short eexp_hw_lasttxstat(struct device *dev);
00260 static void eexp_hw_txrestart(struct device *dev);
00261 
00262 static void eexp_hw_txinit    (struct device *dev);
00263 static void eexp_hw_rxinit    (struct device *dev);
00264 
00265 static void eexp_hw_init586   (struct device *dev);
00266 static void eexp_setup_filter (struct device *dev);
00267 
00268 static char *eexp_ifmap[]={"AUI", "BNC", "RJ45"};
00269 enum eexp_iftype {AUI=0, BNC=1, TPE=2};
00270 
00271 #define STARTED_RU      2
00272 #define STARTED_CU      1
00273 
00274 /*
00275  * Primitive hardware access functions.
00276  */
00277 
00278 static inline unsigned short scb_status(struct device *dev)
00279 {
00280         return inw(dev->base_addr + 0xc008);
00281 }
00282 
00283 static inline unsigned short scb_rdcmd(struct device *dev)
00284 {
00285         return inw(dev->base_addr + 0xc00a);
00286 }
00287 
00288 static inline void scb_command(struct device *dev, unsigned short cmd)
00289 {
00290         outw(cmd, dev->base_addr + 0xc00a);
00291 }
00292 
00293 static inline void scb_wrcbl(struct device *dev, unsigned short val)
00294 {
00295         outw(val, dev->base_addr + 0xc00c);
00296 }
00297 
00298 static inline void scb_wrrfa(struct device *dev, unsigned short val)
00299 {
00300         outw(val, dev->base_addr + 0xc00e);
00301 }
00302 
00303 static inline void set_loopback(struct device *dev)
00304 {
00305         outb(inb(dev->base_addr + Config) | 2, dev->base_addr + Config);
00306 }
00307 
00308 static inline void clear_loopback(struct device *dev)
00309 {
00310         outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config);
00311 }
00312 
00313 static inline unsigned short int SHADOW(short int addr)
00314 {
00315         addr &= 0x1f;
00316         if (addr > 0xf) addr += 0x3ff0;
00317         return addr + 0x4000;
00318 }
00319 
00320 /*
00321  * Linux interface
00322  */
00323 
00324 /*
00325  * checks for presence of EtherExpress card
00326  */
00327 
00328 __initfunc(int express_probe(struct device *dev))
00329 {
00330         unsigned short *port;
00331         static unsigned short ports[] = { 0x300,0x310,0x270,0x320,0x340,0 };
00332         unsigned short ioaddr = dev->base_addr;
00333 
00334         if (ioaddr&0xfe00)
00335                 return eexp_hw_probe(dev,ioaddr);
00336         else if (ioaddr)
00337                 return ENXIO;
00338 
00339         for (port=&ports[0] ; *port ; port++ )
00340         {
00341                 unsigned short sum = 0;
00342                 int i;
00343                 for ( i=0 ; i<4 ; i++ )
00344                 {
00345                         unsigned short t;
00346                         t = inb(*port + ID_PORT);
00347                         sum |= (t>>4) << ((t & 0x03)<<2);
00348                 }
00349                 if (sum==0xbaba && !eexp_hw_probe(dev,*port))
00350                         return 0;
00351         }
00352         return -ENODEV;
00353 }
00354 
00355 /*
00356  * open and initialize the adapter, ready for use
00357  */
00358 
00359 static int eexp_open(struct device *dev)
00360 {
00361         int irq = dev->irq;
00362         unsigned short ioaddr = dev->base_addr;
00363         struct net_local *lp = (struct net_local *)dev->priv;
00364 
00365 #if NET_DEBUG > 6
00366         printk(KERN_DEBUG "%s: eexp_open()\n", dev->name);
00367 #endif
00368 
00369         if (!irq || !irqrmap[irq])
00370                 return -ENXIO;
00371 
00372         if (request_irq(irq,&eexp_irq,0,"EtherExpress",dev))
00373                 return -EAGAIN;
00374 
00375         request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress");
00376         request_region(ioaddr+0x4000, 16, "EtherExpress shadow");
00377         request_region(ioaddr+0x8000, 16, "EtherExpress shadow");
00378         request_region(ioaddr+0xc000, 16, "EtherExpress shadow");
00379         dev->tbusy = 0;
00380         dev->interrupt = 0;
00381         
00382         if (lp->width) {
00383                 printk("%s: forcing ASIC to 8-bit mode\n", dev->name);
00384                 outb(inb(dev->base_addr+Config)&~4, dev->base_addr+Config);
00385         }
00386 
00387         eexp_hw_init586(dev);
00388         dev->start = 1;
00389         MOD_INC_USE_COUNT;
00390 #if NET_DEBUG > 6
00391         printk(KERN_DEBUG "%s: leaving eexp_open()\n", dev->name);
00392 #endif
00393         return 0;
00394 }
00395 
00396 /*
00397  * close and disable the interface, leaving the 586 in reset.
00398  */
00399 
00400 static int eexp_close(struct device *dev)
00401 {
00402         unsigned short ioaddr = dev->base_addr;
00403         struct net_local *lp = dev->priv;
00404 
00405         int irq = dev->irq;
00406 
00407         dev->tbusy = 1;
00408         dev->start = 0;
00409 
00410         outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
00411         lp->started = 0;
00412         scb_command(dev, SCB_CUsuspend|SCB_RUsuspend);
00413         outb(0,ioaddr+SIGNAL_CA);
00414         free_irq(irq,dev);
00415         outb(i586_RST,ioaddr+EEPROM_Ctrl);
00416         release_region(ioaddr, EEXP_IO_EXTENT);
00417         release_region(ioaddr+0x4000, 16);
00418         release_region(ioaddr+0x8000, 16);
00419         release_region(ioaddr+0xc000, 16);
00420 
00421         MOD_DEC_USE_COUNT;
00422         return 0;
00423 }
00424 
00425 /*
00426  * Return interface stats
00427  */
00428 
00429 static struct net_device_stats *eexp_stats(struct device *dev)
00430 {
00431         struct net_local *lp = (struct net_local *)dev->priv;
00432 
00433         return &lp->stats;
00434 }
00435 
00436 /*
00437  * This gets called when a higher level thinks we are broken.  Check that
00438  * nothing has become jammed in the CU.
00439  */
00440 
00441 static void unstick_cu(struct device *dev)
00442 {
00443         struct net_local *lp = (struct net_local *)dev->priv;
00444         unsigned short ioaddr = dev->base_addr;
00445 
00446         if (lp->started)
00447         {
00448                 if ((jiffies - dev->trans_start)>50)
00449                 {
00450                         if (lp->tx_link==lp->last_tx_restart)
00451                         {
00452                                 unsigned short boguscount=200,rsst;
00453                                 printk(KERN_WARNING "%s: Retransmit timed out, status %04x, resetting...\n",
00454                                        dev->name, scb_status(dev));
00455                                 eexp_hw_txinit(dev);
00456                                 lp->last_tx_restart = 0;
00457                                 scb_wrcbl(dev, lp->tx_link);
00458                                 scb_command(dev, SCB_CUstart);
00459                                 outb(0,ioaddr+SIGNAL_CA);
00460                                 while (!SCB_complete(rsst=scb_status(dev)))
00461                                 {
00462                                         if (!--boguscount)
00463                                         {
00464                                                 boguscount=200;
00465                                                 printk(KERN_WARNING "%s: Reset timed out status %04x, retrying...\n",
00466                                                        dev->name,rsst);
00467                                                 scb_wrcbl(dev, lp->tx_link);
00468                                                 scb_command(dev, SCB_CUstart);
00469                                                 outb(0,ioaddr+SIGNAL_CA);
00470                                         }
00471                                 }
00472                                 dev->tbusy = 0;
00473                                 mark_bh(NET_BH);
00474                         }
00475                         else
00476                         {
00477                                 unsigned short status = scb_status(dev);
00478                                 if (SCB_CUdead(status))
00479                                 {
00480                                         unsigned short txstatus = eexp_hw_lasttxstat(dev);
00481                                         printk(KERN_WARNING "%s: Transmit timed out, CU not active status %04x %04x, restarting...\n",
00482                                                dev->name, status, txstatus);
00483                                         eexp_hw_txrestart(dev);
00484                                 }
00485                                 else
00486                                 {
00487                                         unsigned short txstatus = eexp_hw_lasttxstat(dev);
00488                                         if (dev->tbusy && !txstatus)
00489                                         {
00490                                                 printk(KERN_WARNING "%s: CU wedged, status %04x %04x, resetting...\n",
00491                                                        dev->name,status,txstatus);
00492                                                 eexp_hw_init586(dev);
00493                                                 dev->tbusy = 0;
00494                                                 mark_bh(NET_BH);
00495                                         }
00496                                         else
00497                                         {
00498                                                 printk(KERN_WARNING "%s: transmit timed out\n", dev->name);
00499                                         }
00500                                 }
00501                         }
00502                 }
00503         }
00504         else
00505         {
00506                 if ((jiffies-lp->init_time)>10)
00507                 {
00508                         unsigned short status = scb_status(dev);
00509                         printk(KERN_WARNING "%s: i82586 startup timed out, status %04x, resetting...\n",
00510                                dev->name, status);
00511                         eexp_hw_init586(dev);
00512                         dev->tbusy = 0;
00513                         mark_bh(NET_BH);
00514                 }
00515         }
00516 }
00517 
00518 /*
00519  * Called to transmit a packet, or to allow us to right ourselves
00520  * if the kernel thinks we've died.
00521  */
00522 static int eexp_xmit(struct sk_buff *buf, struct device *dev)
00523 {
00524         struct net_local *lp = (struct net_local *)dev->priv;
00525         short length = buf->len;
00526         unsigned long flags;
00527 
00528 #if NET_DEBUG > 6
00529         printk(KERN_DEBUG "%s: eexp_xmit()\n", dev->name);
00530 #endif
00531 
00532         if(buf->len < ETH_ZLEN)
00533         {
00534                 buf = skb_padto(buf, ETH_ZLEN);
00535                 if(buf == NULL)
00536                         return 0;
00537                 length = buf->len;
00538         }
00539 
00540         disable_irq(dev->irq);
00541 
00542         /*
00543          *      Best would be to use synchronize_irq(); spin_lock() here
00544          *      lets make it work first..
00545          */
00546          
00547 #ifdef CONFIG_SMP
00548         spin_lock_irqsave(&lp->lock, flags);
00549 #endif
00550 
00551         /* If dev->tbusy is set, all our tx buffers are full but the kernel
00552          * is calling us anyway.  Check that nothing bad is happening.
00553          */
00554         if (dev->tbusy) {
00555                 int status = scb_status(dev);
00556                 unstick_cu(dev);
00557                 if ((jiffies - lp->last_tx) < HZ)
00558                 {
00559 #ifdef CONFIG_SMP
00560                         spin_unlock_irqrestore(&lp->lock, flags);
00561 #endif
00562 
00563                         return 1;
00564                 }
00565                 printk(KERN_INFO "%s: transmit timed out, %s?", dev->name,
00566                        (SCB_complete(status)?"lost interrupt":
00567                         "board on fire"));
00568                 lp->stats.tx_errors++;
00569                 dev->tbusy = 0;
00570                 lp->last_tx = jiffies;
00571                 if (!SCB_complete(status)) {
00572                         scb_command(dev, SCB_CUabort);
00573                         outb(0,dev->base_addr+SIGNAL_CA);
00574                 }
00575         }
00576   
00577         if (test_and_set_bit(0,(void *)&dev->tbusy))
00578         {
00579                 lp->stats.tx_dropped++;
00580         }
00581         else
00582         {
00583                 unsigned short *data = (unsigned short *)buf->data;
00584 
00585                 lp->stats.tx_bytes += length;
00586 
00587                 eexp_hw_tx_pio(dev,data,length);
00588         }
00589         dev_kfree_skb(buf);
00590 #ifdef CONFIG_SMP
00591         spin_unlock_irqrestore(&lp->lock, flags);
00592 #endif
00593         enable_irq(dev->irq);
00594         return 0;
00595 }
00596 
00597 /*
00598  * Handle an EtherExpress interrupt
00599  * If we've finished initializing, start the RU and CU up.
00600  * If we've already started, reap tx buffers, handle any received packets,
00601  * check to make sure we've not become wedged.
00602  */
00603 
00604 /*
00605  * Handle an EtherExpress interrupt
00606  * If we've finished initializing, start the RU and CU up.
00607  * If we've already started, reap tx buffers, handle any received packets,
00608  * check to make sure we've not become wedged.
00609  */
00610 
00611 static unsigned short eexp_start_irq(struct device *dev,
00612                                      unsigned short status)
00613 {
00614         unsigned short ack_cmd = SCB_ack(status);
00615         struct net_local *lp = (struct net_local *)dev->priv;
00616         unsigned short ioaddr = dev->base_addr;
00617         if ((dev->flags & IFF_UP) && !(lp->started & STARTED_CU)) {
00618                 short diag_status, tdr_status;
00619                 while (SCB_CUstat(status)==2)
00620                         status = scb_status(dev);
00621 #if NET_DEBUG > 4
00622                 printk("%s: CU went non-active (status %04x)\n",
00623                        dev->name, status);
00624 #endif
00625 
00626                 outw(CONF_DIAG_RESULT & ~31, ioaddr + SM_PTR);
00627                 diag_status = inw(ioaddr + SHADOW(CONF_DIAG_RESULT));
00628                 if (diag_status & 1<<11) {
00629                         printk(KERN_WARNING "%s: 82586 failed self-test\n", 
00630                                dev->name);
00631                 } else if (!(diag_status & 1<<13)) {
00632                         printk(KERN_WARNING "%s: 82586 self-test failed to complete\n", dev->name);
00633                 }
00634 
00635                 outw(CONF_TDR_RESULT & ~31, ioaddr + SM_PTR);
00636                 tdr_status = inw(ioaddr + SHADOW(CONF_TDR_RESULT));
00637                 if (tdr_status & (TDR_SHORT|TDR_OPEN)) {
00638                         printk(KERN_WARNING "%s: TDR reports cable %s at %d tick%s\n", dev->name, (tdr_status & TDR_SHORT)?"short":"broken", tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : "");
00639                 } 
00640                 else if (tdr_status & TDR_XCVRPROBLEM) {
00641                         printk(KERN_WARNING "%s: TDR reports transceiver problem\n", dev->name);
00642                 }
00643                 else if (tdr_status & TDR_LINKOK) {
00644 #if NET_DEBUG > 4
00645                         printk(KERN_DEBUG "%s: TDR reports link OK\n", dev->name);
00646 #endif
00647                 } else {
00648                         printk("%s: TDR is ga-ga (status %04x)\n", dev->name,
00649                                tdr_status);
00650                 }
00651                         
00652                 lp->started |= STARTED_CU;
00653                 scb_wrcbl(dev, lp->tx_link);
00654                 /* if the RU isn't running, start it now */
00655                 if (!(lp->started & STARTED_RU)) {
00656                         ack_cmd |= SCB_RUstart;
00657                         scb_wrrfa(dev, lp->rx_buf_start);
00658                         lp->rx_ptr = lp->rx_buf_start;
00659                         lp->started |= STARTED_RU;
00660                 }
00661                 ack_cmd |= SCB_CUstart | 0x2000;
00662         }
00663 
00664         if ((dev->flags & IFF_UP) && !(lp->started & STARTED_RU) && SCB_RUstat(status)==4) 
00665                 lp->started|=STARTED_RU;
00666 
00667         return ack_cmd;
00668 }
00669 
00670 static void eexp_cmd_clear(struct device *dev)
00671 {
00672         unsigned long int oldtime = jiffies;
00673         while (scb_rdcmd(dev) && ((jiffies-oldtime)<10));
00674         if (scb_rdcmd(dev)) {
00675                 printk("%s: command didn't clear\n", dev->name);
00676         }
00677 }
00678         
00679 static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
00680 {
00681         struct device *dev = dev_info;
00682         struct net_local *lp;
00683         unsigned short ioaddr,status,ack_cmd;
00684         unsigned short old_read_ptr, old_write_ptr;
00685 
00686         if (dev==NULL)
00687         {
00688                 printk(KERN_WARNING "eexpress: irq %d for unknown device\n",
00689                        irq);
00690                 return;
00691         }
00692 
00693         lp = (struct net_local *)dev->priv;
00694         ioaddr = dev->base_addr;
00695 
00696         spin_lock(&lp->lock);
00697 
00698         old_read_ptr = inw(ioaddr+READ_PTR);
00699         old_write_ptr = inw(ioaddr+WRITE_PTR);
00700 
00701         outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
00702 
00703         
00704         dev->interrupt = 1;
00705 
00706         status = scb_status(dev);
00707 
00708 #if NET_DEBUG > 4
00709         printk(KERN_DEBUG "%s: interrupt (status %x)\n", dev->name, status);
00710 #endif
00711 
00712         if (lp->started == (STARTED_CU | STARTED_RU)) {
00713 
00714                 do {
00715                         eexp_cmd_clear(dev);
00716 
00717                         ack_cmd = SCB_ack(status);
00718                         scb_command(dev, ack_cmd);
00719                         outb(0,ioaddr+SIGNAL_CA);
00720 
00721                         eexp_cmd_clear(dev);
00722 
00723                         if (SCB_complete(status)) {
00724                                 if (!eexp_hw_lasttxstat(dev)) {
00725                                         printk("%s: tx interrupt but no status\n", dev->name);
00726                                 }
00727                         }
00728                         
00729                         if (SCB_rxdframe(status)) 
00730                                 eexp_hw_rx_pio(dev);
00731 
00732                         status = scb_status(dev);
00733                 } while (status & 0xc000);
00734 
00735                 if (SCB_RUdead(status)) 
00736                 {
00737                         printk(KERN_WARNING "%s: RU stopped: status %04x\n",
00738                                dev->name,status);
00739 #if 0
00740                         printk(KERN_WARNING "%s: cur_rfd=%04x, cur_rbd=%04x\n", dev->name, lp->cur_rfd, lp->cur_rbd);
00741                         outw(lp->cur_rfd, ioaddr+READ_PTR);
00742                         printk(KERN_WARNING "%s: [%04x]\n", dev->name, inw(ioaddr+DATAPORT));
00743                         outw(lp->cur_rfd+6, ioaddr+READ_PTR);
00744                         printk(KERN_WARNING "%s: rbd is %04x\n", dev->name, rbd= inw(ioaddr+DATAPORT));
00745                         outw(rbd, ioaddr+READ_PTR);
00746                         printk(KERN_WARNING "%s: [%04x %04x] ", dev->name, inw(ioaddr+DATAPORT), inw(ioaddr+DATAPORT));
00747                         outw(rbd+8, ioaddr+READ_PTR);
00748                         printk("[%04x]\n", inw(ioaddr+DATAPORT));
00749 #endif
00750                         lp->stats.rx_errors++;
00751 #if 1
00752                         eexp_hw_rxinit(dev);
00753 #else
00754                         lp->cur_rfd = lp->first_rfd;
00755 #endif
00756                         scb_wrrfa(dev, lp->rx_buf_start);
00757                         scb_command(dev, SCB_RUstart);
00758                         outb(0,ioaddr+SIGNAL_CA);
00759                 } 
00760         } else {
00761                 if (status & 0x8000) 
00762                         ack_cmd = eexp_start_irq(dev, status);
00763                 else
00764                         ack_cmd = SCB_ack(status);
00765                 scb_command(dev, ack_cmd);
00766                 outb(0,ioaddr+SIGNAL_CA);
00767         }
00768 
00769         eexp_cmd_clear(dev);
00770 
00771         outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ); 
00772 
00773         dev->interrupt = 0;
00774 #if NET_DEBUG > 6 
00775         printk("%s: leaving eexp_irq()\n", dev->name);
00776 #endif
00777         outw(old_read_ptr, ioaddr+READ_PTR);
00778         outw(old_write_ptr, ioaddr+WRITE_PTR);
00779         
00780         spin_unlock(&lp->lock);
00781         return;
00782 }
00783 
00784 /*
00785  * Hardware access functions
00786  */
00787 
00788 /*
00789  * Set the cable type to use.
00790  */
00791 
00792 static void eexp_hw_set_interface(struct device *dev)
00793 {
00794         unsigned char oldval = inb(dev->base_addr + 0x300e);
00795         oldval &= ~0x82;
00796         switch (dev->if_port) {
00797         case TPE:
00798                 oldval |= 0x2;
00799         case BNC:
00800                 oldval |= 0x80;
00801                 break;
00802         }
00803         outb(oldval, dev->base_addr+0x300e);
00804         mdelay(20);
00805 }
00806 
00807 /*
00808  * Check all the receive buffers, and hand any received packets
00809  * to the upper levels. Basic sanity check on each frame
00810  * descriptor, though we don't bother trying to fix broken ones.
00811  */
00812 
00813 static void eexp_hw_rx_pio(struct device *dev)
00814 {
00815         struct net_local *lp = (struct net_local *)dev->priv;
00816         unsigned short rx_block = lp->rx_ptr;
00817         unsigned short boguscount = lp->num_rx_bufs;
00818         unsigned short ioaddr = dev->base_addr;
00819         unsigned short status;
00820 
00821 #if NET_DEBUG > 6
00822         printk(KERN_DEBUG "%s: eexp_hw_rx()\n", dev->name);
00823 #endif
00824 
00825         do {
00826                 unsigned short rfd_cmd, rx_next, pbuf, pkt_len;
00827   
00828                 outw(rx_block, ioaddr + READ_PTR);
00829                 status = inw(ioaddr + DATAPORT);
00830 
00831                 if (FD_Done(status))
00832                 {
00833                         rfd_cmd = inw(ioaddr + DATAPORT);
00834                         rx_next = inw(ioaddr + DATAPORT);
00835                         pbuf = inw(ioaddr + DATAPORT);
00836  
00837                         outw(pbuf, ioaddr + READ_PTR);
00838                         pkt_len = inw(ioaddr + DATAPORT);
00839 
00840                         if (rfd_cmd!=0x0000)
00841                         {
00842                                 printk(KERN_WARNING "%s: rfd_cmd not zero:0x%04x\n",
00843                                        dev->name, rfd_cmd);
00844                                 continue;
00845                         }
00846                         else if (pbuf!=rx_block+0x16)
00847                         {
00848                                 printk(KERN_WARNING "%s: rfd and rbd out of sync 0x%04x 0x%04x\n", 
00849                                        dev->name, rx_block+0x16, pbuf);
00850                                 continue;
00851                         }
00852                         else if ((pkt_len & 0xc000)!=0xc000) 
00853                         {
00854                                 printk(KERN_WARNING "%s: EOF or F not set on received buffer (%04x)\n",
00855                                        dev->name, pkt_len & 0xc000);
00856                                 continue;
00857                         }
00858                         else if (!FD_OK(status)) 
00859                         {
00860                                 lp->stats.rx_errors++;
00861                                 if (FD_CRC(status))
00862                                         lp->stats.rx_crc_errors++;
00863                                 if (FD_Align(status))
00864                                         lp->stats.rx_frame_errors++;
00865                                 if (FD_Resrc(status))
00866                                         lp->stats.rx_fifo_errors++;
00867                                 if (FD_DMA(status))
00868                                         lp->stats.rx_over_errors++;
00869                                 if (FD_Short(status))
00870                                         lp->stats.rx_length_errors++;
00871                         }
00872                         else
00873                         {
00874                                 struct sk_buff *skb;
00875                                 pkt_len &= 0x3fff;
00876                                 skb = dev_alloc_skb(pkt_len+16);
00877                                 if (skb == NULL)
00878                                 {
00879                                         printk(KERN_WARNING "%s: Memory squeeze, dropping packet\n",dev->name);
00880                                         lp->stats.rx_dropped++;
00881                                         break;
00882                                 }
00883                                 skb->dev = dev;
00884                                 skb_reserve(skb, 2);
00885                                 outw(pbuf+10, ioaddr+READ_PTR);
00886                                 insw(ioaddr+DATAPORT, skb_put(skb,pkt_len),(pkt_len+1)>>1);
00887                                 skb->protocol = eth_type_trans(skb,dev);
00888                                 netif_rx(skb);
00889                                 lp->stats.rx_packets++;
00890                                 lp->stats.rx_bytes += pkt_len;
00891                         }
00892                         outw(rx_block, ioaddr+WRITE_PTR);
00893                         outw(0, ioaddr+DATAPORT);
00894                         outw(0, ioaddr+DATAPORT);
00895                         rx_block = rx_next;
00896                 }
00897         } while (FD_Done(status) && boguscount--);
00898         lp->rx_ptr = rx_block;
00899 }
00900 
00901 /*
00902  * Hand a packet to the card for transmission
00903  * If we get here, we MUST have already checked
00904  * to make sure there is room in the transmit
00905  * buffer region.
00906  */
00907 
00908 static void eexp_hw_tx_pio(struct device *dev, unsigned short *buf,
00909                        unsigned short len)
00910 {
00911         struct net_local *lp = (struct net_local *)dev->priv;
00912         unsigned short ioaddr = dev->base_addr;
00913 
00914         if (LOCKUP16 || lp->width) {
00915                 /* Stop the CU so that there is no chance that it
00916                    jumps off to a bogus address while we are writing the
00917                    pointer to the next transmit packet in 8-bit mode -- 
00918                    this eliminates the "CU wedged" errors in 8-bit mode.
00919                    (Zoltan Szilagyi 10-12-96) */ 
00920                 scb_command(dev, SCB_CUsuspend);
00921                 outw(0xFFFF, ioaddr+SIGNAL_CA);
00922         }
00923 
00924         outw(lp->tx_head, ioaddr + WRITE_PTR);
00925 
00926         outw(0x0000, ioaddr + DATAPORT);
00927         outw(Cmd_INT|Cmd_Xmit, ioaddr + DATAPORT);
00928         outw(lp->tx_head+0x08, ioaddr + DATAPORT);
00929         outw(lp->tx_head+0x0e, ioaddr + DATAPORT);
00930 
00931         outw(0x0000, ioaddr + DATAPORT);
00932         outw(0x0000, ioaddr + DATAPORT);
00933         outw(lp->tx_head+0x08, ioaddr + DATAPORT);
00934 
00935         outw(0x8000|len, ioaddr + DATAPORT);
00936         outw(-1, ioaddr + DATAPORT);
00937         outw(lp->tx_head+0x16, ioaddr + DATAPORT);
00938         outw(0, ioaddr + DATAPORT);
00939 
00940         outsw(ioaddr + DATAPORT, buf, (len+1)>>1);
00941 
00942         outw(lp->tx_tail+0xc, ioaddr + WRITE_PTR);
00943         outw(lp->tx_head, ioaddr + DATAPORT);
00944 
00945         dev->trans_start = jiffies;
00946         lp->tx_tail = lp->tx_head;
00947         if (lp->tx_head==TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
00948                 lp->tx_head = TX_BUF_START;
00949         else
00950                 lp->tx_head += TX_BUF_SIZE;
00951         if (lp->tx_head != lp->tx_reap)
00952                 dev->tbusy = 0;
00953 
00954         if (LOCKUP16 || lp->width) {
00955                 /* Restart the CU so that the packet can actually
00956                    be transmitted. (Zoltan Szilagyi 10-12-96) */
00957                 scb_command(dev, SCB_CUresume);
00958                 outw(0xFFFF, ioaddr+SIGNAL_CA);
00959         }
00960 
00961         lp->stats.tx_packets++;
00962         lp->last_tx = jiffies;
00963 }
00964 
00965 /*
00966  * Sanity check the suspected EtherExpress card
00967  * Read hardware address, reset card, size memory and initialize buffer
00968  * memory pointers. These are held in dev->priv, in case someone has more
00969  * than one card in a machine.
00970  */
00971 
00972 __initfunc(static int eexp_hw_probe(struct device *dev, unsigned short ioaddr))
00973 {
00974         unsigned short hw_addr[3];
00975         unsigned char buswidth;
00976         unsigned int memory_size;
00977         int i;
00978         unsigned short xsum = 0;
00979         struct net_local *lp;
00980 
00981         printk("%s: EtherExpress 16 at %#x ",dev->name,ioaddr);
00982 
00983         outb(ASIC_RST, ioaddr+EEPROM_Ctrl);
00984         outb(0, ioaddr+EEPROM_Ctrl);
00985         udelay(500);
00986         outb(i586_RST, ioaddr+EEPROM_Ctrl);
00987 
00988         hw_addr[0] = eexp_hw_readeeprom(ioaddr,2);
00989         hw_addr[1] = eexp_hw_readeeprom(ioaddr,3);
00990         hw_addr[2] = eexp_hw_readeeprom(ioaddr,4);
00991 
00992         /* Standard Address or Compaq LTE Address */
00993         if (!((hw_addr[2]==0x00aa && ((hw_addr[1] & 0xff00)==0x0000)) ||
00994               (hw_addr[2]==0x0080 && ((hw_addr[1] & 0xff00)==0x5F00)))) 
00995         {
00996                 printk(" rejected: invalid address %04x%04x%04x\n",
00997                         hw_addr[2],hw_addr[1],hw_addr[0]);
00998                 return -ENODEV;
00999         }
01000 
01001         /* Calculate the EEPROM checksum.  Carry on anyway if it's bad,
01002          * though.
01003          */
01004         for (i = 0; i < 64; i++)
01005                 xsum += eexp_hw_readeeprom(ioaddr, i);
01006         if (xsum != 0xbaba)
01007                 printk(" (bad EEPROM xsum 0x%02x)", xsum);
01008 
01009         dev->base_addr = ioaddr;
01010         for ( i=0 ; i<6 ; i++ )
01011                 dev->dev_addr[i] = ((unsigned char *)hw_addr)[5-i];
01012 
01013         {
01014                 static char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0};
01015                 unsigned short setupval = eexp_hw_readeeprom(ioaddr,0);
01016 
01017                 /* Use the IRQ from EEPROM if none was given */
01018                 if (!dev->irq)
01019                         dev->irq = irqmap[setupval>>13];
01020 
01021                 dev->if_port = !(setupval & 0x1000) ? AUI :
01022                         eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TPE : BNC;
01023 
01024                 buswidth = !((setupval & 0x400) >> 10);
01025         }
01026 
01027         dev->priv = lp = kmalloc(sizeof(struct net_local), GFP_KERNEL);
01028         if (!dev->priv)
01029                 return ENOMEM;
01030 
01031         memset(dev->priv, 0, sizeof(struct net_local));
01032 
01033         printk("(IRQ %d, %s connector, %d-bit bus", dev->irq, 
01034                eexp_ifmap[dev->if_port], buswidth?8:16);
01035  
01036         eexp_hw_set_interface(dev);
01037   
01038         /* Find out how much RAM we have on the card */
01039         outw(0, dev->base_addr + WRITE_PTR);
01040         for (i = 0; i < 32768; i++)
01041                 outw(0, dev->base_addr + DATAPORT);
01042 
01043         for (memory_size = 0; memory_size < 64; memory_size++)
01044         {
01045                 outw(memory_size<<10, dev->base_addr + READ_PTR);
01046                 if (inw(dev->base_addr+DATAPORT))
01047                         break;
01048                 outw(memory_size<<10, dev->base_addr + WRITE_PTR);
01049                 outw(memory_size | 0x5000, dev->base_addr+DATAPORT);
01050                 outw(memory_size<<10, dev->base_addr + READ_PTR);
01051                 if (inw(dev->base_addr+DATAPORT) != (memory_size | 0x5000))
01052                         break;
01053         }
01054 
01055         /* Sort out the number of buffers.  We may have 16, 32, 48 or 64k
01056          * of RAM to play with.
01057          */
01058         lp->num_tx_bufs = 4;
01059         lp->rx_buf_end = 0x3ff6;
01060         switch (memory_size)
01061         {
01062         case 64:
01063                 lp->rx_buf_end += 0x4000;
01064         case 48:
01065                 lp->num_tx_bufs += 4;
01066                 lp->rx_buf_end += 0x4000;
01067         case 32:
01068                 lp->rx_buf_end += 0x4000;
01069         case 16:
01070                 printk(", %dk RAM)\n", memory_size);
01071                 break;
01072         default:
01073                 printk(") bad memory size (%dk).\n", memory_size);
01074                 kfree(dev->priv);
01075                 return ENODEV;
01076                 break;
01077         }
01078 
01079         lp->rx_buf_start = TX_BUF_START + (lp->num_tx_bufs*TX_BUF_SIZE);
01080         lp->width = buswidth;
01081 
01082         dev->open = eexp_open;
01083         dev->stop = eexp_close;
01084         dev->hard_start_xmit = eexp_xmit;
01085         dev->get_stats = eexp_stats;
01086         dev->set_multicast_list = &eexp_set_multicast;
01087         ether_setup(dev);
01088         return 0;
01089 }
01090 
01091 /*
01092  * Read a word from the EtherExpress on-board serial EEPROM.
01093  * The EEPROM contains 64 words of 16 bits.
01094  */
01095 __initfunc(static unsigned short eexp_hw_readeeprom(unsigned short ioaddr,
01096                                                     unsigned char location))
01097 {
01098         unsigned short cmd = 0x180|(location&0x7f);
01099         unsigned short rval = 0,wval = EC_CS|i586_RST;
01100         int i;
01101 
01102         outb(EC_CS|i586_RST,ioaddr+EEPROM_Ctrl);
01103         for (i=0x100 ; i ; i>>=1 )
01104         {
01105                 if (cmd&i)
01106                         wval |= EC_Wr;
01107                 else
01108                         wval &= ~EC_Wr;
01109 
01110                 outb(wval,ioaddr+EEPROM_Ctrl);
01111                 outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
01112                 eeprom_delay();
01113                 outb(wval,ioaddr+EEPROM_Ctrl);
01114                 eeprom_delay();
01115         }
01116         wval &= ~EC_Wr;
01117         outb(wval,ioaddr+EEPROM_Ctrl);
01118         for (i=0x8000 ; i ; i>>=1 )
01119         {
01120                 outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
01121                 eeprom_delay();
01122                 if (inb(ioaddr+EEPROM_Ctrl)&EC_Rd)
01123                         rval |= i;
01124                 outb(wval,ioaddr+EEPROM_Ctrl);
01125                 eeprom_delay();
01126         }
01127         wval &= ~EC_CS;
01128         outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
01129         eeprom_delay();
01130         outb(wval,ioaddr+EEPROM_Ctrl);
01131         eeprom_delay();
01132         return rval;
01133 }
01134 
01135 /*
01136  * Reap tx buffers and return last transmit status.
01137  * if ==0 then either:
01138  *    a) we're not transmitting anything, so why are we here?
01139  *    b) we've died.
01140  * otherwise, Stat_Busy(return) means we've still got some packets
01141  * to transmit, Stat_Done(return) means our buffers should be empty
01142  * again
01143  */
01144 
01145 static unsigned short eexp_hw_lasttxstat(struct device *dev)
01146 {
01147         struct net_local *lp = (struct net_local *)dev->priv;
01148         unsigned short tx_block = lp->tx_reap;
01149         unsigned short status;
01150 
01151         if ((!dev->tbusy) && lp->tx_head==lp->tx_reap)
01152                 return 0x0000;
01153 
01154         do
01155         {
01156                 outw(tx_block & ~31, dev->base_addr + SM_PTR);
01157                 status = inw(dev->base_addr + SHADOW(tx_block));
01158                 if (!Stat_Done(status))
01159                 {
01160                         lp->tx_link = tx_block;
01161                         return status;
01162                 }
01163                 else
01164                 {
01165                         lp->last_tx_restart = 0;
01166                         lp->stats.collisions += Stat_NoColl(status);
01167                         if (!Stat_OK(status))
01168                         {
01169                                 char *whatsup = NULL;
01170                                 lp->stats.tx_errors++;
01171                                 if (Stat_Abort(status)) 
01172                                         lp->stats.tx_aborted_errors++;
01173                                 if (Stat_TNoCar(status)) {
01174                                         whatsup = "aborted, no carrier";
01175                                         lp->stats.tx_carrier_errors++;
01176                                 }
01177                                 if (Stat_TNoCTS(status)) {
01178                                         whatsup = "aborted, lost CTS";
01179                                         lp->stats.tx_carrier_errors++;
01180                                 }
01181                                 if (Stat_TNoDMA(status)) {
01182                                         whatsup = "FIFO underran";
01183                                         lp->stats.tx_fifo_errors++;
01184                                 }
01185                                 if (Stat_TXColl(status)) {
01186                                         whatsup = "aborted, too many collisions";
01187                                         lp->stats.tx_aborted_errors++;
01188                                 }
01189                                 if (whatsup)
01190                                         printk(KERN_INFO "%s: transmit %s\n",
01191                                                dev->name, whatsup);
01192                         }
01193                         else
01194                                 lp->stats.tx_packets++;
01195                 }
01196                 if (tx_block == TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
01197                         lp->tx_reap = tx_block = TX_BUF_START;
01198                 else
01199                         lp->tx_reap = tx_block += TX_BUF_SIZE;
01200                 dev->tbusy = 0;
01201                 mark_bh(NET_BH);
01202         }
01203         while (lp->tx_reap != lp->tx_head);
01204 
01205         lp->tx_link = lp->tx_tail + 0x08;
01206 
01207         return status;
01208 }
01209 
01210 /*
01211  * This should never happen. It is called when some higher routine detects
01212  * that the CU has stopped, to try to restart it from the last packet we knew
01213  * we were working on, or the idle loop if we had finished for the time.
01214  */
01215 
01216 static void eexp_hw_txrestart(struct device *dev)
01217 {
01218         struct net_local *lp = (struct net_local *)dev->priv;
01219         unsigned short ioaddr = dev->base_addr;
01220 
01221         lp->last_tx_restart = lp->tx_link;
01222         scb_wrcbl(dev, lp->tx_link);
01223         scb_command(dev, SCB_CUstart);
01224         outb(0,ioaddr+SIGNAL_CA);
01225 
01226         {
01227                 unsigned short boguscount=50,failcount=5;
01228                 while (!scb_status(dev))
01229                 {
01230                         if (!--boguscount)
01231                         {
01232                                 if (--failcount)
01233                                 {
01234                                         printk(KERN_WARNING "%s: CU start timed out, status %04x, cmd %04x\n", dev->name, scb_status(dev), scb_rdcmd(dev));
01235                                         scb_wrcbl(dev, lp->tx_link);
01236                                         scb_command(dev, SCB_CUstart);
01237                                         outb(0,ioaddr+SIGNAL_CA);
01238                                         boguscount = 100;
01239                                 }
01240                                 else
01241                                 {
01242                                         printk(KERN_WARNING "%s: Failed to restart CU, resetting board...\n",dev->name);
01243                                         eexp_hw_init586(dev);
012