Bug Summary

File:obj-scan-build/../linux/src/drivers/net/apricot.c
Location:line 419, column 18
Description:Value stored to 'count' during its initialization is never read

Annotated Source Code

1/* apricot.c: An Apricot 82596 ethernet driver for linux. */
2/*
3 Apricot
4 Written 1994 by Mark Evans.
5 This driver is for the Apricot 82596 bus-master interface
6
7 Modularised 12/94 Mark Evans
8
9 Driver skeleton
10 Written 1993 by Donald Becker.
11 Copyright 1993 United States Government as represented by the Director,
12 National Security Agency. This software may only be used and distributed
13 according to the terms of the GNU Public License as modified by SRC,
14 incorporated herein by reference.
15
16 The author may be reached as becker@super.org or
17 C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
18
19
20*/
21
22static const char *version = "apricot.c:v0.2 05/12/94\n";
23
24#include <linux/module.h>
25
26#include <linux/kernel.h>
27#include <linux/sched.h>
28#include <linux/string.h>
29#include <linux/ptrace.h>
30#include <linux/errno.h>
31#include <linux/ioport.h>
32#include <linux/malloc.h>
33#include <linux/interrupt.h>
34#include <linux/netdevice.h>
35#include <linux/etherdevice.h>
36#include <linux/skbuff.h>
37
38#include <asm/bitops.h>
39#include <asm/io.h>
40#include <asm/dma.h>
41
42#ifndef HAVE_PORTRESERVE
43#define check_region(addr, size) 0
44#define request_region(addr, size,name) do ; while(0)
45#endif
46
47#ifndef HAVE_ALLOC_SKB
48#define alloc_skb(size, priority) (struct sk_buff *) kmalloclinux_kmalloc(size,priority)
49#define kfree_skbmem(buff, size) kfree_s(buff,size)linux_kfree(buff)
50#endif
51
52#define APRICOT_DEBUG1 1
53
54#ifdef APRICOT_DEBUG1
55int i596_debug = APRICOT_DEBUG1;
56#else
57int i596_debug = 1;
58#endif
59
60#define APRICOT_TOTAL_SIZE17 17
61
62#define I596_NULL-1 -1
63
64#define CMD_EOL0x8000 0x8000 /* The last command of the list, stop. */
65#define CMD_SUSP0x4000 0x4000 /* Suspend after doing cmd. */
66#define CMD_INTR0x2000 0x2000 /* Interrupt after doing cmd. */
67
68#define CMD_FLEX0x0008 0x0008 /* Enable flexible memory model */
69
70enum commands {
71 CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
72 CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
73
74#define STAT_C0x8000 0x8000 /* Set to 0 after execution */
75#define STAT_B0x4000 0x4000 /* Command being executed */
76#define STAT_OK0x2000 0x2000 /* Command executed ok */
77#define STAT_A0x1000 0x1000 /* Command aborted */
78
79#define CUC_START0x0100 0x0100
80#define CUC_RESUME0x0200 0x0200
81#define CUC_SUSPEND0x0300 0x0300
82#define CUC_ABORT0x0400 0x0400
83#define RX_START0x0010 0x0010
84#define RX_RESUME0x0020 0x0020
85#define RX_SUSPEND0x0030 0x0030
86#define RX_ABORT0x0040 0x0040
87
88struct i596_cmd {
89 unsigned short status;
90 unsigned short command;
91 struct i596_cmd *next;
92};
93
94#define EOF0x8000 0x8000
95#define SIZE_MASK0x3fff 0x3fff
96
97struct i596_tbd {
98 unsigned short size;
99 unsigned short pad;
100 struct i596_tbd *next;
101 unsigned char *data;
102};
103
104struct tx_cmd {
105 struct i596_cmd cmd;
106 struct i596_tbd *tbd;
107 unsigned short size;
108 unsigned short pad;
109};
110
111struct i596_rfd {
112 unsigned short stat;
113 unsigned short cmd;
114 struct i596_rfd *next;
115 long rbd;
116 unsigned short count;
117 unsigned short size;
118 unsigned char data[1532];
119};
120
121#define RX_RING_SIZE8 8
122
123struct i596_scb {
124 unsigned short status;
125 unsigned short command;
126 struct i596_cmd *cmd;
127 struct i596_rfd *rfd;
128 unsigned long crc_err;
129 unsigned long align_err;
130 unsigned long resource_err;
131 unsigned long over_err;
132 unsigned long rcvdt_err;
133 unsigned long short_err;
134 unsigned short t_on;
135 unsigned short t_off;
136};
137
138struct i596_iscp {
139 unsigned long stat;
140 struct i596_scb *scb;
141};
142
143struct i596_scp {
144 unsigned long sysbus;
145 unsigned long pad;
146 struct i596_iscp *iscp;
147};
148
149struct i596_private {
150 volatile struct i596_scp scp;
151 volatile struct i596_iscp iscp;
152 volatile struct i596_scb scb;
153 volatile struct i596_cmd set_add;
154 char eth_addr[8];
155 volatile struct i596_cmd set_conf;
156 char i596_config[16];
157 volatile struct i596_cmd tdr;
158 unsigned long stat;
159 int last_restart;
160 struct i596_rfd *rx_tail;
161 struct i596_cmd *cmd_tail;
162 struct i596_cmd *cmd_head;
163 int cmd_backlog;
164 unsigned long last_cmd;
165 struct enet_statistics stats;
166};
167
168char init_setup[] = {
169 0x8E, /* length, prefetch on */
170 0xC8, /* fifo to 8, monitor off */
171 0x80, /* don't save bad frames */
172 0x2E, /* No source address insertion, 8 byte preamble */
173 0x00, /* priority and backoff defaults */
174 0x60, /* interframe spacing */
175 0x00, /* slot time LSB */
176 0xf2, /* slot time and retries */
177 0x00, /* promiscuous mode */
178 0x00, /* collision detect */
179 0x40, /* minimum frame length */
180 0xff,
181 0x00,
182 0x7f /* *multi IA */ };
183
184static int i596_open(struct devicelinux_device *dev);
185static int i596_start_xmit(struct sk_buff *skb, struct devicelinux_device *dev);
186static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs);
187static int i596_close(struct devicelinux_device *dev);
188static struct enet_statistics *i596_get_stats(struct devicelinux_device *dev);
189static void i596_add_cmd(struct devicelinux_device *dev, struct i596_cmd *cmd);
190static void print_eth(unsigned char *);
191static void set_multicast_list(struct devicelinux_device *dev);
192
193
194static inlineinline __attribute__((always_inline)) int
195init_rx_bufs(struct devicelinux_device *dev, int num)
196{
197 struct i596_private *lp = (struct i596_private *)dev->priv;
198 int i;
199 struct i596_rfd *rfd;
200
201 lp->scb.rfd = (struct i596_rfd *)I596_NULL-1;
202
203 if (i596_debug > 1) printk ("%s: init_rx_bufs %d.\n", dev->name, num);
204
205 for (i = 0; i < num; i++)
206 {
207 if (!(rfd = (struct i596_rfd *)kmalloclinux_kmalloc(sizeof(struct i596_rfd), GFP_KERNEL0x03)))
208 break;
209
210 rfd->stat = 0x0000;
211 rfd->rbd = I596_NULL-1;
212 rfd->count = 0;
213 rfd->size = 1532;
214 if (i == 0)
215 {
216 rfd->cmd = CMD_EOL0x8000;
217 lp->rx_tail = rfd;
218 }
219 else
220 rfd->cmd = 0x0000;
221
222 rfd->next = lp->scb.rfd;
223 lp->scb.rfd = rfd;
224 }
225
226 if (i != 0)
227 lp->rx_tail->next = lp->scb.rfd;
228
229 return (i);
230}
231
232static inlineinline __attribute__((always_inline)) void
233remove_rx_bufs(struct devicelinux_device *dev)
234{
235 struct i596_private *lp = (struct i596_private *)dev->priv;
236 struct i596_rfd *rfd = lp->scb.rfd;
237
238 lp->rx_tail->next = (struct i596_rfd *)I596_NULL-1;
239
240 do
241 {
242 lp->scb.rfd = rfd->next;
243 kfree_s(rfd, sizeof(struct i596_rfd))linux_kfree(rfd);
244 rfd = lp->scb.rfd;
245 }
246 while (rfd != lp->rx_tail);
247}
248
249static inlineinline __attribute__((always_inline)) void
250init_i596_mem(struct devicelinux_device *dev)
251{
252 struct i596_private *lp = (struct i596_private *)dev->priv;
253 short ioaddr = dev->base_addr;
254 int boguscnt = 100;
255
256 /* change the scp address */
257 outw(0, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0),(ioaddr)) : __outw((0),(ioaddr)))
;
258 outw(0, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((0),(ioaddr)) : __outw((0),(ioaddr)))
;
259 outb(4, ioaddr+0xf)((__builtin_constant_p((ioaddr+0xf)) && (ioaddr+0xf) <
256) ? __outbc((4),(ioaddr+0xf)) : __outb((4),(ioaddr+0xf)))
;
260 outw(((((int)&lp->scp) & 0xffff) | 2), ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc((((((int)&lp->scp) & 0xffff) | 2)),(ioaddr
)) : __outw((((((int)&lp->scp) & 0xffff) | 2)),(ioaddr
)))
;
261 outw((((int)&lp->scp)>>16) & 0xffff, ioaddr)((__builtin_constant_p((ioaddr)) && (ioaddr) < 256
) ? __outwc(((((int)&lp->scp)>>16) & 0xffff)
,(ioaddr)) : __outw(((((int)&lp->scp)>>16) &
0xffff),(ioaddr)))
;
262
263 lp->last_cmd = jiffies;
264
265 lp->scp.sysbus = 0x00440000;
266 lp->scp.iscp = &(lp->iscp);
267 lp->iscp.scb = &(lp->scb);
268 lp->iscp.stat = 0x0001;
269 lp->cmd_backlog = 0;
270
271 lp->cmd_head = lp->scb.cmd = (struct i596_cmd *) I596_NULL-1;
272
273 if (i596_debug > 2) printk("%s: starting i82596.\n", dev->name);
274
275 (void) inb (ioaddr+0x10)((__builtin_constant_p((ioaddr+0x10)) && (ioaddr+0x10
) < 256) ? __inbc(ioaddr+0x10) : __inb(ioaddr+0x10))
;
276 outb(4, ioaddr+0xf)((__builtin_constant_p((ioaddr+0xf)) && (ioaddr+0xf) <
256) ? __outbc((4),(ioaddr+0xf)) : __outb((4),(ioaddr+0xf)))
;
277 outw(0, ioaddr+4)((__builtin_constant_p((ioaddr+4)) && (ioaddr+4) <
256) ? __outwc((0),(ioaddr+4)) : __outw((0),(ioaddr+4)))
;
278
279 while (lp->iscp.stat)
280 if (--boguscnt == 0)
281 {
282 printk("%s: i82596 initialization timed out with status %4.4x, cmd %4.4x.\n",
283 dev->name, lp->scb.status, lp->scb.command);
284 break;
285 }
286
287 lp->scb.command = 0;
288
289 memcpy (lp->i596_config, init_setup, 14)(__builtin_constant_p(14) ? __constant_memcpy((lp->i596_config
),(init_setup),(14)) : __memcpy((lp->i596_config),(init_setup
),(14)))
;
290 lp->set_conf.command = CmdConfigure;
291 i596_add_cmd(dev, &lp->set_conf);
292
293 memcpy (lp->eth_addr, dev->dev_addr, 6)(__builtin_constant_p(6) ? __constant_memcpy((lp->eth_addr
),(dev->dev_addr),(6)) : __memcpy((lp->eth_addr),(dev->
dev_addr),(6)))
;
294 lp->set_add.command = CmdSASetup;
295 i596_add_cmd(dev, &lp->set_add);
296
297 lp->tdr.command = CmdTDR;
298 i596_add_cmd(dev, &lp->tdr);
299
300 boguscnt = 200;
301 while (lp->scb.status, lp->scb.command)
302 if (--boguscnt == 0)
303 {
304 printk("%s: receive unit start timed out with status %4.4x, cmd %4.4x.\n",
305 dev->name, lp->scb.status, lp->scb.command);
306 break;
307 }
308
309 lp->scb.command = RX_START0x0010;
310 outw(0, ioaddr+4)((__builtin_constant_p((ioaddr+4)) && (ioaddr+4) <
256) ? __outwc((0),(ioaddr+4)) : __outw((0),(ioaddr+4)))
;
311
312 boguscnt = 200;
313 while (lp->scb.status, lp->scb.command)
314 if (--boguscnt == 0)
315 {
316 printk("i82596 init timed out with status %4.4x, cmd %4.4x.\n",
317 lp->scb.status, lp->scb.command);
318 break;
319 }
320
321 return;
322}
323
324static inlineinline __attribute__((always_inline)) int
325i596_rx(struct devicelinux_device *dev)
326{
327 struct i596_private *lp = (struct i596_private *)dev->priv;
328 int frames = 0;
329
330 if (i596_debug > 3) printk ("i596_rx()\n");
331
332 while ((lp->scb.rfd->stat) & STAT_C0x8000)
333 {
334 if (i596_debug >2) print_eth(lp->scb.rfd->data);
335
336 if ((lp->scb.rfd->stat) & STAT_OK0x2000)
337 {
338 /* a good frame */
339 int pkt_len = lp->scb.rfd->count & 0x3fff;
340 struct sk_buff *skb = dev_alloc_skb(pkt_len);
341
342 frames++;
343
344 if (skb == NULL((void *) 0))
345 {
346 printk ("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
347 lp->stats.rx_dropped++;
348 break;
349 }
350
351 skb->dev = dev;
352 memcpy(skb_put(skb,pkt_len), lp->scb.rfd->data, pkt_len)(__builtin_constant_p(pkt_len) ? __constant_memcpy((skb_put(skb
,pkt_len)),(lp->scb.rfd->data),(pkt_len)) : __memcpy((skb_put
(skb,pkt_len)),(lp->scb.rfd->data),(pkt_len)))
;
353
354 skb->protocol=eth_type_trans(skb,dev)((unsigned short)0);
355 netif_rx(skb);
356 lp->stats.rx_packets++;
357
358 if (i596_debug > 4) print_eth(skb->data);
359 }
360 else
361 {
362 lp->stats.rx_errors++;
363 if ((lp->scb.rfd->stat) & 0x0001) lp->stats.collisions++;
364 if ((lp->scb.rfd->stat) & 0x0080) lp->stats.rx_length_errors++;
365 if ((lp->scb.rfd->stat) & 0x0100) lp->stats.rx_over_errors++;
366 if ((lp->scb.rfd->stat) & 0x0200) lp->stats.rx_fifo_errors++;
367 if ((lp->scb.rfd->stat) & 0x0400) lp->stats.rx_frame_errors++;
368 if ((lp->scb.rfd->stat) & 0x0800) lp->stats.rx_crc_errors++;
369 if ((lp->scb.rfd->stat) & 0x1000) lp->stats.rx_length_errors++;
370 }
371
372 lp->scb.rfd->stat = 0;
373 lp->rx_tail->cmd = 0;
374 lp->rx_tail = lp->scb.rfd;
375 lp->scb.rfd = lp->scb.rfd->next;
376 lp->rx_tail->count = 0;
377 lp->rx_tail->cmd = CMD_EOL0x8000;
378
379 }
380
381 if (i596_debug > 3) printk ("frames %d\n", frames);
382
383 return 0;
384}
385
386static inlineinline __attribute__((always_inline)) void
387i596_cleanup_cmd(struct i596_private *lp)
388{
389 struct i596_cmd *ptr;
390 int boguscnt = 100;
391
392 if (i596_debug > 4) printk ("i596_cleanup_cmd\n");
393
394 while (lp->cmd_head != (struct i596_cmd *) I596_NULL-1)
395 {
396 ptr = lp->cmd_head;
397
398 lp->cmd_head = lp->cmd_head->next;
399 lp->cmd_backlog--;
400
401 switch ((ptr->command) & 0x7)
402 {
403 case CmdTx:
404 {
405 struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
406 struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
407
408 dev_kfree_skb(skb, FREE_WRITE0);
409
410 lp->stats.tx_errors++;
411 lp->stats.tx_aborted_errors++;
412
413 ptr->next = (struct i596_cmd * ) I596_NULL-1;
414 kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)))linux_kfree((unsigned char *)tx_cmd);
415 break;
416 }
417 case CmdMulticastList:
418 {
419 unsigned short count = *((unsigned short *) (ptr + 1));
Value stored to 'count' during its initialization is never read
420
421 ptr->next = (struct i596_cmd * ) I596_NULL-1;
422 kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2))linux_kfree((unsigned char *)ptr);
423 break;
424 }
425 default:
426 ptr->next = (struct i596_cmd * ) I596_NULL-1;
427 }
428 }
429
430 while (lp->scb.status, lp->scb.command)
431 if (--boguscnt == 0)
432 {
433 printk("i596_cleanup_cmd timed out with status %4.4x, cmd %4.4x.\n",
434 lp->scb.status, lp->scb.command);
435 break;
436 }
437
438 lp->scb.cmd = lp->cmd_head;
439}
440
441static inlineinline __attribute__((always_inline)) void
442i596_reset(struct devicelinux_device *dev, struct i596_private *lp, int ioaddr)
443{
444 int boguscnt = 100;
445
446 if (i596_debug > 4) printk ("i596_reset\n");
447
448 while (lp->scb.status, lp->scb.command)
449 if (--boguscnt == 0)
450 {
451 printk("i596_reset timed out with status %4.4x, cmd %4.4x.\n",
452 lp->scb.status, lp->scb.command);
453 break;
454 }
455
456 dev->start = 0;
457 dev->tbusy = 1;
458
459 lp->scb.command = CUC_ABORT0x0400|RX_ABORT0x0040;
460 outw(0, ioaddr+4)((__builtin_constant_p((ioaddr+4)) && (ioaddr+4) <
256) ? __outwc((0),(ioaddr+4)) : __outw((0),(ioaddr+4)))
;
461
462 /* wait for shutdown */
463 boguscnt = 400;
464
465 while ((lp->scb.status, lp->scb.command) || lp->scb.command)
466 if (--boguscnt == 0)
467 {
468 printk("i596_reset 2 timed out with status %4.4x, cmd %4.4x.\n",
469 lp->scb.status, lp->scb.command);
470 break;
471 }
472
473 i596_cleanup_cmd(lp);
474 i596_rx(dev);
475
476 dev->start = 1;
477 dev->tbusy = 0;
478 dev->interrupt = 0;
479 init_i596_mem(dev);
480}
481
482static void i596_add_cmd(struct devicelinux_device *dev, struct i596_cmd *cmd)
483{
484 struct i596_private *lp = (struct i596_private *)dev->priv;
485 int ioaddr = dev->base_addr;
486 unsigned long flags;
487 int boguscnt = 100;
488
489 if (i596_debug > 4) printk ("i596_add_cmd\n");
490
491 cmd->status = 0;
492 cmd->command |= (CMD_EOL0x8000|CMD_INTR0x2000);
493 cmd->next = (struct i596_cmd *) I596_NULL-1;
494
495 save_flags(flags)__asm__ __volatile__("pushf ; pop %0" : "=r" (flags): :"memory"
)
;
496 cli()__asm__ __volatile__ ("cli": : :"memory");
497 if (lp->cmd_head != (struct i596_cmd *) I596_NULL-1)
498 lp->cmd_tail->next = cmd;
499 else
500 {
501 lp->cmd_head = cmd;
502 while (lp->scb.status, lp->scb.command)
503 if (--boguscnt == 0)
504 {
505 printk("i596_add_cmd timed out with status %4.4x, cmd %4.4x.\n",
506 lp->scb.status, lp->scb.command);
507 break;
508 }
509
510 lp->scb.cmd = cmd;
511 lp->scb.command = CUC_START0x0100;
512 outw (0, ioaddr+4)((__builtin_constant_p((ioaddr+4)) && (ioaddr+4) <
256) ? __outwc((0),(ioaddr+4)) : __outw((0),(ioaddr+4)))
;
513 }
514 lp->cmd_tail = cmd;
515 lp->cmd_backlog++;
516
517 lp->cmd_head = lp->scb.cmd;
518 restore_flags(flags)__asm__ __volatile__("push %0 ; popf": :"g" (flags):"memory");
519
520 if (lp->cmd_backlog > 16)
521 {
522 int tickssofar = jiffies - lp->last_cmd;
523
524 if (tickssofar < 25) return;
525
526 printk("%s: command unit timed out, status resetting.\n", dev->name);
527
528 i596_reset(dev, lp, ioaddr);
529 }
530}
531
532static int
533i596_open(struct devicelinux_device *dev)
534{
535 int i;
536
537 if (i596_debug > 1)
538 printk("%s: i596_open() irq %d.\n", dev->name, dev->irq);
539
540 if (request_irq(dev->irq, &i596_interrupt, 0, "apricot", NULL((void *) 0)))
541 return -EAGAIN11;
542
543 irq2dev_map[dev->irq] = dev;
544
545 i = init_rx_bufs(dev, RX_RING_SIZE8);
546
547 if ((i = init_rx_bufs(dev, RX_RING_SIZE8)) < RX_RING_SIZE8)
548 printk("%s: only able to allocate %d receive buffers\n", dev->name, i);
549
550 if (i < 4)
551 {
552 free_irq(dev->irq, NULL((void *) 0));
553 irq2dev_map[dev->irq] = 0;
554 return -EAGAIN11;
555 }
556
557 dev->tbusy = 0;
558 dev->interrupt = 0;
559 dev->start = 1;
560 MOD_INC_USE_COUNTdo { } while (0);
561
562 /* Initialize the 82596 memory */
563 init_i596_mem(dev);
564
565 return 0; /* Always succeed */
566}
567
568static int
569i596_start_xmit(struct sk_buff *skb, struct devicelinux_device *dev)
570{
571 struct i596_private *lp = (struct i596_private *)dev->priv;
572 int ioaddr = dev->base_addr;
573 struct tx_cmd *tx_cmd;
574
575 if (i596_debug > 2) printk ("%s: Apricot start xmit\n", dev->name);
576
577 /* Transmitter timeout, serious problems. */
578 if (dev->tbusy) {
579 int tickssofar = jiffies - dev->trans_start;
580 if (tickssofar < 5)
581 return 1;
582 printk("%s: transmit timed out, status resetting.\n",
583 dev->name);
584 lp->stats.tx_errors++;
585 /* Try to restart the adaptor */
586 if (lp->last_restart == lp->stats.tx_packets) {
587 if (i596_debug > 1) printk ("Resetting board.\n");
588
589 /* Shutdown and restart */
590 i596_reset(dev,lp, ioaddr);
591 } else {
592 /* Issue a channel attention signal */
593 if (i596_debug > 1) printk ("Kicking board.\n");
594
595 lp->scb.command = CUC_START0x0100|RX_START0x0010;
596 outw(0, ioaddr+4)((__builtin_constant_p((ioaddr+4)) && (ioaddr+4) <
256) ? __outwc((0),(ioaddr+4)) : __outw((0),(ioaddr+4)))
;
597
598 lp->last_restart = lp->stats.tx_packets;
599 }
600 dev->tbusy = 0;
601 dev->trans_start = jiffies;
602 }
603
604 /* If some higher level thinks we've misses a tx-done interrupt
605 we are passed NULL. n.b. dev_tint handles the cli()/sti()
606 itself. */
607 if (skb == NULL((void *) 0)) {
608 dev_tint(dev);
609 return 0;
610 }
611
612 /* shouldn't happen */
613 if (skb->len <= 0) return 0;
614
615 if (i596_debug > 3) printk("%s: i596_start_xmit() called\n", dev->name);
616
617 /* Block a timer-based transmit from overlapping. This could better be
618 done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
619 if (set_bit(0, (void*)&dev->tbusy) != 0)
620 printk("%s: Transmitter access conflict.\n", dev->name);
621 else
622 {
623 short length = ETH_ZLEN60 < skb->len ? skb->len : ETH_ZLEN60;
624 dev->trans_start = jiffies;
625
626 tx_cmd = (struct tx_cmd *) kmalloclinux_kmalloc ((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC0x01);
627 if (tx_cmd == NULL((void *) 0))
628 {
629 printk ("%s: i596_xmit Memory squeeze, dropping packet.\n", dev->name);
630 lp->stats.tx_dropped++;
631
632 dev_kfree_skb(skb, FREE_WRITE0);
633 }
634 else
635 {
636 tx_cmd->tbd = (struct i596_tbd *) (tx_cmd + 1);
637 tx_cmd->tbd->next = (struct i596_tbd *) I596_NULL-1;
638
639 tx_cmd->cmd.command = CMD_FLEX0x0008|CmdTx;
640
641 tx_cmd->pad = 0;
642 tx_cmd->size = 0;
643 tx_cmd->tbd->pad = 0;
644 tx_cmd->tbd->size = EOF0x8000 | length;
645
646 tx_cmd->tbd->data = skb->data;
647
648 if (i596_debug > 3) print_eth(skb->data);
649
650 i596_add_cmd(dev, (struct i596_cmd *)tx_cmd);
651
652 lp->stats.tx_packets++;
653 }
654 }
655
656 dev->tbusy = 0;
657
658 return 0;
659}
660
661
662static void print_eth(unsigned char *add)
663{
664 int i;
665
666 printk ("Dest ");
667 for (i = 0; i < 6; i++)
668 printk(" %2.2X", add[i]);
669 printk ("\n");
670
671 printk ("Source");
672 for (i = 0; i < 6; i++)
673 printk(" %2.2X", add[i+6]);
674 printk ("\n");
675 printk ("type %2.2X%2.2X\n", add[12], add[13]);
676}
677
678int apricot_probe(struct devicelinux_device *dev)
679{
680 int i;
681 struct i596_private *lp;
682 int checksum = 0;
683 int ioaddr = 0x300;
684 char eth_addr[8];
685
686 /* this is easy the ethernet interface can only be at 0x300 */
687 /* first check nothing is already registered here */
688
689 if (check_region(ioaddr, APRICOT_TOTAL_SIZE17))
690 return ENODEV19;
691
692 for (i = 0; i < 8; i++)
693 {
694 eth_addr[i] = inb(ioaddr+8+i)((__builtin_constant_p((ioaddr+8 +i)) && (ioaddr+8 +i
) < 256) ? __inbc(ioaddr+8 +i) : __inb(ioaddr+8 +i))
;
695 checksum += eth_addr[i];
696 }
697
698 /* checksum is a multiple of 0x100, got this wrong first time
699 some machines have 0x100, some 0x200. The DOS driver doesn't
700 even bother with the checksum */
701
702 if (checksum % 0x100) return ENODEV19;
703
704 /* Some other boards trip the checksum.. but then appear as ether
705 address 0. Trap these - AC */
706
707 if(memcmp__builtin_memcmp(eth_addr,"\x00\x00\x49",3)!= 0)
708 return ENODEV19;
709
710 request_region(ioaddr, APRICOT_TOTAL_SIZE17, "apricot");
711
712 dev->base_addr = ioaddr;
713 ether_setup(dev);
714 printk("%s: Apricot 82596 at %#3x,", dev->name, ioaddr);
715
716 for (i = 0; i < 6; i++)
717 printk(" %2.2X", dev->dev_addr[i] = eth_addr[i]);
718
719 dev->base_addr = ioaddr;
720 dev->irq = 10;
721 printk(" IRQ %d.\n", dev->irq);
722
723 if (i596_debug > 0) printk(version);
724
725 /* The APRICOT-specific entries in the device structure. */
726 dev->open = &i596_open;
727 dev->stop = &i596_close;
728 dev->hard_start_xmit = &i596_start_xmit;
729 dev->get_stats = &i596_get_stats;
730 dev->set_multicast_list = &set_multicast_list;
731
732 dev->mem_start = (int)kmalloclinux_kmalloc(sizeof(struct i596_private)+ 0x0f, GFP_KERNEL0x03);
733 /* align for scp */
734 dev->priv = (void *)((dev->mem_start + 0xf) & 0xfffffff0);
735
736 lp = (struct i596_private *)dev->priv;
737 memset((void *)lp, 0, sizeof(struct i596_private))(__builtin_constant_p(0) ? (__builtin_constant_p((sizeof(struct
i596_private))) ? __constant_c_and_count_memset((((void *)lp
)),((0x01010101UL*(unsigned char)(0))),((sizeof(struct i596_private
)))) : __constant_c_memset((((void *)lp)),((0x01010101UL*(unsigned
char)(0))),((sizeof(struct i596_private))))) : (__builtin_constant_p
((sizeof(struct i596_private))) ? __memset_generic(((((void *
)lp))),(((0))),(((sizeof(struct i596_private))))) : __memset_generic
((((void *)lp)),((0)),((sizeof(struct i596_private))))))
;
738 lp->scb.command = 0;
739 lp->scb.cmd = (struct i596_cmd *) I596_NULL-1;
740 lp->scb.rfd = (struct i596_rfd *)I596_NULL-1;
741
742 return 0;
743}
744
745static void
746i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
747{
748 struct devicelinux_device *dev = (struct devicelinux_device *)(irq2dev_map[irq]);
749 struct i596_private *lp;
750 short ioaddr;
751 int boguscnt = 200;
752 unsigned short status, ack_cmd = 0;
753
754 if (dev == NULL((void *) 0)) {
755 printk ("i596_interrupt(): irq %d for unknown device.\n", irq);
756 return;
757 }
758
759 if (i596_debug > 3) printk ("%s: i596_interrupt(): irq %d\n",dev->name, irq);
760
761 if (dev->interrupt)
762 printk("%s: Re-entering the interrupt handler.\n", dev->name);
763
764 dev->interrupt = 1;
765
766 ioaddr = dev->base_addr;
767
768 lp = (struct i596_private *)dev->priv;
769
770 while (lp->scb.status, lp->scb.command)
771 if (--boguscnt == 0)
772 {
773 printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
774 break;
775 }
776 status = lp->scb.status;
777
778 if (i596_debug > 4)
779 printk("%s: i596 interrupt, status %4.4x.\n", dev->name, status);
780
781 ack_cmd = status & 0xf000;
782
783 if ((status & 0x8000) || (status & 0x2000))
784 {
785 struct i596_cmd *ptr;
786
787 if ((i596_debug > 4) && (status & 0x8000))
788 printk("%s: i596 interrupt completed command.\n", dev->name);
789 if ((i596_debug > 4) && (status & 0x2000))
790 printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700);
791
792 while ((lp->cmd_head != (struct i596_cmd *) I596_NULL-1) && (lp->cmd_head->status & STAT_C0x8000))
793 {
794 ptr = lp->cmd_head;
795
796 lp->cmd_head = lp->cmd_head->next;
797 lp->cmd_backlog--;
798
799 switch ((ptr->command) & 0x7)
800 {
801 case CmdTx:
802 {
803 struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
804 struct sk_buff *skb = ((struct sk_buff *)(tx_cmd->tbd->data)) -1;
805
806 dev_kfree_skb(skb, FREE_WRITE0);
807
808 if ((ptr->status) & STAT_OK0x2000)
809 {
810 if (i596_debug >2) print_eth(skb->data);
811 }
812 else
813 {
814 lp->stats.tx_errors++;
815 if ((ptr->status) & 0x0020) lp->stats.collisions++;
816 if (!((ptr->status) & 0x0040)) lp->stats.tx_heartbeat_errors++;
817 if ((ptr->status) & 0x0400) lp->stats.tx_carrier_errors++;
818 if ((ptr->status) & 0x0800) lp->stats.collisions++;
819 if ((ptr->status) & 0x1000) lp->stats.tx_aborted_errors++;
820 }
821
822
823 ptr->next = (struct i596_cmd * ) I596_NULL-1;
824 kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)))linux_kfree((unsigned char *)tx_cmd);
825 break;
826 }
827 case CmdMulticastList:
828 {
829 unsigned short count = *((unsigned short *) (ptr + 1));
830
831 ptr->next = (struct i596_cmd * ) I596_NULL-1;
832 kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2))linux_kfree((unsigned char *)ptr);
833 break;
834 }
835 case CmdTDR:
836 {
837 unsigned long status = *((unsigned long *) (ptr + 1));
838
839 if (status & 0x8000)
840 {
841 if (i596_debug > 3)
842 printk("%s: link ok.\n", dev->name);
843 }
844 else
845 {
846 if (status & 0x4000)
847 printk("%s: Transceiver problem.\n", dev->name);
848 if (status & 0x2000)
849 printk("%s: Termination problem.\n", dev->name);
850 if (status & 0x1000)
851 printk("%s: Short circuit.\n", dev->name);
852
853 printk("%s: Time %ld.\n", dev->name, status & 0x07ff);
854 }
855 }
856 default:
857 ptr->next = (struct i596_cmd * ) I596_NULL-1;
858
859 lp->last_cmd = jiffies;
860 }
861 }
862
863 ptr = lp->cmd_head;
864 while ((ptr != (struct i596_cmd *) I596_NULL-1) && (ptr != lp->cmd_tail))
865 {
866 ptr->command &= 0x1fff;
867 ptr = ptr->next;
868 }
869
870 if ((lp->cmd_head != (struct i596_cmd *) I596_NULL-1) && (dev->start)) ack_cmd |= CUC_START0x0100;
871 lp->scb.cmd = lp->cmd_head;
872 }
873
874 if ((status & 0x1000) || (status & 0x4000))
875 {
876 if ((i596_debug > 4) && (status & 0x4000))
877 printk("%s: i596 interrupt received a frame.\n", dev->name);
878 if ((i596_debug > 4) && (status & 0x1000))
879 printk("%s: i596 interrupt receive unit inactive %x.\n", dev->name, status & 0x0070);
880
881 i596_rx(dev);
882
883 if (dev->start) ack_cmd |= RX_START0x0010;
884 }
885
886 /* acknowledge the interrupt */
887
888/*
889 if ((lp->scb.cmd != (struct i596_cmd *) I596_NULL) && (dev->start)) ack_cmd | = CUC_START;
890*/
891 boguscnt = 100;
892 while (lp->scb.status, lp->scb.command)
893 if (--boguscnt == 0)
894 {
895 printk("%s: i596 interrupt, timeout status %4.4x command %4.4x.\n", dev->name, lp->scb.status, lp->scb.command);
896 break;
897 }
898 lp->scb.command = ack_cmd;
899
900 (void) inb (ioaddr+0x10)((__builtin_constant_p((ioaddr+0x10)) && (ioaddr+0x10
) < 256) ? __inbc(ioaddr+0x10) : __inb(ioaddr+0x10))
;
901 outb (4, ioaddr+0xf)((__builtin_constant_p((ioaddr+0xf)) && (ioaddr+0xf) <
256) ? __outbc((4),(ioaddr+0xf)) : __outb((4),(ioaddr+0xf)))
;
902 outw (0, ioaddr+4)((__builtin_constant_p((ioaddr+4)) && (ioaddr+4) <
256) ? __outwc((0),(ioaddr+4)) : __outw((0),(ioaddr+4)))
;
903
904 if (i596_debug > 4)
905 printk("%s: exiting interrupt.\n", dev->name);
906
907 dev->interrupt = 0;
908 return;
909}
910
911static int
912i596_close(struct devicelinux_device *dev)
913{
914 int ioaddr = dev->base_addr;
915 struct i596_private *lp = (struct i596_private *)dev->priv;
916 int boguscnt = 200;
917
918 dev->start = 0;
919 dev->tbusy = 1;
920
921 if (i596_debug > 1)
922 printk("%s: Shutting down ethercard, status was %4.4x.\n",
923 dev->name, lp->scb.status);
924
925 lp->scb.command = CUC_ABORT0x0400|RX_ABORT0x0040;
926 outw(0, ioaddr+4)((__builtin_constant_p((ioaddr+4)) && (ioaddr+4) <
256) ? __outwc((0),(ioaddr+4)) : __outw((0),(ioaddr+4)))
;
927
928 i596_cleanup_cmd(lp);
929
930 while (lp->scb.status, lp->scb.command)
931 if (--boguscnt == 0)
932 {
933 printk("%s: close timed out with status %4.4x, cmd %4.4x.\n",
934 dev->name, lp->scb.status, lp->scb.command);
935 break;
936 }
937 free_irq(dev->irq, NULL((void *) 0));
938 irq2dev_map[dev->irq] = 0;
939 remove_rx_bufs(dev);
940 MOD_DEC_USE_COUNTdo { } while (0);
941
942 return 0;
943}
944
945static struct enet_statistics *
946i596_get_stats(struct devicelinux_device *dev)
947{
948 struct i596_private *lp = (struct i596_private *)dev->priv;
949
950 return &lp->stats;
951}
952
953/*
954 * Set or clear the multicast filter for this adaptor.
955 */
956
957static void set_multicast_list(struct devicelinux_device *dev)
958{
959 struct i596_private *lp = (struct i596_private *)dev->priv;
960 struct i596_cmd *cmd;
961
962 if (i596_debug > 1)
963 printk ("%s: set multicast list %d\n", dev->name, dev->mc_count);
964
965 if (dev->mc_count > 0)
966 {
967 struct dev_mc_list *dmi;
968 char *cp;
969 cmd = (struct i596_cmd *) kmalloclinux_kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6, GFP_ATOMIC0x01);
970 if (cmd == NULL((void *) 0))
971 {
972 printk ("%s: set_multicast Memory squeeze.\n", dev->name);
973 return;
974 }
975 cmd->command = CmdMulticastList;
976 *((unsigned short *) (cmd + 1)) = dev->mc_count * 6;
977 cp=((char *)(cmd + 1))+2;
978 for(dmi=dev->mc_list;dmi!=NULL((void *) 0);dmi=dmi->next)
979 {
980 memcpy(cp, dmi,6)(__builtin_constant_p(6) ? __constant_memcpy((cp),(dmi),(6)) :
__memcpy((cp),(dmi),(6)))
;
981 cp+=6;
982 }
983 print_eth (((unsigned char *)(cmd + 1)) + 2);
984 i596_add_cmd(dev, cmd);
985 }
986 else
987 {
988 if (lp->set_conf.next != (struct i596_cmd * ) I596_NULL-1)
989 return;
990 if (dev->mc_count == 0 && !(dev->flags&(IFF_PROMISC0x100|IFF_ALLMULTI0x200)))
991 {
992 if(dev->flags&IFF_ALLMULTI0x200)
993 dev->flags|=IFF_PROMISC0x100;
994 lp->i596_config[8] &= ~0x01;
995 }
996 else
997 lp->i596_config[8] |= 0x01;
998
999 i596_add_cmd(dev, &lp->set_conf);
1000 }
1001}
1002
1003#ifdef HAVE_DEVLIST
1004static unsigned int apricot_portlist[] = {0x300, 0};
1005struct netdev_entry apricot_drv =
1006{"apricot", apricot_probe, APRICOT_TOTAL_SIZE17, apricot_portlist};
1007#endif
1008
1009#ifdef MODULE
1010static char devicename[9] = { 0, };
1011static struct devicelinux_device dev_apricot = {
1012 devicename, /* device name inserted by /linux/drivers/net/net_init.c */
1013 0, 0, 0, 0,
1014 0x300, 10,
1015 0, 0, 0, NULL((void *) 0), apricot_probe };
1016
1017static int io = 0x300;
1018static int irq = 10;
1019
1020int
1021init_module(void)
1022{
1023 dev_apricot.base_addr = io;
1024 dev_apricot.irq = irq;
1025 if (register_netdev(&dev_apricot) != 0)
1026 return -EIO5;
1027 return 0;
1028}
1029
1030void
1031cleanup_module(void)
1032{
1033 unregister_netdev(&dev_apricot);
1034 kfree_s((void *)dev_apricot.mem_start, sizeof(struct i596_private) + 0xf)linux_kfree((void *)dev_apricot.mem_start);
1035 dev_apricot.priv = NULL((void *) 0);
1036
1037 /* If we don't do this, we can't re-insmod it later. */
1038 release_region(dev_apricot.base_addr, APRICOT_TOTAL_SIZE17);
1039}
1040#endif /* MODULE */
1041
1042/*
1043 * Local variables:
1044 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c apricot.c"
1045 * End:
1046 */