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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [armnommu/] [drivers/] [net/] [ether1.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * linux/arch/arm/drivers/net/ether1.c
3
 *
4
 * Acorn ether1 driver (82586 chip)
5
 *
6
 * (c) 1996 Russell King
7
 */
8
 
9
/*
10
 * We basically keep two queues in the cards memory - one for transmit
11
 * and one for receive.  Each has a head and a tail.  The head is where
12
 * we/the chip adds packets to be transmitted/received, and the tail
13
 * is where the transmitter has got to/where the receiver will stop.
14
 * Both of these queues are circular, and since the chip is running
15
 * all the time, we have to be careful when we modify the pointers etc
16
 * so that the buffer memory is valid all the time.
17
 */
18
 
19
/*
20
 * Change log:
21
 * 1.00 RMK                     Released
22
 * 1.01 RMK     19/03/96        Transfers the last odd byte onto/off of the card now.
23
 * 1.02 RMK     25/05/97        Added code to restart RU if it goes not ready
24
 * 1.03 RMK     14/09/97        Cleaned up the handling of a reset during the TX interrupt.
25
 *                              Should prevent lockup.
26
 * 1.04 RMK     17/09/97        Added more info when initialsation of chip goes wrong.
27
 *                              TDR now only reports failure when chip reports non-zero
28
 *                              TDR time-distance.
29
 */
30
 
31
#include <linux/module.h>
32
#include <linux/kernel.h>
33
#include <linux/sched.h>
34
#include <linux/types.h>
35
#include <linux/fcntl.h>
36
#include <linux/interrupt.h>
37
#include <linux/ptrace.h>
38
#include <linux/ioport.h>
39
#include <linux/in.h>
40
#include <linux/malloc.h>
41
#include <linux/string.h>
42
#include <asm/system.h>
43
#include <asm/bitops.h>
44
#include <asm/io.h>
45
#include <asm/dma.h>
46
#include <linux/errno.h>
47
 
48
#include <linux/netdevice.h>
49
#include <linux/etherdevice.h>
50
#include <linux/skbuff.h>
51
 
52
#include <asm/ecard.h>
53
 
54
#define __ETHER1_C
55
#include "ether1.h"
56
 
57
static unsigned int net_debug = NET_DEBUG;
58
 
59
#define FUNC_PROLOGUE \
60
        struct ether1_priv *priv = (struct ether1_priv *)dev->priv
61
 
62
#define BUFFER_SIZE     0x10000
63
#define TX_AREA_START   0x00100
64
#define TX_AREA_END     0x05000
65
#define RX_AREA_START   0x05000
66
#define RX_AREA_END     0x0fc00
67
 
68
#define tx_done(dev) 0
69
/* ------------------------------------------------------------------------- */
70
static char *version = "ether1 ethernet driver (c) 1995 Russell King v1.04\n";
71
 
72
#define BUS_16 16
73
#define BUS_8  8
74
 
75
static const card_ids ether1_cids[] = {
76
        { MANU_ACORN, PROD_ACORN_ETHER1 },
77
        { 0xffff, 0xffff }
78
};
79
 
80
/* ------------------------------------------------------------------------- */
81
 
82
#define DISABLEIRQS 1
83
#define NORMALIRQS  0
84
 
85
#define ether1_inw(dev, addr, type, offset, svflgs) ether1_inw_p(dev, addr + (int)(&((type *)0)->offset), svflgs)
86
#define ether1_outw(dev, val, addr, type, offset, svflgs) ether1_outw_p(dev, val, addr + (int)(&((type *)0)->offset), svflgs)
87
 
88
static inline unsigned short
89
ether1_inw_p(const struct device *dev, int addr, const int svflgs)
90
{
91
    unsigned long flags;
92
    unsigned short ret;
93
 
94
    if (svflgs) {
95
        save_flags_cli(flags);
96
    }
97
    outb(addr >> 12, REG_PAGE);
98
    ret = inw(ETHER1_RAM + ((addr & 4095) >> 1));
99
    if (svflgs)
100
        restore_flags(flags);
101
    return ret;
102
}
103
 
104
static inline void
105
ether1_outw_p(const struct device *dev, unsigned short val, int addr, const int svflgs)
106
{
107
    unsigned long flags;
108
 
109
    if (svflgs) {
110
        save_flags_cli(flags);
111
    }
112
    outb(addr >> 12, REG_PAGE);
113
    outw(val, ETHER1_RAM + ((addr & 4095) >> 1));
114
    if (svflgs)
115
        restore_flags(flags);
116
}
117
 
118
static inline void *
119
ether1_inswb(unsigned int addr, void *data, unsigned int len)
120
{
121
    int used;
122
 
123
    addr = IO_BASE + (addr << 2);
124
 
125
    __asm__ __volatile__(
126
        "subs   %3, %3, #2
127
        bmi     2f
128
1:      ldr     %0, [%1], #4
129
        strb    %0, [%2], #1
130
        mov     %0, %0, lsr #8
131
        strb    %0, [%2], #1
132
        subs    %3, %3, #2
133
        bmi     2f
134
        ldr     %0, [%1], #4
135
        strb    %0, [%2], #1
136
        mov     %0, %0, lsr #8
137
        strb    %0, [%2], #1
138
        subs    %3, %3, #2
139
        bmi     2f
140
        ldr     %0, [%1], #4
141
        strb    %0, [%2], #1
142
        mov     %0, %0, lsr #8
143
        strb    %0, [%2], #1
144
        subs    %3, %3, #2
145
        bmi     2f
146
        ldr     %0, [%1], #4
147
        strb    %0, [%2], #1
148
        mov     %0, %0, lsr #8
149
        strb    %0, [%2], #1
150
        subs    %3, %3, #2
151
        bpl     1b
152
2:      adds    %3, %3, #1
153
        ldreqb  %0, [%1]
154
        streqb  %0, [%2]"
155
    : "=&r" (used), "=&r" (addr), "=&r" (data), "=&r" (len)
156
    :                "1"  (addr), "2"   (data), "3"   (len));
157
 
158
    return data;
159
}
160
 
161
static inline void *
162
ether1_outswb(unsigned int addr, void *data, unsigned int len)
163
{
164
    int used;
165
 
166
    addr = IO_BASE + (addr << 2);
167
 
168
    __asm__ __volatile__(
169
        "subs   %3, %3, #2
170
        bmi     2f
171
1:      ldr     %0, [%2], #2
172
        mov     %0, %0, lsl #16
173
        orr     %0, %0, %0, lsr #16
174
        str     %0, [%1], #4
175
        subs    %3, %3, #2
176
        bmi     2f
177
        ldr     %0, [%2], #2
178
        mov     %0, %0, lsl #16
179
        orr     %0, %0, %0, lsr #16
180
        str     %0, [%1], #4
181
        subs    %3, %3, #2
182
        bmi     2f
183
        ldr     %0, [%2], #2
184
        mov     %0, %0, lsl #16
185
        orr     %0, %0, %0, lsr #16
186
        str     %0, [%1], #4
187
        subs    %3, %3, #2
188
        bmi     2f
189
        ldr     %0, [%2], #2
190
        mov     %0, %0, lsl #16
191
        orr     %0, %0, %0, lsr #16
192
        str     %0, [%1], #4
193
        subs    %3, %3, #2
194
        bpl     1b
195
2:      adds    %3, %3, #1
196
        ldreqb  %0, [%2]
197
        streqb  %0, [%1]"
198
    : "=&r" (used), "=&r" (addr), "=&r" (data), "=&r" (len)
199
    :                "1"  (addr), "2"   (data), "3"   (len));
200
 
201
    return data;
202
}
203
 
204
 
205
static void
206
ether1_writebuffer(struct device *dev, void *data, unsigned int start, unsigned int length)
207
{
208
    unsigned int page, thislen, offset;
209
 
210
    offset = start & 4095;
211
 
212
    for (page = start >> 12; length; page++) {
213
        outb(page, REG_PAGE);
214
        if (offset + length > 4096) {
215
            length -= 4096 - offset;
216
            thislen = 4096 - offset;
217
        } else {
218
            thislen = length;
219
            length = 0;
220
        }
221
 
222
        data = ether1_outswb(ETHER1_RAM + (offset >> 1), data, thislen);
223
        offset = 0;
224
    }
225
}
226
 
227
static void
228
ether1_readbuffer(struct device *dev, void *data, unsigned int start, unsigned int length)
229
{
230
    unsigned int page, thislen, offset;
231
 
232
    offset = start & 4095;
233
 
234
    for (page = start >> 12; length; page++) {
235
        outb(page, REG_PAGE);
236
        if (offset + length > 4096) {
237
            length -= 4096 - offset;
238
            thislen = 4096 - offset;
239
        } else {
240
            thislen = length;
241
            length = 0;
242
        }
243
 
244
        data = ether1_inswb(ETHER1_RAM + (offset >> 1), data, thislen);
245
        offset = 0;
246
    }
247
}
248
 
249
static int
250
ether1_ramtest(struct device *dev, unsigned char byte)
251
{
252
    unsigned char *buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
253
    int i, ret = BUFFER_SIZE;
254
    int max_errors = 15;
255
    int bad = -1;
256
    int bad_start = 0;
257
 
258
    if (!buffer)
259
        return 1;
260
 
261
    memset(buffer, byte, BUFFER_SIZE);
262
    ether1_writebuffer(dev, buffer, 0, BUFFER_SIZE);
263
    memset(buffer, byte ^ 0xff, BUFFER_SIZE);
264
    ether1_readbuffer(dev, buffer, 0, BUFFER_SIZE);
265
 
266
    for (i = 0; i < BUFFER_SIZE; i++) {
267
        if (buffer[i] != byte) {
268
            if (max_errors >= 0 && bad != buffer[i]) {
269
                if (bad != -1)
270
                    printk("\n");
271
                printk(KERN_CRIT "%s: RAM failed with (%02X instead of %02X) at 0x%04X",
272
                        dev->name, buffer[i], byte, i);
273
                ret = -ENODEV;
274
                max_errors --;
275
                bad = buffer[i];
276
                bad_start = i;
277
            }
278
        } else {
279
            if (bad != -1) {
280
                if (bad_start == i - 1)
281
                    printk("\n");
282
                else
283
                    printk(" - 0x%04X\n", i - 1);
284
                bad = -1;
285
            }
286
        }
287
    }
288
 
289
    if (bad != -1)
290
        printk(" - 0x%04X\n", BUFFER_SIZE);
291
    kfree(buffer);
292
 
293
    return ret;
294
}
295
 
296
static int
297
ether1_reset(struct device *dev)
298
{
299
    outb(CTRL_RST|CTRL_ACK, REG_CONTROL);
300
    return BUS_16;
301
}
302
 
303
static int
304
ether1_init_2(struct device *dev)
305
{
306
    int i;
307
    dev->mem_start = 0;
308
 
309
    i = ether1_ramtest(dev, 0x5a);
310
 
311
    if (i > 0)
312
        i = ether1_ramtest(dev, 0x1e);
313
 
314
    if (i <= 0)
315
        return -ENODEV;
316
 
317
    dev->mem_end = i;
318
    return 0;
319
}
320
 
321
/*
322
 * These are the structures that are loaded into the ether RAM card to
323
 * initialise the 82586
324
 */
325
 
326
/* at 0x0100 */
327
#define NOP_ADDR        (TX_AREA_START)
328
#define NOP_SIZE        (0x06)
329
static nop_t  init_nop  = {
330
        { 0, CMD_NOP },
331
        NOP_ADDR
332
};
333
 
334
/* at 0x003a */
335
#define TDR_ADDR        (0x003a)
336
#define TDR_SIZE        (0x08)
337
static tdr_t  init_tdr  = {
338
        { 0, CMD_TDR | CMD_INTR },
339
        NOP_ADDR, 0
340
};
341
 
342
/* at 0x002e */
343
#define MC_ADDR         (0x002e)
344
#define MC_SIZE         (0x0c)
345
static mc_t   init_mc   = {
346
        { 0, CMD_SETMULTICAST },
347
        TDR_ADDR, 0, { { 0, } }
348
};
349
 
350
/* at 0x0022 */
351
#define SA_ADDR         (0x0022)
352
#define SA_SIZE         (0x0c)
353
static sa_t   init_sa   = {
354
        { 0, CMD_SETADDRESS },
355
        MC_ADDR, { 0, }
356
};
357
 
358
/* at 0x0010 */
359
#define CFG_ADDR        (0x0010)
360
#define CFG_SIZE        (0x12)
361
static cfg_t  init_cfg  = {
362
        { 0, CMD_CONFIG },
363
        SA_ADDR,
364
        8,
365
        8,
366
        CFG8_SRDY,
367
        CFG9_PREAMB8 | CFG9_ADDRLENBUF | CFG9_ADDRLEN(6),
368
        0,
369
        0x60,
370
        0,
371
        CFG13_RETRY(15) | CFG13_SLOTH(2),
372
        0,
373
};
374
 
375
/* at 0x0000 */
376
#define SCB_ADDR        (0x0000)
377
#define SCB_SIZE        (0x10)
378
static scb_t  init_scb  = {
379
        0,
380
        SCB_CMDACKRNR | SCB_CMDACKCNA | SCB_CMDACKFR | SCB_CMDACKCX,
381
        CFG_ADDR,
382
        RX_AREA_START,
383
        0,
384
        0,
385
        0,
386
 
387
};
388
 
389
/* at 0xffee */
390
#define ISCP_ADDR       (0xffee)
391
#define ISCP_SIZE       (0x08)
392
static iscp_t init_iscp = {
393
        1,
394
        SCB_ADDR,
395
        0x0000,
396
        0x0000
397
};
398
 
399
/* at 0xfff6 */
400
#define SCP_ADDR        (0xfff6)
401
#define SCP_SIZE        (0x0a)
402
static scp_t  init_scp  = {
403
        SCP_SY_16BBUS,
404
        { 0, 0 },
405
        ISCP_ADDR,
406
 
407
};
408
 
409
#define RFD_SIZE        (0x16)
410
#define RBD_SIZE        (0x0a)
411
#define TX_SIZE         (0x08)
412
#define TBD_SIZE        (0x08)
413
 
414
static void
415
ether1_setup_rx_buffer(struct device *dev)
416
{
417
        struct ether1_priv *priv = (struct ether1_priv *)dev->priv;
418
        unsigned int addr, next, next2;
419
        rfd_t rfd;
420
        rbd_t rbd;
421
 
422
        memset(&rfd, 0, sizeof(rfd));
423
        memset(&rbd, 0, sizeof(rbd));
424
 
425
        rbd.rbd_len = ETH_FRAME_LEN + 8;
426
 
427
        /*
428
         * setup circularly linked list of { rfd, rbd, buffer }, with
429
         * all rfds circularly linked, rbds circularly linked.
430
         * First rfd is linked to scp, first rbd is linked to first
431
         * rfd.  Last rbd has a suspend command.
432
         */
433
        addr = RX_AREA_START;
434
        do {
435
                next  = addr + RFD_SIZE + RBD_SIZE + ETH_FRAME_LEN + 10;
436
                next2 = next + RFD_SIZE + RBD_SIZE + ETH_FRAME_LEN + 10;
437
 
438
                if (next2 >= RX_AREA_END) {
439
                        next = RX_AREA_START;
440
                        rfd.hdr.command = RFD_CMDEL | RFD_CMDSUSPEND;
441
                        priv->rx_tail = addr;
442
                } else
443
                        rfd.hdr.command = 0;
444
 
445
                if (addr == RX_AREA_START)
446
                        rfd.rfd_rbdoffset = RX_AREA_START + RFD_SIZE;
447
                else
448
                        rfd.rfd_rbdoffset = 0;
449
 
450
                rfd.rfd_link = next;
451
                rbd.rbd_link = next + RFD_SIZE;
452
                rbd.rbd_bufl = addr + RFD_SIZE + RBD_SIZE;
453
 
454
                ether1_writebuffer(dev, &rfd, addr, RFD_SIZE);
455
                ether1_writebuffer(dev, &rbd, addr + RFD_SIZE, RBD_SIZE);
456
                addr = next;
457
        } while (next2 < RX_AREA_END);
458
}
459
 
460
static int
461
ether1_init_for_open(struct device *dev)
462
{
463
    FUNC_PROLOGUE;
464
    int i, status;
465
    int failures = 0;
466
 
467
    outb(CTRL_RST|CTRL_ACK, REG_CONTROL);
468
 
469
    for (i = 0; i < 6; i++)
470
        init_sa.sa_addr[i] = dev->dev_addr[i];
471
 
472
    /* load data structures into ether1 RAM */
473
    ether1_writebuffer(dev, &init_scp,  SCP_ADDR,  SCP_SIZE);
474
    ether1_writebuffer(dev, &init_iscp, ISCP_ADDR, ISCP_SIZE);
475
    ether1_writebuffer(dev, &init_scb,  SCB_ADDR,  SCB_SIZE);
476
    ether1_writebuffer(dev, &init_cfg,  CFG_ADDR,  CFG_SIZE);
477
    ether1_writebuffer(dev, &init_sa,   SA_ADDR,   SA_SIZE);
478
    ether1_writebuffer(dev, &init_mc,   MC_ADDR,   MC_SIZE);
479
    ether1_writebuffer(dev, &init_tdr,  TDR_ADDR,  TDR_SIZE);
480
    ether1_writebuffer(dev, &init_nop,  NOP_ADDR,  NOP_SIZE);
481
 
482
    if (ether1_inw(dev, CFG_ADDR, cfg_t, hdr.command, NORMALIRQS) != CMD_CONFIG) {
483
        printk(KERN_ERR "%s: detected either RAM fault or compiler bug\n",
484
                dev->name);
485
        return 1;
486
    }
487
 
488
        ether1_setup_rx_buffer(dev);
489
 
490
    priv->tx_link = NOP_ADDR;
491
    priv->tx_head = NOP_ADDR + NOP_SIZE;
492
    priv->tx_tail = TDR_ADDR;
493
    priv->rx_head = RX_AREA_START;
494
 
495
    /* release reset & give 586 a prod */
496
    priv->resetting = 1;
497
    priv->initialising = 1;
498
    outb(CTRL_RST, REG_CONTROL);
499
    outb(0, REG_CONTROL);
500
    outb(CTRL_CA, REG_CONTROL);
501
 
502
    /* 586 should now unset iscp.busy */
503
    i = jiffies + HZ/2;
504
    while (ether1_inw(dev, ISCP_ADDR, iscp_t, iscp_busy, DISABLEIRQS) == 1) {
505
        if (jiffies > i) {
506
            printk(KERN_WARNING "%s: can't initialise 82586: iscp is busy\n", dev->name);
507
            return 1;
508
        }
509
    }
510
 
511
    /* check status of commands that we issued */
512
    i += HZ/10;
513
    while (((status = ether1_inw(dev, CFG_ADDR, cfg_t, hdr.status, DISABLEIRQS))
514
                & STAT_COMPLETE) == 0) {
515
        if (jiffies > i)
516
            break;
517
    }
518
 
519
    if ((status & (STAT_COMPLETE | STAT_OK)) != (STAT_COMPLETE | STAT_OK)) {
520
        printk(KERN_WARNING "%s: can't initialise 82586: config status %04X\n", dev->name, status);
521
        printk(KERN_DEBUG "%s: SCB=[STS=%04X CMD=%04X CBL=%04X RFA=%04X]\n", dev->name,
522
                ether1_inw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS),
523
                ether1_inw(dev, SCB_ADDR, scb_t, scb_command, NORMALIRQS),
524
                ether1_inw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS),
525
                ether1_inw(dev, SCB_ADDR, scb_t, scb_rfa_offset, NORMALIRQS));
526
        failures += 1;
527
    }
528
 
529
    i += HZ/10;
530
    while (((status = ether1_inw(dev, SA_ADDR, sa_t, hdr.status, DISABLEIRQS))
531
                & STAT_COMPLETE) == 0) {
532
        if (jiffies > i)
533
            break;
534
    }
535
 
536
    if ((status & (STAT_COMPLETE | STAT_OK)) != (STAT_COMPLETE | STAT_OK)) {
537
        printk(KERN_WARNING "%s: can't initialise 82586: set address status %04X\n", dev->name, status);
538
        printk(KERN_DEBUG "%s: SCB=[STS=%04X CMD=%04X CBL=%04X RFA=%04X]\n", dev->name,
539
                ether1_inw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS),
540
                ether1_inw(dev, SCB_ADDR, scb_t, scb_command, NORMALIRQS),
541
                ether1_inw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS),
542
                ether1_inw(dev, SCB_ADDR, scb_t, scb_rfa_offset, NORMALIRQS));
543
        failures += 1;
544
    }
545
 
546
    i += HZ/10;
547
    while (((status = ether1_inw(dev, MC_ADDR, mc_t, hdr.status, DISABLEIRQS))
548
                & STAT_COMPLETE) == 0) {
549
        if (jiffies > i)
550
            break;
551
    }
552
 
553
    if ((status & (STAT_COMPLETE | STAT_OK)) != (STAT_COMPLETE | STAT_OK)) {
554
        printk(KERN_WARNING "%s: can't initialise 82586: set multicast status %04X\n", dev->name, status);
555
        printk(KERN_DEBUG "%s: SCB=[STS=%04X CMD=%04X CBL=%04X RFA=%04X]\n", dev->name,
556
                ether1_inw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS),
557
                ether1_inw(dev, SCB_ADDR, scb_t, scb_command, NORMALIRQS),
558
                ether1_inw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS),
559
                ether1_inw(dev, SCB_ADDR, scb_t, scb_rfa_offset, NORMALIRQS));
560
        failures += 1;
561
    }
562
 
563
    i += HZ;
564
    while (((status = ether1_inw(dev, TDR_ADDR, tdr_t, hdr.status, DISABLEIRQS))
565
                & STAT_COMPLETE) == 0) {
566
        if (jiffies > i)
567
            break;
568
    }
569
 
570
    if ((status & (STAT_COMPLETE | STAT_OK)) != (STAT_COMPLETE | STAT_OK)) {
571
        printk(KERN_WARNING "%s: can't tdr (ignored)\n", dev->name);
572
        printk(KERN_DEBUG "%s: SCB=[STS=%04X CMD=%04X CBL=%04X RFA=%04X]\n", dev->name,
573
                ether1_inw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS),
574
                ether1_inw(dev, SCB_ADDR, scb_t, scb_command, NORMALIRQS),
575
                ether1_inw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS),
576
                ether1_inw(dev, SCB_ADDR, scb_t, scb_rfa_offset, NORMALIRQS));
577
    } else {
578
        status = ether1_inw(dev, TDR_ADDR, tdr_t, tdr_result, DISABLEIRQS);
579
        if (status & TDR_XCVRPROB)
580
            printk(KERN_WARNING "%s: i/f failed tdr: transceiver problem\n", dev->name);
581
        else if ((status & (TDR_SHORT|TDR_OPEN)) && (status & TDR_TIME)) {
582
#ifdef FANCY
583
            printk(KERN_WARNING "%s: i/f failed tdr: cable %s %d.%d us away\n", dev->name,
584
                    status & TDR_SHORT ? "short" : "open", (status & TDR_TIME) / 10,
585
                    (status & TDR_TIME) % 10);
586
#else
587
            printk(KERN_WARNING "%s: i/f failed tdr: cable %s %d clks away\n", dev->name,
588
                    status & TDR_SHORT ? "short" : "open", (status & TDR_TIME));
589
#endif
590
        }
591
    }
592
 
593
    if (failures)
594
        ether1_reset(dev);
595
    return failures ? 1 : 0;
596
}
597
 
598
static int
599
ether1_probe1(struct device *dev)
600
{
601
    static unsigned int version_printed = 0;
602
    struct ether1_priv *priv;
603
    int i;
604
 
605
    if (!dev->priv)
606
        dev->priv = kmalloc(sizeof (struct ether1_priv), GFP_KERNEL);
607
 
608
    if (!dev->priv)
609
        return 1;
610
 
611
    priv = (struct ether1_priv *)dev->priv;
612
    memset(priv, 0, sizeof (struct ether1_priv));
613
 
614
    if ((priv->bus_type = ether1_reset(dev)) == 0) {
615
        kfree(dev->priv);
616
        return 1;
617
    }
618
 
619
    if (net_debug && version_printed++ == 0)
620
        printk(KERN_INFO "%s", version);
621
 
622
    printk(KERN_INFO "%s: ether1 found at %08lX, IRQ%d, ether address", dev->name,
623
                dev->base_addr, dev->irq);
624
 
625
    request_region(dev->base_addr, 16, "ether1");
626
    request_region(dev->base_addr + 0x800, 4096, "ether1(ram)");
627
 
628
    for (i = 0; i < 6; i++)
629
        printk(i==0?" %02x":i==5?":%02x\n":":%02x", dev->dev_addr[i]);
630
 
631
    if (ether1_init_2(dev)) {
632
        kfree(dev->priv);
633
        return 1;
634
    }
635
 
636
    dev->open               = ether1_open;
637
    dev->stop               = ether1_close;
638
    dev->hard_start_xmit    = ether1_sendpacket;
639
    dev->get_stats          = ether1_getstats;
640
    dev->set_multicast_list = ether1_setmulticastlist;
641
 
642
    /* Fill in the fields of the device structure with ethernet values */
643
    ether_setup(dev);
644
 
645
    return 0;
646
}
647
 
648
/* ------------------------------------------------------------------------- */
649
 
650
static void
651
ether1_addr(struct device *dev)
652
{
653
    int i;
654
 
655
    for (i = 0; i < 6; i++)
656
        dev->dev_addr[i] = inb(IDPROM_ADDRESS + i);
657
}
658
 
659
int
660
ether1_probe(struct device *dev)
661
{
662
#ifndef MODULE
663
    struct expansion_card *ec;
664
 
665
    if (!dev)
666
        return ENODEV;
667
 
668
    ecard_startfind();
669
    if ((ec = ecard_find(0, ether1_cids)) == NULL)
670
        return ENODEV;
671
 
672
    dev->base_addr = ecard_address(ec, ECARD_IOC, ECARD_FAST);
673
    dev->irq       = ec->irq;
674
 
675
    ecard_claim(ec);
676
 
677
#endif
678
    ether1_addr(dev);
679
 
680
    if (ether1_probe1(dev) == 0)
681
        return 0;
682
    return ENODEV;
683
}
684
 
685
/* ------------------------------------------------------------------------- */
686
 
687
static int
688
ether1_txalloc(struct device *dev, int size)
689
{
690
    FUNC_PROLOGUE;
691
    int start, tail;
692
 
693
    size = (size + 1) & ~1;
694
    tail = priv->tx_tail;
695
 
696
    if (priv->tx_head + size > TX_AREA_END) {
697
        if (tail > priv->tx_head)
698
            return -1;
699
        start = TX_AREA_START;
700
        if (start + size > tail)
701
            return -1;
702
        priv->tx_head = start + size;
703
    } else {
704
        if (priv->tx_head < tail && (priv->tx_head + size) > tail)
705
            return -1;
706
        start = priv->tx_head;
707
        priv->tx_head += size;
708
    }
709
 
710
    return start;
711
}
712
 
713
static void
714
ether1_restart(struct device *dev, char *reason)
715
{
716
    FUNC_PROLOGUE;
717
    priv->stats.tx_errors ++;
718
 
719
    if (reason)
720
        printk(KERN_WARNING "%s: %s - resetting device\n", dev->name, reason);
721
    else
722
        printk(" - resetting device\n");
723
 
724
    ether1_reset(dev);
725
 
726
    dev->start = 0;
727
    dev->tbusy = 0;
728
 
729
    if (ether1_init_for_open(dev))
730
        printk(KERN_ERR "%s: unable to restart interface\n", dev->name);
731
 
732
    dev->start = 1;
733
}
734
 
735
static int
736
ether1_sendpacket(struct sk_buff *skb, struct device *dev)
737
{
738
    FUNC_PROLOGUE;
739
 
740
    if (priv->restart)
741
        ether1_restart(dev, NULL);
742
 
743
    if (dev->tbusy) {
744
        /*
745
         * If we get here, some higher level has decided that we are broken.
746
         * There should really be a "kick me" function call instead.
747
         */
748
        int tickssofar = jiffies - dev->trans_start;
749
 
750
        if (tickssofar < 5)
751
            return 1;
752
 
753
        /* Try to restart the adapter. */
754
        ether1_restart(dev, "transmit timeout, network cable problem?");
755
        dev->trans_start = jiffies;
756
    }
757
 
758
    /*
759
     * If some higher layer thinks we've missed a tx-done interrupt
760
     * we are passed NULL.  Caution: dev_tint() handles the cli()/sti()
761
     * itself.
762
     */
763
    if (skb == NULL) {
764
        dev_tint(dev);
765
        return 0;
766
    }
767
 
768
    /*
769
     * Block a timer-based transmit from overlapping.  This could better be
770
     * done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
771
     */
772
    if (set_bit(0, (void *)&dev->tbusy) != 0)
773
        printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
774
    else {
775
        int len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
776
        int tmp, tst, nopaddr, txaddr, tbdaddr, dataddr;
777
        unsigned long flags;
778
        tx_t tx;
779
        tbd_t tbd;
780
        nop_t nop;
781
 
782
        /*
783
         * insert packet followed by a nop
784
         */
785
        txaddr = ether1_txalloc(dev, TX_SIZE);
786
        tbdaddr = ether1_txalloc(dev, TBD_SIZE);
787
        dataddr = ether1_txalloc(dev, len);
788
        nopaddr = ether1_txalloc(dev, NOP_SIZE);
789
 
790
        tx.hdr.status = 0;
791
        tx.hdr.command = CMD_TX | CMD_INTR;
792
        tx.tx_link = nopaddr;
793
        tx.tx_tbdoffset = tbdaddr;
794
        tbd.tbd_opts = TBD_EOL | len;
795
        tbd.tbd_link = I82586_NULL;
796
        tbd.tbd_bufl = dataddr;
797
        tbd.tbd_bufh = 0;
798
        nop.hdr.status = 0;
799
        nop.hdr.command = CMD_NOP;
800
        nop.nop_link = nopaddr;
801
 
802
        save_flags_cli(flags);
803
        ether1_writebuffer(dev, &tx, txaddr, TX_SIZE);
804
        ether1_writebuffer(dev, &tbd, tbdaddr, TBD_SIZE);
805
        ether1_writebuffer(dev, skb->data, dataddr, len);
806
        ether1_writebuffer(dev, &nop, nopaddr, NOP_SIZE);
807
        tmp = priv->tx_link;
808
        priv->tx_link = nopaddr;
809
 
810
        /* now reset the previous nop pointer */
811
        ether1_outw(dev, txaddr, tmp, nop_t, nop_link, NORMALIRQS);
812
 
813
        restore_flags(flags);
814
 
815
        /* handle transmit */
816
        dev->trans_start = jiffies;
817
 
818
        /* check to see if we have room for a full sized ether frame */
819
        tmp = priv->tx_head;
820
        tst = ether1_txalloc(dev, TX_SIZE + TBD_SIZE + NOP_SIZE + ETH_FRAME_LEN);
821
        priv->tx_head = tmp;
822
        if (tst != -1)
823
            dev->tbusy = 0;
824
    }
825
    dev_kfree_skb(skb, FREE_WRITE);
826
 
827
    return 0;
828
}
829
 
830
static void
831
ether1_xmit_done(struct device *dev)
832
{
833
    FUNC_PROLOGUE;
834
    nop_t nop;
835
    int caddr, tst;
836
 
837
    caddr = priv->tx_tail;
838
 
839
again:
840
    ether1_readbuffer(dev, &nop, caddr, NOP_SIZE);
841
 
842
    switch (nop.hdr.command & CMD_MASK) {
843
    case CMD_TDR:
844
        /* special case */
845
        if (ether1_inw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS)
846
                                != (unsigned short)I82586_NULL) {
847
            ether1_outw(dev, SCB_CMDCUCSTART | SCB_CMDRXSTART, SCB_ADDR, scb_t,
848
                scb_command, NORMALIRQS);
849
            outb(CTRL_CA, REG_CONTROL);
850
        }
851
        priv->tx_tail = NOP_ADDR;
852
        return;
853
 
854
    case CMD_NOP:
855
        if (nop.nop_link == caddr) {
856
            if (priv->initialising == 0)
857
                printk(KERN_WARNING "%s: strange command complete with no tx command!\n", dev->name);
858
            else
859
                priv->initialising = 0;
860
            return;
861
        }
862
        if (caddr == nop.nop_link)
863
                return;
864
        caddr = nop.nop_link;
865
        goto again;
866
 
867
    case CMD_TX:
868
        if (nop.hdr.status & STAT_COMPLETE)
869
            break;
870
        printk(KERN_ERR "%s: strange command complete without completed command\n", dev->name);
871
        priv->restart = 1;
872
        return;
873
 
874
    default:
875
        printk(KERN_WARNING "%s: strange command %d complete! (offset %04X)", dev->name,
876
                nop.hdr.command & CMD_MASK, caddr);
877
        priv->restart = 1;
878
        return;
879
    }
880
 
881
    while (nop.hdr.status & STAT_COMPLETE) {
882
        if (nop.hdr.status & STAT_OK) {
883
            priv->stats.tx_packets ++;
884
            priv->stats.collisions += (nop.hdr.status & STAT_COLLISIONS);
885
        } else {
886
            priv->stats.tx_errors ++;
887
 
888
            if (nop.hdr.status & STAT_COLLAFTERTX)
889
                priv->stats.collisions ++;
890
            if (nop.hdr.status & STAT_NOCARRIER)
891
                priv->stats.tx_carrier_errors ++;
892
            if (nop.hdr.status & STAT_TXLOSTCTS)
893
                printk(KERN_WARNING "%s: cts lost\n", dev->name);
894
            if (nop.hdr.status & STAT_TXSLOWDMA)
895
                priv->stats.tx_fifo_errors ++;
896
            if (nop.hdr.status & STAT_COLLEXCESSIVE)
897
                priv->stats.collisions += 16;
898
        }
899
 
900
        if (nop.nop_link == caddr) {
901
            printk(KERN_ERR "%s: tx buffer chaining error: tx command points to itself\n", dev->name);
902
            break;
903
        }
904
 
905
        caddr = nop.nop_link;
906
        ether1_readbuffer(dev, &nop, caddr, NOP_SIZE);
907
        if ((nop.hdr.command & CMD_MASK) != CMD_NOP) {
908
            printk(KERN_ERR "%s: tx buffer chaining error: no nop after tx command\n", dev->name);
909
            break;
910
        }
911
 
912
        if (caddr == nop.nop_link)
913
            break;
914
 
915
        caddr = nop.nop_link;
916
        ether1_readbuffer(dev, &nop, caddr, NOP_SIZE);
917
        if ((nop.hdr.command & CMD_MASK) != CMD_TX) {
918
            printk(KERN_ERR "%s: tx buffer chaining error: no tx command after nop\n", dev->name);
919
            break;
920
        }
921
    }
922
    priv->tx_tail = caddr;
923
 
924
    caddr = priv->tx_head;
925
    tst = ether1_txalloc(dev, TX_SIZE + TBD_SIZE + NOP_SIZE + ETH_FRAME_LEN);
926
    priv->tx_head = caddr;
927
    if (tst != -1)
928
        dev->tbusy = 0;
929
 
930
    mark_bh(NET_BH);
931
}
932
 
933
static void
934
ether1_recv_done(struct device *dev)
935
{
936
    FUNC_PROLOGUE;
937
    int status;
938
    int nexttail, rbdaddr;
939
    rbd_t rbd;
940
 
941
    do {
942
        status = ether1_inw(dev, priv->rx_head, rfd_t, hdr.status, NORMALIRQS);
943
        if ((status & RFD_COMPLETE) == 0)
944
            break;
945
 
946
        rbdaddr = ether1_inw(dev, priv->rx_head, rfd_t, rfd_rbdoffset, NORMALIRQS);
947
        ether1_readbuffer(dev, &rbd, rbdaddr, RBD_SIZE);
948
 
949
        if ((rbd.rbd_status & (RBD_EOF | RBD_ACNTVALID)) == (RBD_EOF | RBD_ACNTVALID)) {
950
            int length = rbd.rbd_status & RBD_ACNT;
951
            struct sk_buff *skb;
952
 
953
            length = (length + 1) & ~1;
954
            skb = dev_alloc_skb(length + 2);
955
 
956
            if (skb) {
957
                skb->dev = dev;
958
                skb_reserve(skb, 2);
959
 
960
                ether1_readbuffer(dev, skb_put(skb, length), rbd.rbd_bufl, length);
961
 
962
                skb->protocol = eth_type_trans(skb, dev);
963
                netif_rx(skb);
964
                priv->stats.rx_packets ++;
965
            } else
966
                priv->stats.rx_dropped ++;
967
        } else {
968
            printk(KERN_WARNING "%s: %s\n", dev->name,
969
                        (rbd.rbd_status & RBD_EOF) ? "oversized packet" : "acnt not valid");
970
            priv->stats.rx_dropped ++;
971
        }
972
 
973
        nexttail = ether1_inw(dev, priv->rx_tail, rfd_t, rfd_link, NORMALIRQS);
974
        /* nexttail should be rx_head */
975
        if (nexttail != priv->rx_head)
976
            printk(KERN_ERR "%s: receiver buffer chaining error (%04X != %04X)\n",
977
                        dev->name, nexttail, priv->rx_head);
978
        ether1_outw(dev, RFD_CMDEL | RFD_CMDSUSPEND, nexttail, rfd_t, hdr.command, NORMALIRQS);
979
        ether1_outw(dev, 0, priv->rx_tail, rfd_t, hdr.command, NORMALIRQS);
980
        ether1_outw(dev, 0, priv->rx_tail, rfd_t, hdr.status, NORMALIRQS);
981
        ether1_outw(dev, 0, priv->rx_tail, rfd_t, rfd_rbdoffset, NORMALIRQS);
982
 
983
        priv->rx_tail = nexttail;
984
        priv->rx_head = ether1_inw(dev, priv->rx_head, rfd_t, rfd_link, NORMALIRQS);
985
    } while (1);
986
}
987
 
988
static void
989
ether1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
990
{
991
    struct device *dev = (struct device *)dev_id;
992
    FUNC_PROLOGUE;
993
    int status;
994
 
995
    dev->interrupt = 1;
996
 
997
    status = ether1_inw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS);
998
 
999
    if (status) {
1000
        ether1_outw(dev, status & (SCB_STRNR | SCB_STCNA | SCB_STFR | SCB_STCX),
1001
                        SCB_ADDR, scb_t, scb_command, NORMALIRQS);
1002
        outb(CTRL_CA | CTRL_ACK, REG_CONTROL);
1003
        if (status & SCB_STCX) {
1004
            ether1_xmit_done(dev);
1005
        }
1006
        if (status & SCB_STCNA) {
1007
            if (priv->resetting == 0)
1008
                printk(KERN_WARNING "%s: CU went not ready ???\n", dev->name);
1009
            else
1010
                priv->resetting += 1;
1011
            if (ether1_inw(dev, SCB_ADDR, scb_t, scb_cbl_offset, NORMALIRQS)
1012
                                != (unsigned short)I82586_NULL) {
1013
                ether1_outw(dev, SCB_CMDCUCSTART, SCB_ADDR, scb_t, scb_command, NORMALIRQS);
1014
                outb(CTRL_CA, REG_CONTROL);
1015
            }
1016
            if (priv->resetting == 2)
1017
                priv->resetting = 0;
1018
        }
1019
        if (status & SCB_STFR) {
1020
            ether1_recv_done(dev);
1021
        }
1022
        if (status & SCB_STRNR) {
1023
            if (ether1_inw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS) & SCB_STRXSUSP) {
1024
                printk(KERN_WARNING "%s: RU went not ready: RU suspended\n", dev->name);
1025
                ether1_outw(dev, SCB_CMDRXRESUME, SCB_ADDR, scb_t, scb_command, NORMALIRQS);
1026
                outb(CTRL_CA, REG_CONTROL);
1027
                priv->stats.rx_dropped ++;      /* we suspended due to lack of buffer space */
1028
            } else
1029
                printk(KERN_WARNING "%s: RU went not ready: %04X\n", dev->name,
1030
                    ether1_inw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS));
1031
            printk(KERN_WARNING "RU ptr = %04X\n", ether1_inw(dev, SCB_ADDR, scb_t, scb_rfa_offset,
1032
                                        NORMALIRQS));
1033
        }
1034
    } else
1035
        outb(CTRL_ACK, REG_CONTROL);
1036
 
1037
    dev->interrupt = 0;
1038
}
1039
 
1040
static int
1041
ether1_open(struct device *dev)
1042
{
1043
    MOD_INC_USE_COUNT;
1044
 
1045
    if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev)) {
1046
        MOD_DEC_USE_COUNT;
1047
        return -EAGAIN;
1048
    }
1049
 
1050
    dev->tbusy = 0;
1051
    dev->interrupt = 0;
1052
    dev->start = 1;
1053
 
1054
    if (ether1_init_for_open(dev)) {
1055
        free_irq(dev->irq, dev);
1056
        MOD_DEC_USE_COUNT;
1057
        return -EAGAIN;
1058
    }
1059
 
1060
    return 0;
1061
}
1062
 
1063
static int
1064
ether1_close(struct device *dev)
1065
{
1066
    dev->tbusy = 1;
1067
    dev->start = 0;
1068
 
1069
    ether1_reset(dev);
1070
 
1071
    free_irq(dev->irq, dev);
1072
 
1073
    MOD_DEC_USE_COUNT;
1074
    return 0;
1075
}
1076
 
1077
static struct enet_statistics *
1078
ether1_getstats(struct device *dev)
1079
{
1080
    FUNC_PROLOGUE;
1081
    return &priv->stats;
1082
}
1083
 
1084
/*
1085
 * Set or clear the multicast filter for this adaptor.
1086
 * num_addrs == -1      Promiscuous mode, receive all packets.
1087
 * num_addrs == 0       Normal mode, clear multicast list.
1088
 * num_addrs > 0        Multicast mode, receive normal and MC packets, and do
1089
 *                      best-effort filtering.
1090
 */
1091
static void
1092
ether1_setmulticastlist(struct device *dev)
1093
{
1094
}
1095
 
1096
/* ------------------------------------------------------------------------- */
1097
 
1098
#ifdef MODULE
1099
 
1100
static char ethernames[MAX_ECARDS][9];
1101
static struct device *my_ethers[MAX_ECARDS];
1102
static struct expansion_card *ec[MAX_ECARDS];
1103
 
1104
int
1105
init_module(void)
1106
{
1107
    int i;
1108
 
1109
    for (i = 0; i < MAX_ECARDS; i++) {
1110
        my_ethers[i] = NULL;
1111
        ec[i] = NULL;
1112
        strcpy(ethernames[i], "        ");
1113
    }
1114
 
1115
    i = 0;
1116
 
1117
    ecard_startfind();
1118
 
1119
    do {
1120
        if ((ec[i] = ecard_find(0, ether1_cids)) == NULL)
1121
            break;
1122
 
1123
        my_ethers[i] = (struct device *)kmalloc(sizeof (struct device), GFP_KERNEL);
1124
        memset(my_ethers[i], 0, sizeof (struct device));
1125
 
1126
        my_ethers[i]->irq = ec[i]->irq;
1127
        my_ethers[i]->base_addr = ecard_address(ec[i], ECARD_IOC, ECARD_FAST);
1128
        my_ethers[i]->init = ether1_probe;
1129
        my_ethers[i]->name = ethernames[i];
1130
 
1131
        ecard_claim(ec[i]);
1132
 
1133
        if (register_netdev(my_ethers[i]) != 0) {
1134
            for (i = 0; i < 4; i++) {
1135
                if (my_ethers[i]) {
1136
                    kfree(my_ethers[i]);
1137
                    my_ethers[i] = NULL;
1138
                }
1139
                if (ec[i]) {
1140
                    ecard_release(ec[i]);
1141
                    ec[i] = NULL;
1142
                }
1143
            }
1144
            return -EIO;
1145
        }
1146
        i++;
1147
    } while (i < MAX_ECARDS);
1148
 
1149
    return i != 0 ? 0 : -ENODEV;
1150
}
1151
 
1152
void
1153
cleanup_module(void)
1154
{
1155
    int i;
1156
 
1157
    for (i = 0; i < MAX_ECARDS; i++) {
1158
        if (my_ethers[i]) {
1159
            unregister_netdev(my_ethers[i]);
1160
            release_region(my_ethers[i]->base_addr, 16);
1161
            release_region(my_ethers[i]->base_addr + 0x800, 4096);
1162
            my_ethers[i] = NULL;
1163
        }
1164
        if (ec[i]) {
1165
            ecard_release(ec[i]);
1166
            ec[i] = NULL;
1167
        }
1168
    }
1169
}
1170
#endif /* MODULE */

powered by: WebSVN 2.1.0

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