~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise-security

« back to all changes in this revision

Viewing changes to drivers/net/ethernet/dlink/de620.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati
  • Date: 2011-12-06 15:56:07 UTC
  • Revision ID: package-import@ubuntu.com-20111206155607-pcf44kv5fmhk564f
Tags: 3.2.0-1401.1
[ Paolo Pisati ]

* Rebased on top of Ubuntu-3.2.0-3.8
* Tilt-tracking @ ef2487af4bb15bdd0689631774b5a5e3a59f74e2
* Delete debian.ti-omap4/control, it shoudln't be tracked
* Fix architecture spelling (s/armel/armhf/)
* [Config] Update configs following 3.2 import
* [Config] Fix compilation: disable CODA and ARCH_OMAP3
* [Config] Fix compilation: disable Ethernet Faraday
* Update series to precise

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      de620.c $Revision: 1.40 $ BETA
 
3
 *
 
4
 *
 
5
 *      Linux driver for the D-Link DE-620 Ethernet pocket adapter.
 
6
 *
 
7
 *      Portions (C) Copyright 1993, 1994 by Bjorn Ekwall <bj0rn@blox.se>
 
8
 *
 
9
 *      Based on adapter information gathered from DOS packetdriver
 
10
 *      sources from D-Link Inc:  (Special thanks to Henry Ngai of D-Link.)
 
11
 *              Portions (C) Copyright D-Link SYSTEM Inc. 1991, 1992
 
12
 *              Copyright, 1988, Russell Nelson, Crynwr Software
 
13
 *
 
14
 *      Adapted to the sample network driver core for linux,
 
15
 *      written by: Donald Becker <becker@super.org>
 
16
 *              (Now at <becker@scyld.com>)
 
17
 *
 
18
 *      Valuable assistance from:
 
19
 *              J. Joshua Kopper <kopper@rtsg.mot.com>
 
20
 *              Olav Kvittem <Olav.Kvittem@uninett.no>
 
21
 *              Germano Caronni <caronni@nessie.cs.id.ethz.ch>
 
22
 *              Jeremy Fitzhardinge <jeremy@suite.sw.oz.au>
 
23
 *
 
24
 *****************************************************************************/
 
25
/*
 
26
 *      This program is free software; you can redistribute it and/or modify
 
27
 *      it under the terms of the GNU General Public License as published by
 
28
 *      the Free Software Foundation; either version 2, or (at your option)
 
29
 *      any later version.
 
30
 *
 
31
 *      This program is distributed in the hope that it will be useful,
 
32
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 
33
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
34
 *      GNU General Public License for more details.
 
35
 *
 
36
 *      You should have received a copy of the GNU General Public License
 
37
 *      along with this program; if not, write to the Free Software
 
38
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
39
 *
 
40
 *****************************************************************************/
 
41
static const char version[] =
 
42
        "de620.c: $Revision: 1.40 $,  Bjorn Ekwall <bj0rn@blox.se>\n";
 
43
 
 
44
/***********************************************************************
 
45
 *
 
46
 * "Tuning" section.
 
47
 *
 
48
 * Compile-time options: (see below for descriptions)
 
49
 * -DDE620_IO=0x378     (lpt1)
 
50
 * -DDE620_IRQ=7        (lpt1)
 
51
 * -DSHUTDOWN_WHEN_LOST
 
52
 * -DCOUNT_LOOPS
 
53
 * -DLOWSPEED
 
54
 * -DREAD_DELAY
 
55
 * -DWRITE_DELAY
 
56
 */
 
57
 
 
58
/*
 
59
 * This driver assumes that the printer port is a "normal",
 
60
 * dumb, uni-directional port!
 
61
 * If your port is "fancy" in any way, please try to set it to "normal"
 
62
 * with your BIOS setup.  I have no access to machines with bi-directional
 
63
 * ports, so I can't test such a driver :-(
 
64
 * (Yes, I _know_ it is possible to use DE620 with bidirectional ports...)
 
65
 *
 
66
 * There are some clones of DE620 out there, with different names.
 
67
 * If the current driver does not recognize a clone, try to change
 
68
 * the following #define to:
 
69
 *
 
70
 * #define DE620_CLONE 1
 
71
 */
 
72
#define DE620_CLONE 0
 
73
 
 
74
/*
 
75
 * If the adapter has problems with high speeds, enable this #define
 
76
 * otherwise full printerport speed will be attempted.
 
77
 *
 
78
 * You can tune the READ_DELAY/WRITE_DELAY below if you enable LOWSPEED
 
79
 *
 
80
#define LOWSPEED
 
81
 */
 
82
 
 
83
#ifndef READ_DELAY
 
84
#define READ_DELAY 100  /* adapter internal read delay in 100ns units */
 
85
#endif
 
86
 
 
87
#ifndef WRITE_DELAY
 
88
#define WRITE_DELAY 100 /* adapter internal write delay in 100ns units */
 
89
#endif
 
90
 
 
91
/*
 
92
 * Enable this #define if you want the adapter to do a "ifconfig down" on
 
93
 * itself when we have detected that something is possibly wrong with it.
 
94
 * The default behaviour is to retry with "adapter_init()" until success.
 
95
 * This should be used for debugging purposes only.
 
96
 *
 
97
#define SHUTDOWN_WHEN_LOST
 
98
 */
 
99
 
 
100
#ifdef LOWSPEED
 
101
/*
 
102
 * Enable this #define if you want to see debugging output that show how long
 
103
 * we have to wait before the DE-620 is ready for the next read/write/command.
 
104
 *
 
105
#define COUNT_LOOPS
 
106
 */
 
107
#endif
 
108
 
 
109
#include <linux/module.h>
 
110
#include <linux/kernel.h>
 
111
#include <linux/types.h>
 
112
#include <linux/fcntl.h>
 
113
#include <linux/string.h>
 
114
#include <linux/interrupt.h>
 
115
#include <linux/ioport.h>
 
116
#include <linux/in.h>
 
117
#include <linux/errno.h>
 
118
#include <linux/init.h>
 
119
#include <linux/inet.h>
 
120
#include <linux/netdevice.h>
 
121
#include <linux/etherdevice.h>
 
122
#include <linux/skbuff.h>
 
123
 
 
124
#include <asm/io.h>
 
125
#include <asm/system.h>
 
126
 
 
127
/* Constant definitions for the DE-620 registers, commands and bits */
 
128
#include "de620.h"
 
129
 
 
130
typedef unsigned char byte;
 
131
 
 
132
/*******************************************************
 
133
 *                                                     *
 
134
 * Definition of D-Link DE-620 Ethernet Pocket adapter *
 
135
 * See also "de620.h"                                  *
 
136
 *                                                     *
 
137
 *******************************************************/
 
138
#ifndef DE620_IO /* Compile-time configurable */
 
139
#define DE620_IO 0x378
 
140
#endif
 
141
 
 
142
#ifndef DE620_IRQ /* Compile-time configurable */
 
143
#define DE620_IRQ       7
 
144
#endif
 
145
 
 
146
#define DATA_PORT       (dev->base_addr)
 
147
#define STATUS_PORT     (dev->base_addr + 1)
 
148
#define COMMAND_PORT    (dev->base_addr + 2)
 
149
 
 
150
#define RUNT 60         /* Too small Ethernet packet */
 
151
#define GIANT 1514      /* largest legal size packet, no fcs */
 
152
 
 
153
/*
 
154
 * Force media with insmod:
 
155
 *      insmod de620.o bnc=1
 
156
 * or
 
157
 *      insmod de620.o utp=1
 
158
 *
 
159
 * Force io and/or irq with insmod:
 
160
 *      insmod de620.o io=0x378 irq=7
 
161
 *
 
162
 * Make a clone skip the Ethernet-address range check:
 
163
 *      insmod de620.o clone=1
 
164
 */
 
165
static int bnc;
 
166
static int utp;
 
167
static int io  = DE620_IO;
 
168
static int irq = DE620_IRQ;
 
169
static int clone = DE620_CLONE;
 
170
 
 
171
static spinlock_t de620_lock;
 
172
 
 
173
module_param(bnc, int, 0);
 
174
module_param(utp, int, 0);
 
175
module_param(io, int, 0);
 
176
module_param(irq, int, 0);
 
177
module_param(clone, int, 0);
 
178
MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)");
 
179
MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)");
 
180
MODULE_PARM_DESC(io, "DE-620 I/O base address,required");
 
181
MODULE_PARM_DESC(irq, "DE-620 IRQ number,required");
 
182
MODULE_PARM_DESC(clone, "Check also for non-D-Link DE-620 clones (0-1)");
 
183
 
 
184
/***********************************************
 
185
 *                                             *
 
186
 * Index to functions, as function prototypes. *
 
187
 *                                             *
 
188
 ***********************************************/
 
189
 
 
190
/*
 
191
 * Routines used internally. (See also "convenience macros.. below")
 
192
 */
 
193
 
 
194
/* Put in the device structure. */
 
195
static int      de620_open(struct net_device *);
 
196
static int      de620_close(struct net_device *);
 
197
static void     de620_set_multicast_list(struct net_device *);
 
198
static int      de620_start_xmit(struct sk_buff *, struct net_device *);
 
199
 
 
200
/* Dispatch from interrupts. */
 
201
static irqreturn_t de620_interrupt(int, void *);
 
202
static int      de620_rx_intr(struct net_device *);
 
203
 
 
204
/* Initialization */
 
205
static int      adapter_init(struct net_device *);
 
206
static int      read_eeprom(struct net_device *);
 
207
 
 
208
 
 
209
/*
 
210
 * D-Link driver variables:
 
211
 */
 
212
#define SCR_DEF NIBBLEMODE |INTON | SLEEP | AUTOTX
 
213
#define TCR_DEF RXPB                    /* not used: | TXSUCINT | T16INT */
 
214
#define DE620_RX_START_PAGE 12          /* 12 pages (=3k) reserved for tx */
 
215
#define DEF_NIC_CMD IRQEN | ICEN | DS1
 
216
 
 
217
static volatile byte    NIC_Cmd;
 
218
static volatile byte    next_rx_page;
 
219
static byte             first_rx_page;
 
220
static byte             last_rx_page;
 
221
static byte             EIPRegister;
 
222
 
 
223
static struct nic {
 
224
        byte    NodeID[6];
 
225
        byte    RAM_Size;
 
226
        byte    Model;
 
227
        byte    Media;
 
228
        byte    SCR;
 
229
} nic_data;
 
230
 
 
231
/**********************************************************
 
232
 *                                                        *
 
233
 * Convenience macros/functions for D-Link DE-620 adapter *
 
234
 *                                                        *
 
235
 **********************************************************/
 
236
#define de620_tx_buffs(dd) (inb(STATUS_PORT) & (TXBF0 | TXBF1))
 
237
#define de620_flip_ds(dd) NIC_Cmd ^= DS0 | DS1; outb(NIC_Cmd, COMMAND_PORT);
 
238
 
 
239
/* Check for ready-status, and return a nibble (high 4 bits) for data input */
 
240
#ifdef COUNT_LOOPS
 
241
static int tot_cnt;
 
242
#endif
 
243
static inline byte
 
244
de620_ready(struct net_device *dev)
 
245
{
 
246
        byte value;
 
247
        register short int cnt = 0;
 
248
 
 
249
        while ((((value = inb(STATUS_PORT)) & READY) == 0) && (cnt <= 1000))
 
250
                ++cnt;
 
251
 
 
252
#ifdef COUNT_LOOPS
 
253
        tot_cnt += cnt;
 
254
#endif
 
255
        return value & 0xf0; /* nibble */
 
256
}
 
257
 
 
258
static inline void
 
259
de620_send_command(struct net_device *dev, byte cmd)
 
260
{
 
261
        de620_ready(dev);
 
262
        if (cmd == W_DUMMY)
 
263
                outb(NIC_Cmd, COMMAND_PORT);
 
264
 
 
265
        outb(cmd, DATA_PORT);
 
266
 
 
267
        outb(NIC_Cmd ^ CS0, COMMAND_PORT);
 
268
        de620_ready(dev);
 
269
        outb(NIC_Cmd, COMMAND_PORT);
 
270
}
 
271
 
 
272
static inline void
 
273
de620_put_byte(struct net_device *dev, byte value)
 
274
{
 
275
        /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
 
276
        de620_ready(dev);
 
277
        outb(value, DATA_PORT);
 
278
        de620_flip_ds(dev);
 
279
}
 
280
 
 
281
static inline byte
 
282
de620_read_byte(struct net_device *dev)
 
283
{
 
284
        byte value;
 
285
 
 
286
        /* The de620_ready() makes 7 loops, on the average, on a DX2/66 */
 
287
        value = de620_ready(dev); /* High nibble */
 
288
        de620_flip_ds(dev);
 
289
        value |= de620_ready(dev) >> 4; /* Low nibble */
 
290
        return value;
 
291
}
 
292
 
 
293
static inline void
 
294
de620_write_block(struct net_device *dev, byte *buffer, int count, int pad)
 
295
{
 
296
#ifndef LOWSPEED
 
297
        byte uflip = NIC_Cmd ^ (DS0 | DS1);
 
298
        byte dflip = NIC_Cmd;
 
299
#else /* LOWSPEED */
 
300
#ifdef COUNT_LOOPS
 
301
        int bytes = count;
 
302
#endif /* COUNT_LOOPS */
 
303
#endif /* LOWSPEED */
 
304
 
 
305
#ifdef LOWSPEED
 
306
#ifdef COUNT_LOOPS
 
307
        tot_cnt = 0;
 
308
#endif /* COUNT_LOOPS */
 
309
        /* No further optimization useful, the limit is in the adapter. */
 
310
        for ( ; count > 0; --count, ++buffer) {
 
311
                de620_put_byte(dev,*buffer);
 
312
        }
 
313
        for ( count = pad ; count > 0; --count, ++buffer) {
 
314
                de620_put_byte(dev, 0);
 
315
        }
 
316
        de620_send_command(dev,W_DUMMY);
 
317
#ifdef COUNT_LOOPS
 
318
        /* trial debug output: loops per byte in de620_ready() */
 
319
        printk("WRITE(%d)\n", tot_cnt/((bytes?bytes:1)));
 
320
#endif /* COUNT_LOOPS */
 
321
#else /* not LOWSPEED */
 
322
        for ( ; count > 0; count -=2) {
 
323
                outb(*buffer++, DATA_PORT);
 
324
                outb(uflip, COMMAND_PORT);
 
325
                outb(*buffer++, DATA_PORT);
 
326
                outb(dflip, COMMAND_PORT);
 
327
        }
 
328
        de620_send_command(dev,W_DUMMY);
 
329
#endif /* LOWSPEED */
 
330
}
 
331
 
 
332
static inline void
 
333
de620_read_block(struct net_device *dev, byte *data, int count)
 
334
{
 
335
#ifndef LOWSPEED
 
336
        byte value;
 
337
        byte uflip = NIC_Cmd ^ (DS0 | DS1);
 
338
        byte dflip = NIC_Cmd;
 
339
#else /* LOWSPEED */
 
340
#ifdef COUNT_LOOPS
 
341
        int bytes = count;
 
342
 
 
343
        tot_cnt = 0;
 
344
#endif /* COUNT_LOOPS */
 
345
#endif /* LOWSPEED */
 
346
 
 
347
#ifdef LOWSPEED
 
348
        /* No further optimization useful, the limit is in the adapter. */
 
349
        while (count-- > 0) {
 
350
                *data++ = de620_read_byte(dev);
 
351
                de620_flip_ds(dev);
 
352
        }
 
353
#ifdef COUNT_LOOPS
 
354
        /* trial debug output: loops per byte in de620_ready() */
 
355
        printk("READ(%d)\n", tot_cnt/(2*(bytes?bytes:1)));
 
356
#endif /* COUNT_LOOPS */
 
357
#else /* not LOWSPEED */
 
358
        while (count-- > 0) {
 
359
                value = inb(STATUS_PORT) & 0xf0; /* High nibble */
 
360
                outb(uflip, COMMAND_PORT);
 
361
                *data++ = value | inb(STATUS_PORT) >> 4; /* Low nibble */
 
362
                outb(dflip , COMMAND_PORT);
 
363
        }
 
364
#endif /* LOWSPEED */
 
365
}
 
366
 
 
367
static inline void
 
368
de620_set_delay(struct net_device *dev)
 
369
{
 
370
        de620_ready(dev);
 
371
        outb(W_DFR, DATA_PORT);
 
372
        outb(NIC_Cmd ^ CS0, COMMAND_PORT);
 
373
 
 
374
        de620_ready(dev);
 
375
#ifdef LOWSPEED
 
376
        outb(WRITE_DELAY, DATA_PORT);
 
377
#else
 
378
        outb(0, DATA_PORT);
 
379
#endif
 
380
        de620_flip_ds(dev);
 
381
 
 
382
        de620_ready(dev);
 
383
#ifdef LOWSPEED
 
384
        outb(READ_DELAY, DATA_PORT);
 
385
#else
 
386
        outb(0, DATA_PORT);
 
387
#endif
 
388
        de620_flip_ds(dev);
 
389
}
 
390
 
 
391
static inline void
 
392
de620_set_register(struct net_device *dev, byte reg, byte value)
 
393
{
 
394
        de620_ready(dev);
 
395
        outb(reg, DATA_PORT);
 
396
        outb(NIC_Cmd ^ CS0, COMMAND_PORT);
 
397
 
 
398
        de620_put_byte(dev, value);
 
399
}
 
400
 
 
401
static inline byte
 
402
de620_get_register(struct net_device *dev, byte reg)
 
403
{
 
404
        byte value;
 
405
 
 
406
        de620_send_command(dev,reg);
 
407
        value = de620_read_byte(dev);
 
408
        de620_send_command(dev,W_DUMMY);
 
409
 
 
410
        return value;
 
411
}
 
412
 
 
413
/*********************************************************************
 
414
 *
 
415
 * Open/initialize the board.
 
416
 *
 
417
 * This routine should set everything up anew at each open, even
 
418
 * registers that "should" only need to be set once at boot, so that
 
419
 * there is a non-reboot way to recover if something goes wrong.
 
420
 *
 
421
 */
 
422
static int de620_open(struct net_device *dev)
 
423
{
 
424
        int ret = request_irq(dev->irq, de620_interrupt, 0, dev->name, dev);
 
425
        if (ret) {
 
426
                printk (KERN_ERR "%s: unable to get IRQ %d\n", dev->name, dev->irq);
 
427
                return ret;
 
428
        }
 
429
 
 
430
        if (adapter_init(dev)) {
 
431
                ret = -EIO;
 
432
                goto out_free_irq;
 
433
        }
 
434
 
 
435
        netif_start_queue(dev);
 
436
        return 0;
 
437
 
 
438
out_free_irq:
 
439
        free_irq(dev->irq, dev);
 
440
        return ret;
 
441
}
 
442
 
 
443
/************************************************
 
444
 *
 
445
 * The inverse routine to de620_open().
 
446
 *
 
447
 */
 
448
 
 
449
static int de620_close(struct net_device *dev)
 
450
{
 
451
        netif_stop_queue(dev);
 
452
        /* disable recv */
 
453
        de620_set_register(dev, W_TCR, RXOFF);
 
454
        free_irq(dev->irq, dev);
 
455
        return 0;
 
456
}
 
457
 
 
458
/*********************************************
 
459
 *
 
460
 * Set or clear the multicast filter for this adaptor.
 
461
 * (no real multicast implemented for the DE-620, but she can be promiscuous...)
 
462
 *
 
463
 */
 
464
 
 
465
static void de620_set_multicast_list(struct net_device *dev)
 
466
{
 
467
        if (!netdev_mc_empty(dev) || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
 
468
        { /* Enable promiscuous mode */
 
469
                de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
 
470
        }
 
471
        else
 
472
        { /* Disable promiscuous mode, use normal mode */
 
473
                de620_set_register(dev, W_TCR, TCR_DEF);
 
474
        }
 
475
}
 
476
 
 
477
/*******************************************************
 
478
 *
 
479
 * Handle timeouts on transmit
 
480
 */
 
481
 
 
482
static void de620_timeout(struct net_device *dev)
 
483
{
 
484
        printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name, "network cable problem");
 
485
        /* Restart the adapter. */
 
486
        if (!adapter_init(dev)) /* maybe close it */
 
487
                netif_wake_queue(dev);
 
488
}
 
489
 
 
490
/*******************************************************
 
491
 *
 
492
 * Copy a buffer to the adapter transmit page memory.
 
493
 * Start sending.
 
494
 */
 
495
static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
496
{
 
497
        unsigned long flags;
 
498
        int len;
 
499
        byte *buffer = skb->data;
 
500
        byte using_txbuf;
 
501
 
 
502
        using_txbuf = de620_tx_buffs(dev); /* Peek at the adapter */
 
503
 
 
504
        netif_stop_queue(dev);
 
505
 
 
506
 
 
507
        if ((len = skb->len) < RUNT)
 
508
                len = RUNT;
 
509
        if (len & 1) /* send an even number of bytes */
 
510
                ++len;
 
511
 
 
512
        /* Start real output */
 
513
 
 
514
        spin_lock_irqsave(&de620_lock, flags);
 
515
        pr_debug("de620_start_xmit: len=%d, bufs 0x%02x\n",
 
516
                (int)skb->len, using_txbuf);
 
517
 
 
518
        /* select a free tx buffer. if there is one... */
 
519
        switch (using_txbuf) {
 
520
        default: /* both are free: use TXBF0 */
 
521
        case TXBF1: /* use TXBF0 */
 
522
                de620_send_command(dev,W_CR | RW0);
 
523
                using_txbuf |= TXBF0;
 
524
                break;
 
525
 
 
526
        case TXBF0: /* use TXBF1 */
 
527
                de620_send_command(dev,W_CR | RW1);
 
528
                using_txbuf |= TXBF1;
 
529
                break;
 
530
 
 
531
        case (TXBF0 | TXBF1): /* NONE!!! */
 
532
                printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name);
 
533
                spin_unlock_irqrestore(&de620_lock, flags);
 
534
                return NETDEV_TX_BUSY;
 
535
        }
 
536
        de620_write_block(dev, buffer, skb->len, len-skb->len);
 
537
 
 
538
        if(!(using_txbuf == (TXBF0 | TXBF1)))
 
539
                netif_wake_queue(dev);
 
540
 
 
541
        dev->stats.tx_packets++;
 
542
        spin_unlock_irqrestore(&de620_lock, flags);
 
543
        dev_kfree_skb (skb);
 
544
        return NETDEV_TX_OK;
 
545
}
 
546
 
 
547
/*****************************************************
 
548
 *
 
549
 * Handle the network interface interrupts.
 
550
 *
 
551
 */
 
552
static irqreturn_t
 
553
de620_interrupt(int irq_in, void *dev_id)
 
554
{
 
555
        struct net_device *dev = dev_id;
 
556
        byte irq_status;
 
557
        int bogus_count = 0;
 
558
        int again = 0;
 
559
 
 
560
        spin_lock(&de620_lock);
 
561
 
 
562
        /* Read the status register (_not_ the status port) */
 
563
        irq_status = de620_get_register(dev, R_STS);
 
564
 
 
565
        pr_debug("de620_interrupt (%2.2X)\n", irq_status);
 
566
 
 
567
        if (irq_status & RXGOOD) {
 
568
                do {
 
569
                        again = de620_rx_intr(dev);
 
570
                        pr_debug("again=%d\n", again);
 
571
                }
 
572
                while (again && (++bogus_count < 100));
 
573
        }
 
574
 
 
575
        if(de620_tx_buffs(dev) != (TXBF0 | TXBF1))
 
576
                netif_wake_queue(dev);
 
577
 
 
578
        spin_unlock(&de620_lock);
 
579
        return IRQ_HANDLED;
 
580
}
 
581
 
 
582
/**************************************
 
583
 *
 
584
 * Get a packet from the adapter
 
585
 *
 
586
 * Send it "upstairs"
 
587
 *
 
588
 */
 
589
static int de620_rx_intr(struct net_device *dev)
 
590
{
 
591
        struct header_buf {
 
592
                byte            status;
 
593
                byte            Rx_NextPage;
 
594
                unsigned short  Rx_ByteCount;
 
595
        } header_buf;
 
596
        struct sk_buff *skb;
 
597
        int size;
 
598
        byte *buffer;
 
599
        byte pagelink;
 
600
        byte curr_page;
 
601
 
 
602
        pr_debug("de620_rx_intr: next_rx_page = %d\n", next_rx_page);
 
603
 
 
604
        /* Tell the adapter that we are going to read data, and from where */
 
605
        de620_send_command(dev, W_CR | RRN);
 
606
        de620_set_register(dev, W_RSA1, next_rx_page);
 
607
        de620_set_register(dev, W_RSA0, 0);
 
608
 
 
609
        /* Deep breath, and away we goooooo */
 
610
        de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
 
611
        pr_debug("page status=0x%02x, nextpage=%d, packetsize=%d\n",
 
612
                header_buf.status, header_buf.Rx_NextPage,
 
613
                header_buf.Rx_ByteCount);
 
614
 
 
615
        /* Plausible page header? */
 
616
        pagelink = header_buf.Rx_NextPage;
 
617
        if ((pagelink < first_rx_page) || (last_rx_page < pagelink)) {
 
618
                /* Ouch... Forget it! Skip all and start afresh... */
 
619
                printk(KERN_WARNING "%s: Ring overrun? Restoring...\n", dev->name);
 
620
                /* You win some, you lose some. And sometimes plenty... */
 
621
                adapter_init(dev);
 
622
                netif_wake_queue(dev);
 
623
                dev->stats.rx_over_errors++;
 
624
                return 0;
 
625
        }
 
626
 
 
627
        /* OK, this look good, so far. Let's see if it's consistent... */
 
628
        /* Let's compute the start of the next packet, based on where we are */
 
629
        pagelink = next_rx_page +
 
630
                ((header_buf.Rx_ByteCount + (4 - 1 + 0x100)) >> 8);
 
631
 
 
632
        /* Are we going to wrap around the page counter? */
 
633
        if (pagelink > last_rx_page)
 
634
                pagelink -= (last_rx_page - first_rx_page + 1);
 
635
 
 
636
        /* Is the _computed_ next page number equal to what the adapter says? */
 
637
        if (pagelink != header_buf.Rx_NextPage) {
 
638
                /* Naah, we'll skip this packet. Probably bogus data as well */
 
639
                printk(KERN_WARNING "%s: Page link out of sync! Restoring...\n", dev->name);
 
640
                next_rx_page = header_buf.Rx_NextPage; /* at least a try... */
 
641
                de620_send_command(dev, W_DUMMY);
 
642
                de620_set_register(dev, W_NPRF, next_rx_page);
 
643
                dev->stats.rx_over_errors++;
 
644
                return 0;
 
645
        }
 
646
        next_rx_page = pagelink;
 
647
 
 
648
        size = header_buf.Rx_ByteCount - 4;
 
649
        if ((size < RUNT) || (GIANT < size)) {
 
650
                printk(KERN_WARNING "%s: Illegal packet size: %d!\n", dev->name, size);
 
651
        }
 
652
        else { /* Good packet? */
 
653
                skb = dev_alloc_skb(size+2);
 
654
                if (skb == NULL) { /* Yeah, but no place to put it... */
 
655
                        printk(KERN_WARNING "%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size);
 
656
                        dev->stats.rx_dropped++;
 
657
                }
 
658
                else { /* Yep! Go get it! */
 
659
                        skb_reserve(skb,2);     /* Align */
 
660
                        /* skb->data points to the start of sk_buff data area */
 
661
                        buffer = skb_put(skb,size);
 
662
                        /* copy the packet into the buffer */
 
663
                        de620_read_block(dev, buffer, size);
 
664
                        pr_debug("Read %d bytes\n", size);
 
665
                        skb->protocol=eth_type_trans(skb,dev);
 
666
                        netif_rx(skb); /* deliver it "upstairs" */
 
667
                        /* count all receives */
 
668
                        dev->stats.rx_packets++;
 
669
                        dev->stats.rx_bytes += size;
 
670
                }
 
671
        }
 
672
 
 
673
        /* Let's peek ahead to see if we have read the last current packet */
 
674
        /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */
 
675
        curr_page = de620_get_register(dev, R_CPR);
 
676
        de620_set_register(dev, W_NPRF, next_rx_page);
 
677
        pr_debug("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page);
 
678
 
 
679
        return next_rx_page != curr_page; /* That was slightly tricky... */
 
680
}
 
681
 
 
682
/*********************************************
 
683
 *
 
684
 * Reset the adapter to a known state
 
685
 *
 
686
 */
 
687
static int adapter_init(struct net_device *dev)
 
688
{
 
689
        int i;
 
690
        static int was_down;
 
691
 
 
692
        if ((nic_data.Model == 3) || (nic_data.Model == 0)) { /* CT */
 
693
                EIPRegister = NCTL0;
 
694
                if (nic_data.Media != 1)
 
695
                        EIPRegister |= NIS0;    /* not BNC */
 
696
        }
 
697
        else if (nic_data.Model == 2) { /* UTP */
 
698
                EIPRegister = NCTL0 | NIS0;
 
699
        }
 
700
 
 
701
        if (utp)
 
702
                EIPRegister = NCTL0 | NIS0;
 
703
        if (bnc)
 
704
                EIPRegister = NCTL0;
 
705
 
 
706
        de620_send_command(dev, W_CR | RNOP | CLEAR);
 
707
        de620_send_command(dev, W_CR | RNOP);
 
708
 
 
709
        de620_set_register(dev, W_SCR, SCR_DEF);
 
710
        /* disable recv to wait init */
 
711
        de620_set_register(dev, W_TCR, RXOFF);
 
712
 
 
713
        /* Set the node ID in the adapter */
 
714
        for (i = 0; i < 6; ++i) { /* W_PARn = 0xaa + n */
 
715
                de620_set_register(dev, W_PAR0 + i, dev->dev_addr[i]);
 
716
        }
 
717
 
 
718
        de620_set_register(dev, W_EIP, EIPRegister);
 
719
 
 
720
        next_rx_page = first_rx_page = DE620_RX_START_PAGE;
 
721
        if (nic_data.RAM_Size)
 
722
                last_rx_page = nic_data.RAM_Size - 1;
 
723
        else /* 64k RAM */
 
724
                last_rx_page = 255;
 
725
 
 
726
        de620_set_register(dev, W_SPR, first_rx_page); /* Start Page Register*/
 
727
        de620_set_register(dev, W_EPR, last_rx_page);  /* End Page Register */
 
728
        de620_set_register(dev, W_CPR, first_rx_page);/*Current Page Register*/
 
729
        de620_send_command(dev, W_NPR | first_rx_page); /* Next Page Register*/
 
730
        de620_send_command(dev, W_DUMMY);
 
731
        de620_set_delay(dev);
 
732
 
 
733
        /* Final sanity check: Anybody out there? */
 
734
        /* Let's hope some bits from the statusregister make a good check */
 
735
#define CHECK_MASK (  0 | TXSUC |  T16  |  0  | RXCRC | RXSHORT |  0  |  0  )
 
736
#define CHECK_OK   (  0 |   0   |  0    |  0  |   0   |   0     |  0  |  0  )
 
737
        /* success:   X     0      0       X      0       0        X     X  */
 
738
        /* ignore:   EEDI                RXGOOD                   COLS  LNKS*/
 
739
 
 
740
        if (((i = de620_get_register(dev, R_STS)) & CHECK_MASK) != CHECK_OK) {
 
741
                printk(KERN_ERR "%s: Something has happened to the DE-620!  Please check it"
 
742
#ifdef SHUTDOWN_WHEN_LOST
 
743
                        " and do a new ifconfig"
 
744
#endif
 
745
                        "! (%02x)\n", dev->name, i);
 
746
#ifdef SHUTDOWN_WHEN_LOST
 
747
                /* Goodbye, cruel world... */
 
748
                dev->flags &= ~IFF_UP;
 
749
                de620_close(dev);
 
750
#endif
 
751
                was_down = 1;
 
752
                return 1; /* failed */
 
753
        }
 
754
        if (was_down) {
 
755
                printk(KERN_WARNING "%s: Thanks, I feel much better now!\n", dev->name);
 
756
                was_down = 0;
 
757
        }
 
758
 
 
759
        /* All OK, go ahead... */
 
760
        de620_set_register(dev, W_TCR, TCR_DEF);
 
761
 
 
762
        return 0; /* all ok */
 
763
}
 
764
 
 
765
static const struct net_device_ops de620_netdev_ops = {
 
766
        .ndo_open               = de620_open,
 
767
        .ndo_stop               = de620_close,
 
768
        .ndo_start_xmit         = de620_start_xmit,
 
769
        .ndo_tx_timeout         = de620_timeout,
 
770
        .ndo_set_rx_mode        = de620_set_multicast_list,
 
771
        .ndo_change_mtu         = eth_change_mtu,
 
772
        .ndo_set_mac_address    = eth_mac_addr,
 
773
        .ndo_validate_addr      = eth_validate_addr,
 
774
};
 
775
 
 
776
/******************************************************************************
 
777
 *
 
778
 * Only start-up code below
 
779
 *
 
780
 */
 
781
/****************************************
 
782
 *
 
783
 * Check if there is a DE-620 connected
 
784
 */
 
785
struct net_device * __init de620_probe(int unit)
 
786
{
 
787
        byte checkbyte = 0xa5;
 
788
        struct net_device *dev;
 
789
        int err = -ENOMEM;
 
790
        int i;
 
791
 
 
792
        dev = alloc_etherdev(0);
 
793
        if (!dev)
 
794
                goto out;
 
795
 
 
796
        spin_lock_init(&de620_lock);
 
797
 
 
798
        /*
 
799
         * This is where the base_addr and irq gets set.
 
800
         * Tunable at compile-time and insmod-time
 
801
         */
 
802
        dev->base_addr = io;
 
803
        dev->irq       = irq;
 
804
 
 
805
        /* allow overriding parameters on command line */
 
806
        if (unit >= 0) {
 
807
                sprintf(dev->name, "eth%d", unit);
 
808
                netdev_boot_setup_check(dev);
 
809
        }
 
810
 
 
811
        pr_debug("%s", version);
 
812
 
 
813
        printk(KERN_INFO "D-Link DE-620 pocket adapter");
 
814
 
 
815
        if (!request_region(dev->base_addr, 3, "de620")) {
 
816
                printk(" io 0x%3lX, which is busy.\n", dev->base_addr);
 
817
                err = -EBUSY;
 
818
                goto out1;
 
819
        }
 
820
 
 
821
        /* Initially, configure basic nibble mode, so we can read the EEPROM */
 
822
        NIC_Cmd = DEF_NIC_CMD;
 
823
        de620_set_register(dev, W_EIP, EIPRegister);
 
824
 
 
825
        /* Anybody out there? */
 
826
        de620_set_register(dev, W_CPR, checkbyte);
 
827
        checkbyte = de620_get_register(dev, R_CPR);
 
828
 
 
829
        if ((checkbyte != 0xa5) || (read_eeprom(dev) != 0)) {
 
830
                printk(" not identified in the printer port\n");
 
831
                err = -ENODEV;
 
832
                goto out2;
 
833
        }
 
834
 
 
835
        /* else, got it! */
 
836
        dev->dev_addr[0] = nic_data.NodeID[0];
 
837
        for (i = 1; i < ETH_ALEN; i++) {
 
838
                dev->dev_addr[i] = nic_data.NodeID[i];
 
839
                dev->broadcast[i] = 0xff;
 
840
        }
 
841
 
 
842
        printk(", Ethernet Address: %pM", dev->dev_addr);
 
843
 
 
844
        printk(" (%dk RAM,",
 
845
                (nic_data.RAM_Size) ? (nic_data.RAM_Size >> 2) : 64);
 
846
 
 
847
        if (nic_data.Media == 1)
 
848
                printk(" BNC)\n");
 
849
        else
 
850
                printk(" UTP)\n");
 
851
 
 
852
        dev->netdev_ops = &de620_netdev_ops;
 
853
        dev->watchdog_timeo     = HZ*2;
 
854
 
 
855
        /* base_addr and irq are already set, see above! */
 
856
 
 
857
        /* dump eeprom */
 
858
        pr_debug("\nEEPROM contents:\n"
 
859
                "RAM_Size = 0x%02X\n"
 
860
                "NodeID = %pM\n"
 
861
                "Model = %d\n"
 
862
                "Media = %d\n"
 
863
                "SCR = 0x%02x\n", nic_data.RAM_Size, nic_data.NodeID,
 
864
                nic_data.Model, nic_data.Media, nic_data.SCR);
 
865
 
 
866
        err = register_netdev(dev);
 
867
        if (err)
 
868
                goto out2;
 
869
        return dev;
 
870
 
 
871
out2:
 
872
        release_region(dev->base_addr, 3);
 
873
out1:
 
874
        free_netdev(dev);
 
875
out:
 
876
        return ERR_PTR(err);
 
877
}
 
878
 
 
879
/**********************************
 
880
 *
 
881
 * Read info from on-board EEPROM
 
882
 *
 
883
 * Note: Bitwise serial I/O to/from the EEPROM vi the status _register_!
 
884
 */
 
885
#define sendit(dev,data) de620_set_register(dev, W_EIP, data | EIPRegister);
 
886
 
 
887
static unsigned short __init ReadAWord(struct net_device *dev, int from)
 
888
{
 
889
        unsigned short data;
 
890
        int nbits;
 
891
 
 
892
        /* cs   [__~~] SET SEND STATE */
 
893
        /* di   [____]                */
 
894
        /* sck  [_~~_]                */
 
895
        sendit(dev, 0); sendit(dev, 1); sendit(dev, 5); sendit(dev, 4);
 
896
 
 
897
        /* Send the 9-bit address from where we want to read the 16-bit word */
 
898
        for (nbits = 9; nbits > 0; --nbits, from <<= 1) {
 
899
                if (from & 0x0100) { /* bit set? */
 
900
                        /* cs    [~~~~] SEND 1 */
 
901
                        /* di    [~~~~]        */
 
902
                        /* sck   [_~~_]        */
 
903
                        sendit(dev, 6); sendit(dev, 7); sendit(dev, 7); sendit(dev, 6);
 
904
                }
 
905
                else {
 
906
                        /* cs    [~~~~] SEND 0 */
 
907
                        /* di    [____]        */
 
908
                        /* sck   [_~~_]        */
 
909
                        sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
 
910
                }
 
911
        }
 
912
 
 
913
        /* Shift in the 16-bit word. The bits appear serially in EEDI (=0x80) */
 
914
        for (data = 0, nbits = 16; nbits > 0; --nbits) {
 
915
                /* cs    [~~~~] SEND 0 */
 
916
                /* di    [____]        */
 
917
                /* sck   [_~~_]        */
 
918
                sendit(dev, 4); sendit(dev, 5); sendit(dev, 5); sendit(dev, 4);
 
919
                data = (data << 1) | ((de620_get_register(dev, R_STS) & EEDI) >> 7);
 
920
        }
 
921
        /* cs    [____] RESET SEND STATE */
 
922
        /* di    [____]                  */
 
923
        /* sck   [_~~_]                  */
 
924
        sendit(dev, 0); sendit(dev, 1); sendit(dev, 1); sendit(dev, 0);
 
925
 
 
926
        return data;
 
927
}
 
928
 
 
929
static int __init read_eeprom(struct net_device *dev)
 
930
{
 
931
        unsigned short wrd;
 
932
 
 
933
        /* D-Link Ethernet addresses are in the series  00:80:c8:7X:XX:XX:XX */
 
934
        wrd = ReadAWord(dev, 0x1aa);    /* bytes 0 + 1 of NodeID */
 
935
        if (!clone && (wrd != htons(0x0080))) /* Valid D-Link ether sequence? */
 
936
                return -1; /* Nope, not a DE-620 */
 
937
        nic_data.NodeID[0] = wrd & 0xff;
 
938
        nic_data.NodeID[1] = wrd >> 8;
 
939
 
 
940
        wrd = ReadAWord(dev, 0x1ab);    /* bytes 2 + 3 of NodeID */
 
941
        if (!clone && ((wrd & 0xff) != 0xc8)) /* Valid D-Link ether sequence? */
 
942
                return -1; /* Nope, not a DE-620 */
 
943
        nic_data.NodeID[2] = wrd & 0xff;
 
944
        nic_data.NodeID[3] = wrd >> 8;
 
945
 
 
946
        wrd = ReadAWord(dev, 0x1ac);    /* bytes 4 + 5 of NodeID */
 
947
        nic_data.NodeID[4] = wrd & 0xff;
 
948
        nic_data.NodeID[5] = wrd >> 8;
 
949
 
 
950
        wrd = ReadAWord(dev, 0x1ad);    /* RAM size in pages (256 bytes). 0 = 64k */
 
951
        nic_data.RAM_Size = (wrd >> 8);
 
952
 
 
953
        wrd = ReadAWord(dev, 0x1ae);    /* hardware model (CT = 3) */
 
954
        nic_data.Model = (wrd & 0xff);
 
955
 
 
956
        wrd = ReadAWord(dev, 0x1af); /* media (indicates BNC/UTP) */
 
957
        nic_data.Media = (wrd & 0xff);
 
958
 
 
959
        wrd = ReadAWord(dev, 0x1a8); /* System Configuration Register */
 
960
        nic_data.SCR = (wrd >> 8);
 
961
 
 
962
        return 0; /* no errors */
 
963
}
 
964
 
 
965
/******************************************************************************
 
966
 *
 
967
 * Loadable module skeleton
 
968
 *
 
969
 */
 
970
#ifdef MODULE
 
971
static struct net_device *de620_dev;
 
972
 
 
973
int __init init_module(void)
 
974
{
 
975
        de620_dev = de620_probe(-1);
 
976
        if (IS_ERR(de620_dev))
 
977
                return PTR_ERR(de620_dev);
 
978
        return 0;
 
979
}
 
980
 
 
981
void cleanup_module(void)
 
982
{
 
983
        unregister_netdev(de620_dev);
 
984
        release_region(de620_dev->base_addr, 3);
 
985
        free_netdev(de620_dev);
 
986
}
 
987
#endif /* MODULE */
 
988
MODULE_LICENSE("GPL");