1/* seeq8005.c: A network driver for linux. */
2/*
3	Based on skeleton.c,
4	Written 1993-94 by Donald Becker.
5	See the skeleton.c file for further copyright information.
6
7	This software may be used and distributed according to the terms
8	of the GNU General Public License, incorporated herein by reference.
9
10	The author may be reached as hamish@zot.apana.org.au
11
12	This file is a network device driver for the SEEQ 8005 chipset and
13	the Linux operating system.
14
15*/
16
17static const char version[] =
18	"seeq8005.c:v1.00 8/07/95 Hamish Coleman (hamish@zot.apana.org.au)\n";
19
20/*
21  Sources:
22  	SEEQ 8005 databook
23
24  Version history:
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
29  	0.56	Send working
30  	0.48	Receive working
31*/
32
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>
39#include <linux/in.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>
50
51#include <asm/system.h>
52#include <asm/io.h>
53#include <asm/dma.h>
54
55#include "seeq8005.h"
56
57/* First, a few definitions that the brave might change. */
58/* A zero-terminated list of I/O addresses to be probed. */
59static unsigned int seeq8005_portlist[] __initdata =
60   { 0x300, 0x320, 0x340, 0x360, 0};
61
62/* use 0 for production, 1 for verification, >2 for debug */
63#ifndef NET_DEBUG
64#define NET_DEBUG 1
65#endif
66static unsigned int net_debug = NET_DEBUG;
67
68/* Information that need to be kept for each board. */
69struct net_local {
70	struct net_device_stats stats;
71	unsigned short receive_ptr;		/* What address in packet memory do we expect a recv_pkt_header? */
72	long open_time;				/* Useless example local info. */
73};
74
75/* The station (ethernet) address prefix, used for IDing the board. */
76#define SA_ADDR0 0x00
77#define SA_ADDR1 0x80
78#define SA_ADDR2 0x4b
79
80/* Index to functions, as function prototypes. */
81
82static int seeq8005_probe1(struct net_device *dev, int ioaddr);
83static int seeq8005_open(struct net_device *dev);
84static void seeq8005_timeout(struct net_device *dev);
85static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev);
86static irqreturn_t seeq8005_interrupt(int irq, void *dev_id);
87static void seeq8005_rx(struct net_device *dev);
88static int seeq8005_close(struct net_device *dev);
89static struct net_device_stats *seeq8005_get_stats(struct net_device *dev);
90static void set_multicast_list(struct net_device *dev);
91
92/* Example routines you must write ;->. */
93#define tx_done(dev)	(inw(SEEQ_STATUS) & SEEQSTAT_TX_ON)
94static void hardware_send_packet(struct net_device *dev, char *buf, int length);
95extern void seeq8005_init(struct net_device *dev, int startp);
96static inline void wait_for_buffer(struct net_device *dev);
97
98
99/* Check for a network adaptor of this type, and return '0' iff one exists.
100   If dev->base_addr == 0, probe all likely locations.
101   If dev->base_addr == 1, always return failure.
102   */
103
104static int io = 0x320;
105static int irq = 10;
106
107struct net_device * __init seeq8005_probe(int unit)
108{
109	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
110	unsigned *port;
111	int err = 0;
112
113	if (!dev)
114		return ERR_PTR(-ENODEV);
115
116	if (unit >= 0) {
117		sprintf(dev->name, "eth%d", unit);
118		netdev_boot_setup_check(dev);
119		io = dev->base_addr;
120		irq = dev->irq;
121	}
122
123	if (io > 0x1ff) {	/* Check a single specified location. */
124		err = seeq8005_probe1(dev, io);
125	} else if (io != 0) {	/* Don't probe at all. */
126		err = -ENXIO;
127	} else {
128		for (port = seeq8005_portlist; *port; port++) {
129			if (seeq8005_probe1(dev, *port) == 0)
130				break;
131		}
132		if (!*port)
133			err = -ENODEV;
134	}
135	if (err)
136		goto out;
137	err = register_netdev(dev);
138	if (err)
139		goto out1;
140	return dev;
141out1:
142	release_region(dev->base_addr, SEEQ8005_IO_EXTENT);
143out:
144	free_netdev(dev);
145	return ERR_PTR(err);
146}
147
148/* This is the real probe routine.  Linux has a history of friendly device
149   probes on the ISA bus.  A good device probes avoids doing writes, and
150   verifies that the correct device exists and functions.  */
151
152static int __init seeq8005_probe1(struct net_device *dev, int ioaddr)
153{
154	static unsigned version_printed;
155	int i,j;
156	unsigned char SA_prom[32];
157	int old_cfg1;
158	int old_cfg2;
159	int old_stat;
160	int old_dmaar;
161	int old_rear;
162	int retval;
163
164	if (!request_region(ioaddr, SEEQ8005_IO_EXTENT, "seeq8005"))
165		return -ENODEV;
166
167	if (net_debug>1)
168		printk("seeq8005: probing at 0x%x\n",ioaddr);
169
170	old_stat = inw(SEEQ_STATUS);					/* read status register */
171	if (old_stat == 0xffff) {
172		retval = -ENODEV;
173		goto out;						/* assume that 0xffff == no device */
174	}
175	if ( (old_stat & 0x1800) != 0x1800 ) {				/* assume that unused bits are 1, as my manual says */
176		if (net_debug>1) {
177			printk("seeq8005: reserved stat bits != 0x1800\n");
178			printk("          == 0x%04x\n",old_stat);
179		}
180	 	retval = -ENODEV;
181		goto out;
182	}
183
184	old_rear = inw(SEEQ_REA);
185	if (old_rear == 0xffff) {
186		outw(0,SEEQ_REA);
187		if (inw(SEEQ_REA) == 0xffff) {				/* assume that 0xffff == no device */
188			retval = -ENODEV;
189			goto out;
190		}
191	} else if ((old_rear & 0xff00) != 0xff00) {			/* assume that unused bits are 1 */
192		if (net_debug>1) {
193			printk("seeq8005: unused rear bits != 0xff00\n");
194			printk("          == 0x%04x\n",old_rear);
195		}
196		retval = -ENODEV;
197		goto out;
198	}
199
200	old_cfg2 = inw(SEEQ_CFG2);					/* read CFG2 register */
201	old_cfg1 = inw(SEEQ_CFG1);
202	old_dmaar = inw(SEEQ_DMAAR);
203
204	if (net_debug>4) {
205		printk("seeq8005: stat = 0x%04x\n",old_stat);
206		printk("seeq8005: cfg1 = 0x%04x\n",old_cfg1);
207		printk("seeq8005: cfg2 = 0x%04x\n",old_cfg2);
208		printk("seeq8005: raer = 0x%04x\n",old_rear);
209		printk("seeq8005: dmaar= 0x%04x\n",old_dmaar);
210	}
211
212	outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);	/* setup for reading PROM */
213	outw( 0, SEEQ_DMAAR);						/* set starting PROM address */
214	outw( SEEQCFG1_BUFFER_PROM, SEEQ_CFG1);				/* set buffer to look at PROM */
215
216
217	j=0;
218	for(i=0; i <32; i++) {
219		j+= SA_prom[i] = inw(SEEQ_BUFFER) & 0xff;
220	}
221
222
223	outw( SEEQCFG2_RESET, SEEQ_CFG2);				/* reset the card */
224	udelay(5);
225	outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
226
227	if (net_debug) {
228		printk("seeq8005: prom sum = 0x%08x\n",j);
229		for(j=0; j<32; j+=16) {
230			printk("seeq8005: prom %02x: ",j);
231			for(i=0;i<16;i++) {
232				printk("%02x ",SA_prom[j|i]);
233			}
234			printk(" ");
235			for(i=0;i<16;i++) {
236				if ((SA_prom[j|i]>31)&&(SA_prom[j|i]<127)) {
237					printk("%c", SA_prom[j|i]);
238				} else {
239					printk(" ");
240				}
241			}
242			printk("\n");
243		}
244	}
245
246
247	if (net_debug  &&  version_printed++ == 0)
248		printk(version);
249
250	printk("%s: %s found at %#3x, ", dev->name, "seeq8005", ioaddr);
251
252	/* Fill in the 'dev' fields. */
253	dev->base_addr = ioaddr;
254	dev->irq = irq;
255
256	/* Retrieve and print the ethernet address. */
257	for (i = 0; i < 6; i++)
258		printk(" %2.2x", dev->dev_addr[i] = SA_prom[i+6]);
259
260	if (dev->irq == 0xff)
261		;			/* Do nothing: a user-level program will set it. */
262	else if (dev->irq < 2) {	/* "Auto-IRQ" */
263		unsigned long cookie = probe_irq_on();
264
265		outw( SEEQCMD_RX_INT_EN | SEEQCMD_SET_RX_ON | SEEQCMD_SET_RX_OFF, SEEQ_CMD );
266
267		dev->irq = probe_irq_off(cookie);
268
269		if (net_debug >= 2)
270			printk(" autoirq is %d\n", dev->irq);
271	} else if (dev->irq == 2)
272	  /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
273	   * or don't know which one to set.
274	   */
275	  dev->irq = 9;
276
277	dev->open		= seeq8005_open;
278	dev->stop		= seeq8005_close;
279	dev->hard_start_xmit 	= seeq8005_send_packet;
280	dev->tx_timeout		= seeq8005_timeout;
281	dev->watchdog_timeo	= HZ/20;
282	dev->get_stats		= seeq8005_get_stats;
283	dev->set_multicast_list = set_multicast_list;
284	dev->flags &= ~IFF_MULTICAST;
285
286	return 0;
287out:
288	release_region(ioaddr, SEEQ8005_IO_EXTENT);
289	return retval;
290}
291
292
293/* Open/initialize the board.  This is called (in the current kernel)
294   sometime after booting when the 'ifconfig' program is run.
295
296   This routine should set everything up anew at each open, even
297   registers that "should" only need to be set once at boot, so that
298   there is non-reboot way to recover if something goes wrong.
299   */
300static int seeq8005_open(struct net_device *dev)
301{
302	struct net_local *lp = netdev_priv(dev);
303
304	{
305		 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", dev);
306		 if (irqval) {
307			 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
308					 dev->irq, irqval);
309			 return -EAGAIN;
310		 }
311	}
312
313	/* Reset the hardware here.  Don't forget to set the station address. */
314	seeq8005_init(dev, 1);
315
316	lp->open_time = jiffies;
317
318	netif_start_queue(dev);
319	return 0;
320}
321
322static void seeq8005_timeout(struct net_device *dev)
323{
324	int ioaddr = dev->base_addr;
325	printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
326		   tx_done(dev) ? "IRQ conflict" : "network cable problem");
327	/* Try to restart the adaptor. */
328	seeq8005_init(dev, 1);
329	dev->trans_start = jiffies;
330	netif_wake_queue(dev);
331}
332
333static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev)
334{
335	struct net_local *lp = netdev_priv(dev);
336	short length = skb->len;
337	unsigned char *buf;
338
339	if (length < ETH_ZLEN) {
340		if (skb_padto(skb, ETH_ZLEN))
341			return 0;
342		length = ETH_ZLEN;
343	}
344	buf = skb->data;
345
346	/* Block a timer-based transmit from overlapping */
347	netif_stop_queue(dev);
348
349	hardware_send_packet(dev, buf, length);
350	dev->trans_start = jiffies;
351	lp->stats.tx_bytes += length;
352	dev_kfree_skb (skb);
353	/* You might need to clean up and record Tx statistics here. */
354
355	return 0;
356}
357
358/*
359 * wait_for_buffer
360 *
361 * This routine waits for the SEEQ chip to assert that the FIFO is ready
362 * by checking for a window interrupt, and then clearing it. This has to
363 * occur in the interrupt handler!
364 */
365inline void wait_for_buffer(struct net_device * dev)
366{
367	int ioaddr = dev->base_addr;
368	unsigned long tmp;
369	int status;
370
371	tmp = jiffies + HZ;
372	while ( ( ((status=inw(SEEQ_STATUS)) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, tmp))
373		cpu_relax();
374
375	if ( (status & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
376		outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
377}
378
379/* The typical workload of the driver:
380   Handle the network interface interrupts. */
381static irqreturn_t seeq8005_interrupt(int irq, void *dev_id)
382{
383	struct net_device *dev = dev_id;
384	struct net_local *lp;
385	int ioaddr, status, boguscount = 0;
386	int handled = 0;
387
388	ioaddr = dev->base_addr;
389	lp = netdev_priv(dev);
390
391	status = inw(SEEQ_STATUS);
392	do {
393		if (net_debug >2) {
394			printk("%s: int, status=0x%04x\n",dev->name,status);
395		}
396
397		if (status & SEEQSTAT_WINDOW_INT) {
398			handled = 1;
399			outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
400			if (net_debug) {
401				printk("%s: window int!\n",dev->name);
402			}
403		}
404		if (status & SEEQSTAT_TX_INT) {
405			handled = 1;
406			outw( SEEQCMD_TX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
407			lp->stats.tx_packets++;
408			netif_wake_queue(dev);	/* Inform upper layers. */
409		}
410		if (status & SEEQSTAT_RX_INT) {
411			handled = 1;
412			/* Got a packet(s). */
413			seeq8005_rx(dev);
414		}
415		status = inw(SEEQ_STATUS);
416	} while ( (++boguscount < 10) && (status & SEEQSTAT_ANY_INT)) ;
417
418	if(net_debug>2) {
419		printk("%s: eoi\n",dev->name);
420	}
421	return IRQ_RETVAL(handled);
422}
423
424/* We have a good packet(s), get it/them out of the buffers. */
425static void seeq8005_rx(struct net_device *dev)
426{
427	struct net_local *lp = netdev_priv(dev);
428	int boguscount = 10;
429	int pkt_hdr;
430	int ioaddr = dev->base_addr;
431
432	do {
433		int next_packet;
434		int pkt_len;
435		int i;
436		int status;
437
438		status = inw(SEEQ_STATUS);
439	  	outw( lp->receive_ptr, SEEQ_DMAAR);
440		outw(SEEQCMD_FIFO_READ | SEEQCMD_RX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
441	  	wait_for_buffer(dev);
442	  	next_packet = ntohs(inw(SEEQ_BUFFER));
443	  	pkt_hdr = inw(SEEQ_BUFFER);
444
445		if (net_debug>2) {
446			printk("%s: 0x%04x recv next=0x%04x, hdr=0x%04x\n",dev->name,lp->receive_ptr,next_packet,pkt_hdr);
447		}
448
449		if ((next_packet == 0) || ((pkt_hdr & SEEQPKTH_CHAIN)==0)) {	/* Read all the frames? */
450			return;							/* Done for now */
451		}
452
453		if ((pkt_hdr & SEEQPKTS_DONE)==0)
454			break;
455
456		if (next_packet < lp->receive_ptr) {
457			pkt_len = (next_packet + 0x10000 - ((DEFAULT_TEA+1)<<8)) - lp->receive_ptr - 4;
458		} else {
459			pkt_len = next_packet - lp->receive_ptr - 4;
460		}
461
462		if (next_packet < ((DEFAULT_TEA+1)<<8)) {			/* is the next_packet address sane? */
463			printk("%s: recv packet ring corrupt, resetting board\n",dev->name);
464			seeq8005_init(dev,1);
465			return;
466		}
467
468		lp->receive_ptr = next_packet;
469
470		if (net_debug>2) {
471			printk("%s: recv len=0x%04x\n",dev->name,pkt_len);
472		}
473
474		if (pkt_hdr & SEEQPKTS_ANY_ERROR) {				/* There was an error. */
475			lp->stats.rx_errors++;
476			if (pkt_hdr & SEEQPKTS_SHORT) lp->stats.rx_frame_errors++;
477			if (pkt_hdr & SEEQPKTS_DRIB) lp->stats.rx_frame_errors++;
478			if (pkt_hdr & SEEQPKTS_OVERSIZE) lp->stats.rx_over_errors++;
479			if (pkt_hdr & SEEQPKTS_CRC_ERR) lp->stats.rx_crc_errors++;
480			/* skip over this packet */
481			outw( SEEQCMD_FIFO_WRITE | SEEQCMD_DMA_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
482			outw( (lp->receive_ptr & 0xff00)>>8, SEEQ_REA);
483		} else {
484			/* Malloc up new buffer. */
485			struct sk_buff *skb;
486			unsigned char *buf;
487
488			skb = dev_alloc_skb(pkt_len);
489			if (skb == NULL) {
490				printk("%s: Memory squeeze, dropping packet.\n", dev->name);
491				lp->stats.rx_dropped++;
492				break;
493			}
494			skb_reserve(skb, 2);	/* align data on 16 byte */
495			buf = skb_put(skb,pkt_len);
496
497			insw(SEEQ_BUFFER, buf, (pkt_len + 1) >> 1);
498
499			if (net_debug>2) {
500				char * p = buf;
501				printk("%s: recv ",dev->name);
502				for(i=0;i<14;i++) {
503					printk("%02x ",*(p++)&0xff);
504				}
505				printk("\n");
506			}
507
508			skb->protocol=eth_type_trans(skb,dev);
509			netif_rx(skb);
510			dev->last_rx = jiffies;
511			lp->stats.rx_packets++;
512			lp->stats.rx_bytes += pkt_len;
513		}
514	} while ((--boguscount) && (pkt_hdr & SEEQPKTH_CHAIN));
515
516	/* If any worth-while packets have been received, netif_rx()
517	   has done a mark_bh(NET_BH) for us and will work on them
518	   when we get to the bottom-half routine. */
519	return;
520}
521
522/* The inverse routine to net_open(). */
523static int seeq8005_close(struct net_device *dev)
524{
525	struct net_local *lp = netdev_priv(dev);
526	int ioaddr = dev->base_addr;
527
528	lp->open_time = 0;
529
530	netif_stop_queue(dev);
531
532	/* Flush the Tx and disable Rx here. */
533	outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
534
535	free_irq(dev->irq, dev);
536
537	/* Update the statistics here. */
538
539	return 0;
540
541}
542
543/* Get the current statistics.	This may be called with the card open or
544   closed. */
545static struct net_device_stats *seeq8005_get_stats(struct net_device *dev)
546{
547	struct net_local *lp = netdev_priv(dev);
548
549	return &lp->stats;
550}
551
552/* Set or clear the multicast filter for this adaptor.
553   num_addrs == -1	Promiscuous mode, receive all packets
554   num_addrs == 0	Normal mode, clear multicast list
555   num_addrs > 0	Multicast mode, receive normal and MC packets, and do
556			best-effort filtering.
557 */
558static void set_multicast_list(struct net_device *dev)
559{
560/*
561 * I _could_ do up to 6 addresses here, but won't (yet?)
562 */
563
564}
565
566void seeq8005_init(struct net_device *dev, int startp)
567{
568	struct net_local *lp = netdev_priv(dev);
569	int ioaddr = dev->base_addr;
570	int i;
571
572	outw(SEEQCFG2_RESET, SEEQ_CFG2);	/* reset device */
573	udelay(5);
574
575	outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
576	outw( 0, SEEQ_DMAAR);			/* load start address into both low and high byte */
577/*	wait_for_buffer(dev); */		/* I think that you only need a wait for memory buffer */
578	outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
579
580	for(i=0;i<6;i++) {			/* set Station address */
581		outb(dev->dev_addr[i], SEEQ_BUFFER);
582		udelay(2);
583	}
584
585	outw( SEEQCFG1_BUFFER_TEA, SEEQ_CFG1);	/* set xmit end area pointer to 16K */
586	outb( DEFAULT_TEA, SEEQ_BUFFER);	/* this gives us 16K of send buffer and 48K of recv buffer */
587
588	lp->receive_ptr = (DEFAULT_TEA+1)<<8;	/* so we can find our packet_header */
589	outw( lp->receive_ptr, SEEQ_RPR);	/* Receive Pointer Register is set to recv buffer memory */
590
591	outw( 0x00ff, SEEQ_REA);		/* Receive Area End */
592
593	if (net_debug>4) {
594		printk("%s: SA0 = ",dev->name);
595
596		outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
597		outw( 0, SEEQ_DMAAR);
598		outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
599
600		for(i=0;i<6;i++) {
601			printk("%02x ",inb(SEEQ_BUFFER));
602		}
603		printk("\n");
604	}
605
606	outw( SEEQCFG1_MAC0_EN | SEEQCFG1_MATCH_BROAD | SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
607	outw( SEEQCFG2_AUTO_REA | SEEQCFG2_CTRLO, SEEQ_CFG2);
608	outw( SEEQCMD_SET_RX_ON | SEEQCMD_TX_INT_EN | SEEQCMD_RX_INT_EN, SEEQ_CMD);
609
610	if (net_debug>4) {
611		int old_cfg1;
612		old_cfg1 = inw(SEEQ_CFG1);
613		printk("%s: stat = 0x%04x\n",dev->name,inw(SEEQ_STATUS));
614		printk("%s: cfg1 = 0x%04x\n",dev->name,old_cfg1);
615		printk("%s: cfg2 = 0x%04x\n",dev->name,inw(SEEQ_CFG2));
616		printk("%s: raer = 0x%04x\n",dev->name,inw(SEEQ_REA));
617		printk("%s: dmaar= 0x%04x\n",dev->name,inw(SEEQ_DMAAR));
618
619	}
620}
621
622
623static void hardware_send_packet(struct net_device * dev, char *buf, int length)
624{
625	int ioaddr = dev->base_addr;
626	int status = inw(SEEQ_STATUS);
627	int transmit_ptr = 0;
628	unsigned long tmp;
629
630	if (net_debug>4) {
631		printk("%s: send 0x%04x\n",dev->name,length);
632	}
633
634	/* Set FIFO to writemode and set packet-buffer address */
635	outw( SEEQCMD_FIFO_WRITE | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
636	outw( transmit_ptr, SEEQ_DMAAR);
637
638	/* output SEEQ Packet header barfage */
639	outw( htons(length + 4), SEEQ_BUFFER);
640	outw( SEEQPKTH_XMIT | SEEQPKTH_DATA_FOLLOWS | SEEQPKTH_XMIT_INT_EN, SEEQ_BUFFER );
641
642	/* blat the buffer */
643	outsw( SEEQ_BUFFER, buf, (length +1) >> 1);
644	/* paranoia !! */
645	outw( 0, SEEQ_BUFFER);
646	outw( 0, SEEQ_BUFFER);
647
648	/* set address of start of transmit chain */
649	outw( transmit_ptr, SEEQ_TPR);
650
651	/* drain FIFO */
652	tmp = jiffies;
653	while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && time_before(jiffies, tmp + HZ))
654		mb();
655
656	/* doit ! */
657	outw( SEEQCMD_WINDOW_INT_ACK | SEEQCMD_SET_TX_ON | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
658
659}
660
661
662#ifdef MODULE
663
664static struct net_device *dev_seeq;
665MODULE_LICENSE("GPL");
666module_param(io, int, 0);
667module_param(irq, int, 0);
668MODULE_PARM_DESC(io, "SEEQ 8005 I/O base address");
669MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ number");
670
671int __init init_module(void)
672{
673	dev_seeq = seeq8005_probe(-1);
674	if (IS_ERR(dev_seeq))
675		return PTR_ERR(dev_seeq);
676	return 0;
677}
678
679void __exit cleanup_module(void)
680{
681	unregister_netdev(dev_seeq);
682	release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT);
683	free_netdev(dev_seeq);
684}
685
686#endif /* MODULE */
687
688/*
689 * Local variables:
690 *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c skeleton.c"
691 *  version-control: t
692 *  kept-new-versions: 5
693 *  tab-width: 4
694 * End:
695 */
696