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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [net/] [tokenring/] [tmsisa.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  tmsisa.c: A generic network driver for TMS380-based ISA token ring cards.
3
 *
4
 *  Based on tmspci written 1999 by Adam Fritzler
5
 *
6
 *  Written 2000 by Jochen Friedrich
7
 *  Dedicated to my girlfriend Steffi Bopp
8
 *
9
 *  This software may be used and distributed according to the terms
10
 *  of the GNU General Public License, incorporated herein by reference.
11
 *
12
 *  This driver module supports the following cards:
13
 *      - SysKonnect TR4/16(+) ISA      (SK-4190)
14
 *
15
 *  Maintainer(s):
16
 *    AF        Adam Fritzler           mid@auk.cx
17
 *    JF        Jochen Friedrich        jochen@scram.de
18
 *
19
 *  TODO:
20
 *      1. Add support for Proteon TR ISA adapters (1392, 1392+)
21
 */
22
static const char version[] = "tmsisa.c: v1.00 14/01/2001 by Jochen Friedrich\n";
23
 
24
#include <linux/module.h>
25
#include <linux/kernel.h>
26
#include <linux/sched.h>
27
#include <linux/errno.h>
28
#include <linux/pci.h>
29
#include <linux/init.h>
30
 
31
#include <asm/system.h>
32
#include <asm/io.h>
33
#include <asm/irq.h>
34
#include <asm/pci.h>
35
#include <asm/dma.h>
36
 
37
#include <linux/netdevice.h>
38
#include <linux/trdevice.h>
39
#include "tms380tr.h"
40
 
41
#define TMS_ISA_IO_EXTENT 32
42
 
43
/* A zero-terminated list of I/O addresses to be probed. */
44
static unsigned int portlist[] __initdata = {
45
        0x0A20, 0x1A20, 0x0B20, 0x1B20, 0x0980, 0x1980, 0x0900, 0x1900,// SK
46
 
47
};
48
 
49
/* A zero-terminated list of IRQs to be probed.
50
 * Used again after initial probe for sktr_chipset_init, called from sktr_open.
51
 */
52
static unsigned short irqlist[] = {
53
        3, 5, 9, 10, 11, 12, 15,
54
 
55
};
56
 
57
/* A zero-terminated list of DMAs to be probed. */
58
static int dmalist[] __initdata = {
59
        5, 6, 7,
60
 
61
};
62
 
63
static char isa_cardname[] = "SK NET TR 4/16 ISA\0";
64
 
65
int tms_isa_probe(struct net_device *dev);
66
static int tms_isa_open(struct net_device *dev);
67
static int tms_isa_close(struct net_device *dev);
68
static void tms_isa_read_eeprom(struct net_device *dev);
69
static unsigned short tms_isa_setnselout_pins(struct net_device *dev);
70
 
71
static unsigned short tms_isa_sifreadb(struct net_device *dev, unsigned short reg)
72
{
73
        return inb(dev->base_addr + reg);
74
}
75
 
76
static unsigned short tms_isa_sifreadw(struct net_device *dev, unsigned short reg)
77
{
78
        return inw(dev->base_addr + reg);
79
}
80
 
81
static void tms_isa_sifwriteb(struct net_device *dev, unsigned short val, unsigned short reg)
82
{
83
        outb(val, dev->base_addr + reg);
84
}
85
 
86
static void tms_isa_sifwritew(struct net_device *dev, unsigned short val, unsigned short reg)
87
{
88
        outw(val, dev->base_addr + reg);
89
}
90
 
91
struct tms_isa_card {
92
        struct net_device *dev;
93
        struct tms_isa_card *next;
94
};
95
 
96
static struct tms_isa_card *tms_isa_card_list;
97
 
98
static int __init tms_isa_probe1(int ioaddr)
99
{
100
        unsigned char old, chk1, chk2;
101
 
102
        old = inb(ioaddr + SIFADR);     /* Get the old SIFADR value */
103
 
104
        chk1 = 0;        /* Begin with check value 0 */
105
        do {
106
                /* Write new SIFADR value */
107
                outb(chk1, ioaddr + SIFADR);
108
 
109
                /* Read, invert and write */
110
                chk2 = inb(ioaddr + SIFADD);
111
                chk2 ^= 0x0FE;
112
                outb(chk2, ioaddr + SIFADR);
113
 
114
                /* Read, invert and compare */
115
                chk2 = inb(ioaddr + SIFADD);
116
                chk2 ^= 0x0FE;
117
 
118
                if(chk1 != chk2)
119
                        return (-1);    /* No adapter */
120
 
121
                chk1 -= 2;
122
        } while(chk1 != 0);      /* Repeat 128 times (all byte values) */
123
 
124
        /* Restore the SIFADR value */
125
        outb(old, ioaddr + SIFADR);
126
 
127
        return (0);
128
}
129
 
130
int __init tms_isa_probe(struct net_device *dev)
131
{
132
        static int versionprinted;
133
        struct net_local *tp;
134
        int j;
135
        struct tms_isa_card *card;
136
 
137
        if(check_region(dev->base_addr, TMS_ISA_IO_EXTENT))
138
                return -1;
139
 
140
        if(tms_isa_probe1(dev->base_addr))
141
                return -1;
142
 
143
        if (versionprinted++ == 0)
144
                printk("%s", version);
145
 
146
        /* At this point we have found a valid card. */
147
 
148
        if (!request_region(dev->base_addr, TMS_ISA_IO_EXTENT, isa_cardname))
149
                return -1;
150
 
151
        if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL))
152
        {
153
                release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
154
                return -1;
155
        }
156
 
157
        dev->base_addr &= ~3;
158
 
159
        tms_isa_read_eeprom(dev);
160
 
161
        printk("%s:    Ring Station Address: ", dev->name);
162
        printk("%2.2x", dev->dev_addr[0]);
163
        for (j = 1; j < 6; j++)
164
                printk(":%2.2x", dev->dev_addr[j]);
165
        printk("\n");
166
 
167
        tp = (struct net_local *)dev->priv;
168
        tp->setnselout = tms_isa_setnselout_pins;
169
 
170
        tp->sifreadb = tms_isa_sifreadb;
171
        tp->sifreadw = tms_isa_sifreadw;
172
        tp->sifwriteb = tms_isa_sifwriteb;
173
        tp->sifwritew = tms_isa_sifwritew;
174
 
175
        memcpy(tp->ProductID, isa_cardname, PROD_ID_SIZE + 1);
176
 
177
        tp->tmspriv = NULL;
178
 
179
        dev->open = tms_isa_open;
180
        dev->stop = tms_isa_close;
181
 
182
        if (dev->irq == 0)
183
        {
184
                for(j = 0; irqlist[j] != 0; j++)
185
                {
186
                        dev->irq = irqlist[j];
187
                        if (!request_irq(dev->irq, tms380tr_interrupt, 0,
188
                                isa_cardname, dev))
189
                                break;
190
                }
191
 
192
                if(irqlist[j] == 0)
193
                {
194
                        printk("%s: AutoSelect no IRQ available\n", dev->name);
195
                        release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
196
                        tmsdev_term(dev);
197
                        return -1;
198
                }
199
        }
200
        else
201
        {
202
                for(j = 0; irqlist[j] != 0; j++)
203
                        if (irqlist[j] == dev->irq)
204
                                break;
205
                if (irqlist[j] == 0)
206
                {
207
                        printk("%s: Illegal IRQ %d specified\n",
208
                                dev->name, dev->irq);
209
                        release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
210
                        tmsdev_term(dev);
211
                        return -1;
212
                }
213
                if (request_irq(dev->irq, tms380tr_interrupt, 0,
214
                        isa_cardname, dev))
215
                {
216
                        printk("%s: Selected IRQ %d not available\n",
217
                                dev->name, dev->irq);
218
                        release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
219
                        tmsdev_term(dev);
220
                        return -1;
221
                }
222
        }
223
 
224
        if (dev->dma == 0)
225
        {
226
                for(j = 0; dmalist[j] != 0; j++)
227
                {
228
                        dev->dma = dmalist[j];
229
                        if (!request_dma(dev->dma, isa_cardname))
230
                                break;
231
                }
232
 
233
                if(dmalist[j] == 0)
234
                {
235
                        printk("%s: AutoSelect no DMA available\n", dev->name);
236
                        release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
237
                        free_irq(dev->irq, dev);
238
                        tmsdev_term(dev);
239
                        return -1;
240
                }
241
        }
242
        else
243
        {
244
                for(j = 0; dmalist[j] != 0; j++)
245
                        if (dmalist[j] == dev->dma)
246
                                break;
247
                if (dmalist[j] == 0)
248
                {
249
                        printk("%s: Illegal DMA %d specified\n",
250
                                dev->name, dev->dma);
251
                        release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
252
                        free_irq(dev->irq, dev);
253
                        tmsdev_term(dev);
254
                        return -1;
255
                }
256
                if (request_dma(dev->dma, isa_cardname))
257
                {
258
                        printk("%s: Selected DMA %d not available\n",
259
                                dev->name, dev->dma);
260
                        release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
261
                        free_irq(dev->irq, dev);
262
                        tmsdev_term(dev);
263
                        return -1;
264
                }
265
        }
266
 
267
        printk("%s:    IO: %#4lx  IRQ: %d  DMA: %d\n",
268
               dev->name, dev->base_addr, dev->irq, dev->dma);
269
 
270
        if (register_trdev(dev) == 0)
271
        {
272
                /* Enlist in the card list */
273
                card = kmalloc(sizeof(struct tms_isa_card), GFP_KERNEL);
274
                if (!card) {
275
                        unregister_trdev(dev);
276
                        release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
277
                        free_irq(dev->irq, dev);
278
                        free_dma(dev->dma);
279
                        tmsdev_term(dev);
280
                        return -1;
281
                }
282
                card->next = tms_isa_card_list;
283
                tms_isa_card_list = card;
284
                card->dev = dev;
285
        }
286
        else
287
        {
288
                printk("%s: register_trdev() returned non-zero.\n", dev->name);
289
                release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
290
                free_irq(dev->irq, dev);
291
                free_dma(dev->dma);
292
                tmsdev_term(dev);
293
                return -1;
294
        }
295
 
296
        return 0;
297
}
298
 
299
/*
300
 * Reads MAC address from adapter RAM, which should've read it from
301
 * the onboard ROM.
302
 *
303
 * Calling this on a board that does not support it can be a very
304
 * dangerous thing.  The Madge board, for instance, will lock your
305
 * machine hard when this is called.  Luckily, its supported in a
306
 * seperate driver.  --ASF
307
 */
308
static void tms_isa_read_eeprom(struct net_device *dev)
309
{
310
        int i;
311
 
312
        /* Address: 0000:0000 */
313
        tms_isa_sifwritew(dev, 0, SIFADX);
314
        tms_isa_sifwritew(dev, 0, SIFADR);
315
 
316
        /* Read six byte MAC address data */
317
        dev->addr_len = 6;
318
        for(i = 0; i < 6; i++)
319
                dev->dev_addr[i] = tms_isa_sifreadw(dev, SIFINC) >> 8;
320
}
321
 
322
unsigned short tms_isa_setnselout_pins(struct net_device *dev)
323
{
324
        return 0;
325
}
326
 
327
static int tms_isa_open(struct net_device *dev)
328
{
329
        struct net_local *tp = (struct net_local *)dev->priv;
330
        unsigned short val = 0;
331
        unsigned short oldval;
332
        int i;
333
 
334
        val = 0;
335
        for(i = 0; irqlist[i] != 0; i++)
336
        {
337
                if(irqlist[i] == dev->irq)
338
                        break;
339
        }
340
 
341
        val |= CYCLE_TIME << 2;
342
        val |= i << 4;
343
        i = dev->dma - 5;
344
        val |= i;
345
        if(tp->DataRate == SPEED_4)
346
                val |= LINE_SPEED_BIT;
347
        else
348
                val &= ~LINE_SPEED_BIT;
349
        oldval = tms_isa_sifreadb(dev, POSREG);
350
        /* Leave cycle bits alone */
351
        oldval |= 0xf3;
352
        val &= oldval;
353
        tms_isa_sifwriteb(dev, val, POSREG);
354
 
355
        tms380tr_open(dev);
356
        MOD_INC_USE_COUNT;
357
        return 0;
358
}
359
 
360
static int tms_isa_close(struct net_device *dev)
361
{
362
        tms380tr_close(dev);
363
        MOD_DEC_USE_COUNT;
364
        return 0;
365
}
366
 
367
#ifdef MODULE
368
 
369
#define ISATR_MAX_ADAPTERS 3
370
 
371
static int io[ISATR_MAX_ADAPTERS];
372
static int irq[ISATR_MAX_ADAPTERS];
373
static int dma[ISATR_MAX_ADAPTERS];
374
 
375
MODULE_LICENSE("GPL");
376
 
377
MODULE_PARM(io, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
378
MODULE_PARM(irq, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
379
MODULE_PARM(dma, "1-" __MODULE_STRING(ISATR_MAX_ADAPTERS) "i");
380
 
381
int init_module(void)
382
{
383
        int i, num;
384
        struct net_device *dev;
385
 
386
        num = 0;
387
        if (io[0])
388
        { /* Only probe addresses from command line */
389
                for (i = 0; i < ISATR_MAX_ADAPTERS; i++)
390
                {
391
                        if (io[i] == 0)
392
                                continue;
393
 
394
                        dev = init_trdev(NULL, 0);
395
                        if (!dev)
396
                                return (-ENOMEM);
397
 
398
                        dev->base_addr = io[i];
399
                        dev->irq       = irq[i];
400
                        dev->dma       = dma[i];
401
 
402
                        if (tms_isa_probe(dev))
403
                        {
404
                                unregister_netdev(dev);
405
                                kfree(dev);
406
                        }
407
                        else
408
                                num++;
409
                }
410
        }
411
        else
412
        {
413
                for(i = 0; portlist[i]; i++)
414
                {
415
                        if (num >= ISATR_MAX_ADAPTERS)
416
                                continue;
417
 
418
                        dev = init_trdev(NULL, 0);
419
                        if (!dev)
420
                                return (-ENOMEM);
421
 
422
                        dev->base_addr = portlist[i];
423
                        dev->irq       = irq[num];
424
                        dev->dma       = dma[num];
425
 
426
                        if (tms_isa_probe(dev))
427
                        {
428
                                unregister_netdev(dev);
429
                                kfree(dev);
430
                        }
431
                        else
432
                                num++;
433
                }
434
        }
435
        printk(KERN_NOTICE "tmsisa.c: %d cards found.\n", num);
436
        /* Probe for cards. */
437
        if (num == 0) {
438
                printk(KERN_NOTICE "tmsisa.c: No cards found.\n");
439
        }
440
        return (0);
441
}
442
 
443
void cleanup_module(void)
444
{
445
        struct net_device *dev;
446
        struct tms_isa_card *this_card;
447
 
448
        while (tms_isa_card_list) {
449
                dev = tms_isa_card_list->dev;
450
 
451
                unregister_netdev(dev);
452
                release_region(dev->base_addr, TMS_ISA_IO_EXTENT);
453
                free_irq(dev->irq, dev);
454
                free_dma(dev->dma);
455
                tmsdev_term(dev);
456
                kfree(dev);
457
                this_card = tms_isa_card_list;
458
                tms_isa_card_list = this_card->next;
459
                kfree(this_card);
460
        }
461
}
462
#endif /* MODULE */
463
 
464
 
465
/*
466
 * Local variables:
467
 *  compile-command: "gcc -DMODVERSIONS  -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tmsisa.c"
468
 *  alt-compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer -I/usr/src/linux/drivers/net/tokenring/ -c tmsisa.c"
469
 *  c-set-style "K&R"
470
 *  c-indent-level: 8
471
 *  c-basic-offset: 8
472
 *  tab-width: 8
473
 * End:
474
 */

powered by: WebSVN 2.1.0

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