~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/net/ac3200.c

Version: ~ [ 2.2.5 ] ~ [ 2.4.1 ] ~ [ 2.4.9 ] ~ [ 2.6.17.10 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* 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         Changelog:
 17 
 18         Paul Gortmaker 05/98    : add support for shared mem above 1MB.
 19 
 20   */
 21 
 22 static const char *version =
 23         "ac3200.c:v1.01 7/1/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 24 
 25 #include <linux/module.h>
 26 
 27 #include <linux/kernel.h>
 28 #include <linux/sched.h>
 29 #include <linux/errno.h>
 30 #include <linux/string.h>
 31 #include <linux/netdevice.h>
 32 #include <linux/etherdevice.h>
 33 #include <linux/init.h>
 34 
 35 #include <asm/system.h>
 36 #include <asm/io.h>
 37 #include <asm/irq.h>
 38 
 39 #include "8390.h"
 40 
 41 /* Offsets from the base address. */
 42 #define AC_NIC_BASE     0x00
 43 #define AC_SA_PROM      0x16                    /* The station address PROM. */
 44 #define AC_ADDR0        0x00                    /* Prefix station address values. */
 45 #define AC_ADDR1        0x40                    
 46 #define AC_ADDR2        0x90
 47 #define AC_ID_PORT      0xC80
 48 #define AC_EISA_ID      0x0110d305
 49 #define AC_RESET_PORT   0xC84
 50 #define AC_RESET        0x00
 51 #define AC_ENABLE       0x01
 52 #define AC_CONFIG       0xC90   /* The configuration port. */
 53 
 54 #define AC_IO_EXTENT 0x20
 55                                 /* Actually accessed is:
 56                                                                  * AC_NIC_BASE (0-15)
 57                                                                  * AC_SA_PROM (0-5)
 58                                                                  * AC_ID_PORT (0-3)
 59                                                                  * AC_RESET_PORT
 60                                                                  * AC_CONFIG
 61                                                                  */
 62 
 63 /* Decoding of the configuration register. */
 64 static unsigned char config2irqmap[8] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
 65 static int addrmap[8] =
 66 {0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000,  0xD0000, 0 };
 67 static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"};
 68 
 69 #define config2irq(configval)   config2irqmap[((configval) >> 3) & 7]
 70 #define config2mem(configval)   addrmap[(configval) & 7]
 71 #define config2name(configval)  port_name[((configval) >> 6) & 3]
 72 
 73 /* First and last 8390 pages. */
 74 #define AC_START_PG             0x00    /* First page of 8390 TX buffer */
 75 #define AC_STOP_PG              0x80    /* Last page +1 of the 8390 RX ring */
 76 
 77 int ac3200_probe(struct net_device *dev);
 78 static int ac_probe1(int ioaddr, struct net_device *dev);
 79 
 80 static int ac_open(struct net_device *dev);
 81 static void ac_reset_8390(struct net_device *dev);
 82 static void ac_block_input(struct net_device *dev, int count,
 83                                         struct sk_buff *skb, int ring_offset);
 84 static void ac_block_output(struct net_device *dev, const int count,
 85                                                         const unsigned char *buf, const int start_page);
 86 static void ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
 87                                         int ring_page);
 88 
 89 static int ac_close_card(struct net_device *dev);
 90 
 91 
 92 /*      Probe for the AC3200.
 93 
 94         The AC3200 can be identified by either the EISA configuration registers,
 95         or the unique value in the station address PROM.
 96         */
 97 
 98 int __init ac3200_probe(struct net_device *dev)
 99 {
100         unsigned short ioaddr = dev->base_addr;
101 
102         SET_MODULE_OWNER(dev);
103 
104         if (ioaddr > 0x1ff)             /* Check a single specified location. */
105                 return ac_probe1(ioaddr, dev);
106         else if (ioaddr > 0)            /* Don't probe at all. */
107                 return -ENXIO;
108 
109         if ( ! EISA_bus)
110                 return -ENXIO;
111 
112         for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000)
113                 if (ac_probe1(ioaddr, dev) == 0)
114                         return 0;
115 
116         return -ENODEV;
117 }
118 
119 static int __init ac_probe1(int ioaddr, struct net_device *dev)
120 {
121         int i, retval;
122 
123         if (!request_region(ioaddr, AC_IO_EXTENT, dev->name))
124                 return -EBUSY;
125 
126         if (inb_p(ioaddr + AC_ID_PORT) == 0xff) {
127                 retval = -ENODEV;
128                 goto out;
129         }
130 
131         if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
132                 retval = -ENODEV;
133                 goto out;
134         }
135 
136 #ifndef final_version
137         printk(KERN_DEBUG "AC3200 ethercard configuration register is %#02x,"
138                    " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG),
139                    inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1),
140                    inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3));
141 #endif
142 
143         printk("AC3200 in EISA slot %d, node", ioaddr/0x1000);
144         for(i = 0; i < 6; i++)
145                 printk(" %02x", dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i));
146 
147 #if 0
148         /* Check the vendor ID/prefix. Redundant after checking the EISA ID */
149         if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0
150                 || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1
151                 || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) {
152                 printk(", not found (invalid prefix).\n");
153                 retval = -ENODEV;
154                 goto out;
155         }
156 #endif
157 
158         /* Allocate dev->priv and fill in 8390 specific dev fields. */
159         if (ethdev_init(dev)) {
160                 printk (", unable to allocate memory for dev->priv.\n");
161                 retval = -ENOMEM;
162                 goto out;
163         }
164 
165         /* Assign and allocate the interrupt now. */
166         if (dev->irq == 0) {
167                 dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
168                 printk(", using");
169         } else {
170                 dev->irq = irq_cannonicalize(dev->irq);
171                 printk(", assigning");
172         }
173 
174         retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
175         if (retval) {
176                 printk (" nothing! Unable to get IRQ %d.\n", dev->irq);
177                 goto out1;
178         }
179 
180         printk(" IRQ %d, %s port\n", dev->irq, port_name[dev->if_port]);
181 
182         dev->base_addr = ioaddr;
183 
184 #ifdef notyet
185         if (dev->mem_start)     {               /* Override the value from the board. */
186                 for (i = 0; i < 7; i++)
187                         if (addrmap[i] == dev->mem_start)
188                                 break;
189                 if (i >= 7)
190                         i = 0;
191                 outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG);
192         }
193 #endif
194 
195         dev->if_port = inb(ioaddr + AC_CONFIG) >> 6;
196         dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG));
197 
198         printk("%s: AC3200 at %#3x with %dkB memory at physical address %#lx.\n", 
199                         dev->name, ioaddr, AC_STOP_PG/4, dev->mem_start);
200 
201         /*
202          *  BEWARE!! Some dain-bramaged EISA SCUs will allow you to put
203          *  the card mem within the region covered by `normal' RAM  !!!
204          */
205         if (dev->mem_start > 1024*1024) {       /* phys addr > 1MB */
206                 if (dev->mem_start < virt_to_bus(high_memory)) {
207                         printk(KERN_CRIT "ac3200.c: Card RAM overlaps with normal memory!!!\n");
208                         printk(KERN_CRIT "ac3200.c: Use EISA SCU to set card memory below 1MB,\n");
209                         printk(KERN_CRIT "ac3200.c: or to an address above 0x%lx.\n", virt_to_bus(high_memory));
210                         printk(KERN_CRIT "ac3200.c: Driver NOT installed.\n");
211                         retval = -EINVAL;
212                         goto out2;
213                 }
214                 dev->mem_start = (unsigned long)ioremap(dev->mem_start, AC_STOP_PG*0x100);
215                 if (dev->mem_start == 0) {
216                         printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n");
217                         printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n");
218                         printk(KERN_ERR "ac3200.c: Driver NOT installed.\n");
219                         retval = -EINVAL;
220                         goto out2;
221                 }
222                 ei_status.reg0 = 1;     /* Use as remap flag */
223                 printk("ac3200.c: remapped %dkB card memory to virtual address %#lx\n",
224                                 AC_STOP_PG/4, dev->mem_start);
225         }
226 
227         dev->rmem_start = dev->mem_start + TX_PAGES*256;
228         dev->mem_end = dev->rmem_end = dev->mem_start
229                 + (AC_STOP_PG - AC_START_PG)*256;
230 
231         ei_status.name = "AC3200";
232         ei_status.tx_start_page = AC_START_PG;
233         ei_status.rx_start_page = AC_START_PG + TX_PAGES;
234         ei_status.stop_page = AC_STOP_PG;
235         ei_status.word16 = 1;
236 
237         if (ei_debug > 0)
238                 printk(version);
239 
240         ei_status.reset_8390 = &ac_reset_8390;
241         ei_status.block_input = &ac_block_input;
242         ei_status.block_output = &ac_block_output;
243         ei_status.get_8390_hdr = &ac_get_8390_hdr;
244 
245         dev->open = &ac_open;
246         dev->stop = &ac_close_card;
247         NS8390_init(dev, 0);
248         return 0;
249 out2:
250         free_irq(dev->irq, dev);
251 out1:
252         kfree(dev->priv);
253         dev->priv = NULL;
254 out:
255         release_region(ioaddr, AC_IO_EXTENT);
256         return retval;
257 }
258 
259 static int ac_open(struct net_device *dev)
260 {
261 #ifdef notyet
262         /* Someday we may enable the IRQ and shared memory here. */
263         int ioaddr = dev->base_addr;
264 #endif
265 
266         ei_open(dev);
267         return 0;
268 }
269 
270 static void ac_reset_8390(struct net_device *dev)
271 {
272         ushort ioaddr = dev->base_addr;
273 
274         outb(AC_RESET, ioaddr + AC_RESET_PORT);
275         if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies);
276 
277         ei_status.txing = 0;
278         outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
279         if (ei_debug > 1) printk("reset done\n");
280 
281         return;
282 }
283 
284 /* Grab the 8390 specific header. Similar to the block_input routine, but
285    we don't need to be concerned with ring wrap as the header will be at
286    the start of a page, so we optimize accordingly. */
287 
288 static void
289 ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
290 {
291         unsigned long hdr_start = dev->mem_start + ((ring_page - AC_START_PG)<<8);
292         isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
293 }
294 
295 /*  Block input and output are easy on shared memory ethercards, the only
296         complication is when the ring buffer wraps. */
297 
298 static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb,
299                                                   int ring_offset)
300 {
301         unsigned long xfer_start = dev->mem_start + ring_offset - (AC_START_PG<<8);
302 
303         if (xfer_start + count > dev->rmem_end) {
304                 /* We must wrap the input move. */
305                 int semi_count = dev->rmem_end - xfer_start;
306                 isa_memcpy_fromio(skb->data, xfer_start, semi_count);
307                 count -= semi_count;
308                 isa_memcpy_fromio(skb->data + semi_count, dev->rmem_start, count);
309         } else {
310                 /* Packet is in one chunk -- we can copy + cksum. */
311                 isa_eth_io_copy_and_sum(skb, xfer_start, count, 0);
312         }
313 }
314 
315 static void ac_block_output(struct net_device *dev, int count,
316                                                         const unsigned char *buf, int start_page)
317 {
318         unsigned long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8);
319 
320         isa_memcpy_toio(shmem, buf, count);
321 }
322 
323 static int ac_close_card(struct net_device *dev)
324 {
325         if (ei_debug > 1)
326                 printk("%s: Shutting down ethercard.\n", dev->name);
327 
328 #ifdef notyet
329         /* We should someday disable shared memory and interrupts. */
330         outb(0x00, ioaddr + 6); /* Disable interrupts. */
331         free_irq(dev->irq, dev);
332 #endif
333 
334         ei_close(dev);
335         return 0;
336 }
337 
338 #ifdef MODULE
339 #define MAX_AC32_CARDS  4       /* Max number of AC32 cards per module */
340 static struct net_device dev_ac32[MAX_AC32_CARDS];
341 static int io[MAX_AC32_CARDS];
342 static int irq[MAX_AC32_CARDS];
343 static int mem[MAX_AC32_CARDS];
344 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
345 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
346 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
347 
348 int
349 init_module(void)
350 {
351         int this_dev, found = 0;
352 
353         for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
354                 struct net_device *dev = &dev_ac32[this_dev];
355                 dev->irq = irq[this_dev];
356                 dev->base_addr = io[this_dev];
357                 dev->mem_start = mem[this_dev];         /* Currently ignored by driver */
358                 dev->init = ac3200_probe;
359                 /* Default is to only install one card. */
360                 if (io[this_dev] == 0 && this_dev != 0) break;
361                 if (register_netdev(dev) != 0) {
362                         printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
363                         if (found != 0) {       /* Got at least one. */
364                                 return 0;
365                         }
366                         return -ENXIO;
367                 }
368                 found++;
369         }
370         return 0;
371 }
372 
373 void
374 cleanup_module(void)
375 {
376         int this_dev;
377 
378         for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
379                 struct net_device *dev = &dev_ac32[this_dev];
380                 if (dev->priv != NULL) {
381                         /* Someday free_irq may be in ac_close_card() */
382                         free_irq(dev->irq, dev);
383                         release_region(dev->base_addr, AC_IO_EXTENT);
384                         if (ei_status.reg0)
385                                 iounmap((void *)dev->mem_start);
386                         unregister_netdev(dev);
387                         kfree(dev->priv);
388                         dev->priv = NULL;
389                 }
390         }
391 }
392 #endif /* MODULE */
393 
394 /*
395  * Local variables:
396  * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c ac3200.c"
397  *  version-control: t
398  *  kept-new-versions: 5
399  *  tab-width: 4
400  * End:
401  */
402 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.