OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [net/] [seeq8005.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.