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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* znet.c: An Zenith Z-Note ethernet driver for linux. */
2
 
3
static const char *version = "znet.c:v1.02 9/23/94 becker@cesdis.gsfc.nasa.gov\n";
4
 
5
/*
6
        Written by Donald Becker.
7
 
8
        The author may be reached as becker@cesdis.gsfc.nasa.gov.
9
        This driver is based on the Linux skeleton driver.  The copyright of the
10
        skeleton driver is held by the United States Government, as represented
11
        by DIRNSA, and it is released under the GPL.
12
 
13
        Thanks to Mike Hollick for alpha testing and suggestions.
14
 
15
  References:
16
           The Crynwr packet driver.
17
 
18
          "82593 CSMA/CD Core LAN Controller" Intel datasheet, 1992
19
          Intel Microcommunications Databook, Vol. 1, 1990.
20
    As usual with Intel, the documentation is incomplete and inaccurate.
21
        I had to read the Crynwr packet driver to figure out how to actually
22
        use the i82593, and guess at what register bits matched the loosely
23
        related i82586.
24
 
25
                                        Theory of Operation
26
 
27
        The i82593 used in the Zenith Z-Note series operates using two(!) slave
28
        DMA     channels, one interrupt, and one 8-bit I/O port.
29
 
30
        While there     several ways to configure '593 DMA system, I chose the one
31
        that seemed commensurate with the highest system performance in the face
32
        of moderate interrupt latency: Both DMA channels are configured as
33
        recirculating ring buffers, with one channel (#0) dedicated to Rx and
34
        the other channel (#1) to Tx and configuration.  (Note that this is
35
        different than the Crynwr driver, where the Tx DMA channel is initialized
36
        before each operation.  That approach simplifies operation and Tx error
37
        recovery, but requires additional I/O in normal operation and precludes
38
        transmit buffer chaining.)
39
 
40
        Both rings are set to 8192 bytes using {TX,RX}_RING_SIZE.  This provides
41
        a reasonable ring size for Rx, while simplifying DMA buffer allocation --
42
        DMA buffers must not cross a 128K boundary.  (In truth the size selection
43
        was influenced by my lack of '593 documentation.  I thus was constrained
44
        to use the Crynwr '593 initialization table, which sets the Rx ring size
45
        to 8K.)
46
 
47
        Despite my usual low opinion about Intel-designed parts, I must admit
48
        that the bulk data handling of the i82593 is a good design for
49
        an integrated system, like a laptop, where using two slave DMA channels
50
        doesn't pose a problem.  I still take issue with using only a single I/O
51
        port.  In the same controlled environment there are essentially no
52
        limitations on I/O space, and using multiple locations would eliminate
53
        the     need for multiple operations when looking at status registers,
54
        setting the Rx ring boundary, or switching to promiscuous mode.
55
 
56
        I also question Zenith's selection of the '593: one of the advertised
57
        advantages of earlier Intel parts was that if you figured out the magic
58
        initialization incantation you could use the same part on many different
59
        network types.  Zenith's use of the "FriendlyNet" (sic) connector rather
60
        than an on-board transceiver leads me to believe that they were planning
61
        to take advantage of this.  But, uhmmm, the '593 omits all but ethernet
62
        functionality from the serial subsystem.
63
 */
64
 
65
#include <linux/kernel.h>
66
#include <linux/sched.h>
67
#include <linux/string.h>
68
#include <linux/ptrace.h>
69
#include <linux/errno.h>
70
#include <linux/interrupt.h>
71
#include <linux/ioport.h>
72
#include <asm/system.h>
73
#include <asm/bitops.h>
74
#include <asm/io.h>
75
#include <asm/dma.h>
76
 
77
#include <linux/netdevice.h>
78
#include <linux/etherdevice.h>
79
#include <linux/skbuff.h>
80
#include <linux/if_arp.h>
81
 
82
#ifndef ZNET_DEBUG
83
#define ZNET_DEBUG 1
84
#endif
85
static unsigned int znet_debug = ZNET_DEBUG;
86
 
87
/* The DMA modes we need aren't in <dma.h>. */
88
#define DMA_RX_MODE             0x14    /* Auto init, I/O to mem, ++, demand. */
89
#define DMA_TX_MODE             0x18    /* Auto init, Mem to I/O, ++, demand. */
90
#define dma_page_eq(ptr1, ptr2) ((long)(ptr1)>>17 == (long)(ptr2)>>17)
91
#define DMA_BUF_SIZE 8192
92
#define RX_BUF_SIZE 8192
93
#define TX_BUF_SIZE 8192
94
 
95
/* Commands to the i82593 channel 0. */
96
#define CMD0_CHNL_0                     0x00
97
#define CMD0_CHNL_1                     0x10            /* Switch to channel 1. */
98
#define CMD0_NOP (CMD0_CHNL_0)
99
#define CMD0_PORT_1     CMD0_CHNL_1
100
#define CMD1_PORT_0     1
101
#define CMD0_IA_SETUP           1
102
#define CMD0_CONFIGURE          2
103
#define CMD0_MULTICAST_LIST 3
104
#define CMD0_TRANSMIT           4
105
#define CMD0_DUMP                       6
106
#define CMD0_DIAGNOSE           7
107
#define CMD0_Rx_ENABLE          8
108
#define CMD0_Rx_DISABLE         10
109
#define CMD0_Rx_STOP            11
110
#define CMD0_RETRANSMIT         12
111
#define CMD0_ABORT                      13
112
#define CMD0_RESET                      14
113
 
114
#define CMD0_ACK 0x80
115
 
116
#define CMD0_STAT0 (0 << 5)
117
#define CMD0_STAT1 (1 << 5)
118
#define CMD0_STAT2 (2 << 5)
119
#define CMD0_STAT3 (3 << 5)
120
 
121
#define net_local znet_private
122
struct znet_private {
123
        int rx_dma, tx_dma;
124
        struct enet_statistics stats;
125
        /* The starting, current, and end pointers for the packet buffers. */
126
        ushort *rx_start, *rx_cur, *rx_end;
127
        ushort *tx_start, *tx_cur, *tx_end;
128
        ushort tx_buf_len;                      /* Tx buffer length, in words. */
129
};
130
 
131
/* Only one can be built-in;-> */
132
static struct znet_private zn;
133
static ushort dma_buffer1[DMA_BUF_SIZE/2];
134
static ushort dma_buffer2[DMA_BUF_SIZE/2];
135
static ushort dma_buffer3[DMA_BUF_SIZE/2 + 8];
136
 
137
/* The configuration block.  What an undocumented nightmare.  The first
138
   set of values are those suggested (without explanation) for ethernet
139
   in the Intel 82586 databook.  The rest appear to be completely undocumented,
140
   except for cryptic notes in the Crynwr packet driver.  This driver uses
141
   the Crynwr values verbatim. */
142
 
143
static unsigned char i593_init[] = {
144
  0xAA,                                 /* 0: 16-byte input & 80-byte output FIFO. */
145
                                                /*        threshold, 96-byte FIFO, 82593 mode. */
146
  0x88,                                 /* 1: Continuous w/interrupts, 128-clock DMA.*/
147
  0x2E,                                 /* 2: 8-byte preamble, NO address insertion, */
148
                                                /*        6-byte Ethernet address, loopback off.*/
149
  0x00,                                 /* 3: Default priorities & backoff methods. */
150
  0x60,                                 /* 4: 96-bit interframe spacing. */
151
  0x00,                                 /* 5: 512-bit slot time (low-order). */
152
  0xF2,                                 /* 6: Slot time (high-order), 15 COLL retries. */
153
  0x00,                                 /* 7: Promisc-off, broadcast-on, default CRC. */
154
  0x00,                                 /* 8: Default carrier-sense, collision-detect. */
155
  0x40,                                 /* 9: 64-byte minimum frame length. */
156
  0x5F,                                 /* A: Type/length checks OFF, no CRC input,
157
                                                   "jabber" termination, etc. */
158
  0x00,                                 /* B: Full-duplex disabled. */
159
  0x3F,                                 /* C: Default multicast addresses & backoff. */
160
  0x07,                                 /* D: Default IFS retriggering. */
161
  0x31,                                 /* E: Internal retransmit, drop "runt" packets,
162
                                                   synchr. DRQ deassertion, 6 status bytes. */
163
  0x22,                                 /* F: Receive ring-buffer size (8K),
164
                                                   receive-stop register enable. */
165
};
166
 
167
struct netidblk {
168
        char magic[8];          /* The magic number (string) "NETIDBLK" */
169
        unsigned char netid[8]; /* The physical station address */
170
        char nettype, globalopt;
171
        char vendor[8];         /* The machine vendor and product name. */
172
        char product[8];
173
        char irq1, irq2;                /* Interrupts, only one is currently used.      */
174
        char dma1, dma2;
175
        short dma_mem_misc[8];          /* DMA buffer locations (unused in Linux). */
176
        short iobase1, iosize1;
177
        short iobase2, iosize2;         /* Second iobase unused. */
178
        char driver_options;                    /* Misc. bits */
179
        char pad;
180
};
181
 
182
int znet_probe(struct device *dev);
183
static int      znet_open(struct device *dev);
184
static int      znet_send_packet(struct sk_buff *skb, struct device *dev);
185
static void     znet_interrupt(int irq, void *dev_id, struct pt_regs *regs);
186
static void     znet_rx(struct device *dev);
187
static int      znet_close(struct device *dev);
188
static struct enet_statistics *net_get_stats(struct device *dev);
189
static void set_multicast_list(struct device *dev);
190
static void hardware_init(struct device *dev);
191
static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset);
192
 
193
#ifdef notdef
194
static struct sigaction znet_sigaction = { &znet_interrupt, 0, 0, NULL, };
195
#endif
196
 
197
 
198
/* The Z-Note probe is pretty easy.  The NETIDBLK exists in the safe-to-probe
199
   BIOS area.  We just scan for the signature, and pull the vital parameters
200
   out of the structure. */
201
 
202
int znet_probe(struct device *dev)
203
{
204
        int i;
205
        struct netidblk *netinfo;
206
        char *p;
207
 
208
        /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */
209
        for(p = (char *)0xf0000; p < (char *)0x100000; p++)
210
                if (*p == 'N'  &&  strncmp(p, "NETIDBLK", 8) == 0)
211
                        break;
212
 
213
        if (p >= (char *)0x100000) {
214
                if (znet_debug > 1)
215
                        printk(KERN_INFO "No Z-Note ethernet adaptor found.\n");
216
                return ENODEV;
217
        }
218
        netinfo = (struct netidblk *)p;
219
        dev->base_addr = netinfo->iobase1;
220
        dev->irq = netinfo->irq1;
221
 
222
        printk(KERN_INFO "%s: ZNET at %#3lx,", dev->name, dev->base_addr);
223
 
224
        /* The station address is in the "netidblk" at 0x0f0000. */
225
        for (i = 0; i < 6; i++)
226
                printk(" %2.2x", dev->dev_addr[i] = netinfo->netid[i]);
227
 
228
        printk(", using IRQ %d DMA %d and %d.\n", dev->irq, netinfo->dma1,
229
                netinfo->dma2);
230
 
231
        if (znet_debug > 1) {
232
                printk(KERN_INFO "%s: vendor '%16.16s' IRQ1 %d IRQ2 %d DMA1 %d DMA2 %d.\n",
233
                           dev->name, netinfo->vendor,
234
                           netinfo->irq1, netinfo->irq2,
235
                           netinfo->dma1, netinfo->dma2);
236
                printk(KERN_INFO "%s: iobase1 %#x size %d iobase2 %#x size %d net type %2.2x.\n",
237
                           dev->name, netinfo->iobase1, netinfo->iosize1,
238
                           netinfo->iobase2, netinfo->iosize2, netinfo->nettype);
239
        }
240
 
241
        if (znet_debug > 0)
242
                printk("%s%s", KERN_INFO, version);
243
 
244
        dev->priv = (void *) &zn;
245
        zn.rx_dma = netinfo->dma1;
246
        zn.tx_dma = netinfo->dma2;
247
 
248
        /* These should never fail.  You can't add devices to a sealed box! */
249
        if (request_irq(dev->irq, &znet_interrupt, 0, "ZNet", NULL)
250
                || request_dma(zn.rx_dma,"ZNet rx")
251
                || request_dma(zn.tx_dma,"ZNet tx")) {
252
                printk(KERN_WARNING "%s: Not opened -- resource busy?!?\n", dev->name);
253
                return EBUSY;
254
        }
255
        irq2dev_map[dev->irq] = dev;
256
 
257
        /* Allocate buffer memory.      We can cross a 128K boundary, so we
258
           must be careful about the allocation.  It's easiest to waste 8K. */
259
        if (dma_page_eq(dma_buffer1, &dma_buffer1[RX_BUF_SIZE/2-1]))
260
          zn.rx_start = dma_buffer1;
261
        else
262
          zn.rx_start = dma_buffer2;
263
 
264
        if (dma_page_eq(dma_buffer3, &dma_buffer3[RX_BUF_SIZE/2-1]))
265
          zn.tx_start = dma_buffer3;
266
        else
267
          zn.tx_start = dma_buffer2;
268
        zn.rx_end = zn.rx_start + RX_BUF_SIZE/2;
269
        zn.tx_buf_len = TX_BUF_SIZE/2;
270
        zn.tx_end = zn.tx_start + zn.tx_buf_len;
271
 
272
        /* The ZNET-specific entries in the device structure. */
273
        dev->open = &znet_open;
274
        dev->hard_start_xmit = &znet_send_packet;
275
        dev->stop = &znet_close;
276
        dev->get_stats  = net_get_stats;
277
        dev->set_multicast_list = &set_multicast_list;
278
 
279
        /* Fill in the 'dev' with ethernet-generic values. */
280
        ether_setup(dev);
281
 
282
        return 0;
283
}
284
 
285
 
286
static int znet_open(struct device *dev)
287
{
288
        int ioaddr = dev->base_addr;
289
 
290
        if (znet_debug > 2)
291
                printk(KERN_DEBUG "%s: znet_open() called.\n", dev->name);
292
 
293
        /* Turn on the 82501 SIA, using zenith-specific magic. */
294
        outb(0x10, 0xe6);                                       /* Select LAN control register */
295
        outb(inb(0xe7) | 0x84, 0xe7);           /* Turn on LAN power (bit 2). */
296
        /* According to the Crynwr driver we should wait 50 msec. for the
297
           LAN clock to stabilize.  My experiments indicates that the '593 can
298
           be initialized immediately.  The delay is probably needed for the
299
           DC-to-DC converter to come up to full voltage, and for the oscillator
300
           to be spot-on at 20Mhz before transmitting.
301
           Until this proves to be a problem we rely on the higher layers for the
302
           delay and save allocating a timer entry. */
303
 
304
        /* This follows the packet driver's lead, and checks for success. */
305
        if (inb(ioaddr) != 0x10 && inb(ioaddr) != 0x00)
306
                printk(KERN_WARNING "%s: Problem turning on the transceiver power.\n",
307
                           dev->name);
308
 
309
        dev->tbusy = 0;
310
        dev->interrupt = 0;
311
        hardware_init(dev);
312
        dev->start = 1;
313
 
314
        return 0;
315
}
316
 
317
static int znet_send_packet(struct sk_buff *skb, struct device *dev)
318
{
319
        int ioaddr = dev->base_addr;
320
 
321
        if (znet_debug > 4)
322
                printk(KERN_DEBUG "%s: ZNet_send_packet(%ld).\n", dev->name, dev->tbusy);
323
 
324
        /* Transmitter timeout, likely just recovery after suspending the machine. */
325
        if (dev->tbusy) {
326
                ushort event, tx_status, rx_offset, state;
327
                int tickssofar = jiffies - dev->trans_start;
328
                if (tickssofar < 10)
329
                        return 1;
330
                outb(CMD0_STAT0, ioaddr); event = inb(ioaddr);
331
                outb(CMD0_STAT1, ioaddr); tx_status = inw(ioaddr);
332
                outb(CMD0_STAT2, ioaddr); rx_offset = inw(ioaddr);
333
                outb(CMD0_STAT3, ioaddr); state = inb(ioaddr);
334
                printk(KERN_WARNING "%s: transmit timed out, status %02x %04x %04x %02x,"
335
                           " resetting.\n", dev->name, event, tx_status, rx_offset, state);
336
                if (tx_status == 0x0400)
337
                  printk(KERN_WARNING "%s: Tx carrier error, check transceiver cable.\n",
338
                                 dev->name);
339
                outb(CMD0_RESET, ioaddr);
340
                hardware_init(dev);
341
        }
342
 
343
        if (skb == NULL) {
344
                dev_tint(dev);
345
                return 0;
346
        }
347
 
348
        /* Check that the part hasn't reset itself, probably from suspend. */
349
        outb(CMD0_STAT0, ioaddr);
350
        if (inw(ioaddr) == 0x0010
351
                && inw(ioaddr) == 0x0000
352
                && inw(ioaddr) == 0x0010)
353
          hardware_init(dev);
354
 
355
        /* Block a timer-based transmit from overlapping.  This could better be
356
           done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
357
        if (set_bit(0, (void*)&dev->tbusy) != 0)
358
                printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
359
        else {
360
                short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
361
                unsigned char *buf = (void *)skb->data;
362
                ushort *tx_link = zn.tx_cur - 1;
363
                ushort rnd_len = (length + 1)>>1;
364
 
365
                {
366
                        short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
367
                        unsigned addr = inb(dma_port);
368
                        addr |= inb(dma_port) << 8;
369
                        addr <<= 1;
370
                        if (((int)zn.tx_cur & 0x1ffff) != addr)
371
                          printk(KERN_WARNING "Address mismatch at Tx: %#x vs %#x.\n",
372
                                         (int)zn.tx_cur & 0xffff, addr);
373
                        zn.tx_cur = (ushort *)(((int)zn.tx_cur & 0xfe0000) | addr);
374
                }
375
 
376
                if (zn.tx_cur >= zn.tx_end)
377
                  zn.tx_cur = zn.tx_start;
378
                *zn.tx_cur++ = length;
379
                if (zn.tx_cur + rnd_len + 1 > zn.tx_end) {
380
                        int semi_cnt = (zn.tx_end - zn.tx_cur)<<1; /* Cvrt to byte cnt. */
381
                        memcpy(zn.tx_cur, buf, semi_cnt);
382
                        rnd_len -= semi_cnt>>1;
383
                        memcpy(zn.tx_start, buf + semi_cnt, length - semi_cnt);
384
                        zn.tx_cur = zn.tx_start + rnd_len;
385
                } else {
386
                        memcpy(zn.tx_cur, buf, skb->len);
387
                        zn.tx_cur += rnd_len;
388
                }
389
                *zn.tx_cur++ = 0;
390
                cli(); {
391
                        *tx_link = CMD0_TRANSMIT + CMD0_CHNL_1;
392
                        /* Is this always safe to do? */
393
                        outb(CMD0_TRANSMIT + CMD0_CHNL_1,ioaddr);
394
                } sti();
395
 
396
                dev->trans_start = jiffies;
397
                if (znet_debug > 4)
398
                  printk(KERN_DEBUG "%s: Transmitter queued, length %d.\n", dev->name, length);
399
        }
400
        dev_kfree_skb(skb, FREE_WRITE);
401
        return 0;
402
}
403
 
404
/* The ZNET interrupt handler. */
405
static void     znet_interrupt(int irq, void *dev_id, struct pt_regs * regs)
406
{
407
        struct device *dev = irq2dev_map[irq];
408
        int ioaddr;
409
        int boguscnt = 20;
410
 
411
        if (dev == NULL) {
412
                printk(KERN_WARNING "znet_interrupt(): IRQ %d for unknown device.\n", irq);
413
                return;
414
        }
415
 
416
        dev->interrupt = 1;
417
        ioaddr = dev->base_addr;
418
 
419
        outb(CMD0_STAT0, ioaddr);
420
        do {
421
                ushort status = inb(ioaddr);
422
                if (znet_debug > 5) {
423
                        ushort result, rx_ptr, running;
424
                        outb(CMD0_STAT1, ioaddr);
425
                        result = inw(ioaddr);
426
                        outb(CMD0_STAT2, ioaddr);
427
                        rx_ptr = inw(ioaddr);
428
                        outb(CMD0_STAT3, ioaddr);
429
                        running = inb(ioaddr);
430
                        printk(KERN_DEBUG "%s: interrupt, status %02x, %04x %04x %02x serial %d.\n",
431
                                 dev->name, status, result, rx_ptr, running, boguscnt);
432
                }
433
                if ((status & 0x80) == 0)
434
                        break;
435
 
436
                if ((status & 0x0F) == 4) {     /* Transmit done. */
437
                        struct net_local *lp = (struct net_local *)dev->priv;
438
                        int tx_status;
439
                        outb(CMD0_STAT1, ioaddr);
440
                        tx_status = inw(ioaddr);
441
                        /* It's undocumented, but tx_status seems to match the i82586. */
442
                        if (tx_status & 0x2000) {
443
                                lp->stats.tx_packets++;
444
                                lp->stats.collisions += tx_status & 0xf;
445
                        } else {
446
                                if (tx_status & 0x0600)  lp->stats.tx_carrier_errors++;
447
                                if (tx_status & 0x0100)  lp->stats.tx_fifo_errors++;
448
                                if (!(tx_status & 0x0040)) lp->stats.tx_heartbeat_errors++;
449
                                if (tx_status & 0x0020)  lp->stats.tx_aborted_errors++;
450
                                /* ...and the catch-all. */
451
                                if ((tx_status | 0x0760) != 0x0760)
452
                                  lp->stats.tx_errors++;
453
                        }
454
                        dev->tbusy = 0;
455
                        mark_bh(NET_BH);        /* Inform upper layers. */
456
                }
457
 
458
                if ((status & 0x40)
459
                        || (status & 0x0f) == 11) {
460
                        znet_rx(dev);
461
                }
462
                /* Clear the interrupts we've handled. */
463
                outb(CMD0_ACK,ioaddr);
464
        } while (boguscnt--);
465
 
466
        dev->interrupt = 0;
467
        return;
468
}
469
 
470
static void znet_rx(struct device *dev)
471
{
472
        struct net_local *lp = (struct net_local *)dev->priv;
473
        int ioaddr = dev->base_addr;
474
        int boguscount = 1;
475
        short next_frame_end_offset = 0;                 /* Offset of next frame start. */
476
        short *cur_frame_end;
477
        short cur_frame_end_offset;
478
 
479
        outb(CMD0_STAT2, ioaddr);
480
        cur_frame_end_offset = inw(ioaddr);
481
 
482
        if (cur_frame_end_offset == zn.rx_cur - zn.rx_start) {
483
                printk(KERN_WARNING "%s: Interrupted, but nothing to receive, offset %03x.\n",
484
                           dev->name, cur_frame_end_offset);
485
                return;
486
        }
487
 
488
        /* Use same method as the Crynwr driver: construct a forward list in
489
           the same area of the backwards links we now have.  This allows us to
490
           pass packets to the upper layers in the order they were received --
491
           important for fast-path sequential operations. */
492
         while (zn.rx_start + cur_frame_end_offset != zn.rx_cur
493
                        && ++boguscount < 5) {
494
                unsigned short hi_cnt, lo_cnt, hi_status, lo_status;
495
                int count, status;
496
 
497
                if (cur_frame_end_offset < 4) {
498
                        /* Oh no, we have a special case: the frame trailer wraps around
499
                           the end of the ring buffer.  We've saved space at the end of
500
                           the ring buffer for just this problem. */
501
                        memcpy(zn.rx_end, zn.rx_start, 8);
502
                        cur_frame_end_offset += (RX_BUF_SIZE/2);
503
                }
504
                cur_frame_end = zn.rx_start + cur_frame_end_offset - 4;
505
 
506
                lo_status = *cur_frame_end++;
507
                hi_status = *cur_frame_end++;
508
                status = ((hi_status & 0xff) << 8) + (lo_status & 0xff);
509
                lo_cnt = *cur_frame_end++;
510
                hi_cnt = *cur_frame_end++;
511
                count = ((hi_cnt & 0xff) << 8) + (lo_cnt & 0xff);
512
 
513
                if (znet_debug > 5)
514
                  printk(KERN_DEBUG "Constructing trailer at location %03x, %04x %04x %04x %04x"
515
                                 " count %#x status %04x.\n",
516
                                 cur_frame_end_offset<<1, lo_status, hi_status, lo_cnt, hi_cnt,
517
                                 count, status);
518
                cur_frame_end[-4] = status;
519
                cur_frame_end[-3] = next_frame_end_offset;
520
                cur_frame_end[-2] = count;
521
                next_frame_end_offset = cur_frame_end_offset;
522
                cur_frame_end_offset -= ((count + 1)>>1) + 3;
523
                if (cur_frame_end_offset < 0)
524
                  cur_frame_end_offset += RX_BUF_SIZE/2;
525
        };
526
 
527
        /* Now step  forward through the list. */
528
        do {
529
                ushort *this_rfp_ptr = zn.rx_start + next_frame_end_offset;
530
                int status = this_rfp_ptr[-4];
531
                int pkt_len = this_rfp_ptr[-2];
532
 
533
                if (znet_debug > 5)
534
                  printk(KERN_DEBUG "Looking at trailer ending at %04x status %04x length %03x"
535
                                 " next %04x.\n", next_frame_end_offset<<1, status, pkt_len,
536
                                 this_rfp_ptr[-3]<<1);
537
                /* Once again we must assume that the i82586 docs apply. */
538
                if ( ! (status & 0x2000)) {                             /* There was an error. */
539
                        lp->stats.rx_errors++;
540
                        if (status & 0x0800) lp->stats.rx_crc_errors++;
541
                        if (status & 0x0400) lp->stats.rx_frame_errors++;
542
                        if (status & 0x0200) lp->stats.rx_over_errors++; /* Wrong. */
543
                        if (status & 0x0100) lp->stats.rx_fifo_errors++;
544
                        if (status & 0x0080) lp->stats.rx_length_errors++;
545
                } else if (pkt_len > 1536) {
546
                        lp->stats.rx_length_errors++;
547
                } else {
548
                        /* Malloc up new buffer. */
549
                        struct sk_buff *skb;
550
 
551
                        skb = dev_alloc_skb(pkt_len);
552
                        if (skb == NULL) {
553
                                if (znet_debug)
554
                                  printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
555
                                lp->stats.rx_dropped++;
556
                                break;
557
                        }
558
                        skb->dev = dev;
559
 
560
                        if (&zn.rx_cur[(pkt_len+1)>>1] > zn.rx_end) {
561
                                int semi_cnt = (zn.rx_end - zn.rx_cur)<<1;
562
                                memcpy(skb_put(skb,semi_cnt), zn.rx_cur, semi_cnt);
563
                                memcpy(skb_put(skb,pkt_len-semi_cnt), zn.rx_start,
564
                                           pkt_len - semi_cnt);
565
                        } else {
566
                                memcpy(skb_put(skb,pkt_len), zn.rx_cur, pkt_len);
567
                                if (znet_debug > 6) {
568
                                        unsigned int *packet = (unsigned int *) skb->data;
569
                                        printk(KERN_DEBUG "Packet data is %08x %08x %08x %08x.\n", packet[0],
570
                                                   packet[1], packet[2], packet[3]);
571
                                }
572
                  }
573
                  skb->protocol=eth_type_trans(skb,dev);
574
                  netif_rx(skb);
575
                  lp->stats.rx_packets++;
576
                }
577
                zn.rx_cur = this_rfp_ptr;
578
                if (zn.rx_cur >= zn.rx_end)
579
                        zn.rx_cur -= RX_BUF_SIZE/2;
580
                update_stop_hit(ioaddr, (zn.rx_cur - zn.rx_start)<<1);
581
                next_frame_end_offset = this_rfp_ptr[-3];
582
                if (next_frame_end_offset == 0)          /* Read all the frames? */
583
                        break;                  /* Done for now */
584
                this_rfp_ptr = zn.rx_start + next_frame_end_offset;
585
        } while (--boguscount);
586
 
587
        /* If any worth-while packets have been received, dev_rint()
588
           has done a mark_bh(INET_BH) for us and will work on them
589
           when we get to the bottom-half routine. */
590
        return;
591
}
592
 
593
/* The inverse routine to znet_open(). */
594
static int znet_close(struct device *dev)
595
{
596
        int ioaddr = dev->base_addr;
597
 
598
        dev->tbusy = 1;
599
        dev->start = 0;
600
 
601
        outb(CMD0_RESET, ioaddr);                       /* CMD0_RESET */
602
 
603
        disable_dma(zn.rx_dma);
604
        disable_dma(zn.tx_dma);
605
 
606
        free_irq(dev->irq, NULL);
607
 
608
        if (znet_debug > 1)
609
                printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name);
610
        /* Turn off transceiver power. */
611
        outb(0x10, 0xe6);                                       /* Select LAN control register */
612
        outb(inb(0xe7) & ~0x84, 0xe7);          /* Turn on LAN power (bit 2). */
613
 
614
        return 0;
615
}
616
 
617
/* Get the current statistics.  This may be called with the card open or
618
   closed. */
619
static struct enet_statistics *net_get_stats(struct device *dev)
620
{
621
                struct net_local *lp = (struct net_local *)dev->priv;
622
 
623
                return &lp->stats;
624
}
625
 
626
/* Set or clear the multicast filter for this adaptor.
627
   As a side effect this routine must also initialize the device parameters.
628
   This is taken advantage of in open().
629
 
630
   N.B. that we change i593_init[] in place.  This (properly) makes the
631
   mode change persistent, but must be changed if this code is moved to
632
   a multiple adaptor environment.
633
 */
634
static void set_multicast_list(struct device *dev)
635
{
636
        short ioaddr = dev->base_addr;
637
 
638
        if (dev->flags&IFF_PROMISC) {
639
                /* Enable promiscuous mode */
640
                i593_init[7] &= ~3;             i593_init[7] |= 1;
641
                i593_init[13] &= ~8;    i593_init[13] |= 8;
642
        } else if (dev->mc_list || (dev->flags&IFF_ALLMULTI)) {
643
                /* Enable accept-all-multicast mode */
644
                i593_init[7] &= ~3;             i593_init[7] |= 0;
645
                i593_init[13] &= ~8;    i593_init[13] |= 8;
646
        } else {                                        /* Enable normal mode. */
647
                i593_init[7] &= ~3;             i593_init[7] |= 0;
648
                i593_init[13] &= ~8;    i593_init[13] |= 0;
649
        }
650
        *zn.tx_cur++ = sizeof(i593_init);
651
        memcpy(zn.tx_cur, i593_init, sizeof(i593_init));
652
        zn.tx_cur += sizeof(i593_init)/2;
653
        outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
654
#ifdef not_tested
655
        if (num_addrs > 0) {
656
                int addrs_len = 6*num_addrs;
657
                *zn.tx_cur++ = addrs_len;
658
                memcpy(zn.tx_cur, addrs, addrs_len);
659
                outb(CMD0_MULTICAST_LIST+CMD0_CHNL_1, ioaddr);
660
                zn.tx_cur += addrs_len>>1;
661
        }
662
#endif
663
}
664
 
665
void show_dma(void)
666
{
667
        short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
668
        unsigned addr = inb(dma_port);
669
        addr |= inb(dma_port) << 8;
670
        printk("Addr: %04x cnt:%3x...", addr<<1, get_dma_residue(zn.tx_dma));
671
}
672
 
673
/* Initialize the hardware.  We have to do this when the board is open()ed
674
   or when we come out of suspend mode. */
675
static void hardware_init(struct device *dev)
676
{
677
        short ioaddr = dev->base_addr;
678
 
679
        zn.rx_cur = zn.rx_start;
680
        zn.tx_cur = zn.tx_start;
681
 
682
        /* Reset the chip, and start it up. */
683
        outb(CMD0_RESET, ioaddr);
684
 
685
        cli(); {                                                        /* Protect against a DMA flip-flop */
686
                disable_dma(zn.rx_dma);                 /* reset by an interrupting task. */
687
                clear_dma_ff(zn.rx_dma);
688
                set_dma_mode(zn.rx_dma, DMA_RX_MODE);
689
                set_dma_addr(zn.rx_dma, (unsigned int) zn.rx_start);
690
                set_dma_count(zn.rx_dma, RX_BUF_SIZE);
691
                enable_dma(zn.rx_dma);
692
                /* Now set up the Tx channel. */
693
                disable_dma(zn.tx_dma);
694
                clear_dma_ff(zn.tx_dma);
695
                set_dma_mode(zn.tx_dma, DMA_TX_MODE);
696
                set_dma_addr(zn.tx_dma, (unsigned int) zn.tx_start);
697
                set_dma_count(zn.tx_dma, zn.tx_buf_len<<1);
698
                enable_dma(zn.tx_dma);
699
        } sti();
700
 
701
        if (znet_debug > 1)
702
          printk(KERN_DEBUG "%s: Initializing the i82593, tx buf %p... ", dev->name,
703
                         zn.tx_start);
704
        /* Do an empty configure command, just like the Crynwr driver.  This
705
           resets to chip to its default values. */
706
        *zn.tx_cur++ = 0;
707
        *zn.tx_cur++ = 0;
708
        printk("stat:%02x ", inb(ioaddr)); show_dma();
709
        outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
710
        *zn.tx_cur++ = sizeof(i593_init);
711
        memcpy(zn.tx_cur, i593_init, sizeof(i593_init));
712
        zn.tx_cur += sizeof(i593_init)/2;
713
        printk("stat:%02x ", inb(ioaddr)); show_dma();
714
        outb(CMD0_CONFIGURE+CMD0_CHNL_1, ioaddr);
715
        *zn.tx_cur++ = 6;
716
        memcpy(zn.tx_cur, dev->dev_addr, 6);
717
        zn.tx_cur += 3;
718
        printk("stat:%02x ", inb(ioaddr)); show_dma();
719
        outb(CMD0_IA_SETUP + CMD0_CHNL_1, ioaddr);
720
        printk("stat:%02x ", inb(ioaddr)); show_dma();
721
 
722
        update_stop_hit(ioaddr, 8192);
723
        if (znet_debug > 1)  printk("enabling Rx.\n");
724
        outb(CMD0_Rx_ENABLE+CMD0_CHNL_0, ioaddr);
725
        dev->tbusy = 0;
726
}
727
 
728
static void update_stop_hit(short ioaddr, unsigned short rx_stop_offset)
729
{
730
        outb(CMD0_PORT_1, ioaddr);
731
        if (znet_debug > 5)
732
          printk(KERN_DEBUG "Updating stop hit with value %02x.\n",
733
                         (rx_stop_offset >> 6) | 0x80);
734
        outb((rx_stop_offset >> 6) | 0x80, ioaddr);
735
        outb(CMD1_PORT_0, ioaddr);
736
}
737
 
738
/*
739
 * Local variables:
740
 *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c znet.c"
741
 *  version-control: t
742
 *  kept-new-versions: 5
743
 *  c-indent-level: 4
744
 *  tab-width: 4
745
 * End:
746
 */

powered by: WebSVN 2.1.0

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