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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [net/] [cirrus.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
 
2
/*
3
 * linux/drivers/net/cirrus.c
4
 *
5
 * Author: Abraham van der Merwe <abraham@2d3d.co.za>
6
 *
7
 * A Cirrus Logic CS8900A driver for Linux
8
 * based on the cs89x0 driver written by Russell Nelson,
9
 * Donald Becker, and others.
10
 *
11
 * This source code is free software; you can redistribute it and/or
12
 * modify it under the terms of the GNU General Public License
13
 * version 2 as published by the Free Software Foundation.
14
 */
15
 
16
/*
17
 * At the moment the driver does not support memory mode operation.
18
 * It is trivial to implement this, but not worth the effort.
19
 */
20
 
21
/*
22
 * TODO:
23
 *
24
 *   1. If !ready in send_start(), queue buffer and send it in interrupt handler
25
 *      when we receive a BufEvent with Rdy4Tx, send it again. dangerous!
26
 *   2. how do we prevent interrupt handler destroying integrity of get_stats()?
27
 *   3. Change reset code to check status.
28
 *   4. Implement set_mac_address and remove fake mac address
29
 *   5. Link status detection stuff
30
 *   6. Write utility to write EEPROM, do self testing, etc.
31
 *   7. Implement DMA routines (I need a board w/ DMA support for that)
32
 *   8. Power management
33
 *   9. Add support for multiple ethernet chips
34
 *  10. Add support for other cs89xx chips (need hardware for that)
35
 */
36
 
37
#include <linux/config.h>
38
#include <linux/version.h>
39
#include <linux/module.h>
40
 
41
#include <linux/kernel.h>
42
#include <linux/types.h>
43
#include <linux/errno.h>
44
#include <linux/ioport.h>
45
#include <linux/init.h>
46
#include <linux/delay.h>
47
 
48
#include <asm/irq.h>
49
#include <asm/hardware.h>
50
#include <asm/io.h>
51
 
52
#include <linux/netdevice.h>
53
#include <linux/etherdevice.h>
54
#include <linux/skbuff.h>
55
 
56
#include "cirrus.h"
57
 
58
/* #define DEBUG */
59
/* #define FULL_DUPLEX */
60
 
61
#ifdef CONFIG_SA1100_FRODO
62
#       define CIRRUS_DEFAULT_IO FRODO_ETH_IO + 0x300
63
#       define CIRRUS_DEFAULT_IRQ FRODO_ETH_IRQ
64
#elif CONFIG_SA1100_CERF
65
#       define CIRRUS_DEFAULT_IO CERF_ETH_IO + 0x300
66
#       define CIRRUS_DEFAULT_IRQ CERF_ETH_IRQ
67
#elif CONFIG_ARCH_CDB89712
68
#       define CIRRUS_DEFAULT_IO ETHER_BASE + 0x300
69
#       define CIRRUS_DEFAULT_IRQ IRQ_EINT3
70
#else
71
#       define CIRRUS_DEFAULT_IO        0
72
#       define CIRRUS_DEFAULT_IRQ       0
73
#endif  /* #ifdef CONFIG_SA1100_CERF */
74
 
75
typedef struct {
76
        struct net_device_stats stats;
77
        u16 txlen;
78
} cirrus_t;
79
 
80
typedef struct {
81
        u16 io_base;            /* I/O Base Address                     */
82
        u16 irq;                        /* Interrupt Number                     */
83
        u16 dma;                        /* DMA Channel Numbers          */
84
        u32 mem_base;           /* Memory Base Address          */
85
        u32 rom_base;           /* Boot PROM Base Address       */
86
        u32 rom_mask;           /* Boot PROM Address Mask       */
87
        u8 mac[6];                      /* Individual Address           */
88
} cirrus_eeprom_t;
89
 
90
/*
91
 * I/O routines
92
 */
93
 
94
static inline u16 cirrus_read (struct net_device *dev,u16 reg)
95
{
96
        outw (reg,dev->base_addr + PP_Address);
97
        return (inw (dev->base_addr + PP_Data));
98
}
99
 
100
static inline void cirrus_write (struct net_device *dev,u16 reg,u16 value)
101
{
102
        outw (reg,dev->base_addr + PP_Address);
103
        outw (value,dev->base_addr + PP_Data);
104
}
105
 
106
static inline void cirrus_set (struct net_device *dev,u16 reg,u16 value)
107
{
108
        cirrus_write (dev,reg,cirrus_read (dev,reg) | value);
109
}
110
 
111
static inline void cirrus_clear (struct net_device *dev,u16 reg,u16 value)
112
{
113
        cirrus_write (dev,reg,cirrus_read (dev,reg) & ~value);
114
}
115
 
116
static inline void cirrus_frame_read (struct net_device *dev,struct sk_buff *skb,u16 length)
117
{
118
        insw (dev->base_addr,skb_put (skb,length),(length + 1) / 2);
119
}
120
 
121
static inline void cirrus_frame_write (struct net_device *dev,struct sk_buff *skb)
122
{
123
        outsw (dev->base_addr,skb->data,(skb->len + 1) / 2);
124
}
125
 
126
/*
127
 * Debugging functions
128
 */
129
 
130
#ifdef DEBUG
131
static inline int printable (int c)
132
{
133
        return ((c >= 32 && c <= 126) ||
134
                        (c >= 174 && c <= 223) ||
135
                        (c >= 242 && c <= 243) ||
136
                        (c >= 252 && c <= 253));
137
}
138
 
139
static void dump16 (struct net_device *dev,const u8 *s,size_t len)
140
{
141
        int i;
142
        char str[128];
143
 
144
        if (!len) return;
145
 
146
        *str = '\0';
147
 
148
        for (i = 0; i < len; i++) {
149
                if (i && !(i % 4)) strcat (str," ");
150
                sprintf (str,"%s%.2x ",str,s[i]);
151
        }
152
 
153
        for ( ; i < 16; i++) {
154
                if (i && !(i % 4)) strcat (str," ");
155
                strcat (str,"   ");
156
        }
157
 
158
        strcat (str," ");
159
        for (i = 0; i < len; i++) sprintf (str,"%s%c",str,printable (s[i]) ? s[i] : '.');
160
 
161
        printk (KERN_DEBUG "%s:     %s\n",dev->name,str);
162
}
163
 
164
static void hexdump (struct net_device *dev,const void *ptr,size_t size)
165
{
166
        const u8 *s = (u8 *) ptr;
167
        int i;
168
        for (i = 0; i < size / 16; i++, s += 16) dump16 (dev,s,16);
169
        dump16 (dev,s,size % 16);
170
}
171
 
172
static void dump_packet (struct net_device *dev,struct sk_buff *skb,const char *type)
173
{
174
        printk (KERN_INFO "%s: %s %d byte frame %.2x:%.2x:%.2x:%.2x:%.2x:%.2x to %.2x:%.2x:%.2x:%.2x:%.2x:%.2x type %.4x\n",
175
                        dev->name,
176
                        type,
177
                        skb->len,
178
                        skb->data[0],skb->data[1],skb->data[2],skb->data[3],skb->data[4],skb->data[5],
179
                        skb->data[6],skb->data[7],skb->data[8],skb->data[9],skb->data[10],skb->data[11],
180
                        (skb->data[12] << 8) | skb->data[13]);
181
        if (skb->len < 0x100) hexdump (dev,skb->data,skb->len);
182
}
183
#endif  /* #ifdef DEBUG */
184
 
185
/*
186
 * Driver functions
187
 */
188
 
189
static void cirrus_receive (struct net_device *dev)
190
{
191
        cirrus_t *priv = (cirrus_t *) dev->priv;
192
        struct sk_buff *skb;
193
        u16 status,length;
194
 
195
        status = cirrus_read (dev,PP_RxStatus);
196
        length = cirrus_read (dev,PP_RxLength);
197
 
198
        if (!(status & RxOK)) {
199
                priv->stats.rx_errors++;
200
                if ((status & (Runt | Extradata))) priv->stats.rx_length_errors++;
201
                if ((status & CRCerror)) priv->stats.rx_crc_errors++;
202
                return;
203
        }
204
 
205
        if ((skb = dev_alloc_skb (length + 4)) == NULL) {
206
                priv->stats.rx_dropped++;
207
                return;
208
        }
209
 
210
        skb->dev = dev;
211
        skb_reserve (skb,2);
212
 
213
        cirrus_frame_read (dev,skb,length);
214
 
215
#ifdef DEBUG
216
        dump_packet (dev,skb,"recv");
217
#endif  /* #ifdef DEBUG */
218
 
219
        skb->protocol = eth_type_trans (skb,dev);
220
 
221
        netif_rx (skb);
222
        dev->last_rx = jiffies;
223
 
224
        priv->stats.rx_packets++;
225
        priv->stats.rx_bytes += length;
226
}
227
 
228
static int cirrus_send_start (struct sk_buff *skb,struct net_device *dev)
229
{
230
        cirrus_t *priv = (cirrus_t *) dev->priv;
231
        u16 status;
232
 
233
        netif_stop_queue (dev);
234
 
235
        cirrus_write (dev,PP_TxCMD,TxStart (After5));
236
        cirrus_write (dev,PP_TxLength,skb->len);
237
 
238
        status = cirrus_read (dev,PP_BusST);
239
 
240
        if ((status & TxBidErr)) {
241
                printk (KERN_WARNING "%s: Invalid frame size %d!\n",dev->name,skb->len);
242
                priv->stats.tx_errors++;
243
                priv->stats.tx_aborted_errors++;
244
                priv->txlen = 0;
245
                return (1);
246
        }
247
 
248
        if (!(status & Rdy4TxNOW)) {
249
                printk (KERN_WARNING "%s: Transmit buffer not free!\n",dev->name);
250
                priv->stats.tx_errors++;
251
                priv->txlen = 0;
252
                /* FIXME: store skb and send it in interrupt handler */
253
                return (1);
254
        }
255
 
256
        cirrus_frame_write (dev,skb);
257
 
258
#ifdef DEBUG
259
        dump_packet (dev,skb,"send");
260
#endif  /* #ifdef DEBUG */
261
 
262
        dev->trans_start = jiffies;
263
 
264
        dev_kfree_skb (skb);
265
 
266
        priv->txlen = skb->len;
267
 
268
        return (0);
269
}
270
 
271
static void cirrus_interrupt (int irq,void *id,struct pt_regs *regs)
272
{
273
        struct net_device *dev = (struct net_device *) id;
274
        cirrus_t *priv;
275
        u16 status;
276
 
277
        if (dev->priv == NULL) {
278
                printk (KERN_WARNING "%s: irq %d for unknown device.\n",dev->name,irq);
279
                return;
280
        }
281
 
282
        priv = (cirrus_t *) dev->priv;
283
 
284
        while ((status = cirrus_read (dev,PP_ISQ))) {
285
                switch (RegNum (status)) {
286
                case RxEvent:
287
                        cirrus_receive (dev);
288
                        break;
289
 
290
                case TxEvent:
291
                        priv->stats.collisions += ColCount (cirrus_read (dev,PP_TxCOL));
292
                        if (!(RegContent (status) & TxOK)) {
293
                                priv->stats.tx_errors++;
294
                                if ((RegContent (status) & Out_of_window)) priv->stats.tx_window_errors++;
295
                                if ((RegContent (status) & Jabber)) priv->stats.tx_aborted_errors++;
296
                                break;
297
                        } else if (priv->txlen) {
298
                                priv->stats.tx_packets++;
299
                                priv->stats.tx_bytes += priv->txlen;
300
                        }
301
                        priv->txlen = 0;
302
                        netif_wake_queue (dev);
303
                        break;
304
 
305
                case BufEvent:
306
                        if ((RegContent (status) & RxMiss)) {
307
                                u16 missed = MissCount (cirrus_read (dev,PP_RxMISS));
308
                                priv->stats.rx_errors += missed;
309
                                priv->stats.rx_missed_errors += missed;
310
                        }
311
                        if ((RegContent (status) & TxUnderrun)) {
312
                                priv->stats.tx_errors++;
313
                                priv->stats.tx_fifo_errors++;
314
                        }
315
                        /* FIXME: if Rdy4Tx, transmit last sent packet (if any) */
316
                        priv->txlen = 0;
317
                        netif_wake_queue (dev);
318
                        break;
319
 
320
                case TxCOL:
321
                        priv->stats.collisions += ColCount (cirrus_read (dev,PP_TxCOL));
322
                        break;
323
 
324
                case RxMISS:
325
                        status = MissCount (cirrus_read (dev,PP_RxMISS));
326
                        priv->stats.rx_errors += status;
327
                        priv->stats.rx_missed_errors += status;
328
                        break;
329
                }
330
        }
331
}
332
 
333
static void cirrus_transmit_timeout (struct net_device *dev)
334
{
335
        cirrus_t *priv = (cirrus_t *) dev->priv;
336
        priv->stats.tx_errors++;
337
        priv->stats.tx_heartbeat_errors++;
338
        priv->txlen = 0;
339
        netif_wake_queue (dev);
340
}
341
 
342
static int cirrus_start (struct net_device *dev)
343
{
344
        int result;
345
 
346
        /* valid ethernet address? */
347
        if (!is_valid_ether_addr(dev->dev_addr)) {
348
                printk(KERN_ERR "%s: invalid ethernet MAC address\n",dev->name);
349
                return (-EINVAL);
350
        }
351
 
352
        /* install interrupt handler */
353
        if ((result = request_irq (dev->irq,&cirrus_interrupt,0,dev->name,dev)) < 0) {
354
                printk (KERN_ERR "%s: could not register interrupt %d\n",dev->name,dev->irq);
355
                return (result);
356
        }
357
 
358
        /* enable the ethernet controller */
359
        cirrus_set (dev,PP_RxCFG,RxOKiE | BufferCRC | CRCerroriE | RuntiE | ExtradataiE);
360
        cirrus_set (dev,PP_RxCTL,RxOKA | IndividualA | BroadcastA);
361
        cirrus_set (dev,PP_TxCFG,TxOKiE | Out_of_windowiE | JabberiE);
362
        cirrus_set (dev,PP_BufCFG,Rdy4TxiE | RxMissiE | TxUnderruniE | TxColOvfiE | MissOvfloiE);
363
        cirrus_set (dev,PP_LineCTL,SerRxON | SerTxON);
364
        cirrus_set (dev,PP_BusCTL,EnableRQ);
365
 
366
#ifdef FULL_DUPLEX
367
        cirrus_set (dev,PP_TestCTL,FDX);
368
#endif  /* #ifdef FULL_DUPLEX */
369
 
370
        /* start the queue */
371
        netif_start_queue (dev);
372
 
373
        MOD_INC_USE_COUNT;
374
 
375
        return (0);
376
}
377
 
378
static int cirrus_stop (struct net_device *dev)
379
{
380
        /* disable ethernet controller */
381
        cirrus_write (dev,PP_BusCTL,0);
382
        cirrus_write (dev,PP_TestCTL,0);
383
        cirrus_write (dev,PP_SelfCTL,0);
384
        cirrus_write (dev,PP_LineCTL,0);
385
        cirrus_write (dev,PP_BufCFG,0);
386
        cirrus_write (dev,PP_TxCFG,0);
387
        cirrus_write (dev,PP_RxCTL,0);
388
        cirrus_write (dev,PP_RxCFG,0);
389
 
390
        /* uninstall interrupt handler */
391
        free_irq (dev->irq,dev);
392
 
393
        /* stop the queue */
394
        netif_stop_queue (dev);
395
 
396
        MOD_DEC_USE_COUNT;
397
 
398
        return (0);
399
}
400
 
401
static int cirrus_set_mac_address (struct net_device *dev, void *p)
402
{
403
        struct sockaddr *addr = (struct sockaddr *)p;
404
        int i;
405
 
406
        if (netif_running(dev))
407
                return -EBUSY;
408
 
409
        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
410
 
411
        /* configure MAC address */
412
        for (i = 0; i < ETH_ALEN; i += 2)
413
                cirrus_write (dev,PP_IA + i,dev->dev_addr[i] | (dev->dev_addr[i + 1] << 8));
414
 
415
        return 0;
416
}
417
 
418
static struct net_device_stats *cirrus_get_stats (struct net_device *dev)
419
{
420
        cirrus_t *priv = (cirrus_t *) dev->priv;
421
        return (&priv->stats);
422
}
423
 
424
static void cirrus_set_receive_mode (struct net_device *dev)
425
{
426
        if ((dev->flags & IFF_PROMISC))
427
                cirrus_set (dev,PP_RxCTL,PromiscuousA);
428
        else
429
                cirrus_clear (dev,PP_RxCTL,PromiscuousA);
430
 
431
        if ((dev->flags & IFF_ALLMULTI) && dev->mc_list)
432
                cirrus_set (dev,PP_RxCTL,MulticastA);
433
        else
434
                cirrus_clear (dev,PP_RxCTL,MulticastA);
435
}
436
 
437
static int cirrus_eeprom_wait (struct net_device *dev)
438
{
439
        int i;
440
 
441
        for (i = 0; i < 200; i++) {
442
                if (!(cirrus_read (dev,PP_SelfST) & SIBUSY))
443
                        return (0);
444
                udelay (1);
445
        }
446
 
447
        return (-1);
448
}
449
 
450
static int cirrus_eeprom_read (struct net_device *dev,u16 *value,u16 offset)
451
{
452
        if (cirrus_eeprom_wait (dev) < 0)
453
                return (-1);
454
 
455
        cirrus_write (dev,PP_EEPROMCommand,offset | EEReadRegister);
456
 
457
        if (cirrus_eeprom_wait (dev) < 0)
458
                return (-1);
459
 
460
        *value = cirrus_read (dev,PP_EEPROMData);
461
 
462
        return (0);
463
}
464
 
465
static int cirrus_eeprom (struct net_device *dev,cirrus_eeprom_t *eeprom)
466
{
467
        u16 offset,buf[16],*word;
468
        u8 checksum = 0,*byte;
469
 
470
        if (cirrus_eeprom_read (dev,buf,0) < 0) {
471
                read_timed_out:
472
                printk (KERN_DEBUG "%s: EEPROM read timed out\n",dev->name);
473
                return (-ETIMEDOUT);
474
        }
475
 
476
        if ((buf[0] >> 8) != 0xa1) {
477
                printk (KERN_DEBUG "%s: No EEPROM present\n",dev->name);
478
                return (-ENODEV);
479
        }
480
 
481
        if ((buf[0] & 0xff) < sizeof (buf)) {
482
                eeprom_too_small:
483
                printk (KERN_DEBUG "%s: EEPROM too small\n",dev->name);
484
                return (-ENODEV);
485
        }
486
 
487
        for (offset = 1; offset < (buf[0] & 0xff); offset++) {
488
                if (cirrus_eeprom_read (dev,buf + offset,offset) < 0)
489
                        goto read_timed_out;
490
 
491
                if (buf[offset] == 0xffff)
492
                        goto eeprom_too_small;
493
        }
494
 
495
        if (buf[1] != 0x2020) {
496
                printk (KERN_DEBUG "%s: Group Header #1 mismatch\n",dev->name);
497
                return (-EIO);
498
        }
499
 
500
        if (buf[5] != 0x502c) {
501
                printk (KERN_DEBUG "%s: Group Header #2 mismatch\n",dev->name);
502
                return (-EIO);
503
        }
504
 
505
        if (buf[12] != 0x2158) {
506
                printk (KERN_DEBUG "%s: Group Header #3 mismatch\n",dev->name);
507
                return (-EIO);
508
        }
509
 
510
        eeprom->io_base = buf[2];
511
        eeprom->irq = buf[3];
512
        eeprom->dma = buf[4];
513
        eeprom->mem_base = (buf[7] << 16) | buf[6];
514
        eeprom->rom_base = (buf[9] << 16) | buf[8];
515
        eeprom->rom_mask = (buf[11] << 16) | buf[10];
516
 
517
        word = (u16 *) eeprom->mac;
518
        for (offset = 0; offset < 3; offset++) word[offset] = buf[13 + offset];
519
 
520
        byte = (u8 *) buf;
521
        for (offset = 0; offset < sizeof (buf); offset++) checksum += byte[offset];
522
 
523
        if (cirrus_eeprom_read (dev,&offset,0x10) < 0)
524
                goto read_timed_out;
525
 
526
        if ((offset >> 8) != (u8) (0x100 - checksum)) {
527
                printk (KERN_DEBUG "%s: Checksum mismatch (expected 0x%.2x, got 0x%.2x instead\n",
528
                                dev->name,
529
                                (u8) (0x100 - checksum),
530
                                offset >> 8);
531
                return (-EIO);
532
        }
533
 
534
        return (0);
535
}
536
 
537
/*
538
 * Architecture dependant code
539
 */
540
 
541
#ifdef CONFIG_SA1100_FRODO
542
static void frodo_reset (struct net_device *dev)
543
{
544
        int i;
545
        volatile u16 value;
546
 
547
        /* reset ethernet controller */
548
        FRODO_CPLD_ETHERNET |= FRODO_ETH_RESET;
549
        mdelay (50);
550
        FRODO_CPLD_ETHERNET &= ~FRODO_ETH_RESET;
551
        mdelay (50);
552
 
553
        /* we tied SBHE to CHIPSEL, so each memory access ensure the chip is in 16-bit mode */
554
        for (i = 0; i < 3; i++) value = cirrus_read (dev,0);
555
 
556
        /* FIXME: poll status bit */
557
}
558
#endif  /* #ifdef CONFIG_SA1100_FRODO */
559
 
560
/*
561
 * Driver initialization routines
562
 */
563
 
564
static int io = 0;
565
static int irq = 0;
566
 
567
int __init cirrus_probe (struct net_device *dev)
568
{
569
        static cirrus_t priv;
570
        int i,result;
571
        u16 value;
572
        cirrus_eeprom_t eeprom;
573
 
574
        printk ("Cirrus Logic CS8900A driver for Linux (V0.02)\n");
575
 
576
        memset (&priv,0,sizeof (cirrus_t));
577
 
578
        ether_setup (dev);
579
 
580
        dev->open               = cirrus_start;
581
        dev->stop               = cirrus_stop;
582
        dev->hard_start_xmit    = cirrus_send_start;
583
        dev->get_stats          = cirrus_get_stats;
584
        dev->set_multicast_list = cirrus_set_receive_mode;
585
        dev->set_mac_address    = cirrus_set_mac_address;
586
        dev->tx_timeout         = cirrus_transmit_timeout;
587
        dev->watchdog_timeo     = HZ;
588
 
589
        dev->dev_addr[0] = 0x00;
590
        dev->dev_addr[1] = 0x00;
591
        dev->dev_addr[2] = 0x00;
592
        dev->dev_addr[3] = 0x00;
593
        dev->dev_addr[4] = 0x00;
594
        dev->dev_addr[5] = 0x00;
595
 
596
        dev->if_port   = IF_PORT_10BASET;
597
        dev->priv      = (void *) &priv;
598
 
599
        SET_MODULE_OWNER (dev);
600
 
601
        dev->base_addr = CIRRUS_DEFAULT_IO;
602
        dev->irq = CIRRUS_DEFAULT_IRQ;
603
 
604
        /* module parameters override everything */
605
        if (io > 0) dev->base_addr = io;
606
        if (irq > 0) dev->irq = irq;
607
 
608
        if (!dev->base_addr) {
609
                printk (KERN_ERR
610
                                "%s: No default I/O base address defined. Use io=... or\n"
611
                                "%s: define CIRRUS_DEFAULT_IO for your platform\n",
612
                                dev->name,dev->name);
613
                return (-EINVAL);
614
        }
615
 
616
        if (!dev->irq) {
617
                printk (KERN_ERR
618
                                "%s: No default IRQ number defined. Use irq=... or\n"
619
                                "%s: define CIRRUS_DEFAULT_IRQ for your platform\n",
620
                                dev->name,dev->name);
621
                return (-EINVAL);
622
        }
623
 
624
        if ((result = check_region (dev->base_addr,16))) {
625
                printk (KERN_ERR "%s: can't get I/O port address 0x%lx\n",dev->name,dev->base_addr);
626
                return (result);
627
        }
628
 
629
        if (!request_region (dev->base_addr,16,dev->name))
630
                return -EBUSY;
631
 
632
#ifdef CONFIG_SA1100_FRODO
633
        frodo_reset (dev);
634
#endif  /* #ifdef CONFIG_SA1100_FRODO */
635
 
636
        /* if an EEPROM is present, use it's MAC address */
637
        if (!cirrus_eeprom (dev,&eeprom))
638
                for (i = 0; i < 6; i++)
639
                        dev->dev_addr[i] = eeprom.mac[i];
640
 
641
        /* verify EISA registration number for Cirrus Logic */
642
        if ((value = cirrus_read (dev,PP_ProductID)) != EISA_REG_CODE) {
643
                printk (KERN_ERR "%s: incorrect signature 0x%.4x\n",dev->name,value);
644
                return (-ENXIO);
645
        }
646
 
647
        /* verify chip version */
648
        value = cirrus_read (dev,PP_ProductID + 2);
649
        if (VERSION (value) != CS8900A) {
650
                printk (KERN_ERR "%s: unknown chip version 0x%.8x\n",dev->name,VERSION (value));
651
                return (-ENXIO);
652
        }
653
        printk (KERN_INFO "%s: CS8900A rev %c detected\n",dev->name,'B' + REVISION (value) - REV_B);
654
 
655
        /* setup interrupt number */
656
        cirrus_write (dev,PP_IntNum,0);
657
 
658
        /* configure MAC address */
659
        for (i = 0; i < ETH_ALEN; i += 2)
660
                cirrus_write (dev,PP_IA + i,dev->dev_addr[i] | (dev->dev_addr[i + 1] << 8));
661
 
662
        return (0);
663
}
664
 
665
EXPORT_NO_SYMBOLS;
666
 
667
static struct net_device dev;
668
 
669
static int __init cirrus_init (void)
670
{
671
        memset (&dev,0,sizeof (struct net_device));
672
        dev.init = cirrus_probe;
673
        return (register_netdev (&dev));
674
}
675
 
676
static void __exit cirrus_cleanup (void)
677
{
678
        release_region (dev.base_addr,16);
679
        unregister_netdev (&dev);
680
}
681
 
682
MODULE_AUTHOR ("Abraham van der Merwe <abraham@2d3d.co.za>");
683
MODULE_DESCRIPTION ("Cirrus Logic CS8900A driver for Linux (V0.02)");
684
MODULE_LICENSE ("GPL");
685
MODULE_PARM_DESC (io,"I/O Base Address");
686
MODULE_PARM (io,"i");
687
MODULE_PARM_DESC (irq,"IRQ Number");
688
MODULE_PARM (irq,"i");
689
 
690
module_init (cirrus_init);
691
module_exit (cirrus_cleanup);
692
 

powered by: WebSVN 2.1.0

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