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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [sun3lance.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/* sun3lance.c: Ethernet driver for SUN3 Lance chip */
2
/*
3
 
4
  Sun3 Lance ethernet driver, by Sam Creasey (sammy@users.qual.net).
5
  This driver is a part of the linux kernel, and is thus distributed
6
  under the GNU General Public License.
7
 
8
  The values used in LANCE_OBIO and LANCE_IRQ seem to be empirically
9
  true for the correct IRQ and address of the lance registers.  They
10
  have not been widely tested, however.  What we probably need is a
11
  "proper" way to search for a device in the sun3's prom, but, alas,
12
  linux has no such thing.
13
 
14
  This driver is largely based on atarilance.c, by Roman Hodek.  Other
15
  sources of inspiration were the NetBSD sun3 am7990 driver, and the
16
  linux sparc lance driver (sunlance.c).
17
 
18
  There are more assumptions made throughout this driver, it almost
19
  certainly still needs work, but it does work at least for RARP/BOOTP and
20
  mounting the root NFS filesystem.
21
 
22
*/
23
 
24
static char *version = "sun3lance.c: v1.2 1/12/2001  Sam Creasey (sammy@sammy.net)\n";
25
 
26
#include <linux/module.h>
27
#include <linux/stddef.h>
28
#include <linux/kernel.h>
29
#include <linux/string.h>
30
#include <linux/errno.h>
31
#include <linux/slab.h>
32
#include <linux/interrupt.h>
33
#include <linux/init.h>
34
#include <linux/ioport.h>
35
#include <linux/delay.h>
36
#include <linux/netdevice.h>
37
#include <linux/etherdevice.h>
38
#include <linux/skbuff.h>
39
#include <linux/bitops.h>
40
 
41
#include <asm/cacheflush.h>
42
#include <asm/setup.h>
43
#include <asm/irq.h>
44
#include <asm/io.h>
45
#include <asm/pgtable.h>
46
#include <asm/dvma.h>
47
#include <asm/idprom.h>
48
#include <asm/machines.h>
49
 
50
#ifdef CONFIG_SUN3
51
#include <asm/sun3mmu.h>
52
#else
53
#include <asm/sun3xprom.h>
54
#endif
55
 
56
/* sun3/60 addr/irq for the lance chip.  If your sun is different,
57
   change this. */
58
#define LANCE_OBIO 0x120000
59
#define LANCE_IRQ IRQ_AUTO_3
60
 
61
/* Debug level:
62
 *  0 = silent, print only serious errors
63
 *  1 = normal, print error messages
64
 *  2 = debug, print debug infos
65
 *  3 = debug, print even more debug infos (packet data)
66
 */
67
 
68
#define LANCE_DEBUG     0
69
 
70
#ifdef LANCE_DEBUG
71
static int lance_debug = LANCE_DEBUG;
72
#else
73
static int lance_debug = 1;
74
#endif
75
module_param(lance_debug, int, 0);
76
MODULE_PARM_DESC(lance_debug, "SUN3 Lance debug level (0-3)");
77
MODULE_LICENSE("GPL");
78
 
79
#define DPRINTK(n,a) \
80
        do {  \
81
                if (lance_debug >= n)  \
82
                        printk a; \
83
        } while( 0 )
84
 
85
 
86
/* we're only using 32k of memory, so we use 4 TX
87
   buffers and 16 RX buffers.  These values are expressed as log2. */
88
 
89
#define TX_LOG_RING_SIZE                        3
90
#define RX_LOG_RING_SIZE                        5
91
 
92
/* These are the derived values */
93
 
94
#define TX_RING_SIZE                    (1 << TX_LOG_RING_SIZE)
95
#define TX_RING_LEN_BITS                (TX_LOG_RING_SIZE << 5)
96
#define TX_RING_MOD_MASK                (TX_RING_SIZE - 1)
97
 
98
#define RX_RING_SIZE                    (1 << RX_LOG_RING_SIZE)
99
#define RX_RING_LEN_BITS                (RX_LOG_RING_SIZE << 5)
100
#define RX_RING_MOD_MASK                (RX_RING_SIZE - 1)
101
 
102
/* Definitions for packet buffer access: */
103
#define PKT_BUF_SZ              1544
104
 
105
/* Get the address of a packet buffer corresponding to a given buffer head */
106
#define PKTBUF_ADDR(head)       (void *)((unsigned long)(MEM) | (head)->base)
107
 
108
 
109
/* The LANCE Rx and Tx ring descriptors. */
110
struct lance_rx_head {
111
        unsigned short  base;           /* Low word of base addr */
112
        volatile unsigned char  flag;
113
        unsigned char  base_hi; /* High word of base addr (unused) */
114
        short buf_length;       /* This length is 2s complement! */
115
        volatile short msg_length;      /* This length is "normal". */
116
};
117
 
118
struct lance_tx_head {
119
        unsigned short base;            /* Low word of base addr */
120
        volatile unsigned char  flag;
121
        unsigned char base_hi;  /* High word of base addr (unused) */
122
        short length;           /* Length is 2s complement! */
123
        volatile short misc;
124
};
125
 
126
/* The LANCE initialization block, described in databook. */
127
struct lance_init_block {
128
        unsigned short  mode;           /* Pre-set mode */
129
        unsigned char   hwaddr[6];      /* Physical ethernet address */
130
        unsigned int    filter[2];      /* Multicast filter (unused). */
131
        /* Receive and transmit ring base, along with length bits. */
132
        unsigned short rdra;
133
        unsigned short rlen;
134
        unsigned short tdra;
135
        unsigned short tlen;
136
        unsigned short pad[4]; /* is thie needed? */
137
};
138
 
139
/* The whole layout of the Lance shared memory */
140
struct lance_memory {
141
        struct lance_init_block init;
142
        struct lance_tx_head    tx_head[TX_RING_SIZE];
143
        struct lance_rx_head    rx_head[RX_RING_SIZE];
144
        char   rx_data[RX_RING_SIZE][PKT_BUF_SZ];
145
        char   tx_data[TX_RING_SIZE][PKT_BUF_SZ];
146
};
147
 
148
/* The driver's private device structure */
149
 
150
struct lance_private {
151
        volatile unsigned short *iobase;
152
        struct lance_memory     *mem;
153
        int new_rx, new_tx;     /* The next free ring entry */
154
        int old_tx, old_rx;     /* ring entry to be processed */
155
/* These two must be longs for set_bit() */
156
        long        tx_full;
157
        long        lock;
158
};
159
 
160
/* I/O register access macros */
161
 
162
#define MEM     lp->mem
163
#define DREG    lp->iobase[0]
164
#define AREG    lp->iobase[1]
165
#define REGA(a) (*( AREG = (a), &DREG ))
166
 
167
/* Definitions for the Lance */
168
 
169
/* tx_head flags */
170
#define TMD1_ENP                0x01    /* end of packet */
171
#define TMD1_STP                0x02    /* start of packet */
172
#define TMD1_DEF                0x04    /* deferred */
173
#define TMD1_ONE                0x08    /* one retry needed */
174
#define TMD1_MORE               0x10    /* more than one retry needed */
175
#define TMD1_ERR                0x40    /* error summary */
176
#define TMD1_OWN                0x80    /* ownership (set: chip owns) */
177
 
178
#define TMD1_OWN_CHIP   TMD1_OWN
179
#define TMD1_OWN_HOST   0
180
 
181
/* tx_head misc field */
182
#define TMD3_TDR                0x03FF  /* Time Domain Reflectometry counter */
183
#define TMD3_RTRY               0x0400  /* failed after 16 retries */
184
#define TMD3_LCAR               0x0800  /* carrier lost */
185
#define TMD3_LCOL               0x1000  /* late collision */
186
#define TMD3_UFLO               0x4000  /* underflow (late memory) */
187
#define TMD3_BUFF               0x8000  /* buffering error (no ENP) */
188
 
189
/* rx_head flags */
190
#define RMD1_ENP                0x01    /* end of packet */
191
#define RMD1_STP                0x02    /* start of packet */
192
#define RMD1_BUFF               0x04    /* buffer error */
193
#define RMD1_CRC                0x08    /* CRC error */
194
#define RMD1_OFLO               0x10    /* overflow */
195
#define RMD1_FRAM               0x20    /* framing error */
196
#define RMD1_ERR                0x40    /* error summary */
197
#define RMD1_OWN                0x80    /* ownership (set: ship owns) */
198
 
199
#define RMD1_OWN_CHIP   RMD1_OWN
200
#define RMD1_OWN_HOST   0
201
 
202
/* register names */
203
#define CSR0    0                /* mode/status */
204
#define CSR1    1               /* init block addr (low) */
205
#define CSR2    2               /* init block addr (high) */
206
#define CSR3    3               /* misc */
207
#define CSR8    8               /* address filter */
208
#define CSR15   15              /* promiscuous mode */
209
 
210
/* CSR0 */
211
/* (R=readable, W=writeable, S=set on write, C=clear on write) */
212
#define CSR0_INIT       0x0001          /* initialize (RS) */
213
#define CSR0_STRT       0x0002          /* start (RS) */
214
#define CSR0_STOP       0x0004          /* stop (RS) */
215
#define CSR0_TDMD       0x0008          /* transmit demand (RS) */
216
#define CSR0_TXON       0x0010          /* transmitter on (R) */
217
#define CSR0_RXON       0x0020          /* receiver on (R) */
218
#define CSR0_INEA       0x0040          /* interrupt enable (RW) */
219
#define CSR0_INTR       0x0080          /* interrupt active (R) */
220
#define CSR0_IDON       0x0100          /* initialization done (RC) */
221
#define CSR0_TINT       0x0200          /* transmitter interrupt (RC) */
222
#define CSR0_RINT       0x0400          /* receiver interrupt (RC) */
223
#define CSR0_MERR       0x0800          /* memory error (RC) */
224
#define CSR0_MISS       0x1000          /* missed frame (RC) */
225
#define CSR0_CERR       0x2000          /* carrier error (no heartbeat :-) (RC) */
226
#define CSR0_BABL       0x4000          /* babble: tx-ed too many bits (RC) */
227
#define CSR0_ERR        0x8000          /* error (RC) */
228
 
229
/* CSR3 */
230
#define CSR3_BCON       0x0001          /* byte control */
231
#define CSR3_ACON       0x0002          /* ALE control */
232
#define CSR3_BSWP       0x0004          /* byte swap (1=big endian) */
233
 
234
/***************************** Prototypes *****************************/
235
 
236
static int lance_probe( struct net_device *dev);
237
static int lance_open( struct net_device *dev );
238
static void lance_init_ring( struct net_device *dev );
239
static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev );
240
static irqreturn_t lance_interrupt( int irq, void *dev_id);
241
static int lance_rx( struct net_device *dev );
242
static int lance_close( struct net_device *dev );
243
static void set_multicast_list( struct net_device *dev );
244
 
245
/************************* End of Prototypes **************************/
246
 
247
struct net_device * __init sun3lance_probe(int unit)
248
{
249
        struct net_device *dev;
250
        static int found;
251
        int err = -ENODEV;
252
 
253
        /* check that this machine has an onboard lance */
254
        switch(idprom->id_machtype) {
255
        case SM_SUN3|SM_3_50:
256
        case SM_SUN3|SM_3_60:
257
        case SM_SUN3X|SM_3_80:
258
                /* these machines have lance */
259
                break;
260
 
261
        default:
262
                return ERR_PTR(-ENODEV);
263
        }
264
 
265
        if (found)
266
                return ERR_PTR(-ENODEV);
267
 
268
        dev = alloc_etherdev(sizeof(struct lance_private));
269
        if (!dev)
270
                return ERR_PTR(-ENOMEM);
271
        if (unit >= 0) {
272
                sprintf(dev->name, "eth%d", unit);
273
                netdev_boot_setup_check(dev);
274
        }
275
 
276
        if (!lance_probe(dev))
277
                goto out;
278
 
279
        err = register_netdev(dev);
280
        if (err)
281
                goto out1;
282
        found = 1;
283
        return dev;
284
 
285
out1:
286
#ifdef CONFIG_SUN3
287
        iounmap((void __iomem *)dev->base_addr);
288
#endif
289
out:
290
        free_netdev(dev);
291
        return ERR_PTR(err);
292
}
293
 
294
static int __init lance_probe( struct net_device *dev)
295
{
296
        unsigned long ioaddr;
297
 
298
        struct lance_private    *lp;
299
        int                     i;
300
        static int              did_version;
301
        volatile unsigned short *ioaddr_probe;
302
        unsigned short tmp1, tmp2;
303
        DECLARE_MAC_BUF(mac);
304
 
305
#ifdef CONFIG_SUN3
306
        ioaddr = (unsigned long)ioremap(LANCE_OBIO, PAGE_SIZE);
307
        if (!ioaddr)
308
                return 0;
309
#else
310
        ioaddr = SUN3X_LANCE;
311
#endif
312
 
313
        /* test to see if there's really a lance here */
314
        /* (CSRO_INIT shouldn't be readable) */
315
 
316
        ioaddr_probe = (volatile unsigned short *)ioaddr;
317
        tmp1 = ioaddr_probe[0];
318
        tmp2 = ioaddr_probe[1];
319
 
320
        ioaddr_probe[1] = CSR0;
321
        ioaddr_probe[0] = CSR0_INIT | CSR0_STOP;
322
 
323
        if(ioaddr_probe[0] != CSR0_STOP) {
324
                ioaddr_probe[0] = tmp1;
325
                ioaddr_probe[1] = tmp2;
326
 
327
#ifdef CONFIG_SUN3
328
                iounmap((void __iomem *)ioaddr);
329
#endif
330
                return 0;
331
        }
332
 
333
        lp = netdev_priv(dev);
334
 
335
        /* XXX - leak? */
336
        MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000);
337
        if (MEM == NULL) {
338
#ifdef CONFIG_SUN3
339
                iounmap((void __iomem *)ioaddr);
340
#endif
341
                printk(KERN_WARNING "SUN3 Lance couldn't allocate DVMA memory\n");
342
                return 0;
343
        }
344
 
345
        lp->iobase = (volatile unsigned short *)ioaddr;
346
        dev->base_addr = (unsigned long)ioaddr; /* informational only */
347
 
348
        REGA(CSR0) = CSR0_STOP;
349
 
350
        if (request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev) < 0) {
351
#ifdef CONFIG_SUN3
352
                iounmap((void __iomem *)ioaddr);
353
#endif
354
                dvma_free((void *)MEM);
355
                printk(KERN_WARNING "SUN3 Lance unable to allocate IRQ\n");
356
                return 0;
357
        }
358
        dev->irq = (unsigned short)LANCE_IRQ;
359
 
360
 
361
        printk("%s: SUN3 Lance at io %#lx, mem %#lx, irq %d, hwaddr ",
362
                   dev->name,
363
                   (unsigned long)ioaddr,
364
                   (unsigned long)MEM,
365
                   dev->irq);
366
 
367
        /* copy in the ethernet address from the prom */
368
        for(i = 0; i < 6 ; i++)
369
             dev->dev_addr[i] = idprom->id_ethaddr[i];
370
 
371
        /* tell the card it's ether address, bytes swapped */
372
        MEM->init.hwaddr[0] = dev->dev_addr[1];
373
        MEM->init.hwaddr[1] = dev->dev_addr[0];
374
        MEM->init.hwaddr[2] = dev->dev_addr[3];
375
        MEM->init.hwaddr[3] = dev->dev_addr[2];
376
        MEM->init.hwaddr[4] = dev->dev_addr[5];
377
        MEM->init.hwaddr[5] = dev->dev_addr[4];
378
 
379
        printk("%s\n", print_mac(mac, dev->dev_addr));
380
 
381
        MEM->init.mode = 0x0000;
382
        MEM->init.filter[0] = 0x00000000;
383
        MEM->init.filter[1] = 0x00000000;
384
        MEM->init.rdra = dvma_vtob(MEM->rx_head);
385
        MEM->init.rlen    = (RX_LOG_RING_SIZE << 13) |
386
                (dvma_vtob(MEM->rx_head) >> 16);
387
        MEM->init.tdra = dvma_vtob(MEM->tx_head);
388
        MEM->init.tlen    = (TX_LOG_RING_SIZE << 13) |
389
                (dvma_vtob(MEM->tx_head) >> 16);
390
 
391
        DPRINTK(2, ("initaddr: %08lx rx_ring: %08lx tx_ring: %08lx\n",
392
               dvma_vtob(&(MEM->init)), dvma_vtob(MEM->rx_head),
393
               (dvma_vtob(MEM->tx_head))));
394
 
395
        if (did_version++ == 0)
396
                printk( version );
397
 
398
        /* The LANCE-specific entries in the device structure. */
399
        dev->open = &lance_open;
400
        dev->hard_start_xmit = &lance_start_xmit;
401
        dev->stop = &lance_close;
402
        dev->set_multicast_list = &set_multicast_list;
403
        dev->set_mac_address = NULL;
404
//      KLUDGE -- REMOVE ME
405
        set_bit(__LINK_STATE_PRESENT, &dev->state);
406
 
407
 
408
        return 1;
409
}
410
 
411
static int lance_open( struct net_device *dev )
412
{
413
        struct lance_private *lp = netdev_priv(dev);
414
        int i;
415
 
416
        DPRINTK( 2, ( "%s: lance_open()\n", dev->name ));
417
 
418
        REGA(CSR0) = CSR0_STOP;
419
 
420
        lance_init_ring(dev);
421
 
422
        /* From now on, AREG is kept to point to CSR0 */
423
        REGA(CSR0) = CSR0_INIT;
424
 
425
        i = 1000000;
426
        while (--i > 0)
427
                if (DREG & CSR0_IDON)
428
                        break;
429
        if (i < 0 || (DREG & CSR0_ERR)) {
430
                DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
431
                                          dev->name, i, DREG ));
432
                DREG = CSR0_STOP;
433
                return( -EIO );
434
        }
435
 
436
        DREG = CSR0_IDON | CSR0_STRT | CSR0_INEA;
437
 
438
        netif_start_queue(dev);
439
 
440
        DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG ));
441
 
442
        return( 0 );
443
}
444
 
445
 
446
/* Initialize the LANCE Rx and Tx rings. */
447
 
448
static void lance_init_ring( struct net_device *dev )
449
{
450
        struct lance_private *lp = netdev_priv(dev);
451
        int i;
452
 
453
        lp->lock = 0;
454
        lp->tx_full = 0;
455
        lp->new_rx = lp->new_tx = 0;
456
        lp->old_rx = lp->old_tx = 0;
457
 
458
        for( i = 0; i < TX_RING_SIZE; i++ ) {
459
                MEM->tx_head[i].base = dvma_vtob(MEM->tx_data[i]);
460
                MEM->tx_head[i].flag = 0;
461
                MEM->tx_head[i].base_hi =
462
                        (dvma_vtob(MEM->tx_data[i])) >>16;
463
                MEM->tx_head[i].length = 0;
464
                MEM->tx_head[i].misc = 0;
465
        }
466
 
467
        for( i = 0; i < RX_RING_SIZE; i++ ) {
468
                MEM->rx_head[i].base = dvma_vtob(MEM->rx_data[i]);
469
                MEM->rx_head[i].flag = RMD1_OWN_CHIP;
470
                MEM->rx_head[i].base_hi =
471
                        (dvma_vtob(MEM->rx_data[i])) >> 16;
472
                MEM->rx_head[i].buf_length = -PKT_BUF_SZ | 0xf000;
473
                MEM->rx_head[i].msg_length = 0;
474
        }
475
 
476
        /* tell the card it's ether address, bytes swapped */
477
        MEM->init.hwaddr[0] = dev->dev_addr[1];
478
        MEM->init.hwaddr[1] = dev->dev_addr[0];
479
        MEM->init.hwaddr[2] = dev->dev_addr[3];
480
        MEM->init.hwaddr[3] = dev->dev_addr[2];
481
        MEM->init.hwaddr[4] = dev->dev_addr[5];
482
        MEM->init.hwaddr[5] = dev->dev_addr[4];
483
 
484
        MEM->init.mode = 0x0000;
485
        MEM->init.filter[0] = 0x00000000;
486
        MEM->init.filter[1] = 0x00000000;
487
        MEM->init.rdra = dvma_vtob(MEM->rx_head);
488
        MEM->init.rlen    = (RX_LOG_RING_SIZE << 13) |
489
                (dvma_vtob(MEM->rx_head) >> 16);
490
        MEM->init.tdra = dvma_vtob(MEM->tx_head);
491
        MEM->init.tlen    = (TX_LOG_RING_SIZE << 13) |
492
                (dvma_vtob(MEM->tx_head) >> 16);
493
 
494
 
495
        /* tell the lance the address of its init block */
496
        REGA(CSR1) = dvma_vtob(&(MEM->init));
497
        REGA(CSR2) = dvma_vtob(&(MEM->init)) >> 16;
498
 
499
#ifdef CONFIG_SUN3X
500
        REGA(CSR3) = CSR3_BSWP | CSR3_ACON | CSR3_BCON;
501
#else
502
        REGA(CSR3) = CSR3_BSWP;
503
#endif
504
 
505
}
506
 
507
 
508
static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
509
{
510
        struct lance_private *lp = netdev_priv(dev);
511
        int entry, len;
512
        struct lance_tx_head *head;
513
        unsigned long flags;
514
 
515
        DPRINTK( 1, ( "%s: transmit start.\n",
516
                      dev->name));
517
 
518
        /* Transmitter timeout, serious problems. */
519
        if (netif_queue_stopped(dev)) {
520
                int tickssofar = jiffies - dev->trans_start;
521
                if (tickssofar < 20)
522
                        return( 1 );
523
 
524
                DPRINTK( 1, ( "%s: transmit timed out, status %04x, resetting.\n",
525
                                          dev->name, DREG ));
526
                DREG = CSR0_STOP;
527
                /*
528
                 * Always set BSWP after a STOP as STOP puts it back into
529
                 * little endian mode.
530
                 */
531
                REGA(CSR3) = CSR3_BSWP;
532
                dev->stats.tx_errors++;
533
 
534
                if(lance_debug >= 2) {
535
                        int i;
536
                        printk("Ring data: old_tx %d new_tx %d%s new_rx %d\n",
537
                               lp->old_tx, lp->new_tx,
538
                               lp->tx_full ? " (full)" : "",
539
                               lp->new_rx );
540
                        for( i = 0 ; i < RX_RING_SIZE; i++ )
541
                                printk( "rx #%d: base=%04x blen=%04x mlen=%04x\n",
542
                                        i, MEM->rx_head[i].base,
543
                                        -MEM->rx_head[i].buf_length,
544
                                        MEM->rx_head[i].msg_length);
545
                        for( i = 0 ; i < TX_RING_SIZE; i++ )
546
                                printk("tx #%d: base=%04x len=%04x misc=%04x\n",
547
                                       i, MEM->tx_head[i].base,
548
                                       -MEM->tx_head[i].length,
549
                                       MEM->tx_head[i].misc );
550
                }
551
 
552
                lance_init_ring(dev);
553
                REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
554
 
555
                netif_start_queue(dev);
556
                dev->trans_start = jiffies;
557
 
558
                return 0;
559
        }
560
 
561
 
562
        /* Block a timer-based transmit from overlapping.  This could better be
563
           done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
564
 
565
        /* Block a timer-based transmit from overlapping with us by
566
           stopping the queue for a bit... */
567
 
568
        netif_stop_queue(dev);
569
 
570
        if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) {
571
                printk( "%s: tx queue lock!.\n", dev->name);
572
                /* don't clear dev->tbusy flag. */
573
                return 1;
574
        }
575
 
576
        AREG = CSR0;
577
        DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
578
                                  dev->name, DREG ));
579
 
580
#ifdef CONFIG_SUN3X
581
        /* this weirdness doesn't appear on sun3... */
582
        if(!(DREG & CSR0_INIT)) {
583
                DPRINTK( 1, ("INIT not set, reinitializing...\n"));
584
                REGA( CSR0 ) = CSR0_STOP;
585
                lance_init_ring(dev);
586
                REGA( CSR0 ) = CSR0_INIT | CSR0_STRT;
587
        }
588
#endif
589
 
590
        /* Fill in a Tx ring entry */
591
#if 0
592
        if (lance_debug >= 2) {
593
                printk( "%s: TX pkt %d type 0x%04x"
594
                        " from %s to %s"
595
                        " data at 0x%08x len %d\n",
596
                        dev->name, lp->new_tx, ((u_short *)skb->data)[6],
597
                        DEV_ADDR(&skb->data[6]), DEV_ADDR(skb->data),
598
                        (int)skb->data, (int)skb->len );
599
        }
600
#endif
601
        /* We're not prepared for the int until the last flags are set/reset.
602
         * And the int may happen already after setting the OWN_CHIP... */
603
        local_irq_save(flags);
604
 
605
        /* Mask to ring buffer boundary. */
606
        entry = lp->new_tx;
607
        head  = &(MEM->tx_head[entry]);
608
 
609
        /* Caution: the write order is important here, set the "ownership" bits
610
         * last.
611
         */
612
 
613
        /* the sun3's lance needs it's buffer padded to the minimum
614
           size */
615
        len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
616
 
617
//      head->length = -len;
618
        head->length = (-len) | 0xf000;
619
        head->misc = 0;
620
 
621
        skb_copy_from_linear_data(skb, PKTBUF_ADDR(head), skb->len);
622
        if (len != skb->len)
623
                memset(PKTBUF_ADDR(head) + skb->len, 0, len-skb->len);
624
 
625
        head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP;
626
        lp->new_tx = (lp->new_tx + 1) & TX_RING_MOD_MASK;
627
        dev->stats.tx_bytes += skb->len;
628
 
629
        /* Trigger an immediate send poll. */
630
        REGA(CSR0) = CSR0_INEA | CSR0_TDMD | CSR0_STRT;
631
        AREG = CSR0;
632
        DPRINTK( 2, ( "%s: lance_start_xmit() exiting, csr0 %4.4x.\n",
633
                                  dev->name, DREG ));
634
        dev->trans_start = jiffies;
635
        dev_kfree_skb( skb );
636
 
637
        lp->lock = 0;
638
        if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
639
            TMD1_OWN_HOST)
640
                netif_start_queue(dev);
641
 
642
        local_irq_restore(flags);
643
 
644
        return 0;
645
}
646
 
647
/* The LANCE interrupt handler. */
648
 
649
static irqreturn_t lance_interrupt( int irq, void *dev_id)
650
{
651
        struct net_device *dev = dev_id;
652
        struct lance_private *lp = netdev_priv(dev);
653
        int csr0;
654
        static int in_interrupt;
655
 
656
        if (dev == NULL) {
657
                DPRINTK( 1, ( "lance_interrupt(): invalid dev_id\n" ));
658
                return IRQ_NONE;
659
        }
660
 
661
        if (in_interrupt)
662
                DPRINTK( 2, ( "%s: Re-entering the interrupt handler.\n", dev->name ));
663
        in_interrupt = 1;
664
 
665
 still_more:
666
        flush_cache_all();
667
 
668
        AREG = CSR0;
669
        csr0 = DREG;
670
 
671
        /* ack interrupts */
672
        DREG = csr0 & (CSR0_TINT | CSR0_RINT | CSR0_IDON);
673
 
674
        /* clear errors */
675
        if(csr0 & CSR0_ERR)
676
                DREG = CSR0_BABL | CSR0_MERR | CSR0_CERR | CSR0_MISS;
677
 
678
 
679
        DPRINTK( 2, ( "%s: interrupt  csr0=%04x new csr=%04x.\n",
680
                      dev->name, csr0, DREG ));
681
 
682
        if (csr0 & CSR0_TINT) {                 /* Tx-done interrupt */
683
                int old_tx = lp->old_tx;
684
 
685
//              if(lance_debug >= 3) {
686
//                      int i;
687
//
688
//                      printk("%s: tx int\n", dev->name);
689
//
690
//                      for(i = 0; i < TX_RING_SIZE; i++)
691
//                              printk("ring %d flag=%04x\n", i,
692
//                                     MEM->tx_head[i].flag);
693
//              }
694
 
695
                while( old_tx != lp->new_tx) {
696
                        struct lance_tx_head *head = &(MEM->tx_head[old_tx]);
697
 
698
                        DPRINTK(3, ("on tx_ring %d\n", old_tx));
699
 
700
                        if (head->flag & TMD1_OWN_CHIP)
701
                                break; /* It still hasn't been Txed */
702
 
703
                        if (head->flag & TMD1_ERR) {
704
                                int status = head->misc;
705
                                dev->stats.tx_errors++;
706
                                if (status & TMD3_RTRY) dev->stats.tx_aborted_errors++;
707
                                if (status & TMD3_LCAR) dev->stats.tx_carrier_errors++;
708
                                if (status & TMD3_LCOL) dev->stats.tx_window_errors++;
709
                                if (status & (TMD3_UFLO | TMD3_BUFF)) {
710
                                        dev->stats.tx_fifo_errors++;
711
                                        printk("%s: Tx FIFO error\n",
712
                                               dev->name);
713
                                        REGA(CSR0) = CSR0_STOP;
714
                                        REGA(CSR3) = CSR3_BSWP;
715
                                        lance_init_ring(dev);
716
                                        REGA(CSR0) = CSR0_STRT | CSR0_INEA;
717
                                        return IRQ_HANDLED;
718
                                }
719
                        } else if(head->flag & (TMD1_ENP | TMD1_STP)) {
720
 
721
                                head->flag &= ~(TMD1_ENP | TMD1_STP);
722
                                if(head->flag & (TMD1_ONE | TMD1_MORE))
723
                                        dev->stats.collisions++;
724
 
725
                                dev->stats.tx_packets++;
726
                                DPRINTK(3, ("cleared tx ring %d\n", old_tx));
727
                        }
728
                        old_tx = (old_tx +1) & TX_RING_MOD_MASK;
729
                }
730
 
731
                lp->old_tx = old_tx;
732
        }
733
 
734
 
735
        if (netif_queue_stopped(dev)) {
736
                /* The ring is no longer full, clear tbusy. */
737
                netif_start_queue(dev);
738
                netif_wake_queue(dev);
739
        }
740
 
741
        if (csr0 & CSR0_RINT)                   /* Rx interrupt */
742
                lance_rx( dev );
743
 
744
        /* Log misc errors. */
745
        if (csr0 & CSR0_BABL) dev->stats.tx_errors++; /* Tx babble. */
746
        if (csr0 & CSR0_MISS) dev->stats.rx_errors++; /* Missed a Rx frame. */
747
        if (csr0 & CSR0_MERR) {
748
                DPRINTK( 1, ( "%s: Bus master arbitration failure (?!?), "
749
                              "status %04x.\n", dev->name, csr0 ));
750
                /* Restart the chip. */
751
                REGA(CSR0) = CSR0_STOP;
752
                REGA(CSR3) = CSR3_BSWP;
753
                lance_init_ring(dev);
754
                REGA(CSR0) = CSR0_STRT | CSR0_INEA;
755
        }
756
 
757
 
758
    /* Clear any other interrupt, and set interrupt enable. */
759
//      DREG = CSR0_BABL | CSR0_CERR | CSR0_MISS | CSR0_MERR |
760
//                 CSR0_IDON | CSR0_INEA;
761
 
762
        REGA(CSR0) = CSR0_INEA;
763
 
764
        if(DREG & (CSR0_RINT | CSR0_TINT)) {
765
             DPRINTK(2, ("restarting interrupt, csr0=%#04x\n", DREG));
766
             goto still_more;
767
        }
768
 
769
        DPRINTK( 2, ( "%s: exiting interrupt, csr0=%#04x.\n",
770
                                  dev->name, DREG ));
771
        in_interrupt = 0;
772
        return IRQ_HANDLED;
773
}
774
 
775
/* get packet, toss into skbuff */
776
static int lance_rx( struct net_device *dev )
777
{
778
        struct lance_private *lp = netdev_priv(dev);
779
        int entry = lp->new_rx;
780
 
781
        /* If we own the next entry, it's a new packet. Send it up. */
782
        while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) {
783
                struct lance_rx_head *head = &(MEM->rx_head[entry]);
784
                int status = head->flag;
785
 
786
                if (status != (RMD1_ENP|RMD1_STP)) {  /* There was an error. */
787
                        /* There is a tricky error noted by John Murphy,
788
                           <murf@perftech.com> to Russ Nelson: Even with
789
                           full-sized buffers it's possible for a jabber packet to use two
790
                           buffers, with only the last correctly noting the error. */
791
                        if (status & RMD1_ENP)  /* Only count a general error at the */
792
                                dev->stats.rx_errors++; /* end of a packet.*/
793
                        if (status & RMD1_FRAM) dev->stats.rx_frame_errors++;
794
                        if (status & RMD1_OFLO) dev->stats.rx_over_errors++;
795
                        if (status & RMD1_CRC) dev->stats.rx_crc_errors++;
796
                        if (status & RMD1_BUFF) dev->stats.rx_fifo_errors++;
797
                        head->flag &= (RMD1_ENP|RMD1_STP);
798
                } else {
799
                        /* Malloc up new buffer, compatible with net-3. */
800
//                      short pkt_len = head->msg_length;// & 0xfff;
801
                        short pkt_len = (head->msg_length & 0xfff) - 4;
802
                        struct sk_buff *skb;
803
 
804
                        if (pkt_len < 60) {
805
                                printk( "%s: Runt packet!\n", dev->name );
806
                                dev->stats.rx_errors++;
807
                        }
808
                        else {
809
                                skb = dev_alloc_skb( pkt_len+2 );
810
                                if (skb == NULL) {
811
                                        DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
812
                                                      dev->name ));
813
 
814
                                        dev->stats.rx_dropped++;
815
                                        head->msg_length = 0;
816
                                        head->flag |= RMD1_OWN_CHIP;
817
                                        lp->new_rx = (lp->new_rx+1) &
818
                                             RX_RING_MOD_MASK;
819
                                }
820
 
821
#if 0
822
                                if (lance_debug >= 3) {
823
                                        u_char *data = PKTBUF_ADDR(head);
824
                                        DECLARE_MAC_BUF(mac);
825
                                        DECLARE_MAC_BUF(mac2)
826
                                        printk("%s: RX pkt %d type 0x%04x"
827
                                               " from %s to %s",
828
                                               dev->name, lp->new_tx, ((u_short *)data)[6],
829
                                               print_mac(mac, &data[6]), print_mac(mac2, data));
830
 
831
                                        printk(" data %02x %02x %02x %02x %02x %02x %02x %02x "
832
                                               "len %d at %08x\n",
833
                                               data[15], data[16], data[17], data[18],
834
                                               data[19], data[20], data[21], data[22],
835
                                               pkt_len, data);
836
                                }
837
#endif
838
                                if (lance_debug >= 3) {
839
                                        u_char *data = PKTBUF_ADDR(head);
840
                                        printk( "%s: RX pkt %d type 0x%04x len %d\n ", dev->name, entry, ((u_short *)data)[6], pkt_len);
841
                                }
842
 
843
 
844
                                skb_reserve( skb, 2 );  /* 16 byte align */
845
                                skb_put( skb, pkt_len );        /* Make room */
846
                                skb_copy_to_linear_data(skb,
847
                                                 PKTBUF_ADDR(head),
848
                                                 pkt_len);
849
 
850
                                skb->protocol = eth_type_trans( skb, dev );
851
                                netif_rx( skb );
852
                                dev->last_rx = jiffies;
853
                                dev->stats.rx_packets++;
854
                                dev->stats.rx_bytes += pkt_len;
855
                        }
856
                }
857
 
858
//              head->buf_length = -PKT_BUF_SZ | 0xf000;
859
                head->msg_length = 0;
860
                head->flag = RMD1_OWN_CHIP;
861
 
862
                entry = lp->new_rx = (lp->new_rx +1) & RX_RING_MOD_MASK;
863
        }
864
 
865
        /* From lance.c (Donald Becker): */
866
        /* We should check that at least two ring entries are free.
867
           If not, we should free one and mark stats->rx_dropped++. */
868
 
869
        return 0;
870
}
871
 
872
 
873
static int lance_close( struct net_device *dev )
874
{
875
        struct lance_private *lp = netdev_priv(dev);
876
 
877
        netif_stop_queue(dev);
878
 
879
        AREG = CSR0;
880
 
881
        DPRINTK( 2, ( "%s: Shutting down ethercard, status was %2.2x.\n",
882
                                  dev->name, DREG ));
883
 
884
        /* We stop the LANCE here -- it occasionally polls
885
           memory if we don't. */
886
        DREG = CSR0_STOP;
887
        return 0;
888
}
889
 
890
 
891
/* Set or clear the multicast filter for this adaptor.
892
   num_addrs == -1              Promiscuous mode, receive all packets
893
   num_addrs == 0               Normal mode, clear multicast list
894
   num_addrs > 0                Multicast mode, receive normal and MC packets, and do
895
                                                best-effort filtering.
896
 */
897
 
898
/* completely untested on a sun3 */
899
static void set_multicast_list( struct net_device *dev )
900
{
901
        struct lance_private *lp = netdev_priv(dev);
902
 
903
        if(netif_queue_stopped(dev))
904
                /* Only possible if board is already started */
905
                return;
906
 
907
        /* We take the simple way out and always enable promiscuous mode. */
908
        DREG = CSR0_STOP; /* Temporarily stop the lance. */
909
 
910
        if (dev->flags & IFF_PROMISC) {
911
                /* Log any net taps. */
912
                DPRINTK( 3, ( "%s: Promiscuous mode enabled.\n", dev->name ));
913
                REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
914
        } else {
915
                short multicast_table[4];
916
                int num_addrs = dev->mc_count;
917
                int i;
918
                /* We don't use the multicast table, but rely on upper-layer
919
                 * filtering. */
920
                memset( multicast_table, (num_addrs == 0) ? 0 : -1,
921
                                sizeof(multicast_table) );
922
                for( i = 0; i < 4; i++ )
923
                        REGA( CSR8+i ) = multicast_table[i];
924
                REGA( CSR15 ) = 0; /* Unset promiscuous mode */
925
        }
926
 
927
        /*
928
         * Always set BSWP after a STOP as STOP puts it back into
929
         * little endian mode.
930
         */
931
        REGA( CSR3 ) = CSR3_BSWP;
932
 
933
        /* Resume normal operation and reset AREG to CSR0 */
934
        REGA( CSR0 ) = CSR0_IDON | CSR0_INEA | CSR0_STRT;
935
}
936
 
937
 
938
#ifdef MODULE
939
 
940
static struct net_device *sun3lance_dev;
941
 
942
int __init init_module(void)
943
{
944
        sun3lance_dev = sun3lance_probe(-1);
945
        if (IS_ERR(sun3lance_dev))
946
                return PTR_ERR(sun3lance_dev);
947
        return 0;
948
}
949
 
950
void __exit cleanup_module(void)
951
{
952
        unregister_netdev(sun3lance_dev);
953
#ifdef CONFIG_SUN3
954
        iounmap((void __iomem *)sun3lance_dev->base_addr);
955
#endif
956
        free_netdev(sun3lance_dev);
957
}
958
 
959
#endif /* MODULE */
960
 

powered by: WebSVN 2.1.0

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