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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [net/] [open_eth.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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