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