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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [net/] [de600.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
static const char version[] = "de600.c: $Revision: 1.41-2.5 $,  Bjorn Ekwall (bj0rn@blox.se)\n";
2
/*
3
 *      de600.c
4
 *
5
 *      Linux driver for the D-Link DE-600 Ethernet pocket adapter.
6
 *
7
 *      Portions (C) Copyright 1993, 1994 by Bjorn Ekwall
8
 *      The Author may be reached as bj0rn@blox.se
9
 *
10
 *      Based on adapter information gathered from DE600.ASM by D-Link Inc.,
11
 *      as included on disk C in the v.2.11 of PC/TCP from FTP Software.
12
 *      For DE600.asm:
13
 *              Portions (C) Copyright 1990 D-Link, Inc.
14
 *              Copyright, 1988-1992, Russell Nelson, Crynwr Software
15
 *
16
 *      Adapted to the sample network driver core for linux,
17
 *      written by: Donald Becker <becker@super.org>
18
 *              (Now at <becker@scyld.com>)
19
 *
20
 **************************************************************/
21
/*
22
 *      This program is free software; you can redistribute it and/or modify
23
 *      it under the terms of the GNU General Public License as published by
24
 *      the Free Software Foundation; either version 2, or (at your option)
25
 *      any later version.
26
 *
27
 *      This program is distributed in the hope that it will be useful,
28
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
29
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30
 *      GNU General Public License for more details.
31
 *
32
 *      You should have received a copy of the GNU General Public License
33
 *      along with this program; if not, write to the Free Software
34
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35
 *
36
 **************************************************************/
37
 
38
/* Add more time here if your adapter won't work OK: */
39
#define DE600_SLOW_DOWN udelay(delay_time)
40
 
41
/* use 0 for production, 1 for verification, >2 for debug */
42
#ifdef DE600_DEBUG
43
#define PRINTK(x) if (de600_debug >= 2) printk x
44
#else
45
#define DE600_DEBUG 0
46
#define PRINTK(x) /**/
47
#endif
48
 
49
#include <linux/module.h>
50
#include <linux/kernel.h>
51
#include <linux/types.h>
52
#include <linux/fcntl.h>
53
#include <linux/string.h>
54
#include <linux/interrupt.h>
55
#include <linux/ioport.h>
56
#include <linux/in.h>
57
#include <asm/system.h>
58
#include <linux/errno.h>
59
#include <linux/init.h>
60
#include <linux/delay.h>
61
#include <linux/inet.h>
62
#include <linux/netdevice.h>
63
#include <linux/etherdevice.h>
64
#include <linux/skbuff.h>
65
 
66
#include <asm/io.h>
67
 
68
#include "de600.h"
69
 
70
static unsigned int de600_debug = DE600_DEBUG;
71
module_param(de600_debug, int, 0);
72
MODULE_PARM_DESC(de600_debug, "DE-600 debug level (0-2)");
73
 
74
static unsigned int check_lost = 1;
75
module_param(check_lost, bool, 0);
76
MODULE_PARM_DESC(check_lost, "If set then check for unplugged de600");
77
 
78
static unsigned int delay_time = 10;
79
module_param(delay_time, int, 0);
80
MODULE_PARM_DESC(delay_time, "DE-600 deley on I/O in microseconds");
81
 
82
 
83
/*
84
 * D-Link driver variables:
85
 */
86
 
87
static volatile int             rx_page;
88
 
89
#define TX_PAGES 2
90
static volatile int             tx_fifo[TX_PAGES];
91
static volatile int             tx_fifo_in;
92
static volatile int             tx_fifo_out;
93
static volatile int             free_tx_pages = TX_PAGES;
94
static int                      was_down;
95
static DEFINE_SPINLOCK(de600_lock);
96
 
97
static inline u8 de600_read_status(struct net_device *dev)
98
{
99
        u8 status;
100
 
101
        outb_p(STATUS, DATA_PORT);
102
        status = inb(STATUS_PORT);
103
        outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT);
104
 
105
        return status;
106
}
107
 
108
static inline u8 de600_read_byte(unsigned char type, struct net_device *dev)
109
{
110
        /* dev used by macros */
111
        u8 lo;
112
        outb_p((type), DATA_PORT);
113
        lo = ((unsigned char)inb(STATUS_PORT)) >> 4;
114
        outb_p((type) | HI_NIBBLE, DATA_PORT);
115
        return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo;
116
}
117
 
118
/*
119
 * Open/initialize the board.  This is called (in the current kernel)
120
 * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
121
 *
122
 * This routine should set everything up anew at each open, even
123
 * registers that "should" only need to be set once at boot, so that
124
 * there is a non-reboot way to recover if something goes wrong.
125
 */
126
 
127
static int de600_open(struct net_device *dev)
128
{
129
        unsigned long flags;
130
        int ret = request_irq(DE600_IRQ, de600_interrupt, 0, dev->name, dev);
131
        if (ret) {
132
                printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name, DE600_IRQ);
133
                return ret;
134
        }
135
        spin_lock_irqsave(&de600_lock, flags);
136
        ret = adapter_init(dev);
137
        spin_unlock_irqrestore(&de600_lock, flags);
138
        return ret;
139
}
140
 
141
/*
142
 * The inverse routine to de600_open().
143
 */
144
 
145
static int de600_close(struct net_device *dev)
146
{
147
        select_nic();
148
        rx_page = 0;
149
        de600_put_command(RESET);
150
        de600_put_command(STOP_RESET);
151
        de600_put_command(0);
152
        select_prn();
153
        free_irq(DE600_IRQ, dev);
154
        return 0;
155
}
156
 
157
static inline void trigger_interrupt(struct net_device *dev)
158
{
159
        de600_put_command(FLIP_IRQ);
160
        select_prn();
161
        DE600_SLOW_DOWN;
162
        select_nic();
163
        de600_put_command(0);
164
}
165
 
166
/*
167
 * Copy a buffer to the adapter transmit page memory.
168
 * Start sending.
169
 */
170
 
171
static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
172
{
173
        unsigned long flags;
174
        int     transmit_from;
175
        int     len;
176
        int     tickssofar;
177
        u8      *buffer = skb->data;
178
        int     i;
179
 
180
        if (free_tx_pages <= 0) {        /* Do timeouts, to avoid hangs. */
181
                tickssofar = jiffies - dev->trans_start;
182
                if (tickssofar < 5)
183
                        return 1;
184
                /* else */
185
                printk(KERN_WARNING "%s: transmit timed out (%d), %s?\n", dev->name, tickssofar, "network cable problem");
186
                /* Restart the adapter. */
187
                spin_lock_irqsave(&de600_lock, flags);
188
                if (adapter_init(dev)) {
189
                        spin_unlock_irqrestore(&de600_lock, flags);
190
                        return 1;
191
                }
192
                spin_unlock_irqrestore(&de600_lock, flags);
193
        }
194
 
195
        /* Start real output */
196
        PRINTK(("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages));
197
 
198
        if ((len = skb->len) < RUNT)
199
                len = RUNT;
200
 
201
        spin_lock_irqsave(&de600_lock, flags);
202
        select_nic();
203
        tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len;
204
        tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */
205
 
206
        if(check_lost)
207
        {
208
                /* This costs about 40 instructions per packet... */
209
                de600_setup_address(NODE_ADDRESS, RW_ADDR);
210
                de600_read_byte(READ_DATA, dev);
211
                if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
212
                        if (adapter_init(dev)) {
213
                                spin_unlock_irqrestore(&de600_lock, flags);
214
                                return 1;
215
                        }
216
                }
217
        }
218
 
219
        de600_setup_address(transmit_from, RW_ADDR);
220
        for (i = 0;  i < skb->len ; ++i, ++buffer)
221
                de600_put_byte(*buffer);
222
        for (; i < len; ++i)
223
                de600_put_byte(0);
224
 
225
        if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */
226
                dev->trans_start = jiffies;
227
                netif_start_queue(dev); /* allow more packets into adapter */
228
                /* Send page and generate a faked interrupt */
229
                de600_setup_address(transmit_from, TX_ADDR);
230
                de600_put_command(TX_ENABLE);
231
        }
232
        else {
233
                if (free_tx_pages)
234
                        netif_start_queue(dev);
235
                else
236
                        netif_stop_queue(dev);
237
                select_prn();
238
        }
239
        spin_unlock_irqrestore(&de600_lock, flags);
240
        dev_kfree_skb(skb);
241
        return 0;
242
}
243
 
244
/*
245
 * The typical workload of the driver:
246
 * Handle the network interface interrupts.
247
 */
248
 
249
static irqreturn_t de600_interrupt(int irq, void *dev_id)
250
{
251
        struct net_device       *dev = dev_id;
252
        u8              irq_status;
253
        int             retrig = 0;
254
        int             boguscount = 0;
255
 
256
        spin_lock(&de600_lock);
257
 
258
        select_nic();
259
        irq_status = de600_read_status(dev);
260
 
261
        do {
262
                PRINTK(("de600_interrupt (%02X)\n", irq_status));
263
 
264
                if (irq_status & RX_GOOD)
265
                        de600_rx_intr(dev);
266
                else if (!(irq_status & RX_BUSY))
267
                        de600_put_command(RX_ENABLE);
268
 
269
                /* Any transmission in progress? */
270
                if (free_tx_pages < TX_PAGES)
271
                        retrig = de600_tx_intr(dev, irq_status);
272
                else
273
                        retrig = 0;
274
 
275
                irq_status = de600_read_status(dev);
276
        } while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
277
        /*
278
         * Yeah, it _looks_ like busy waiting, smells like busy waiting
279
         * and I know it's not PC, but please, it will only occur once
280
         * in a while and then only for a loop or so (< 1ms for sure!)
281
         */
282
 
283
        /* Enable adapter interrupts */
284
        select_prn();
285
        if (retrig)
286
                trigger_interrupt(dev);
287
        spin_unlock(&de600_lock);
288
        return IRQ_HANDLED;
289
}
290
 
291
static int de600_tx_intr(struct net_device *dev, int irq_status)
292
{
293
        /*
294
         * Returns 1 if tx still not done
295
         */
296
 
297
        /* Check if current transmission is done yet */
298
        if (irq_status & TX_BUSY)
299
                return 1; /* tx not done, try again */
300
 
301
        /* else */
302
        /* If last transmission OK then bump fifo index */
303
        if (!(irq_status & TX_FAILED16)) {
304
                tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES;
305
                ++free_tx_pages;
306
                dev->stats.tx_packets++;
307
                netif_wake_queue(dev);
308
        }
309
 
310
        /* More to send, or resend last packet? */
311
        if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) {
312
                dev->trans_start = jiffies;
313
                de600_setup_address(tx_fifo[tx_fifo_out], TX_ADDR);
314
                de600_put_command(TX_ENABLE);
315
                return 1;
316
        }
317
        /* else */
318
 
319
        return 0;
320
}
321
 
322
/*
323
 * We have a good packet, get it out of the adapter.
324
 */
325
static void de600_rx_intr(struct net_device *dev)
326
{
327
        struct sk_buff  *skb;
328
        int             i;
329
        int             read_from;
330
        int             size;
331
        unsigned char   *buffer;
332
 
333
        /* Get size of received packet */
334
        size = de600_read_byte(RX_LEN, dev);    /* low byte */
335
        size += (de600_read_byte(RX_LEN, dev) << 8);    /* high byte */
336
        size -= 4;      /* Ignore trailing 4 CRC-bytes */
337
 
338
        /* Tell adapter where to store next incoming packet, enable receiver */
339
        read_from = rx_page_adr();
340
        next_rx_page();
341
        de600_put_command(RX_ENABLE);
342
 
343
        if ((size < 32)  ||  (size > 1535)) {
344
                printk(KERN_WARNING "%s: Bogus packet size %d.\n", dev->name, size);
345
                if (size > 10000)
346
                        adapter_init(dev);
347
                return;
348
        }
349
 
350
        skb = dev_alloc_skb(size+2);
351
        if (skb == NULL) {
352
                printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
353
                return;
354
        }
355
        /* else */
356
 
357
        skb_reserve(skb,2);     /* Align */
358
 
359
        /* 'skb->data' points to the start of sk_buff data area. */
360
        buffer = skb_put(skb,size);
361
 
362
        /* copy the packet into the buffer */
363
        de600_setup_address(read_from, RW_ADDR);
364
        for (i = size; i > 0; --i, ++buffer)
365
                *buffer = de600_read_byte(READ_DATA, dev);
366
 
367
        skb->protocol=eth_type_trans(skb,dev);
368
 
369
        netif_rx(skb);
370
 
371
        /* update stats */
372
        dev->last_rx = jiffies;
373
        dev->stats.rx_packets++; /* count all receives */
374
        dev->stats.rx_bytes += size; /* count all received bytes */
375
 
376
        /*
377
         * If any worth-while packets have been received, netif_rx()
378
         * will work on them when we get to the tasklets.
379
         */
380
}
381
 
382
static struct net_device * __init de600_probe(void)
383
{
384
        int     i;
385
        struct net_device *dev;
386
        int err;
387
        DECLARE_MAC_BUF(mac);
388
 
389
        dev = alloc_etherdev(0);
390
        if (!dev)
391
                return ERR_PTR(-ENOMEM);
392
 
393
 
394
        if (!request_region(DE600_IO, 3, "de600")) {
395
                printk(KERN_WARNING "DE600: port 0x%x busy\n", DE600_IO);
396
                err = -EBUSY;
397
                goto out;
398
        }
399
 
400
        printk(KERN_INFO "%s: D-Link DE-600 pocket adapter", dev->name);
401
        /* Alpha testers must have the version number to report bugs. */
402
        if (de600_debug > 1)
403
                printk(version);
404
 
405
        /* probe for adapter */
406
        err = -ENODEV;
407
        rx_page = 0;
408
        select_nic();
409
        (void)de600_read_status(dev);
410
        de600_put_command(RESET);
411
        de600_put_command(STOP_RESET);
412
        if (de600_read_status(dev) & 0xf0) {
413
                printk(": not at I/O %#3x.\n", DATA_PORT);
414
                goto out1;
415
        }
416
 
417
        /*
418
         * Maybe we found one,
419
         * have to check if it is a D-Link DE-600 adapter...
420
         */
421
 
422
        /* Get the adapter ethernet address from the ROM */
423
        de600_setup_address(NODE_ADDRESS, RW_ADDR);
424
        for (i = 0; i < ETH_ALEN; i++) {
425
                dev->dev_addr[i] = de600_read_byte(READ_DATA, dev);
426
                dev->broadcast[i] = 0xff;
427
        }
428
 
429
        /* Check magic code */
430
        if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) {
431
                /* OK, install real address */
432
                dev->dev_addr[0] = 0x00;
433
                dev->dev_addr[1] = 0x80;
434
                dev->dev_addr[2] = 0xc8;
435
                dev->dev_addr[3] &= 0x0f;
436
                dev->dev_addr[3] |= 0x70;
437
        } else {
438
                printk(" not identified in the printer port\n");
439
                goto out1;
440
        }
441
 
442
        printk(", Ethernet Address: %s\n", print_mac(mac, dev->dev_addr));
443
 
444
        dev->open = de600_open;
445
        dev->stop = de600_close;
446
        dev->hard_start_xmit = &de600_start_xmit;
447
 
448
        dev->flags&=~IFF_MULTICAST;
449
 
450
        select_prn();
451
 
452
        err = register_netdev(dev);
453
        if (err)
454
                goto out1;
455
 
456
        return dev;
457
 
458
out1:
459
        release_region(DE600_IO, 3);
460
out:
461
        free_netdev(dev);
462
        return ERR_PTR(err);
463
}
464
 
465
static int adapter_init(struct net_device *dev)
466
{
467
        int     i;
468
 
469
        select_nic();
470
        rx_page = 0; /* used by RESET */
471
        de600_put_command(RESET);
472
        de600_put_command(STOP_RESET);
473
 
474
        /* Check if it is still there... */
475
        /* Get the some bytes of the adapter ethernet address from the ROM */
476
        de600_setup_address(NODE_ADDRESS, RW_ADDR);
477
        de600_read_byte(READ_DATA, dev);
478
        if ((de600_read_byte(READ_DATA, dev) != 0xde) ||
479
            (de600_read_byte(READ_DATA, dev) != 0x15)) {
480
        /* was: if (de600_read_status(dev) & 0xf0) { */
481
                printk("Something has happened to the DE-600!  Please check it and do a new ifconfig!\n");
482
                /* Goodbye, cruel world... */
483
                dev->flags &= ~IFF_UP;
484
                de600_close(dev);
485
                was_down = 1;
486
                netif_stop_queue(dev); /* Transmit busy...  */
487
                return 1; /* failed */
488
        }
489
 
490
        if (was_down) {
491
                printk(KERN_INFO "%s: Thanks, I feel much better now!\n", dev->name);
492
                was_down = 0;
493
        }
494
 
495
        tx_fifo_in = 0;
496
        tx_fifo_out = 0;
497
        free_tx_pages = TX_PAGES;
498
 
499
 
500
        /* set the ether address. */
501
        de600_setup_address(NODE_ADDRESS, RW_ADDR);
502
        for (i = 0; i < ETH_ALEN; i++)
503
                de600_put_byte(dev->dev_addr[i]);
504
 
505
        /* where to start saving incoming packets */
506
        rx_page = RX_BP | RX_BASE_PAGE;
507
        de600_setup_address(MEM_4K, RW_ADDR);
508
        /* Enable receiver */
509
        de600_put_command(RX_ENABLE);
510
        select_prn();
511
 
512
        netif_start_queue(dev);
513
 
514
        return 0; /* OK */
515
}
516
 
517
static struct net_device *de600_dev;
518
 
519
static int __init de600_init(void)
520
{
521
        de600_dev = de600_probe();
522
        if (IS_ERR(de600_dev))
523
                return PTR_ERR(de600_dev);
524
        return 0;
525
}
526
 
527
static void __exit de600_exit(void)
528
{
529
        unregister_netdev(de600_dev);
530
        release_region(DE600_IO, 3);
531
        free_netdev(de600_dev);
532
}
533
 
534
module_init(de600_init);
535
module_exit(de600_exit);
536
 
537
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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