1 /* seeq8005.c: A network driver for linux. */
4 Written 1993-94 by Donald Becker.
5 See the skeleton.c file for further copyright information.
7 This software may be used and distributed according to the terms
8 of the GNU General Public License, incorporated herein by reference.
10 The author may be reached as hamish@zot.apana.org.au
12 This file is a network device driver for the SEEQ 8005 chipset and
13 the Linux operating system.
17 static const char version
[] =
18 "seeq8005.c:v1.00 8/07/95 Hamish Coleman (hamish@zot.apana.org.au)\n";
25 1.00 Public release. cosmetic changes (no warnings now)
26 0.68 Turning per- packet,interrupt debug messages off - testing for release.
27 0.67 timing problems/bad buffer reads seem to be fixed now
28 0.63 *!@$ protocol=eth_type_trans -- now packets flow
33 #include <linux/module.h>
34 #include <linux/kernel.h>
35 #include <linux/types.h>
36 #include <linux/fcntl.h>
37 #include <linux/interrupt.h>
38 #include <linux/ioport.h>
40 #include <linux/slab.h>
41 #include <linux/string.h>
42 #include <linux/init.h>
43 #include <linux/delay.h>
44 #include <linux/errno.h>
45 #include <linux/netdevice.h>
46 #include <linux/etherdevice.h>
47 #include <linux/skbuff.h>
48 #include <linux/bitops.h>
49 #include <linux/jiffies.h>
51 #include <asm/system.h>
57 /* First, a few definitions that the brave might change. */
58 /* A zero-terminated list of I/O addresses to be probed. */
59 static unsigned int seeq8005_portlist
[] __initdata
=
60 { 0x300, 0x320, 0x340, 0x360, 0};
62 /* use 0 for production, 1 for verification, >2 for debug */
66 static unsigned int net_debug
= NET_DEBUG
;
68 /* Information that need to be kept for each board. */
70 unsigned short receive_ptr
; /* What address in packet memory do we expect a recv_pkt_header? */
71 long open_time
; /* Useless example local info. */
74 /* The station (ethernet) address prefix, used for IDing the board. */
79 /* Index to functions, as function prototypes. */
81 static int seeq8005_probe1(struct net_device
*dev
, int ioaddr
);
82 static int seeq8005_open(struct net_device
*dev
);
83 static void seeq8005_timeout(struct net_device
*dev
);
84 static int seeq8005_send_packet(struct sk_buff
*skb
, struct net_device
*dev
);
85 static irqreturn_t
seeq8005_interrupt(int irq
, void *dev_id
);
86 static void seeq8005_rx(struct net_device
*dev
);
87 static int seeq8005_close(struct net_device
*dev
);
88 static void set_multicast_list(struct net_device
*dev
);
90 /* Example routines you must write ;->. */
91 #define tx_done(dev) (inw(SEEQ_STATUS) & SEEQSTAT_TX_ON)
92 static void hardware_send_packet(struct net_device
*dev
, char *buf
, int length
);
93 extern void seeq8005_init(struct net_device
*dev
, int startp
);
94 static inline void wait_for_buffer(struct net_device
*dev
);
97 /* Check for a network adaptor of this type, and return '0' iff one exists.
98 If dev->base_addr == 0, probe all likely locations.
99 If dev->base_addr == 1, always return failure.
102 static int io
= 0x320;
105 struct net_device
* __init
seeq8005_probe(int unit
)
107 struct net_device
*dev
= alloc_etherdev(sizeof(struct net_local
));
112 return ERR_PTR(-ENODEV
);
115 sprintf(dev
->name
, "eth%d", unit
);
116 netdev_boot_setup_check(dev
);
121 if (io
> 0x1ff) { /* Check a single specified location. */
122 err
= seeq8005_probe1(dev
, io
);
123 } else if (io
!= 0) { /* Don't probe at all. */
126 for (port
= seeq8005_portlist
; *port
; port
++) {
127 if (seeq8005_probe1(dev
, *port
) == 0)
135 err
= register_netdev(dev
);
140 release_region(dev
->base_addr
, SEEQ8005_IO_EXTENT
);
146 /* This is the real probe routine. Linux has a history of friendly device
147 probes on the ISA bus. A good device probes avoids doing writes, and
148 verifies that the correct device exists and functions. */
150 static int __init
seeq8005_probe1(struct net_device
*dev
, int ioaddr
)
152 static unsigned version_printed
;
154 unsigned char SA_prom
[32];
162 if (!request_region(ioaddr
, SEEQ8005_IO_EXTENT
, "seeq8005"))
166 printk("seeq8005: probing at 0x%x\n",ioaddr
);
168 old_stat
= inw(SEEQ_STATUS
); /* read status register */
169 if (old_stat
== 0xffff) {
171 goto out
; /* assume that 0xffff == no device */
173 if ( (old_stat
& 0x1800) != 0x1800 ) { /* assume that unused bits are 1, as my manual says */
175 printk("seeq8005: reserved stat bits != 0x1800\n");
176 printk(" == 0x%04x\n",old_stat
);
182 old_rear
= inw(SEEQ_REA
);
183 if (old_rear
== 0xffff) {
185 if (inw(SEEQ_REA
) == 0xffff) { /* assume that 0xffff == no device */
189 } else if ((old_rear
& 0xff00) != 0xff00) { /* assume that unused bits are 1 */
191 printk("seeq8005: unused rear bits != 0xff00\n");
192 printk(" == 0x%04x\n",old_rear
);
198 old_cfg2
= inw(SEEQ_CFG2
); /* read CFG2 register */
199 old_cfg1
= inw(SEEQ_CFG1
);
200 old_dmaar
= inw(SEEQ_DMAAR
);
203 printk("seeq8005: stat = 0x%04x\n",old_stat
);
204 printk("seeq8005: cfg1 = 0x%04x\n",old_cfg1
);
205 printk("seeq8005: cfg2 = 0x%04x\n",old_cfg2
);
206 printk("seeq8005: raer = 0x%04x\n",old_rear
);
207 printk("seeq8005: dmaar= 0x%04x\n",old_dmaar
);
210 outw( SEEQCMD_FIFO_WRITE
| SEEQCMD_SET_ALL_OFF
, SEEQ_CMD
); /* setup for reading PROM */
211 outw( 0, SEEQ_DMAAR
); /* set starting PROM address */
212 outw( SEEQCFG1_BUFFER_PROM
, SEEQ_CFG1
); /* set buffer to look at PROM */
216 for(i
=0; i
<32; i
++) {
217 j
+= SA_prom
[i
] = inw(SEEQ_BUFFER
) & 0xff;
221 /* untested because I only have the one card */
222 if ( (j
&0xff) != 0 ) { /* checksum appears to be 8bit = 0 */
223 if (net_debug
>1) { /* check this before deciding that we have a card */
224 printk("seeq8005: prom sum error\n");
226 outw( old_stat
, SEEQ_STATUS
);
227 outw( old_dmaar
, SEEQ_DMAAR
);
228 outw( old_cfg1
, SEEQ_CFG1
);
234 outw( SEEQCFG2_RESET
, SEEQ_CFG2
); /* reset the card */
236 outw( SEEQCMD_SET_ALL_OFF
, SEEQ_CMD
);
239 printk("seeq8005: prom sum = 0x%08x\n",j
);
240 for(j
=0; j
<32; j
+=16) {
241 printk("seeq8005: prom %02x: ",j
);
243 printk("%02x ",SA_prom
[j
|i
]);
247 if ((SA_prom
[j
|i
]>31)&&(SA_prom
[j
|i
]<127)) {
248 printk("%c", SA_prom
[j
|i
]);
259 * testing the packet buffer memory doesn't work yet
260 * but all other buffer accesses do
261 * - fixing is not a priority
263 if (net_debug
>1) { /* test packet buffer memory */
264 printk("seeq8005: testing packet buffer ... ");
265 outw( SEEQCFG1_BUFFER_BUFFER
, SEEQ_CFG1
);
266 outw( SEEQCMD_FIFO_WRITE
| SEEQCMD_SET_ALL_OFF
, SEEQ_CMD
);
267 outw( 0 , SEEQ_DMAAR
);
268 for(i
=0;i
<32768;i
++) {
269 outw(0x5a5a, SEEQ_BUFFER
);
272 while ( ((inw(SEEQ_STATUS
) & SEEQSTAT_FIFO_EMPTY
) != SEEQSTAT_FIFO_EMPTY
) && time_before(jiffies
, j
) )
274 outw( 0 , SEEQ_DMAAR
);
275 while ( ((inw(SEEQ_STATUS
) & SEEQSTAT_WINDOW_INT
) != SEEQSTAT_WINDOW_INT
) && time_before(jiffies
, j
+HZ
))
277 if ( (inw(SEEQ_STATUS
) & SEEQSTAT_WINDOW_INT
) == SEEQSTAT_WINDOW_INT
)
278 outw( SEEQCMD_WINDOW_INT_ACK
| (inw(SEEQ_STATUS
)& SEEQCMD_INT_MASK
), SEEQ_CMD
);
279 outw( SEEQCMD_FIFO_READ
| SEEQCMD_SET_ALL_OFF
, SEEQ_CMD
);
281 for(i
=0;i
<32768;i
++) {
282 if (inw(SEEQ_BUFFER
) != 0x5a5a)
293 if (net_debug
&& version_printed
++ == 0)
296 printk("%s: %s found at %#3x, ", dev
->name
, "seeq8005", ioaddr
);
298 /* Fill in the 'dev' fields. */
299 dev
->base_addr
= ioaddr
;
302 /* Retrieve and print the ethernet address. */
303 for (i
= 0; i
< 6; i
++)
304 dev
->dev_addr
[i
] = SA_prom
[i
+6];
305 printk("%pM", dev
->dev_addr
);
307 if (dev
->irq
== 0xff)
308 ; /* Do nothing: a user-level program will set it. */
309 else if (dev
->irq
< 2) { /* "Auto-IRQ" */
310 unsigned long cookie
= probe_irq_on();
312 outw( SEEQCMD_RX_INT_EN
| SEEQCMD_SET_RX_ON
| SEEQCMD_SET_RX_OFF
, SEEQ_CMD
);
314 dev
->irq
= probe_irq_off(cookie
);
317 printk(" autoirq is %d\n", dev
->irq
);
318 } else if (dev
->irq
== 2)
319 /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
320 * or don't know which one to set.
326 int irqval
= request_irq(dev
->irq
, &seeq8005_interrupt
, 0, "seeq8005", dev
);
328 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev
->name
,
335 dev
->open
= seeq8005_open
;
336 dev
->stop
= seeq8005_close
;
337 dev
->hard_start_xmit
= seeq8005_send_packet
;
338 dev
->tx_timeout
= seeq8005_timeout
;
339 dev
->watchdog_timeo
= HZ
/20;
340 dev
->set_multicast_list
= set_multicast_list
;
341 dev
->flags
&= ~IFF_MULTICAST
;
345 release_region(ioaddr
, SEEQ8005_IO_EXTENT
);
350 /* Open/initialize the board. This is called (in the current kernel)
351 sometime after booting when the 'ifconfig' program is run.
353 This routine should set everything up anew at each open, even
354 registers that "should" only need to be set once at boot, so that
355 there is non-reboot way to recover if something goes wrong.
357 static int seeq8005_open(struct net_device
*dev
)
359 struct net_local
*lp
= netdev_priv(dev
);
362 int irqval
= request_irq(dev
->irq
, &seeq8005_interrupt
, 0, "seeq8005", dev
);
364 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev
->name
,
370 /* Reset the hardware here. Don't forget to set the station address. */
371 seeq8005_init(dev
, 1);
373 lp
->open_time
= jiffies
;
375 netif_start_queue(dev
);
379 static void seeq8005_timeout(struct net_device
*dev
)
381 int ioaddr
= dev
->base_addr
;
382 printk(KERN_WARNING
"%s: transmit timed out, %s?\n", dev
->name
,
383 tx_done(dev
) ? "IRQ conflict" : "network cable problem");
384 /* Try to restart the adaptor. */
385 seeq8005_init(dev
, 1);
386 dev
->trans_start
= jiffies
;
387 netif_wake_queue(dev
);
390 static int seeq8005_send_packet(struct sk_buff
*skb
, struct net_device
*dev
)
392 short length
= skb
->len
;
395 if (length
< ETH_ZLEN
) {
396 if (skb_padto(skb
, ETH_ZLEN
))
402 /* Block a timer-based transmit from overlapping */
403 netif_stop_queue(dev
);
405 hardware_send_packet(dev
, buf
, length
);
406 dev
->trans_start
= jiffies
;
407 dev
->stats
.tx_bytes
+= length
;
409 /* You might need to clean up and record Tx statistics here. */
417 * This routine waits for the SEEQ chip to assert that the FIFO is ready
418 * by checking for a window interrupt, and then clearing it. This has to
419 * occur in the interrupt handler!
421 inline void wait_for_buffer(struct net_device
* dev
)
423 int ioaddr
= dev
->base_addr
;
428 while ( ( ((status
=inw(SEEQ_STATUS
)) & SEEQSTAT_WINDOW_INT
) != SEEQSTAT_WINDOW_INT
) && time_before(jiffies
, tmp
))
431 if ( (status
& SEEQSTAT_WINDOW_INT
) == SEEQSTAT_WINDOW_INT
)
432 outw( SEEQCMD_WINDOW_INT_ACK
| (status
& SEEQCMD_INT_MASK
), SEEQ_CMD
);
435 /* The typical workload of the driver:
436 Handle the network interface interrupts. */
437 static irqreturn_t
seeq8005_interrupt(int irq
, void *dev_id
)
439 struct net_device
*dev
= dev_id
;
440 struct net_local
*lp
;
441 int ioaddr
, status
, boguscount
= 0;
444 ioaddr
= dev
->base_addr
;
445 lp
= netdev_priv(dev
);
447 status
= inw(SEEQ_STATUS
);
450 printk("%s: int, status=0x%04x\n",dev
->name
,status
);
453 if (status
& SEEQSTAT_WINDOW_INT
) {
455 outw( SEEQCMD_WINDOW_INT_ACK
| (status
& SEEQCMD_INT_MASK
), SEEQ_CMD
);
457 printk("%s: window int!\n",dev
->name
);
460 if (status
& SEEQSTAT_TX_INT
) {
462 outw( SEEQCMD_TX_INT_ACK
| (status
& SEEQCMD_INT_MASK
), SEEQ_CMD
);
463 dev
->stats
.tx_packets
++;
464 netif_wake_queue(dev
); /* Inform upper layers. */
466 if (status
& SEEQSTAT_RX_INT
) {
468 /* Got a packet(s). */
471 status
= inw(SEEQ_STATUS
);
472 } while ( (++boguscount
< 10) && (status
& SEEQSTAT_ANY_INT
)) ;
475 printk("%s: eoi\n",dev
->name
);
477 return IRQ_RETVAL(handled
);
480 /* We have a good packet(s), get it/them out of the buffers. */
481 static void seeq8005_rx(struct net_device
*dev
)
483 struct net_local
*lp
= netdev_priv(dev
);
486 int ioaddr
= dev
->base_addr
;
494 status
= inw(SEEQ_STATUS
);
495 outw( lp
->receive_ptr
, SEEQ_DMAAR
);
496 outw(SEEQCMD_FIFO_READ
| SEEQCMD_RX_INT_ACK
| (status
& SEEQCMD_INT_MASK
), SEEQ_CMD
);
497 wait_for_buffer(dev
);
498 next_packet
= ntohs(inw(SEEQ_BUFFER
));
499 pkt_hdr
= inw(SEEQ_BUFFER
);
502 printk("%s: 0x%04x recv next=0x%04x, hdr=0x%04x\n",dev
->name
,lp
->receive_ptr
,next_packet
,pkt_hdr
);
505 if ((next_packet
== 0) || ((pkt_hdr
& SEEQPKTH_CHAIN
)==0)) { /* Read all the frames? */
506 return; /* Done for now */
509 if ((pkt_hdr
& SEEQPKTS_DONE
)==0)
512 if (next_packet
< lp
->receive_ptr
) {
513 pkt_len
= (next_packet
+ 0x10000 - ((DEFAULT_TEA
+1)<<8)) - lp
->receive_ptr
- 4;
515 pkt_len
= next_packet
- lp
->receive_ptr
- 4;
518 if (next_packet
< ((DEFAULT_TEA
+1)<<8)) { /* is the next_packet address sane? */
519 printk("%s: recv packet ring corrupt, resetting board\n",dev
->name
);
520 seeq8005_init(dev
,1);
524 lp
->receive_ptr
= next_packet
;
527 printk("%s: recv len=0x%04x\n",dev
->name
,pkt_len
);
530 if (pkt_hdr
& SEEQPKTS_ANY_ERROR
) { /* There was an error. */
531 dev
->stats
.rx_errors
++;
532 if (pkt_hdr
& SEEQPKTS_SHORT
) dev
->stats
.rx_frame_errors
++;
533 if (pkt_hdr
& SEEQPKTS_DRIB
) dev
->stats
.rx_frame_errors
++;
534 if (pkt_hdr
& SEEQPKTS_OVERSIZE
) dev
->stats
.rx_over_errors
++;
535 if (pkt_hdr
& SEEQPKTS_CRC_ERR
) dev
->stats
.rx_crc_errors
++;
536 /* skip over this packet */
537 outw( SEEQCMD_FIFO_WRITE
| SEEQCMD_DMA_INT_ACK
| (status
& SEEQCMD_INT_MASK
), SEEQ_CMD
);
538 outw( (lp
->receive_ptr
& 0xff00)>>8, SEEQ_REA
);
540 /* Malloc up new buffer. */
544 skb
= dev_alloc_skb(pkt_len
);
546 printk("%s: Memory squeeze, dropping packet.\n", dev
->name
);
547 dev
->stats
.rx_dropped
++;
550 skb_reserve(skb
, 2); /* align data on 16 byte */
551 buf
= skb_put(skb
,pkt_len
);
553 insw(SEEQ_BUFFER
, buf
, (pkt_len
+ 1) >> 1);
557 printk("%s: recv ",dev
->name
);
559 printk("%02x ",*(p
++)&0xff);
564 skb
->protocol
=eth_type_trans(skb
,dev
);
566 dev
->last_rx
= jiffies
;
567 dev
->stats
.rx_packets
++;
568 dev
->stats
.rx_bytes
+= pkt_len
;
570 } while ((--boguscount
) && (pkt_hdr
& SEEQPKTH_CHAIN
));
572 /* If any worth-while packets have been received, netif_rx()
573 has done a mark_bh(NET_BH) for us and will work on them
574 when we get to the bottom-half routine. */
578 /* The inverse routine to net_open(). */
579 static int seeq8005_close(struct net_device
*dev
)
581 struct net_local
*lp
= netdev_priv(dev
);
582 int ioaddr
= dev
->base_addr
;
586 netif_stop_queue(dev
);
588 /* Flush the Tx and disable Rx here. */
589 outw( SEEQCMD_SET_ALL_OFF
, SEEQ_CMD
);
591 free_irq(dev
->irq
, dev
);
593 /* Update the statistics here. */
599 /* Set or clear the multicast filter for this adaptor.
600 num_addrs == -1 Promiscuous mode, receive all packets
601 num_addrs == 0 Normal mode, clear multicast list
602 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
603 best-effort filtering.
605 static void set_multicast_list(struct net_device
*dev
)
608 * I _could_ do up to 6 addresses here, but won't (yet?)
612 int ioaddr
= dev
->base_addr
;
614 * hmm, not even sure if my matching works _anyway_ - seem to be receiving
618 if (num_addrs
) { /* Enable promiscuous mode */
619 outw( (inw(SEEQ_CFG1
) & ~SEEQCFG1_MATCH_MASK
)| SEEQCFG1_MATCH_ALL
, SEEQ_CFG1
);
620 dev
->flags
|=IFF_PROMISC
;
621 } else { /* Disable promiscuous mode, use normal mode */
622 outw( (inw(SEEQ_CFG1
) & ~SEEQCFG1_MATCH_MASK
)| SEEQCFG1_MATCH_BROAD
, SEEQ_CFG1
);
627 void seeq8005_init(struct net_device
*dev
, int startp
)
629 struct net_local
*lp
= netdev_priv(dev
);
630 int ioaddr
= dev
->base_addr
;
633 outw(SEEQCFG2_RESET
, SEEQ_CFG2
); /* reset device */
636 outw( SEEQCMD_FIFO_WRITE
| SEEQCMD_SET_ALL_OFF
, SEEQ_CMD
);
637 outw( 0, SEEQ_DMAAR
); /* load start address into both low and high byte */
638 /* wait_for_buffer(dev); */ /* I think that you only need a wait for memory buffer */
639 outw( SEEQCFG1_BUFFER_MAC0
, SEEQ_CFG1
);
641 for(i
=0;i
<6;i
++) { /* set Station address */
642 outb(dev
->dev_addr
[i
], SEEQ_BUFFER
);
646 outw( SEEQCFG1_BUFFER_TEA
, SEEQ_CFG1
); /* set xmit end area pointer to 16K */
647 outb( DEFAULT_TEA
, SEEQ_BUFFER
); /* this gives us 16K of send buffer and 48K of recv buffer */
649 lp
->receive_ptr
= (DEFAULT_TEA
+1)<<8; /* so we can find our packet_header */
650 outw( lp
->receive_ptr
, SEEQ_RPR
); /* Receive Pointer Register is set to recv buffer memory */
652 outw( 0x00ff, SEEQ_REA
); /* Receive Area End */
655 printk("%s: SA0 = ",dev
->name
);
657 outw( SEEQCMD_FIFO_READ
| SEEQCMD_SET_ALL_OFF
, SEEQ_CMD
);
658 outw( 0, SEEQ_DMAAR
);
659 outw( SEEQCFG1_BUFFER_MAC0
, SEEQ_CFG1
);
662 printk("%02x ",inb(SEEQ_BUFFER
));
667 outw( SEEQCFG1_MAC0_EN
| SEEQCFG1_MATCH_BROAD
| SEEQCFG1_BUFFER_BUFFER
, SEEQ_CFG1
);
668 outw( SEEQCFG2_AUTO_REA
| SEEQCFG2_CTRLO
, SEEQ_CFG2
);
669 outw( SEEQCMD_SET_RX_ON
| SEEQCMD_TX_INT_EN
| SEEQCMD_RX_INT_EN
, SEEQ_CMD
);
673 old_cfg1
= inw(SEEQ_CFG1
);
674 printk("%s: stat = 0x%04x\n",dev
->name
,inw(SEEQ_STATUS
));
675 printk("%s: cfg1 = 0x%04x\n",dev
->name
,old_cfg1
);
676 printk("%s: cfg2 = 0x%04x\n",dev
->name
,inw(SEEQ_CFG2
));
677 printk("%s: raer = 0x%04x\n",dev
->name
,inw(SEEQ_REA
));
678 printk("%s: dmaar= 0x%04x\n",dev
->name
,inw(SEEQ_DMAAR
));
684 static void hardware_send_packet(struct net_device
* dev
, char *buf
, int length
)
686 int ioaddr
= dev
->base_addr
;
687 int status
= inw(SEEQ_STATUS
);
688 int transmit_ptr
= 0;
692 printk("%s: send 0x%04x\n",dev
->name
,length
);
695 /* Set FIFO to writemode and set packet-buffer address */
696 outw( SEEQCMD_FIFO_WRITE
| (status
& SEEQCMD_INT_MASK
), SEEQ_CMD
);
697 outw( transmit_ptr
, SEEQ_DMAAR
);
699 /* output SEEQ Packet header barfage */
700 outw( htons(length
+ 4), SEEQ_BUFFER
);
701 outw( SEEQPKTH_XMIT
| SEEQPKTH_DATA_FOLLOWS
| SEEQPKTH_XMIT_INT_EN
, SEEQ_BUFFER
);
703 /* blat the buffer */
704 outsw( SEEQ_BUFFER
, buf
, (length
+1) >> 1);
706 outw( 0, SEEQ_BUFFER
);
707 outw( 0, SEEQ_BUFFER
);
709 /* set address of start of transmit chain */
710 outw( transmit_ptr
, SEEQ_TPR
);
714 while ( (((status
=inw(SEEQ_STATUS
)) & SEEQSTAT_FIFO_EMPTY
) == 0) && time_before(jiffies
, tmp
+ HZ
))
718 outw( SEEQCMD_WINDOW_INT_ACK
| SEEQCMD_SET_TX_ON
| (status
& SEEQCMD_INT_MASK
), SEEQ_CMD
);
725 static struct net_device
*dev_seeq
;
726 MODULE_LICENSE("GPL");
727 module_param(io
, int, 0);
728 module_param(irq
, int, 0);
729 MODULE_PARM_DESC(io
, "SEEQ 8005 I/O base address");
730 MODULE_PARM_DESC(irq
, "SEEQ 8005 IRQ number");
732 int __init
init_module(void)
734 dev_seeq
= seeq8005_probe(-1);
735 if (IS_ERR(dev_seeq
))
736 return PTR_ERR(dev_seeq
);
740 void __exit
cleanup_module(void)
742 unregister_netdev(dev_seeq
);
743 release_region(dev_seeq
->base_addr
, SEEQ8005_IO_EXTENT
);
744 free_netdev(dev_seeq
);
751 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c skeleton.c"
753 * kept-new-versions: 5