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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* ac3200.c: A driver for the Ansel Communications EISA ethernet adaptor. */
2
/*
3
        Written 1993, 1994 by Donald Becker.
4
        Copyright 1993 United States Government as represented by the Director,
5
        National Security Agency.  This software may only be used and distributed
6
        according to the terms of the GNU Public License as modified by SRC,
7
        incorporated herein by reference.
8
 
9
        The author may be reached as becker@cesdis.gsfc.nasa.gov, or
10
    C/O Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
11
 
12
        This is driver for the Ansel Communications Model 3200 EISA Ethernet LAN
13
        Adapter.  The programming information is from the users manual, as related
14
        by glee@ardnassak.math.clemson.edu.
15
  */
16
 
17
static const char *version =
18
        "ac3200.c:v1.01 7/1/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
19
 
20
#include <linux/module.h>
21
 
22
#include <linux/kernel.h>
23
#include <linux/sched.h>
24
#include <linux/errno.h>
25
#include <linux/string.h>
26
#include <linux/netdevice.h>
27
#include <linux/etherdevice.h>
28
 
29
#include <asm/system.h>
30
#include <asm/io.h>
31
 
32
#include "8390.h"
33
 
34
/* Offsets from the base address. */
35
#define AC_NIC_BASE             0x00
36
#define AC_SA_PROM              0x16                    /* The station address PROM. */
37
#define  AC_ADDR0                0x00                   /* Prefix station address values. */
38
#define  AC_ADDR1                0x40                   /* !!!!These are just guesses!!!! */
39
#define  AC_ADDR2                0x90
40
#define AC_ID_PORT              0xC80
41
#define AC_EISA_ID               0x0110d305
42
#define AC_RESET_PORT   0xC84
43
#define  AC_RESET                0x00
44
#define  AC_ENABLE               0x01
45
#define AC_CONFIG               0xC90   /* The configuration port. */
46
 
47
#define AC_IO_EXTENT 0x10               /* IS THIS REALLY TRUE ??? */
48
                                /* Actually accessed is:
49
                                                                 * AC_NIC_BASE (0-15)
50
                                                                 * AC_SA_PROM (0-5)
51
                                                                 * AC_ID_PORT (0-3)
52
                                                                 * AC_RESET_PORT
53
                                                                 * AC_CONFIG
54
                                                                 */
55
 
56
/* Decoding of the configuration register. */
57
static unsigned char config2irqmap[8] = {15, 12, 11, 10, 9, 7, 5, 3};
58
static int addrmap[8] =
59
{0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000,  0xD0000, 0 };
60
static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"};
61
 
62
#define config2irq(configval)   config2irqmap[((configval) >> 3) & 7]
63
#define config2mem(configval)   addrmap[(configval) & 7]
64
#define config2name(configval)  port_name[((configval) >> 6) & 3]
65
 
66
/* First and last 8390 pages. */
67
#define AC_START_PG             0x00    /* First page of 8390 TX buffer */
68
#define AC_STOP_PG              0x80    /* Last page +1 of the 8390 RX ring */
69
 
70
int ac3200_probe(struct device *dev);
71
static int ac_probe1(int ioaddr, struct device *dev);
72
 
73
static int ac_open(struct device *dev);
74
static void ac_reset_8390(struct device *dev);
75
static void ac_block_input(struct device *dev, int count,
76
                                        struct sk_buff *skb, int ring_offset);
77
static void ac_block_output(struct device *dev, const int count,
78
                                                        const unsigned char *buf, const int start_page);
79
static void ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
80
                                        int ring_page);
81
 
82
static int ac_close_card(struct device *dev);
83
 
84
 
85
/*      Probe for the AC3200.
86
 
87
        The AC3200 can be identified by either the EISA configuration registers,
88
        or the unique value in the station address PROM.
89
        */
90
 
91
int ac3200_probe(struct device *dev)
92
{
93
        unsigned short ioaddr = dev->base_addr;
94
 
95
        if (ioaddr > 0x1ff)             /* Check a single specified location. */
96
                return ac_probe1(ioaddr, dev);
97
        else if (ioaddr > 0)             /* Don't probe at all. */
98
                return ENXIO;
99
 
100
        /* If you have a pre 0.99pl15 machine you should delete this line. */
101
        if ( ! EISA_bus)
102
                return ENXIO;
103
 
104
        for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
105
                if (check_region(ioaddr, AC_IO_EXTENT))
106
                        continue;
107
                if (ac_probe1(ioaddr, dev) == 0)
108
                        return 0;
109
        }
110
 
111
        return ENODEV;
112
}
113
 
114
static int ac_probe1(int ioaddr, struct device *dev)
115
{
116
        int i;
117
 
118
#ifndef final_version
119
        printk("AC3200 ethercard probe at %#3x:", ioaddr);
120
 
121
        for(i = 0; i < 6; i++)
122
                printk(" %02x", inb(ioaddr + AC_SA_PROM + i));
123
#endif
124
 
125
        /* !!!!The values of AC_ADDRn (see above) should be corrected when we
126
           find out the correct station address prefix!!!! */
127
        if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0
128
                || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1
129
                || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) {
130
#ifndef final_version
131
                printk(" not found (invalid prefix).\n");
132
#endif
133
                return ENODEV;
134
        }
135
 
136
        /* The correct probe method is to check the EISA ID. */
137
        for (i = 0; i < 4; i++)
138
                if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
139
                        printk("EISA ID mismatch, %8x vs %8x.\n",
140
                                   inl(ioaddr + AC_ID_PORT), AC_EISA_ID);
141
                        return ENODEV;
142
                }
143
 
144
 
145
        /* We should have a "dev" from Space.c or the static module table. */
146
        if (dev == NULL) {
147
                printk("ac3200.c: Passed a NULL device.\n");
148
                dev = init_etherdev(0, 0);
149
        }
150
 
151
        for(i = 0; i < ETHER_ADDR_LEN; i++)
152
                dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i);
153
 
154
#ifndef final_version
155
        printk("\nAC3200 ethercard configuration register is %#02x,"
156
                   " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG),
157
                   inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1),
158
                   inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3));
159
#endif
160
 
161
        /* Assign and allocate the interrupt now. */
162
        if (dev->irq == 0)
163
                dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
164
        else if (dev->irq == 2)
165
                dev->irq = 9;
166
 
167
        if (request_irq(dev->irq, ei_interrupt, 0, "ac3200", NULL)) {
168
                printk (" unable to get IRQ %d.\n", dev->irq);
169
                return EAGAIN;
170
        }
171
 
172
        /* Allocate dev->priv and fill in 8390 specific dev fields. */
173
        if (ethdev_init(dev)) {
174
                printk (" unable to allocate memory for dev->priv.\n");
175
                free_irq(dev->irq, NULL);
176
                return -ENOMEM;
177
        }
178
 
179
        request_region(ioaddr, AC_IO_EXTENT, "ac3200");
180
 
181
        dev->base_addr = ioaddr;
182
 
183
#ifdef notyet
184
        if (dev->mem_start)     {               /* Override the value from the board. */
185
                for (i = 0; i < 7; i++)
186
                        if (addrmap[i] == dev->mem_start)
187
                                break;
188
                if (i >= 7)
189
                        i = 0;
190
                outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG);
191
        }
192
#endif
193
 
194
        dev->if_port = inb(ioaddr + AC_CONFIG) >> 6;
195
        dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG));
196
        dev->rmem_start = dev->mem_start + TX_PAGES*256;
197
        dev->mem_end = dev->rmem_end = dev->mem_start
198
                + (AC_STOP_PG - AC_START_PG)*256;
199
 
200
        ei_status.name = "AC3200";
201
        ei_status.tx_start_page = AC_START_PG;
202
        ei_status.rx_start_page = AC_START_PG + TX_PAGES;
203
        ei_status.stop_page = AC_STOP_PG;
204
        ei_status.word16 = 1;
205
 
206
        printk("\n%s: AC3200 at %#x, IRQ %d, %s port, shared memory %#lx-%#lx.\n",
207
                   dev->name, ioaddr, dev->irq, port_name[dev->if_port],
208
                   dev->mem_start, dev->mem_end-1);
209
 
210
        if (ei_debug > 0)
211
                printk(version);
212
 
213
        ei_status.reset_8390 = &ac_reset_8390;
214
        ei_status.block_input = &ac_block_input;
215
        ei_status.block_output = &ac_block_output;
216
        ei_status.get_8390_hdr = &ac_get_8390_hdr;
217
 
218
        dev->open = &ac_open;
219
        dev->stop = &ac_close_card;
220
        NS8390_init(dev, 0);
221
        return 0;
222
}
223
 
224
static int ac_open(struct device *dev)
225
{
226
#ifdef notyet
227
        /* Someday we may enable the IRQ and shared memory here. */
228
        int ioaddr = dev->base_addr;
229
 
230
        if (request_irq(dev->irq, ei_interrupt, 0, "ac3200", NULL))
231
                return -EAGAIN;
232
#endif
233
 
234
        ei_open(dev);
235
 
236
        MOD_INC_USE_COUNT;
237
 
238
        return 0;
239
}
240
 
241
static void ac_reset_8390(struct device *dev)
242
{
243
        ushort ioaddr = dev->base_addr;
244
 
245
        outb(AC_RESET, ioaddr + AC_RESET_PORT);
246
        if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies);
247
 
248
        ei_status.txing = 0;
249
        outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
250
        if (ei_debug > 1) printk("reset done\n");
251
 
252
        return;
253
}
254
 
255
/* Grab the 8390 specific header. Similar to the block_input routine, but
256
   we don't need to be concerned with ring wrap as the header will be at
257
   the start of a page, so we optimize accordingly. */
258
 
259
static void
260
ac_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
261
{
262
        unsigned long hdr_start = dev->mem_start + ((ring_page - AC_START_PG)<<8);
263
        memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
264
}
265
 
266
/*  Block input and output are easy on shared memory ethercards, the only
267
        complication is when the ring buffer wraps. */
268
 
269
static void ac_block_input(struct device *dev, int count, struct sk_buff *skb,
270
                                                  int ring_offset)
271
{
272
        unsigned long xfer_start = dev->mem_start + ring_offset - (AC_START_PG<<8);
273
 
274
        if (xfer_start + count > dev->rmem_end) {
275
                /* We must wrap the input move. */
276
                int semi_count = dev->rmem_end - xfer_start;
277
                memcpy_fromio(skb->data, xfer_start, semi_count);
278
                count -= semi_count;
279
                memcpy_fromio(skb->data + semi_count, dev->rmem_start, count);
280
        } else {
281
                /* Packet is in one chunk -- we can copy + cksum. */
282
                eth_io_copy_and_sum(skb, xfer_start, count, 0);
283
        }
284
}
285
 
286
static void ac_block_output(struct device *dev, int count,
287
                                                        const unsigned char *buf, int start_page)
288
{
289
        unsigned long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8);
290
 
291
        memcpy_toio(shmem, buf, count);
292
}
293
 
294
static int ac_close_card(struct device *dev)
295
{
296
        dev->start = 0;
297
        dev->tbusy = 1;
298
 
299
        if (ei_debug > 1)
300
                printk("%s: Shutting down ethercard.\n", dev->name);
301
 
302
#ifdef notyet
303
        /* We should someday disable shared memory and interrupts. */
304
        outb(0x00, ioaddr + 6); /* Disable interrupts. */
305
        free_irq(dev->irq, NULL);
306
        irq2dev_map[dev->irq] = 0;
307
#endif
308
 
309
        ei_close(dev);
310
 
311
        MOD_DEC_USE_COUNT;
312
 
313
        return 0;
314
}
315
 
316
#ifdef MODULE
317
#define MAX_AC32_CARDS  4       /* Max number of AC32 cards per module */
318
#define NAMELEN         8       /* # of chars for storing dev->name */
319
static char namelist[NAMELEN * MAX_AC32_CARDS] = { 0, };
320
static struct device dev_ac32[MAX_AC32_CARDS] = {
321
        {
322
                NULL,           /* assign a chunk of namelist[] below */
323
                0, 0, 0, 0,
324
                0, 0,
325
                0, 0, 0, NULL, NULL
326
        },
327
};
328
 
329
static int io[MAX_AC32_CARDS] = { 0, };
330
static int irq[MAX_AC32_CARDS]  = { 0, };
331
static int mem[MAX_AC32_CARDS] = { 0, };
332
 
333
int
334
init_module(void)
335
{
336
        int this_dev, found = 0;
337
 
338
        for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
339
                struct device *dev = &dev_ac32[this_dev];
340
                dev->name = namelist+(NAMELEN*this_dev);
341
                dev->irq = irq[this_dev];
342
                dev->base_addr = io[this_dev];
343
                dev->mem_start = mem[this_dev];         /* Currently ignored by driver */
344
                dev->init = ac3200_probe;
345
                /* Default is to only install one card. */
346
                if (io[this_dev] == 0 && this_dev != 0) break;
347
                if (register_netdev(dev) != 0) {
348
                        printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
349
                        if (found != 0) return 0; /* Got at least one. */
350
                        return -ENXIO;
351
                }
352
                found++;
353
        }
354
 
355
        return 0;
356
}
357
 
358
void
359
cleanup_module(void)
360
{
361
        int this_dev;
362
 
363
        for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
364
                struct device *dev = &dev_ac32[this_dev];
365
                if (dev->priv != NULL) {
366
                        kfree(dev->priv);
367
                        dev->priv = NULL;
368
                        /* Someday free_irq + irq2dev may be in ac_close_card() */
369
                        free_irq(dev->irq, NULL);
370
                        irq2dev_map[dev->irq] = NULL;
371
                        release_region(dev->base_addr, AC_IO_EXTENT);
372
                        unregister_netdev(dev);
373
                }
374
        }
375
}
376
#endif /* MODULE */
377
 
378
/*
379
 * Local variables:
380
 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c ac3200.c"
381
 *  version-control: t
382
 *  kept-new-versions: 5
383
 *  tab-width: 4
384
 * End:
385
 */

powered by: WebSVN 2.1.0

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