OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [net/] [apricot.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* 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
 
22
static 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 *) kmalloc(size,priority)
49
#define kfree_skbmem(buff, size) kfree_s(buff,size)
50
#endif
51
 
52
#define APRICOT_DEBUG 1
53
 
54
#ifdef APRICOT_DEBUG
55
int i596_debug = APRICOT_DEBUG;
56
#else
57
int i596_debug = 1;
58
#endif
59
 
60
#define APRICOT_TOTAL_SIZE 17
61
 
62
#define I596_NULL -1
63
 
64
#define CMD_EOL         0x8000  /* The last command of the list, stop. */
65
#define CMD_SUSP        0x4000  /* Suspend after doing cmd. */
66
#define CMD_INTR        0x2000  /* Interrupt after doing cmd. */
67
 
68
#define CMD_FLEX        0x0008  /* Enable flexible memory model */
69
 
70
enum commands {
71
        CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
72
        CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
73
 
74
#define STAT_C          0x8000  /* Set to 0 after execution */
75
#define STAT_B          0x4000  /* Command being executed */
76
#define STAT_OK         0x2000  /* Command executed ok */
77
#define STAT_A          0x1000  /* Command aborted */
78
 
79
#define  CUC_START      0x0100
80
#define  CUC_RESUME     0x0200
81
#define  CUC_SUSPEND    0x0300
82
#define  CUC_ABORT      0x0400
83
#define  RX_START       0x0010
84
#define  RX_RESUME      0x0020
85
#define  RX_SUSPEND     0x0030
86
#define  RX_ABORT       0x0040
87
 
88
struct i596_cmd {
89
    unsigned short status;
90
    unsigned short command;
91
    struct i596_cmd *next;
92
};
93
 
94
#define EOF             0x8000
95
#define SIZE_MASK       0x3fff
96
 
97
struct i596_tbd {
98
    unsigned short size;
99
    unsigned short pad;
100
    struct i596_tbd *next;
101
    char *data;
102
};
103
 
104
struct tx_cmd {
105
    struct i596_cmd cmd;
106
    struct i596_tbd *tbd;
107
    unsigned short size;
108
    unsigned short pad;
109
};
110
 
111
struct 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
    char data[1532];
119
};
120
 
121
#define RX_RING_SIZE 8
122
 
123
struct 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
 
138
struct i596_iscp {
139
    unsigned long stat;
140
    struct i596_scb *scb;
141
};
142
 
143
struct i596_scp {
144
    unsigned long sysbus;
145
    unsigned long pad;
146
    struct i596_iscp *iscp;
147
};
148
 
149
struct 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
 
168
char 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
 
184
static int i596_open(struct device *dev);
185
static int i596_start_xmit(struct sk_buff *skb, struct device *dev);
186
static void i596_interrupt(int irq, void *dev_id, struct pt_regs *regs);
187
static int i596_close(struct device *dev);
188
static struct enet_statistics *i596_get_stats(struct device *dev);
189
static void i596_add_cmd(struct device *dev, struct i596_cmd *cmd);
190
static void print_eth(char *);
191
static void set_multicast_list(struct device *dev);
192
 
193
 
194
static inline int
195
init_rx_bufs(struct 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;
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 *)kmalloc(sizeof(struct i596_rfd), GFP_KERNEL)))
208
            break;
209
 
210
        rfd->stat = 0x0000;
211
        rfd->rbd = I596_NULL;
212
        rfd->count = 0;
213
        rfd->size = 1532;
214
        if (i == 0)
215
        {
216
            rfd->cmd = CMD_EOL;
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
 
232
static inline void
233
remove_rx_bufs(struct 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;
239
 
240
    do
241
    {
242
        lp->scb.rfd = rfd->next;
243
        kfree_s(rfd, sizeof(struct i596_rfd));
244
        rfd = lp->scb.rfd;
245
    }
246
    while (rfd != lp->rx_tail);
247
}
248
 
249
static inline void
250
init_i596_mem(struct 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);
258
    outw(0, ioaddr);
259
    outb(4, ioaddr+0xf);
260
    outw(((((int)&lp->scp) & 0xffff) | 2), ioaddr);
261
    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;
272
 
273
    if (i596_debug > 2) printk("%s: starting i82596.\n", dev->name);
274
 
275
    (void) inb (ioaddr+0x10);
276
    outb(4, ioaddr+0xf);
277
    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);
290
    lp->set_conf.command = CmdConfigure;
291
    i596_add_cmd(dev, &lp->set_conf);
292
 
293
    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_START;
310
    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
 
324
static inline int
325
i596_rx(struct 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_C)
333
    {
334
        if (i596_debug >2) print_eth(lp->scb.rfd->data);
335
 
336
        if ((lp->scb.rfd->stat) & STAT_OK)
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)
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);
353
 
354
            skb->protocol=eth_type_trans(skb,dev);
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_EOL;
378
 
379
    }
380
 
381
    if (i596_debug > 3) printk ("frames %d\n", frames);
382
 
383
    return 0;
384
}
385
 
386
static inline void
387
i596_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)
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_WRITE);
409
 
410
                lp->stats.tx_errors++;
411
                lp->stats.tx_aborted_errors++;
412
 
413
                ptr->next = (struct i596_cmd * ) I596_NULL;
414
                kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
415
                break;
416
            }
417
            case CmdMulticastList:
418
            {
419
                unsigned short count = *((unsigned short *) (ptr + 1));
420
 
421
                ptr->next = (struct i596_cmd * ) I596_NULL;
422
                kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
423
                break;
424
            }
425
            default:
426
                ptr->next = (struct i596_cmd * ) I596_NULL;
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
 
441
static inline void
442
i596_reset(struct 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_ABORT|RX_ABORT;
460
    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
 
482
static void i596_add_cmd(struct 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_EOL|CMD_INTR);
493
    cmd->next = (struct i596_cmd *) I596_NULL;
494
 
495
    save_flags(flags);
496
    cli();
497
    if (lp->cmd_head != (struct i596_cmd *) I596_NULL)
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_START;
512
        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);
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
 
532
static int
533
i596_open(struct 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))
541
        return -EAGAIN;
542
 
543
    irq2dev_map[dev->irq] = dev;
544
 
545
    i = init_rx_bufs(dev, RX_RING_SIZE);
546
 
547
    if ((i = init_rx_bufs(dev, RX_RING_SIZE)) < RX_RING_SIZE)
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);
553
        irq2dev_map[dev->irq] = 0;
554
        return -EAGAIN;
555
    }
556
 
557
    dev->tbusy = 0;
558
    dev->interrupt = 0;
559
    dev->start = 1;
560
    MOD_INC_USE_COUNT;
561
 
562
    /* Initialize the 82596 memory */
563
    init_i596_mem(dev);
564
 
565
    return 0;                    /* Always succeed */
566
}
567
 
568
static int
569
i596_start_xmit(struct sk_buff *skb, struct 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_START|RX_START;
596
            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) {
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_ZLEN < skb->len ? skb->len : ETH_ZLEN;
624
        dev->trans_start = jiffies;
625
 
626
        tx_cmd = (struct tx_cmd *) kmalloc ((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC);
627
        if (tx_cmd == NULL)
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_WRITE);
633
        }
634
        else
635
        {
636
            tx_cmd->tbd = (struct i596_tbd *) (tx_cmd + 1);
637
            tx_cmd->tbd->next = (struct i596_tbd *) I596_NULL;
638
 
639
            tx_cmd->cmd.command = CMD_FLEX|CmdTx;
640
 
641
            tx_cmd->pad = 0;
642
            tx_cmd->size = 0;
643
            tx_cmd->tbd->pad = 0;
644
            tx_cmd->tbd->size = EOF | 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
 
662
static void print_eth(char *add)
663
{
664
    int i;
665
 
666
    printk ("Dest  ");
667
    for (i = 0; i < 6; i++)
668
        printk(" %2.2X", (unsigned char)add[i]);
669
    printk ("\n");
670
 
671
    printk ("Source");
672
    for (i = 0; i < 6; i++)
673
        printk(" %2.2X", (unsigned char)add[i+6]);
674
    printk ("\n");
675
    printk ("type %2.2X%2.2X\n", (unsigned char)add[12], (unsigned char)add[13]);
676
}
677
 
678
int apricot_probe(struct device *dev)
679
{
680
    int i;
681
    struct i596_private *lp;
682
    int checksum = 0;
683
    int ioaddr = 0x300;
684
    char eth_addr[6];
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_SIZE))
690
        return ENODEV;
691
 
692
    for (i = 0; i < 8; i++)
693
    {
694
        eth_addr[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 ENODEV;
703
 
704
    /* Some other boards trip the checksum.. but then appear as ether
705
       address 0. Trap these - AC */
706
 
707
    if(memcmp(eth_addr,"\x00\x00\x49",3)!= 0)
708
        return ENODEV;
709
 
710
    request_region(ioaddr, APRICOT_TOTAL_SIZE, "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)kmalloc(sizeof(struct i596_private)+ 0x0f, GFP_KERNEL);
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));
738
    lp->scb.command = 0;
739
    lp->scb.cmd = (struct i596_cmd *) I596_NULL;
740
    lp->scb.rfd = (struct i596_rfd *)I596_NULL;
741
 
742
    return 0;
743
}
744
 
745
static void
746
i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
747
{
748
    struct device *dev = (struct 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) {
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) && (lp->cmd_head->status & STAT_C))
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_WRITE);
807
 
808
                    if ((ptr->status) & STAT_OK)
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;
824
                    kfree_s((unsigned char *)tx_cmd, (sizeof (struct tx_cmd) + sizeof (struct i596_tbd)));
825
                    break;
826
                }
827
                case CmdMulticastList:
828
                {
829
                    unsigned short count = *((unsigned short *) (ptr + 1));
830
 
831
                    ptr->next = (struct i596_cmd * ) I596_NULL;
832
                    kfree_s((unsigned char *)ptr, (sizeof (struct i596_cmd) + count + 2));
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;
858
 
859
                lp->last_cmd = jiffies;
860
            }
861
        }
862
 
863
        ptr = lp->cmd_head;
864
        while ((ptr != (struct i596_cmd *) I596_NULL) && (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) && (dev->start)) ack_cmd |= CUC_START;
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_START;
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);
901
    outb (4, ioaddr+0xf);
902
    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
 
911
static int
912
i596_close(struct 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_ABORT|RX_ABORT;
926
    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);
938
    irq2dev_map[dev->irq] = 0;
939
    remove_rx_bufs(dev);
940
    MOD_DEC_USE_COUNT;
941
 
942
    return 0;
943
}
944
 
945
static struct enet_statistics *
946
i596_get_stats(struct 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
 
957
static void set_multicast_list(struct 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 *) kmalloc(sizeof(struct i596_cmd)+2+dev->mc_count*6, GFP_ATOMIC);
970
                if (cmd == NULL)
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;dmi=dmi->next)
979
                {
980
                        memcpy(cp, dmi,6);
981
                        cp+=6;
982
                }
983
                print_eth (((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)
989
                        return;
990
                if (dev->mc_count == 0 && !(dev->flags&(IFF_PROMISC|IFF_ALLMULTI)))
991
                {
992
                        if(dev->flags&IFF_ALLMULTI)
993
                                dev->flags|=IFF_PROMISC;
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
1004
static unsigned int apricot_portlist[] = {0x300, 0};
1005
struct netdev_entry apricot_drv =
1006
{"apricot", apricot_probe, APRICOT_TOTAL_SIZE, apricot_portlist};
1007
#endif
1008
 
1009
#ifdef MODULE
1010
static char devicename[9] = { 0, };
1011
static struct 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, apricot_probe };
1016
 
1017
static int io = 0x300;
1018
static int irq = 10;
1019
 
1020
int
1021
init_module(void)
1022
{
1023
  dev_apricot.base_addr = io;
1024
  dev_apricot.irq       = irq;
1025
  if (register_netdev(&dev_apricot) != 0)
1026
    return -EIO;
1027
  return 0;
1028
}
1029
 
1030
void
1031
cleanup_module(void)
1032
{
1033
    unregister_netdev(&dev_apricot);
1034
    kfree_s((void *)dev_apricot.mem_start, sizeof(struct i596_private) + 0xf);
1035
    dev_apricot.priv = NULL;
1036
 
1037
    /* If we don't do this, we can't re-insmod it later. */
1038
    release_region(dev_apricot.base_addr, APRICOT_TOTAL_SIZE);
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
 */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.