]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* Intel Professional Workstation/panther ethernet driver */ |
2 | /* lp486e.c: A panther 82596 ethernet driver for linux. */ | |
3 | /* | |
4 | History and copyrights: | |
5 | ||
6 | Driver skeleton | |
7 | Written 1993 by Donald Becker. | |
8 | Copyright 1993 United States Government as represented by the Director, | |
9 | National Security Agency. This software may only be used and | |
10 | distributed according to the terms of the GNU General Public License | |
11 | as modified by SRC, incorporated herein by reference. | |
12 | ||
13 | The author may be reached as [email protected], or C/O | |
14 | Scyld Computing Corporation | |
15 | 410 Severn Ave., Suite 210 | |
16 | Annapolis MD 21403 | |
17 | ||
18 | Apricot | |
19 | Written 1994 by Mark Evans. | |
20 | This driver is for the Apricot 82596 bus-master interface | |
21 | ||
22 | Modularised 12/94 Mark Evans | |
23 | ||
24 | Professional Workstation | |
25 | Derived from apricot.c by Ard van Breemen | |
26 | <[email protected]>|<[email protected]>|<[email protected]> | |
27 | ||
28 | Credits: | |
29 | Thanks to Murphy Software BV for letting me write this in their time. | |
30 | Well, actually, I get payed doing this... | |
31 | (Also: see http://www.murphy.nl for murphy, and my homepage ~ard for | |
32 | more information on the Professional Workstation) | |
33 | ||
34 | Present version | |
35 | [email protected] | |
36 | */ | |
37 | /* | |
38 | There are currently two motherboards that I know of in the | |
39 | professional workstation. The only one that I know is the | |
40 | intel panther motherboard. -- ard | |
41 | */ | |
42 | /* | |
43 | The pws is equipped with an intel 82596. This is a very intelligent controller | |
44 | which runs its own micro-code. Communication with the hostprocessor is done | |
45 | through linked lists of commands and buffers in the hostprocessors memory. | |
46 | A complete description of the 82596 is available from intel. Search for | |
47 | a file called "29021806.pdf". It is a complete description of the chip itself. | |
48 | To use it for the pws some additions are needed regarding generation of | |
49 | the PORT and CA signal, and the interrupt glue needed for a pc. | |
50 | I/O map: | |
51 | PORT SIZE ACTION MEANING | |
52 | 0xCB0 2 WRITE Lower 16 bits for PORT command | |
53 | 0xCB2 2 WRITE Upper 16 bits for PORT command, and issue of PORT command | |
54 | 0xCB4 1 WRITE Generation of CA signal | |
55 | 0xCB8 1 WRITE Clear interrupt glue | |
56 | All other communication is through memory! | |
57 | */ | |
58 | ||
1da177e4 LT |
59 | #include <linux/module.h> |
60 | #include <linux/init.h> | |
61 | #include <linux/delay.h> | |
62 | #include <linux/kernel.h> | |
63 | #include <linux/string.h> | |
64 | #include <linux/errno.h> | |
65 | #include <linux/ioport.h> | |
66 | #include <linux/slab.h> | |
67 | #include <linux/interrupt.h> | |
68 | #include <linux/netdevice.h> | |
69 | #include <linux/etherdevice.h> | |
70 | #include <linux/skbuff.h> | |
71 | #include <linux/bitops.h> | |
72 | ||
73 | #include <asm/io.h> | |
74 | #include <asm/dma.h> | |
75 | ||
76 | #define DRV_NAME "lp486e" | |
77 | ||
78 | /* debug print flags */ | |
79 | #define LOG_SRCDST 0x80000000 | |
80 | #define LOG_STATINT 0x40000000 | |
81 | #define LOG_STARTINT 0x20000000 | |
82 | ||
83 | #define i596_debug debug | |
84 | ||
85 | static int i596_debug = 0; | |
86 | ||
87 | static const char * const medianame[] = { | |
88 | "10baseT", "AUI", | |
89 | "10baseT-FD", "AUI-FD", | |
90 | }; | |
91 | ||
92 | #define LP486E_TOTAL_SIZE 16 | |
93 | ||
94 | #define I596_NULL (0xffffffff) | |
95 | ||
96 | #define CMD_EOL 0x8000 /* The last command of the list, stop. */ | |
97 | #define CMD_SUSP 0x4000 /* Suspend after doing cmd. */ | |
98 | #define CMD_INTR 0x2000 /* Interrupt after doing cmd. */ | |
99 | ||
100 | #define CMD_FLEX 0x0008 /* Enable flexible memory model */ | |
101 | ||
102 | enum commands { | |
103 | CmdNOP = 0, | |
104 | CmdIASetup = 1, | |
105 | CmdConfigure = 2, | |
106 | CmdMulticastList = 3, | |
107 | CmdTx = 4, | |
108 | CmdTDR = 5, | |
109 | CmdDump = 6, | |
110 | CmdDiagnose = 7 | |
111 | }; | |
112 | ||
113 | #if 0 | |
114 | static const char *CUcmdnames[8] = { "NOP", "IASetup", "Configure", "MulticastList", | |
115 | "Tx", "TDR", "Dump", "Diagnose" }; | |
116 | #endif | |
117 | ||
118 | /* Status word bits */ | |
119 | #define STAT_CX 0x8000 /* The CU finished executing a command | |
120 | with the Interrupt bit set */ | |
121 | #define STAT_FR 0x4000 /* The RU finished receiving a frame */ | |
122 | #define STAT_CNA 0x2000 /* The CU left the active state */ | |
123 | #define STAT_RNR 0x1000 /* The RU left the active state */ | |
124 | #define STAT_ACK (STAT_CX | STAT_FR | STAT_CNA | STAT_RNR) | |
125 | #define STAT_CUS 0x0700 /* Status of CU: 0: idle, 1: suspended, | |
126 | 2: active, 3-7: unused */ | |
127 | #define STAT_RUS 0x00f0 /* Status of RU: 0: idle, 1: suspended, | |
128 | 2: no resources, 4: ready, | |
129 | 10: no resources due to no more RBDs, | |
130 | 12: no more RBDs, other: unused */ | |
131 | #define STAT_T 0x0008 /* Bus throttle timers loaded */ | |
132 | #define STAT_ZERO 0x0807 /* Always zero */ | |
133 | ||
134 | #if 0 | |
135 | static char *CUstates[8] = { | |
136 | "idle", "suspended", "active", 0, 0, 0, 0, 0 | |
137 | }; | |
138 | static char *RUstates[16] = { | |
139 | "idle", "suspended", "no resources", 0, "ready", 0, 0, 0, | |
140 | 0, 0, "no RBDs", 0, "out of RBDs", 0, 0, 0 | |
141 | }; | |
142 | ||
143 | static void | |
144 | i596_out_status(int status) { | |
145 | int bad = 0; | |
146 | char *s; | |
147 | ||
148 | printk("status %4.4x:", status); | |
149 | if (status == 0xffff) | |
150 | printk(" strange..\n"); | |
151 | else { | |
152 | if (status & STAT_CX) | |
153 | printk(" CU done"); | |
154 | if (status & STAT_CNA) | |
155 | printk(" CU stopped"); | |
156 | if (status & STAT_FR) | |
157 | printk(" got a frame"); | |
158 | if (status & STAT_RNR) | |
159 | printk(" RU stopped"); | |
160 | if (status & STAT_T) | |
161 | printk(" throttled"); | |
162 | if (status & STAT_ZERO) | |
163 | bad = 1; | |
164 | s = CUstates[(status & STAT_CUS) >> 8]; | |
165 | if (!s) | |
166 | bad = 1; | |
167 | else | |
168 | printk(" CU(%s)", s); | |
169 | s = RUstates[(status & STAT_RUS) >> 4]; | |
170 | if (!s) | |
171 | bad = 1; | |
172 | else | |
173 | printk(" RU(%s)", s); | |
174 | if (bad) | |
175 | printk(" bad status"); | |
176 | printk("\n"); | |
177 | } | |
178 | } | |
179 | #endif | |
180 | ||
181 | /* Command word bits */ | |
182 | #define ACK_CX 0x8000 | |
183 | #define ACK_FR 0x4000 | |
184 | #define ACK_CNA 0x2000 | |
185 | #define ACK_RNR 0x1000 | |
186 | ||
187 | #define CUC_START 0x0100 | |
188 | #define CUC_RESUME 0x0200 | |
189 | #define CUC_SUSPEND 0x0300 | |
190 | #define CUC_ABORT 0x0400 | |
191 | ||
192 | #define RX_START 0x0010 | |
193 | #define RX_RESUME 0x0020 | |
194 | #define RX_SUSPEND 0x0030 | |
195 | #define RX_ABORT 0x0040 | |
196 | ||
197 | typedef u32 phys_addr; | |
198 | ||
199 | static inline phys_addr | |
200 | va_to_pa(void *x) { | |
201 | return x ? virt_to_bus(x) : I596_NULL; | |
202 | } | |
203 | ||
204 | static inline void * | |
205 | pa_to_va(phys_addr x) { | |
206 | return (x == I596_NULL) ? NULL : bus_to_virt(x); | |
207 | } | |
208 | ||
209 | /* status bits for cmd */ | |
210 | #define CMD_STAT_C 0x8000 /* CU command complete */ | |
211 | #define CMD_STAT_B 0x4000 /* CU command in progress */ | |
212 | #define CMD_STAT_OK 0x2000 /* CU command completed without errors */ | |
213 | #define CMD_STAT_A 0x1000 /* CU command abnormally terminated */ | |
214 | ||
215 | struct i596_cmd { /* 8 bytes */ | |
216 | unsigned short status; | |
217 | unsigned short command; | |
218 | phys_addr pa_next; /* va_to_pa(struct i596_cmd *next) */ | |
219 | }; | |
220 | ||
221 | #define EOF 0x8000 | |
222 | #define SIZE_MASK 0x3fff | |
223 | ||
224 | struct i596_tbd { | |
225 | unsigned short size; | |
226 | unsigned short pad; | |
227 | phys_addr pa_next; /* va_to_pa(struct i596_tbd *next) */ | |
228 | phys_addr pa_data; /* va_to_pa(char *data) */ | |
229 | struct sk_buff *skb; | |
230 | }; | |
231 | ||
232 | struct tx_cmd { | |
233 | struct i596_cmd cmd; | |
234 | phys_addr pa_tbd; /* va_to_pa(struct i596_tbd *tbd) */ | |
235 | unsigned short size; | |
236 | unsigned short pad; | |
237 | }; | |
238 | ||
239 | /* status bits for rfd */ | |
240 | #define RFD_STAT_C 0x8000 /* Frame reception complete */ | |
241 | #define RFD_STAT_B 0x4000 /* Frame reception in progress */ | |
242 | #define RFD_STAT_OK 0x2000 /* Frame received without errors */ | |
243 | #define RFD_STATUS 0x1fff | |
244 | #define RFD_LENGTH_ERR 0x1000 | |
245 | #define RFD_CRC_ERR 0x0800 | |
246 | #define RFD_ALIGN_ERR 0x0400 | |
247 | #define RFD_NOBUFS_ERR 0x0200 | |
248 | #define RFD_DMA_ERR 0x0100 /* DMA overrun failure to acquire system bus */ | |
249 | #define RFD_SHORT_FRAME_ERR 0x0080 | |
250 | #define RFD_NOEOP_ERR 0x0040 | |
251 | #define RFD_TRUNC_ERR 0x0020 | |
252 | #define RFD_MULTICAST 0x0002 /* 0: destination had our address | |
253 | 1: destination was broadcast/multicast */ | |
254 | #define RFD_COLLISION 0x0001 | |
255 | ||
256 | /* receive frame descriptor */ | |
257 | struct i596_rfd { | |
258 | unsigned short stat; | |
259 | unsigned short cmd; | |
260 | phys_addr pa_next; /* va_to_pa(struct i596_rfd *next) */ | |
261 | phys_addr pa_rbd; /* va_to_pa(struct i596_rbd *rbd) */ | |
262 | unsigned short count; | |
263 | unsigned short size; | |
264 | char data[1532]; | |
265 | }; | |
266 | ||
267 | #define RBD_EL 0x8000 | |
268 | #define RBD_P 0x4000 | |
269 | #define RBD_SIZEMASK 0x3fff | |
270 | #define RBD_EOF 0x8000 | |
271 | #define RBD_F 0x4000 | |
272 | ||
273 | /* receive buffer descriptor */ | |
274 | struct i596_rbd { | |
275 | unsigned short size; | |
276 | unsigned short pad; | |
277 | phys_addr pa_next; /* va_to_pa(struct i596_tbd *next) */ | |
278 | phys_addr pa_data; /* va_to_pa(char *data) */ | |
279 | phys_addr pa_prev; /* va_to_pa(struct i596_tbd *prev) */ | |
6aa20a22 | 280 | |
1da177e4 LT |
281 | /* Driver private part */ |
282 | struct sk_buff *skb; | |
283 | }; | |
284 | ||
285 | #define RX_RING_SIZE 64 | |
286 | #define RX_SKBSIZE (ETH_FRAME_LEN+10) | |
287 | #define RX_RBD_SIZE 32 | |
288 | ||
289 | /* System Control Block - 40 bytes */ | |
290 | struct i596_scb { | |
291 | u16 status; /* 0 */ | |
292 | u16 command; /* 2 */ | |
293 | phys_addr pa_cmd; /* 4 - va_to_pa(struct i596_cmd *cmd) */ | |
294 | phys_addr pa_rfd; /* 8 - va_to_pa(struct i596_rfd *rfd) */ | |
295 | u32 crc_err; /* 12 */ | |
296 | u32 align_err; /* 16 */ | |
297 | u32 resource_err; /* 20 */ | |
298 | u32 over_err; /* 24 */ | |
299 | u32 rcvdt_err; /* 28 */ | |
300 | u32 short_err; /* 32 */ | |
301 | u16 t_on; /* 36 */ | |
302 | u16 t_off; /* 38 */ | |
303 | }; | |
304 | ||
305 | /* Intermediate System Configuration Pointer - 8 bytes */ | |
306 | struct i596_iscp { | |
307 | u32 busy; /* 0 */ | |
308 | phys_addr pa_scb; /* 4 - va_to_pa(struct i596_scb *scb) */ | |
309 | }; | |
310 | ||
311 | /* System Configuration Pointer - 12 bytes */ | |
312 | struct i596_scp { | |
313 | u32 sysbus; /* 0 */ | |
314 | u32 pad; /* 4 */ | |
315 | phys_addr pa_iscp; /* 8 - va_to_pa(struct i596_iscp *iscp) */ | |
316 | }; | |
317 | ||
318 | /* Selftest and dump results - needs 16-byte alignment */ | |
319 | /* | |
320 | * The size of the dump area is 304 bytes. When the dump is executed | |
321 | * by the Port command an extra word will be appended to the dump area. | |
322 | * The extra word is a copy of the Dump status word (containing the | |
323 | * C, B, OK bits). [I find 0xa006, with a0 for C+OK and 6 for dump] | |
324 | */ | |
325 | struct i596_dump { | |
326 | u16 dump[153]; /* (304 = 130h) + 2 bytes */ | |
327 | }; | |
328 | ||
329 | struct i596_private { /* aligned to a 16-byte boundary */ | |
330 | struct i596_scp scp; /* 0 - needs 16-byte alignment */ | |
331 | struct i596_iscp iscp; /* 12 */ | |
332 | struct i596_scb scb; /* 20 */ | |
333 | u32 dummy; /* 60 */ | |
334 | struct i596_dump dump; /* 64 - needs 16-byte alignment */ | |
335 | ||
336 | struct i596_cmd set_add; | |
337 | char eth_addr[8]; /* directly follows set_add */ | |
338 | ||
339 | struct i596_cmd set_conf; | |
340 | char i596_config[16]; /* directly follows set_conf */ | |
341 | ||
342 | struct i596_cmd tdr; | |
343 | unsigned long tdr_stat; /* directly follows tdr */ | |
344 | ||
345 | int last_restart; | |
346 | struct i596_rbd *rbd_list; | |
347 | struct i596_rbd *rbd_tail; | |
348 | struct i596_rfd *rx_tail; | |
349 | struct i596_cmd *cmd_tail; | |
350 | struct i596_cmd *cmd_head; | |
351 | int cmd_backlog; | |
352 | unsigned long last_cmd; | |
1da177e4 LT |
353 | spinlock_t cmd_lock; |
354 | }; | |
355 | ||
356 | static char init_setup[14] = { | |
357 | 0x8E, /* length 14 bytes, prefetch on */ | |
358 | 0xC8, /* default: fifo to 8, monitor off */ | |
359 | 0x40, /* default: don't save bad frames (apricot.c had 0x80) */ | |
360 | 0x2E, /* (default is 0x26) | |
361 | No source address insertion, 8 byte preamble */ | |
362 | 0x00, /* default priority and backoff */ | |
363 | 0x60, /* default interframe spacing */ | |
364 | 0x00, /* default slot time LSB */ | |
365 | 0xf2, /* default slot time and nr of retries */ | |
366 | 0x00, /* default various bits | |
367 | (0: promiscuous mode, 1: broadcast disable, | |
368 | 2: encoding mode, 3: transmit on no CRS, | |
369 | 4: no CRC insertion, 5: CRC type, | |
370 | 6: bit stuffing, 7: padding) */ | |
371 | 0x00, /* default carrier sense and collision detect */ | |
372 | 0x40, /* default minimum frame length */ | |
373 | 0xff, /* (default is 0xff, and that is what apricot.c has; | |
374 | elp486.c has 0xfb: Enable crc append in memory.) */ | |
375 | 0x00, /* default: not full duplex */ | |
376 | 0x7f /* (default is 0x3f) multi IA */ | |
377 | }; | |
378 | ||
379 | static int i596_open(struct net_device *dev); | |
380 | static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev); | |
7d12e780 | 381 | static irqreturn_t i596_interrupt(int irq, void *dev_id); |
1da177e4 | 382 | static int i596_close(struct net_device *dev); |
1da177e4 LT |
383 | static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd); |
384 | static void print_eth(char *); | |
385 | static void set_multicast_list(struct net_device *dev); | |
386 | static void i596_tx_timeout(struct net_device *dev); | |
387 | ||
388 | static int | |
389 | i596_timeout(struct net_device *dev, char *msg, int ct) { | |
390 | struct i596_private *lp; | |
391 | int boguscnt = ct; | |
392 | ||
393 | lp = (struct i596_private *) dev->priv; | |
394 | while (lp->scb.command) { | |
395 | if (--boguscnt == 0) { | |
396 | printk("%s: %s timed out - stat %4.4x, cmd %4.4x\n", | |
397 | dev->name, msg, | |
398 | lp->scb.status, lp->scb.command); | |
399 | return 1; | |
400 | } | |
401 | udelay(5); | |
402 | barrier(); | |
403 | } | |
404 | return 0; | |
405 | } | |
406 | ||
407 | static inline int | |
408 | init_rx_bufs(struct net_device *dev, int num) { | |
409 | struct i596_private *lp; | |
410 | struct i596_rfd *rfd; | |
411 | int i; | |
412 | // struct i596_rbd *rbd; | |
413 | ||
414 | lp = (struct i596_private *) dev->priv; | |
415 | lp->scb.pa_rfd = I596_NULL; | |
416 | ||
417 | for (i = 0; i < num; i++) { | |
418 | rfd = kmalloc(sizeof(struct i596_rfd), GFP_KERNEL); | |
419 | if (rfd == NULL) | |
420 | break; | |
421 | ||
422 | rfd->stat = 0; | |
423 | rfd->pa_rbd = I596_NULL; | |
424 | rfd->count = 0; | |
425 | rfd->size = 1532; | |
426 | if (i == 0) { | |
427 | rfd->cmd = CMD_EOL; | |
428 | lp->rx_tail = rfd; | |
429 | } else { | |
430 | rfd->cmd = 0; | |
431 | } | |
432 | rfd->pa_next = lp->scb.pa_rfd; | |
433 | lp->scb.pa_rfd = va_to_pa(rfd); | |
434 | lp->rx_tail->pa_next = lp->scb.pa_rfd; | |
435 | } | |
436 | ||
437 | #if 0 | |
438 | for (i = 0; i<RX_RBD_SIZE; i++) { | |
439 | rbd = kmalloc(sizeof(struct i596_rbd), GFP_KERNEL); | |
440 | if (rbd) { | |
441 | rbd->pad = 0; | |
442 | rbd->count = 0; | |
8ce90907 | 443 | rbd->skb = dev_alloc_skb(RX_SKBSIZE); |
1da177e4 LT |
444 | if (!rbd->skb) { |
445 | printk("dev_alloc_skb failed"); | |
446 | } | |
447 | rbd->next = rfd->rbd; | |
448 | if (i) { | |
449 | rfd->rbd->prev = rbd; | |
8ce90907 | 450 | rbd->size = RX_SKBSIZE; |
1da177e4 | 451 | } else { |
8ce90907 | 452 | rbd->size = (RX_SKBSIZE | RBD_EL); |
1da177e4 LT |
453 | lp->rbd_tail = rbd; |
454 | } | |
455 | ||
456 | rfd->rbd = rbd; | |
457 | } else { | |
458 | printk("Could not kmalloc rbd\n"); | |
459 | } | |
460 | } | |
461 | lp->rbd_tail->next = rfd->rbd; | |
462 | #endif | |
463 | return (i); | |
464 | } | |
465 | ||
466 | static inline void | |
467 | remove_rx_bufs(struct net_device *dev) { | |
468 | struct i596_private *lp; | |
469 | struct i596_rfd *rfd; | |
470 | ||
471 | lp = (struct i596_private *) dev->priv; | |
472 | lp->rx_tail->pa_next = I596_NULL; | |
473 | ||
474 | do { | |
475 | rfd = pa_to_va(lp->scb.pa_rfd); | |
476 | lp->scb.pa_rfd = rfd->pa_next; | |
477 | kfree(rfd); | |
478 | } while (rfd != lp->rx_tail); | |
479 | ||
480 | lp->rx_tail = NULL; | |
481 | ||
482 | #if 0 | |
483 | for (lp->rbd_list) { | |
484 | } | |
485 | #endif | |
486 | } | |
487 | ||
488 | #define PORT_RESET 0x00 /* reset 82596 */ | |
489 | #define PORT_SELFTEST 0x01 /* selftest */ | |
490 | #define PORT_ALTSCP 0x02 /* alternate SCB address */ | |
491 | #define PORT_DUMP 0x03 /* dump */ | |
492 | ||
493 | #define IOADDR 0xcb0 /* real constant */ | |
494 | #define IRQ 10 /* default IRQ - can be changed by ECU */ | |
495 | ||
496 | /* The 82596 requires two 16-bit write cycles for a port command */ | |
497 | static inline void | |
498 | PORT(phys_addr a, unsigned int cmd) { | |
499 | if (a & 0xf) | |
500 | printk("lp486e.c: PORT: address not aligned\n"); | |
501 | outw(((a & 0xffff) | cmd), IOADDR); | |
502 | outw(((a>>16) & 0xffff), IOADDR+2); | |
503 | } | |
504 | ||
505 | static inline void | |
506 | CA(void) { | |
507 | outb(0, IOADDR+4); | |
508 | udelay(8); | |
509 | } | |
510 | ||
511 | static inline void | |
512 | CLEAR_INT(void) { | |
513 | outb(0, IOADDR+8); | |
514 | } | |
515 | ||
1da177e4 LT |
516 | #if 0 |
517 | /* selftest or dump */ | |
518 | static void | |
519 | i596_port_do(struct net_device *dev, int portcmd, char *cmdname) { | |
520 | struct i596_private *lp = dev->priv; | |
521 | u16 *outp; | |
522 | int i, m; | |
523 | ||
524 | memset((void *)&(lp->dump), 0, sizeof(struct i596_dump)); | |
525 | outp = &(lp->dump.dump[0]); | |
526 | ||
527 | PORT(va_to_pa(outp), portcmd); | |
528 | mdelay(30); /* random, unmotivated */ | |
529 | ||
530 | printk("lp486e i82596 %s result:\n", cmdname); | |
ff8ac609 | 531 | for (m = ARRAY_SIZE(lp->dump.dump); m && lp->dump.dump[m-1] == 0; m--) |
1da177e4 LT |
532 | ; |
533 | for (i = 0; i < m; i++) { | |
534 | printk(" %04x", lp->dump.dump[i]); | |
535 | if (i%8 == 7) | |
536 | printk("\n"); | |
537 | } | |
538 | printk("\n"); | |
539 | } | |
540 | #endif | |
541 | ||
542 | static int | |
543 | i596_scp_setup(struct net_device *dev) { | |
544 | struct i596_private *lp = dev->priv; | |
545 | int boguscnt; | |
546 | ||
547 | /* Setup SCP, ISCP, SCB */ | |
548 | /* | |
549 | * sysbus bits: | |
550 | * only a single byte is significant - here 0x44 | |
551 | * 0x80: big endian mode (details depend on stepping) | |
552 | * 0x40: 1 | |
553 | * 0x20: interrupt pin is active low | |
554 | * 0x10: lock function disabled | |
555 | * 0x08: external triggering of bus throttle timers | |
556 | * 0x06: 00: 82586 compat mode, 01: segmented mode, 10: linear mode | |
557 | * 0x01: unused | |
558 | */ | |
559 | lp->scp.sysbus = 0x00440000; /* linear mode */ | |
560 | lp->scp.pad = 0; /* must be zero */ | |
561 | lp->scp.pa_iscp = va_to_pa(&(lp->iscp)); | |
562 | ||
563 | /* | |
564 | * The CPU sets the ISCP to 1 before it gives the first CA() | |
565 | */ | |
566 | lp->iscp.busy = 0x0001; | |
567 | lp->iscp.pa_scb = va_to_pa(&(lp->scb)); | |
568 | ||
569 | lp->scb.command = 0; | |
570 | lp->scb.status = 0; | |
571 | lp->scb.pa_cmd = I596_NULL; | |
572 | /* lp->scb.pa_rfd has been initialised already */ | |
573 | ||
574 | lp->last_cmd = jiffies; | |
575 | lp->cmd_backlog = 0; | |
576 | lp->cmd_head = NULL; | |
577 | ||
578 | /* | |
579 | * Reset the 82596. | |
580 | * We need to wait 10 systemclock cycles, and | |
581 | * 5 serial clock cycles. | |
582 | */ | |
583 | PORT(0, PORT_RESET); /* address part ignored */ | |
584 | udelay(100); | |
585 | ||
586 | /* | |
587 | * Before the CA signal is asserted, the default SCP address | |
588 | * (0x00fffff4) can be changed to a 16-byte aligned value | |
589 | */ | |
590 | PORT(va_to_pa(&lp->scp), PORT_ALTSCP); /* change the scp address */ | |
591 | ||
592 | /* | |
593 | * The initialization procedure begins when a | |
594 | * Channel Attention signal is asserted after a reset. | |
595 | */ | |
596 | ||
597 | CA(); | |
598 | ||
599 | /* | |
600 | * The ISCP busy is cleared by the 82596 after the SCB address is read. | |
601 | */ | |
602 | boguscnt = 100; | |
603 | while (lp->iscp.busy) { | |
604 | if (--boguscnt == 0) { | |
605 | /* No i82596 present? */ | |
606 | printk("%s: i82596 initialization timed out\n", | |
607 | dev->name); | |
608 | return 1; | |
609 | } | |
610 | udelay(5); | |
611 | barrier(); | |
612 | } | |
613 | /* I find here boguscnt==100, so no delay was required. */ | |
614 | ||
615 | return 0; | |
616 | } | |
617 | ||
618 | static int | |
619 | init_i596(struct net_device *dev) { | |
620 | struct i596_private *lp; | |
621 | ||
622 | if (i596_scp_setup(dev)) | |
623 | return 1; | |
624 | ||
625 | lp = (struct i596_private *) dev->priv; | |
626 | lp->scb.command = 0; | |
627 | ||
628 | memcpy ((void *)lp->i596_config, init_setup, 14); | |
629 | lp->set_conf.command = CmdConfigure; | |
630 | i596_add_cmd(dev, (void *)&lp->set_conf); | |
631 | ||
632 | memcpy ((void *)lp->eth_addr, dev->dev_addr, 6); | |
633 | lp->set_add.command = CmdIASetup; | |
634 | i596_add_cmd(dev, (struct i596_cmd *)&lp->set_add); | |
635 | ||
636 | lp->tdr.command = CmdTDR; | |
637 | i596_add_cmd(dev, (struct i596_cmd *)&lp->tdr); | |
638 | ||
639 | if (lp->scb.command && i596_timeout(dev, "i82596 init", 200)) | |
640 | return 1; | |
641 | ||
642 | lp->scb.command = RX_START; | |
643 | CA(); | |
644 | ||
645 | barrier(); | |
6aa20a22 | 646 | |
1da177e4 LT |
647 | if (lp->scb.command && i596_timeout(dev, "Receive Unit start", 100)) |
648 | return 1; | |
649 | ||
650 | return 0; | |
651 | } | |
652 | ||
653 | /* Receive a single frame */ | |
654 | static inline int | |
655 | i596_rx_one(struct net_device *dev, struct i596_private *lp, | |
656 | struct i596_rfd *rfd, int *frames) { | |
657 | ||
658 | if (rfd->stat & RFD_STAT_OK) { | |
659 | /* a good frame */ | |
660 | int pkt_len = (rfd->count & 0x3fff); | |
661 | struct sk_buff *skb = dev_alloc_skb(pkt_len); | |
662 | ||
663 | (*frames)++; | |
664 | ||
665 | if (rfd->cmd & CMD_EOL) | |
666 | printk("Received on EOL\n"); | |
667 | ||
668 | if (skb == NULL) { | |
669 | printk ("%s: i596_rx Memory squeeze, " | |
670 | "dropping packet.\n", dev->name); | |
09f75cd7 | 671 | dev->stats.rx_dropped++; |
1da177e4 LT |
672 | return 1; |
673 | } | |
674 | ||
1da177e4 LT |
675 | memcpy(skb_put(skb,pkt_len), rfd->data, pkt_len); |
676 | ||
677 | skb->protocol = eth_type_trans(skb,dev); | |
678 | netif_rx(skb); | |
679 | dev->last_rx = jiffies; | |
09f75cd7 | 680 | dev->stats.rx_packets++; |
1da177e4 LT |
681 | } else { |
682 | #if 0 | |
683 | printk("Frame reception error status %04x\n", | |
684 | rfd->stat); | |
685 | #endif | |
09f75cd7 | 686 | dev->stats.rx_errors++; |
1da177e4 | 687 | if (rfd->stat & RFD_COLLISION) |
09f75cd7 | 688 | dev->stats.collisions++; |
1da177e4 | 689 | if (rfd->stat & RFD_SHORT_FRAME_ERR) |
09f75cd7 | 690 | dev->stats.rx_length_errors++; |
1da177e4 | 691 | if (rfd->stat & RFD_DMA_ERR) |
09f75cd7 | 692 | dev->stats.rx_over_errors++; |
1da177e4 | 693 | if (rfd->stat & RFD_NOBUFS_ERR) |
09f75cd7 | 694 | dev->stats.rx_fifo_errors++; |
1da177e4 | 695 | if (rfd->stat & RFD_ALIGN_ERR) |
09f75cd7 | 696 | dev->stats.rx_frame_errors++; |
1da177e4 | 697 | if (rfd->stat & RFD_CRC_ERR) |
09f75cd7 | 698 | dev->stats.rx_crc_errors++; |
1da177e4 | 699 | if (rfd->stat & RFD_LENGTH_ERR) |
09f75cd7 | 700 | dev->stats.rx_length_errors++; |
1da177e4 LT |
701 | } |
702 | rfd->stat = rfd->count = 0; | |
703 | return 0; | |
704 | } | |
705 | ||
706 | static int | |
707 | i596_rx(struct net_device *dev) { | |
708 | struct i596_private *lp = (struct i596_private *) dev->priv; | |
709 | struct i596_rfd *rfd; | |
710 | int frames = 0; | |
711 | ||
712 | while (1) { | |
713 | rfd = pa_to_va(lp->scb.pa_rfd); | |
714 | if (!rfd) { | |
715 | printk(KERN_ERR "i596_rx: NULL rfd?\n"); | |
716 | return 0; | |
717 | } | |
718 | #if 1 | |
719 | if (rfd->stat && !(rfd->stat & (RFD_STAT_C | RFD_STAT_B))) | |
720 | printk("SF:%p-%04x\n", rfd, rfd->stat); | |
721 | #endif | |
722 | if (!(rfd->stat & RFD_STAT_C)) | |
723 | break; /* next one not ready */ | |
724 | if (i596_rx_one(dev, lp, rfd, &frames)) | |
725 | break; /* out of memory */ | |
726 | rfd->cmd = CMD_EOL; | |
727 | lp->rx_tail->cmd = 0; | |
728 | lp->rx_tail = rfd; | |
729 | lp->scb.pa_rfd = rfd->pa_next; | |
730 | barrier(); | |
731 | } | |
732 | ||
733 | return frames; | |
734 | } | |
735 | ||
736 | static void | |
737 | i596_cleanup_cmd(struct net_device *dev) { | |
738 | struct i596_private *lp; | |
739 | struct i596_cmd *cmd; | |
740 | ||
741 | lp = (struct i596_private *) dev->priv; | |
742 | while (lp->cmd_head) { | |
743 | cmd = (struct i596_cmd *)lp->cmd_head; | |
744 | ||
745 | lp->cmd_head = pa_to_va(lp->cmd_head->pa_next); | |
746 | lp->cmd_backlog--; | |
747 | ||
748 | switch ((cmd->command) & 0x7) { | |
749 | case CmdTx: { | |
750 | struct tx_cmd *tx_cmd = (struct tx_cmd *) cmd; | |
751 | struct i596_tbd * tx_cmd_tbd; | |
752 | tx_cmd_tbd = pa_to_va(tx_cmd->pa_tbd); | |
753 | ||
754 | dev_kfree_skb_any(tx_cmd_tbd->skb); | |
755 | ||
09f75cd7 JG |
756 | dev->stats.tx_errors++; |
757 | dev->stats.tx_aborted_errors++; | |
1da177e4 LT |
758 | |
759 | cmd->pa_next = I596_NULL; | |
760 | kfree((unsigned char *)tx_cmd); | |
761 | netif_wake_queue(dev); | |
762 | break; | |
763 | } | |
764 | case CmdMulticastList: { | |
765 | // unsigned short count = *((unsigned short *) (ptr + 1)); | |
766 | ||
767 | cmd->pa_next = I596_NULL; | |
768 | kfree((unsigned char *)cmd); | |
769 | break; | |
770 | } | |
771 | default: { | |
772 | cmd->pa_next = I596_NULL; | |
773 | break; | |
774 | } | |
775 | } | |
776 | barrier(); | |
777 | } | |
778 | ||
779 | if (lp->scb.command && i596_timeout(dev, "i596_cleanup_cmd", 100)) | |
780 | ; | |
781 | ||
782 | lp->scb.pa_cmd = va_to_pa(lp->cmd_head); | |
783 | } | |
784 | ||
785 | static void i596_reset(struct net_device *dev, struct i596_private *lp, int ioaddr) { | |
786 | ||
787 | if (lp->scb.command && i596_timeout(dev, "i596_reset", 100)) | |
788 | ; | |
789 | ||
790 | netif_stop_queue(dev); | |
791 | ||
792 | lp->scb.command = CUC_ABORT | RX_ABORT; | |
793 | CA(); | |
794 | barrier(); | |
6aa20a22 | 795 | |
1da177e4 LT |
796 | /* wait for shutdown */ |
797 | if (lp->scb.command && i596_timeout(dev, "i596_reset(2)", 400)) | |
798 | ; | |
799 | ||
800 | i596_cleanup_cmd(dev); | |
801 | i596_rx(dev); | |
802 | ||
803 | netif_start_queue(dev); | |
804 | /*dev_kfree_skb(skb, FREE_WRITE);*/ | |
805 | init_i596(dev); | |
806 | } | |
807 | ||
808 | static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd) { | |
809 | struct i596_private *lp = dev->priv; | |
810 | int ioaddr = dev->base_addr; | |
811 | unsigned long flags; | |
812 | ||
813 | cmd->status = 0; | |
814 | cmd->command |= (CMD_EOL | CMD_INTR); | |
815 | cmd->pa_next = I596_NULL; | |
816 | ||
817 | spin_lock_irqsave(&lp->cmd_lock, flags); | |
6aa20a22 | 818 | |
1da177e4 LT |
819 | if (lp->cmd_head) { |
820 | lp->cmd_tail->pa_next = va_to_pa(cmd); | |
821 | } else { | |
822 | lp->cmd_head = cmd; | |
823 | if (lp->scb.command && i596_timeout(dev, "i596_add_cmd", 100)) | |
824 | ; | |
825 | lp->scb.pa_cmd = va_to_pa(cmd); | |
826 | lp->scb.command = CUC_START; | |
827 | CA(); | |
828 | } | |
829 | lp->cmd_tail = cmd; | |
830 | lp->cmd_backlog++; | |
831 | ||
832 | lp->cmd_head = pa_to_va(lp->scb.pa_cmd); | |
833 | spin_unlock_irqrestore(&lp->cmd_lock, flags); | |
834 | ||
835 | if (lp->cmd_backlog > 16) { | |
836 | int tickssofar = jiffies - lp->last_cmd; | |
837 | if (tickssofar < HZ/4) | |
838 | return; | |
839 | ||
840 | printk(KERN_WARNING "%s: command unit timed out, status resetting.\n", dev->name); | |
841 | i596_reset(dev, lp, ioaddr); | |
842 | } | |
843 | } | |
844 | ||
6aa20a22 | 845 | static int i596_open(struct net_device *dev) |
1da177e4 LT |
846 | { |
847 | int i; | |
848 | ||
1fb9df5d | 849 | i = request_irq(dev->irq, &i596_interrupt, IRQF_SHARED, dev->name, dev); |
1da177e4 LT |
850 | if (i) { |
851 | printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq); | |
852 | return i; | |
853 | } | |
854 | ||
855 | if ((i = init_rx_bufs(dev, RX_RING_SIZE)) < RX_RING_SIZE) | |
856 | printk(KERN_ERR "%s: only able to allocate %d receive buffers\n", dev->name, i); | |
857 | ||
858 | if (i < 4) { | |
859 | free_irq(dev->irq, dev); | |
860 | return -EAGAIN; | |
861 | } | |
862 | netif_start_queue(dev); | |
863 | init_i596(dev); | |
864 | return 0; /* Always succeed */ | |
865 | } | |
866 | ||
867 | static int i596_start_xmit (struct sk_buff *skb, struct net_device *dev) { | |
1da177e4 LT |
868 | struct tx_cmd *tx_cmd; |
869 | short length; | |
870 | ||
871 | length = skb->len; | |
6aa20a22 | 872 | |
1da177e4 | 873 | if (length < ETH_ZLEN) { |
5b057c6b | 874 | if (skb_padto(skb, ETH_ZLEN)) |
1da177e4 LT |
875 | return 0; |
876 | length = ETH_ZLEN; | |
877 | } | |
6aa20a22 | 878 | |
1da177e4 LT |
879 | dev->trans_start = jiffies; |
880 | ||
5cbded58 | 881 | tx_cmd = kmalloc((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC); |
1da177e4 LT |
882 | if (tx_cmd == NULL) { |
883 | printk(KERN_WARNING "%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name); | |
09f75cd7 | 884 | dev->stats.tx_dropped++; |
1da177e4 LT |
885 | dev_kfree_skb (skb); |
886 | } else { | |
887 | struct i596_tbd *tx_cmd_tbd; | |
888 | tx_cmd_tbd = (struct i596_tbd *) (tx_cmd + 1); | |
889 | tx_cmd->pa_tbd = va_to_pa (tx_cmd_tbd); | |
890 | tx_cmd_tbd->pa_next = I596_NULL; | |
891 | ||
892 | tx_cmd->cmd.command = (CMD_FLEX | CmdTx); | |
893 | ||
894 | tx_cmd->pad = 0; | |
895 | tx_cmd->size = 0; | |
896 | tx_cmd_tbd->pad = 0; | |
897 | tx_cmd_tbd->size = (EOF | length); | |
898 | ||
899 | tx_cmd_tbd->pa_data = va_to_pa (skb->data); | |
900 | tx_cmd_tbd->skb = skb; | |
901 | ||
902 | if (i596_debug & LOG_SRCDST) | |
903 | print_eth (skb->data); | |
904 | ||
905 | i596_add_cmd (dev, (struct i596_cmd *) tx_cmd); | |
906 | ||
09f75cd7 | 907 | dev->stats.tx_packets++; |
1da177e4 LT |
908 | } |
909 | ||
910 | return 0; | |
911 | } | |
912 | ||
913 | static void | |
914 | i596_tx_timeout (struct net_device *dev) { | |
915 | struct i596_private *lp = dev->priv; | |
916 | int ioaddr = dev->base_addr; | |
917 | ||
918 | /* Transmitter timeout, serious problems. */ | |
919 | printk(KERN_WARNING "%s: transmit timed out, status resetting.\n", dev->name); | |
09f75cd7 | 920 | dev->stats.tx_errors++; |
1da177e4 LT |
921 | |
922 | /* Try to restart the adaptor */ | |
09f75cd7 | 923 | if (lp->last_restart == dev->stats.tx_packets) { |
1da177e4 LT |
924 | printk ("Resetting board.\n"); |
925 | ||
926 | /* Shutdown and restart */ | |
927 | i596_reset (dev, lp, ioaddr); | |
928 | } else { | |
929 | /* Issue a channel attention signal */ | |
930 | printk ("Kicking board.\n"); | |
931 | lp->scb.command = (CUC_START | RX_START); | |
932 | CA(); | |
09f75cd7 | 933 | lp->last_restart = dev->stats.tx_packets; |
1da177e4 LT |
934 | } |
935 | netif_wake_queue(dev); | |
936 | } | |
937 | ||
6aa20a22 | 938 | static void print_eth(char *add) |
1da177e4 LT |
939 | { |
940 | int i; | |
941 | ||
942 | printk ("Dest "); | |
943 | for (i = 0; i < 6; i++) | |
944 | printk(" %2.2X", (unsigned char) add[i]); | |
945 | printk ("\n"); | |
946 | ||
947 | printk ("Source"); | |
948 | for (i = 0; i < 6; i++) | |
949 | printk(" %2.2X", (unsigned char) add[i+6]); | |
950 | printk ("\n"); | |
951 | ||
952 | printk ("type %2.2X%2.2X\n", | |
953 | (unsigned char) add[12], (unsigned char) add[13]); | |
954 | } | |
955 | ||
956 | static int __init lp486e_probe(struct net_device *dev) { | |
957 | struct i596_private *lp; | |
958 | unsigned char eth_addr[6] = { 0, 0xaa, 0, 0, 0, 0 }; | |
959 | unsigned char *bios; | |
960 | int i, j; | |
961 | int ret = -ENOMEM; | |
962 | static int probed; | |
963 | ||
964 | if (probed) | |
965 | return -ENODEV; | |
966 | probed++; | |
967 | ||
968 | if (!request_region(IOADDR, LP486E_TOTAL_SIZE, DRV_NAME)) { | |
969 | printk(KERN_ERR "lp486e: IO address 0x%x in use\n", IOADDR); | |
970 | return -EBUSY; | |
971 | } | |
972 | ||
973 | lp = (struct i596_private *) dev->priv; | |
974 | spin_lock_init(&lp->cmd_lock); | |
6aa20a22 | 975 | |
1da177e4 LT |
976 | /* |
977 | * Do we really have this thing? | |
978 | */ | |
979 | if (i596_scp_setup(dev)) { | |
980 | ret = -ENODEV; | |
981 | goto err_out_kfree; | |
982 | } | |
983 | ||
984 | dev->base_addr = IOADDR; | |
985 | dev->irq = IRQ; | |
986 | ||
987 | ||
988 | /* | |
989 | * How do we find the ethernet address? I don't know. | |
990 | * One possibility is to look at the EISA configuration area | |
991 | * [0xe8000-0xe9fff]. This contains the ethernet address | |
992 | * but not at a fixed address - things depend on setup options. | |
993 | * | |
994 | * If we find no address, or the wrong address, use | |
995 | * ifconfig eth0 hw ether a1:a2:a3:a4:a5:a6 | |
996 | * with the value found in the BIOS setup. | |
997 | */ | |
998 | bios = bus_to_virt(0xe8000); | |
999 | for (j = 0; j < 0x2000; j++) { | |
1000 | if (bios[j] == 0 && bios[j+1] == 0xaa && bios[j+2] == 0) { | |
1001 | printk("%s: maybe address at BIOS 0x%x:", | |
1002 | dev->name, 0xe8000+j); | |
1003 | for (i = 0; i < 6; i++) { | |
1004 | eth_addr[i] = bios[i+j]; | |
1005 | printk(" %2.2X", eth_addr[i]); | |
1006 | } | |
1007 | printk("\n"); | |
1008 | } | |
1009 | } | |
1010 | ||
1011 | printk("%s: lp486e 82596 at %#3lx, IRQ %d,", | |
1012 | dev->name, dev->base_addr, dev->irq); | |
1013 | for (i = 0; i < 6; i++) | |
1014 | printk(" %2.2X", dev->dev_addr[i] = eth_addr[i]); | |
1015 | printk("\n"); | |
1016 | ||
1017 | /* The LP486E-specific entries in the device structure. */ | |
1018 | dev->open = &i596_open; | |
1019 | dev->stop = &i596_close; | |
1020 | dev->hard_start_xmit = &i596_start_xmit; | |
1da177e4 LT |
1021 | dev->set_multicast_list = &set_multicast_list; |
1022 | dev->watchdog_timeo = 5*HZ; | |
1023 | dev->tx_timeout = i596_tx_timeout; | |
1024 | ||
1025 | #if 0 | |
1026 | /* selftest reports 0x320925ae - don't know what that means */ | |
1027 | i596_port_do(dev, PORT_SELFTEST, "selftest"); | |
1028 | i596_port_do(dev, PORT_DUMP, "dump"); | |
1029 | #endif | |
1030 | return 0; | |
1031 | ||
1032 | err_out_kfree: | |
1033 | release_region(IOADDR, LP486E_TOTAL_SIZE); | |
1034 | return ret; | |
1035 | } | |
1036 | ||
1037 | static inline void | |
1038 | i596_handle_CU_completion(struct net_device *dev, | |
1039 | struct i596_private *lp, | |
1040 | unsigned short status, | |
1041 | unsigned short *ack_cmdp) { | |
1042 | struct i596_cmd *cmd; | |
1043 | int frames_out = 0; | |
1044 | int commands_done = 0; | |
1045 | int cmd_val; | |
1046 | unsigned long flags; | |
1047 | ||
1048 | spin_lock_irqsave(&lp->cmd_lock, flags); | |
1049 | cmd = lp->cmd_head; | |
1050 | ||
1051 | while (lp->cmd_head && (lp->cmd_head->status & CMD_STAT_C)) { | |
1052 | cmd = lp->cmd_head; | |
1053 | ||
1054 | lp->cmd_head = pa_to_va(lp->cmd_head->pa_next); | |
1055 | lp->cmd_backlog--; | |
1056 | ||
1057 | commands_done++; | |
1058 | cmd_val = cmd->command & 0x7; | |
1059 | #if 0 | |
1060 | printk("finished CU %s command (%d)\n", | |
1061 | CUcmdnames[cmd_val], cmd_val); | |
1062 | #endif | |
1063 | switch (cmd_val) { | |
1064 | case CmdTx: | |
1065 | { | |
1066 | struct tx_cmd *tx_cmd; | |
1067 | struct i596_tbd *tx_cmd_tbd; | |
1068 | ||
1069 | tx_cmd = (struct tx_cmd *) cmd; | |
1070 | tx_cmd_tbd = pa_to_va(tx_cmd->pa_tbd); | |
1071 | ||
1072 | frames_out++; | |
1073 | if (cmd->status & CMD_STAT_OK) { | |
1074 | if (i596_debug) | |
1075 | print_eth(pa_to_va(tx_cmd_tbd->pa_data)); | |
1076 | } else { | |
09f75cd7 | 1077 | dev->stats.tx_errors++; |
1da177e4 LT |
1078 | if (i596_debug) |
1079 | printk("transmission failure:%04x\n", | |
1080 | cmd->status); | |
1081 | if (cmd->status & 0x0020) | |
09f75cd7 | 1082 | dev->stats.collisions++; |
1da177e4 | 1083 | if (!(cmd->status & 0x0040)) |
09f75cd7 | 1084 | dev->stats.tx_heartbeat_errors++; |
1da177e4 | 1085 | if (cmd->status & 0x0400) |
09f75cd7 | 1086 | dev->stats.tx_carrier_errors++; |
1da177e4 | 1087 | if (cmd->status & 0x0800) |
09f75cd7 | 1088 | dev->stats.collisions++; |
1da177e4 | 1089 | if (cmd->status & 0x1000) |
09f75cd7 | 1090 | dev->stats.tx_aborted_errors++; |
1da177e4 LT |
1091 | } |
1092 | dev_kfree_skb_irq(tx_cmd_tbd->skb); | |
1093 | ||
1094 | cmd->pa_next = I596_NULL; | |
1095 | kfree((unsigned char *)tx_cmd); | |
1096 | netif_wake_queue(dev); | |
1097 | break; | |
1098 | } | |
1099 | ||
1100 | case CmdMulticastList: | |
1101 | cmd->pa_next = I596_NULL; | |
1102 | kfree((unsigned char *)cmd); | |
1103 | break; | |
1104 | ||
1105 | case CmdTDR: | |
1106 | { | |
1107 | unsigned long status = *((unsigned long *) (cmd + 1)); | |
1108 | if (status & 0x8000) { | |
1109 | if (i596_debug) | |
1110 | printk("%s: link ok.\n", dev->name); | |
1111 | } else { | |
1112 | if (status & 0x4000) | |
1113 | printk("%s: Transceiver problem.\n", | |
1114 | dev->name); | |
1115 | if (status & 0x2000) | |
1116 | printk("%s: Termination problem.\n", | |
1117 | dev->name); | |
1118 | if (status & 0x1000) | |
1119 | printk("%s: Short circuit.\n", | |
1120 | dev->name); | |
1121 | printk("%s: Time %ld.\n", | |
1122 | dev->name, status & 0x07ff); | |
1123 | } | |
1124 | } | |
1125 | default: | |
1126 | cmd->pa_next = I596_NULL; | |
1127 | lp->last_cmd = jiffies; | |
6aa20a22 | 1128 | |
1da177e4 LT |
1129 | } |
1130 | barrier(); | |
1131 | } | |
1132 | ||
1133 | cmd = lp->cmd_head; | |
1134 | while (cmd && (cmd != lp->cmd_tail)) { | |
1135 | cmd->command &= 0x1fff; | |
1136 | cmd = pa_to_va(cmd->pa_next); | |
1137 | barrier(); | |
1138 | } | |
1139 | ||
1140 | if (lp->cmd_head) | |
1141 | *ack_cmdp |= CUC_START; | |
1142 | lp->scb.pa_cmd = va_to_pa(lp->cmd_head); | |
1143 | spin_unlock_irqrestore(&lp->cmd_lock, flags); | |
1144 | } | |
1145 | ||
1146 | static irqreturn_t | |
cba0516d | 1147 | i596_interrupt(int irq, void *dev_instance) |
28fc1f5a JG |
1148 | { |
1149 | struct net_device *dev = dev_instance; | |
1150 | struct i596_private *lp = dev->priv; | |
1da177e4 LT |
1151 | unsigned short status, ack_cmd = 0; |
1152 | int frames_in = 0; | |
1153 | ||
1da177e4 LT |
1154 | /* |
1155 | * The 82596 examines the command, performs the required action, | |
1156 | * and then clears the SCB command word. | |
1157 | */ | |
1158 | if (lp->scb.command && i596_timeout(dev, "interrupt", 40)) | |
1159 | ; | |
1160 | ||
1161 | /* | |
1162 | * The status word indicates the status of the 82596. | |
1163 | * It is modified only by the 82596. | |
1164 | * | |
1165 | * [So, we must not clear it. I find often status 0xffff, | |
1166 | * which is not one of the values allowed by the docs.] | |
1167 | */ | |
1168 | status = lp->scb.status; | |
1169 | #if 0 | |
1170 | if (i596_debug) { | |
1171 | printk("%s: i596 interrupt, ", dev->name); | |
1172 | i596_out_status(status); | |
1173 | } | |
1174 | #endif | |
1175 | /* Impossible, but it happens - perhaps when we get | |
1176 | a receive interrupt but scb.pa_rfd is I596_NULL. */ | |
1177 | if (status == 0xffff) { | |
1178 | printk("%s: i596_interrupt: got status 0xffff\n", dev->name); | |
1179 | goto out; | |
1180 | } | |
1181 | ||
1182 | ack_cmd = (status & STAT_ACK); | |
1183 | ||
1184 | if (status & (STAT_CX | STAT_CNA)) | |
1185 | i596_handle_CU_completion(dev, lp, status, &ack_cmd); | |
1186 | ||
1187 | if (status & (STAT_FR | STAT_RNR)) { | |
1188 | /* Restart the receive unit when it got inactive somehow */ | |
1189 | if ((status & STAT_RNR) && netif_running(dev)) | |
1190 | ack_cmd |= RX_START; | |
1191 | ||
1192 | if (status & STAT_FR) { | |
1193 | frames_in = i596_rx(dev); | |
1194 | if (!frames_in) | |
1195 | printk("receive frame reported, but no frames\n"); | |
1196 | } | |
1197 | } | |
1198 | ||
1199 | /* acknowledge the interrupt */ | |
1200 | /* | |
1201 | if ((lp->scb.pa_cmd != I596_NULL) && netif_running(dev)) | |
1202 | ack_cmd |= CUC_START; | |
1203 | */ | |
1204 | ||
1205 | if (lp->scb.command && i596_timeout(dev, "i596 interrupt", 100)) | |
1206 | ; | |
1207 | ||
1208 | lp->scb.command = ack_cmd; | |
1209 | ||
1210 | CLEAR_INT(); | |
1211 | CA(); | |
1212 | ||
1213 | out: | |
1214 | return IRQ_HANDLED; | |
1215 | } | |
1216 | ||
1217 | static int i596_close(struct net_device *dev) { | |
1218 | struct i596_private *lp = dev->priv; | |
1219 | ||
1220 | netif_stop_queue(dev); | |
1221 | ||
1222 | if (i596_debug) | |
1223 | printk("%s: Shutting down ethercard, status was %4.4x.\n", | |
1224 | dev->name, lp->scb.status); | |
1225 | ||
1226 | lp->scb.command = (CUC_ABORT | RX_ABORT); | |
1227 | CA(); | |
1228 | ||
1229 | i596_cleanup_cmd(dev); | |
1230 | ||
1231 | if (lp->scb.command && i596_timeout(dev, "i596_close", 200)) | |
1232 | ; | |
1233 | ||
1234 | free_irq(dev->irq, dev); | |
1235 | remove_rx_bufs(dev); | |
1236 | ||
1237 | return 0; | |
1238 | } | |
1239 | ||
1da177e4 LT |
1240 | /* |
1241 | * Set or clear the multicast filter for this adaptor. | |
1242 | */ | |
1243 | ||
1244 | static void set_multicast_list(struct net_device *dev) { | |
1245 | struct i596_private *lp = dev->priv; | |
1246 | struct i596_cmd *cmd; | |
1247 | ||
1248 | if (i596_debug > 1) | |
1249 | printk ("%s: set multicast list %d\n", | |
1250 | dev->name, dev->mc_count); | |
1251 | ||
1252 | if (dev->mc_count > 0) { | |
1253 | struct dev_mc_list *dmi; | |
1254 | char *cp; | |
5cbded58 | 1255 | cmd = kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6, GFP_ATOMIC); |
1da177e4 LT |
1256 | if (cmd == NULL) { |
1257 | printk (KERN_ERR "%s: set_multicast Memory squeeze.\n", dev->name); | |
1258 | return; | |
1259 | } | |
1260 | cmd->command = CmdMulticastList; | |
1261 | *((unsigned short *) (cmd + 1)) = dev->mc_count * 6; | |
1262 | cp = ((char *)(cmd + 1))+2; | |
1263 | for (dmi = dev->mc_list; dmi != NULL; dmi = dmi->next) { | |
1264 | memcpy(cp, dmi,6); | |
1265 | cp += 6; | |
1266 | } | |
1267 | if (i596_debug & LOG_SRCDST) | |
1268 | print_eth (((char *)(cmd + 1)) + 2); | |
1269 | i596_add_cmd(dev, cmd); | |
1270 | } else { | |
1271 | if (lp->set_conf.pa_next != I596_NULL) { | |
1272 | return; | |
1273 | } | |
1274 | if (dev->mc_count == 0 && !(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) { | |
1275 | if (dev->flags & IFF_ALLMULTI) | |
1276 | dev->flags |= IFF_PROMISC; | |
1277 | lp->i596_config[8] &= ~0x01; | |
1278 | } else { | |
1279 | lp->i596_config[8] |= 0x01; | |
1280 | } | |
1281 | ||
1282 | i596_add_cmd(dev, (struct i596_cmd *) &lp->set_conf); | |
1283 | } | |
1284 | } | |
1285 | ||
1286 | MODULE_AUTHOR("Ard van Breemen <[email protected]>"); | |
1287 | MODULE_DESCRIPTION("Intel Panther onboard i82596 driver"); | |
1288 | MODULE_LICENSE("GPL"); | |
1289 | ||
1290 | static struct net_device *dev_lp486e; | |
1291 | static int full_duplex; | |
1292 | static int options; | |
1293 | static int io = IOADDR; | |
1294 | static int irq = IRQ; | |
1295 | ||
1296 | module_param(debug, int, 0); | |
1297 | //module_param(max_interrupt_work, int, 0); | |
1298 | //module_param(reverse_probe, int, 0); | |
1299 | //module_param(rx_copybreak, int, 0); | |
1300 | module_param(options, int, 0); | |
1301 | module_param(full_duplex, int, 0); | |
1302 | ||
1303 | static int __init lp486e_init_module(void) { | |
1304 | int err; | |
1305 | struct net_device *dev = alloc_etherdev(sizeof(struct i596_private)); | |
1306 | if (!dev) | |
1307 | return -ENOMEM; | |
1308 | ||
1309 | dev->irq = irq; | |
1310 | dev->base_addr = io; | |
1311 | err = lp486e_probe(dev); | |
1312 | if (err) { | |
1313 | free_netdev(dev); | |
1314 | return err; | |
1315 | } | |
1316 | err = register_netdev(dev); | |
1317 | if (err) { | |
1318 | release_region(dev->base_addr, LP486E_TOTAL_SIZE); | |
1319 | free_netdev(dev); | |
1320 | return err; | |
1321 | } | |
1322 | dev_lp486e = dev; | |
1323 | full_duplex = 0; | |
1324 | options = 0; | |
1325 | return 0; | |
1326 | } | |
1327 | ||
1328 | static void __exit lp486e_cleanup_module(void) { | |
1329 | unregister_netdev(dev_lp486e); | |
1330 | release_region(dev_lp486e->base_addr, LP486E_TOTAL_SIZE); | |
1331 | free_netdev(dev_lp486e); | |
1332 | } | |
1333 | ||
1334 | module_init(lp486e_init_module); | |
1335 | module_exit(lp486e_cleanup_module); |