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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
net-3-driver for the IBM LAN Adapter/A
3
 
4
This is an extension to the Linux operating system, and is covered by the
5
same GNU General Public License that covers that work.
6
 
7
Copyright 1999 by Alfred Arnold (alfred@ccac.rwth-aachen.de,
8
                                 alfred.arnold@lancom.de)
9
 
10
This driver is based both on the SK_MCA driver, which is itself based on the
11
SK_G16 and 3C523 driver.
12
 
13
paper sources:
14
  'PC Hardware: Aufbau, Funktionsweise, Programmierung' by
15
  Hans-Peter Messmer for the basic Microchannel stuff
16
 
17
  'Linux Geraetetreiber' by Allesandro Rubini, Kalle Dalheimer
18
  for help on Ethernet driver programming
19
 
20
  'DP83934CVUL-20/25 MHz SONIC-T Ethernet Controller Datasheet' by National
21
  Semiconductor for info on the MAC chip
22
 
23
  'LAN Technical Reference Ethernet Adapter Interface Version 1 Release 1.0
24
   Document Number SC30-3661-00' by IBM for info on the adapter itself
25
 
26
  Also see http://www.natsemi.com/
27
 
28
special acknowledgements to:
29
  - Bob Eager for helping me out with documentation from IBM
30
  - Jim Shorney for his endless patience with me while I was using
31
    him as a beta tester to trace down the address filter bug ;-)
32
 
33
  Missing things:
34
 
35
  -> set debug level via ioctl instead of compile-time switches
36
  -> I didn't follow the development of the 2.1.x kernels, so my
37
     assumptions about which things changed with which kernel version
38
     are probably nonsense
39
 
40
History:
41
  Nov 6th, 1999
42
        startup from SK_MCA driver
43
  Dec 6th, 1999
44
        finally got docs about the card.  A big thank you to Bob Eager!
45
  Dec 12th, 1999
46
        first packet received
47
  Dec 13th, 1999
48
        recv queue done, tcpdump works
49
  Dec 15th, 1999
50
        transmission part works
51
  Dec 28th, 1999
52
        added usage of the isa_functions for Linux 2.3 .  Things should
53
        still work with 2.0.x....
54
  Jan 28th, 2000
55
        in Linux 2.2.13, the version.h file mysteriously didn't get
56
        included.  Added a workaround for this.  Futhermore, it now
57
        not only compiles as a modules ;-)
58
  Jan 30th, 2000
59
        newer kernels automatically probe more than one board, so the
60
        'startslot' as a variable is also needed here
61
  Apr 12th, 2000
62
        the interrupt mask register is not set 'hard' instead of individually
63
        setting registers, since this seems to set bits that shouldn't be
64
        set
65
  May 21st, 2000
66
        reset interrupt status immediately after CAM load
67
        add a recovery delay after releasing the chip's reset line
68
  May 24th, 2000
69
        finally found the bug in the address filter setup - damned signed
70
        chars!
71
  June 1st, 2000
72
        corrected version codes, added support for the latest 2.3 changes
73
  Oct 28th, 2002
74
        cleaned up for the 2.5 tree <alan@redhat.com>
75
 
76
 *************************************************************************/
77
 
78
#include <linux/kernel.h>
79
#include <linux/string.h>
80
#include <linux/errno.h>
81
#include <linux/ioport.h>
82
#include <linux/slab.h>
83
#include <linux/interrupt.h>
84
#include <linux/delay.h>
85
#include <linux/time.h>
86
#include <linux/mca-legacy.h>
87
#include <linux/module.h>
88
#include <linux/netdevice.h>
89
#include <linux/etherdevice.h>
90
#include <linux/skbuff.h>
91
#include <linux/bitops.h>
92
 
93
#include <asm/processor.h>
94
#include <asm/io.h>
95
 
96
#define _IBM_LANA_DRIVER_
97
#include "ibmlana.h"
98
 
99
#undef DEBUG
100
 
101
#define DRV_NAME "ibmlana"
102
 
103
/* ------------------------------------------------------------------------
104
 * global static data - not more since we can handle multiple boards and
105
 * have to pack all state info into the device struct!
106
 * ------------------------------------------------------------------------ */
107
 
108
static char *MediaNames[Media_Count] = {
109
        "10BaseT", "10Base5", "Unknown", "10Base2"
110
};
111
 
112
/* ------------------------------------------------------------------------
113
 * private subfunctions
114
 * ------------------------------------------------------------------------ */
115
 
116
#ifdef DEBUG
117
  /* dump all registers */
118
 
119
static void dumpregs(struct net_device *dev)
120
{
121
        int z;
122
 
123
        for (z = 0; z < 160; z += 2) {
124
                if (!(z & 15))
125
                        printk("REGS: %04x:", z);
126
                printk(" %04x", inw(dev->base_addr + z));
127
                if ((z & 15) == 14)
128
                        printk("\n");
129
        }
130
}
131
 
132
/* dump parts of shared memory - only needed during debugging */
133
 
134
static void dumpmem(struct net_device *dev, u32 start, u32 len)
135
{
136
        ibmlana_priv *priv = netdev_priv(dev);
137
        int z;
138
 
139
        printk("Address %04x:\n", start);
140
        for (z = 0; z < len; z++) {
141
                if ((z & 15) == 0)
142
                        printk("%04x:", z);
143
                printk(" %02x", readb(priv->base + start + z));
144
                if ((z & 15) == 15)
145
                        printk("\n");
146
        }
147
        if ((z & 15) != 0)
148
                printk("\n");
149
}
150
 
151
/* print exact time - ditto */
152
 
153
static void PrTime(void)
154
{
155
        struct timeval tv;
156
 
157
        do_gettimeofday(&tv);
158
        printk("%9d:%06d: ", (int) tv.tv_sec, (int) tv.tv_usec);
159
}
160
#endif                          /* DEBUG */
161
 
162
/* deduce resources out of POS registers */
163
 
164
static void getaddrs(int slot, int *base, int *memlen, int *iobase,
165
                     int *irq, ibmlana_medium * medium)
166
{
167
        u_char pos0, pos1;
168
 
169
        pos0 = mca_read_stored_pos(slot, 2);
170
        pos1 = mca_read_stored_pos(slot, 3);
171
 
172
        *base = 0xc0000 + ((pos1 & 0xf0) << 9);
173
        *memlen = (pos1 & 0x01) ? 0x8000 : 0x4000;
174
        *iobase = (pos0 & 0xe0) << 7;
175
        switch (pos0 & 0x06) {
176
        case 0:
177
                *irq = 5;
178
                break;
179
        case 2:
180
                *irq = 15;
181
                break;
182
        case 4:
183
                *irq = 10;
184
                break;
185
        case 6:
186
                *irq = 11;
187
                break;
188
        }
189
        *medium = (pos0 & 0x18) >> 3;
190
}
191
 
192
/* wait on register value with mask and timeout */
193
 
194
static int wait_timeout(struct net_device *dev, int regoffs, u16 mask,
195
                        u16 value, int timeout)
196
{
197
        unsigned long fin = jiffies + timeout;
198
 
199
        while (time_before(jiffies,fin))
200
                if ((inw(dev->base_addr + regoffs) & mask) == value)
201
                        return 1;
202
 
203
        return 0;
204
}
205
 
206
 
207
/* reset the whole board */
208
 
209
static void ResetBoard(struct net_device *dev)
210
{
211
        unsigned char bcmval;
212
 
213
        /* read original board control value */
214
 
215
        bcmval = inb(dev->base_addr + BCMREG);
216
 
217
        /* set reset bit for a while */
218
 
219
        bcmval |= BCMREG_RESET;
220
        outb(bcmval, dev->base_addr + BCMREG);
221
        udelay(10);
222
        bcmval &= ~BCMREG_RESET;
223
        outb(bcmval, dev->base_addr + BCMREG);
224
 
225
        /* switch over to RAM again */
226
 
227
        bcmval |= BCMREG_RAMEN | BCMREG_RAMWIN;
228
        outb(bcmval, dev->base_addr + BCMREG);
229
}
230
 
231
/* calculate RAM layout & set up descriptors in RAM */
232
 
233
static void InitDscrs(struct net_device *dev)
234
{
235
        ibmlana_priv *priv = netdev_priv(dev);
236
        u32 addr, baddr, raddr;
237
        int z;
238
        tda_t tda;
239
        rda_t rda;
240
        rra_t rra;
241
 
242
        /* initialize RAM */
243
 
244
        memset_io(priv->base, 0xaa,
245
                      dev->mem_start - dev->mem_start); /* XXX: typo? */
246
 
247
        /* setup n TX descriptors - independent of RAM size */
248
 
249
        priv->tdastart = addr = 0;
250
        priv->txbufstart = baddr = sizeof(tda_t) * TXBUFCNT;
251
        for (z = 0; z < TXBUFCNT; z++) {
252
                tda.status = 0;
253
                tda.config = 0;
254
                tda.length = 0;
255
                tda.fragcount = 1;
256
                tda.startlo = baddr;
257
                tda.starthi = 0;
258
                tda.fraglength = 0;
259
                if (z == TXBUFCNT - 1)
260
                        tda.link = priv->tdastart;
261
                else
262
                        tda.link = addr + sizeof(tda_t);
263
                tda.link |= 1;
264
                memcpy_toio(priv->base + addr, &tda, sizeof(tda_t));
265
                addr += sizeof(tda_t);
266
                baddr += PKTSIZE;
267
        }
268
 
269
        /* calculate how many receive buffers fit into remaining memory */
270
 
271
        priv->rxbufcnt = (dev->mem_end - dev->mem_start - baddr) / (sizeof(rra_t) + sizeof(rda_t) + PKTSIZE);
272
 
273
        /* calculate receive addresses */
274
 
275
        priv->rrastart = raddr = priv->txbufstart + (TXBUFCNT * PKTSIZE);
276
        priv->rdastart = addr = priv->rrastart + (priv->rxbufcnt * sizeof(rra_t));
277
        priv->rxbufstart = baddr = priv->rdastart + (priv->rxbufcnt * sizeof(rda_t));
278
 
279
        for (z = 0; z < priv->rxbufcnt; z++) {
280
                rra.startlo = baddr;
281
                rra.starthi = 0;
282
                rra.cntlo = PKTSIZE >> 1;
283
                rra.cnthi = 0;
284
                memcpy_toio(priv->base + raddr, &rra, sizeof(rra_t));
285
 
286
                rda.status = 0;
287
                rda.length = 0;
288
                rda.startlo = 0;
289
                rda.starthi = 0;
290
                rda.seqno = 0;
291
                if (z < priv->rxbufcnt - 1)
292
                        rda.link = addr + sizeof(rda_t);
293
                else
294
                        rda.link = 1;
295
                rda.inuse = 1;
296
                memcpy_toio(priv->base + addr, &rda, sizeof(rda_t));
297
 
298
                baddr += PKTSIZE;
299
                raddr += sizeof(rra_t);
300
                addr += sizeof(rda_t);
301
        }
302
 
303
        /* initialize current pointers */
304
 
305
        priv->nextrxdescr = 0;
306
        priv->lastrxdescr = priv->rxbufcnt - 1;
307
        priv->nexttxdescr = 0;
308
        priv->currtxdescr = 0;
309
        priv->txusedcnt = 0;
310
        memset(priv->txused, 0, sizeof(priv->txused));
311
}
312
 
313
/* set up Rx + Tx descriptors in SONIC */
314
 
315
static int InitSONIC(struct net_device *dev)
316
{
317
        ibmlana_priv *priv = netdev_priv(dev);
318
 
319
        /* set up start & end of resource area */
320
 
321
        outw(0, SONIC_URRA);
322
        outw(priv->rrastart, dev->base_addr + SONIC_RSA);
323
        outw(priv->rrastart + (priv->rxbufcnt * sizeof(rra_t)), dev->base_addr + SONIC_REA);
324
        outw(priv->rrastart, dev->base_addr + SONIC_RRP);
325
        outw(priv->rrastart, dev->base_addr + SONIC_RWP);
326
 
327
        /* set EOBC so that only one packet goes into one buffer */
328
 
329
        outw((PKTSIZE - 4) >> 1, dev->base_addr + SONIC_EOBC);
330
 
331
        /* let SONIC read the first RRA descriptor */
332
 
333
        outw(CMDREG_RRRA, dev->base_addr + SONIC_CMDREG);
334
        if (!wait_timeout(dev, SONIC_CMDREG, CMDREG_RRRA, 0, 2)) {
335
                printk(KERN_ERR "%s: SONIC did not respond on RRRA command - giving up.", dev->name);
336
                return 0;
337
        }
338
 
339
        /* point SONIC to the first RDA */
340
 
341
        outw(0, dev->base_addr + SONIC_URDA);
342
        outw(priv->rdastart, dev->base_addr + SONIC_CRDA);
343
 
344
        /* set upper half of TDA address */
345
 
346
        outw(0, dev->base_addr + SONIC_UTDA);
347
 
348
        return 1;
349
}
350
 
351
/* stop SONIC so we can reinitialize it */
352
 
353
static void StopSONIC(struct net_device *dev)
354
{
355
        /* disable interrupts */
356
 
357
        outb(inb(dev->base_addr + BCMREG) & (~BCMREG_IEN), dev->base_addr + BCMREG);
358
        outb(0, dev->base_addr + SONIC_IMREG);
359
 
360
        /* reset the SONIC */
361
 
362
        outw(CMDREG_RST, dev->base_addr + SONIC_CMDREG);
363
        udelay(10);
364
        outw(CMDREG_RST, dev->base_addr + SONIC_CMDREG);
365
}
366
 
367
/* initialize card and SONIC for proper operation */
368
 
369
static void putcam(camentry_t * cams, int *camcnt, char *addr)
370
{
371
        camentry_t *pcam = cams + (*camcnt);
372
        u8 *uaddr = (u8 *) addr;
373
 
374
        pcam->index = *camcnt;
375
        pcam->addr0 = (((u16) uaddr[1]) << 8) | uaddr[0];
376
        pcam->addr1 = (((u16) uaddr[3]) << 8) | uaddr[2];
377
        pcam->addr2 = (((u16) uaddr[5]) << 8) | uaddr[4];
378
        (*camcnt)++;
379
}
380
 
381
static void InitBoard(struct net_device *dev)
382
{
383
        ibmlana_priv *priv = netdev_priv(dev);
384
        int camcnt;
385
        camentry_t cams[16];
386
        u32 cammask;
387
        struct dev_mc_list *mcptr;
388
        u16 rcrval;
389
 
390
        /* reset the SONIC */
391
 
392
        outw(CMDREG_RST, dev->base_addr + SONIC_CMDREG);
393
        udelay(10);
394
 
395
        /* clear all spurious interrupts */
396
 
397
        outw(inw(dev->base_addr + SONIC_ISREG), dev->base_addr + SONIC_ISREG);
398
 
399
        /* set up the SONIC's bus interface - constant for this adapter -
400
           must be done while the SONIC is in reset */
401
 
402
        outw(DCREG_USR1 | DCREG_USR0 | DCREG_WC1 | DCREG_DW32, dev->base_addr + SONIC_DCREG);
403
        outw(0, dev->base_addr + SONIC_DCREG2);
404
 
405
        /* remove reset form the SONIC */
406
 
407
        outw(0, dev->base_addr + SONIC_CMDREG);
408
        udelay(10);
409
 
410
        /* data sheet requires URRA to be programmed before setting up the CAM contents */
411
 
412
        outw(0, dev->base_addr + SONIC_URRA);
413
 
414
        /* program the CAM entry 0 to the device address */
415
 
416
        camcnt = 0;
417
        putcam(cams, &camcnt, dev->dev_addr);
418
 
419
        /* start putting the multicast addresses into the CAM list.  Stop if
420
           it is full. */
421
 
422
        for (mcptr = dev->mc_list; mcptr != NULL; mcptr = mcptr->next) {
423
                putcam(cams, &camcnt, mcptr->dmi_addr);
424
                if (camcnt == 16)
425
                        break;
426
        }
427
 
428
        /* calculate CAM mask */
429
 
430
        cammask = (1 << camcnt) - 1;
431
 
432
        /* feed CDA into SONIC, initialize RCR value (always get broadcasts) */
433
 
434
        memcpy_toio(priv->base, cams, sizeof(camentry_t) * camcnt);
435
        memcpy_toio(priv->base + (sizeof(camentry_t) * camcnt), &cammask, sizeof(cammask));
436
 
437
#ifdef DEBUG
438
        printk("CAM setup:\n");
439
        dumpmem(dev, 0, sizeof(camentry_t) * camcnt + sizeof(cammask));
440
#endif
441
 
442
        outw(0, dev->base_addr + SONIC_CAMPTR);
443
        outw(camcnt, dev->base_addr + SONIC_CAMCNT);
444
        outw(CMDREG_LCAM, dev->base_addr + SONIC_CMDREG);
445
        if (!wait_timeout(dev, SONIC_CMDREG, CMDREG_LCAM, 0, 2)) {
446
                printk(KERN_ERR "%s:SONIC did not respond on LCAM command - giving up.", dev->name);
447
                return;
448
        } else {
449
                /* clear interrupt condition */
450
 
451
                outw(ISREG_LCD, dev->base_addr + SONIC_ISREG);
452
 
453
#ifdef DEBUG
454
                printk("Loading CAM done, address pointers %04x:%04x\n",
455
                       inw(dev->base_addr + SONIC_URRA),
456
                       inw(dev->base_addr + SONIC_CAMPTR));
457
                {
458
                        int z;
459
 
460
                        printk("\n-->CAM: PTR %04x CNT %04x\n",
461
                               inw(dev->base_addr + SONIC_CAMPTR),
462
                               inw(dev->base_addr + SONIC_CAMCNT));
463
                        outw(CMDREG_RST, dev->base_addr + SONIC_CMDREG);
464
                        for (z = 0; z < camcnt; z++) {
465
                                outw(z, dev->base_addr + SONIC_CAMEPTR);
466
                                printk("Entry %d: %04x %04x %04x\n", z,
467
                                       inw(dev->base_addr + SONIC_CAMADDR0),
468
                                       inw(dev->base_addr + SONIC_CAMADDR1),
469
                                       inw(dev->base_addr + SONIC_CAMADDR2));
470
                        }
471
                        outw(0, dev->base_addr + SONIC_CMDREG);
472
                }
473
#endif
474
        }
475
 
476
        rcrval = RCREG_BRD | RCREG_LB_NONE;
477
 
478
        /* if still multicast addresses left or ALLMULTI is set, set the multicast
479
           enable bit */
480
 
481
        if ((dev->flags & IFF_ALLMULTI) || (mcptr != NULL))
482
                rcrval |= RCREG_AMC;
483
 
484
        /* promiscous mode ? */
485
 
486
        if (dev->flags & IFF_PROMISC)
487
                rcrval |= RCREG_PRO;
488
 
489
        /* program receive mode */
490
 
491
        outw(rcrval, dev->base_addr + SONIC_RCREG);
492
#ifdef DEBUG
493
        printk("\nRCRVAL: %04x\n", rcrval);
494
#endif
495
 
496
        /* set up descriptors in shared memory + feed them into SONIC registers */
497
 
498
        InitDscrs(dev);
499
        if (!InitSONIC(dev))
500
                return;
501
 
502
        /* reset all pending interrupts */
503
 
504
        outw(0xffff, dev->base_addr + SONIC_ISREG);
505
 
506
        /* enable transmitter + receiver interrupts */
507
 
508
        outw(CMDREG_RXEN, dev->base_addr + SONIC_CMDREG);
509
        outw(IMREG_PRXEN | IMREG_RBEEN | IMREG_PTXEN | IMREG_TXEREN, dev->base_addr + SONIC_IMREG);
510
 
511
        /* turn on card interrupts */
512
 
513
        outb(inb(dev->base_addr + BCMREG) | BCMREG_IEN, dev->base_addr + BCMREG);
514
 
515
#ifdef DEBUG
516
        printk("Register dump after initialization:\n");
517
        dumpregs(dev);
518
#endif
519
}
520
 
521
/* start transmission of a descriptor */
522
 
523
static void StartTx(struct net_device *dev, int descr)
524
{
525
        ibmlana_priv *priv = netdev_priv(dev);
526
        int addr;
527
 
528
        addr = priv->tdastart + (descr * sizeof(tda_t));
529
 
530
        /* put descriptor address into SONIC */
531
 
532
        outw(addr, dev->base_addr + SONIC_CTDA);
533
 
534
        /* trigger transmitter */
535
 
536
        priv->currtxdescr = descr;
537
        outw(CMDREG_TXP, dev->base_addr + SONIC_CMDREG);
538
}
539
 
540
/* ------------------------------------------------------------------------
541
 * interrupt handler(s)
542
 * ------------------------------------------------------------------------ */
543
 
544
/* receive buffer area exhausted */
545
 
546
static void irqrbe_handler(struct net_device *dev)
547
{
548
        ibmlana_priv *priv = netdev_priv(dev);
549
 
550
        /* point the SONIC back to the RRA start */
551
 
552
        outw(priv->rrastart, dev->base_addr + SONIC_RRP);
553
        outw(priv->rrastart, dev->base_addr + SONIC_RWP);
554
}
555
 
556
/* receive interrupt */
557
 
558
static void irqrx_handler(struct net_device *dev)
559
{
560
        ibmlana_priv *priv = netdev_priv(dev);
561
        rda_t rda;
562
        u32 rdaaddr, lrdaaddr;
563
 
564
        /* loop until ... */
565
 
566
        while (1) {
567
                /* read descriptor that was next to be filled by SONIC */
568
 
569
                rdaaddr = priv->rdastart + (priv->nextrxdescr * sizeof(rda_t));
570
                lrdaaddr = priv->rdastart + (priv->lastrxdescr * sizeof(rda_t));
571
                memcpy_fromio(&rda, priv->base + rdaaddr, sizeof(rda_t));
572
 
573
                /* iron out upper word halves of fields we use - SONIC will duplicate
574
                   bits 0..15 to 16..31 */
575
 
576
                rda.status &= 0xffff;
577
                rda.length &= 0xffff;
578
                rda.startlo &= 0xffff;
579
 
580
                /* stop if the SONIC still owns it, i.e. there is no data for us */
581
 
582
                if (rda.inuse)
583
                        break;
584
 
585
                /* good packet? */
586
 
587
                else if (rda.status & RCREG_PRX) {
588
                        struct sk_buff *skb;
589
 
590
                        /* fetch buffer */
591
 
592
                        skb = dev_alloc_skb(rda.length + 2);
593
                        if (skb == NULL)
594
                                dev->stats.rx_dropped++;
595
                        else {
596
                                /* copy out data */
597
 
598
                                memcpy_fromio(skb_put(skb, rda.length),
599
                                               priv->base +
600
                                               rda.startlo, rda.length);
601
 
602
                                /* set up skb fields */
603
 
604
                                skb->protocol = eth_type_trans(skb, dev);
605
                                skb->ip_summed = CHECKSUM_NONE;
606
 
607
                                /* bookkeeping */
608
                                dev->last_rx = jiffies;
609
                                dev->stats.rx_packets++;
610
                                dev->stats.rx_bytes += rda.length;
611
 
612
                                /* pass to the upper layers */
613
                                netif_rx(skb);
614
                        }
615
                }
616
 
617
                /* otherwise check error status bits and increase statistics */
618
 
619
                else {
620
                        dev->stats.rx_errors++;
621
                        if (rda.status & RCREG_FAER)
622
                                dev->stats.rx_frame_errors++;
623
                        if (rda.status & RCREG_CRCR)
624
                                dev->stats.rx_crc_errors++;
625
                }
626
 
627
                /* descriptor processed, will become new last descriptor in queue */
628
 
629
                rda.link = 1;
630
                rda.inuse = 1;
631
                memcpy_toio(priv->base + rdaaddr, &rda,
632
                             sizeof(rda_t));
633
 
634
                /* set up link and EOL = 0 in currently last descriptor. Only write
635
                   the link field since the SONIC may currently already access the
636
                   other fields. */
637
 
638
                memcpy_toio(priv->base + lrdaaddr + 20, &rdaaddr, 4);
639
 
640
                /* advance indices */
641
 
642
                priv->lastrxdescr = priv->nextrxdescr;
643
                if ((++priv->nextrxdescr) >= priv->rxbufcnt)
644
                        priv->nextrxdescr = 0;
645
        }
646
}
647
 
648
/* transmit interrupt */
649
 
650
static void irqtx_handler(struct net_device *dev)
651
{
652
        ibmlana_priv *priv = netdev_priv(dev);
653
        tda_t tda;
654
 
655
        /* fetch descriptor (we forgot the size ;-) */
656
        memcpy_fromio(&tda, priv->base + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
657
 
658
        /* update statistics */
659
        dev->stats.tx_packets++;
660
        dev->stats.tx_bytes += tda.length;
661
 
662
        /* update our pointers */
663
        priv->txused[priv->currtxdescr] = 0;
664
        priv->txusedcnt--;
665
 
666
        /* if there are more descriptors present in RAM, start them */
667
        if (priv->txusedcnt > 0)
668
                StartTx(dev, (priv->currtxdescr + 1) % TXBUFCNT);
669
 
670
        /* tell the upper layer we can go on transmitting */
671
        netif_wake_queue(dev);
672
}
673
 
674
static void irqtxerr_handler(struct net_device *dev)
675
{
676
        ibmlana_priv *priv = netdev_priv(dev);
677
        tda_t tda;
678
 
679
        /* fetch descriptor to check status */
680
        memcpy_fromio(&tda, priv->base + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));
681
 
682
        /* update statistics */
683
        dev->stats.tx_errors++;
684
        if (tda.status & (TCREG_NCRS | TCREG_CRSL))
685
                dev->stats.tx_carrier_errors++;
686
        if (tda.status & TCREG_EXC)
687
                dev->stats.tx_aborted_errors++;
688
        if (tda.status & TCREG_OWC)
689
                dev->stats.tx_window_errors++;
690
        if (tda.status & TCREG_FU)
691
                dev->stats.tx_fifo_errors++;
692
 
693
        /* update our pointers */
694
        priv->txused[priv->currtxdescr] = 0;
695
        priv->txusedcnt--;
696
 
697
        /* if there are more descriptors present in RAM, start them */
698
        if (priv->txusedcnt > 0)
699
                StartTx(dev, (priv->currtxdescr + 1) % TXBUFCNT);
700
 
701
        /* tell the upper layer we can go on transmitting */
702
        netif_wake_queue(dev);
703
}
704
 
705
/* general interrupt entry */
706
 
707
static irqreturn_t irq_handler(int irq, void *device)
708
{
709
        struct net_device *dev = (struct net_device *) device;
710
        u16 ival;
711
 
712
        /* in case we're not meant... */
713
        if (!(inb(dev->base_addr + BCMREG) & BCMREG_IPEND))
714
                return IRQ_NONE;
715
 
716
        /* loop through the interrupt bits until everything is clear */
717
        while (1) {
718
                ival = inw(dev->base_addr + SONIC_ISREG);
719
 
720
                if (ival & ISREG_RBE) {
721
                        irqrbe_handler(dev);
722
                        outw(ISREG_RBE, dev->base_addr + SONIC_ISREG);
723
                }
724
                if (ival & ISREG_PKTRX) {
725
                        irqrx_handler(dev);
726
                        outw(ISREG_PKTRX, dev->base_addr + SONIC_ISREG);
727
                }
728
                if (ival & ISREG_TXDN) {
729
                        irqtx_handler(dev);
730
                        outw(ISREG_TXDN, dev->base_addr + SONIC_ISREG);
731
                }
732
                if (ival & ISREG_TXER) {
733
                        irqtxerr_handler(dev);
734
                        outw(ISREG_TXER, dev->base_addr + SONIC_ISREG);
735
                }
736
                break;
737
        }
738
        return IRQ_HANDLED;
739
}
740
 
741
/* ------------------------------------------------------------------------
742
 * driver methods
743
 * ------------------------------------------------------------------------ */
744
 
745
/* MCA info */
746
 
747
static int ibmlana_getinfo(char *buf, int slot, void *d)
748
{
749
        int len = 0, i;
750
        struct net_device *dev = (struct net_device *) d;
751
        ibmlana_priv *priv;
752
 
753
        /* can't say anything about an uninitialized device... */
754
 
755
        if (dev == NULL)
756
                return len;
757
        priv = netdev_priv(dev);
758
 
759
        /* print info */
760
 
761
        len += sprintf(buf + len, "IRQ: %d\n", priv->realirq);
762
        len += sprintf(buf + len, "I/O: %#lx\n", dev->base_addr);
763
        len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start, dev->mem_end - 1);
764
        len += sprintf(buf + len, "Transceiver: %s\n", MediaNames[priv->medium]);
765
        len += sprintf(buf + len, "Device: %s\n", dev->name);
766
        len += sprintf(buf + len, "MAC address:");
767
        for (i = 0; i < 6; i++)
768
                len += sprintf(buf + len, " %02x", dev->dev_addr[i]);
769
        buf[len++] = '\n';
770
        buf[len] = 0;
771
 
772
        return len;
773
}
774
 
775
/* open driver.  Means also initialization and start of LANCE */
776
 
777
static int ibmlana_open(struct net_device *dev)
778
{
779
        int result;
780
        ibmlana_priv *priv = netdev_priv(dev);
781
 
782
        /* register resources - only necessary for IRQ */
783
 
784
        result = request_irq(priv->realirq, irq_handler, IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev);
785
        if (result != 0) {
786
                printk(KERN_ERR "%s: failed to register irq %d\n", dev->name, dev->irq);
787
                return result;
788
        }
789
        dev->irq = priv->realirq;
790
 
791
        /* set up the card and SONIC */
792
        InitBoard(dev);
793
 
794
        /* initialize operational flags */
795
        netif_start_queue(dev);
796
        return 0;
797
}
798
 
799
/* close driver.  Shut down board and free allocated resources */
800
 
801
static int ibmlana_close(struct net_device *dev)
802
{
803
        /* turn off board */
804
 
805
        /* release resources */
806
        if (dev->irq != 0)
807
                free_irq(dev->irq, dev);
808
        dev->irq = 0;
809
        return 0;
810
}
811
 
812
/* transmit a block. */
813
 
814
static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
815
{
816
        ibmlana_priv *priv = netdev_priv(dev);
817
        int retval = 0, tmplen, addr;
818
        unsigned long flags;
819
        tda_t tda;
820
        int baddr;
821
 
822
        /* find out if there are free slots for a frame to transmit. If not,
823
           the upper layer is in deep desperation and we simply ignore the frame. */
824
 
825
        if (priv->txusedcnt >= TXBUFCNT) {
826
                retval = -EIO;
827
                dev->stats.tx_dropped++;
828
                goto tx_done;
829
        }
830
 
831
        /* copy the frame data into the next free transmit buffer - fillup missing */
832
        tmplen = skb->len;
833
        if (tmplen < 60)
834
                tmplen = 60;
835
        baddr = priv->txbufstart + (priv->nexttxdescr * PKTSIZE);
836
        memcpy_toio(priv->base + baddr, skb->data, skb->len);
837
 
838
        /* copy filler into RAM - in case we're filling up...
839
           we're filling a bit more than necessary, but that doesn't harm
840
           since the buffer is far larger...
841
           Sorry Linus for the filler string but I couldn't resist ;-) */
842
 
843
        if (tmplen > skb->len) {
844
                char *fill = "NetBSD is a nice OS too! ";
845
                unsigned int destoffs = skb->len, l = strlen(fill);
846
 
847
                while (destoffs < tmplen) {
848
                        memcpy_toio(priv->base + baddr + destoffs, fill, l);
849
                        destoffs += l;
850
                }
851
        }
852
 
853
        /* set up the new frame descriptor */
854
        addr = priv->tdastart + (priv->nexttxdescr * sizeof(tda_t));
855
        memcpy_fromio(&tda, priv->base + addr, sizeof(tda_t));
856
        tda.length = tda.fraglength = tmplen;
857
        memcpy_toio(priv->base + addr, &tda, sizeof(tda_t));
858
 
859
        /* if there were no active descriptors, trigger the SONIC */
860
        spin_lock_irqsave(&priv->lock, flags);
861
 
862
        priv->txusedcnt++;
863
        priv->txused[priv->nexttxdescr] = 1;
864
 
865
        /* are all transmission slots used up ? */
866
        if (priv->txusedcnt >= TXBUFCNT)
867
                netif_stop_queue(dev);
868
 
869
        if (priv->txusedcnt == 1)
870
                StartTx(dev, priv->nexttxdescr);
871
        priv->nexttxdescr = (priv->nexttxdescr + 1) % TXBUFCNT;
872
 
873
        spin_unlock_irqrestore(&priv->lock, flags);
874
tx_done:
875
        dev_kfree_skb(skb);
876
        return retval;
877
}
878
 
879
/* switch receiver mode. */
880
 
881
static void ibmlana_set_multicast_list(struct net_device *dev)
882
{
883
        /* first stop the SONIC... */
884
        StopSONIC(dev);
885
        /* ...then reinit it with the new flags */
886
        InitBoard(dev);
887
}
888
 
889
/* ------------------------------------------------------------------------
890
 * hardware check
891
 * ------------------------------------------------------------------------ */
892
 
893
static int startslot;           /* counts through slots when probing multiple devices */
894
 
895
static int ibmlana_probe(struct net_device *dev)
896
{
897
        int slot, z;
898
        int base = 0, irq = 0, iobase = 0, memlen = 0;
899
        ibmlana_priv *priv;
900
        ibmlana_medium medium;
901
        DECLARE_MAC_BUF(mac);
902
 
903
        /* can't work without an MCA bus ;-) */
904
        if (MCA_bus == 0)
905
                return -ENODEV;
906
 
907
        base = dev->mem_start;
908
        irq = dev->irq;
909
 
910
        for (slot = startslot; (slot = mca_find_adapter(IBM_LANA_ID, slot)) != -1; slot++) {
911
                /* deduce card addresses */
912
                getaddrs(slot, &base, &memlen, &iobase, &irq, &medium);
913
 
914
                /* slot already in use ? */
915
                if (mca_is_adapter_used(slot))
916
                        continue;
917
                /* were we looking for something different ? */
918
                if (dev->irq && dev->irq != irq)
919
                        continue;
920
                if (dev->mem_start && dev->mem_start != base)
921
                        continue;
922
                /* found something that matches */
923
                break;
924
        }
925
 
926
        /* nothing found ? */
927
        if (slot == -1)
928
                return (base != 0 || irq != 0) ? -ENXIO : -ENODEV;
929
 
930
        /* announce success */
931
        printk(KERN_INFO "%s: IBM LAN Adapter/A found in slot %d\n", dev->name, slot + 1);
932
 
933
        /* try to obtain I/O range */
934
        if (!request_region(iobase, IBM_LANA_IORANGE, DRV_NAME)) {
935
                printk(KERN_ERR "%s: cannot allocate I/O range at %#x!\n", DRV_NAME, iobase);
936
                startslot = slot + 1;
937
                return -EBUSY;
938
        }
939
 
940
        priv = netdev_priv(dev);
941
        priv->slot = slot;
942
        priv->realirq = irq;
943
        priv->medium = medium;
944
        spin_lock_init(&priv->lock);
945
 
946
 
947
        /* set base + irq for this device (irq not allocated so far) */
948
 
949
        dev->irq = 0;
950
        dev->mem_start = base;
951
        dev->mem_end = base + memlen;
952
        dev->base_addr = iobase;
953
 
954
        priv->base = ioremap(base, memlen);
955
        if (!priv->base) {
956
                printk(KERN_ERR "%s: cannot remap memory!\n", DRV_NAME);
957
                startslot = slot + 1;
958
                release_region(iobase, IBM_LANA_IORANGE);
959
                return -EBUSY;
960
        }
961
 
962
        /* make procfs entries */
963
        mca_set_adapter_name(slot, "IBM LAN Adapter/A");
964
        mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmlana_getinfo, dev);
965
 
966
        mca_mark_as_used(slot);
967
 
968
        /* set methods */
969
 
970
        dev->open = ibmlana_open;
971
        dev->stop = ibmlana_close;
972
        dev->hard_start_xmit = ibmlana_tx;
973
        dev->do_ioctl = NULL;
974
        dev->set_multicast_list = ibmlana_set_multicast_list;
975
        dev->flags |= IFF_MULTICAST;
976
 
977
        /* copy out MAC address */
978
 
979
        for (z = 0; z < sizeof(dev->dev_addr); z++)
980
                dev->dev_addr[z] = inb(dev->base_addr + MACADDRPROM + z);
981
 
982
        /* print config */
983
 
984
        printk(KERN_INFO "%s: IRQ %d, I/O %#lx, memory %#lx-%#lx, "
985
               "MAC address %s.\n",
986
               dev->name, priv->realirq, dev->base_addr,
987
               dev->mem_start, dev->mem_end - 1,
988
               print_mac(mac, dev->dev_addr));
989
        printk(KERN_INFO "%s: %s medium\n", dev->name, MediaNames[priv->medium]);
990
 
991
        /* reset board */
992
 
993
        ResetBoard(dev);
994
 
995
        /* next probe will start at next slot */
996
 
997
        startslot = slot + 1;
998
 
999
        return 0;
1000
}
1001
 
1002
/* ------------------------------------------------------------------------
1003
 * modularization support
1004
 * ------------------------------------------------------------------------ */
1005
 
1006
#ifdef MODULE
1007
 
1008
#define DEVMAX 5
1009
 
1010
static struct net_device *moddevs[DEVMAX];
1011
static int irq;
1012
static int io;
1013
 
1014
module_param(irq, int, 0);
1015
module_param(io, int, 0);
1016
MODULE_PARM_DESC(irq, "IBM LAN/A IRQ number");
1017
MODULE_PARM_DESC(io, "IBM LAN/A I/O base address");
1018
MODULE_LICENSE("GPL");
1019
 
1020
int init_module(void)
1021
{
1022
        int z;
1023
 
1024
        startslot = 0;
1025
        for (z = 0; z < DEVMAX; z++) {
1026
                struct net_device *dev = alloc_etherdev(sizeof(ibmlana_priv));
1027
                if (!dev)
1028
                        break;
1029
                dev->irq = irq;
1030
                dev->base_addr = io;
1031
                if (ibmlana_probe(dev)) {
1032
                        free_netdev(dev);
1033
                        break;
1034
                }
1035
                if (register_netdev(dev)) {
1036
                        ibmlana_priv *priv = netdev_priv(dev);
1037
                        release_region(dev->base_addr, IBM_LANA_IORANGE);
1038
                        mca_mark_as_unused(priv->slot);
1039
                        mca_set_adapter_name(priv->slot, "");
1040
                        mca_set_adapter_procfn(priv->slot, NULL, NULL);
1041
                        iounmap(priv->base);
1042
                        free_netdev(dev);
1043
                        break;
1044
                }
1045
                moddevs[z] = dev;
1046
        }
1047
        return (z > 0) ? 0 : -EIO;
1048
}
1049
 
1050
void cleanup_module(void)
1051
{
1052
        int z;
1053
        for (z = 0; z < DEVMAX; z++) {
1054
                struct net_device *dev = moddevs[z];
1055
                if (dev) {
1056
                        ibmlana_priv *priv = netdev_priv(dev);
1057
                        unregister_netdev(dev);
1058
                        /*DeinitBoard(dev); */
1059
                        release_region(dev->base_addr, IBM_LANA_IORANGE);
1060
                        mca_mark_as_unused(priv->slot);
1061
                        mca_set_adapter_name(priv->slot, "");
1062
                        mca_set_adapter_procfn(priv->slot, NULL, NULL);
1063
                        iounmap(priv->base);
1064
                        free_netdev(dev);
1065
                }
1066
        }
1067
}
1068
#endif                          /* MODULE */

powered by: WebSVN 2.1.0

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