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 827

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

powered by: WebSVN 2.1.0

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