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

Subversion Repositories or1k

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

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

Line No. Rev Author Line
1 743 simons
/*
2
 * Ethernet driver for Open Ethernet Controller (www.opencores.org).
3
 *      Copyright (c) 2002 Simon Srot (simons@opencores.org)
4
 *
5
 * Based on:
6
 *
7
 * Ethernet driver for Motorola MPC8xx.
8
 *      Copyright (c) 1997 Dan Malek (dmalek@jlc.net)
9
 *
10
 * mcen302.c: A Linux network driver for Mototrola 68EN302 MCU
11
 *
12
 *      Copyright (C) 1999 Aplio S.A. Written by Vadim Lebedev
13
 *
14
 * Rigt now XXBUFF_PREALLOC must be used, bacause MAC does not
15
 * handle unaligned buffers yet.  Also the cache inhibit calls
16
 * should be used some day.
17
 *
18
 */
19
 
20
#include <linux/config.h>
21
#include <linux/kernel.h>
22
#include <linux/sched.h>
23
#include <linux/string.h>
24
#include <linux/ptrace.h>
25
#include <linux/errno.h>
26
#include <linux/ioport.h>
27
#include <linux/interrupt.h>
28
#include <linux/delay.h>
29
#include <linux/inet.h>
30
#include <linux/netdevice.h>
31
#include <linux/etherdevice.h>
32
#include <linux/skbuff.h>
33
 
34
#include <asm/irq.h>
35
#include <asm/pgtable.h>
36
#include <asm/bitops.h>
37
 
38
 
39
#include "open_eth.h"
40
 
41
#define net_device device
42
#define __pa(x) (x)
43
#define __va(x) (x)
44
#define __clear_user(add,len) memset((add),0,(len))
45
 
46
#define DEBUG 1
47
 
48
#define RXBUFF_PREALLOC 1
49
#define TXBUFF_PREALLOC 1
50
 
51 764 simons
#define SRAM_BUFF       1
52
#define SRAM_BUFF_BASE  (FBMEM_BASE_ADD + 0x80000)
53
 
54 743 simons
/* The transmitter timeout
55
 */
56
#define TX_TIMEOUT      (2*HZ)
57
 
58
/* Buffer number (must be 2^n)
59
 */
60
#define OETH_RXBD_NUM           8
61
#define OETH_TXBD_NUM           8
62
#define OETH_RXBD_NUM_MASK      (OETH_RXBD_NUM-1)
63
#define OETH_TXBD_NUM_MASK      (OETH_TXBD_NUM-1)
64
 
65
/* Buffer size
66
 */
67
#define OETH_RX_BUFF_SIZE       2048
68
#define OETH_TX_BUFF_SIZE       2048
69
 
70
/* How many buffers per page
71
 */
72
#define OETH_RX_BUFF_PPGAE      (PAGE_SIZE/OETH_RX_BUFF_SIZE)
73
#define OETH_TX_BUFF_PPGAE      (PAGE_SIZE/OETH_TX_BUFF_SIZE)
74
 
75
/* How many pages is needed for buffers
76
 */
77
#define OETH_RX_BUFF_PAGE_NUM   (OETH_RXBD_NUM/OETH_RX_BUFF_PPGAE)
78
#define OETH_TX_BUFF_PAGE_NUM   (OETH_TXBD_NUM/OETH_TX_BUFF_PPGAE)
79
 
80
/* Buffer size  (if not XXBUF_PREALLOC
81
 */
82
#define MAX_FRAME_SIZE          1518
83
 
84
/* The buffer descriptors track the ring buffers.
85
 */
86
struct oeth_private {
87
        struct  sk_buff* rx_skbuff[OETH_RXBD_NUM];
88
        struct  sk_buff* tx_skbuff[OETH_TXBD_NUM];
89
 
90
        ushort  tx_next;                        /* Next buffer to be sent */
91
        ushort  tx_last;                        /* Next buffer to be checked if packet sent */
92
        ushort  tx_full;                        /* Buffer ring fuul indicator */
93
        ushort  rx_cur;                         /* Next buffer to be checked if packet received */
94
 
95
        oeth_regs       *regs;                  /* Address of controller registers. */
96
        oeth_bd         *rx_bd_base;            /* Address of Rx BDs. */
97
        oeth_bd         *tx_bd_base;            /* Address of Tx BDs. */
98
 
99
        struct enet_statistics stats;
100
};
101
 
102
static int oeth_open(struct net_device *dev);
103
static int oeth_start_xmit(struct sk_buff *skb, struct net_device *dev);
104
static void oeth_rx(struct net_device *dev);
105
static void oeth_tx(struct net_device *dev);
106
static void oeth_interrupt(int irq, void *dev_id, struct pt_regs *regs);
107
static int oeth_close(struct net_device *dev);
108
static struct enet_statistics *oeth_get_stats(struct net_device *dev);
109
static void oeth_set_multicast_list(struct net_device *dev);
110
static void oeth_set_mac_add(struct device *dev, void *addr);
111
static int calc_crc(char *mac_addr);
112
 
113
#if DEBUG
114
static void
115
oeth_print_packet(unsigned long add, int len)
116
{
117
        int i;
118
 
119
        _print("ipacket: add = %x len = %d\n", add, len);
120
        for(i = 0; i < len; i++) {
121
                if(!(i % 16))
122
                        _print("\n");
123
                _print(" %.2x", *(((unsigned char *)add) + i));
124
        }
125
        _print("\n");
126
}
127
#endif
128
 
129
static int
130
oeth_open(struct net_device *dev)
131
{
132
 
133
        oeth_regs *regs = (oeth_regs *)dev->base_addr;
134
 
135
#ifndef RXBUFF_PREALLOC
136
        struct oeth_private *cep = (struct oeth_private *)dev->priv;
137
        struct  sk_buff *skb;
138
        volatile oeth_bd *rx_bd;
139
        int i;
140
 
141
        rx_bd = cep->rx_bd_base;
142
 
143
        for(i = 0; i < OETH_RXBD_NUM; i++) {
144
 
145
                skb = dev_alloc_skb(MAX_FRAME_SIZE);
146
 
147
                if (skb == NULL)
148
                        rx_bd[i].status = OETH_RX_BD_IRQ;
149
                else
150
                        rx_bd[i].status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ;
151
 
152
                cep->rx_skbuff[i] = skb;
153
 
154
                rx_bd[i].len = 0;
155
                rx_bd[i].addr = (unsigned long)skb->tail;
156
        }
157
        rx_bd[OETH_RXBD_NUM - 1].status |= OETH_RX_BD_WRAP;
158
#endif
159
 
160
        /* Install our interrupt handler.
161
         */
162
        request_irq(IRQ_ETH_0, oeth_interrupt, 0, "eth", (void *)dev);
163
 
164
        /* Enable receiver and transmiter
165
         */
166
        regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN;
167
 
168
        return 0;
169
}
170
 
171
static int
172
oeth_close(struct net_device *dev)
173
{
174
        struct oeth_private *cep = (struct oeth_private *)dev->priv;
175
        oeth_regs *regs = (oeth_regs *)dev->base_addr;
176
        volatile oeth_bd *bdp;
177
        int i;
178
 
179
        /* Free interrupt hadler
180
         */
181
        free_irq(IRQ_ETH_0, (void *)dev);
182
 
183
        /* Disable receiver and transmitesr
184
         */
185
        regs->moder &= ~(OETH_MODER_RXEN | OETH_MODER_TXEN);
186
 
187
        bdp = cep->rx_bd_base;
188
        for (i = 0; i < OETH_RXBD_NUM; i++) {
189
                bdp->status &= ~(OETH_TX_BD_STATS | OETH_TX_BD_READY);
190
                bdp++;
191
        }
192
 
193
        bdp = cep->tx_bd_base;
194
        for (i = 0; i < OETH_TXBD_NUM; i++) {
195
                bdp->status &= ~(OETH_RX_BD_STATS | OETH_RX_BD_EMPTY);
196
                bdp++;
197
        }
198
 
199
#ifndef RXBUFF_PREALLOC
200
 
201
        /* Free all alocated rx buffers
202
         */
203
        for (i = 0; i < OETH_RXBD_NUM; i++) {
204
 
205
                if (cep->rx_skbuff[i] != NULL)
206
                        dev_kfree_skb(cep->rx_skbuff[i], FREE_READ);
207
 
208
        }
209
#endif
210
#ifndef TXBUFF_PREALLOC
211
 
212
        /* Free all alocated tx buffers
213
         */
214
        for (i = 0; i < OETH_TXBD_NUM; i++) {
215
 
216
                if (cep->tx_skbuff[i] != NULL)
217
                        dev_kfree_skb(cep->tx_skbuff[i], FREE_WRITE);
218
        }
219
#endif
220
 
221
        return 0;
222
}
223
 
224
static int
225
oeth_start_xmit(struct sk_buff *skb, struct net_device *dev)
226
{
227
        struct oeth_private *cep = (struct oeth_private *)dev->priv;
228
        volatile oeth_bd *bdp;
229
        unsigned long flags;
230
 
231
        /* Fill in a Tx ring entry
232
         */
233
        bdp = cep->tx_bd_base + cep->tx_next;
234
 
235
        if (cep->tx_full) {
236
 
237
                /* All transmit buffers are full.  Bail out.
238
                 */
239
                printk("%s: tx queue full!.\n", dev->name);
240
                return 1;
241
        }
242
 
243
        /* Clear all of the status flags.
244
         */
245
        bdp->status &= ~OETH_TX_BD_STATS;
246
 
247
        /* If the frame is short, tell CPM to pad it.
248
         */
249
        if (skb->len <= ETH_ZLEN)
250
                bdp->status |= OETH_TX_BD_PAD;
251
        else
252
                bdp->status &= ~OETH_TX_BD_PAD;
253
 
254
#if DEBUG
255
        _print("TX\n");
256
        oeth_print_packet(skb->data, skb->len);
257
#endif
258
 
259
#ifdef TXBUFF_PREALLOC
260
 
261
        /* Copy data in preallocated buffer */
262
        if (skb->len > OETH_TX_BUFF_SIZE) {
263
                printk("%s: tx frame too long!.\n", dev->name);
264
                return 1;
265
        }
266
        else
267
                memcpy((unsigned char *)bdp->addr, skb->data, skb->len);
268
 
269
        bdp->len = skb->len;
270
 
271
        dev_kfree_skb(skb, FREE_WRITE);
272
#else
273
        /* Set buffer length and buffer pointer.
274
         */
275
        bdp->len = skb->len;
276
        bdp->addr = (uint)__pa(skb->data);
277
 
278
        /* Save skb pointer.
279
         */
280
        cep->tx_skbuff[cep->tx_next] = skb;
281
#endif
282
 
283
        cep->tx_next = (cep->tx_next + 1) & OETH_TXBD_NUM_MASK;
284
 
285
        save_flags(flags); cli();
286
 
287
        if (cep->tx_next == cep->tx_last)
288
                cep->tx_full = 1;
289
 
290
        /* Send it on its way.  Tell controller its ready, interrupt when done,
291
         * and to put the CRC on the end.
292
         */
293
        bdp->status |= (OETH_TX_BD_READY | OETH_TX_BD_IRQ | OETH_TX_BD_CRC);
294
 
295
        dev->trans_start = jiffies;
296
 
297
        restore_flags(flags);
298
 
299
        return 0;
300
}
301
 
302
/* The interrupt handler.
303
 */
304
static void
305
oeth_interrupt(int irq, void *dev_id, struct pt_regs *regs)
306
{
307
        struct  net_device *dev = dev_id;
308
        volatile struct oeth_private *cep;
309
        uint    int_events;
310
 
311
        cep = (struct oeth_private *)dev->priv;
312
 
313
        /* Get the interrupt events that caused us to be here.
314
         */
315
        int_events = cep->regs->int_src;
316
        cep->regs->int_src = int_events;
317
 
318
        /* Handle receive event in its own function.
319
         */
320
        if (int_events & (OETH_INT_RXF | OETH_INT_RXE))
321
                oeth_rx(dev_id);
322
 
323
        /* Handle transmit event in its own function.
324
         */
325
        if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) {
326
                oeth_tx(dev_id);
327
                mark_bh(NET_BH);
328
        }
329
 
330
        /* Check for receive busy, i.e. packets coming but no place to
331
         * put them.
332
         */
333
        if (int_events & OETH_INT_BUSY) {
334
                if (!(int_events & (OETH_INT_RXF | OETH_INT_RXE)))
335
                        oeth_rx(dev_id);
336
        }
337
 
338
        return;
339
}
340
 
341
 
342
static void
343
oeth_tx(struct net_device *dev)
344
{
345
        struct  oeth_private *cep;
346
        volatile oeth_bd *bdp;
347
 
348
#ifndef TXBUFF_PREALLOC
349
        struct  sk_buff *skb;
350
#endif
351
 
352
        cep = (struct oeth_private *)dev->priv;
353
 
354
        for (;; cep->tx_last = (cep->tx_last + 1) & OETH_TXBD_NUM_MASK) {
355
 
356
                bdp = cep->tx_bd_base + cep->tx_last;
357
 
358
                if ((bdp->status & OETH_TX_BD_READY) ||
359
                        ((cep->tx_last == cep->tx_next) && !cep->tx_full))
360
                        break;
361
 
362
                /* Check status for errors
363
                 */
364
                if (bdp->status & OETH_TX_BD_LATECOL)
365
                        cep->stats.tx_window_errors++;
366
                if (bdp->status & OETH_TX_BD_RETLIM)
367
                        cep->stats.tx_aborted_errors++;
368
                if (bdp->status & OETH_TX_BD_UNDERRUN)
369
                        cep->stats.tx_fifo_errors++;
370
                if (bdp->status & OETH_TX_BD_CARRIER)
371
                        cep->stats.tx_carrier_errors++;
372
                if (bdp->status & (OETH_TX_BD_LATECOL | OETH_TX_BD_RETLIM | OETH_TX_BD_UNDERRUN))
373
                        cep->stats.tx_errors++;
374
 
375
                cep->stats.tx_packets++;
376
                cep->stats.collisions += (bdp->status >> 4) & 0x000f;
377
 
378
#ifndef TXBUFF_PREALLOC
379
                skb = cep->tx_skbuff[cep->tx_last];
380
 
381
                /* Free the sk buffer associated with this last transmit.
382
                */
383
                dev_kfree_skb(skb, FREE_WRITE);
384
#endif
385
 
386
                if (cep->tx_full)
387
                        cep->tx_full = 0;
388
        }
389
}
390
 
391
static void
392
oeth_rx(struct net_device *dev)
393
{
394
        struct  oeth_private *cep;
395
        volatile oeth_bd *bdp;
396
        struct  sk_buff *skb;
397
        int     pkt_len;
398
        int     bad = 0;
399
#ifndef RXBUFF_PREALLOC
400
        struct  sk_buff *small_skb;
401
#endif
402
 
403
        cep = (struct oeth_private *)dev->priv;
404
 
405
        /* First, grab all of the stats for the incoming packet.
406
         * These get messed up if we get called due to a busy condition.
407
         */
408
        for (;;cep->rx_cur = (cep->rx_cur + 1) & OETH_RXBD_NUM_MASK) {
409
 
410
                bdp = cep->rx_bd_base + cep->rx_cur;
411
 
412
#ifndef RXBUFF_PREALLOC
413
                skb = cep->rx_skbuff[cep->rx_cur];
414
 
415
                if (skb == NULL) {
416
 
417
                        skb = dev_alloc_skb(MAX_FRAME_SIZE);
418
 
419
                        if (skb != NULL)
420
                        {
421
                                bdp->addr = (unsigned long) skb->tail;
422
                                bdp->status |= OETH_RX_BD_EMPTY;
423
                        }
424
 
425
                        continue;
426
                }
427
#endif
428
 
429
                if (bdp->status & OETH_RX_BD_EMPTY)
430
                        break;
431
 
432
                /* Check status for errors.
433
                 */
434
                if (bdp->status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) {
435
                        cep->stats.rx_length_errors++;
436
                        bad = 1;
437
                }
438
                if (bdp->status & OETH_RX_BD_DRIBBLE) {
439
                        cep->stats.rx_frame_errors++;
440
                        bad = 1;
441
                }
442
                if (bdp->status & OETH_RX_BD_CRCERR) {
443
                        cep->stats.rx_crc_errors++;
444
                        bad = 1;
445
                }
446
                if (bdp->status & OETH_RX_BD_OVERRUN) {
447
                        cep->stats.rx_crc_errors++;
448
                        bad = 1;
449
                }
450
                if (bdp->status & OETH_RX_BD_MISS) {
451
 
452
                }
453
                if (bdp->status & OETH_RX_BD_LATECOL) {
454
                        cep->stats.rx_frame_errors++;
455
                        bad = 1;
456
                }
457
 
458
 
459
                if (bad) {
460
 
461
                        bdp->status &= ~OETH_RX_BD_STATS;
462
                        bdp->status |= OETH_RX_BD_EMPTY;
463
 
464
                        continue;
465
                }
466
 
467
                /* Process the incoming frame.
468
                 */
469
                pkt_len = bdp->len;
470
 
471
#ifdef RXBUFF_PREALLOC
472
                skb = dev_alloc_skb(pkt_len);
473
 
474
                if (skb == NULL) {
475
                        printk("%s: Memory squeeze, dropping packet.\n", dev->name);
476
                        cep->stats.rx_dropped++;
477
                }
478
                else {
479
                        skb->dev = dev;
480
#if DEBUG
481
                        _print("RX\n");
482
                        oeth_print_packet(bdp->addr, pkt_len);
483
#endif
484
                        memcpy(skb_put(skb, pkt_len), (unsigned char *)__va(bdp->addr), pkt_len);
485
                        skb->protocol = eth_type_trans(skb,dev);
486
                        netif_rx(skb);
487
                        cep->stats.rx_packets++;
488
                }
489
 
490
                bdp->status &= ~OETH_RX_BD_STATS;
491
                bdp->status |= OETH_RX_BD_EMPTY;
492
#else
493
 
494
                if (pkt_len < 128) {
495
 
496
                        small_skb = dev_alloc_skb(pkt_len);
497
 
498
                        if (small_skb) {
499
                                small_skb->dev = dev;
500
#if DEBUG
501
                                _print("RX short\n");
502
                                oeth_print_packet(bdp->addr, bdp->len);
503
#endif
504
                                memcpy(skb_put(small_skb, pkt_len), (unsigned char *)__va(bdp->addr), pkt_len);
505
                                small_skb->protocol = eth_type_trans(small_skb,dev);
506
                                netif_rx(small_skb);
507
                                cep->stats.rx_packets++;
508
                        }
509
                        else {
510
                                printk("%s: Memory squeeze, dropping packet.\n", dev->name);
511
                                cep->stats.rx_dropped++;
512
                        }
513
 
514
                        bdp->status &= ~OETH_RX_BD_STATS;
515
                        bdp->status |= OETH_RX_BD_EMPTY;
516
                }
517
                else {
518
                        skb->dev = dev;
519
                        skb_put(skb, bdp->len);
520
                        skb->protocol = eth_type_trans(skb,dev);
521
                        netif_rx(skb);
522
                        cep->stats.rx_packets++;
523
#if DEBUG
524
                        _print("RX long\n");
525
                        oeth_print_packet(bdp->addr, bdp->len);
526
#endif
527
 
528
                        skb = dev_alloc_skb(MAX_FRAME_SIZE);
529
 
530
                        bdp->status &= ~OETH_RX_BD_STATS;
531
 
532
                        if (skb) {
533
                                cep->rx_skbuff[cep->rx_cur] = skb;
534
 
535
                                bdp->addr = (unsigned long)skb->tail;
536
                                bdp->status |= OETH_RX_BD_EMPTY;
537
                        }
538
                        else {
539
                                cep->rx_skbuff[cep->rx_cur] = NULL;
540
                        }
541
                }
542
#endif
543
        }
544
}
545
 
546
static int calc_crc(char *mac_addr)
547
{
548
        int result = 0;
549
        return (result & 0x3f);
550
}
551
 
552
static struct enet_statistics *oeth_get_stats(struct net_device *dev)
553
{
554
        struct oeth_private *cep = (struct oeth_private *)dev->priv;
555
 
556
        return &cep->stats;
557
}
558
 
559
static void oeth_set_multicast_list(struct net_device *dev)
560
{
561
        struct  oeth_private *cep;
562
        struct  dev_mc_list *dmi;
563
        volatile oeth_regs *regs;
564
        int     i;
565
 
566
        cep = (struct oeth_private *)dev->priv;
567
 
568
        /* Get pointer of controller registers.
569
         */
570
        regs = (oeth_regs *)dev->base_addr;
571
 
572
        if (dev->flags & IFF_PROMISC) {
573
 
574
                /* Log any net taps.
575
                 */
576
                printk("%s: Promiscuous mode enabled.\n", dev->name);
577
                regs->moder |= OETH_MODER_PRO;
578
        } else {
579
 
580
                regs->moder &= ~OETH_MODER_PRO;
581
 
582
                if (dev->flags & IFF_ALLMULTI) {
583
 
584
                        /* Catch all multicast addresses, so set the
585
                         * filter to all 1's.
586
                         */
587
                        regs->hash_addr0 = 0xffffffff;
588
                        regs->hash_addr1 = 0xffffffff;
589
                }
590
                else if (dev->mc_count) {
591
 
592
                        /* Clear filter and add the addresses in the list.
593
                         */
594
                        regs->hash_addr0 = 0x00000000;
595
                        regs->hash_addr0 = 0x00000000;
596
 
597
                        dmi = dev->mc_list;
598
 
599
                        for (i = 0; i < dev->mc_count; i++) {
600
 
601
                                int hash_b;
602
 
603
                                /* Only support group multicast for now.
604
                                 */
605
                                if (!(dmi->dmi_addr[0] & 1))
606
                                        continue;
607
 
608
                                hash_b = calc_crc(dmi->dmi_addr);
609
                                if(hash_b >= 32)
610
                                        regs->hash_addr1 |= 1 << (hash_b - 32);
611
                                else
612
                                        regs->hash_addr0 |= 1 << hash_b;
613
                        }
614
                }
615
        }
616
}
617
 
618
static void oeth_set_mac_add(struct net_device *dev, void *p)
619
{
620
        struct sockaddr *addr=p;
621
        volatile oeth_regs *regs;
622
 
623
        memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
624
 
625
        regs = (oeth_regs *)dev->base_addr;
626
 
627
        regs->mac_addr1 =       addr->sa_data[0] << 8    |
628
                                addr->sa_data[1];
629
        regs->mac_addr0 =       addr->sa_data[2] << 24  |
630
                                addr->sa_data[3] << 16  |
631
                                addr->sa_data[4] << 8   |
632
                                addr->sa_data[5];
633
}
634
 
635
/* Initialize the Open Ethernet MAC.
636
 */
637
int oeth_probe(struct net_device *dev)
638
{
639
        struct oeth_private *cep;
640
        volatile oeth_regs *regs;
641
        volatile oeth_bd *tx_bd, *rx_bd;
642
        int i, j, k;
643 764 simons
        unsigned long mem_addr = SRAM_BUFF_BASE;
644 743 simons
 
645
        cep = (struct oeth_private *)dev->priv;
646
 
647
        /* Allocate a new 'dev' if needed.
648
         */
649
        if (dev == NULL) {
650
                /*
651
                 * Don't allocate the private data here, it is done later
652
                 * This makes it easier to free the memory when this driver
653
                 * is used as a module.
654
                 */
655
                dev = init_etherdev(0, 0);
656
                if (dev == NULL)
657
                        return -ENOMEM;
658
        }
659
 
660
        /* Initialize the device structure.
661
         */
662
        if (dev->priv == NULL) {
663
                cep = (struct oeth_private *)kmalloc(sizeof(*cep), GFP_KERNEL);
664
                dev->priv = cep;
665
                if (dev->priv == NULL)
666
                        return -ENOMEM;
667
        }
668
 
669
        __clear_user(cep,sizeof(*cep));
670
 
671
        /* Get pointer ethernet controller configuration registers.
672
         */
673
        cep->regs = (oeth_regs *)(OETH_REG_BASE);
674
        regs = (oeth_regs *)(OETH_REG_BASE);
675
 
676
        /* Reset the controller.
677
         */
678
        regs->moder = OETH_MODER_RST;   /* Reset ON */
679 800 simons
        regs->moder &= ~OETH_MODER_RST; /* Reset OFF */
680 743 simons
 
681
        /* Setting TXBD base to OETH_TXBD_NUM.
682
         */
683
        regs->tx_bd_num = OETH_TXBD_NUM << 1;
684
 
685
        /* Initialize TXBD pointer
686
         */
687
        cep->tx_bd_base = (oeth_bd *)OETH_BD_BASE;
688
        tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
689
 
690
        /* Initialize RXBD pointer
691
         */
692
        cep->rx_bd_base = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
693
        rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
694
 
695
        /* Initialize transmit pointers.
696
         */
697
        cep->rx_cur = 0;
698
        cep->tx_next = 0;
699
        cep->tx_last = 0;
700
        cep->tx_full = 0;
701
 
702
        /* Set min/max packet length
703
         */
704
        regs->packet_len = 0x003c0600;
705
 
706
        /* Set IPGT register to recomended value
707
         */
708
        regs->ipgt = 0x00000012;
709
 
710
        /* Set IPGR1 register to recomended value
711
         */
712
        regs->ipgr1 = 0x0000000c;
713
 
714
        /* Set IPGR2 register to recomended value
715
         */
716
        regs->ipgr2 = 0x00000012;
717
 
718
        /* Set COLLCONF register to recomended value
719
         */
720
        regs->collconf = 0x000f003f;
721
 
722
        /* Set control module mode
723
         */
724
#if 0
725
        regs->ctrlmoder = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW;
726
#else
727
        regs->ctrlmoder = 0;
728
#endif
729
 
730
#ifdef TXBUFF_PREALLOC
731
 
732
        /* Initialize TXBDs.
733
         */
734
        for(i = 0, k = 0; i < OETH_TX_BUFF_PAGE_NUM; i++) {
735
 
736 764 simons
#ifndef SRAM_BUFF
737
                mem_addr = __get_free_page(GFP_KERNEL);
738
#endif
739 743 simons
 
740
                for(j = 0; j < OETH_TX_BUFF_PPGAE; j++, k++) {
741
                        tx_bd[k].status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ;
742
                        tx_bd[k].addr = __pa(mem_addr);
743
                        mem_addr += OETH_TX_BUFF_SIZE;
744
                }
745
        }
746
        tx_bd[OETH_TXBD_NUM - 1].status |= OETH_TX_BD_WRAP;
747
#else
748
 
749
        /* Initialize TXBDs.
750
         */
751
        for(i = 0; i < OETH_TXBD_NUM; i++) {
752
 
753
                cep->tx_skbuff[i] = NULL;
754
 
755
                tx_bd[i].len = 0;
756
                tx_bd[i].status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ;
757
                tx_bd[i].addr = 0;
758
        }
759
        tx_bd[OETH_TXBD_NUM - 1].status |= OETH_TX_BD_WRAP;
760
#endif
761
 
762
#ifdef RXBUFF_PREALLOC
763
 
764
        /* Initialize RXBDs.
765
         */
766
        for(i = 0, k = 0; i < OETH_RX_BUFF_PAGE_NUM; i++) {
767
 
768 764 simons
#ifndef SRAM_BUFF
769
                mem_addr = __get_free_page(GFP_KERNEL);
770
#endif
771 743 simons
 
772
                for(j = 0; j < OETH_RX_BUFF_PPGAE; j++, k++) {
773
                        rx_bd[k].status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ;
774
                        rx_bd[k].addr = __pa(mem_addr);
775
                        mem_addr += OETH_RX_BUFF_SIZE;
776
                }
777
        }
778
        rx_bd[OETH_RXBD_NUM - 1].status |= OETH_RX_BD_WRAP;
779
 
780
#else
781
        /* Initialize RXBDs.
782
         */
783
        for(i = 0; i < OETH_RXBD_NUM; i++) {
784
 
785
 
786
                rx_bd[i].status = OETH_RX_BD_IRQ;
787
 
788
                cep->rx_skbuff[i] = NULL;
789
 
790
                rx_bd[i].len = 0;
791
                rx_bd[i].addr = 0;
792
        }
793
        rx_bd[OETH_RXBD_NUM - 1].status |= OETH_RX_BD_WRAP;
794
 
795
#endif
796
 
797
        /* Set default ethernet station address.
798
         */
799
        dev->dev_addr[0] = MACADDR0;
800
        dev->dev_addr[1] = MACADDR1;
801
        dev->dev_addr[2] = MACADDR2;
802
        dev->dev_addr[3] = MACADDR3;
803
        dev->dev_addr[4] = MACADDR4;
804
        dev->dev_addr[5] = MACADDR5;
805
 
806
        regs->mac_addr1 = MACADDR0 << 8 | MACADDR1;
807
        regs->mac_addr0 = MACADDR2 << 24 | MACADDR3 << 16 | MACADDR4 << 8 | MACADDR5;
808
 
809
        /* Clear all pending interrupts
810
         */
811
        regs->int_src = 0xffffffff;
812
 
813
        /* Promisc, IFG, CRCEn
814
         */
815
        regs->moder |= OETH_MODER_PAD | OETH_MODER_IFG | OETH_MODER_CRCEN;
816
 
817
        /* Enable interrupt sources.
818
         */
819
        regs->int_mask = OETH_INT_MASK_TXB      |
820
                        OETH_INT_MASK_TXE       |
821
                        OETH_INT_MASK_RXF       |
822
                        OETH_INT_MASK_RXE       |
823
                        OETH_INT_MASK_BUSY      |
824
                        OETH_INT_MASK_TXC       |
825
                        OETH_INT_MASK_RXC;
826
 
827
        /* Fill in the fields of the device structure with ethernet values.
828
         */
829
        ether_setup(dev);
830
 
831
        dev->base_addr = (unsigned long)OETH_REG_BASE;
832
 
833
        /* The Open Ethernet specific entries in the device structure.
834
         */
835
        dev->open = oeth_open;
836
        dev->hard_start_xmit = oeth_start_xmit;
837
        dev->stop = oeth_close;
838
        dev->get_stats = oeth_get_stats;
839
        dev->set_multicast_list = oeth_set_multicast_list;
840
        dev->set_mac_address = oeth_set_mac_add;
841
 
842
        printk("%s: Open Ethernet Core Version 1.0\n", dev->name);
843
 
844
        return 0;
845
}
846
 
847
 

powered by: WebSVN 2.1.0

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