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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [net/] [at1700.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* at1700.c: A network device driver for  the Allied Telesis AT1700.
2
 
3
        Written 1993-98 by Donald Becker.
4
 
5
        Copyright 1993 United States Government as represented by the
6
        Director, National Security Agency.
7
 
8
        This software may be used and distributed according to the terms
9
        of the GNU Public License, incorporated herein by reference.
10
 
11
        The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
12
        Center of Excellence in Space Data and Information Sciences
13
           Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
14
 
15
        This is a device driver for the Allied Telesis AT1700, which is a
16
        straight-forward Fujitsu MB86965 implementation.
17
 
18
  Sources:
19
    The Fujitsu MB86965 datasheet.
20
 
21
        After the initial version of this driver was written Gerry Sawkins of
22
        ATI provided their EEPROM configuration code header file.
23
    Thanks to NIIBE Yutaka <gniibe@mri.co.jp> for bug fixes.
24
 
25
  Bugs:
26
        The MB86965 has a design flaw that makes all probes unreliable.  Not
27
        only is it difficult to detect, it also moves around in I/O space in
28
        response to inb()s from other device probes!
29
*/
30
 
31
static const char *version =
32
        "at1700.c:v1.15 4/7/98  Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
33
 
34
#include <linux/module.h>
35
 
36
#include <linux/kernel.h>
37
#include <linux/sched.h>
38
#include <linux/types.h>
39
#include <linux/fcntl.h>
40
#include <linux/interrupt.h>
41
#include <linux/ptrace.h>
42
#include <linux/ioport.h>
43
#include <linux/in.h>
44
#include <linux/malloc.h>
45
#include <linux/string.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
 
56
/* Tunable parameters. */
57
 
58
/* When to switch from the 64-entry multicast filter to Rx-all-multicast. */
59
#define MC_FILTERBREAK 64
60
 
61
/* These unusual address orders are used to verify the CONFIG register. */
62
static int at1700_probe_list[] =
63
{0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0};
64
static int fmv18x_probe_list[] =
65
{0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0};
66
 
67
 
68
/* use 0 for production, 1 for verification, >2 for debug */
69
#ifndef NET_DEBUG
70
#define NET_DEBUG 1
71
#endif
72
static unsigned int net_debug = NET_DEBUG;
73
 
74
typedef unsigned char uchar;
75
 
76
/* Information that need to be kept for each board. */
77
struct net_local {
78
        struct enet_statistics stats;
79
        unsigned char mc_filter[8];
80
        uint jumpered:1;                        /* Set iff the board has jumper config. */
81
        uint tx_started:1;                      /* Packets are on the Tx queue. */
82
        uint invalid_irq:1;
83
        uchar tx_queue;                         /* Number of packet on the Tx queue. */
84
        ushort tx_queue_len;            /* Current length of the Tx queue. */
85
};
86
 
87
 
88
/* Offsets from the base address. */
89
#define STATUS                  0
90
#define TX_STATUS               0
91
#define RX_STATUS               1
92
#define TX_INTR                 2               /* Bit-mapped interrupt enable registers. */
93
#define RX_INTR                 3
94
#define TX_MODE                 4
95
#define RX_MODE                 5
96
#define CONFIG_0                6               /* Misc. configuration settings. */
97
#define CONFIG_1                7
98
/* Run-time register bank 2 definitions. */
99
#define DATAPORT                8               /* Word-wide DMA or programmed-I/O dataport. */
100
#define TX_START                10
101
#define MODE13                  13
102
/* Configuration registers only on the '865A/B chips. */
103
#define EEPROM_Ctrl     16
104
#define EEPROM_Data     17
105
#define IOCONFIG                18              /* Either read the jumper, or move the I/O. */
106
#define IOCONFIG1               19
107
#define SAPROM                  20              /* The station address PROM, if no EEPROM. */
108
#define RESET                   31              /* Write to reset some parts of the chip. */
109
#define AT1700_IO_EXTENT        32
110
/* Index to functions, as function prototypes. */
111
 
112
extern int at1700_probe(struct device *dev);
113
 
114
static int at1700_probe1(struct device *dev, int ioaddr);
115
static int read_eeprom(int ioaddr, int location);
116
static int net_open(struct device *dev);
117
static int      net_send_packet(struct sk_buff *skb, struct device *dev);
118
static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
119
static void net_rx(struct device *dev);
120
static int net_close(struct device *dev);
121
static struct enet_statistics *net_get_stats(struct device *dev);
122
static void set_rx_mode(struct device *dev);
123
 
124
 
125
/* Check for a network adaptor of this type, and return '0' iff one exists.
126
   If dev->base_addr == 0, probe all likely locations.
127
   If dev->base_addr == 1, always return failure.
128
   If dev->base_addr == 2, allocate space for the device and return success
129
   (detachable devices only).
130
   */
131
#ifdef HAVE_DEVLIST
132
/* Support for a alternate probe manager, which will eliminate the
133
   boilerplate below. */
134
struct netdev_entry at1700_drv =
135
{"at1700", at1700_probe1, AT1700_IO_EXTENT, at1700_probe_list};
136
#else
137
int
138
at1700_probe(struct device *dev)
139
{
140
        int i;
141
        int base_addr = dev ? dev->base_addr : 0;
142
 
143
        if (base_addr > 0x1ff)          /* Check a single specified location. */
144
                return at1700_probe1(dev, base_addr);
145
        else if (base_addr != 0) /* Don't probe at all. */
146
                return ENXIO;
147
 
148
        for (i = 0; at1700_probe_list[i]; i++) {
149
                int ioaddr = at1700_probe_list[i];
150
                if (check_region(ioaddr, AT1700_IO_EXTENT))
151
                        continue;
152
                if (at1700_probe1(dev, ioaddr) == 0)
153
                        return 0;
154
        }
155
 
156
        return ENODEV;
157
}
158
#endif
159
 
160
/* The Fujitsu datasheet suggests that the NIC be probed for by checking its
161
   "signature", the default bit pattern after a reset.  This *doesn't* work --
162
   there is no way to reset the bus interface without a complete power-cycle!
163
 
164
   It turns out that ATI came to the same conclusion I did: the only thing
165
   that can be done is checking a few bits and then diving right into an
166
   EEPROM read. */
167
 
168
int at1700_probe1(struct device *dev, int ioaddr)
169
{
170
        char fmv_irqmap[4] = {3, 7, 10, 15};
171
        char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
172
        unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0;
173
 
174
        /* Resetting the chip doesn't reset the ISA interface, so don't bother.
175
           That means we have to be careful with the register values we probe for.
176
           */
177
#ifdef notdef
178
        printk("at1700 probe at %#x, eeprom is %4.4x %4.4x %4.4x ctrl %4.4x.\n",
179
                   ioaddr, read_eeprom(ioaddr, 4), read_eeprom(ioaddr, 5),
180
                   read_eeprom(ioaddr, 6), inw(ioaddr + EEPROM_Ctrl));
181
#endif
182
        /* We must check for the EEPROM-config boards first, else accessing
183
           IOCONFIG0 will move the board! */
184
        if (at1700_probe_list[inb(ioaddr + IOCONFIG1) & 0x07] == ioaddr
185
                && read_eeprom(ioaddr, 4) == 0x0000
186
                && (read_eeprom(ioaddr, 5) & 0xff00) == 0xF400)
187
                is_at1700 = 1;
188
        else if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] == ioaddr
189
                && inb(ioaddr + SAPROM    ) == 0x00
190
                && inb(ioaddr + SAPROM + 1) == 0x00
191
                && inb(ioaddr + SAPROM + 2) == 0x0e)
192
                is_fmv18x = 1;
193
        else
194
                return -ENODEV;
195
 
196
        /* Reset the internal state machines. */
197
        outb(0, ioaddr + RESET);
198
 
199
        /* Allocate a new 'dev' if needed. */
200
        if (dev == NULL)
201
                dev = init_etherdev(0, sizeof(struct net_local));
202
 
203
        if (is_at1700)
204
                irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04)
205
                                                   | (read_eeprom(ioaddr, 0)>>14)];
206
        else
207
                irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03];
208
 
209
        /* Grab the region so that we can find another board if the IRQ request
210
           fails. */
211
        request_region(ioaddr, AT1700_IO_EXTENT, dev->name);
212
 
213
        printk("%s: AT1700 found at %#3x, IRQ %d, address ", dev->name,
214
                   ioaddr, irq);
215
 
216
        dev->base_addr = ioaddr;
217
        dev->irq = irq;
218
 
219
        for(i = 0; i < 3; i++) {
220
                unsigned short eeprom_val = read_eeprom(ioaddr, 4+i);
221
                printk("%04x", eeprom_val);
222
                ((unsigned short *)dev->dev_addr)[i] = ntohs(eeprom_val);
223
        }
224
 
225
        /* The EEPROM word 12 bit 0x0400 means use regular 100 ohm 10baseT signals,
226
           rather than 150 ohm shielded twisted pair compensation.
227
           0x0000 == auto-sense the interface
228
           0x0800 == use TP interface
229
           0x1800 == use coax interface
230
           */
231
        {
232
                const char *porttype[] = {"auto-sense", "10baseT", "auto-sense", "10base2"};
233
                ushort setup_value = read_eeprom(ioaddr, 12);
234
 
235
                dev->if_port = setup_value >> 8;
236
                printk(" %s interface.\n", porttype[(dev->if_port>>3) & 3]);
237
        }
238
 
239
        /* Set the station address in bank zero. */
240
        outb(0xe0, ioaddr + CONFIG_1);
241
        for (i = 0; i < 6; i++)
242
                outb(dev->dev_addr[i], ioaddr + 8 + i);
243
 
244
        /* Switch to bank 1 and set the multicast table to accept none. */
245
        outb(0xe4, ioaddr + CONFIG_1);
246
        for (i = 0; i < 8; i++)
247
                outb(0x00, ioaddr + 8 + i);
248
 
249
        /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
250
           bus access, two 4K Tx queues, and disabled Tx and Rx. */
251
        outb(0xda, ioaddr + CONFIG_0);
252
 
253
        /* Switch to bank 2 and lock our I/O address. */
254
        outb(0xe8, ioaddr + CONFIG_1);
255
        outb(dev->if_port, MODE13);
256
 
257
        /* Power-down the chip.  Aren't we green! */
258
        outb(0x00, ioaddr + CONFIG_1);
259
 
260
        if (net_debug)
261
                printk(version);
262
 
263
        /* Initialize the device structure. */
264
        dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
265
        if (dev->priv == NULL)
266
                return -ENOMEM;
267
        memset(dev->priv, 0, sizeof(struct net_local));
268
 
269
        dev->open               = net_open;
270
        dev->stop               = net_close;
271
        dev->hard_start_xmit = net_send_packet;
272
        dev->get_stats  = net_get_stats;
273
        dev->set_multicast_list = &set_rx_mode;
274
 
275
        /* Fill in the fields of 'dev' with ethernet-generic values. */
276
        ether_setup(dev);
277
 
278
        {
279
                struct net_local *lp = (struct net_local *)dev->priv;
280
                lp->jumpered = is_fmv18x;
281
                /* Snarf the interrupt vector now. */
282
                if (request_irq(irq, &net_interrupt, 0, dev->name, dev)) {
283
                        printk ("  AT1700 at %#3x is unusable due to a conflict on"
284
                                        "IRQ %d.\n", ioaddr, irq);
285
                        lp->invalid_irq = 1;
286
                        return 0;
287
                }
288
        }
289
 
290
        return 0;
291
}
292
 
293
 
294
/*  EEPROM_Ctrl bits. */
295
#define EE_SHIFT_CLK    0x40    /* EEPROM shift clock, in reg. 16. */
296
#define EE_CS                   0x20    /* EEPROM chip select, in reg. 16. */
297
#define EE_DATA_WRITE   0x80    /* EEPROM chip data in, in reg. 17. */
298
#define EE_DATA_READ    0x80    /* EEPROM chip data out, in reg. 17. */
299
 
300
/* Delay between EEPROM clock transitions. */
301
#define eeprom_delay()  do {} while (0);
302
 
303
/* The EEPROM commands include the alway-set leading bit. */
304
#define EE_WRITE_CMD    (5 << 6)
305
#define EE_READ_CMD             (6 << 6)
306
#define EE_ERASE_CMD    (7 << 6)
307
 
308
static int read_eeprom(int ioaddr, int location)
309
{
310
        int i;
311
        unsigned short retval = 0;
312
        int ee_addr = ioaddr + EEPROM_Ctrl;
313
        int ee_daddr = ioaddr + EEPROM_Data;
314
        int read_cmd = location | EE_READ_CMD;
315
 
316
        /* Shift the read command bits out. */
317
        for (i = 9; i >= 0; i--) {
318
                short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
319
                outb(EE_CS, ee_addr);
320
                outb(dataval, ee_daddr);
321
                eeprom_delay();
322
                outb(EE_CS | EE_SHIFT_CLK, ee_addr);    /* EEPROM clock tick. */
323
                eeprom_delay();
324
        }
325
        outb(EE_DATA_WRITE, ee_daddr);
326
        for (i = 16; i > 0; i--) {
327
                outb(EE_CS, ee_addr);
328
                eeprom_delay();
329
                outb(EE_CS | EE_SHIFT_CLK, ee_addr);
330
                eeprom_delay();
331
                retval = (retval << 1) | ((inb(ee_daddr) & EE_DATA_READ) ? 1 : 0);
332
        }
333
 
334
        /* Terminate the EEPROM access. */
335
        outb(EE_CS, ee_addr);
336
        eeprom_delay();
337
        outb(EE_SHIFT_CLK, ee_addr);
338
        outb(0, ee_addr);
339
        return retval;
340
}
341
 
342
 
343
 
344
static int net_open(struct device *dev)
345
{
346
        struct net_local *lp = (struct net_local *)dev->priv;
347
        int ioaddr = dev->base_addr;
348
        int i;
349
 
350
        /* Powerup the chip, initialize config register 1, and select bank 0. */
351
        outb(0xe0, ioaddr + CONFIG_1);
352
 
353
        /* Set the station address in bank zero. */
354
        for (i = 0; i < 6; i++)
355
                outb(dev->dev_addr[i], ioaddr + 8 + i);
356
 
357
        /* Switch to bank 1 and set the multicast table to accept none. */
358
        outb(0xe4, ioaddr + CONFIG_1);
359
        for (i = 0; i < 8; i++)
360
                outb(0x00, ioaddr + 8 + i);
361
 
362
        /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
363
           bus access, and two 4K Tx queues. */
364
        outb(0xda, ioaddr + CONFIG_0);
365
 
366
        /* Switch to register bank 2, enable the Rx and Tx. */
367
        outw(0xe85a, ioaddr + CONFIG_0);
368
 
369
        lp->tx_started = 0;
370
        lp->tx_queue = 0;
371
        lp->tx_queue_len = 0;
372
 
373
        /* Turn on Rx interrupts, leave Tx interrupts off until packet Tx. */
374
        outb(0x00, ioaddr + TX_INTR);
375
        outb(0x81, ioaddr + RX_INTR);
376
 
377
        dev->tbusy = 0;
378
        dev->interrupt = 0;
379
        dev->start = 1;
380
 
381
        MOD_INC_USE_COUNT;
382
 
383
        return 0;
384
}
385
 
386
static int
387
net_send_packet(struct sk_buff *skb, struct device *dev)
388
{
389
        struct net_local *lp = (struct net_local *)dev->priv;
390
        int ioaddr = dev->base_addr;
391
 
392
        if (dev->tbusy) {
393
                /* If we get here, some higher level has decided we are broken.
394
                   There should really be a "kick me" function call instead. */
395
                int tickssofar = jiffies - dev->trans_start;
396
                if (tickssofar < 10)
397
                        return 1;
398
                printk("%s: transmit timed out with status %04x, %s?\n", dev->name,
399
                           inw(ioaddr + STATUS), inb(ioaddr + TX_STATUS) & 0x80
400
                           ? "IRQ conflict" : "network cable problem");
401
                printk("%s: timeout registers: %04x %04x %04x %04x %04x %04x %04x %04x.\n",
402
                           dev->name, inw(ioaddr + 0), inw(ioaddr + 2), inw(ioaddr + 4),
403
                           inw(ioaddr + 6), inw(ioaddr + 8), inw(ioaddr + 10),
404
                           inw(ioaddr + 12), inw(ioaddr + 14));
405
                lp->stats.tx_errors++;
406
                /* ToDo: We should try to restart the adaptor... */
407
                outw(0xffff, ioaddr + 24);
408
                outw(0xffff, ioaddr + TX_STATUS);
409
                outw(0xe85a, ioaddr + CONFIG_0);
410
                outw(0x8100, ioaddr + TX_INTR);
411
                dev->tbusy=0;
412
                dev->trans_start = jiffies;
413
                lp->tx_started = 0;
414
                lp->tx_queue = 0;
415
                lp->tx_queue_len = 0;
416
        }
417
 
418
        /* If some higher layer thinks we've missed an tx-done interrupt
419
           we are passed NULL. Caution: dev_tint() handles the cli()/sti()
420
           itself. */
421
        if (skb == NULL) {
422
                dev_tint(dev);
423
                return 0;
424
        }
425
 
426
        /* Block a timer-based transmit from overlapping.  This could better be
427
           done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
428
        if (set_bit(0, (void*)&dev->tbusy) != 0)
429
                printk("%s: Transmitter access conflict.\n", dev->name);
430
        else {
431
                short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
432
                unsigned char *buf = skb->data;
433
 
434
                /* Turn off the possible Tx interrupts. */
435
                outb(0x00, ioaddr + TX_INTR);
436
 
437
                outw(length, ioaddr + DATAPORT);
438
                outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
439
 
440
                lp->tx_queue++;
441
                lp->tx_queue_len += length + 2;
442
 
443
                if (lp->tx_started == 0) {
444
                        /* If the Tx is idle, always trigger a transmit. */
445
                        outb(0x80 | lp->tx_queue, ioaddr + TX_START);
446
                        lp->tx_queue = 0;
447
                        lp->tx_queue_len = 0;
448
                        dev->trans_start = jiffies;
449
                        lp->tx_started = 1;
450
                        dev->tbusy = 0;
451
                } else if (lp->tx_queue_len < 4096 - 1502)
452
                        /* Yes, there is room for one more packet. */
453
                        dev->tbusy = 0;
454
 
455
                /* Turn on Tx interrupts back on. */
456
                outb(0x82, ioaddr + TX_INTR);
457
        }
458
        dev_kfree_skb (skb, FREE_WRITE);
459
 
460
        return 0;
461
}
462
 
463
/* The typical workload of the driver:
464
   Handle the network interface interrupts. */
465
static void
466
net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
467
{
468
        struct device *dev = dev_id;
469
        struct net_local *lp;
470
        int ioaddr, status;
471
 
472
        if (dev == NULL) {
473
                printk ("at1700_interrupt(): irq %d for unknown device.\n", irq);
474
                return;
475
        }
476
        dev->interrupt = 1;
477
 
478
        ioaddr = dev->base_addr;
479
        lp = (struct net_local *)dev->priv;
480
        status = inw(ioaddr + TX_STATUS);
481
        outw(status, ioaddr + TX_STATUS);
482
 
483
        if (net_debug > 4)
484
                printk("%s: Interrupt with status %04x.\n", dev->name, status);
485
        if (status & 0xff00
486
                ||  (inb(ioaddr + RX_MODE) & 0x40) == 0) {                       /* Got a packet(s). */
487
                net_rx(dev);
488
        }
489
        if (status & 0x00ff) {
490
                if (status & 0x80) {
491
                        lp->stats.tx_packets++;
492
                        if (lp->tx_queue) {
493
                                outb(0x80 | lp->tx_queue, ioaddr + TX_START);
494
                                lp->tx_queue = 0;
495
                                lp->tx_queue_len = 0;
496
                                dev->trans_start = jiffies;
497
                                dev->tbusy = 0;
498
                                mark_bh(NET_BH);        /* Inform upper layers. */
499
                        } else {
500
                                lp->tx_started = 0;
501
                                /* Turn on Tx interrupts off. */
502
                                outb(0x00, ioaddr + TX_INTR);
503
                                dev->tbusy = 0;
504
                                mark_bh(NET_BH);        /* Inform upper layers. */
505
                        }
506
                }
507
        }
508
 
509
        dev->interrupt = 0;
510
        return;
511
}
512
 
513
/* We have a good packet(s), get it/them out of the buffers. */
514
static void
515
net_rx(struct device *dev)
516
{
517
        struct net_local *lp = (struct net_local *)dev->priv;
518
        int ioaddr = dev->base_addr;
519
        int boguscount = 5;
520
 
521
        while ((inb(ioaddr + RX_MODE) & 0x40) == 0) {
522
                ushort status = inw(ioaddr + DATAPORT);
523
                ushort pkt_len = inw(ioaddr + DATAPORT);
524
 
525
                if (net_debug > 4)
526
                        printk("%s: Rxing packet mode %02x status %04x.\n",
527
                                   dev->name, inb(ioaddr + RX_MODE), status);
528
#ifndef final_version
529
                if (status == 0) {
530
                        outb(0x05, ioaddr + 14);
531
                        break;
532
                }
533
#endif
534
 
535
                if ((status & 0xF0) != 0x20) {  /* There was an error. */
536
                        lp->stats.rx_errors++;
537
                        if (status & 0x08) lp->stats.rx_length_errors++;
538
                        if (status & 0x04) lp->stats.rx_frame_errors++;
539
                        if (status & 0x02) lp->stats.rx_crc_errors++;
540
                        if (status & 0x01) lp->stats.rx_over_errors++;
541
                } else {
542
                        /* Malloc up new buffer. */
543
                        struct sk_buff *skb;
544
 
545
                        if (pkt_len > 1550) {
546
                                printk("%s: The AT1700 claimed a very large packet, size %d.\n",
547
                                           dev->name, pkt_len);
548
                                /* Prime the FIFO and then flush the packet. */
549
                                inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
550
                                outb(0x05, ioaddr + 14);
551
                                lp->stats.rx_errors++;
552
                                break;
553
                        }
554
                        skb = dev_alloc_skb(pkt_len+3);
555
                        if (skb == NULL) {
556
                                printk("%s: Memory squeeze, dropping packet (len %d).\n",
557
                                           dev->name, pkt_len);
558
                                /* Prime the FIFO and then flush the packet. */
559
                                inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
560
                                outb(0x05, ioaddr + 14);
561
                                lp->stats.rx_dropped++;
562
                                break;
563
                        }
564
                        skb->dev = dev;
565
                        skb_reserve(skb,2);
566
 
567
                        insw(ioaddr + DATAPORT, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
568
                        skb->protocol=eth_type_trans(skb, dev);
569
                        netif_rx(skb);
570
                        lp->stats.rx_packets++;
571
                }
572
                if (--boguscount <= 0)
573
                        break;
574
        }
575
 
576
        /* If any worth-while packets have been received, dev_rint()
577
           has done a mark_bh(NET_BH) for us and will work on them
578
           when we get to the bottom-half routine. */
579
        {
580
                int i;
581
                for (i = 0; i < 20; i++) {
582
                        if ((inb(ioaddr + RX_MODE) & 0x40) == 0x40)
583
                                break;
584
                        inw(ioaddr + DATAPORT);                         /* dummy status read */
585
                        outb(0x05, ioaddr + 14);
586
                }
587
 
588
                if (net_debug > 5)
589
                        printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
590
                                   dev->name, inb(ioaddr + RX_MODE), i);
591
        }
592
        return;
593
}
594
 
595
/* The inverse routine to net_open(). */
596
static int net_close(struct device *dev)
597
{
598
        int ioaddr = dev->base_addr;
599
 
600
        dev->tbusy = 1;
601
        dev->start = 0;
602
 
603
        /* Set configuration register 0 to disable Tx and Rx. */
604
        outb(0xda, ioaddr + CONFIG_0);
605
 
606
        /* No statistic counters on the chip to update. */
607
 
608
        /* Power-down the chip.  Green, green, green! */
609
        outb(0x00, ioaddr + CONFIG_1);
610
 
611
        MOD_DEC_USE_COUNT;
612
 
613
        return 0;
614
}
615
 
616
/* Get the current statistics.
617
   This may be called with the card open or closed.
618
   There are no on-chip counters, so this function is trivial.
619
*/
620
static struct enet_statistics *
621
net_get_stats(struct device *dev)
622
{
623
        struct net_local *lp = (struct net_local *)dev->priv;
624
        return &lp->stats;
625
}
626
 
627
/*
628
  Set the multicast/promiscuous mode for this adaptor.
629
*/
630
 
631
/* The little-endian AUTODIN II ethernet CRC calculation.
632
   N.B. Do not use for bulk data, use a table-based routine instead.
633
   This is common code and should be moved to net/core/crc.c */
634
static unsigned const ethernet_polynomial_le = 0xedb88320U;
635
static inline unsigned ether_crc_le(int length, unsigned char *data)
636
{
637
        unsigned int crc = 0xffffffff;  /* Initial value. */
638
        while(--length >= 0) {
639
                unsigned char current_octet = *data++;
640
                int bit;
641
                for (bit = 8; --bit >= 0; current_octet >>= 1) {
642
                        if ((crc ^ current_octet) & 1) {
643
                                crc >>= 1;
644
                                crc ^= ethernet_polynomial_le;
645
                        } else
646
                                crc >>= 1;
647
                }
648
        }
649
        return crc;
650
}
651
 
652
static void
653
set_rx_mode(struct device *dev)
654
{
655
        int ioaddr = dev->base_addr;
656
        struct net_local *lp = (struct net_local *)dev->priv;
657
        unsigned char mc_filter[8];              /* Multicast hash filter */
658
        long flags;
659
        int i;
660
 
661
        if (dev->flags & IFF_PROMISC) {
662
                /* Unconditionally log net taps. */
663
                printk("%s: Promiscuous mode enabled.\n", dev->name);
664
                memset(mc_filter, 0xff, sizeof(mc_filter));
665
                outb(3, ioaddr + RX_MODE);      /* Enable promiscuous mode */
666
        } else if (dev->mc_count > MC_FILTERBREAK
667
                           ||  (dev->flags & IFF_ALLMULTI)) {
668
                /* Too many to filter perfectly -- accept all multicasts. */
669
                memset(mc_filter, 0xff, sizeof(mc_filter));
670
                outb(2, ioaddr + RX_MODE);      /* Use normal mode. */
671
        } else if (dev->mc_count == 0) {
672
                memset(mc_filter, 0x00, sizeof(mc_filter));
673
                outb(1, ioaddr + RX_MODE);      /* Ignore almost all multicasts. */
674
        } else {
675
                struct dev_mc_list *mclist;
676
                int i;
677
 
678
                memset(mc_filter, 0, sizeof(mc_filter));
679
                for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
680
                         i++, mclist = mclist->next)
681
                        set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26,
682
                                        mc_filter);
683
        }
684
 
685
        save_flags(flags);
686
        cli();
687
        if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
688
                int saved_bank = inw(ioaddr + CONFIG_0);
689
                /* Switch to bank 1 and set the multicast table. */
690
                outw((saved_bank & ~0x0C00) | 0x0480, ioaddr + CONFIG_0);
691
                for (i = 0; i < 8; i++)
692
                        outb(mc_filter[i], ioaddr + 8 + i);
693
                memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));
694
                outw(saved_bank, ioaddr + CONFIG_0);
695
        }
696
        restore_flags(flags);
697
        return;
698
}
699
 
700
#ifdef MODULE
701
static char devicename[9] = { 0, };
702
static struct device dev_at1700 = {
703
        devicename, /* device name is inserted by linux/drivers/net/net_init.c */
704
        0, 0, 0, 0,
705
        0, 0,
706
        0, 0, 0, NULL, at1700_probe };
707
 
708
static int io = 0x260;
709
static int irq = 0;
710
 
711
int init_module(void)
712
{
713
        if (io == 0)
714
                printk("at1700: You should not use auto-probing with insmod!\n");
715
        dev_at1700.base_addr = io;
716
        dev_at1700.irq       = irq;
717
        if (register_netdev(&dev_at1700) != 0) {
718
                printk("at1700: register_netdev() returned non-zero.\n");
719
                return -EIO;
720
        }
721
        return 0;
722
}
723
 
724
void
725
cleanup_module(void)
726
{
727
        unregister_netdev(&dev_at1700);
728
        kfree(dev_at1700.priv);
729
        dev_at1700.priv = NULL;
730
 
731
        /* If we don't do this, we can't re-insmod it later. */
732
        free_irq(dev_at1700.irq, NULL);
733
        release_region(dev_at1700.base_addr, AT1700_IO_EXTENT);
734
}
735
#endif /* MODULE */
736
 
737
/*
738
 * Local variables:
739
 *  compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c at1700.c"
740
 *  alt-compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c at1700.c"
741
 *  tab-width: 4
742
 *  c-basic-offset: 4
743
 *  c-indent-level: 4
744
 * End:
745
 */

powered by: WebSVN 2.1.0

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