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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [or32/] [drivers/] [open_eth.c] - Blame information for rev 7

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

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

powered by: WebSVN 2.1.0

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