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 743

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

powered by: WebSVN 2.1.0

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