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 9

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

powered by: WebSVN 2.1.0

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