[NET] drivers/net: statistics cleanup #1 -- save memory and shrink code
[pv_ops_mirror.git] / drivers / net / seeq8005.c
blob8ef94028cba5fda979e4673ae5e813880d67e0b7
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.
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";
21 Sources:
22 SEEQ 8005 databook
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
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>
51 #include <asm/system.h>
52 #include <asm/io.h>
53 #include <asm/dma.h>
55 #include "seeq8005.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 */
63 #ifndef NET_DEBUG
64 #define NET_DEBUG 1
65 #endif
66 static unsigned int net_debug = NET_DEBUG;
68 /* Information that need to be kept for each board. */
69 struct net_local {
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. */
75 #define SA_ADDR0 0x00
76 #define SA_ADDR1 0x80
77 #define SA_ADDR2 0x4b
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;
103 static int irq = 10;
105 struct net_device * __init seeq8005_probe(int unit)
107 struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
108 unsigned *port;
109 int err = 0;
111 if (!dev)
112 return ERR_PTR(-ENODEV);
114 if (unit >= 0) {
115 sprintf(dev->name, "eth%d", unit);
116 netdev_boot_setup_check(dev);
117 io = dev->base_addr;
118 irq = dev->irq;
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. */
124 err = -ENXIO;
125 } else {
126 for (port = seeq8005_portlist; *port; port++) {
127 if (seeq8005_probe1(dev, *port) == 0)
128 break;
130 if (!*port)
131 err = -ENODEV;
133 if (err)
134 goto out;
135 err = register_netdev(dev);
136 if (err)
137 goto out1;
138 return dev;
139 out1:
140 release_region(dev->base_addr, SEEQ8005_IO_EXTENT);
141 out:
142 free_netdev(dev);
143 return ERR_PTR(err);
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;
153 int i,j;
154 unsigned char SA_prom[32];
155 int old_cfg1;
156 int old_cfg2;
157 int old_stat;
158 int old_dmaar;
159 int old_rear;
160 int retval;
162 if (!request_region(ioaddr, SEEQ8005_IO_EXTENT, "seeq8005"))
163 return -ENODEV;
165 if (net_debug>1)
166 printk("seeq8005: probing at 0x%x\n",ioaddr);
168 old_stat = inw(SEEQ_STATUS); /* read status register */
169 if (old_stat == 0xffff) {
170 retval = -ENODEV;
171 goto out; /* assume that 0xffff == no device */
173 if ( (old_stat & 0x1800) != 0x1800 ) { /* assume that unused bits are 1, as my manual says */
174 if (net_debug>1) {
175 printk("seeq8005: reserved stat bits != 0x1800\n");
176 printk(" == 0x%04x\n",old_stat);
178 retval = -ENODEV;
179 goto out;
182 old_rear = inw(SEEQ_REA);
183 if (old_rear == 0xffff) {
184 outw(0,SEEQ_REA);
185 if (inw(SEEQ_REA) == 0xffff) { /* assume that 0xffff == no device */
186 retval = -ENODEV;
187 goto out;
189 } else if ((old_rear & 0xff00) != 0xff00) { /* assume that unused bits are 1 */
190 if (net_debug>1) {
191 printk("seeq8005: unused rear bits != 0xff00\n");
192 printk(" == 0x%04x\n",old_rear);
194 retval = -ENODEV;
195 goto out;
198 old_cfg2 = inw(SEEQ_CFG2); /* read CFG2 register */
199 old_cfg1 = inw(SEEQ_CFG1);
200 old_dmaar = inw(SEEQ_DMAAR);
202 if (net_debug>4) {
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 */
215 j=0;
216 for(i=0; i <32; i++) {
217 j+= SA_prom[i] = inw(SEEQ_BUFFER) & 0xff;
220 #if 0
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);
229 retval = -ENODEV;
230 goto out;
232 #endif
234 outw( SEEQCFG2_RESET, SEEQ_CFG2); /* reset the card */
235 udelay(5);
236 outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
238 if (net_debug) {
239 printk("seeq8005: prom sum = 0x%08x\n",j);
240 for(j=0; j<32; j+=16) {
241 printk("seeq8005: prom %02x: ",j);
242 for(i=0;i<16;i++) {
243 printk("%02x ",SA_prom[j|i]);
245 printk(" ");
246 for(i=0;i<16;i++) {
247 if ((SA_prom[j|i]>31)&&(SA_prom[j|i]<127)) {
248 printk("%c", SA_prom[j|i]);
249 } else {
250 printk(" ");
253 printk("\n");
257 #if 0
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);
271 j=jiffies+HZ;
272 while ( ((inw(SEEQ_STATUS) & SEEQSTAT_FIFO_EMPTY) != SEEQSTAT_FIFO_EMPTY) && time_before(jiffies, j) )
273 mb();
274 outw( 0 , SEEQ_DMAAR);
275 while ( ((inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, j+HZ))
276 mb();
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);
280 j=0;
281 for(i=0;i<32768;i++) {
282 if (inw(SEEQ_BUFFER) != 0x5a5a)
283 j++;
285 if (j) {
286 printk("%i\n",j);
287 } else {
288 printk("ok.\n");
291 #endif
293 if (net_debug && version_printed++ == 0)
294 printk(version);
296 printk("%s: %s found at %#3x, ", dev->name, "seeq8005", ioaddr);
298 /* Fill in the 'dev' fields. */
299 dev->base_addr = ioaddr;
300 dev->irq = irq;
302 /* Retrieve and print the ethernet address. */
303 for (i = 0; i < 6; i++)
304 printk(" %2.2x", dev->dev_addr[i] = SA_prom[i+6]);
306 if (dev->irq == 0xff)
307 ; /* Do nothing: a user-level program will set it. */
308 else if (dev->irq < 2) { /* "Auto-IRQ" */
309 unsigned long cookie = probe_irq_on();
311 outw( SEEQCMD_RX_INT_EN | SEEQCMD_SET_RX_ON | SEEQCMD_SET_RX_OFF, SEEQ_CMD );
313 dev->irq = probe_irq_off(cookie);
315 if (net_debug >= 2)
316 printk(" autoirq is %d\n", dev->irq);
317 } else if (dev->irq == 2)
318 /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
319 * or don't know which one to set.
321 dev->irq = 9;
323 #if 0
325 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", dev);
326 if (irqval) {
327 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
328 dev->irq, irqval);
329 retval = -EAGAIN;
330 goto out;
333 #endif
334 dev->open = seeq8005_open;
335 dev->stop = seeq8005_close;
336 dev->hard_start_xmit = seeq8005_send_packet;
337 dev->tx_timeout = seeq8005_timeout;
338 dev->watchdog_timeo = HZ/20;
339 dev->set_multicast_list = set_multicast_list;
340 dev->flags &= ~IFF_MULTICAST;
342 return 0;
343 out:
344 release_region(ioaddr, SEEQ8005_IO_EXTENT);
345 return retval;
349 /* Open/initialize the board. This is called (in the current kernel)
350 sometime after booting when the 'ifconfig' program is run.
352 This routine should set everything up anew at each open, even
353 registers that "should" only need to be set once at boot, so that
354 there is non-reboot way to recover if something goes wrong.
356 static int seeq8005_open(struct net_device *dev)
358 struct net_local *lp = netdev_priv(dev);
361 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", dev);
362 if (irqval) {
363 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
364 dev->irq, irqval);
365 return -EAGAIN;
369 /* Reset the hardware here. Don't forget to set the station address. */
370 seeq8005_init(dev, 1);
372 lp->open_time = jiffies;
374 netif_start_queue(dev);
375 return 0;
378 static void seeq8005_timeout(struct net_device *dev)
380 int ioaddr = dev->base_addr;
381 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
382 tx_done(dev) ? "IRQ conflict" : "network cable problem");
383 /* Try to restart the adaptor. */
384 seeq8005_init(dev, 1);
385 dev->trans_start = jiffies;
386 netif_wake_queue(dev);
389 static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev)
391 short length = skb->len;
392 unsigned char *buf;
394 if (length < ETH_ZLEN) {
395 if (skb_padto(skb, ETH_ZLEN))
396 return 0;
397 length = ETH_ZLEN;
399 buf = skb->data;
401 /* Block a timer-based transmit from overlapping */
402 netif_stop_queue(dev);
404 hardware_send_packet(dev, buf, length);
405 dev->trans_start = jiffies;
406 dev->stats.tx_bytes += length;
407 dev_kfree_skb (skb);
408 /* You might need to clean up and record Tx statistics here. */
410 return 0;
414 * wait_for_buffer
416 * This routine waits for the SEEQ chip to assert that the FIFO is ready
417 * by checking for a window interrupt, and then clearing it. This has to
418 * occur in the interrupt handler!
420 inline void wait_for_buffer(struct net_device * dev)
422 int ioaddr = dev->base_addr;
423 unsigned long tmp;
424 int status;
426 tmp = jiffies + HZ;
427 while ( ( ((status=inw(SEEQ_STATUS)) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, tmp))
428 cpu_relax();
430 if ( (status & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
431 outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
434 /* The typical workload of the driver:
435 Handle the network interface interrupts. */
436 static irqreturn_t seeq8005_interrupt(int irq, void *dev_id)
438 struct net_device *dev = dev_id;
439 struct net_local *lp;
440 int ioaddr, status, boguscount = 0;
441 int handled = 0;
443 ioaddr = dev->base_addr;
444 lp = netdev_priv(dev);
446 status = inw(SEEQ_STATUS);
447 do {
448 if (net_debug >2) {
449 printk("%s: int, status=0x%04x\n",dev->name,status);
452 if (status & SEEQSTAT_WINDOW_INT) {
453 handled = 1;
454 outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
455 if (net_debug) {
456 printk("%s: window int!\n",dev->name);
459 if (status & SEEQSTAT_TX_INT) {
460 handled = 1;
461 outw( SEEQCMD_TX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
462 dev->stats.tx_packets++;
463 netif_wake_queue(dev); /* Inform upper layers. */
465 if (status & SEEQSTAT_RX_INT) {
466 handled = 1;
467 /* Got a packet(s). */
468 seeq8005_rx(dev);
470 status = inw(SEEQ_STATUS);
471 } while ( (++boguscount < 10) && (status & SEEQSTAT_ANY_INT)) ;
473 if(net_debug>2) {
474 printk("%s: eoi\n",dev->name);
476 return IRQ_RETVAL(handled);
479 /* We have a good packet(s), get it/them out of the buffers. */
480 static void seeq8005_rx(struct net_device *dev)
482 struct net_local *lp = netdev_priv(dev);
483 int boguscount = 10;
484 int pkt_hdr;
485 int ioaddr = dev->base_addr;
487 do {
488 int next_packet;
489 int pkt_len;
490 int i;
491 int status;
493 status = inw(SEEQ_STATUS);
494 outw( lp->receive_ptr, SEEQ_DMAAR);
495 outw(SEEQCMD_FIFO_READ | SEEQCMD_RX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
496 wait_for_buffer(dev);
497 next_packet = ntohs(inw(SEEQ_BUFFER));
498 pkt_hdr = inw(SEEQ_BUFFER);
500 if (net_debug>2) {
501 printk("%s: 0x%04x recv next=0x%04x, hdr=0x%04x\n",dev->name,lp->receive_ptr,next_packet,pkt_hdr);
504 if ((next_packet == 0) || ((pkt_hdr & SEEQPKTH_CHAIN)==0)) { /* Read all the frames? */
505 return; /* Done for now */
508 if ((pkt_hdr & SEEQPKTS_DONE)==0)
509 break;
511 if (next_packet < lp->receive_ptr) {
512 pkt_len = (next_packet + 0x10000 - ((DEFAULT_TEA+1)<<8)) - lp->receive_ptr - 4;
513 } else {
514 pkt_len = next_packet - lp->receive_ptr - 4;
517 if (next_packet < ((DEFAULT_TEA+1)<<8)) { /* is the next_packet address sane? */
518 printk("%s: recv packet ring corrupt, resetting board\n",dev->name);
519 seeq8005_init(dev,1);
520 return;
523 lp->receive_ptr = next_packet;
525 if (net_debug>2) {
526 printk("%s: recv len=0x%04x\n",dev->name,pkt_len);
529 if (pkt_hdr & SEEQPKTS_ANY_ERROR) { /* There was an error. */
530 dev->stats.rx_errors++;
531 if (pkt_hdr & SEEQPKTS_SHORT) dev->stats.rx_frame_errors++;
532 if (pkt_hdr & SEEQPKTS_DRIB) dev->stats.rx_frame_errors++;
533 if (pkt_hdr & SEEQPKTS_OVERSIZE) dev->stats.rx_over_errors++;
534 if (pkt_hdr & SEEQPKTS_CRC_ERR) dev->stats.rx_crc_errors++;
535 /* skip over this packet */
536 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_DMA_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
537 outw( (lp->receive_ptr & 0xff00)>>8, SEEQ_REA);
538 } else {
539 /* Malloc up new buffer. */
540 struct sk_buff *skb;
541 unsigned char *buf;
543 skb = dev_alloc_skb(pkt_len);
544 if (skb == NULL) {
545 printk("%s: Memory squeeze, dropping packet.\n", dev->name);
546 dev->stats.rx_dropped++;
547 break;
549 skb_reserve(skb, 2); /* align data on 16 byte */
550 buf = skb_put(skb,pkt_len);
552 insw(SEEQ_BUFFER, buf, (pkt_len + 1) >> 1);
554 if (net_debug>2) {
555 char * p = buf;
556 printk("%s: recv ",dev->name);
557 for(i=0;i<14;i++) {
558 printk("%02x ",*(p++)&0xff);
560 printk("\n");
563 skb->protocol=eth_type_trans(skb,dev);
564 netif_rx(skb);
565 dev->last_rx = jiffies;
566 dev->stats.rx_packets++;
567 dev->stats.rx_bytes += pkt_len;
569 } while ((--boguscount) && (pkt_hdr & SEEQPKTH_CHAIN));
571 /* If any worth-while packets have been received, netif_rx()
572 has done a mark_bh(NET_BH) for us and will work on them
573 when we get to the bottom-half routine. */
574 return;
577 /* The inverse routine to net_open(). */
578 static int seeq8005_close(struct net_device *dev)
580 struct net_local *lp = netdev_priv(dev);
581 int ioaddr = dev->base_addr;
583 lp->open_time = 0;
585 netif_stop_queue(dev);
587 /* Flush the Tx and disable Rx here. */
588 outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
590 free_irq(dev->irq, dev);
592 /* Update the statistics here. */
594 return 0;
598 /* Set or clear the multicast filter for this adaptor.
599 num_addrs == -1 Promiscuous mode, receive all packets
600 num_addrs == 0 Normal mode, clear multicast list
601 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
602 best-effort filtering.
604 static void set_multicast_list(struct net_device *dev)
607 * I _could_ do up to 6 addresses here, but won't (yet?)
610 #if 0
611 int ioaddr = dev->base_addr;
613 * hmm, not even sure if my matching works _anyway_ - seem to be receiving
614 * _everything_ . . .
617 if (num_addrs) { /* Enable promiscuous mode */
618 outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_ALL, SEEQ_CFG1);
619 dev->flags|=IFF_PROMISC;
620 } else { /* Disable promiscuous mode, use normal mode */
621 outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_BROAD, SEEQ_CFG1);
623 #endif
626 void seeq8005_init(struct net_device *dev, int startp)
628 struct net_local *lp = netdev_priv(dev);
629 int ioaddr = dev->base_addr;
630 int i;
632 outw(SEEQCFG2_RESET, SEEQ_CFG2); /* reset device */
633 udelay(5);
635 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
636 outw( 0, SEEQ_DMAAR); /* load start address into both low and high byte */
637 /* wait_for_buffer(dev); */ /* I think that you only need a wait for memory buffer */
638 outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
640 for(i=0;i<6;i++) { /* set Station address */
641 outb(dev->dev_addr[i], SEEQ_BUFFER);
642 udelay(2);
645 outw( SEEQCFG1_BUFFER_TEA, SEEQ_CFG1); /* set xmit end area pointer to 16K */
646 outb( DEFAULT_TEA, SEEQ_BUFFER); /* this gives us 16K of send buffer and 48K of recv buffer */
648 lp->receive_ptr = (DEFAULT_TEA+1)<<8; /* so we can find our packet_header */
649 outw( lp->receive_ptr, SEEQ_RPR); /* Receive Pointer Register is set to recv buffer memory */
651 outw( 0x00ff, SEEQ_REA); /* Receive Area End */
653 if (net_debug>4) {
654 printk("%s: SA0 = ",dev->name);
656 outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
657 outw( 0, SEEQ_DMAAR);
658 outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
660 for(i=0;i<6;i++) {
661 printk("%02x ",inb(SEEQ_BUFFER));
663 printk("\n");
666 outw( SEEQCFG1_MAC0_EN | SEEQCFG1_MATCH_BROAD | SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
667 outw( SEEQCFG2_AUTO_REA | SEEQCFG2_CTRLO, SEEQ_CFG2);
668 outw( SEEQCMD_SET_RX_ON | SEEQCMD_TX_INT_EN | SEEQCMD_RX_INT_EN, SEEQ_CMD);
670 if (net_debug>4) {
671 int old_cfg1;
672 old_cfg1 = inw(SEEQ_CFG1);
673 printk("%s: stat = 0x%04x\n",dev->name,inw(SEEQ_STATUS));
674 printk("%s: cfg1 = 0x%04x\n",dev->name,old_cfg1);
675 printk("%s: cfg2 = 0x%04x\n",dev->name,inw(SEEQ_CFG2));
676 printk("%s: raer = 0x%04x\n",dev->name,inw(SEEQ_REA));
677 printk("%s: dmaar= 0x%04x\n",dev->name,inw(SEEQ_DMAAR));
683 static void hardware_send_packet(struct net_device * dev, char *buf, int length)
685 int ioaddr = dev->base_addr;
686 int status = inw(SEEQ_STATUS);
687 int transmit_ptr = 0;
688 unsigned long tmp;
690 if (net_debug>4) {
691 printk("%s: send 0x%04x\n",dev->name,length);
694 /* Set FIFO to writemode and set packet-buffer address */
695 outw( SEEQCMD_FIFO_WRITE | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
696 outw( transmit_ptr, SEEQ_DMAAR);
698 /* output SEEQ Packet header barfage */
699 outw( htons(length + 4), SEEQ_BUFFER);
700 outw( SEEQPKTH_XMIT | SEEQPKTH_DATA_FOLLOWS | SEEQPKTH_XMIT_INT_EN, SEEQ_BUFFER );
702 /* blat the buffer */
703 outsw( SEEQ_BUFFER, buf, (length +1) >> 1);
704 /* paranoia !! */
705 outw( 0, SEEQ_BUFFER);
706 outw( 0, SEEQ_BUFFER);
708 /* set address of start of transmit chain */
709 outw( transmit_ptr, SEEQ_TPR);
711 /* drain FIFO */
712 tmp = jiffies;
713 while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && time_before(jiffies, tmp + HZ))
714 mb();
716 /* doit ! */
717 outw( SEEQCMD_WINDOW_INT_ACK | SEEQCMD_SET_TX_ON | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
722 #ifdef MODULE
724 static struct net_device *dev_seeq;
725 MODULE_LICENSE("GPL");
726 module_param(io, int, 0);
727 module_param(irq, int, 0);
728 MODULE_PARM_DESC(io, "SEEQ 8005 I/O base address");
729 MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ number");
731 int __init init_module(void)
733 dev_seeq = seeq8005_probe(-1);
734 if (IS_ERR(dev_seeq))
735 return PTR_ERR(dev_seeq);
736 return 0;
739 void __exit cleanup_module(void)
741 unregister_netdev(dev_seeq);
742 release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT);
743 free_netdev(dev_seeq);
746 #endif /* MODULE */
749 * Local variables:
750 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c skeleton.c"
751 * version-control: t
752 * kept-new-versions: 5
753 * tab-width: 4
754 * End: