* better
[mascara-docs.git] / i386 / linux-2.3.21 / drivers / net / hydra.c
blob483d94e4542c352ad77d1be62b4e692215cd380b
1 /* Linux/68k Hydra Amiganet board driver v2.1 BETA */
2 /* copyleft by Topi Kanerva (topi@susanna.oulu.fi) */
3 /* also some code & lots of fixes by Timo Rossi (trossi@cc.jyu.fi) */
5 /* The code is mostly based on the linux/68k Ariadne driver */
6 /* copyrighted by Geert Uytterhoeven (geert@linux-m68k.org) */
7 /* and Peter De Schrijver (Peter.DeSchrijver@linux.cc.kuleuven.ac.be) */
9 /* This file is subject to the terms and conditions of the GNU General */
10 /* Public License. See the file COPYING in the main directory of the */
11 /* Linux distribution for more details. */
13 /* The Amiganet is a Zorro-II board made by Hydra Systems. It contains a */
14 /* NS8390 NIC (network interface controller) clone, 16 or 64K on-board RAM */
15 /* and 10BASE-2 (thin coax) and AUI connectors. */
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/sched.h>
21 #include <linux/string.h>
22 #include <linux/ptrace.h>
23 #include <linux/errno.h>
24 #include <linux/ioport.h>
25 #include <linux/malloc.h>
26 #include <linux/interrupt.h>
27 #include <linux/netdevice.h>
28 #include <linux/etherdevice.h>
29 #include <linux/skbuff.h>
30 #include <linux/init.h>
32 #include <asm/bitops.h>
33 #include <asm/io.h>
34 #include <asm/irq.h>
36 #include <asm/amigaints.h>
37 #include <asm/amigahw.h>
38 #include <linux/zorro.h>
40 #include "hydra.h"
43 #define HYDRA_DEBUG
44 #undef HAVE_MULTICAST
46 #define HYDRA_VERSION "v2.1 BETA"
48 #undef HYDRA_DEBUG /* define this for (lots of) debugging information */
50 #if 0 /* currently hardwired to one transmit buffer */
51 #define TX_RING_SIZE 5
52 #define RX_RING_SIZE 16
53 #else
54 #define TX_RING_SIZE 1
55 #define RX_RING_SIZE 8
56 #endif
58 #define ETHER_MIN_LEN 64
59 #define ETHER_MAX_LEN 1518
60 #define ETHER_ADDR_LEN 6
64 * let's define here nice macros for writing and reading NIC registers
66 * the CIA accesses here are uses to make sure the minimum time
67 * requirement between NIC chip selects is met.
69 #define WRITE_REG(reg, val) (ciaa.pra, ((u8)(*(nicbase+(reg))=val)))
70 #define READ_REG(reg) (ciaa.pra, ((u8)(*(nicbase+(reg)))))
72 /* mask value for the interrupts we use */
73 #define NIC_INTS (ISR_PRX | ISR_PTX | ISR_RXE | ISR_TXE | ISR_OVW | ISR_CNT)
75 /* only broadcasts, no promiscuous mode for now */
76 #define NIC_RCRBITS (0)
79 * Private Device Data
81 struct hydra_private
83 u8 *hydra_base;
84 u8 *hydra_nic_base;
85 u16 tx_page_start;
86 u16 rx_page_start;
87 u16 rx_page_stop;
88 u16 next_pkt;
89 struct net_device_stats stats;
90 unsigned int key;
93 static int hydra_open(struct net_device *dev);
94 static int hydra_start_xmit(struct sk_buff *skb, struct net_device *dev);
95 static void hydra_interrupt(int irq, void *data, struct pt_regs *fp);
96 static void __inline__ hydra_rx(struct net_device *dev, struct hydra_private *priv, volatile u8 *nicbase);
97 static int hydra_close(struct net_device *dev);
98 static struct net_device_stats *hydra_get_stats(struct net_device *dev);
99 #ifdef HAVE_MULTICAST
100 static void set_multicast_list(struct net_device *dev, int num_addrs, void *addrs);
101 #endif
104 /* this is now coherent with the C version below, */
105 /* compile the source with -D__USE_ASM__ if you */
106 /* want it - it'll only be some 10% faster though */
108 #if defined (__GNUC__) && defined (__mc68000__) && defined (USE_ASM)
110 static __inline__ void *memcpyw(u16 *dest, u16 *src, int len)
112 __asm__(" move.l %0,%/a1; move.l %1,%/a0; move.l %2,%/d0 \n\t"
113 " cmpi.l #2,%/d0 \n\t"
114 "1: bcs.s 2f \n\t"
115 " move.w %/a0@+,%/a1@+ \n\t"
116 " subq.l #2,%/d0 \n\t"
117 " bra.s 1b \n\t"
118 "2: cmpi.l #1,%/d0 \n\t"
119 " bne.s 3f \n\t"
120 " move.w %/a0@,%/d0 \n\t"
121 " swap.w %/d0 \n\t"
122 " move.b %/d0,%/a1@ \n\t"
123 "3: moveq #0,%/d0 \n\t"
125 : "g" (dest), "g" (src), "g" (len)
126 : "a1", "a0", "d0");
127 return;
130 #else
132 /* hydra memory can only be read or written as words or longwords. */
133 /* that will mean that we'll have to write a special memcpy for it. */
134 /* this one here relies on the fact that _writes_ to hydra memory */
135 /* are guaranteed to be of even length. (reads can be arbitrary) */
138 * FIXME: Surely we should be using the OS generic stuff and do
140 * memcpy(dest,src,(len+1)&~1);
142 * Can a 68K guy with this card check that ? - better yet
143 * use a copy/checksum on it.
146 static void memcpyw(u16 *dest, u16 *src, int len)
148 if(len & 1)
149 len++;
151 while (len >= 2)
153 *(dest++) = *(src++);
154 len -= 2;
158 #endif
160 int __init hydra_probe(struct net_device *dev)
162 struct hydra_private *priv;
163 u32 board;
164 unsigned int key;
165 const struct ConfigDev *cd;
166 int j;
168 #ifdef HYDRA_DEBUG
169 printk("hydra_probe(%x)\n", dev);
170 #endif
172 if ((key = zorro_find(ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET, 0, 0)))
174 cd = zorro_get_board(key);
175 if((board = (u32) cd->cd_BoardAddr))
177 for(j = 0; j < ETHER_ADDR_LEN; j++)
178 dev->dev_addr[j] = *((u8 *)ZTWO_VADDR(board + HYDRA_ADDRPROM + 2*j));
180 printk("%s: hydra at 0x%08x, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n",
181 dev->name, (int)board, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
182 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
183 init_etherdev(dev, 0);
185 dev->priv = kmalloc(sizeof(struct hydra_private), GFP_KERNEL);
186 priv = (struct hydra_private *)dev->priv;
187 memset(priv, 0, sizeof(struct hydra_private));
189 priv->hydra_base = (u8 *) ZTWO_VADDR(board);
190 priv->hydra_nic_base = (u8 *) ZTWO_VADDR(board) + HYDRA_NIC_BASE;
191 priv->key = key;
193 dev->open = &hydra_open;
194 dev->stop = &hydra_close;
195 dev->hard_start_xmit = &hydra_start_xmit;
196 dev->get_stats = &hydra_get_stats;
197 #ifdef HAVE_MULTICAST
198 dev->set_multicast_list = &set_multicast_list;
199 #endif
202 * Cannot yet do multicast
204 dev->flags&=~IFF_MULTICAST;
205 zorro_config_board(key, 0);
206 return(0);
209 return(-ENODEV);
213 static int hydra_open(struct net_device *dev)
215 struct hydra_private *priv = (struct hydra_private *)dev->priv;
216 volatile u8 *nicbase = priv->hydra_nic_base;
217 int i;
219 #ifdef HYDRA_DEBUG
220 printk("hydra_open(0x%x)\n", dev);
221 #endif
223 /* first, initialize the private structure */
224 priv->tx_page_start = 0; /* these are 256 byte buffers for NS8390 */
225 priv->rx_page_start = 6;
226 priv->rx_page_stop = 62; /* these values are hard coded for now */
228 /* Reset the NS8390 NIC */
229 WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP);
231 /* be sure that the NIC is in stopped state */
232 while(!(READ_REG(NIC_ISR) & ISR_RST));
234 /* word transfer, big endian bytes, loopback, FIFO threshold 4 bytes */
235 WRITE_REG(NIC_DCR, DCR_WTS | DCR_BOS | DCR_LS | DCR_FT0);
237 /* clear remote byte count registers */
238 WRITE_REG(NIC_RBCR0, 0);
239 WRITE_REG(NIC_RBCR1, 0);
241 /* accept packets addressed to this card and also broadcast packets */
242 WRITE_REG(NIC_RCR, NIC_RCRBITS);
244 /* enable loopback mode 1 */
245 WRITE_REG(NIC_TCR, TCR_LB1);
247 /* initialize receive buffer ring */
248 WRITE_REG(NIC_PSTART, priv->rx_page_start);
249 WRITE_REG(NIC_PSTOP, priv->rx_page_stop);
250 WRITE_REG(NIC_BNDRY, priv->rx_page_start);
252 /* clear interrupts */
253 WRITE_REG(NIC_ISR, 0xff);
255 /* enable interrupts */
256 WRITE_REG(NIC_IMR, NIC_INTS);
258 /* set the ethernet hardware address */
259 WRITE_REG(NIC_CR, CR_PAGE1 | CR_NODMA | CR_STOP); /* goto page 1 */
261 WRITE_REG(NIC_PAR0, dev->dev_addr[0]);
262 WRITE_REG(NIC_PAR1, dev->dev_addr[1]);
263 WRITE_REG(NIC_PAR2, dev->dev_addr[2]);
264 WRITE_REG(NIC_PAR3, dev->dev_addr[3]);
265 WRITE_REG(NIC_PAR4, dev->dev_addr[4]);
266 WRITE_REG(NIC_PAR5, dev->dev_addr[5]);
268 /* clear multicast hash table */
269 for(i = 0; i < 8; i++)
270 WRITE_REG(NIC_MAR0 + 2*i, 0);
272 priv->next_pkt = priv->rx_page_start+1; /* init our s/w variable */
273 WRITE_REG(NIC_CURR, priv->next_pkt); /* set the next buf for current */
275 /* goto page 0, start NIC */
276 WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START);
278 /* take interface out of loopback */
279 WRITE_REG(NIC_TCR, 0);
281 dev->tbusy = 0;
282 dev->interrupt = 0;
283 dev->start = 1;
285 if(request_irq(IRQ_AMIGA_PORTS, hydra_interrupt, SA_SHIRQ,
286 "Hydra Ethernet", dev))
287 return(-EAGAIN);
289 MOD_INC_USE_COUNT;
291 return(0);
295 static int hydra_close(struct net_device *dev)
297 struct hydra_private *priv = (struct hydra_private *)dev->priv;
298 volatile u8 *nicbase = priv->hydra_nic_base;
299 int n = 5000;
301 dev->start = 0;
302 dev->tbusy = 1;
304 #ifdef HYDRA_DEBUG
305 printk("%s: Shutting down ethercard\n", dev->name);
306 printk("%s: %d packets missed\n", dev->name, priv->stats.rx_missed_errors);
307 #endif
309 WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP);
311 /* wait for NIC to stop (what a nice timeout..) */
312 while(((READ_REG(NIC_ISR) & ISR_RST) == 0) && --n);
314 free_irq(IRQ_AMIGA_PORTS, dev);
316 MOD_DEC_USE_COUNT;
318 return(0);
322 static void hydra_interrupt(int irq, void *data, struct pt_regs *fp)
324 volatile u8 *nicbase;
326 struct net_device *dev = (struct net_device *) data;
327 struct hydra_private *priv;
328 u16 intbits;
330 if(dev == NULL)
332 printk("hydra_interrupt(): irq for unknown device\n");
333 return;
336 /* this is not likely a problem - i think */
337 if(dev->interrupt)
338 printk("%s: re-entering the interrupt handler\n", dev->name);
340 dev->interrupt = 1;
342 priv = (struct hydra_private *) dev->priv;
343 nicbase = (u8 *) priv->hydra_nic_base;
345 /* select page 0 */
346 WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
348 intbits = READ_REG(NIC_ISR) & NIC_INTS;
349 if(intbits == 0)
351 dev->interrupt = 0;
352 return;
355 /* acknowledge all interrupts, by clearing the interrupt flag */
356 WRITE_REG(NIC_ISR, intbits);
358 if((intbits & ISR_PTX) && !(intbits & ISR_TXE))
360 dev->tbusy = 0;
361 mark_bh(NET_BH);
364 if((intbits & ISR_PRX) && !(intbits & ISR_RXE))/* packet received OK */
365 hydra_rx(dev, priv, nicbase);
367 if(intbits & ISR_TXE)
368 priv->stats.tx_errors++;
370 if(intbits & ISR_RXE)
371 priv->stats.rx_errors++;
373 if(intbits & ISR_CNT)
376 * read the tally counters and (currently) ignore the values
377 * might be useful because of bugs of some versions of the 8390 NIC
379 #ifdef HYDRA_DEBUG
380 printk("hydra_interrupt(): ISR_CNT\n");
381 #endif
382 (void)READ_REG(NIC_CNTR0);
383 (void)READ_REG(NIC_CNTR1);
384 (void)READ_REG(NIC_CNTR2);
387 if(intbits & ISR_OVW)
389 #ifdef HYDRA_DEBUG
390 WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA);
391 /* another one just too much for me to comprehend - basically this could */
392 /* only occur because of invalid access to hydra ram, thus invalidating */
393 /* the interrupt bits read - in average usage these do not occur at all */
394 printk("hydra_interrupt(): overwrite warning, NIC_ISR %02x, NIC_CURR %02x\n",
395 intbits, READ_REG(NIC_CURR));
396 WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
397 #endif
400 /* overwrite warning occurred, stop NIC & check the BOUNDARY pointer */
401 /* FIXME - real overwrite handling needed !! */
403 printk("hydra_interrupt(): overwrite warning, resetting NIC\n");
404 WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP);
405 while(!(READ_REG(NIC_ISR) & ISR_RST));
406 /* wait for NIC to reset */
407 WRITE_REG(NIC_DCR, DCR_WTS | DCR_BOS | DCR_LS | DCR_FT0);
408 WRITE_REG(NIC_RBCR0, 0);
409 WRITE_REG(NIC_RBCR1, 0);
410 WRITE_REG(NIC_RCR, NIC_RCRBITS);
411 WRITE_REG(NIC_TCR, TCR_LB1);
412 WRITE_REG(NIC_PSTART, priv->rx_page_start);
413 WRITE_REG(NIC_PSTOP, priv->rx_page_stop);
414 WRITE_REG(NIC_BNDRY, priv->rx_page_start);
415 WRITE_REG(NIC_ISR, 0xff);
416 WRITE_REG(NIC_IMR, NIC_INTS);
417 /* currently this _won't_ reset my hydra, even though it is */
418 /* basically the same code as in the board init - any ideas? */
420 priv->next_pkt = priv->rx_page_start+1; /* init our s/w variable */
421 WRITE_REG(NIC_CURR, priv->next_pkt); /* set the next buf for current */
423 WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START);
425 WRITE_REG(NIC_TCR, 0);
428 dev->interrupt = 0;
429 return;
434 * packet transmit routine
437 static int hydra_start_xmit(struct sk_buff *skb, struct net_device *dev)
439 struct hydra_private *priv = (struct hydra_private *)dev->priv;
440 volatile u8 *nicbase = priv->hydra_nic_base;
441 int len, len1;
443 /* Transmitter timeout, serious problems. */
445 if(dev->tbusy)
447 int tickssofar = jiffies - dev->trans_start;
448 if(tickssofar < 20)
449 return(1);
450 WRITE_REG(NIC_CR, CR_STOP);
451 printk("%s: transmit timed out, status %4.4x, resetting.\n", dev->name, 0);
452 priv->stats.tx_errors++;
453 dev->tbusy = 0;
454 dev->trans_start = jiffies;
455 return(0);
458 len=skb->len;
460 /* fill in a tx ring entry */
462 #ifdef HYDRA_DEBUG
463 printk("TX pkt type 0x%04x from ", ((u16 *)skb->data)[6]);
465 int i;
466 u8 *ptr = &((u8 *)skb->data)[6];
467 for (i = 0; i < 6; i++)
468 printk("%02x", ptr[i]);
470 printk(" to ");
472 int i;
473 u8 *ptr = (u8 *)skb->data;
474 for (i = 0; i < 6; i++)
475 printk("%02x", ptr[i]);
477 printk(" data 0x%08x len %d\n", (int)skb->data, len);
478 #endif
481 * make sure that the packet size is at least the minimum
482 * allowed ethernet packet length.
483 * (FIXME: Should also clear the unused space...)
484 * note: minimum packet length is 64, including CRC
486 len1 = len;
488 if(len < (ETHER_MIN_LEN-4))
489 len = (ETHER_MIN_LEN-1);
491 /* make sure we've got an even number of bytes to copy to hydra's mem */
492 if(len & 1) len++;
494 if((u32)(priv->hydra_base + (priv->tx_page_start << 8)) < 0x80000000)
495 printk("weirdness: memcpyw(txbuf, skbdata, len): txbuf = 0x%x\n", (u_int)(priv->hydra_base+(priv->tx_page_start<<8)));
497 /* copy the packet data to the transmit buffer
498 in the ethernet card RAM */
499 memcpyw((u16 *)(priv->hydra_base + (priv->tx_page_start << 8)),
500 (u16 *)skb->data, len);
501 /* clear the unused space */
502 for(; len1<len; len1++)
503 (u16)*(priv->hydra_base + (priv->tx_page_start<<8) + len1) = 0;
504 dev_kfree_skb(skb);
506 priv->stats.tx_packets++;
508 cli();
509 /* make sure we are on the correct page */
510 WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START);
512 /* here we configure the transmit page start register etc */
513 /* notice that this code is hardwired to one transmit buffer */
514 WRITE_REG(NIC_TPSR, priv->tx_page_start);
515 WRITE_REG(NIC_TBCR0, len & 0xff);
516 WRITE_REG(NIC_TBCR1, len >> 8);
518 /* commit the packet to the wire */
519 WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA | CR_TXP);
520 sti();
522 dev->trans_start = jiffies;
524 return(0);
528 static void __inline__ hydra_rx(struct net_device *dev, struct hydra_private *priv, volatile u8 *nicbase)
530 volatile u16 *board_ram_ptr;
531 struct sk_buff *skb;
532 int hdr_next_pkt, pkt_len, len1, boundary;
535 /* remove packet(s) from the ring and commit them to TCP layer */
536 WRITE_REG(NIC_CR, CR_PAGE1 | CR_NODMA | CR_START); /* page 1 */
537 while(priv->next_pkt != READ_REG(NIC_CURR)) /* should read this only once? */
539 board_ram_ptr = (u16 *)(priv->hydra_base + (priv->next_pkt << 8));
541 #ifdef HYDRA_DEBUG
542 printk("next_pkt = 0x%x, board_ram_ptr = 0x%x\n", priv->next_pkt, board_ram_ptr);
543 #endif
545 /* the following must be done with two steps, or
546 GCC optimizes it to a byte access to Hydra memory,
547 which doesn't work... */
548 hdr_next_pkt = board_ram_ptr[0];
549 hdr_next_pkt >>= 8;
551 pkt_len = board_ram_ptr[1];
552 pkt_len = ((pkt_len >> 8) | ((pkt_len & 0xff) << 8));
554 #ifdef HYDRA_DEBUG
555 printk("hydra_interrupt(): hdr_next_pkt = 0x%02x, len = %d\n", hdr_next_pkt, pkt_len);
556 #endif
558 if(pkt_len >= ETHER_MIN_LEN && pkt_len <= ETHER_MAX_LEN)
560 /* note that board_ram_ptr is u16 */
561 /* CRC is not included in the packet length */
563 pkt_len -= 4;
564 skb = dev_alloc_skb(pkt_len+2);
565 if(skb == NULL)
567 printk(KERN_INFO "%s: memory squeeze, dropping packet.\n", dev->name);
568 priv->stats.rx_dropped++;
570 else
572 skb->dev = dev;
573 skb_reserve(skb, 2);
574 if(hdr_next_pkt < priv->next_pkt && hdr_next_pkt != priv->rx_page_start)
576 /* here, the packet is wrapped */
577 len1 = ((priv->rx_page_stop - priv->next_pkt)<<8)-4;
579 memcpyw((u16 *)skb_put(skb, len1), (u16 *)(board_ram_ptr+2), len1);
580 memcpyw((u16 *)skb_put(skb, pkt_len-len1), (u16 *)(priv->hydra_base+(priv->rx_page_start<<8)), pkt_len-len1);
582 #ifdef HYDRA_DEBUG
583 printk("wrapped packet: %d/%d bytes\n", len1, pkt_len-len1);
584 #endif
585 } /* ... here, packet is not wrapped */
586 else
587 memcpyw((u16 *) skb_put(skb, pkt_len), (u16 *)(board_ram_ptr+2), pkt_len);
590 else
592 WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA);
593 printk("hydra_interrupt(): invalid packet len: %d, NIC_CURR = %02x\n", pkt_len, READ_REG(NIC_CURR));
595 this is the error i kept getting until i switched to 0.9.10. it still doesn't
596 mean that the bug would have gone away - so be alarmed. the packet is likely
597 being fetched from a wrong memory location - but why - dunno
599 note-for-v2.1: not really problem anymore. hasn't been for a long time.
602 WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
603 /* should probably reset the NIC here ?? */
605 hydra_open(dev); /* FIXME - i shouldn't really be doing this. */
606 return;
609 /* now, update the next_pkt pointer */
610 if(hdr_next_pkt < priv->rx_page_stop)
611 priv->next_pkt = hdr_next_pkt;
612 else
613 printk("hydra_interrupt(): invalid next_pkt pointer %d\n", hdr_next_pkt);
615 /* update the boundary pointer */
616 boundary = priv->next_pkt - 1;
617 if(boundary < priv->rx_page_start)
618 boundary = priv->rx_page_stop - 1;
620 /* set NIC to page 0 to update the NIC_BNDRY register */
621 WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
622 WRITE_REG(NIC_BNDRY, boundary);
624 /* select page1 to access the NIC_CURR register */
625 WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA);
628 skb->protocol = eth_type_trans(skb, dev);
629 netif_rx(skb);
630 priv->stats.rx_packets++;
633 return;
637 static struct net_device_stats *hydra_get_stats(struct net_device *dev)
639 struct hydra_private *priv = (struct hydra_private *)dev->priv;
640 #if 0
641 u8 *board = priv->hydra_base;
643 short saved_addr;
644 #endif
645 /* currently does nothing :) i'll finish this later */
647 return(&priv->stats);
650 #ifdef HAVE_MULTICAST
651 static void set_multicast_list(struct net_device *dev, int num_addrs, void *addrs)
653 struct hydra_private *priv = (struct hydra_private *)dev->priv;
654 u8 *board = priv->hydra_base;
656 /* yes, this code is also waiting for someone to complete.. :) */
657 /* (personally i don't care about multicasts at all :) */
658 return;
660 #endif
663 #ifdef MODULE
664 static char devicename[9] = { 0, };
666 static struct net_device hydra_dev =
668 devicename, /* filled in by register_netdev() */
669 0, 0, 0, 0, /* memory */
670 0, 0, /* base, irq */
671 0, 0, 0, NULL, hydra_probe,
674 int init_module(void)
676 int err;
678 if ((err = register_netdev(&hydra_dev))) {
679 if (err == -EIO)
680 printk("No Hydra board found. Module not loaded.\n");
681 return(err);
683 return(0);
686 void cleanup_module(void)
688 struct hydra_private *priv = (struct hydra_private *)hydra_dev.priv;
690 unregister_netdev(&hydra_dev);
691 zorro_unconfig_board(priv->key, 0);
692 kfree(priv);
695 #endif /* MODULE */