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

Subversion Repositories or1k

[/] [or1k/] [tags/] [before_ORP/] [uclinux/] [uClinux-2.0.x/] [drivers/] [net/] [hydra.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/* Linux/68k Hydra Amiganet board driver v2.1 BETA                          */
2
/* copyleft by Topi Kanerva (topi@susanna.oulu.fi)                          */
3
/* also some code & lots of fixes by Timo Rossi (trossi@cc.jyu.fi)          */
4
 
5
/* The code is mostly based on the linux/68k Ariadne driver                 */
6
/* copyrighted by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be) */
7
/* and Peter De Schrijver (Peter.DeSchrijver@linux.cc.kuleuven.ac.be)       */
8
 
9
/* This file is subject to the terms and conditions of the GNU General      */
10
/* Public License.  See the file COPYING in the main directory of the       */
11
/* Linux distribution for more details.                                     */
12
 
13
/* The Amiganet is a Zorro-II board made by Hydra Systems. It contains a    */
14
/* NS8390 NIC (network interface controller) clone, 16 or 64K on-board RAM  */
15
/* and 10BASE-2 (thin coax) and AUI connectors.                             */
16
 
17
 
18
#include <linux/module.h>
19
#include <linux/kernel.h>
20
#include <linux/sched.h>
21
#include <linux/string.h>
22
#include <linux/ptrace.h>
23
#include <linux/errno.h>
24
#include <linux/ioport.h>
25
#include <linux/malloc.h>
26
#include <linux/interrupt.h>
27
#include <linux/netdevice.h>
28
#include <linux/etherdevice.h>
29
#include <linux/skbuff.h>
30
 
31
#include <asm/bitops.h>
32
#include <asm/io.h>
33
#include <asm/irq.h>
34
 
35
#include <asm/bootinfo.h>
36
#include <asm/amigaints.h>
37
#include <asm/amigahw.h>
38
#include <asm/zorro.h>
39
 
40
#include "hydra.h"
41
 
42
 
43
#define HYDRA_DEBUG
44
#undef HAVE_MULTICAST
45
 
46
#define HYDRA_VERSION "v2.1 BETA"
47
 
48
#undef HYDRA_DEBUG        /* define this for (lots of) debugging information */
49
 
50
#if 0                         /* currently hardwired to one transmit buffer */
51
 #define TX_RING_SIZE   5
52
 #define RX_RING_SIZE   16
53
#else
54
 #define TX_RING_SIZE 1
55
 #define RX_RING_SIZE 8
56
#endif
57
 
58
#define ETHER_MIN_LEN 64
59
#define ETHER_MAX_LEN 1518
60
#define ETHER_ADDR_LEN 6
61
 
62
 
63
/*
64
 *   let's define here nice macros for writing and reading NIC registers
65
 *
66
 * the CIA accesses here are uses to make sure the minimum time
67
 * requirement between NIC chip selects is met.
68
 */
69
#define WRITE_REG(reg, val) (ciaa.pra, ((u_char)(*(nicbase+(reg))=val)))
70
#define READ_REG(reg) (ciaa.pra, ((u_char)(*(nicbase+(reg)))))
71
 
72
/* mask value for the interrupts we use */
73
#define NIC_INTS (ISR_PRX | ISR_PTX | ISR_RXE | ISR_TXE | ISR_OVW | ISR_CNT)
74
 
75
/* only broadcasts, no promiscuous mode for now */
76
#define NIC_RCRBITS (0)
77
 
78
/*
79
 *   Private Device Data
80
 */
81
struct hydra_private
82
    {
83
    u_char *hydra_base;
84
    u_char *hydra_nic_base;
85
    u_short tx_page_start;
86
    u_short rx_page_start;
87
    u_short rx_page_stop;
88
    u_short next_pkt;
89
    struct enet_statistics stats;
90
    int key;
91
    };
92
 
93
static int hydra_open(struct device *dev);
94
static int hydra_start_xmit(struct sk_buff *skb, struct device *dev);
95
static void hydra_interrupt(int irq, struct pt_regs *fp, void *data);
96
static void __inline__ hydra_rx(struct device *dev, struct hydra_private *priv, volatile u_char *nicbase);
97
static int hydra_close(struct device *dev);
98
static struct enet_statistics *hydra_get_stats(struct device *dev);
99
#ifdef HAVE_MULTICAST
100
static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
101
#endif
102
 
103
 
104
/* this is now coherent with the C version below, */
105
/* compile the source with -D__USE_ASM__ if you   */
106
/* want it - it'll only be some 10% faster though */
107
 
108
#if defined (__GNUC__) && defined (__mc68000__) && defined (USE_ASM)
109
 
110
static __inline__ void *memcpyw(u_short *dest, u_short *src, int len)
111
    {
112
    __asm__("   move.l %0,%/a1; move.l %1,%/a0; move.l %2,%/d0 \n\t"
113
            "   cmpi.l #2,%/d0 \n\t"
114
            "1: bcs.s  2f \n\t"
115
            "   move.w %/a0@+,%/a1@+ \n\t"
116
            "   subq.l #2,%/d0 \n\t"
117
            "   bra.s  1b \n\t"
118
            "2: cmpi.l #1,%/d0 \n\t"
119
            "   bne.s  3f \n\t"
120
            "   move.w %/a0@,%/d0 \n\t"
121
            "   swap.w %/d0 \n\t"
122
            "   move.b %/d0,%/a1@ \n\t"
123
            "3: moveq  #0,%/d0 \n\t"
124
          :
125
          : "g" (dest), "g" (src), "g" (len)
126
          : "a1", "a0", "d0");
127
    return;
128
}
129
 
130
#else
131
 
132
/* hydra memory can only be read or written as words or longwords.  */
133
/* that will mean that we'll have to write a special memcpy for it. */
134
/* this one here relies on the fact that _writes_ to hydra memory   */
135
/* are guaranteed to be of even length. (reads can be arbitrary)    */
136
 
137
static void memcpyw(u_short *dest, u_short *src, int len)
138
{
139
  if(len & 1)
140
    len++;
141
 
142
  while (len >= 2) {
143
    *(dest++) = *(src++);
144
    len -= 2;
145
  }
146
 
147
}
148
 
149
#endif
150
 
151
int hydra_probe(struct device *dev)
152
    {
153
    struct hydra_private *priv;
154
    u_long board;
155
    int key;
156
    struct ConfigDev *cd;
157
    int j;
158
 
159
#ifdef HYDRA_DEBUG
160
 printk("hydra_probe(%x)\n", dev);
161
#endif
162
 
163
    if ((key = zorro_find(MANUF_HYDRA_SYSTEMS, PROD_AMIGANET, 0, 0))) {
164
        cd = zorro_get_board(key);
165
        if((board = (u_long) cd->cd_BoardAddr))
166
            {
167
            for(j = 0; j < ETHER_ADDR_LEN; j++)
168
                dev->dev_addr[j] = *((u_char *)ZTWO_VADDR(board + HYDRA_ADDRPROM + 2*j));
169
 
170
            printk("%s: hydra at 0x%08x, address %02x:%02x:%02x:%02x:%02x:%02x (hydra.c " HYDRA_VERSION ")\n",
171
                   dev->name, (int)board, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
172
                   dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
173
 
174
            init_etherdev(dev, 0);
175
 
176
            dev->priv = kmalloc(sizeof(struct hydra_private), GFP_KERNEL);
177
            priv = (struct hydra_private *)dev->priv;
178
            memset(priv, 0, sizeof(struct hydra_private));
179
 
180
            priv->hydra_base = (u_char *) ZTWO_VADDR(board);
181
            priv->hydra_nic_base = (u_char *) ZTWO_VADDR(board) + HYDRA_NIC_BASE;
182
            priv->key = key;
183
 
184
            dev->open = &hydra_open;
185
            dev->stop = &hydra_close;
186
            dev->hard_start_xmit = &hydra_start_xmit;
187
            dev->get_stats = &hydra_get_stats;
188
#ifdef HAVE_MULTICAST
189
            dev->set_multicast_list = &hydra_set_multicast_list;
190
#endif
191
            zorro_config_board(key, 0);
192
            return(0);
193
            }
194
        }
195
    return(ENODEV);
196
    }
197
 
198
 
199
static int hydra_open(struct device *dev)
200
  {
201
    struct hydra_private *priv = (struct hydra_private *)dev->priv;
202
    volatile u_char *nicbase = priv->hydra_nic_base;
203
#ifdef HAVE_MULTICAST
204
    int i;
205
#endif
206
 
207
#ifdef HYDRA_DEBUG
208
 printk("hydra_open(0x%x)\n", dev);
209
#endif
210
 
211
    /* first, initialize the private structure */
212
    priv->tx_page_start = 0;   /* these are 256 byte buffers for NS8390 */
213
    priv->rx_page_start = 6;
214
    priv->rx_page_stop  = 62;  /* these values are hard coded for now */
215
 
216
    /* Reset the NS8390 NIC */
217
    WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP);
218
 
219
    /* be sure that the NIC is in stopped state */
220
    while(!(READ_REG(NIC_ISR) & ISR_RST));
221
 
222
    /* word transfer, big endian bytes, loopback, FIFO threshold 4 bytes */
223
    WRITE_REG(NIC_DCR, DCR_WTS | DCR_BOS | DCR_LS | DCR_FT0);
224
 
225
    /* clear remote byte count registers */
226
    WRITE_REG(NIC_RBCR0, 0);
227
    WRITE_REG(NIC_RBCR1, 0);
228
 
229
    /* accept packets addressed to this card and also broadcast packets */
230
    WRITE_REG(NIC_RCR, NIC_RCRBITS);
231
 
232
    /* enable loopback mode 1 */
233
    WRITE_REG(NIC_TCR, TCR_LB1);
234
 
235
    /* initialize receive buffer ring */
236
    WRITE_REG(NIC_PSTART, priv->rx_page_start);
237
    WRITE_REG(NIC_PSTOP, priv->rx_page_stop);
238
    WRITE_REG(NIC_BNDRY, priv->rx_page_start);
239
 
240
    /* clear interrupts */
241
    WRITE_REG(NIC_ISR, 0xff);
242
 
243
    /* enable interrupts */
244
    WRITE_REG(NIC_IMR, NIC_INTS);
245
 
246
    /* set the ethernet hardware address */
247
    WRITE_REG(NIC_CR, CR_PAGE1 | CR_NODMA | CR_STOP); /* goto page 1 */
248
 
249
    WRITE_REG(NIC_PAR0, dev->dev_addr[0]);
250
    WRITE_REG(NIC_PAR1, dev->dev_addr[1]);
251
    WRITE_REG(NIC_PAR2, dev->dev_addr[2]);
252
    WRITE_REG(NIC_PAR3, dev->dev_addr[3]);
253
    WRITE_REG(NIC_PAR4, dev->dev_addr[4]);
254
    WRITE_REG(NIC_PAR5, dev->dev_addr[5]);
255
 
256
#ifdef HAVE_MULTICAST
257
    /* clear multicast hash table */
258
    for(i = 0; i < 8; i++)
259
      WRITE_REG(NIC_MAR0 + 2*i, 0);
260
#endif
261
 
262
    priv->next_pkt = priv->rx_page_start+1; /* init our s/w variable */
263
    WRITE_REG(NIC_CURR, priv->next_pkt);    /* set the next buf for current */
264
 
265
    /* goto page 0, start NIC */
266
    WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START);
267
 
268
    /* take interface out of loopback */
269
    WRITE_REG(NIC_TCR, 0);
270
 
271
    dev->tbusy = 0;
272
    dev->interrupt = 0;
273
    dev->start = 1;
274
 
275
    if(!add_isr(IRQ_AMIGA_PORTS, hydra_interrupt, 0, dev, "Hydra Ethernet"))
276
      return(-EAGAIN);
277
 
278
    MOD_INC_USE_COUNT;
279
 
280
    return(0);
281
  }
282
 
283
 
284
static int hydra_close(struct device *dev)
285
{
286
  struct hydra_private *priv = (struct hydra_private *)dev->priv;
287
  volatile u_char *nicbase = priv->hydra_nic_base;
288
  int n = 5000;
289
 
290
  dev->start = 0;
291
  dev->tbusy = 1;
292
 
293
#ifdef HYDRA_DEBUG
294
  printk("%s: Shutting down ethercard\n", dev->name);
295
  printk("%s: %d packets missed\n", dev->name, priv->stats.rx_missed_errors);
296
#endif
297
 
298
  WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP);
299
 
300
  /* wait for NIC to stop (what a nice timeout..) */
301
  while(((READ_REG(NIC_ISR) & ISR_RST) == 0) && --n);
302
 
303
  remove_isr(IRQ_AMIGA_PORTS, hydra_interrupt, dev);
304
 
305
  MOD_DEC_USE_COUNT;
306
 
307
  return(0);
308
}
309
 
310
 
311
static void hydra_interrupt(int irq, struct pt_regs *fp, void *data)
312
    {
313
    volatile u_char *nicbase;
314
 
315
    struct device *dev = (struct device *) data;
316
    struct hydra_private *priv;
317
    u_short intbits;
318
 
319
    if(dev == NULL)
320
        {
321
        printk("hydra_interrupt(): irq for unknown device\n");
322
        return;
323
        }
324
 
325
/* this is not likely a problem - i think */
326
    if(dev->interrupt)
327
        printk("%s: re-entering the interrupt handler\n", dev->name);
328
 
329
    dev->interrupt = 1;
330
 
331
    priv = (struct hydra_private *) dev->priv;
332
    nicbase = (u_char *) priv->hydra_nic_base;
333
 
334
    /* select page 0 */
335
    WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
336
 
337
    intbits = READ_REG(NIC_ISR) & NIC_INTS;
338
    if(intbits == 0)
339
        {
340
        dev->interrupt = 0;
341
        return;
342
        }
343
 
344
        /* acknowledge all interrupts, by clearing the interrupt flag */
345
        WRITE_REG(NIC_ISR, intbits);
346
 
347
        if((intbits & ISR_PTX) && !(intbits & ISR_TXE))
348
            {
349
            dev->tbusy = 0;
350
            mark_bh(NET_BH);
351
            }
352
 
353
        if((intbits & ISR_PRX) && !(intbits & ISR_RXE))/* packet received OK */
354
              hydra_rx(dev, priv, nicbase);
355
 
356
        if(intbits & ISR_TXE)
357
            priv->stats.tx_errors++;
358
 
359
        if(intbits & ISR_RXE)
360
            priv->stats.rx_errors++;
361
 
362
        if(intbits & ISR_CNT) {
363
          /*
364
           * read the tally counters and (currently) ignore the values
365
           * might be useful because of bugs of some versions of the 8390 NIC
366
           */
367
#ifdef HYDRA_DEBUG
368
          printk("hydra_interrupt(): ISR_CNT\n");
369
#endif
370
          (void)READ_REG(NIC_CNTR0);
371
          (void)READ_REG(NIC_CNTR1);
372
          (void)READ_REG(NIC_CNTR2);
373
        }
374
 
375
        if(intbits & ISR_OVW)
376
            {
377
            #ifdef HYDRA_DEBUG
378
            WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA);
379
/* another one just too much for me to comprehend - basically this could  */
380
/* only occur because of invalid access to hydra ram, thus invalidating  */
381
/* the interrupt bits read - in average usage these do not occur at all */
382
            printk("hydra_interrupt(): overwrite warning, NIC_ISR %02x, NIC_CURR %02x\n",
383
                 intbits, READ_REG(NIC_CURR));
384
            WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
385
            #endif
386
 
387
 
388
            /* overwrite warning occurred, stop NIC & check the BOUNDARY pointer */
389
            /* FIXME - real overwrite handling needed !! */
390
 
391
            printk("hydra_interrupt(): overwrite warning, resetting NIC\n");
392
            WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_STOP);
393
            while(!(READ_REG(NIC_ISR) & ISR_RST));
394
            /* wait for NIC to reset */
395
            WRITE_REG(NIC_DCR, DCR_WTS | DCR_BOS | DCR_LS | DCR_FT0);
396
            WRITE_REG(NIC_RBCR0, 0);
397
            WRITE_REG(NIC_RBCR1, 0);
398
            WRITE_REG(NIC_RCR, NIC_RCRBITS);
399
            WRITE_REG(NIC_TCR, TCR_LB1);
400
            WRITE_REG(NIC_PSTART, priv->rx_page_start);
401
            WRITE_REG(NIC_PSTOP, priv->rx_page_stop);
402
            WRITE_REG(NIC_BNDRY, priv->rx_page_start);
403
            WRITE_REG(NIC_ISR, 0xff);
404
            WRITE_REG(NIC_IMR, NIC_INTS);
405
/* currently this _won't_ reset my hydra, even though it is */
406
/* basically the same code as in the board init - any ideas? */
407
 
408
            priv->next_pkt = priv->rx_page_start+1; /* init our s/w variable */
409
            WRITE_REG(NIC_CURR, priv->next_pkt);    /* set the next buf for current */
410
 
411
            WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START);
412
 
413
            WRITE_REG(NIC_TCR, 0);
414
            }
415
 
416
    dev->interrupt = 0;
417
    return;
418
    }
419
 
420
 
421
/*
422
 * packet transmit routine
423
 */
424
static int hydra_start_xmit(struct sk_buff *skb, struct device *dev)
425
    {
426
    struct hydra_private *priv = (struct hydra_private *)dev->priv;
427
    volatile u_char *nicbase = priv->hydra_nic_base;
428
    int len, len1;
429
 
430
        /* Transmitter timeout, serious problems. */
431
 
432
    if(dev->tbusy)
433
        {
434
        int tickssofar = jiffies - dev->trans_start;
435
        if(tickssofar < 20)
436
            return(1);
437
        WRITE_REG(NIC_CR, CR_STOP);
438
        printk("%s: transmit timed out, status %4.4x, resetting.\n", dev->name, 0);
439
        priv->stats.tx_errors++;
440
 
441
 
442
        dev->tbusy = 0;
443
        dev->trans_start = jiffies;
444
        dev_kfree_skb(skb, FREE_WRITE);
445
        return(0);
446
        }
447
 
448
 
449
    if(skb == NULL)
450
        {
451
        dev_tint(dev);
452
        return(0);
453
        }
454
 
455
    if((len = skb->len) <= 0)
456
        return(0);
457
 
458
    /* fill in a tx ring entry */
459
 
460
#ifdef HYDRA_DEBUG
461
 printk("TX pkt type 0x%04x from ", ((u_short *)skb->data)[6]);
462
        {
463
                int i;
464
                u_char *ptr = &((u_char *)skb->data)[6];
465
                for (i = 0; i < 6; i++)
466
                        printk("%02x", ptr[i]);
467
        }
468
        printk(" to ");
469
        {
470
                int i;
471
                u_char *ptr = (u_char *)skb->data;
472
                for (i = 0; i < 6; i++)
473
                        printk("%02x", ptr[i]);
474
        }
475
        printk(" data 0x%08x len %d\n", (int)skb->data, len);
476
#endif
477
 
478
    /*
479
     * make sure that the packet size is at least the minimum
480
     * allowed ethernet packet length.
481
     * (possibly should also clear the unused space...)
482
     * note: minimum packet length is 64, including CRC
483
     */
484
    len1 = len;
485
    if(len < (ETHER_MIN_LEN-4))
486
        len = (ETHER_MIN_LEN-1);
487
 
488
    /* make sure we've got an even number of bytes to copy to hydra's mem */
489
    if(len & 1) len++;
490
 
491
    if((u_long)(priv->hydra_base + (priv->tx_page_start << 8)) < 0x80000000)
492
      printk("weirdness: memcpyw(txbuf, skbdata, len): txbuf = 0x%x\n", (u_int)(priv->hydra_base+(priv->tx_page_start<<8)));
493
 
494
    /* copy the packet data to the transmit buffer
495
       in the ethernet card RAM */
496
    memcpyw((u_short *)(priv->hydra_base + (priv->tx_page_start << 8)),
497
            (u_short *)skb->data, len);
498
    /* clear the unused space */
499
/*    for(; len1<len; len1++)
500
      (u_short)*(priv->hydra_base + (priv->tx_page_start<<8) + len1) = 0;
501
*/
502
    dev_kfree_skb(skb, FREE_WRITE);
503
 
504
    priv->stats.tx_packets++;
505
 
506
    cli();
507
    /* make sure we are on the correct page */
508
    WRITE_REG(NIC_CR, CR_PAGE0 | CR_NODMA | CR_START);
509
 
510
    /* here we configure the transmit page start register etc */
511
    /* notice that this code is hardwired to one transmit buffer */
512
    WRITE_REG(NIC_TPSR, priv->tx_page_start);
513
    WRITE_REG(NIC_TBCR0, len & 0xff);
514
    WRITE_REG(NIC_TBCR1, len >> 8);
515
 
516
    /* commit the packet to the wire */
517
    WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA | CR_TXP);
518
    sti();
519
 
520
    dev->trans_start = jiffies;
521
 
522
    return(0);
523
    }
524
 
525
 
526
static void __inline__ hydra_rx(struct device *dev, struct hydra_private *priv, volatile u_char *nicbase)
527
    {
528
    volatile u_short *board_ram_ptr;
529
    struct sk_buff *skb;
530
    int hdr_next_pkt, pkt_len, len1, boundary;
531
 
532
 
533
    /* remove packet(s) from the ring and commit them to TCP layer */
534
    WRITE_REG(NIC_CR, CR_PAGE1 | CR_NODMA | CR_START); /* page 1 */
535
    while(priv->next_pkt != READ_REG(NIC_CURR)) /* should read this only once? */
536
      {
537
        board_ram_ptr = (u_short *)(priv->hydra_base + (priv->next_pkt << 8));
538
 
539
#ifdef HYDRA_DEBUG
540
        printk("next_pkt = 0x%x, board_ram_ptr = 0x%x\n", priv->next_pkt, board_ram_ptr);
541
#endif
542
 
543
        /* the following must be done with two steps, or
544
           GCC optimizes it to a byte access to Hydra memory,
545
           which doesn't work... */
546
        hdr_next_pkt = board_ram_ptr[0];
547
        hdr_next_pkt >>= 8;
548
 
549
        pkt_len = board_ram_ptr[1];
550
        pkt_len = ((pkt_len >> 8) | ((pkt_len & 0xff) << 8));
551
 
552
#ifdef HYDRA_DEBUG
553
        printk("hydra_interrupt(): hdr_next_pkt = 0x%02x, len = %d\n", hdr_next_pkt, pkt_len);
554
#endif
555
 
556
        if(pkt_len >= ETHER_MIN_LEN && pkt_len <= ETHER_MAX_LEN)
557
          {
558
            /* note that board_ram_ptr is u_short */
559
            /* CRC is not included in the packet length */
560
 
561
            pkt_len -= 4;
562
            skb = dev_alloc_skb(pkt_len+2);
563
            if(skb == NULL)
564
              {
565
                printk("%s: memory squeeze, dropping packet.\n", dev->name);
566
                priv->stats.rx_dropped++;
567
              }
568
            else
569
              {
570
                skb->dev = dev;
571
                skb_reserve(skb, 2);
572
 
573
                if(hdr_next_pkt < priv->next_pkt && hdr_next_pkt != priv->rx_page_start)
574
                  {
575
                    /* here, the packet is wrapped */
576
                    len1 = ((priv->rx_page_stop - priv->next_pkt)<<8)-4;
577
 
578
                    memcpyw((u_short *)skb_put(skb, len1), (u_short *)(board_ram_ptr+2), len1);
579
                    memcpyw((u_short *)skb_put(skb, pkt_len-len1),  (u_short *)(priv->hydra_base+(priv->rx_page_start<<8)), pkt_len-len1);
580
 
581
#ifdef HYDRA_DEBUG
582
                    printk("wrapped packet: %d/%d bytes\n", len1, pkt_len-len1);
583
#endif
584
                  }  /* ... here, packet is not wrapped */
585
                else memcpyw((u_short *) skb_put(skb, pkt_len), (u_short *)(board_ram_ptr+2), pkt_len);
586
              }
587
            /* if(skb == NULL) ... */
588
          }
589
        else
590
          {
591
            WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA);
592
            printk("hydra_interrupt(): invalid packet len: %d, NIC_CURR = %02x\n", pkt_len, READ_REG(NIC_CURR));
593
/*
594
this is the error i kept getting until i switched to 0.9.10. it still doesn't
595
mean that the bug would have gone away - so be alarmed. the packet is likely
596
being fetched from a wrong memory location - but why - dunno
597
 
598
note-for-v2.1: not really problem anymore. hasn't been for a long time.
599
*/
600
 
601
            WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
602
            /* should probably reset the NIC here ?? */
603
 
604
            hydra_open(dev);  /* FIXME - i shouldn't really be doing this. */
605
            return;
606
          }
607
 
608
        /* now, update the next_pkt pointer */
609
        if(hdr_next_pkt < priv->rx_page_stop) priv->next_pkt = hdr_next_pkt;
610
        else printk("hydra_interrupt(): invalid next_pkt pointer %d\n", hdr_next_pkt);
611
 
612
        /* update the boundary pointer */
613
        boundary = priv->next_pkt - 1;
614
        if(boundary < priv->rx_page_start)
615
          boundary = priv->rx_page_stop - 1;
616
 
617
        /* set NIC to page 0 to update the NIC_BNDRY register */
618
        WRITE_REG(NIC_CR, CR_PAGE0 | CR_START | CR_NODMA);
619
        WRITE_REG(NIC_BNDRY, boundary);
620
 
621
        /* select page1 to access the NIC_CURR register */
622
        WRITE_REG(NIC_CR, CR_PAGE1 | CR_START | CR_NODMA);
623
 
624
 
625
        skb->protocol = eth_type_trans(skb, dev);
626
        netif_rx(skb);
627
        priv->stats.rx_packets++;
628
 
629
      }
630
    return;
631
    }
632
 
633
 
634
static struct enet_statistics *hydra_get_stats(struct device *dev)
635
{
636
        struct hydra_private *priv = (struct hydra_private *)dev->priv;
637
#if 0
638
        u_char *board = priv->hydra_base;
639
 
640
        short saved_addr;
641
#endif
642
/* currently does nothing :) i'll finish this later */
643
 
644
        return(&priv->stats);
645
}
646
 
647
#ifdef HAVE_MULTICAST
648
static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
649
    {
650
    struct hydra_private *priv = (struct hydra_private *)dev->priv;
651
    u_char *board = priv->hydra_base;
652
 
653
    /* yes, this code is also waiting for someone to complete.. :) */
654
    /* (personally i don't care about multicasts at all :) */
655
    return;
656
    }
657
#endif
658
 
659
 
660
#ifdef MODULE
661
static char devicename[9] = { 0, };
662
 
663
static struct device hydra_dev =
664
{
665
        devicename,                     /* filled in by register_netdev() */
666
        0, 0, 0, 0,                 /* memory */
667
        0, 0,                             /* base, irq */
668
        0, 0, 0, NULL, hydra_probe,
669
};
670
 
671
int init_module(void)
672
{
673
        int err;
674
 
675
        if ((err = register_netdev(&hydra_dev))) {
676
                if (err == -EIO)
677
                        printk("No Hydra board found. Module not loaded.\n");
678
                return(err);
679
        }
680
        return(0);
681
}
682
 
683
void cleanup_module(void)
684
{
685
        struct hydra_private *priv = (struct hydra_private *)hydra_dev.priv;
686
 
687
        unregister_netdev(&hydra_dev);
688
        zorro_unconfig_board(priv->key, 0);
689
        kfree(priv);
690
}
691
 
692
#endif /* MODULE */

powered by: WebSVN 2.1.0

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