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

Subversion Repositories or1k

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

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

Line No. Rev Author Line
1 1626 jcastillo
static const char *version =
2
        "de600.c: $Revision: 1.1 $,  Bjorn Ekwall (bj0rn@blox.se)\n";
3
/*
4
 *      de600.c
5
 *
6
 *      Linux driver for the D-Link DE-600 Ethernet pocket adapter.
7
 *
8
 *      Portions (C) Copyright 1993, 1994 by Bjorn Ekwall
9
 *      The Author may be reached as bj0rn@blox.se
10
 *
11
 *      Based on adapter information gathered from DE600.ASM by D-Link Inc.,
12
 *      as included on disk C in the v.2.11 of PC/TCP from FTP Software.
13
 *      For DE600.asm:
14
 *              Portions (C) Copyright 1990 D-Link, Inc.
15
 *              Copyright, 1988-1992, Russell Nelson, Crynwr Software
16
 *
17
 *      Adapted to the sample network driver core for linux,
18
 *      written by: Donald Becker <becker@super.org>
19
 *      C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
20
 *
21
 *      compile-command:
22
 *      "gcc -D__KERNEL__  -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer \
23
 *       -m486 -c de600.c
24
 *
25
 **************************************************************/
26
/*
27
 *      This program is free software; you can redistribute it and/or modify
28
 *      it under the terms of the GNU General Public License as published by
29
 *      the Free Software Foundation; either version 2, or (at your option)
30
 *      any later version.
31
 *
32
 *      This program is distributed in the hope that it will be useful,
33
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
34
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
35
 *      GNU General Public License for more details.
36
 *
37
 *      You should have received a copy of the GNU General Public License
38
 *      along with this program; if not, write to the Free Software
39
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
40
 *
41
 **************************************************************/
42
/* Add another "; SLOW_DOWN_IO" here if your adapter won't work OK: */
43
#define DE600_SLOW_DOWN SLOW_DOWN_IO; SLOW_DOWN_IO; SLOW_DOWN_IO
44
 
45
 /*
46
 * If you still have trouble reading/writing to the adapter,
47
 * modify the following "#define": (see <asm/io.h> for more info)
48
#define REALLY_SLOW_IO
49
 */
50
#define SLOW_IO_BY_JUMPING /* Looks "better" than dummy write to port 0x80 :-) */
51
 
52
/*
53
 * If you want to enable automatic continuous checking for the DE600,
54
 * keep this #define enabled.
55
 * It doesn't cost much per packet, so I think it is worth it!
56
 * If you disagree, comment away the #define, and live with it...
57
 *
58
 */
59
#define CHECK_LOST_DE600
60
 
61
/*
62
 * Enable this #define if you want the adapter to do a "ifconfig down" on
63
 * itself when we have detected that something is possibly wrong with it.
64
 * The default behaviour is to retry with "adapter_init()" until success.
65
 * This should be used for debugging purposes only.
66
 * (Depends on the CHECK_LOST_DE600 above)
67
 *
68
 */
69
#define SHUTDOWN_WHEN_LOST
70
 
71
/*
72
 * See comment at "de600_rspace()"!
73
 * This is an *ugly* hack, but for now it achieves its goal of
74
 * faking a TCP flow-control that will not flood the poor DE600.
75
 *
76
 * Tricks TCP to announce a small max window (max 2 fast packets please :-)
77
 *
78
 * Comment away at your own risk!
79
 *
80
 * Update: Use the more general per-device maxwindow parameter instead.
81
 */
82
#undef FAKE_SMALL_MAX
83
 
84
/* use 0 for production, 1 for verification, >2 for debug */
85
#ifdef DE600_DEBUG
86
#define PRINTK(x) if (de600_debug >= 2) printk x
87
#else
88
#define DE600_DEBUG 0
89
#define PRINTK(x) /**/
90
#endif
91
unsigned int de600_debug = DE600_DEBUG;
92
 
93
#include <linux/module.h>
94
 
95
#include <linux/kernel.h>
96
#include <linux/sched.h>
97
#include <linux/types.h>
98
#include <linux/fcntl.h>
99
#include <linux/string.h>
100
#include <linux/interrupt.h>
101
#include <linux/ioport.h>
102
#include <asm/io.h>
103
#include <linux/in.h>
104
#include <linux/ptrace.h>
105
#include <asm/system.h>
106
#include <linux/errno.h>
107
 
108
#include <linux/inet.h>
109
#include <linux/netdevice.h>
110
#include <linux/etherdevice.h>
111
#include <linux/skbuff.h>
112
 
113
#ifdef FAKE_SMALL_MAX
114
static unsigned long de600_rspace(struct sock *sk);
115
#include <net/sock.h>
116
#endif
117
 
118
#define netstats enet_statistics
119
typedef unsigned char byte;
120
 
121
/**************************************************
122
 *                                                *
123
 * Definition of D-Link Ethernet Pocket adapter   *
124
 *                                                *
125
 **************************************************/
126
/*
127
 * D-Link Ethernet pocket adapter ports
128
 */
129
/*
130
 * OK, so I'm cheating, but there are an awful lot of
131
 * reads and writes in order to get anything in and out
132
 * of the DE-600 with 4 bits at a time in the parallel port,
133
 * so every saved instruction really helps :-)
134
 *
135
 * That is, I don't care what the device struct says
136
 * but hope that Space.c will keep the rest of the drivers happy.
137
 */
138
#ifndef DE600_IO
139
#define DE600_IO 0x378
140
#endif
141
 
142
#define DATA_PORT       (DE600_IO)
143
#define STATUS_PORT     (DE600_IO + 1)
144
#define COMMAND_PORT    (DE600_IO + 2)
145
 
146
#ifndef DE600_IRQ
147
#define DE600_IRQ       7
148
#endif
149
/*
150
 * It really should look like this, and autoprobing as well...
151
 *
152
#define DATA_PORT       (dev->base_addr + 0)
153
#define STATUS_PORT     (dev->base_addr + 1)
154
#define COMMAND_PORT    (dev->base_addr + 2)
155
#define DE600_IRQ       dev->irq
156
 */
157
 
158
/*
159
 * D-Link COMMAND_PORT commands
160
 */
161
#define SELECT_NIC      0x04 /* select Network Interface Card */
162
#define SELECT_PRN      0x1c /* select Printer */
163
#define NML_PRN         0xec /* normal Printer situation */
164
#define IRQEN           0x10 /* enable IRQ line */
165
 
166
/*
167
 * D-Link STATUS_PORT
168
 */
169
#define RX_BUSY         0x80
170
#define RX_GOOD         0x40
171
#define TX_FAILED16     0x10
172
#define TX_BUSY         0x08
173
 
174
/*
175
 * D-Link DATA_PORT commands
176
 * command in low 4 bits
177
 * data in high 4 bits
178
 * select current data nibble with HI_NIBBLE bit
179
 */
180
#define WRITE_DATA      0x00 /* write memory */
181
#define READ_DATA       0x01 /* read memory */
182
#define STATUS          0x02 /* read  status register */
183
#define COMMAND         0x03 /* write command register (see COMMAND below) */
184
#define NULL_COMMAND    0x04 /* null command */
185
#define RX_LEN          0x05 /* read  received packet length */
186
#define TX_ADDR         0x06 /* set adapter transmit memory address */
187
#define RW_ADDR         0x07 /* set adapter read/write memory address */
188
#define HI_NIBBLE       0x08 /* read/write the high nibble of data,
189
                                or-ed with rest of command */
190
 
191
/*
192
 * command register, accessed through DATA_PORT with low bits = COMMAND
193
 */
194
#define RX_ALL          0x01 /* PROMISCUOUS */
195
#define RX_BP           0x02 /* default: BROADCAST & PHYSICAL ADDRESS */
196
#define RX_MBP          0x03 /* MULTICAST, BROADCAST & PHYSICAL ADDRESS */
197
 
198
#define TX_ENABLE       0x04 /* bit 2 */
199
#define RX_ENABLE       0x08 /* bit 3 */
200
 
201
#define RESET           0x80 /* set bit 7 high */
202
#define STOP_RESET      0x00 /* set bit 7 low */
203
 
204
/*
205
 * data to command register
206
 * (high 4 bits in write to DATA_PORT)
207
 */
208
#define RX_PAGE2_SELECT 0x10 /* bit 4, only 2 pages to select */
209
#define RX_BASE_PAGE    0x20 /* bit 5, always set when specifying RX_ADDR */
210
#define FLIP_IRQ        0x40 /* bit 6 */
211
 
212
/*
213
 * D-Link adapter internal memory:
214
 *
215
 * 0-2K 1:st transmit page (send from pointer up to 2K)
216
 * 2-4K 2:nd transmit page (send from pointer up to 4K)
217
 *
218
 * 4-6K 1:st receive page (data from 4K upwards)
219
 * 6-8K 2:nd receive page (data from 6K upwards)
220
 *
221
 * 8K+  Adapter ROM (contains magic code and last 3 bytes of Ethernet address)
222
 */
223
#define MEM_2K          0x0800 /* 2048 */
224
#define MEM_4K          0x1000 /* 4096 */
225
#define MEM_6K          0x1800 /* 6144 */
226
#define NODE_ADDRESS    0x2000 /* 8192 */
227
 
228
#define RUNT 60         /* Too small Ethernet packet */
229
 
230
/**************************************************
231
 *                                                *
232
 *             End of definition                  *
233
 *                                                *
234
 **************************************************/
235
 
236
/*
237
 * Index to functions, as function prototypes.
238
 */
239
/* Routines used internally. (See "convenience macros") */
240
static byte     de600_read_status(struct device *dev);
241
static byte     de600_read_byte(unsigned char type, struct device *dev);
242
 
243
/* Put in the device structure. */
244
static int      de600_open(struct device *dev);
245
static int      de600_close(struct device *dev);
246
static struct netstats *get_stats(struct device *dev);
247
static int      de600_start_xmit(struct sk_buff *skb, struct device *dev);
248
 
249
/* Dispatch from interrupts. */
250
static void     de600_interrupt(int irq, void *dev_id, struct pt_regs *regs);
251
static int      de600_tx_intr(struct device *dev, int irq_status);
252
static void     de600_rx_intr(struct device *dev);
253
 
254
/* Initialization */
255
static void     trigger_interrupt(struct device *dev);
256
int             de600_probe(struct device *dev);
257
static int      adapter_init(struct device *dev);
258
 
259
/*
260
 * D-Link driver variables:
261
 */
262
static volatile int             rx_page         = 0;
263
 
264
#define TX_PAGES 2
265
static volatile int             tx_fifo[TX_PAGES];
266
static volatile int             tx_fifo_in = 0;
267
static volatile int             tx_fifo_out = 0;
268
static volatile int             free_tx_pages = TX_PAGES;
269
static int                      was_down = 0;
270
 
271
/*
272
 * Convenience macros/functions for D-Link adapter
273
 */
274
 
275
#define select_prn() outb_p(SELECT_PRN, COMMAND_PORT); DE600_SLOW_DOWN
276
#define select_nic() outb_p(SELECT_NIC, COMMAND_PORT); DE600_SLOW_DOWN
277
 
278
/* Thanks for hints from Mark Burton <markb@ordern.demon.co.uk> */
279
#define de600_put_byte(data) ( \
280
        outb_p(((data) << 4)   | WRITE_DATA            , DATA_PORT), \
281
        outb_p(((data) & 0xf0) | WRITE_DATA | HI_NIBBLE, DATA_PORT))
282
 
283
/*
284
 * The first two outb_p()'s below could perhaps be deleted if there
285
 * would be more delay in the last two. Not certain about it yet...
286
 */
287
#define de600_put_command(cmd) ( \
288
        outb_p(( rx_page        << 4)   | COMMAND            , DATA_PORT), \
289
        outb_p(( rx_page        & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT), \
290
        outb_p(((rx_page | cmd) << 4)   | COMMAND            , DATA_PORT), \
291
        outb_p(((rx_page | cmd) & 0xf0) | COMMAND | HI_NIBBLE, DATA_PORT))
292
 
293
#define de600_setup_address(addr,type) ( \
294
        outb_p((((addr) << 4) & 0xf0) | type            , DATA_PORT), \
295
        outb_p(( (addr)       & 0xf0) | type | HI_NIBBLE, DATA_PORT), \
296
        outb_p((((addr) >> 4) & 0xf0) | type            , DATA_PORT), \
297
        outb_p((((addr) >> 8) & 0xf0) | type | HI_NIBBLE, DATA_PORT))
298
 
299
#define rx_page_adr() ((rx_page & RX_PAGE2_SELECT)?(MEM_6K):(MEM_4K))
300
 
301
/* Flip bit, only 2 pages */
302
#define next_rx_page() (rx_page ^= RX_PAGE2_SELECT)
303
 
304
#define tx_page_adr(a) (((a) + 1) * MEM_2K)
305
 
306
static inline byte
307
de600_read_status(struct device *dev)
308
{
309
        byte status;
310
 
311
        outb_p(STATUS, DATA_PORT);
312
        status = inb(STATUS_PORT);
313
        outb_p(NULL_COMMAND | HI_NIBBLE, DATA_PORT);
314
 
315
        return status;
316
}
317
 
318
static inline byte
319
de600_read_byte(unsigned char type, struct device *dev) { /* dev used by macros */
320
        byte lo;
321
 
322
        (void)outb_p((type), DATA_PORT);
323
        lo = ((unsigned char)inb(STATUS_PORT)) >> 4;
324
        (void)outb_p((type) | HI_NIBBLE, DATA_PORT);
325
        return ((unsigned char)inb(STATUS_PORT) & (unsigned char)0xf0) | lo;
326
}
327
 
328
/*
329
 * Open/initialize the board.  This is called (in the current kernel)
330
 * after booting when 'ifconfig <dev->name> $IP_ADDR' is run (in rc.inet1).
331
 *
332
 * This routine should set everything up anew at each open, even
333
 * registers that "should" only need to be set once at boot, so that
334
 * there is a non-reboot way to recover if something goes wrong.
335
 */
336
static int
337
de600_open(struct device *dev)
338
{
339
        if (request_irq(DE600_IRQ, de600_interrupt, 0, "de600", NULL)) {
340
                printk ("%s: unable to get IRQ %d\n", dev->name, DE600_IRQ);
341
                return 1;
342
        }
343
        irq2dev_map[DE600_IRQ] = dev;
344
 
345
        MOD_INC_USE_COUNT;
346
        dev->start = 1;
347
        if (adapter_init(dev)) {
348
                return 1;
349
        }
350
 
351
        return 0;
352
}
353
 
354
/*
355
 * The inverse routine to de600_open().
356
 */
357
static int
358
de600_close(struct device *dev)
359
{
360
        select_nic();
361
        rx_page = 0;
362
        de600_put_command(RESET);
363
        de600_put_command(STOP_RESET);
364
        de600_put_command(0);
365
        select_prn();
366
 
367
        if (dev->start) {
368
                free_irq(DE600_IRQ, NULL);
369
                irq2dev_map[DE600_IRQ] = NULL;
370
                dev->start = 0;
371
                MOD_DEC_USE_COUNT;
372
        }
373
        return 0;
374
}
375
 
376
static struct netstats *
377
get_stats(struct device *dev)
378
{
379
    return (struct netstats *)(dev->priv);
380
}
381
 
382
static inline void
383
trigger_interrupt(struct device *dev)
384
{
385
        de600_put_command(FLIP_IRQ);
386
        select_prn();
387
        DE600_SLOW_DOWN;
388
        select_nic();
389
        de600_put_command(0);
390
}
391
 
392
/*
393
 * Copy a buffer to the adapter transmit page memory.
394
 * Start sending.
395
 */
396
static int
397
de600_start_xmit(struct sk_buff *skb, struct device *dev)
398
{
399
        int     transmit_from;
400
        int     len;
401
        int     tickssofar;
402
        byte    *buffer = skb->data;
403
 
404
        /*
405
         * If some higher layer thinks we've missed a
406
         * tx-done interrupt we are passed NULL.
407
         * Caution: dev_tint() handles the cli()/sti() itself.
408
         */
409
 
410
        if (skb == NULL) {
411
                dev_tint(dev);
412
                return 0;
413
        }
414
 
415
        if (free_tx_pages <= 0) {        /* Do timeouts, to avoid hangs. */
416
                tickssofar = jiffies - dev->trans_start;
417
 
418
                if (tickssofar < 5)
419
                        return 1;
420
 
421
                /* else */
422
                printk("%s: transmit timed out (%d), %s?\n",
423
                        dev->name,
424
                        tickssofar,
425
                        "network cable problem"
426
                        );
427
                /* Restart the adapter. */
428
                if (adapter_init(dev)) {
429
                        return 1;
430
                }
431
        }
432
 
433
        /* Start real output */
434
        PRINTK(("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages));
435
 
436
        if ((len = skb->len) < RUNT)
437
                len = RUNT;
438
 
439
        cli();
440
        select_nic();
441
        tx_fifo[tx_fifo_in] = transmit_from = tx_page_adr(tx_fifo_in) - len;
442
        tx_fifo_in = (tx_fifo_in + 1) % TX_PAGES; /* Next free tx page */
443
 
444
#ifdef CHECK_LOST_DE600
445
        /* This costs about 40 instructions per packet... */
446
        de600_setup_address(NODE_ADDRESS, RW_ADDR);
447
        de600_read_byte(READ_DATA, dev);
448
        if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
449
                if (adapter_init(dev)) {
450
                        sti();
451
                        return 1;
452
                }
453
        }
454
#endif
455
 
456
        de600_setup_address(transmit_from, RW_ADDR);
457
        for ( ; len > 0; --len, ++buffer)
458
                de600_put_byte(*buffer);
459
 
460
        if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */
461
                dev->trans_start = jiffies;
462
                dev->tbusy = 0;  /* allow more packets into adapter */
463
                /* Send page and generate a faked interrupt */
464
                de600_setup_address(transmit_from, TX_ADDR);
465
                de600_put_command(TX_ENABLE);
466
        }
467
        else {
468
                dev->tbusy = !free_tx_pages;
469
                select_prn();
470
        }
471
 
472
        sti(); /* interrupts back on */
473
 
474
#ifdef FAKE_SMALL_MAX
475
        /* This will "patch" the socket TCP proto at an early moment */
476
        if (skb->sk && (skb->sk->protocol == IPPROTO_TCP) &&
477
                (skb->sk->prot->rspace != &de600_rspace))
478
                skb->sk->prot->rspace = de600_rspace; /* Ugh! */
479
#endif
480
 
481
        dev_kfree_skb (skb, FREE_WRITE);
482
 
483
        return 0;
484
}
485
 
486
/*
487
 * The typical workload of the driver:
488
 * Handle the network interface interrupts.
489
 */
490
static void
491
de600_interrupt(int irq, void *dev_id, struct pt_regs * regs)
492
{
493
        struct device   *dev = irq2dev_map[irq];
494
        byte            irq_status;
495
        int             retrig = 0;
496
        int             boguscount = 0;
497
 
498
        /* This might just as well be deleted now, no crummy drivers present :-) */
499
        if ((dev == NULL) || (dev->start == 0) || (DE600_IRQ != irq)) {
500
                printk("%s: bogus interrupt %d\n", dev?dev->name:"DE-600", irq);
501
                return;
502
        }
503
 
504
        dev->interrupt = 1;
505
        select_nic();
506
        irq_status = de600_read_status(dev);
507
 
508
        do {
509
                PRINTK(("de600_interrupt (%02X)\n", irq_status));
510
 
511
                if (irq_status & RX_GOOD)
512
                        de600_rx_intr(dev);
513
                else if (!(irq_status & RX_BUSY))
514
                        de600_put_command(RX_ENABLE);
515
 
516
                /* Any transmission in progress? */
517
                if (free_tx_pages < TX_PAGES)
518
                        retrig = de600_tx_intr(dev, irq_status);
519
                else
520
                        retrig = 0;
521
 
522
                irq_status = de600_read_status(dev);
523
        } while ( (irq_status & RX_GOOD) || ((++boguscount < 100) && retrig) );
524
        /*
525
         * Yeah, it _looks_ like busy waiting, smells like busy waiting
526
         * and I know it's not PC, but please, it will only occur once
527
         * in a while and then only for a loop or so (< 1ms for sure!)
528
         */
529
 
530
        /* Enable adapter interrupts */
531
        dev->interrupt = 0;
532
        select_prn();
533
 
534
        if (retrig)
535
                trigger_interrupt(dev);
536
 
537
        sti();
538
        return;
539
}
540
 
541
static int
542
de600_tx_intr(struct device *dev, int irq_status)
543
{
544
        /*
545
         * Returns 1 if tx still not done
546
         */
547
 
548
        mark_bh(NET_BH);
549
        /* Check if current transmission is done yet */
550
        if (irq_status & TX_BUSY)
551
                return 1; /* tx not done, try again */
552
 
553
        /* else */
554
        /* If last transmission OK then bump fifo index */
555
        if (!(irq_status & TX_FAILED16)) {
556
                tx_fifo_out = (tx_fifo_out + 1) % TX_PAGES;
557
                ++free_tx_pages;
558
                ((struct netstats *)(dev->priv))->tx_packets++;
559
                dev->tbusy = 0;
560
        }
561
 
562
        /* More to send, or resend last packet? */
563
        if ((free_tx_pages < TX_PAGES) || (irq_status & TX_FAILED16)) {
564
                dev->trans_start = jiffies;
565
                de600_setup_address(tx_fifo[tx_fifo_out], TX_ADDR);
566
                de600_put_command(TX_ENABLE);
567
                return 1;
568
        }
569
        /* else */
570
 
571
        return 0;
572
}
573
 
574
/*
575
 * We have a good packet, get it out of the adapter.
576
 */
577
static void
578
de600_rx_intr(struct device *dev)
579
{
580
        struct sk_buff  *skb;
581
        int             i;
582
        int             read_from;
583
        int             size;
584
        register unsigned char  *buffer;
585
 
586
        cli();
587
        /* Get size of received packet */
588
        size = de600_read_byte(RX_LEN, dev);    /* low byte */
589
        size += (de600_read_byte(RX_LEN, dev) << 8);    /* high byte */
590
        size -= 4;      /* Ignore trailing 4 CRC-bytes */
591
 
592
        /* Tell adapter where to store next incoming packet, enable receiver */
593
        read_from = rx_page_adr();
594
        next_rx_page();
595
        de600_put_command(RX_ENABLE);
596
        sti();
597
 
598
        if ((size < 32)  ||  (size > 1535)) {
599
                printk("%s: Bogus packet size %d.\n", dev->name, size);
600
                if (size > 10000)
601
                        adapter_init(dev);
602
                return;
603
        }
604
 
605
        skb = dev_alloc_skb(size+2);
606
        sti();
607
        if (skb == NULL) {
608
                printk("%s: Couldn't allocate a sk_buff of size %d.\n",
609
                        dev->name, size);
610
                return;
611
        }
612
        /* else */
613
 
614
        skb->dev = dev;
615
        skb_reserve(skb,2);     /* Align */
616
 
617
        /* 'skb->data' points to the start of sk_buff data area. */
618
        buffer = skb_put(skb,size);
619
 
620
        /* copy the packet into the buffer */
621
        de600_setup_address(read_from, RW_ADDR);
622
        for (i = size; i > 0; --i, ++buffer)
623
                *buffer = de600_read_byte(READ_DATA, dev);
624
 
625
        ((struct netstats *)(dev->priv))->rx_packets++; /* count all receives */
626
 
627
        skb->protocol=eth_type_trans(skb,dev);
628
 
629
        netif_rx(skb);
630
        /*
631
         * If any worth-while packets have been received, netif_rx()
632
         * has done a mark_bh(INET_BH) for us and will work on them
633
         * when we get to the bottom-half routine.
634
         */
635
}
636
 
637
int
638
de600_probe(struct device *dev)
639
{
640
        int     i;
641
        static struct netstats de600_netstats;
642
        /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/
643
 
644
        printk("%s: D-Link DE-600 pocket adapter", dev->name);
645
        /* Alpha testers must have the version number to report bugs. */
646
        if (de600_debug > 1)
647
                printk(version);
648
 
649
        /* probe for adapter */
650
        rx_page = 0;
651
        select_nic();
652
        (void)de600_read_status(dev);
653
        de600_put_command(RESET);
654
        de600_put_command(STOP_RESET);
655
        if (de600_read_status(dev) & 0xf0) {
656
                printk(": not at I/O %#3x.\n", DATA_PORT);
657
                return ENODEV;
658
        }
659
 
660
        /*
661
         * Maybe we found one,
662
         * have to check if it is a D-Link DE-600 adapter...
663
         */
664
 
665
        /* Get the adapter ethernet address from the ROM */
666
        de600_setup_address(NODE_ADDRESS, RW_ADDR);
667
        for (i = 0; i < ETH_ALEN; i++) {
668
                dev->dev_addr[i] = de600_read_byte(READ_DATA, dev);
669
                dev->broadcast[i] = 0xff;
670
        }
671
 
672
        /* Check magic code */
673
        if ((dev->dev_addr[1] == 0xde) && (dev->dev_addr[2] == 0x15)) {
674
                /* OK, install real address */
675
                dev->dev_addr[0] = 0x00;
676
                dev->dev_addr[1] = 0x80;
677
                dev->dev_addr[2] = 0xc8;
678
                dev->dev_addr[3] &= 0x0f;
679
                dev->dev_addr[3] |= 0x70;
680
        } else {
681
                printk(" not identified in the printer port\n");
682
                return ENODEV;
683
        }
684
 
685
#if 0 /* Not yet */
686
        if (check_region(DE600_IO, 3)) {
687
                printk(", port 0x%x busy\n", DE600_IO);
688
                return EBUSY;
689
        }
690
#endif
691
        request_region(DE600_IO, 3, "de600");
692
 
693
        printk(", Ethernet Address: %02X", dev->dev_addr[0]);
694
        for (i = 1; i < ETH_ALEN; i++)
695
                printk(":%02X",dev->dev_addr[i]);
696
        printk("\n");
697
 
698
        /* Initialize the device structure. */
699
        /*dev->priv = kmalloc(sizeof(struct netstats), GFP_KERNEL);*/
700
        dev->priv = &de600_netstats;
701
 
702
        memset(dev->priv, 0, sizeof(struct netstats));
703
        dev->get_stats = get_stats;
704
 
705
        dev->open = de600_open;
706
        dev->stop = de600_close;
707
        dev->hard_start_xmit = &de600_start_xmit;
708
 
709
        ether_setup(dev);
710
 
711
        dev->flags&=~IFF_MULTICAST;
712
 
713
        select_prn();
714
        return 0;
715
}
716
 
717
static int
718
adapter_init(struct device *dev)
719
{
720
        int     i;
721
        long flags;
722
 
723
        save_flags(flags);
724
        cli();
725
 
726
        select_nic();
727
        rx_page = 0; /* used by RESET */
728
        de600_put_command(RESET);
729
        de600_put_command(STOP_RESET);
730
#ifdef CHECK_LOST_DE600
731
        /* Check if it is still there... */
732
        /* Get the some bytes of the adapter ethernet address from the ROM */
733
        de600_setup_address(NODE_ADDRESS, RW_ADDR);
734
        de600_read_byte(READ_DATA, dev);
735
        if ((de600_read_byte(READ_DATA, dev) != 0xde) ||
736
            (de600_read_byte(READ_DATA, dev) != 0x15)) {
737
        /* was: if (de600_read_status(dev) & 0xf0) { */
738
                printk("Something has happened to the DE-600!  Please check it"
739
#ifdef SHUTDOWN_WHEN_LOST
740
                        " and do a new ifconfig"
741
#endif /* SHUTDOWN_WHEN_LOST */
742
                        "!\n");
743
#ifdef SHUTDOWN_WHEN_LOST
744
                /* Goodbye, cruel world... */
745
                dev->flags &= ~IFF_UP;
746
                de600_close(dev);
747
#endif /* SHUTDOWN_WHEN_LOST */
748
                was_down = 1;
749
                dev->tbusy = 1;         /* Transmit busy...  */
750
                restore_flags(flags);
751
                return 1; /* failed */
752
        }
753
#endif /* CHECK_LOST_DE600 */
754
        if (was_down) {
755
                printk("Thanks, I feel much better now!\n");
756
                was_down = 0;
757
        }
758
 
759
        dev->tbusy = 0;          /* Transmit busy...  */
760
        dev->interrupt = 0;
761
        tx_fifo_in = 0;
762
        tx_fifo_out = 0;
763
        free_tx_pages = TX_PAGES;
764
 
765
        /* set the ether address. */
766
        de600_setup_address(NODE_ADDRESS, RW_ADDR);
767
        for (i = 0; i < ETH_ALEN; i++)
768
                de600_put_byte(dev->dev_addr[i]);
769
 
770
        /* where to start saving incoming packets */
771
        rx_page = RX_BP | RX_BASE_PAGE;
772
        de600_setup_address(MEM_4K, RW_ADDR);
773
        /* Enable receiver */
774
        de600_put_command(RX_ENABLE);
775
        select_prn();
776
        restore_flags(flags);
777
 
778
        return 0; /* OK */
779
}
780
 
781
#ifdef FAKE_SMALL_MAX
782
/*
783
 *      The new router code (coming soon 8-) ) will fix this properly.
784
 */
785
#define DE600_MIN_WINDOW 1024
786
#define DE600_MAX_WINDOW 2048
787
#define DE600_TCP_WINDOW_DIFF 1024
788
/*
789
 * Copied from "net/inet/sock.c"
790
 *
791
 * Sets a lower max receive window in order to achieve <= 2
792
 * packets arriving at the adapter in fast succession.
793
 * (No way that a DE-600 can keep up with a net saturated
794
 *  with packets homing in on it :-( )
795
 *
796
 * Since there are only 2 receive buffers in the DE-600
797
 * and it takes some time to copy from the adapter,
798
 * this is absolutely necessary for any TCP performance whatsoever!
799
 *
800
 * Note that the returned window info will never be smaller than
801
 * DE600_MIN_WINDOW, i.e. 1024
802
 * This differs from the standard function, that can return an
803
 * arbitrarily small window!
804
 */
805
#define min(a,b)        ((a)<(b)?(a):(b))
806
static unsigned long
807
de600_rspace(struct sock *sk)
808
{
809
  int amt;
810
 
811
  if (sk != NULL) {
812
/*
813
 * Hack! You might want to play with commenting away the following line,
814
 * if you know what you do!
815
        sk->max_unacked = DE600_MAX_WINDOW - DE600_TCP_WINDOW_DIFF;
816
 */
817
 
818
        if (sk->rmem_alloc >= sk->rcvbuf-2*DE600_MIN_WINDOW) return(0);
819
        amt = min((sk->rcvbuf-sk->rmem_alloc)/2/*-DE600_MIN_WINDOW*/, DE600_MAX_WINDOW);
820
        if (amt < 0) return(0);
821
        return(amt);
822
  }
823
  return(0);
824
}
825
#endif
826
 
827
#ifdef MODULE
828
static char nullname[8];
829
static struct device de600_dev = {
830
        nullname, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, de600_probe };
831
 
832
int
833
init_module(void)
834
{
835
        if (register_netdev(&de600_dev) != 0)
836
                return -EIO;
837
        return 0;
838
}
839
 
840
void
841
cleanup_module(void)
842
{
843
        unregister_netdev(&de600_dev);
844
        release_region(DE600_IO, 3);
845
}
846
#endif /* MODULE */
847
/*
848
 * Local variables:
849
 *  kernel-compile-command: "gcc -D__KERNEL__ -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
850
 *  module-compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
851
 *  compile-command: "gcc -D__KERNEL__ -DMODULE -Ilinux/include -I../../net/inet -Wall -Wstrict-prototypes -O2 -m486 -c de600.c"
852
 * End:
853
 */

powered by: WebSVN 2.1.0

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