Bug Summary

File:obj-scan-build/../linux/src/drivers/net/eexpress.c
Location:line 531, column 3
Description:Value stored to 'txstatus' is never read

Annotated Source Code

1/* $Id: eexpress.c,v 1.1 1999/04/26 05:52:09 tb Exp $
2 *
3 * Intel EtherExpress device driver for Linux
4 *
5 * Original version written 1993 by Donald Becker
6 * Modularized by Pauline Middelink <middelin@polyware.iaf.nl>
7 * Changed to support io= irq= by Alan Cox <Alan.Cox@linux.org>
8 * Reworked 1995 by John Sullivan <js10039@cam.ac.uk>
9 * More fixes by Philip Blundell <pjb27@cam.ac.uk>
10 * Added the Compaq LTE Alan Cox <alan@redhat.com>
11 *
12 * Note - this driver is experimental still - it has problems on faster
13 * machines. Someone needs to sit down and go through it line by line with
14 * a databook...
15 */
16
17/*
18 * The original EtherExpress driver was just about usable, but
19 * suffered from a long startup delay, a hard limit of 16k memory
20 * usage on the card (EtherExpress 16s have either 32k or 64k),
21 * and random locks under load. The last was particularly annoying
22 * and made running eXceed/W preferable to Linux/XFree. After hacking
23 * through the driver for a couple of days, I had fixed most of the
24 * card handling errors, at the expense of turning the code into
25 * a complete jungle, but still hadn't tracked down the lock-ups.
26 * I had hoped these would be an IP bug, but failed to reproduce them
27 * under other drivers, so decided to start from scratch and rewrite
28 * the driver cleanly. And here it is.
29 *
30 * It's still not quite there, but self-corrects a lot more problems.
31 * the 'CU wedged, resetting...' message shouldn't happen at all, but
32 * at least we recover. It still locks occasionally, any ideas welcome.
33 *
34 * The original startup delay experienced by some people was due to the
35 * first ARP request for the address of the default router getting lost.
36 * (mostly the reply we were getting back was arriving before our
37 * hardware address was set up, or before the configuration sequence
38 * had told the card NOT to strip of the frame header). If you a long
39 * startup delay, you may have lost this ARP request/reply, although
40 * the original cause has been fixed. However, it is more likely that
41 * you've just locked under this version.
42 *
43 * The main changes are in the 586 initialization procedure (which was
44 * just broken before - the EExp is a strange beasty and needs careful
45 * handling) the receive buffer handling (we now use a non-terminating
46 * circular list of buffers, which stops the card giving us out-of-
47 * resources errors), and the transmit code. The driver is also more
48 * structured, and I have tried to keep the kernel interface separate
49 * from the hardware interface (although some routines naturally want
50 * to do both).
51 *
52 * John Sullivan
53 *
54 * 18/5/95:
55 *
56 * The lock-ups seem to happen when you access card memory after a 586
57 * reset. This happens only 1 in 12 resets, on a random basis, and
58 * completely locks the machine. As far as I can see there is no
59 * workaround possible - the only thing to be done is make sure we
60 * never reset the card *after* booting the kernel - once at probe time
61 * must be sufficient, and we'll just have to put up with that failing
62 * occasionally (or buy a new NIC). By the way, this looks like a
63 * definite card bug, since Intel's own driver for DOS does exactly the
64 * same.
65 *
66 * This bug makes switching in and out of promiscuous mode a risky
67 * business, since we must do a 586 reset each time.
68 */
69
70/*
71 * Sources:
72 *
73 * The original eexpress.c by Donald Becker
74 * Sources: the Crynwr EtherExpress driver source.
75 * the Intel Microcommunications Databook Vol.1 1990
76 *
77 * wavelan.c and i82586.h
78 * This was invaluable for the complete '586 configuration details
79 * and command format.
80 *
81 * The Crynwr sources (again)
82 * Not as useful as the Wavelan driver, but then I had eexpress.c to
83 * go off.
84 *
85 * The Intel EtherExpress 16 ethernet card
86 * Provided the only reason I want to see a working etherexpress driver.
87 * A lot of fixes came from just observing how the card (mis)behaves when
88 * you prod it.
89 *
90 */
91
92static char version[] =
93"eexpress.c: v0.10 04-May-95 John Sullivan <js10039@cam.ac.uk>\n"
94" v0.14 19-May-96 Philip Blundell <phil@tazenda.demon.co.uk>\n"
95" v0.15 04-Aug-98 Alan Cox <alan@redhat.com>\n";
96
97#include <linux/module.h>
98
99#include <linux/kernel.h>
100#include <linux/sched.h>
101#include <linux/types.h>
102#include <linux/fcntl.h>
103#include <linux/interrupt.h>
104#include <linux/ptrace.h>
105#include <linux/ioport.h>
106#include <linux/string.h>
107#include <linux/in.h>
108#include <asm/system.h>
109#include <asm/bitops.h>
110#include <asm/io.h>
111#include <asm/dma.h>
112#include <linux/delay.h>
113#include <linux/errno.h>
114
115#include <linux/netdevice.h>
116#include <linux/etherdevice.h>
117#include <linux/skbuff.h>
118#include <linux/malloc.h>
119
120/*
121 * Not actually used yet - may be implemented when the driver has
122 * been debugged!
123 *
124 * Debug Level Driver Status
125 * 0 Final release
126 * 1 Beta test
127 * 2
128 * 3
129 * 4 Report timeouts & 586 errors (normal debug level)
130 * 5 Report all major events
131 * 6 Dump sent/received packet contents
132 * 7 Report function entry/exit
133 */
134
135#ifndef NET_DEBUG4
136#define NET_DEBUG4 4
137#endif
138static unsigned int net_debug = NET_DEBUG4;
139
140#undef F_DEB
141
142#include "eth82586.h"
143
144#define PRIV(x)((struct net_local *)(x)->priv) ((struct net_local *)(x)->priv)
145#define EEXP_IO_EXTENT16 16
146
147/*
148 * Private data declarations
149 */
150
151struct net_local
152{
153 struct enet_statistics stats;
154 unsigned long init_time; /* jiffies when eexp_hw_init586 called */
155 unsigned short rx_first; /* first rx buf, same as RX_BUF_START */
156 unsigned short rx_last; /* last rx buf */
157 unsigned short tx_head; /* next free tx buf */
158 unsigned short tx_reap; /* first in-use tx buf */
159 unsigned short tx_tail; /* previous tx buf to tx_head */
160 unsigned short tx_link; /* last known-executing tx buf */
161 unsigned short last_tx_restart; /* set to tx_link when we restart the CU */
162 unsigned char started;
163 unsigned char promisc;
164 unsigned short rx_buf_start;
165 unsigned short rx_buf_end;
166 unsigned short num_tx_bufs;
167 unsigned short num_rx_bufs;
168};
169
170unsigned short start_code[] = {
171 0x0000, /* SCP: set bus to 16 bits */
172 0x0000,0x0000, /* junk */
173 0x0000,0x0000, /* address of ISCP (lo,hi) */
174
175 0x0001, /* ISCP: busy - cleared after reset */
176 0x0008,0x0000,0x0000, /* offset,address (lo,hi) of SCB */
177
178 0x0000,0x0000, /* SCB: status, commands */
179 0x0000,0x0000, /* links to first command block, first receive descriptor */
180 0x0000,0x0000, /* CRC error, alignment error counts */
181 0x0000,0x0000, /* out of resources, overrun error counts */
182
183 0x0000,0x0000, /* pad */
184 0x0000,0x0000,
185
186 0x0000,Cmd_Config0x0002, /* startup configure sequence, at 0x0020 */
187 0x0032, /* link to next command */
188 0x080c, /* 12 bytes follow : fifo threshold=8 */
189 0x2e40, /* don't rx bad frames : SRDY/ARDY => ext. sync. : preamble len=8
190 * take addresses from data buffers : 6 bytes/address */
191 0x6000, /* default backoff method & priority : interframe spacing = 0x60 */
192 0xf200, /* slot time=0x200 : max collision retry = 0xf */
193 0x0000, /* no HDLC : normal CRC : enable broadcast : disable promiscuous/multicast modes */
194 0x003c, /* minimum frame length = 60 octets) */
195
196 0x0000,Cmd_INT0x2000|Cmd_SetAddr0x0001,
197 0x003e, /* link to next command */
198 0x0000,0x0000,0x0000, /* hardware address placed here, 0x0038 */
199 0x0000,Cmd_END0x8000|Cmd_Nop0x0000, /* end of configure sequence */
200 0x003e,
201
202 0x0000
203
204};
205
206#define CONF_LINK0x0020 0x0020
207#define CONF_HW_ADDR0x0038 0x0038
208
209/* maps irq number to EtherExpress magic value */
210static char irqrmap[] = { 0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0 };
211
212/*
213 * Prototypes for Linux interface
214 */
215
216extern int express_probe(struct devicelinux_device *dev);
217static int eexp_open (struct devicelinux_device *dev);
218static int eexp_close(struct devicelinux_device *dev);
219static struct enet_statistics *eexp_stats(struct devicelinux_device *dev);
220static int eexp_xmit (struct sk_buff *buf, struct devicelinux_device *dev);
221
222static void eexp_irq (int irq, void *dev_addr, struct pt_regs *regs);
223static void eexp_set_multicast(struct devicelinux_device *dev);
224
225/*
226 * Prototypes for hardware access functions
227 */
228
229static void eexp_hw_rx (struct devicelinux_device *dev);
230static void eexp_hw_tx (struct devicelinux_device *dev, unsigned short *buf, unsigned short len);
231static int eexp_hw_probe (struct devicelinux_device *dev,unsigned short ioaddr);
232static unsigned short eexp_hw_readeeprom(unsigned short ioaddr, unsigned char location);
233
234static unsigned short eexp_hw_lasttxstat(struct devicelinux_device *dev);
235static void eexp_hw_txrestart (struct devicelinux_device *dev);
236
237static void eexp_hw_txinit (struct devicelinux_device *dev);
238static void eexp_hw_rxinit (struct devicelinux_device *dev);
239
240static void eexp_hw_init586 (struct devicelinux_device *dev);
241static void eexp_hw_ASICrst (struct devicelinux_device *dev);
242
243/*
244 * Linux interface
245 */
246
247/*
248 * checks for presence of EtherExpress card
249 */
250
251int express_probe(struct devicelinux_device *dev)
252{
253 unsigned short *port,ports[] = { 0x0300,0x0270,0x0320,0x0340,0 };
254 unsigned short ioaddr = dev->base_addr;
255
256 if (ioaddr&0xfe00)
257 return eexp_hw_probe(dev,ioaddr);
258 else if (ioaddr)
259 return ENXIO6;
260
261 for ( port=&ports[0] ; *port ; port++ )
262 {
263 unsigned short sum = 0;
264 int i;
265 for ( i=0 ; i<4 ; i++ )
266 {
267 unsigned short t;
268 t = inb(*port + ID_PORT)((__builtin_constant_p((*port + 0x000f)) && (*port + 0x000f
) < 256) ? __inbc(*port + 0x000f) : __inb(*port + 0x000f))
;
269 sum |= (t>>4) << ((t & 0x03)<<2);
270 }
271 if (sum==0xbaba && !eexp_hw_probe(dev,*port))
272 return 0;
273 }
274 return ENODEV19;
275}
276
277/*
278 * open and initialize the adapter, ready for use
279 */
280
281static int eexp_open(struct devicelinux_device *dev)
282{
283 int irq = dev->irq;
284 unsigned short ioaddr = dev->base_addr;
285
286#if NET_DEBUG4 > 6
287 printk(KERN_DEBUG"<7>" "%s: eexp_open()\n", dev->name);
288#endif
289
290 if (!irq || !irqrmap[irq])
291 return -ENXIO6;
292
293 if (irq2dev_map[irq] ||
294 /* more consistent, surely? */
295 ((irq2dev_map[irq]=dev),0) ||
296 request_irq(irq,&eexp_irq,0,"eexpress",NULL((void *) 0)))
297 return -EAGAIN11;
298
299 request_region(ioaddr, EEXP_IO_EXTENT16, "eexpress");
300 dev->tbusy = 0;
301 dev->interrupt = 0;
302 eexp_hw_init586(dev);
303 dev->start = 1;
304 MOD_INC_USE_COUNTdo { } while (0);
305#if NET_DEBUG4 > 6
306 printk(KERN_DEBUG"<7>" "%s: leaving eexp_open()\n", dev->name);
307#endif
308 return 0;
309}
310
311/*
312 * close and disable the interface, leaving
313 * the 586 in reset
314 */
315static int eexp_close(struct devicelinux_device *dev)
316{
317 unsigned short ioaddr = dev->base_addr;
318 int irq = dev->irq;
319
320 dev->tbusy = 1;
321 dev->start = 0;
322
323 outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0x00|irqrmap[irq]),(ioaddr+0x0007)) : __outb
((0x00|irqrmap[irq]),(ioaddr+0x0007)))
;
324 PRIV(dev)((struct net_local *)(dev)->priv)->started = 0;
325 outw(SCB_CUsuspend|SCB_RUsuspend,ioaddr+SCB_CMD)((__builtin_constant_p((ioaddr+0xc00a)) && (ioaddr+0xc00a
) < 256) ? __outwc((0x0300|0x0030),(ioaddr+0xc00a)) : __outw
((0x0300|0x0030),(ioaddr+0xc00a)))
;
326 outb(0,ioaddr+SIGNAL_CA)((__builtin_constant_p((ioaddr+0x0006)) && (ioaddr+0x0006
) < 256) ? __outbc((0),(ioaddr+0x0006)) : __outb((0),(ioaddr
+0x0006)))
;
327 free_irq(irq,NULL((void *) 0));
328 irq2dev_map[irq] = NULL((void *) 0);
329 outb(i586_RST,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((0x80),(ioaddr+0x000e)) : __outb((0x80)
,(ioaddr+0x000e)))
;
330 release_region(ioaddr,16);
331 MOD_DEC_USE_COUNTdo { } while (0);
332 return 0;
333}
334
335/*
336 * Return interface stats
337 */
338
339static struct enet_statistics *eexp_stats(struct devicelinux_device *dev)
340{
341 struct net_local *lp = (struct net_local *)dev->priv;
342
343 /*
344 * Hmmm, this looks a little too easy... The card maintains
345 * some stats in the SCB, and I'm not convinced we're
346 * incrementing the most sensible statistics when the card
347 * returns an error (esp. slow DMA, out-of-resources)
348 */
349 return &lp->stats;
350}
351
352/*
353 * Called to transmit a packet, or to allow us to right ourselves
354 * if the kernel thinks we've died.
355 */
356
357static int eexp_xmit(struct sk_buff *buf, struct devicelinux_device *dev)
358{
359 struct net_local *lp = (struct net_local *)dev->priv;
360 unsigned short ioaddr = dev->base_addr;
361
362#if NET_DEBUG4 > 6
363 printk(KERN_DEBUG"<7>" "%s: eexp_xmit()\n", dev->name);
364#endif
365
366 outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0x00|irqrmap[dev->irq]),(ioaddr+0x0007
)) : __outb((0x00|irqrmap[dev->irq]),(ioaddr+0x0007)))
;
367 if (dev->tbusy)
368 {
369 /* This will happen, but hopefully not as often as when
370 * tbusy==0. If it happens too much, we probably ought
371 * to think about unwedging ourselves...
372 */
373 if (test_bit(0,(void *)&PRIV(dev)((struct net_local *)(dev)->priv)->started))
374 {
375 if ((jiffies - dev->trans_start)>5)
376 {
377 if (lp->tx_link==lp->last_tx_restart)
378 {
379 unsigned short boguscount=200,rsst;
380 printk(KERN_WARNING"<4>" "%s: Retransmit timed out, status %04x, resetting...\n",
381 dev->name,inw(ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __inwc(ioaddr+0xc008) : __inw(ioaddr+0xc008))
);
382 eexp_hw_txinit(dev);
383 lp->last_tx_restart = 0;
384 outw(lp->tx_link,ioaddr+SCB_CBL)((__builtin_constant_p((ioaddr+0xc00c)) && (ioaddr+0xc00c
) < 256) ? __outwc((lp->tx_link),(ioaddr+0xc00c)) : __outw
((lp->tx_link),(ioaddr+0xc00c)))
;
385 outw(0,ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __outwc((0),(ioaddr+0xc008)) : __outw((0),(ioaddr
+0xc008)))
;
386 outw(SCB_CUstart,ioaddr+SCB_CMD)((__builtin_constant_p((ioaddr+0xc00a)) && (ioaddr+0xc00a
) < 256) ? __outwc((0x0100),(ioaddr+0xc00a)) : __outw((0x0100
),(ioaddr+0xc00a)))
;
387 outb(0,ioaddr+SIGNAL_CA)((__builtin_constant_p((ioaddr+0x0006)) && (ioaddr+0x0006
) < 256) ? __outbc((0),(ioaddr+0x0006)) : __outb((0),(ioaddr
+0x0006)))
;
388 while (!SCB_complete(rsst=inw(ioaddr+SCB_STATUS))((rsst=((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr
+0xc008) < 256) ? __inwc(ioaddr+0xc008) : __inw(ioaddr+0xc008
))&0x8000)!=0)
)
389 {
390 if (!--boguscount)
391 {
392 boguscount=200;
393 printk(KERN_WARNING"<4>" "%s: Reset timed out status %04x, retrying...\n",
394 dev->name,rsst);
395 outw(lp->tx_link,ioaddr+SCB_CBL)((__builtin_constant_p((ioaddr+0xc00c)) && (ioaddr+0xc00c
) < 256) ? __outwc((lp->tx_link),(ioaddr+0xc00c)) : __outw
((lp->tx_link),(ioaddr+0xc00c)))
;
396 outw(0,ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __outwc((0),(ioaddr+0xc008)) : __outw((0),(ioaddr
+0xc008)))
;
397 outw(SCB_CUstart,ioaddr+SCB_CMD)((__builtin_constant_p((ioaddr+0xc00a)) && (ioaddr+0xc00a
) < 256) ? __outwc((0x0100),(ioaddr+0xc00a)) : __outw((0x0100
),(ioaddr+0xc00a)))
;
398 outb(0,ioaddr+SIGNAL_CA)((__builtin_constant_p((ioaddr+0x0006)) && (ioaddr+0x0006
) < 256) ? __outbc((0),(ioaddr+0x0006)) : __outb((0),(ioaddr
+0x0006)))
;
399 }
400 }
401 dev->tbusy = 0;
402 mark_bh(NET_BH);
403 }
404 else
405 {
406 unsigned short status = inw(ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __inwc(ioaddr+0xc008) : __inw(ioaddr+0xc008))
;
407 if (SCB_CUdead(status)((status&0x2000)!=0))
408 {
409 unsigned short txstatus = eexp_hw_lasttxstat(dev);
410 printk(KERN_WARNING"<4>" "%s: Transmit timed out, CU not active status %04x %04x, restarting...\n",
411 dev->name, status, txstatus);
412 eexp_hw_txrestart(dev);
413 }
414 else
415 {
416 unsigned short txstatus = eexp_hw_lasttxstat(dev);
417 if (dev->tbusy && !txstatus)
418 {
419 printk(KERN_WARNING"<4>" "%s: CU wedged, status %04x %04x, resetting...\n",
420 dev->name,status,txstatus);
421 eexp_hw_init586(dev);
422 dev->tbusy = 0;
423 mark_bh(NET_BH);
424 }
425 }
426 }
427 }
428 }
429 else
430 {
431 if ((jiffies-lp->init_time)>10)
432 {
433 unsigned short status = inw(ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __inwc(ioaddr+0xc008) : __inw(ioaddr+0xc008))
;
434 printk(KERN_WARNING"<4>" "%s: i82586 startup timed out, status %04x, resetting...\n",
435 dev->name, status);
436 eexp_hw_init586(dev);
437 dev->tbusy = 0;
438 mark_bh(NET_BH);
439 }
440 }
441 }
442
443 if (buf==NULL((void *) 0))
444 {
445 unsigned short status = inw(ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __inwc(ioaddr+0xc008) : __inw(ioaddr+0xc008))
;
446 unsigned short txstatus = eexp_hw_lasttxstat(dev);
447 if (SCB_CUdead(status)((status&0x2000)!=0))
448 {
449 printk(KERN_WARNING"<4>" "%s: CU has died! status %04x %04x, attempting to restart...\n",
450 dev->name, status, txstatus);
451 lp->stats.tx_errors++;
452 eexp_hw_txrestart(dev);
453 }
454 dev_tint(dev);
455 outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0x08|irqrmap[dev->irq]),(ioaddr+0x0007
)) : __outb((0x08|irqrmap[dev->irq]),(ioaddr+0x0007)))
;
456 dev_kfree_skb(buf, FREE_WRITE0);
457 return 0;
458 }
459
460 if (set_bit(0,(void *)&dev->tbusy))
461 {
462 lp->stats.tx_dropped++;
463 }
464 else
465 {
466 unsigned short length = (ETH_ZLEN60 < buf->len) ? buf->len : ETH_ZLEN60;
467 unsigned short *data = (unsigned short *)buf->data;
468
469 outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0x00|irqrmap[dev->irq]),(ioaddr+0x0007
)) : __outb((0x00|irqrmap[dev->irq]),(ioaddr+0x0007)))
;
470 eexp_hw_tx(dev,data,length);
471 outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0x08|irqrmap[dev->irq]),(ioaddr+0x0007
)) : __outb((0x08|irqrmap[dev->irq]),(ioaddr+0x0007)))
;
472 }
473 dev_kfree_skb(buf, FREE_WRITE0);
474 outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0x08|irqrmap[dev->irq]),(ioaddr+0x0007
)) : __outb((0x08|irqrmap[dev->irq]),(ioaddr+0x0007)))
;
475 return 0;
476}
477
478/*
479 * Handle an EtherExpress interrupt
480 * If we've finished initializing, start the RU and CU up.
481 * If we've already started, reap tx buffers, handle any received packets,
482 * check to make sure we've not become wedged.
483 */
484
485static void eexp_irq(int irq, void *dev_info, struct pt_regs *regs)
486{
487 struct devicelinux_device *dev = irq2dev_map[irq];
488 struct net_local *lp;
489 unsigned short ioaddr,status,ack_cmd;
490 unsigned short old_rp,old_wp;
491
492 if (dev==NULL((void *) 0))
493 {
494 printk(KERN_WARNING"<4>" "net_interrupt(): irq %d for unknown device caught by EExpress\n",irq);
495 return;
496 }
497
498#if NET_DEBUG4 > 6
499 printk(KERN_DEBUG"<7>" "%s: interrupt\n", dev->name);
500#endif
501
502 dev->interrupt = 1; /* should this be reset on exit? */
503
504 lp = (struct net_local *)dev->priv;
505 ioaddr = dev->base_addr;
506
507 outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0x00|irqrmap[irq]),(ioaddr+0x0007)) : __outb
((0x00|irqrmap[irq]),(ioaddr+0x0007)))
;
508 old_rp = inw(ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __inwc(ioaddr+0x0004) : __inw(ioaddr+0x0004))
;
509 old_wp = inw(ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __inwc(ioaddr+0x0002) : __inw(ioaddr+0x0002))
;
510 status = inw(ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __inwc(ioaddr+0xc008) : __inw(ioaddr+0xc008))
;
511 ack_cmd = SCB_ack(status)(status & 0xf000);
512
513 if (PRIV(dev)((struct net_local *)(dev)->priv)->started==0 && SCB_complete(status)((status&0x8000)!=0))
514 {
515#if NET_DEBUG4 > 4
516 printk(KERN_DEBUG"<7>" "%s: SCBcomplete event received\n", dev->name);
517#endif
518 while (SCB_CUstat(status)((status&0x0300)>>8)==2)
519 status = inw_p(ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __inwc_p(ioaddr+0xc008) : __inw_p(ioaddr+0xc008
))
;
520#if NET_DEBUG4 > 4
521 printk(KERN_DEBUG"<7>" "%s: CU went non-active (status = %08x)\n", dev->name, status);
522#endif
523 PRIV(dev)((struct net_local *)(dev)->priv)->started=1;
524 outw_p(lp->tx_link,ioaddr+SCB_CBL)((__builtin_constant_p((ioaddr+0xc00c)) && (ioaddr+0xc00c
) < 256) ? __outwc_p((lp->tx_link),(ioaddr+0xc00c)) : __outw_p
((lp->tx_link),(ioaddr+0xc00c)))
;
525 outw_p(PRIV(dev)->rx_buf_start,ioaddr+SCB_RFA)((__builtin_constant_p((ioaddr+0xc00e)) && (ioaddr+0xc00e
) < 256) ? __outwc_p((((struct net_local *)(dev)->priv)
->rx_buf_start),(ioaddr+0xc00e)) : __outw_p((((struct net_local
*)(dev)->priv)->rx_buf_start),(ioaddr+0xc00e)))
;
526 ack_cmd |= SCB_CUstart0x0100 | SCB_RUstart0x0010;
527 }
528 else if (PRIV(dev)((struct net_local *)(dev)->priv)->started)
529 {
530 unsigned short txstatus;
531 txstatus = eexp_hw_lasttxstat(dev);
Value stored to 'txstatus' is never read
532 }
533
534 if (SCB_rxdframe(status)((status&0x4000)!=0))
535 {
536 eexp_hw_rx(dev);
537 }
538
539 if ((PRIV(dev)((struct net_local *)(dev)->priv)->started&2)!=0 && SCB_RUstat(status)((status&0x0070)>>4)!=4)
540 {
541 printk(KERN_WARNING"<4>" "%s: RU stopped status %04x, restarting...\n",
542 dev->name,status);
543 lp->stats.rx_errors++;
544 eexp_hw_rxinit(dev);
545 outw(PRIV(dev)->rx_buf_start,ioaddr+SCB_RFA)((__builtin_constant_p((ioaddr+0xc00e)) && (ioaddr+0xc00e
) < 256) ? __outwc((((struct net_local *)(dev)->priv)->
rx_buf_start),(ioaddr+0xc00e)) : __outw((((struct net_local *
)(dev)->priv)->rx_buf_start),(ioaddr+0xc00e)))
;
546 ack_cmd |= SCB_RUstart0x0010;
547 }
548 else if (PRIV(dev)((struct net_local *)(dev)->priv)->started==1 && SCB_RUstat(status)((status&0x0070)>>4)==4)
549 PRIV(dev)((struct net_local *)(dev)->priv)->started|=2;
550
551 outw(ack_cmd,ioaddr+SCB_CMD)((__builtin_constant_p((ioaddr+0xc00a)) && (ioaddr+0xc00a
) < 256) ? __outwc((ack_cmd),(ioaddr+0xc00a)) : __outw((ack_cmd
),(ioaddr+0xc00a)))
;
552 outb(0,ioaddr+SIGNAL_CA)((__builtin_constant_p((ioaddr+0x0006)) && (ioaddr+0x0006
) < 256) ? __outbc((0),(ioaddr+0x0006)) : __outb((0),(ioaddr
+0x0006)))
;
553 outw(old_rp,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((old_rp),(ioaddr+0x0004)) : __outw((old_rp
),(ioaddr+0x0004)))
;
554 outw(old_wp,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((old_wp),(ioaddr+0x0002)) : __outw((old_wp
),(ioaddr+0x0002)))
;
555 outb(SIRQ_en|irqrmap[irq],ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0x08|irqrmap[irq]),(ioaddr+0x0007)) : __outb
((0x08|irqrmap[irq]),(ioaddr+0x0007)))
;
556 dev->interrupt = 0;
557#if NET_DEBUG4 > 6
558 printk(KERN_DEBUG"<7>" "%s: leaving eexp_irq()\n", dev->name);
559#endif
560 return;
561}
562
563/*
564 * Hardware access functions
565 */
566
567/*
568 * Check all the receive buffers, and hand any received packets
569 * to the upper levels. Basic sanity check on each frame
570 * descriptor
571 */
572
573static void eexp_hw_rx(struct devicelinux_device *dev)
574{
575 struct net_local *lp = (struct net_local *)dev->priv;
576 unsigned short ioaddr = dev->base_addr;
577 unsigned short old_wp = inw(ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __inwc(ioaddr+0x0002) : __inw(ioaddr+0x0002))
;
578 unsigned short old_rp = inw(ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __inwc(ioaddr+0x0004) : __inw(ioaddr+0x0004))
;
579 unsigned short rx_block = lp->rx_first;
580 unsigned short boguscount = lp->num_rx_bufs;
581
582#if NET_DEBUG4 > 6
583 printk(KERN_DEBUG"<7>" "%s: eexp_hw_rx()\n", dev->name);
584#endif
585
586 while (outw(rx_block,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((rx_block),(ioaddr+0x0004)) : __outw((rx_block
),(ioaddr+0x0004)))
,boguscount--)
587 {
588 unsigned short status = inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
;
589 unsigned short rfd_cmd = inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
;
590 unsigned short rx_next = inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
;
591 unsigned short pbuf = inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
;
592 unsigned short pkt_len;
593
594 if (FD_Done(status)((status&0x8000)!=0))
595 {
596 outw(pbuf,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((pbuf),(ioaddr+0x0004)) : __outw((pbuf)
,(ioaddr+0x0004)))
;
597 pkt_len = inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
;
598
599 if (rfd_cmd!=0x0000 || pbuf!=rx_block+0x16
600 || (pkt_len & 0xc000)!=0xc000)
601 {
602 printk(KERN_WARNING"<4>" "%s: Rx frame at %04x corrupted, status %04x, cmd %04x, "
603 "next %04x, pbuf %04x, len %04x\n",dev->name,rx_block,
604 status,rfd_cmd,rx_next,pbuf,pkt_len);
605 boguscount++;
606 continue;
607 }
608 else if (!FD_OK(status)((status&0x2000)!=0))
609 {
610 lp->stats.rx_errors++;
611 if (FD_CRC(status)((status&0x0800)!=0))
612 lp->stats.rx_crc_errors++;
613 if (FD_Align(status)((status&0x0400)!=0))
614 lp->stats.rx_frame_errors++;
615 if (FD_Resrc(status)((status&0x0200)!=0))
616 lp->stats.rx_fifo_errors++;
617 if (FD_DMA(status)((status&0x0100)!=0))
618 lp->stats.rx_over_errors++;
619 if (FD_Short(status)((status&0x0080)!=0))
620 lp->stats.rx_length_errors++;
621 }
622 else
623 {
624 struct sk_buff *skb;
625 pkt_len &= 0x3fff;
626 skb = dev_alloc_skb(pkt_len+16);
627 if (skb == NULL((void *) 0))
628 {
629 printk(KERN_WARNING"<4>" "%s: Memory squeeze, dropping packet\n",dev->name);
630 lp->stats.rx_dropped++;
631 break;
632 }
633 skb->dev = dev;
634 skb_reserve(skb, 2);
635 outw(pbuf+10,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((pbuf+10),(ioaddr+0x0004)) : __outw((pbuf
+10),(ioaddr+0x0004)))
;
636 insw(ioaddr,skb_put(skb,pkt_len),(pkt_len+1)>>1);
637 skb->protocol = eth_type_trans(skb,dev)((unsigned short)0);
638 netif_rx(skb);
639 lp->stats.rx_packets++;
640 }
641 outw(rx_block,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((rx_block),(ioaddr+0x0002)) : __outw((rx_block
),(ioaddr+0x0002)))
;
642 outw(0x0000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x0000),(ioaddr)) : __outw((0x0000),(ioaddr)))
;
643 outw(0x0000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x0000),(ioaddr)) : __outw((0x0000),(ioaddr)))
;
644 }
645 rx_block = rx_next;
646 }
647 outw(old_rp,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((old_rp),(ioaddr+0x0004)) : __outw((old_rp
),(ioaddr+0x0004)))
;
648 outw(old_wp,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((old_wp),(ioaddr+0x0002)) : __outw((old_wp
),(ioaddr+0x0002)))
;
649}
650
651/*
652 * Hand a packet to the card for transmission
653 * If we get here, we MUST have already checked
654 * to make sure there is room in the transmit
655 * buffer region
656 */
657
658static void eexp_hw_tx(struct devicelinux_device *dev, unsigned short *buf, unsigned short len)
659{
660 struct net_local *lp = (struct net_local *)dev->priv;
661 unsigned short ioaddr = dev->base_addr;
662 unsigned short old_wp = inw(ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __inwc(ioaddr+0x0002) : __inw(ioaddr+0x0002))
;
663
664 outw(lp->tx_head,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((lp->tx_head),(ioaddr+0x0002)) : __outw
((lp->tx_head),(ioaddr+0x0002)))
;
665 outw(0x0000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x0000),(ioaddr)) : __outw((0x0000),(ioaddr)))
;
666 outw(Cmd_INT|Cmd_Xmit,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x2000|0x0004),(ioaddr)) : __outw((0x2000|0x0004
),(ioaddr)))
;
667 outw(lp->tx_head+0x08,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((lp->tx_head+0x08),(ioaddr)) : __outw((lp->
tx_head+0x08),(ioaddr)))
;
668 outw(lp->tx_head+0x0e,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((lp->tx_head+0x0e),(ioaddr)) : __outw((lp->
tx_head+0x0e),(ioaddr)))
;
669 outw(0x0000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x0000),(ioaddr)) : __outw((0x0000),(ioaddr)))
;
670 outw(0x0000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x0000),(ioaddr)) : __outw((0x0000),(ioaddr)))
;
671 outw(lp->tx_head+0x08,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((lp->tx_head+0x08),(ioaddr)) : __outw((lp->
tx_head+0x08),(ioaddr)))
;
672 outw(0x8000|len,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x8000|len),(ioaddr)) : __outw((0x8000|len),(ioaddr
)))
;
673 outw(-1,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((-1),(ioaddr)) : __outw((-1),(ioaddr)))
;
674 outw(lp->tx_head+0x16,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((lp->tx_head+0x16),(ioaddr)) : __outw((lp->
tx_head+0x16),(ioaddr)))
;
675 outw(0,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0),(ioaddr)) : __outw((0),(ioaddr)))
;
676 outsw(ioaddr,buf,(len+1)>>1);
677 outw(lp->tx_tail+0x0c,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((lp->tx_tail+0x0c),(ioaddr+0x0002)) :
__outw((lp->tx_tail+0x0c),(ioaddr+0x0002)))
;
678 outw(lp->tx_head,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((lp->tx_head),(ioaddr)) : __outw((lp->tx_head
),(ioaddr)))
;
679 dev->trans_start = jiffies;
680 lp->tx_tail = lp->tx_head;
681 if (lp->tx_head==TX_BUF_START0x0100+((lp->num_tx_bufs-1)*TX_BUF_SIZE((24 +1514 +31)&~0x1f)))
682 lp->tx_head = TX_BUF_START0x0100;
683 else
684 lp->tx_head += TX_BUF_SIZE((24 +1514 +31)&~0x1f);
685 if (lp->tx_head != lp->tx_reap)
686 dev->tbusy = 0;
687 outw(old_wp,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((old_wp),(ioaddr+0x0002)) : __outw((old_wp
),(ioaddr+0x0002)))
;
688}
689
690/*
691 * Sanity check the suspected EtherExpress card
692 * Read hardware address, reset card, size memory and
693 * initialize buffer memory pointers. These should
694 * probably be held in dev->priv, in case someone has 2
695 * differently configured cards in their box (Arghhh!)
696 */
697
698static int eexp_hw_probe(struct devicelinux_device *dev, unsigned short ioaddr)
699{
700 unsigned short hw_addr[3];
701 int i;
702 unsigned char *chw_addr = (unsigned char *)hw_addr;
703
704 printk("%s: EtherExpress at %#x, ",dev->name,ioaddr);
705
706 hw_addr[0] = eexp_hw_readeeprom(ioaddr,2);
707 hw_addr[1] = eexp_hw_readeeprom(ioaddr,3);
708 hw_addr[2] = eexp_hw_readeeprom(ioaddr,4);
709
710 /* Standard Address or Compaq LTE Address */
711 if (!((hw_addr[2]==0x00aa && ((hw_addr[1] & 0xff00)==0x0000)) ||
712 (hw_addr[2]==0x0080 && ((hw_addr[1] & 0xff00)==0x5F00))))
713 {
714 printk("rejected: invalid address %04x%04x%04x\n",
715 hw_addr[2],hw_addr[1],hw_addr[0]);
716 return -ENODEV19;
717 }
718
719 dev->base_addr = ioaddr;
720 for ( i=0 ; i<6 ; i++ )
721 dev->dev_addr[i] = chw_addr[5-i];
722
723 {
724 char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0};
725 char *ifmap[]={"AUI", "BNC", "10baseT"};
726 enum iftype {AUI=0, BNC=1, TP=2};
727 unsigned short setupval = eexp_hw_readeeprom(ioaddr,0);
728
729 dev->irq = irqmap[setupval>>13];
730 dev->if_port = !(setupval & 0x1000) ? AUI :
731 eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TP : BNC;
732
733 printk("IRQ %d, Interface %s, ",dev->irq,ifmap[dev->if_port]);
734
735 outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0x00|irqrmap[dev->irq]),(ioaddr+0x0007
)) : __outb((0x00|irqrmap[dev->irq]),(ioaddr+0x0007)))
;
736 outb(0,ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0),(ioaddr+0x0007)) : __outb((0),(ioaddr
+0x0007)))
;
737 }
738
739 dev->priv = kmalloclinux_kmalloc(sizeof(struct net_local), GFP_KERNEL0x03);
740 if (!dev->priv)
741 return -ENOMEM12;
742
743 memset(dev->priv, 0, sizeof(struct net_local))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(struct
net_local))) ? __constant_c_and_count_memset(((dev->priv)
),((0x01010101UL*(unsigned char)(0))),((sizeof(struct net_local
)))) : __constant_c_memset(((dev->priv)),((0x01010101UL*(unsigned
char)(0))),((sizeof(struct net_local))))) : (__builtin_constant_p
((sizeof(struct net_local))) ? __memset_generic((((dev->priv
))),(((0))),(((sizeof(struct net_local))))) : __memset_generic
(((dev->priv)),((0)),((sizeof(struct net_local))))))
;
744
745 eexp_hw_ASICrst(dev);
746
747 {
748 unsigned short i586mso = 0x023e;
749 unsigned short old_wp,old_rp,old_a0,old_a1;
750 unsigned short a0_0,a1_0,a0_1,a1_1;
751
752 old_wp = inw(ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __inwc(ioaddr+0x0002) : __inw(ioaddr+0x0002))
;
753 old_rp = inw(ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __inwc(ioaddr+0x0004) : __inw(ioaddr+0x0004))
;
754 outw(0x8000+i586mso,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((0x8000 +i586mso),(ioaddr+0x0004)) : __outw
((0x8000 +i586mso),(ioaddr+0x0004)))
;
755 old_a1 = inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
;
756 outw(i586mso,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((i586mso),(ioaddr+0x0004)) : __outw((i586mso
),(ioaddr+0x0004)))
;
757 old_a0 = inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
;
758 outw(i586mso,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((i586mso),(ioaddr+0x0002)) : __outw((i586mso
),(ioaddr+0x0002)))
;
759 outw(0x55aa,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x55aa),(ioaddr)) : __outw((0x55aa),(ioaddr)))
;
760 outw(i586mso,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((i586mso),(ioaddr+0x0004)) : __outw((i586mso
),(ioaddr+0x0004)))
;
761 a0_0 = inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
;
762 outw(0x8000+i586mso,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((0x8000 +i586mso),(ioaddr+0x0002)) : __outw
((0x8000 +i586mso),(ioaddr+0x0002)))
;
763 outw(0x5a5a,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x5a5a),(ioaddr)) : __outw((0x5a5a),(ioaddr)))
;
764 outw(0x8000+i586mso,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((0x8000 +i586mso),(ioaddr+0x0004)) : __outw
((0x8000 +i586mso),(ioaddr+0x0004)))
;
765 a1_0 = inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
;
766 outw(i586mso,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((i586mso),(ioaddr+0x0004)) : __outw((i586mso
),(ioaddr+0x0004)))
;
767 a0_1 = inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
;
768 outw(i586mso,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((i586mso),(ioaddr+0x0002)) : __outw((i586mso
),(ioaddr+0x0002)))
;
769 outw(0x1234,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x1234),(ioaddr)) : __outw((0x1234),(ioaddr)))
;
770 outw(0x8000+i586mso,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((0x8000 +i586mso),(ioaddr+0x0004)) : __outw
((0x8000 +i586mso),(ioaddr+0x0004)))
;
771 a1_1 = inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
;
772
773 if ((a0_0 != a0_1) || (a1_0 != a1_1) ||
774 (a1_0 != 0x5a5a) || (a0_0 != 0x55aa))
775 {
776 printk("32k\n");
777 PRIV(dev)((struct net_local *)(dev)->priv)->rx_buf_end = 0x7ff6;
778 PRIV(dev)((struct net_local *)(dev)->priv)->num_tx_bufs = 4;
779 }
780 else
781 {
782 printk("64k\n");
783 PRIV(dev)((struct net_local *)(dev)->priv)->num_tx_bufs = 8;
784 PRIV(dev)((struct net_local *)(dev)->priv)->rx_buf_start = TX_BUF_START0x0100 + (PRIV(dev)((struct net_local *)(dev)->priv)->num_tx_bufs*TX_BUF_SIZE((24 +1514 +31)&~0x1f));
785 PRIV(dev)((struct net_local *)(dev)->priv)->rx_buf_end = 0xfff6;
786 }
787
788 outw(0x8000+i586mso,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((0x8000 +i586mso),(ioaddr+0x0002)) : __outw
((0x8000 +i586mso),(ioaddr+0x0002)))
;
789 outw(old_a1,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((old_a1),(ioaddr)) : __outw((old_a1),(ioaddr)))
;
790 outw(i586mso,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((i586mso),(ioaddr+0x0002)) : __outw((i586mso
),(ioaddr+0x0002)))
;
791 outw(old_a0,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((old_a0),(ioaddr)) : __outw((old_a0),(ioaddr)))
;
792 outw(old_wp,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((old_wp),(ioaddr+0x0002)) : __outw((old_wp
),(ioaddr+0x0002)))
;
793 outw(old_rp,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((old_rp),(ioaddr+0x0004)) : __outw((old_rp
),(ioaddr+0x0004)))
;
794 }
795
796 if (net_debug)
797 printk(version);
798 dev->open = eexp_open;
799 dev->stop = eexp_close;
800 dev->hard_start_xmit = eexp_xmit;
801 dev->get_stats = eexp_stats;
802 dev->set_multicast_list = &eexp_set_multicast;
803 ether_setup(dev);
804 return 0;
805}
806
807/*
808 * Read a word from eeprom location (0-63?)
809 */
810static unsigned short eexp_hw_readeeprom(unsigned short ioaddr, unsigned char location)
811{
812 unsigned short cmd = 0x180|(location&0x7f);
813 unsigned short rval = 0,wval = EC_CS0x02|i586_RST0x80;
814 int i;
815
816 outb(EC_CS|i586_RST,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((0x02|0x80),(ioaddr+0x000e)) : __outb((
0x02|0x80),(ioaddr+0x000e)))
;
817 for ( i=0x100 ; i ; i>>=1 )
818 {
819 if (cmd&i)
820 wval |= EC_Wr0x04;
821 else
822 wval &= ~EC_Wr0x04;
823
824 outb(wval,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((wval),(ioaddr+0x000e)) : __outb((wval)
,(ioaddr+0x000e)))
;
825 outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((wval|0x01),(ioaddr+0x000e)) : __outb((
wval|0x01),(ioaddr+0x000e)))
;
826 eeprom_delay(){ int _i = 40; while (--_i>0) { __asm__ __volatile__("outb %al,$0x80"
); }}
;
827 outb(wval,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((wval),(ioaddr+0x000e)) : __outb((wval)
,(ioaddr+0x000e)))
;
828 eeprom_delay(){ int _i = 40; while (--_i>0) { __asm__ __volatile__("outb %al,$0x80"
); }}
;
829 }
830 wval &= ~EC_Wr0x04;
831 outb(wval,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((wval),(ioaddr+0x000e)) : __outb((wval)
,(ioaddr+0x000e)))
;
832 for ( i=0x8000 ; i ; i>>=1 )
833 {
834 outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((wval|0x01),(ioaddr+0x000e)) : __outb((
wval|0x01),(ioaddr+0x000e)))
;
835 eeprom_delay(){ int _i = 40; while (--_i>0) { __asm__ __volatile__("outb %al,$0x80"
); }}
;
836 if (inb(ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __inbc(ioaddr+0x000e) : __inb(ioaddr+0x000e))
&EC_Rd0x08)
837 rval |= i;
838 outb(wval,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((wval),(ioaddr+0x000e)) : __outb((wval)
,(ioaddr+0x000e)))
;
839 eeprom_delay(){ int _i = 40; while (--_i>0) { __asm__ __volatile__("outb %al,$0x80"
); }}
;
840 }
841 wval &= ~EC_CS0x02;
842 outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((wval|0x01),(ioaddr+0x000e)) : __outb((
wval|0x01),(ioaddr+0x000e)))
;
843 eeprom_delay(){ int _i = 40; while (--_i>0) { __asm__ __volatile__("outb %al,$0x80"
); }}
;
844 outb(wval,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((wval),(ioaddr+0x000e)) : __outb((wval)
,(ioaddr+0x000e)))
;
845 eeprom_delay(){ int _i = 40; while (--_i>0) { __asm__ __volatile__("outb %al,$0x80"
); }}
;
846 return rval;
847}
848
849/*
850 * Reap tx buffers and return last transmit status.
851 * if ==0 then either:
852 * a) we're not transmitting anything, so why are we here?
853 * b) we've died.
854 * otherwise, Stat_Busy(return) means we've still got some packets
855 * to transmit, Stat_Done(return) means our buffers should be empty
856 * again
857 */
858
859static unsigned short eexp_hw_lasttxstat(struct devicelinux_device *dev)
860{
861 struct net_local *lp = (struct net_local *)dev->priv;
862 unsigned short ioaddr = dev->base_addr;
863 unsigned short old_rp = inw(ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __inwc(ioaddr+0x0004) : __inw(ioaddr+0x0004))
;
864 unsigned short old_wp = inw(ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __inwc(ioaddr+0x0002) : __inw(ioaddr+0x0002))
;
865 unsigned short tx_block = lp->tx_reap;
866 unsigned short status;
867
868 if (!test_bit(0,(void *)&dev->tbusy) && lp->tx_head==lp->tx_reap)
869 return 0x0000;
870
871 do
872 {
873 outw(tx_block,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((tx_block),(ioaddr+0x0004)) : __outw((tx_block
),(ioaddr+0x0004)))
;
874 status = inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
;
875 if (!Stat_Done(status)((status&0x8000)!=0))
876 {
877 lp->tx_link = tx_block;
878 outw(old_rp,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((old_rp),(ioaddr+0x0004)) : __outw((old_rp
),(ioaddr+0x0004)))
;
879 outw(old_wp,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((old_wp),(ioaddr+0x0002)) : __outw((old_wp
),(ioaddr+0x0002)))
;
880 return status;
881 }
882 else
883 {
884 lp->last_tx_restart = 0;
885 lp->stats.collisions += Stat_NoColl(status)(status&0x000f);
886 if (!Stat_OK(status)((status&0x2000)!=0))
887 {
888 if (Stat_Abort(status)((status&0x1000)!=0))
889 lp->stats.tx_aborted_errors++;
890 if (Stat_TNoCar(status)((status&0x0400)!=0) || Stat_TNoCTS(status)((status&0x0200)!=0))
891 lp->stats.tx_carrier_errors++;
892 if (Stat_TNoDMA(status)((status&0x0100)!=0))
893 lp->stats.tx_fifo_errors++;
894 }
895 else
896 lp->stats.tx_packets++;
897 }
898 if (tx_block == TX_BUF_START0x0100+((lp->num_tx_bufs-1)*TX_BUF_SIZE((24 +1514 +31)&~0x1f)))
899 lp->tx_reap = tx_block = TX_BUF_START0x0100;
900 else
901 lp->tx_reap = tx_block += TX_BUF_SIZE((24 +1514 +31)&~0x1f);
902 dev->tbusy = 0;
903 mark_bh(NET_BH);
904 }
905 while (lp->tx_reap != lp->tx_head);
906
907 lp->tx_link = lp->tx_tail + 0x08;
908 outw(old_rp,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((old_rp),(ioaddr+0x0004)) : __outw((old_rp
),(ioaddr+0x0004)))
;
909 outw(old_wp,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((old_wp),(ioaddr+0x0002)) : __outw((old_wp
),(ioaddr+0x0002)))
;
910
911 return status;
912}
913
914/*
915 * This should never happen. It is called when some higher
916 * routine detects the CU has stopped, to try to restart
917 * it from the last packet we knew we were working on,
918 * or the idle loop if we had finished for the time.
919 */
920
921static void eexp_hw_txrestart(struct devicelinux_device *dev)
922{
923 struct net_local *lp = (struct net_local *)dev->priv;
924 unsigned short ioaddr = dev->base_addr;
925
926 lp->last_tx_restart = lp->tx_link;
927 outw(lp->tx_link,ioaddr+SCB_CBL)((__builtin_constant_p((ioaddr+0xc00c)) && (ioaddr+0xc00c
) < 256) ? __outwc((lp->tx_link),(ioaddr+0xc00c)) : __outw
((lp->tx_link),(ioaddr+0xc00c)))
;
928 outw(SCB_CUstart,ioaddr+SCB_CMD)((__builtin_constant_p((ioaddr+0xc00a)) && (ioaddr+0xc00a
) < 256) ? __outwc((0x0100),(ioaddr+0xc00a)) : __outw((0x0100
),(ioaddr+0xc00a)))
;
929 outw(0,ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __outwc((0),(ioaddr+0xc008)) : __outw((0),(ioaddr
+0xc008)))
;
930 outb(0,ioaddr+SIGNAL_CA)((__builtin_constant_p((ioaddr+0x0006)) && (ioaddr+0x0006
) < 256) ? __outbc((0),(ioaddr+0x0006)) : __outb((0),(ioaddr
+0x0006)))
;
931
932 {
933 unsigned short boguscount=50,failcount=5;
934 while (!inw(ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __inwc(ioaddr+0xc008) : __inw(ioaddr+0xc008))
)
935 {
936 if (!--boguscount)
937 {
938 if (--failcount)
939 {
940 printk(KERN_WARNING"<4>" "%s: CU start timed out, status %04x, cmd %04x\n",
941 dev->name, inw(ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __inwc(ioaddr+0xc008) : __inw(ioaddr+0xc008))
, inw(ioaddr+SCB_CMD)((__builtin_constant_p((ioaddr+0xc00a)) && (ioaddr+0xc00a
) < 256) ? __inwc(ioaddr+0xc00a) : __inw(ioaddr+0xc00a))
);
942 outw(lp->tx_link,ioaddr+SCB_CBL)((__builtin_constant_p((ioaddr+0xc00c)) && (ioaddr+0xc00c
) < 256) ? __outwc((lp->tx_link),(ioaddr+0xc00c)) : __outw
((lp->tx_link),(ioaddr+0xc00c)))
;
943 outw(0,ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __outwc((0),(ioaddr+0xc008)) : __outw((0),(ioaddr
+0xc008)))
;
944 outw(SCB_CUstart,ioaddr+SCB_CMD)((__builtin_constant_p((ioaddr+0xc00a)) && (ioaddr+0xc00a
) < 256) ? __outwc((0x0100),(ioaddr+0xc00a)) : __outw((0x0100
),(ioaddr+0xc00a)))
;
945 outb(0,ioaddr+SIGNAL_CA)((__builtin_constant_p((ioaddr+0x0006)) && (ioaddr+0x0006
) < 256) ? __outbc((0),(ioaddr+0x0006)) : __outb((0),(ioaddr
+0x0006)))
;
946 boguscount = 100;
947 }
948 else
949 {
950 printk(KERN_WARNING"<4>" "%s: Failed to restart CU, resetting board...\n",dev->name);
951 eexp_hw_init586(dev);
952 dev->tbusy = 0;
953 mark_bh(NET_BH);
954 return;
955 }
956 }
957 }
958 }
959}
960
961/*
962 * Writes down the list of transmit buffers into card
963 * memory. Initial separate, repeated transmits link
964 * them into a circular list, such that the CU can
965 * be constantly active, and unlink them as we reap
966 * transmitted packet buffers, so the CU doesn't loop
967 * and endlessly transmit packets. (Try hacking the driver
968 * to send continuous broadcast messages, say ARP requests
969 * on a subnet with Windows boxes running on Novell and
970 * LAN Workplace with EMM386. Amusing to watch them all die
971 * horribly leaving the Linux boxes up!)
972 */
973
974static void eexp_hw_txinit(struct devicelinux_device *dev)
975{
976 struct net_local *lp = (struct net_local *)dev->priv;
977 unsigned short ioaddr = dev->base_addr;
978 unsigned short old_wp = inw(ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __inwc(ioaddr+0x0002) : __inw(ioaddr+0x0002))
;
979 unsigned short tx_block = TX_BUF_START0x0100;
980 unsigned short curtbuf;
981
982 for ( curtbuf=0 ; curtbuf<lp->num_tx_bufs ; curtbuf++ )
983 {
984 outw(tx_block,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((tx_block),(ioaddr+0x0002)) : __outw((tx_block
),(ioaddr+0x0002)))
;
985 outw(0x0000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x0000),(ioaddr)) : __outw((0x0000),(ioaddr)))
;
986 outw(Cmd_INT|Cmd_Xmit,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x2000|0x0004),(ioaddr)) : __outw((0x2000|0x0004
),(ioaddr)))
;
987 outw(tx_block+0x08,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((tx_block+0x08),(ioaddr)) : __outw((tx_block+0x08
),(ioaddr)))
;
988 outw(tx_block+0x0e,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((tx_block+0x0e),(ioaddr)) : __outw((tx_block+0x0e
),(ioaddr)))
;
989 outw(0x0000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x0000),(ioaddr)) : __outw((0x0000),(ioaddr)))
;
990 outw(0x0000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x0000),(ioaddr)) : __outw((0x0000),(ioaddr)))
;
991 outw(tx_block+0x08,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((tx_block+0x08),(ioaddr)) : __outw((tx_block+0x08
),(ioaddr)))
;
992 outw(0x8000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x8000),(ioaddr)) : __outw((0x8000),(ioaddr)))
;
993 outw(-1,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((-1),(ioaddr)) : __outw((-1),(ioaddr)))
;
994 outw(tx_block+0x16,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((tx_block+0x16),(ioaddr)) : __outw((tx_block+0x16
),(ioaddr)))
;
995 outw(0x0000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x0000),(ioaddr)) : __outw((0x0000),(ioaddr)))
;
996 tx_block += TX_BUF_SIZE((24 +1514 +31)&~0x1f);
997 }
998 lp->tx_head = TX_BUF_START0x0100;
999 lp->tx_reap = TX_BUF_START0x0100;
1000 lp->tx_tail = tx_block - TX_BUF_SIZE((24 +1514 +31)&~0x1f);
1001 lp->tx_link = lp->tx_tail + 0x08;
1002 lp->rx_buf_start = tx_block;
1003 outw(old_wp,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((old_wp),(ioaddr+0x0002)) : __outw((old_wp
),(ioaddr+0x0002)))
;
1004}
1005
1006/* is this a standard test pattern, or dbecker randomness? */
1007
1008unsigned short rx_words[] =
1009{
1010 0xfeed,0xf00d,0xf001,0x0505,0x2424,0x6565,0xdeaf
1011};
1012
1013/*
1014 * Write the circular list of receive buffer descriptors to
1015 * card memory. Note, we no longer mark the end of the list,
1016 * so if all the buffers fill up, the 82586 will loop until
1017 * we free one. This may sound dodgy, but it works, and
1018 * it makes the error detection in the interrupt handler
1019 * a lot simpler.
1020 */
1021
1022static void eexp_hw_rxinit(struct devicelinux_device *dev)
1023{
1024 struct net_local *lp = (struct net_local *)dev->priv;
1025 unsigned short ioaddr = dev->base_addr;
1026 unsigned short old_wp = inw(ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __inwc(ioaddr+0x0002) : __inw(ioaddr+0x0002))
;
1027 unsigned short rx_block = lp->rx_buf_start;
1028
1029 lp->num_rx_bufs = 0;
1030 lp->rx_first = rx_block;
1031 do
1032 {
1033 lp->num_rx_bufs++;
1034 outw(rx_block,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((rx_block),(ioaddr+0x0002)) : __outw((rx_block
),(ioaddr+0x0002)))
;
1035 outw(0x0000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x0000),(ioaddr)) : __outw((0x0000),(ioaddr)))
;
1036 outw(0x0000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x0000),(ioaddr)) : __outw((0x0000),(ioaddr)))
;
1037 outw(rx_block+RX_BUF_SIZE,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((rx_block+((32 +1514 +31)&~0x1f)),(ioaddr)) :
__outw((rx_block+((32 +1514 +31)&~0x1f)),(ioaddr)))
;
1038 outw(rx_block+0x16,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((rx_block+0x16),(ioaddr)) : __outw((rx_block+0x16
),(ioaddr)))
;
1039 outsw(ioaddr, rx_words, sizeof(rx_words)>>1);
1040 outw(0x8000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x8000),(ioaddr)) : __outw((0x8000),(ioaddr)))
;
1041 outw(-1,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((-1),(ioaddr)) : __outw((-1),(ioaddr)))
;
1042 outw(rx_block+0x20,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((rx_block+0x20),(ioaddr)) : __outw((rx_block+0x20
),(ioaddr)))
;
1043 outw(0x0000,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x0000),(ioaddr)) : __outw((0x0000),(ioaddr)))
;
1044 outw(0x8000|(RX_BUF_SIZE-0x20),ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0x8000|(((32 +1514 +31)&~0x1f)-0x20)),(ioaddr
)) : __outw((0x8000|(((32 +1514 +31)&~0x1f)-0x20)),(ioaddr
)))
;
1045 lp->rx_last = rx_block;
1046 rx_block += RX_BUF_SIZE((32 +1514 +31)&~0x1f);
1047 } while (rx_block <= lp->rx_buf_end-RX_BUF_SIZE((32 +1514 +31)&~0x1f));
1048
1049 outw(lp->rx_last+4,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((lp->rx_last+4),(ioaddr+0x0002)) : __outw
((lp->rx_last+4),(ioaddr+0x0002)))
;
1050 outw(lp->rx_first,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((lp->rx_first),(ioaddr)) : __outw((lp->rx_first
),(ioaddr)))
;
1051
1052 outw(old_wp,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((old_wp),(ioaddr+0x0002)) : __outw((old_wp
),(ioaddr+0x0002)))
;
1053}
1054
1055/*
1056 * Reset the 586, fill memory (including calls to
1057 * eexp_hw_[(rx)(tx)]init()) unreset, and start
1058 * the configuration sequence. We don't wait for this
1059 * to finish, but allow the interrupt handler to start
1060 * the CU and RU for us. We can't start the receive/
1061 * transmission system up before we know that the
1062 * hardware is configured correctly
1063 */
1064static void eexp_hw_init586(struct devicelinux_device *dev)
1065{
1066 struct net_local *lp = (struct net_local *)dev->priv;
1067 unsigned short ioaddr = dev->base_addr;
1068
1069#if NET_DEBUG4 > 6
1070 printk("%s: eexp_hw_init586()\n", dev->name);
1071#endif
1072
1073 lp->started = 0;
1074 set_loopback((__builtin_constant_p((ioaddr+0x000d)) && (ioaddr+0x000d
) < 256) ? __outbc((((__builtin_constant_p((ioaddr+0x000d)
) && (ioaddr+0x000d) < 256) ? __inbc(ioaddr+0x000d
) : __inb(ioaddr+0x000d))|0x02),(ioaddr+0x000d)) : __outb((((
__builtin_constant_p((ioaddr+0x000d)) && (ioaddr+0x000d
) < 256) ? __inbc(ioaddr+0x000d) : __inb(ioaddr+0x000d))|0x02
),(ioaddr+0x000d)))
;
1075
1076 outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0x00|irqrmap[dev->irq]),(ioaddr+0x0007
)) : __outb((0x00|irqrmap[dev->irq]),(ioaddr+0x0007)))
;
1077 outb_p(i586_RST,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc_p((0x80),(ioaddr+0x000e)) : __outb_p((0x80
),(ioaddr+0x000e)))
;
1078 udelay(2000)(__builtin_constant_p(2000) ? __const_udelay((2000) * 0x10c6ul
) : __udelay(2000))
; /* delay 20ms */
1079 {
1080 unsigned long ofs;
1081 for (ofs = 0; ofs < lp->rx_buf_end; ofs += 32) {
1082 unsigned long i;
1083 outw_p(ofs, ioaddr+SM_PTR)((__builtin_constant_p((ioaddr+0x0008)) && (ioaddr+0x0008
) < 256) ? __outwc_p((ofs),(ioaddr+0x0008)) : __outw_p((ofs
),(ioaddr+0x0008)))
;
1084 for (i = 0; i < 16; i++) {
1085 outw_p(0, ioaddr+SM_ADDR(i<<1))((__builtin_constant_p((ioaddr+(0x4000 +((i<<1&0x10
)<<10)+(i<<1&0xf)))) && (ioaddr+(0x4000
+((i<<1&0x10)<<10)+(i<<1&0xf))) <
256) ? __outwc_p((0),(ioaddr+(0x4000 +((i<<1&0x10)
<<10)+(i<<1&0xf)))) : __outw_p((0),(ioaddr+(0x4000
+((i<<1&0x10)<<10)+(i<<1&0xf)))))
;
1086 }
1087 }
1088 }
1089
1090 outw_p(lp->rx_buf_end,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc_p((lp->rx_buf_end),(ioaddr+0x0002)) :
__outw_p((lp->rx_buf_end),(ioaddr+0x0002)))
;
1091 start_code[28] = (dev->flags & IFF_PROMISC0x100)?(start_code[28] | 1):(start_code[28] & ~1);
1092 lp->promisc = dev->flags & IFF_PROMISC0x100;
1093 /* We may die here */
1094 outsw(ioaddr, start_code, sizeof(start_code)>>1);
1095 outw(CONF_HW_ADDR,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((0x0038),(ioaddr+0x0002)) : __outw((0x0038
),(ioaddr+0x0002)))
;
1096 outsw(ioaddr,dev->dev_addr,3);
1097 eexp_hw_txinit(dev);
1098 eexp_hw_rxinit(dev);
1099 outw(0,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((0),(ioaddr+0x0002)) : __outw((0),(ioaddr
+0x0002)))
;
1100 outw(1,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((1),(ioaddr)) : __outw((1),(ioaddr)))
;
1101 outb(0,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((0),(ioaddr+0x000e)) : __outb((0),(ioaddr
+0x000e)))
;
1102 outw(0,ioaddr+SCB_CMD)((__builtin_constant_p((ioaddr+0xc00a)) && (ioaddr+0xc00a
) < 256) ? __outwc((0),(ioaddr+0xc00a)) : __outw((0),(ioaddr
+0xc00a)))
;
1103 outb(0,ioaddr+SIGNAL_CA)((__builtin_constant_p((ioaddr+0x0006)) && (ioaddr+0x0006
) < 256) ? __outbc((0),(ioaddr+0x0006)) : __outb((0),(ioaddr
+0x0006)))
;
1104 {
1105 unsigned short rboguscount=50,rfailcount=5;
1106 while (outw(0,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((0),(ioaddr+0x0004)) : __outw((0),(ioaddr
+0x0004)))
,inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
)
1107 {
1108 if (!--rboguscount)
1109 {
1110 printk(KERN_WARNING"<4>" "%s: i82586 reset timed out, kicking...\n",
1111 dev->name);
1112 outw(0,ioaddr+SCB_CMD)((__builtin_constant_p((ioaddr+0xc00a)) && (ioaddr+0xc00a
) < 256) ? __outwc((0),(ioaddr+0xc00a)) : __outw((0),(ioaddr
+0xc00a)))
;
1113 outb(0,ioaddr+SIGNAL_CA)((__builtin_constant_p((ioaddr+0x0006)) && (ioaddr+0x0006
) < 256) ? __outbc((0),(ioaddr+0x0006)) : __outb((0),(ioaddr
+0x0006)))
;
1114 rboguscount = 100;
1115 if (!--rfailcount)
1116 {
1117 printk(KERN_WARNING"<4>" "%s: i82586 not responding, giving up.\n",
1118 dev->name);
1119 return;
1120 }
1121 }
1122 }
1123 }
1124
1125 outw(CONF_LINK,ioaddr+SCB_CBL)((__builtin_constant_p((ioaddr+0xc00c)) && (ioaddr+0xc00c
) < 256) ? __outwc((0x0020),(ioaddr+0xc00c)) : __outw((0x0020
),(ioaddr+0xc00c)))
;
1126 outw(0,ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __outwc((0),(ioaddr+0xc008)) : __outw((0),(ioaddr
+0xc008)))
;
1127 outw(0xf000|SCB_CUstart,ioaddr+SCB_CMD)((__builtin_constant_p((ioaddr+0xc00a)) && (ioaddr+0xc00a
) < 256) ? __outwc((0xf000|0x0100),(ioaddr+0xc00a)) : __outw
((0xf000|0x0100),(ioaddr+0xc00a)))
;
1128 outb(0,ioaddr+SIGNAL_CA)((__builtin_constant_p((ioaddr+0x0006)) && (ioaddr+0x0006
) < 256) ? __outbc((0),(ioaddr+0x0006)) : __outb((0),(ioaddr
+0x0006)))
;
1129 {
1130 unsigned short iboguscount=50,ifailcount=5;
1131 while (!inw(ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __inwc(ioaddr+0xc008) : __inw(ioaddr+0xc008))
)
1132 {
1133 if (!--iboguscount)
1134 {
1135 if (--ifailcount)
1136 {
1137 printk(KERN_WARNING"<4>" "%s: i82586 initialization timed out, status %04x, cmd %04x\n",
1138 dev->name, inw(ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __inwc(ioaddr+0xc008) : __inw(ioaddr+0xc008))
, inw(ioaddr+SCB_CMD)((__builtin_constant_p((ioaddr+0xc00a)) && (ioaddr+0xc00a
) < 256) ? __inwc(ioaddr+0xc00a) : __inw(ioaddr+0xc00a))
);
1139 outw(CONF_LINK,ioaddr+SCB_CBL)((__builtin_constant_p((ioaddr+0xc00c)) && (ioaddr+0xc00c
) < 256) ? __outwc((0x0020),(ioaddr+0xc00c)) : __outw((0x0020
),(ioaddr+0xc00c)))
;
1140 outw(0,ioaddr+SCB_STATUS)((__builtin_constant_p((ioaddr+0xc008)) && (ioaddr+0xc008
) < 256) ? __outwc((0),(ioaddr+0xc008)) : __outw((0),(ioaddr
+0xc008)))
;
1141 outw(0xf000|SCB_CUstart,ioaddr+SCB_CMD)((__builtin_constant_p((ioaddr+0xc00a)) && (ioaddr+0xc00a
) < 256) ? __outwc((0xf000|0x0100),(ioaddr+0xc00a)) : __outw
((0xf000|0x0100),(ioaddr+0xc00a)))
;
1142 outb(0,ioaddr+SIGNAL_CA)((__builtin_constant_p((ioaddr+0x0006)) && (ioaddr+0x0006
) < 256) ? __outbc((0),(ioaddr+0x0006)) : __outb((0),(ioaddr
+0x0006)))
;
1143 iboguscount = 100;
1144 }
1145 else
1146 {
1147 printk(KERN_WARNING"<4>" "%s: Failed to initialize i82586, giving up.\n",dev->name);
1148 return;
1149 }
1150 }
1151 }
1152 }
1153
1154 outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0x08|irqrmap[dev->irq]),(ioaddr+0x0007
)) : __outb((0x08|irqrmap[dev->irq]),(ioaddr+0x0007)))
;
1155 clear_loopback((__builtin_constant_p((ioaddr+0x000d)) && (ioaddr+0x000d
) < 256) ? __outbc((((__builtin_constant_p((ioaddr+0x000d)
) && (ioaddr+0x000d) < 256) ? __inbc(ioaddr+0x000d
) : __inb(ioaddr+0x000d))&0xfd),(ioaddr+0x000d)) : __outb
((((__builtin_constant_p((ioaddr+0x000d)) && (ioaddr+
0x000d) < 256) ? __inbc(ioaddr+0x000d) : __inb(ioaddr+0x000d
))&0xfd),(ioaddr+0x000d)))
;
1156 lp->init_time = jiffies;
1157#if NET_DEBUG4 > 6
1158 printk("%s: leaving eexp_hw_init586()\n", dev->name);
1159#endif
1160 return;
1161}
1162
1163/*
1164 * completely reset the EtherExpress hardware. We will most likely get
1165 * an interrupt during this whether we want one or not. It is best,
1166 * therefore, to call this while we don't have a request_irq() on.
1167 */
1168
1169static void eexp_hw_ASICrst(struct devicelinux_device *dev)
1170{
1171 unsigned short ioaddr = dev->base_addr;
1172 unsigned short wrval = 0x0001,succount=0,boguscount=500;
1173
1174 outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ)((__builtin_constant_p((ioaddr+0x0007)) && (ioaddr+0x0007
) < 256) ? __outbc((0x00|irqrmap[dev->irq]),(ioaddr+0x0007
)) : __outb((0x00|irqrmap[dev->irq]),(ioaddr+0x0007)))
;
1175
1176 PRIV(dev)((struct net_local *)(dev)->priv)->started = 0;
1177 outb(ASIC_RST|i586_RST,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((0x40|0x80),(ioaddr+0x000e)) : __outb((
0x40|0x80),(ioaddr+0x000e)))
;
1178 while (succount<20)
1179 {
1180 if (wrval == 0xffff)
1181 wrval = 0x0001;
1182 outw(0,ioaddr+WRITE_PTR)((__builtin_constant_p((ioaddr+0x0002)) && (ioaddr+0x0002
) < 256) ? __outwc((0),(ioaddr+0x0002)) : __outw((0),(ioaddr
+0x0002)))
;
1183 outw(wrval,ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((wrval),(ioaddr)) : __outw((wrval),(ioaddr)))
;
1184 outw(0,ioaddr+READ_PTR)((__builtin_constant_p((ioaddr+0x0004)) && (ioaddr+0x0004
) < 256) ? __outwc((0),(ioaddr+0x0004)) : __outw((0),(ioaddr
+0x0004)))
;
1185 if (wrval++ == inw(ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __inwc(ioaddr) : __inw(ioaddr))
)
1186 succount++;
1187 else
1188 {
1189 succount = 0;
1190 if (!boguscount--)
1191 {
1192 boguscount = 500;
1193 printk("%s: Having problems resetting EtherExpress ASIC, continuing...\n",
1194 dev->name);
1195 wrval = 0x0001;
1196 outb(ASIC_RST|i586_RST,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((0x40|0x80),(ioaddr+0x000e)) : __outb((
0x40|0x80),(ioaddr+0x000e)))
;
1197 }
1198 }
1199 }
1200 outb(i586_RST,ioaddr+EEPROM_Ctrl)((__builtin_constant_p((ioaddr+0x000e)) && (ioaddr+0x000e
) < 256) ? __outbc((0x80),(ioaddr+0x000e)) : __outb((0x80)
,(ioaddr+0x000e)))
;
1201}
1202
1203
1204/*
1205 * Set or clear the multicast filter for this adaptor.
1206 * We have to do a complete 586 restart for this to take effect.
1207 * At the moment only promiscuous mode is supported.
1208 */
1209static void
1210eexp_set_multicast(struct devicelinux_device *dev)
1211{
1212 if ((dev->flags & IFF_PROMISC0x100) != PRIV(dev)((struct net_local *)(dev)->priv)->promisc)
1213 eexp_hw_init586(dev);
1214}
1215
1216
1217/*
1218 * MODULE stuff
1219 */
1220#ifdef MODULE
1221
1222#define EEXP_MAX_CARDS 4 /* max number of cards to support */
1223#define NAMELEN 8 /* max length of dev->name (inc null) */
1224
1225static char namelist[NAMELEN * EEXP_MAX_CARDS] = { 0, };
1226
1227static struct devicelinux_device dev_eexp[EEXP_MAX_CARDS] =
1228{
1229 { NULL((void *) 0), /* will allocate dynamically */
1230 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL((void *) 0), express_probe },
1231};
1232
1233int irq[EEXP_MAX_CARDS] = {0, };
1234int io[EEXP_MAX_CARDS] = {0, };
1235
1236/* Ideally the user would give us io=, irq= for every card. If any parameters
1237 * are specified, we verify and then use them. If no parameters are given, we
1238 * autoprobe for one card only.
1239 */
1240int init_module(void)
1241{
1242 int this_dev, found = 0;
1243
1244 for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
1245 struct devicelinux_device *dev = &dev_eexp[this_dev];
1246 dev->name = namelist + (NAMELEN*this_dev);
1247 dev->irq = irq[this_dev];
1248 dev->base_addr = io[this_dev];
1249 if (io[this_dev] == 0) {
1250 if (this_dev) break;
1251 printk(KERN_NOTICE"<5>" "eexpress.c: Module autoprobe not recommended, give io=xx.\n");
1252 }
1253 if (register_netdev(dev) != 0) {
1254 printk(KERN_WARNING"<4>" "eexpress.c: Failed to register card at 0x%x.\n", io[this_dev]);
1255 if (found != 0) return 0;
1256 return -ENXIO6;
1257 }
1258 found++;
1259 }
1260 return 0;
1261}
1262
1263void cleanup_module(void)
1264{
1265 int this_dev;
1266
1267 for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
1268 struct devicelinux_device *dev = &dev_eexp[this_dev];
1269 if (dev->priv != NULL((void *) 0)) {
1270 kfreelinux_kfree(dev->priv);
1271 dev->priv = NULL((void *) 0);
1272 release_region(dev->base_addr, EEXP_IO_EXTENT16);
1273 unregister_netdev(dev);
1274 }
1275 }
1276}
1277#endif
1278
1279/*
1280 * Local Variables:
1281 * c-file-style: "linux"
1282 * tab-width: 8
1283 * compile-command: "gcc -D__KERNEL__ -I/discs/bibble/src/linux-1.3.69/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strength-reduce -pipe -m486 -DCPU=486 -DMODULE -c 3c505.c"
1284 * End:
1285 */