Root/drivers/net/smc-ultra32.c

1/* smc-ultra32.c: An SMC Ultra32 EISA ethernet driver for linux.
2
3Sources:
4
5    This driver is based on (cloned from) the ISA SMC Ultra driver
6    written by Donald Becker. Modifications to support the EISA
7    version of the card by Paul Gortmaker and Leonard N. Zubkoff.
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
12Theory of Operation:
13
14    The SMC Ultra32C card uses the SMC 83c790 chip which is also
15    found on the ISA SMC Ultra cards. It has a shared memory mode of
16    operation that makes it similar to the ISA version of the card.
17    The main difference is that the EISA card has 32KB of RAM, but
18    only an 8KB window into that memory. The EISA card also can be
19    set for a bus-mastering mode of operation via the ECU, but that
20    is not (and probably will never be) supported by this driver.
21    The ECU should be run to enable shared memory and to disable the
22    bus-mastering feature for use with linux.
23
24    By programming the 8390 to use only 8KB RAM, the modifications
25    to the ISA driver can be limited to the probe and initialization
26    code. This allows easy integration of EISA support into the ISA
27    driver. However, the driver development kit from SMC provided the
28    register information for sliding the 8KB window, and hence the 8390
29    is programmed to use the full 32KB RAM.
30
31    Unfortunately this required code changes outside the probe/init
32    routines, and thus we decided to separate the EISA driver from
33    the ISA one. In this way, ISA users don't end up with a larger
34    driver due to the EISA code, and EISA users don't end up with a
35    larger driver due to the ISA EtherEZ PIO code. The driver is
36    similar to the 3c503/16 driver, in that the window must be set
37    back to the 1st 8KB of space for access to the two 8390 Tx slots.
38
39    In testing, using only 8KB RAM (3 Tx / 5 Rx) didn't appear to
40    be a limiting factor, since the EISA bus could get packets off
41    the card fast enough, but having the use of lots of RAM as Rx
42    space is extra insurance if interrupt latencies become excessive.
43
44*/
45
46static const char *version = "smc-ultra32.c: 06/97 v1.00\n";
47
48
49#include <linux/module.h>
50#include <linux/eisa.h>
51#include <linux/kernel.h>
52#include <linux/errno.h>
53#include <linux/string.h>
54#include <linux/init.h>
55#include <linux/interrupt.h>
56#include <linux/netdevice.h>
57#include <linux/etherdevice.h>
58
59#include <asm/io.h>
60#include <asm/system.h>
61
62#include "8390.h"
63
64#define DRV_NAME "smc-ultra32"
65
66static int ultra32_probe1(struct net_device *dev, int ioaddr);
67static int ultra32_open(struct net_device *dev);
68static void ultra32_reset_8390(struct net_device *dev);
69static void ultra32_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
70                 int ring_page);
71static void ultra32_block_input(struct net_device *dev, int count,
72                struct sk_buff *skb, int ring_offset);
73static void ultra32_block_output(struct net_device *dev, int count,
74                 const unsigned char *buf,
75                 const int start_page);
76static int ultra32_close(struct net_device *dev);
77
78#define ULTRA32_CMDREG 0 /* Offset to ASIC command register. */
79#define ULTRA32_RESET 0x80 /* Board reset, in ULTRA32_CMDREG. */
80#define ULTRA32_MEMENB 0x40 /* Enable the shared memory. */
81#define ULTRA32_NIC_OFFSET 16 /* NIC register offset from the base_addr. */
82#define ULTRA32_IO_EXTENT 32
83#define EN0_ERWCNT 0x08 /* Early receive warning count. */
84
85/*
86 * Defines that apply only to the Ultra32 EISA card. Note that
87 * "smc" = 10011 01101 00011 = 0x4da3, and hence !smc8010.cfg translates
88 * into an EISA ID of 0x1080A34D
89 */
90#define ULTRA32_BASE 0xca0
91#define ULTRA32_ID 0x1080a34d
92#define ULTRA32_IDPORT (-0x20) /* 0xc80 */
93/* Config regs 1->7 from the EISA !SMC8010.CFG file. */
94#define ULTRA32_CFG1 0x04 /* 0xca4 */
95#define ULTRA32_CFG2 0x05 /* 0xca5 */
96#define ULTRA32_CFG3 (-0x18) /* 0xc88 */
97#define ULTRA32_CFG4 (-0x17) /* 0xc89 */
98#define ULTRA32_CFG5 (-0x16) /* 0xc8a */
99#define ULTRA32_CFG6 (-0x15) /* 0xc8b */
100#define ULTRA32_CFG7 0x0d /* 0xcad */
101
102static void cleanup_card(struct net_device *dev)
103{
104    int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET;
105    /* NB: ultra32_close_card() does free_irq */
106    release_region(ioaddr, ULTRA32_IO_EXTENT);
107    iounmap(ei_status.mem);
108}
109
110/* Probe for the Ultra32. This looks like a 8013 with the station
111    address PROM at I/O ports <base>+8 to <base>+13, with a checksum
112    following.
113*/
114
115struct net_device * __init ultra32_probe(int unit)
116{
117    struct net_device *dev;
118    int base;
119    int irq;
120    int err = -ENODEV;
121
122    if (!EISA_bus)
123        return ERR_PTR(-ENODEV);
124
125    dev = alloc_ei_netdev();
126
127    if (!dev)
128        return ERR_PTR(-ENOMEM);
129
130    if (unit >= 0) {
131        sprintf(dev->name, "eth%d", unit);
132        netdev_boot_setup_check(dev);
133    }
134
135    irq = dev->irq;
136
137    /* EISA spec allows for up to 16 slots, but 8 is typical. */
138    for (base = 0x1000 + ULTRA32_BASE; base < 0x9000; base += 0x1000) {
139        if (ultra32_probe1(dev, base) == 0)
140            break;
141        dev->irq = irq;
142    }
143    if (base >= 0x9000)
144        goto out;
145    err = register_netdev(dev);
146    if (err)
147        goto out1;
148    return dev;
149out1:
150    cleanup_card(dev);
151out:
152    free_netdev(dev);
153    return ERR_PTR(err);
154}
155
156
157static const struct net_device_ops ultra32_netdev_ops = {
158    .ndo_open = ultra32_open,
159    .ndo_stop = ultra32_close,
160    .ndo_start_xmit = ei_start_xmit,
161    .ndo_tx_timeout = ei_tx_timeout,
162    .ndo_get_stats = ei_get_stats,
163    .ndo_set_multicast_list = ei_set_multicast_list,
164    .ndo_validate_addr = eth_validate_addr,
165    .ndo_set_mac_address = eth_mac_addr,
166    .ndo_change_mtu = eth_change_mtu,
167#ifdef CONFIG_NET_POLL_CONTROLLER
168    .ndo_poll_controller = ei_poll,
169#endif
170};
171
172static int __init ultra32_probe1(struct net_device *dev, int ioaddr)
173{
174    int i, edge, media, retval;
175    int checksum = 0;
176    const char *model_name;
177    static unsigned version_printed;
178    /* Values from various config regs. */
179    unsigned char idreg;
180    unsigned char reg4;
181    const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"};
182
183    if (!request_region(ioaddr, ULTRA32_IO_EXTENT, DRV_NAME))
184        return -EBUSY;
185
186    if (inb(ioaddr + ULTRA32_IDPORT) == 0xff ||
187        inl(ioaddr + ULTRA32_IDPORT) != ULTRA32_ID) {
188        retval = -ENODEV;
189        goto out;
190    }
191
192    media = inb(ioaddr + ULTRA32_CFG7) & 0x03;
193    edge = inb(ioaddr + ULTRA32_CFG5) & 0x08;
194    printk("SMC Ultra32 in EISA Slot %d, Media: %s, %s IRQs.\n",
195        ioaddr >> 12, ifmap[media],
196        (edge ? "Edge Triggered" : "Level Sensitive"));
197
198    idreg = inb(ioaddr + 7);
199    reg4 = inb(ioaddr + 4) & 0x7f;
200
201    /* Check the ID nibble. */
202    if ((idreg & 0xf0) != 0x20) { /* SMC Ultra */
203        retval = -ENODEV;
204        goto out;
205    }
206
207    /* Select the station address register set. */
208    outb(reg4, ioaddr + 4);
209
210    for (i = 0; i < 8; i++)
211        checksum += inb(ioaddr + 8 + i);
212    if ((checksum & 0xff) != 0xff) {
213        retval = -ENODEV;
214        goto out;
215    }
216
217    if (ei_debug && version_printed++ == 0)
218        printk(version);
219
220    model_name = "SMC Ultra32";
221
222    for (i = 0; i < 6; i++)
223        dev->dev_addr[i] = inb(ioaddr + 8 + i);
224
225    printk("%s: %s at 0x%X, %pM",
226           dev->name, model_name, ioaddr, dev->dev_addr);
227
228    /* Switch from the station address to the alternate register set and
229       read the useful registers there. */
230    outb(0x80 | reg4, ioaddr + 4);
231
232    /* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */
233    outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c);
234
235    /* Reset RAM addr. */
236    outb(0x00, ioaddr + 0x0b);
237
238    /* Switch back to the station address register set so that the
239       MS-DOS driver can find the card after a warm boot. */
240    outb(reg4, ioaddr + 4);
241
242    if ((inb(ioaddr + ULTRA32_CFG5) & 0x40) == 0) {
243        printk("\nsmc-ultra32: Card RAM is disabled! "
244               "Run EISA config utility.\n");
245        retval = -ENODEV;
246        goto out;
247    }
248    if ((inb(ioaddr + ULTRA32_CFG2) & 0x04) == 0)
249        printk("\nsmc-ultra32: Ignoring Bus-Master enable bit. "
250               "Run EISA config utility.\n");
251
252    if (dev->irq < 2) {
253        unsigned char irqmap[] = {0, 9, 3, 5, 7, 10, 11, 15};
254        int irq = irqmap[inb(ioaddr + ULTRA32_CFG5) & 0x07];
255        if (irq == 0) {
256            printk(", failed to detect IRQ line.\n");
257            retval = -EAGAIN;
258            goto out;
259        }
260        dev->irq = irq;
261    }
262
263    /* The 8390 isn't at the base address, so fake the offset */
264    dev->base_addr = ioaddr + ULTRA32_NIC_OFFSET;
265
266    /* Save RAM address in the unused reg0 to avoid excess inb's. */
267    ei_status.reg0 = inb(ioaddr + ULTRA32_CFG3) & 0xfc;
268
269    dev->mem_start = 0xc0000 + ((ei_status.reg0 & 0x7c) << 11);
270
271    ei_status.name = model_name;
272    ei_status.word16 = 1;
273    ei_status.tx_start_page = 0;
274    ei_status.rx_start_page = TX_PAGES;
275    /* All Ultra32 cards have 32KB memory with an 8KB window. */
276    ei_status.stop_page = 128;
277
278    ei_status.mem = ioremap(dev->mem_start, 0x2000);
279    if (!ei_status.mem) {
280        printk(", failed to ioremap.\n");
281        retval = -ENOMEM;
282        goto out;
283    }
284    dev->mem_end = dev->mem_start + 0x1fff;
285
286    printk(", IRQ %d, 32KB memory, 8KB window at 0x%lx-0x%lx.\n",
287           dev->irq, dev->mem_start, dev->mem_end);
288    ei_status.block_input = &ultra32_block_input;
289    ei_status.block_output = &ultra32_block_output;
290    ei_status.get_8390_hdr = &ultra32_get_8390_hdr;
291    ei_status.reset_8390 = &ultra32_reset_8390;
292
293    dev->netdev_ops = &ultra32_netdev_ops;
294    NS8390_init(dev, 0);
295
296    return 0;
297out:
298    release_region(ioaddr, ULTRA32_IO_EXTENT);
299    return retval;
300}
301
302static int ultra32_open(struct net_device *dev)
303{
304    int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC addr */
305    int irq_flags = (inb(ioaddr + ULTRA32_CFG5) & 0x08) ? 0 : IRQF_SHARED;
306    int retval;
307
308    retval = request_irq(dev->irq, ei_interrupt, irq_flags, dev->name, dev);
309    if (retval)
310        return retval;
311
312    outb(ULTRA32_MEMENB, ioaddr); /* Enable Shared Memory. */
313    outb(0x80, ioaddr + ULTRA32_CFG6); /* Enable Interrupts. */
314    outb(0x84, ioaddr + 5); /* Enable MEM16 & Disable Bus Master. */
315    outb(0x01, ioaddr + 6); /* Enable Interrupts. */
316    /* Set the early receive warning level in window 0 high enough not
317       to receive ERW interrupts. */
318    outb_p(E8390_NODMA+E8390_PAGE0, dev->base_addr);
319    outb(0xff, dev->base_addr + EN0_ERWCNT);
320    ei_open(dev);
321    return 0;
322}
323
324static int ultra32_close(struct net_device *dev)
325{
326    int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* CMDREG */
327
328    netif_stop_queue(dev);
329
330    if (ei_debug > 1)
331        printk("%s: Shutting down ethercard.\n", dev->name);
332
333    outb(0x00, ioaddr + ULTRA32_CFG6); /* Disable Interrupts. */
334    outb(0x00, ioaddr + 6); /* Disable interrupts. */
335    free_irq(dev->irq, dev);
336
337    NS8390_init(dev, 0);
338
339    return 0;
340}
341
342static void ultra32_reset_8390(struct net_device *dev)
343{
344    int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC base addr */
345
346    outb(ULTRA32_RESET, ioaddr);
347    if (ei_debug > 1) printk("resetting Ultra32, t=%ld...", jiffies);
348    ei_status.txing = 0;
349
350    outb(ULTRA32_MEMENB, ioaddr); /* Enable Shared Memory. */
351    outb(0x80, ioaddr + ULTRA32_CFG6); /* Enable Interrupts. */
352    outb(0x84, ioaddr + 5); /* Enable MEM16 & Disable Bus Master. */
353    outb(0x01, ioaddr + 6); /* Enable Interrupts. */
354    if (ei_debug > 1) printk("reset done\n");
355    return;
356}
357
358/* Grab the 8390 specific header. Similar to the block_input routine, but
359   we don't need to be concerned with ring wrap as the header will be at
360   the start of a page, so we optimize accordingly. */
361
362static void ultra32_get_8390_hdr(struct net_device *dev,
363                 struct e8390_pkt_hdr *hdr,
364                 int ring_page)
365{
366    void __iomem *hdr_start = ei_status.mem + ((ring_page & 0x1f) << 8);
367    unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3;
368
369    /* Select correct 8KB Window. */
370    outb(ei_status.reg0 | ((ring_page & 0x60) >> 5), RamReg);
371
372#ifdef __BIG_ENDIAN
373    /* Officially this is what we are doing, but the readl() is faster */
374    /* unfortunately it isn't endian aware of the struct */
375    memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
376    hdr->count = le16_to_cpu(hdr->count);
377#else
378    ((unsigned int*)hdr)[0] = readl(hdr_start);
379#endif
380}
381
382/* Block input and output are easy on shared memory ethercards, the only
383   complication is when the ring buffer wraps, or in this case, when a
384   packet spans an 8KB boundary. Note that the current 8KB segment is
385   already set by the get_8390_hdr routine. */
386
387static void ultra32_block_input(struct net_device *dev,
388                int count,
389                struct sk_buff *skb,
390                int ring_offset)
391{
392    void __iomem *xfer_start = ei_status.mem + (ring_offset & 0x1fff);
393    unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3;
394
395    if ((ring_offset & ~0x1fff) != ((ring_offset + count - 1) & ~0x1fff)) {
396        int semi_count = 8192 - (ring_offset & 0x1FFF);
397        memcpy_fromio(skb->data, xfer_start, semi_count);
398        count -= semi_count;
399        if (ring_offset < 96*256) {
400            /* Select next 8KB Window. */
401            ring_offset += semi_count;
402            outb(ei_status.reg0 | ((ring_offset & 0x6000) >> 13), RamReg);
403            memcpy_fromio(skb->data + semi_count, ei_status.mem, count);
404        } else {
405            /* Select first 8KB Window. */
406            outb(ei_status.reg0, RamReg);
407            memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
408        }
409    } else {
410        memcpy_fromio(skb->data, xfer_start, count);
411    }
412}
413
414static void ultra32_block_output(struct net_device *dev,
415                 int count,
416                 const unsigned char *buf,
417                 int start_page)
418{
419    void __iomem *xfer_start = ei_status.mem + (start_page<<8);
420    unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3;
421
422    /* Select first 8KB Window. */
423    outb(ei_status.reg0, RamReg);
424
425    memcpy_toio(xfer_start, buf, count);
426}
427
428#ifdef MODULE
429#define MAX_ULTRA32_CARDS 4 /* Max number of Ultra cards per module */
430static struct net_device *dev_ultra[MAX_ULTRA32_CARDS];
431
432MODULE_DESCRIPTION("SMC Ultra32 EISA ethernet driver");
433MODULE_LICENSE("GPL");
434
435int __init init_module(void)
436{
437    int this_dev, found = 0;
438
439    for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) {
440        struct net_device *dev = ultra32_probe(-1);
441        if (IS_ERR(dev))
442            break;
443        dev_ultra[found++] = dev;
444    }
445    if (found)
446        return 0;
447    printk(KERN_WARNING "smc-ultra32.c: No SMC Ultra32 found.\n");
448    return -ENXIO;
449}
450
451void __exit cleanup_module(void)
452{
453    int this_dev;
454
455    for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) {
456        struct net_device *dev = dev_ultra[this_dev];
457        if (dev) {
458            unregister_netdev(dev);
459            cleanup_card(dev);
460            free_netdev(dev);
461        }
462    }
463}
464#endif /* MODULE */
465
466

Archive Download this file



interactive