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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [net/] [seeq8005.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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