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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [net/] [3c509.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* 3c509.c: A 3c509 EtherLink3 ethernet driver for linux. */
2
/*
3
        Written 1993-1998 by Donald Becker.
4
 
5
        Copyright 1994-1998 by Donald Becker.
6
        Copyright 1993 United States Government as represented by the
7
        Director, National Security Agency.      This software may be used and
8
        distributed according to the terms of the GNU Public License,
9
        incorporated herein by reference.
10
 
11
        This driver is for the 3Com EtherLinkIII series.
12
 
13
        The author may be reached as becker@cesdis.gsfc.nasa.gov or
14
        C/O Center of Excellence in Space Data and Information Sciences
15
                Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
16
 
17
        Known limitations:
18
        Because of the way 3c509 ISA detection works it's difficult to predict
19
        a priori which of several ISA-mode cards will be detected first.
20
 
21
        This driver does not use predictive interrupt mode, resulting in higher
22
        packet latency but lower overhead.  If interrupts are disabled for an
23
        unusually long time it could also result in missed packets, but in
24
        practice this rarely happens.
25
 
26
 
27
        FIXES:
28
                Alan Cox:       Removed the 'Unexpected interrupt' bug.
29
                Michael Meskes: Upgraded to Donald Becker's version 1.07.
30
                Alan Cox:       Increased the eeprom delay. Regardless of
31
                                what the docs say some people definitely
32
                                get problems with lower (but in card spec)
33
                                delays
34
                v1.10 4/21/97 Fixed module code so that multiple cards may be detected,
35
                                other cleanups.  -djb
36
                v1.13 9/8/97 Made 'max_interrupt_work' an insmod-settable variable -djb
37
                v1.14 10/15/97 Avoided waiting..discard message for fast machines -djb
38
                v1.15 1/31/98 Faster recovery for Tx errors. -djb
39
                v1.16 2/3/98 Different ID port handling to avoid sound cards. -djb
40
*/
41
 
42
static char *version = "3c509.c:1.16 2/3/98 becker@cesdis.gsfc.nasa.gov\n";
43
/* A few values that may be tweaked. */
44
 
45
/* Time in jiffies before concluding the transmitter is hung. */
46
#define TX_TIMEOUT  (400*HZ/1000)
47
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
48
static int max_interrupt_work = 10;
49
 
50
#include <linux/module.h>
51
 
52
#include <linux/config.h>
53
#include <linux/kernel.h>
54
#include <linux/sched.h>
55
#include <linux/string.h>
56
#include <linux/interrupt.h>
57
#include <linux/ptrace.h>
58
#include <linux/errno.h>
59
#include <linux/in.h>
60
#include <linux/malloc.h>
61
#include <linux/ioport.h>
62
#include <linux/netdevice.h>
63
#include <linux/etherdevice.h>
64
#include <linux/skbuff.h>
65
#include <linux/config.h>       /* for CONFIG_MCA */
66
#include <linux/delay.h>        /* for udelay() */
67
 
68
#include <asm/bitops.h>
69
#include <asm/io.h>
70
 
71
#ifdef EL3_DEBUG
72
int el3_debug = EL3_DEBUG;
73
#else
74
int el3_debug = 2;
75
#endif
76
 
77
/* To minimize the size of the driver source I only define operating
78
   constants if they are used several times.  You'll need the manual
79
   anyway if you want to understand driver details. */
80
/* Offsets from base I/O address. */
81
#define EL3_DATA 0x00
82
#define EL3_CMD 0x0e
83
#define EL3_STATUS 0x0e
84
#define  EEPROM_READ 0x80
85
 
86
#define EL3_IO_EXTENT   16
87
 
88
#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
89
 
90
 
91
/* The top five bits written to EL3_CMD are a command, the lower
92
   11 bits are the parameter, if applicable. */
93
enum c509cmd {
94
        TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
95
        RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
96
        TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
97
        FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
98
        SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
99
        SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
100
        StatsDisable = 22<<11, StopCoax = 23<<11,};
101
 
102
enum c509status {
103
        IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
104
        TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
105
        IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000, };
106
 
107
/* The SetRxFilter command accepts the following classes: */
108
enum RxFilter {
109
        RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 };
110
 
111
/* Register window 1 offsets, the window used in normal operation. */
112
#define TX_FIFO         0x00
113
#define RX_FIFO         0x00
114
#define RX_STATUS       0x08
115
#define TX_STATUS       0x0B
116
#define TX_FREE         0x0C            /* Remaining free bytes in Tx buffer. */
117
 
118
#define WN0_IRQ         0x08            /* Window 0: Set IRQ line in bits 12-15. */
119
#define WN4_MEDIA       0x0A            /* Window 4: Various transcvr/media bits. */
120
#define  MEDIA_TP       0x00C0          /* Enable link beat and jabber for 10baseT. */
121
 
122
/*
123
 * Must be a power of two (we use a binary and in the
124
 * circular queue)
125
 */
126
#define SKB_QUEUE_SIZE  64
127
 
128
struct el3_private {
129
        struct enet_statistics stats;
130
        struct device *next_dev;
131
        /* skb send-queue */
132
        int head, size;
133
        struct sk_buff *queue[SKB_QUEUE_SIZE];
134
};
135
static int id_port = 0x110;             /* Start with 0x110 to avoid new sound cards.*/
136
static struct device *el3_root_dev = NULL;
137
 
138
static ushort id_read_eeprom(int index);
139
static ushort read_eeprom(int ioaddr, int index);
140
static int el3_open(struct device *dev);
141
static int el3_start_xmit(struct sk_buff *skb, struct device *dev);
142
static void el3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
143
static void update_stats(int addr, struct device *dev);
144
static struct enet_statistics *el3_get_stats(struct device *dev);
145
static int el3_rx(struct device *dev);
146
static int el3_close(struct device *dev);
147
static void set_multicast_list(struct device *dev);
148
 
149
 
150
 
151
int el3_probe(struct device *dev)
152
{
153
        short lrs_state = 0xff, i;
154
        int ioaddr, irq, if_port;
155
        u16 phys_addr[3];
156
        static int current_tag = 0;
157
 
158
        /* First check all slots of the EISA bus.  The next slot address to
159
           probe is kept in 'eisa_addr' to support multiple probe() calls. */
160
        if (EISA_bus) {
161
                static int eisa_addr = 0x1000;
162
                while (eisa_addr < 0x9000) {
163
                        ioaddr = eisa_addr;
164
                        eisa_addr += 0x1000;
165
 
166
                        /* Check the standard EISA ID register for an encoded '3Com'. */
167
                        if (inw(ioaddr + 0xC80) != 0x6d50)
168
                                continue;
169
 
170
                        /* Change the register set to the configuration window 0. */
171
                        outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
172
 
173
                        irq = inw(ioaddr + WN0_IRQ) >> 12;
174
                        if_port = inw(ioaddr + 6)>>14;
175
                        for (i = 0; i < 3; i++)
176
                                phys_addr[i] = htons(read_eeprom(ioaddr, i));
177
 
178
                        /* Restore the "Product ID" to the EEPROM read register. */
179
                        read_eeprom(ioaddr, 3);
180
 
181
                        /* Was the EISA code an add-on hack?  Nahhhhh... */
182
                        goto found;
183
                }
184
        }
185
 
186
#ifdef CONFIG_MCA
187
        if (MCA_bus) {
188
                mca_adaptor_select_mode(1);
189
                for (i = 0; i < 8; i++)
190
                        if ((mca_adaptor_id(i) | 1) == 0x627c) {
191
                                ioaddr = mca_pos_base_addr(i);
192
                                irq = inw(ioaddr + WN0_IRQ) >> 12;
193
                                if_port = inw(ioaddr + 6)>>14;
194
                                for (i = 0; i < 3; i++)
195
                                        phys_addr[i] = htons(read_eeprom(ioaddr, i));
196
 
197
                                mca_adaptor_select_mode(0);
198
                                goto found;
199
                        }
200
                mca_adaptor_select_mode(0);
201
 
202
        }
203
#endif
204
 
205
        /* Reset the ISA PnP mechanism on 3c509b. */
206
        outb(0x02, 0x279);           /* Select PnP config control register. */
207
        outb(0x02, 0xA79);           /* Return to WaitForKey state. */
208
        /* Select an open I/O location at 0x1*0 to do contention select. */
209
        for ( ; id_port < 0x200; id_port += 0x10) {
210
                if (check_region(id_port, 1))
211
                        continue;
212
                outb(0x00, id_port);
213
                outb(0xff, id_port);
214
                if (inb(id_port) & 0x01)
215
                        break;
216
        }
217
        if (id_port >= 0x200) {             /* GCC optimizes this test out. */
218
                /* Rare -- do we really need a warning? */
219
                printk(" WARNING: No I/O port available for 3c509 activation.\n");
220
                return -ENODEV;
221
        }
222
        /* Next check for all ISA bus boards by sending the ID sequence to the
223
           ID_PORT.  We find cards past the first by setting the 'current_tag'
224
           on cards as they are found.  Cards with their tag set will not
225
           respond to subsequent ID sequences. */
226
 
227
        outb(0x00, id_port);
228
        outb(0x00, id_port);
229
        for(i = 0; i < 255; i++) {
230
                outb(lrs_state, id_port);
231
                lrs_state <<= 1;
232
                lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
233
        }
234
 
235
        /* For the first probe, clear all board's tag registers. */
236
        if (current_tag == 0)
237
                outb(0xd0, id_port);
238
        else                            /* Otherwise kill off already-found boards. */
239
                outb(0xd8, id_port);
240
 
241
        if (id_read_eeprom(7) != 0x6d50) {
242
                return -ENODEV;
243
        }
244
 
245
        /* Read in EEPROM data, which does contention-select.
246
           Only the lowest address board will stay "on-line".
247
           3Com got the byte order backwards. */
248
        for (i = 0; i < 3; i++) {
249
                phys_addr[i] = htons(id_read_eeprom(i));
250
        }
251
 
252
        {
253
                unsigned int iobase = id_read_eeprom(8);
254
                if_port = iobase >> 14;
255
                ioaddr = 0x200 + ((iobase & 0x1f) << 4);
256
        }
257
        irq = id_read_eeprom(9) >> 12;
258
 
259
        if (dev) {                                      /* Set passed-in IRQ or I/O Addr. */
260
                if (dev->irq > 1  &&  dev->irq < 16)
261
                        irq = dev->irq;
262
 
263
                if (dev->base_addr) {
264
                        if (dev->mem_end == 0x3c509                     /* Magic key */
265
                                && dev->base_addr >= 0x200  &&  dev->base_addr <= 0x3e0)
266
                                ioaddr = dev->base_addr & 0x3f0;
267
                        else if (dev->base_addr != ioaddr)
268
                                return -ENODEV;
269
                }
270
        }
271
 
272
        /* Set the adaptor tag so that the next card can be found. */
273
        outb(0xd0 + ++current_tag, id_port);
274
 
275
        /* Activate the adaptor at the EEPROM location. */
276
        outb((ioaddr >> 4) | 0xe0, id_port);
277
 
278
        EL3WINDOW(0);
279
        if (inw(ioaddr) != 0x6d50)
280
                return -ENODEV;
281
 
282
        /* Free the interrupt so that some other card can use it. */
283
        outw(0x0f00, ioaddr + WN0_IRQ);
284
 found:
285
        if (dev == NULL) {
286
                dev = init_etherdev(dev, sizeof(struct el3_private));
287
        }
288
        memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
289
        dev->base_addr = ioaddr;
290
        dev->irq = irq;
291
        dev->if_port = (dev->mem_start & 0x1f) ? dev->mem_start & 3 : if_port;
292
 
293
        request_region(dev->base_addr, EL3_IO_EXTENT, "3c509");
294
 
295
        {
296
                const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
297
                printk("%s: 3c509 at %#3.3lx tag %d, %s port, address ",
298
                           dev->name, dev->base_addr, current_tag, if_names[dev->if_port]);
299
        }
300
 
301
        /* Read in the station address. */
302
        for (i = 0; i < 6; i++)
303
                printk(" %2.2x", dev->dev_addr[i]);
304
        printk(", IRQ %d.\n", dev->irq);
305
 
306
        /* Make up a EL3-specific-data structure. */
307
        if (dev->priv == NULL)
308
                dev->priv = kmalloc(sizeof(struct el3_private), GFP_KERNEL);
309
        if (dev->priv == NULL)
310
                return -ENOMEM;
311
        memset(dev->priv, 0, sizeof(struct el3_private));
312
 
313
        ((struct el3_private *)dev->priv)->next_dev = el3_root_dev;
314
        el3_root_dev = dev;
315
 
316
        if (el3_debug > 0)
317
                printk(version);
318
 
319
        /* The EL3-specific entries in the device structure. */
320
        dev->open = &el3_open;
321
        dev->hard_start_xmit = &el3_start_xmit;
322
        dev->stop = &el3_close;
323
        dev->get_stats = &el3_get_stats;
324
        dev->set_multicast_list = &set_multicast_list;
325
 
326
        /* Fill in the generic fields of the device structure. */
327
        ether_setup(dev);
328
        return 0;
329
}
330
 
331
/* Read a word from the EEPROM using the regular EEPROM access register.
332
   Assume that we are in register window zero.
333
 */
334
static ushort read_eeprom(int ioaddr, int index)
335
{
336
        outw(EEPROM_READ + index, ioaddr + 10);
337
        /* Pause for at least 162 us. for the read to take place. */
338
        udelay (500);
339
        return inw(ioaddr + 12);
340
}
341
 
342
/* Read a word from the EEPROM when in the ISA ID probe state. */
343
static ushort id_read_eeprom(int index)
344
{
345
        int bit, word = 0;
346
 
347
        /* Issue read command, and pause for at least 162 us. for it to complete.
348
           Assume extra-fast 16Mhz bus. */
349
        outb(EEPROM_READ + index, id_port);
350
 
351
        /* Pause for at least 162 us. for the read to take place. */
352
        udelay (500);
353
 
354
        for (bit = 15; bit >= 0; bit--)
355
                word = (word << 1) + (inb(id_port) & 0x01);
356
 
357
        if (el3_debug > 3)
358
                printk("  3c509 EEPROM word %d %#4.4x.\n", index, word);
359
 
360
        return word;
361
}
362
 
363
 
364
 
365
static int
366
el3_open(struct device *dev)
367
{
368
        int ioaddr = dev->base_addr;
369
        int i;
370
 
371
        outw(TxReset, ioaddr + EL3_CMD);
372
        outw(RxReset, ioaddr + EL3_CMD);
373
        outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
374
 
375
        if (request_irq(dev->irq, &el3_interrupt, 0, "3c509", dev)) {
376
                return -EAGAIN;
377
        }
378
 
379
        EL3WINDOW(0);
380
        if (el3_debug > 3)
381
                printk("%s: Opening, IRQ %d      status@%x %4.4x.\n", dev->name,
382
                           dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
383
 
384
        /* Activate board: this is probably unnecessary. */
385
        outw(0x0001, ioaddr + 4);
386
 
387
        /* Set the IRQ line. */
388
        outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
389
 
390
        /* Set the station address in window 2 each time opened. */
391
        EL3WINDOW(2);
392
 
393
        for (i = 0; i < 6; i++)
394
                outb(dev->dev_addr[i], ioaddr + i);
395
 
396
        if (dev->if_port == 3)
397
                /* Start the thinnet transceiver. We should really wait 50ms...*/
398
                outw(StartCoax, ioaddr + EL3_CMD);
399
        else if (dev->if_port == 0) {
400
                /* 10baseT interface, enabled link beat and jabber check. */
401
                EL3WINDOW(4);
402
                outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
403
        }
404
 
405
        /* Switch to the stats window, and clear all stats by reading. */
406
        outw(StatsDisable, ioaddr + EL3_CMD);
407
        EL3WINDOW(6);
408
        for (i = 0; i < 9; i++)
409
                inb(ioaddr + i);
410
        inw(ioaddr + 10);
411
        inw(ioaddr + 12);
412
 
413
        /* Switch to register set 1 for normal use. */
414
        EL3WINDOW(1);
415
 
416
        /* Accept b-case and phys addr only. */
417
        outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
418
        outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
419
 
420
        dev->interrupt = 0;
421
        dev->tbusy = 0;
422
        dev->start = 1;
423
 
424
        outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
425
        outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
426
        /* Allow status bits to be seen. */
427
        outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
428
        /* Ack all pending events, and set active indicator mask. */
429
        outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
430
                 ioaddr + EL3_CMD);
431
        outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull,
432
                 ioaddr + EL3_CMD);
433
 
434
        if (el3_debug > 3)
435
                printk("%s: Opened 3c509  IRQ %d  status %4.4x.\n",
436
                           dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
437
 
438
        MOD_INC_USE_COUNT;
439
        return 0;                                        /* Always succeed */
440
}
441
 
442
static int
443
el3_start_xmit(struct sk_buff *skb, struct device *dev)
444
{
445
        struct el3_private *lp = (struct el3_private *)dev->priv;
446
        int ioaddr = dev->base_addr;
447
 
448
        /* Transmitter timeout, serious problems. */
449
        if (dev->tbusy) {
450
                int tickssofar = jiffies - dev->trans_start;
451
                if (tickssofar < TX_TIMEOUT)
452
                        return 1;
453
                printk("%s: transmit timed out, Tx_status %2.2x status %4.4x "
454
                           "Tx FIFO room %d.\n",
455
                           dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
456
                           inw(ioaddr + TX_FREE));
457
                lp->stats.tx_errors++;
458
                dev->trans_start = jiffies;
459
                /* Issue TX_RESET and TX_START commands. */
460
                outw(TxReset, ioaddr + EL3_CMD);
461
                outw(TxEnable, ioaddr + EL3_CMD);
462
                dev->tbusy = 0;
463
        }
464
 
465
        if (el3_debug > 4) {
466
                printk("%s: el3_start_xmit(length = %ld) called, status %4.4x.\n",
467
                           dev->name, skb->len, inw(ioaddr + EL3_STATUS));
468
        }
469
#if 0
470
#ifndef final_version
471
        {       /* Error-checking code, delete someday. */
472
                ushort status = inw(ioaddr + EL3_STATUS);
473
                if (status & 0x0001             /* IRQ line active, missed one. */
474
                        && inw(ioaddr + EL3_STATUS) & 1) {                      /* Make sure. */
475
                        printk("%s: Missed interrupt, status then %04x now %04x"
476
                                   "  Tx %2.2x Rx %4.4x.\n", dev->name, status,
477
                                   inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
478
                                   inw(ioaddr + RX_STATUS));
479
                        /* Fake interrupt trigger by masking, acknowledge interrupts. */
480
                        outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
481
                        outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
482
                                 ioaddr + EL3_CMD);
483
                        outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
484
                }
485
        }
486
#endif
487
#endif
488
        /* Avoid timer-based retransmission conflicts. */
489
        if (set_bit(0, (void*)&dev->tbusy) != 0)
490
                printk("%s: Transmitter access conflict.\n", dev->name);
491
        else {
492
                /* Put out the doubleword header... */
493
                outw(skb->len, ioaddr + TX_FIFO);
494
                outw(0x00, ioaddr + TX_FIFO);
495
                /* ... and the packet rounded to a doubleword. */
496
#ifdef  __powerpc__
497
                outsl_unswapped(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
498
#else
499
                outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
500
#endif
501
 
502
                dev->trans_start = jiffies;
503
                if (inw(ioaddr + TX_FREE) > 1536) {
504
                        dev->tbusy = 0;
505
                } else
506
                        /* Interrupt us when the FIFO has room for max-sized packet. */
507
                        outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
508
        }
509
 
510
        dev_kfree_skb (skb, FREE_WRITE);
511
 
512
        /* Clear the Tx status stack. */
513
        {
514
                short tx_status;
515
                int i = 4;
516
 
517
                while (--i > 0   &&      (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
518
                        if (tx_status & 0x38) lp->stats.tx_aborted_errors++;
519
                        if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
520
                        if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
521
                        outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
522
                }
523
        }
524
        return 0;
525
}
526
 
527
/* The EL3 interrupt handler. */
528
static void
529
el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
530
{
531
        struct device *dev = (struct device *)dev_id;
532
        int ioaddr, status;
533
        int i = max_interrupt_work;
534
 
535
        if (dev == NULL) {
536
                printk ("el3_interrupt(): irq %d for unknown device.\n", irq);
537
                return;
538
        }
539
 
540
        if (dev->interrupt)
541
                printk("%s: Re-entering the interrupt handler.\n", dev->name);
542
        dev->interrupt = 1;
543
 
544
        ioaddr = dev->base_addr;
545
        status = inw(ioaddr + EL3_STATUS);
546
 
547
        if (el3_debug > 4)
548
                printk("%s: interrupt, status %4.4x.\n", dev->name, status);
549
 
550
        while ((status = inw(ioaddr + EL3_STATUS)) &
551
                   (IntLatch | RxComplete | StatsFull)) {
552
 
553
                if (status & RxComplete)
554
                        el3_rx(dev);
555
 
556
                if (status & TxAvailable) {
557
                        if (el3_debug > 5)
558
                                printk("        TX room bit was handled.\n");
559
                        /* There's room in the FIFO for a full-sized packet. */
560
                        outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
561
                        dev->tbusy = 0;
562
                        mark_bh(NET_BH);
563
                }
564
                if (status & (AdapterFailure | RxEarly | StatsFull | TxComplete)) {
565
                        /* Handle all uncommon interrupts. */
566
                        if (status & StatsFull)                         /* Empty statistics. */
567
                                update_stats(ioaddr, dev);
568
                        if (status & RxEarly) {                         /* Rx early is unused. */
569
                                el3_rx(dev);
570
                                outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
571
                        }
572
                        if (status & TxComplete) {                      /* Really Tx error. */
573
                                struct el3_private *lp = (struct el3_private *)dev->priv;
574
                                short tx_status;
575
                                int i = 4;
576
 
577
                                while (--i>0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
578
                                        if (tx_status & 0x38) lp->stats.tx_aborted_errors++;
579
                                        if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
580
                                        if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
581
                                        outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
582
                                }
583
                        }
584
                        if (status & AdapterFailure) {
585
                                /* Adapter failure requires Rx reset and reinit. */
586
                                outw(RxReset, ioaddr + EL3_CMD);
587
                                /* Set the Rx filter to the current state. */
588
                                outw(SetRxFilter | RxStation | RxBroadcast
589
                                         | (dev->flags & IFF_ALLMULTI ? RxMulticast : 0)
590
                                         | (dev->flags & IFF_PROMISC ? RxProm : 0),
591
                                         ioaddr + EL3_CMD);
592
                                outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
593
                                outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD);
594
                        }
595
                }
596
 
597
                if (--i < 0) {
598
                        printk("%s: Infinite loop in interrupt, status %4.4x.\n",
599
                                   dev->name, status);
600
                        /* Clear all interrupts. */
601
                        outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
602
                        break;
603
                }
604
                /* Acknowledge the IRQ. */
605
                outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); /* Ack IRQ */
606
        }
607
 
608
        if (el3_debug > 4) {
609
                printk("%s: exiting interrupt, status %4.4x.\n", dev->name,
610
                           inw(ioaddr + EL3_STATUS));
611
        }
612
 
613
        dev->interrupt = 0;
614
        return;
615
}
616
 
617
 
618
static struct enet_statistics *
619
el3_get_stats(struct device *dev)
620
{
621
        struct el3_private *lp = (struct el3_private *)dev->priv;
622
        unsigned long flags;
623
 
624
        save_flags(flags);
625
        cli();
626
        update_stats(dev->base_addr, dev);
627
        restore_flags(flags);
628
        return &lp->stats;
629
}
630
 
631
/*  Update statistics.  We change to register window 6, so this should be run
632
        single-threaded if the device is active. This is expected to be a rare
633
        operation, and it's simpler for the rest of the driver to assume that
634
        window 1 is always valid rather than use a special window-state variable.
635
        */
636
static void update_stats(int ioaddr, struct device *dev)
637
{
638
        struct el3_private *lp = (struct el3_private *)dev->priv;
639
 
640
        if (el3_debug > 5)
641
                printk("   Updating the statistics.\n");
642
        /* Turn off statistics updates while reading. */
643
        outw(StatsDisable, ioaddr + EL3_CMD);
644
        /* Switch to the stats window, and read everything. */
645
        EL3WINDOW(6);
646
        lp->stats.tx_carrier_errors     += inb(ioaddr + 0);
647
        lp->stats.tx_heartbeat_errors   += inb(ioaddr + 1);
648
        /* Multiple collisions. */              inb(ioaddr + 2);
649
        lp->stats.collisions                    += inb(ioaddr + 3);
650
        lp->stats.tx_window_errors              += inb(ioaddr + 4);
651
        lp->stats.rx_fifo_errors                += inb(ioaddr + 5);
652
        lp->stats.tx_packets                    += inb(ioaddr + 6);
653
        /* Rx packets   */                              inb(ioaddr + 7);
654
        /* Tx deferrals */                              inb(ioaddr + 8);
655
        inw(ioaddr + 10);       /* Total Rx and Tx octets. */
656
        inw(ioaddr + 12);
657
 
658
        /* Back to window 1, and turn statistics back on. */
659
        EL3WINDOW(1);
660
        outw(StatsEnable, ioaddr + EL3_CMD);
661
        return;
662
}
663
 
664
static int
665
el3_rx(struct device *dev)
666
{
667
        struct el3_private *lp = (struct el3_private *)dev->priv;
668
        int ioaddr = dev->base_addr;
669
        short rx_status;
670
 
671
        if (el3_debug > 5)
672
                printk("   In rx_packet(), status %4.4x, rx_status %4.4x.\n",
673
                           inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
674
        while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
675
                if (rx_status & 0x4000) { /* Error, update stats. */
676
                        short error = rx_status & 0x3800;
677
 
678
                        outw(RxDiscard, ioaddr + EL3_CMD);
679
                        lp->stats.rx_errors++;
680
                        switch (error) {
681
                        case 0x0000:            lp->stats.rx_over_errors++; break;
682
                        case 0x0800:            lp->stats.rx_length_errors++; break;
683
                        case 0x1000:            lp->stats.rx_frame_errors++; break;
684
                        case 0x1800:            lp->stats.rx_length_errors++; break;
685
                        case 0x2000:            lp->stats.rx_frame_errors++; break;
686
                        case 0x2800:            lp->stats.rx_crc_errors++; break;
687
                        }
688
                } else {
689
                        short pkt_len = rx_status & 0x7ff;
690
                        struct sk_buff *skb;
691
 
692
                        skb = dev_alloc_skb(pkt_len+5);
693
                        if (el3_debug > 4)
694
                                printk("Receiving packet size %d status %4.4x.\n",
695
                                           pkt_len, rx_status);
696
                        if (skb != NULL) {
697
                                skb->dev = dev;
698
                                skb_reserve(skb, 2);     /* Align IP on 16 byte */
699
 
700
                                /* 'skb->data' points to the start of sk_buff data area. */
701
#ifdef  __powerpc__
702
                                insl_unswapped(ioaddr+RX_FIFO, skb_put(skb,pkt_len),
703
                                                           (pkt_len + 3) >> 2);
704
#else
705
                                insl(ioaddr + RX_FIFO, skb_put(skb,pkt_len),
706
                                         (pkt_len + 3) >> 2);
707
#endif
708
 
709
                                outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
710
                                skb->protocol = eth_type_trans(skb,dev);
711
                                netif_rx(skb);
712
                                lp->stats.rx_packets++;
713
                                continue;
714
                        }
715
                        outw(RxDiscard, ioaddr + EL3_CMD);
716
                        lp->stats.rx_dropped++;
717
                        if (el3_debug)
718
                                printk("%s: Couldn't allocate a sk_buff of size %d.\n",
719
                                           dev->name, pkt_len);
720
                }
721
                inw(ioaddr + EL3_STATUS);                               /* Delay. */
722
                while (inw(ioaddr + EL3_STATUS) & 0x1000)
723
                        printk("        Waiting for 3c509 to discard packet, status %x.\n",
724
                                   inw(ioaddr + EL3_STATUS) );
725
        }
726
 
727
        return 0;
728
}
729
 
730
/*
731
 *     Set or clear the multicast filter for this adaptor.
732
 */
733
static void
734
set_multicast_list(struct device *dev)
735
{
736
        int ioaddr = dev->base_addr;
737
        if (el3_debug > 1) {
738
                static int old = 0;
739
                if (old != dev->mc_count) {
740
                        old = dev->mc_count;
741
                        printk("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
742
                }
743
        }
744
        if (dev->flags&IFF_PROMISC) {
745
                outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
746
                         ioaddr + EL3_CMD);
747
        }
748
        else if (dev->mc_count || (dev->flags&IFF_ALLMULTI)) {
749
                outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast, ioaddr + EL3_CMD);
750
        }
751
        else
752
                outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
753
}
754
 
755
static int
756
el3_close(struct device *dev)
757
{
758
        int ioaddr = dev->base_addr;
759
 
760
        if (el3_debug > 2)
761
                printk("%s: Shutting down ethercard.\n", dev->name);
762
 
763
        dev->tbusy = 1;
764
        dev->start = 0;
765
 
766
        /* Turn off statistics ASAP.  We update lp->stats below. */
767
        outw(StatsDisable, ioaddr + EL3_CMD);
768
 
769
        /* Disable the receiver and transmitter. */
770
        outw(RxDisable, ioaddr + EL3_CMD);
771
        outw(TxDisable, ioaddr + EL3_CMD);
772
 
773
        if (dev->if_port == 3)
774
                /* Turn off thinnet power.  Green! */
775
                outw(StopCoax, ioaddr + EL3_CMD);
776
        else if (dev->if_port == 0) {
777
                /* Disable link beat and jabber, if_port may change ere next open(). */
778
                EL3WINDOW(4);
779
                outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
780
        }
781
 
782
        free_irq(dev->irq, dev);
783
        /* Switching back to window 0 disables the IRQ. */
784
        EL3WINDOW(0);
785
        /* But we explicitly zero the IRQ line select anyway. */
786
        outw(0x0f00, ioaddr + WN0_IRQ);
787
 
788
        update_stats(ioaddr, dev);
789
        MOD_DEC_USE_COUNT;
790
        return 0;
791
}
792
 
793
#ifdef MODULE
794
/* Parameters that may be passed into the module. */
795
static int debug = -1;
796
static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
797
static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1};
798
 
799
int
800
init_module(void)
801
{
802
        int el3_cards = 0;
803
 
804
        if (debug >= 0)
805
                el3_debug = debug;
806
 
807
        el3_root_dev = NULL;
808
        while (el3_probe(0) == 0) {
809
                if (irq[el3_cards] > 1)
810
                        el3_root_dev->irq = irq[el3_cards];
811
                if (xcvr[el3_cards] >= 0)
812
                        el3_root_dev->if_port = xcvr[el3_cards];
813
                el3_cards++;
814
        }
815
 
816
        return el3_cards ? 0 : -ENODEV;
817
}
818
 
819
void
820
cleanup_module(void)
821
{
822
        struct device *next_dev;
823
 
824
        /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
825
        while (el3_root_dev) {
826
                next_dev = ((struct el3_private *)el3_root_dev->priv)->next_dev;
827
                unregister_netdev(el3_root_dev);
828
                release_region(el3_root_dev->base_addr, EL3_IO_EXTENT);
829
                kfree(el3_root_dev);
830
                el3_root_dev = next_dev;
831
        }
832
}
833
#endif /* MODULE */
834
 
835
/*
836
 * Local variables:
837
 *  compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c509.c"
838
 *  version-control: t
839
 *  kept-new-versions: 5
840
 *  tab-width: 4
841
 * End:
842
 */

powered by: WebSVN 2.1.0

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