~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/ipxe/src/drivers/net/ns8390.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
ETHERBOOT -  BOOTP/TFTP Bootstrap Program
 
3
 
 
4
Author: Martin Renters
 
5
  Date: May/94
 
6
 
 
7
 This code is based heavily on David Greenman's if_ed.c driver
 
8
 
 
9
 Copyright (C) 1993-1994, David Greenman, Martin Renters.
 
10
  This software may be used, modified, copied, distributed, and sold, in
 
11
  both source and binary form provided that the above copyright and these
 
12
  terms are retained. Under no circumstances are the authors responsible for
 
13
  the proper functioning of this software, nor do the authors assume any
 
14
  responsibility for damages incurred with its use.
 
15
 
 
16
Multicast support added by Timothy Legge (timlegge@users.sourceforge.net) 09/28/2003
 
17
Relocation support added by Ken Yap (ken_yap@users.sourceforge.net) 28/12/02
 
18
3c503 support added by Bill Paul (wpaul@ctr.columbia.edu) on 11/15/94
 
19
SMC8416 support added by Bill Paul (wpaul@ctr.columbia.edu) on 12/25/94
 
20
3c503 PIO support added by Jim Hague (jim.hague@acm.org) on 2/17/98
 
21
RX overrun by Klaus Espenlaub (espenlaub@informatik.uni-ulm.de) on 3/10/99
 
22
  parts taken from the Linux 8390 driver (by Donald Becker and Paul Gortmaker)
 
23
SMC8416 PIO support added by Andrew Bettison (andrewb@zip.com.au) on 4/3/02
 
24
  based on the Linux 8390 driver (by Donald Becker and Paul Gortmaker)
 
25
 
 
26
**************************************************************************/
 
27
 
 
28
FILE_LICENCE ( BSD2 );
 
29
 
 
30
/* #warning "ns8390.c: FIXME: split ISA and PCI, clean up" */
 
31
 
 
32
#if 1
 
33
 
 
34
#if !defined(INCLUDE_NS8390) && !defined(INCLUDE_WD) && \
 
35
    !defined(INCLUDE_NE) && !defined(INCLUDE_3C503)
 
36
  /* The driver named ns8390 is the PCI driver, often called
 
37
     "PCI ne2000 clones". */
 
38
# define INCLUDE_NS8390 1
 
39
#endif
 
40
 
 
41
#include "etherboot.h"
 
42
#include "nic.h"
 
43
#include "ns8390.h"
 
44
#include <ipxe/ethernet.h>
 
45
#ifdef  INCLUDE_NS8390
 
46
#include <ipxe/pci.h>
 
47
#else
 
48
#include <ipxe/isa.h>
 
49
#endif
 
50
 
 
51
static unsigned char    eth_vendor, eth_flags;
 
52
#ifdef  INCLUDE_WD
 
53
static unsigned char    eth_laar;
 
54
#endif
 
55
static unsigned short   eth_nic_base, eth_asic_base;
 
56
static unsigned char    eth_memsize, eth_rx_start, eth_tx_start;
 
57
static Address          eth_bmem, eth_rmem;
 
58
static unsigned char    eth_drain_receiver;
 
59
 
 
60
#ifdef  INCLUDE_WD
 
61
static struct wd_board {
 
62
        const char *name;
 
63
        char id;
 
64
        char flags;
 
65
        char memsize;
 
66
} wd_boards[] = {
 
67
        {"WD8003S",     TYPE_WD8003S,   0,                      MEM_8192},
 
68
        {"WD8003E",     TYPE_WD8003E,   0,                      MEM_8192},
 
69
        {"WD8013EBT",   TYPE_WD8013EBT, FLAG_16BIT,             MEM_16384},
 
70
        {"WD8003W",     TYPE_WD8003W,   0,                      MEM_8192},
 
71
        {"WD8003EB",    TYPE_WD8003EB,  0,                      MEM_8192},
 
72
        {"WD8013W",     TYPE_WD8013W,   FLAG_16BIT,             MEM_16384},
 
73
        {"WD8003EP/WD8013EP",
 
74
                        TYPE_WD8013EP,  0,                      MEM_8192},
 
75
        {"WD8013WC",    TYPE_WD8013WC,  FLAG_16BIT,             MEM_16384},
 
76
        {"WD8013EPC",   TYPE_WD8013EPC, FLAG_16BIT,             MEM_16384},
 
77
        {"SMC8216T",    TYPE_SMC8216T,  FLAG_16BIT | FLAG_790,  MEM_16384},
 
78
        {"SMC8216C",    TYPE_SMC8216C,  FLAG_16BIT | FLAG_790,  MEM_16384},
 
79
        {"SMC8416T",    TYPE_SMC8416T,  FLAG_16BIT | FLAG_790,  MEM_8192},
 
80
        {"SMC8416C/BT", TYPE_SMC8416C,  FLAG_16BIT | FLAG_790,  MEM_8192},
 
81
        {"SMC8013EBP",  TYPE_SMC8013EBP,FLAG_16BIT,             MEM_16384},
 
82
        {NULL,          0,              0,                      0}
 
83
};
 
84
#endif
 
85
 
 
86
#ifdef  INCLUDE_3C503
 
87
static unsigned char    t503_output;    /* AUI or internal xcvr (Thinnet) */
 
88
#endif
 
89
 
 
90
#if     defined(INCLUDE_WD)
 
91
#define ASIC_PIO        WD_IAR
 
92
#define eth_probe       wd_probe
 
93
#if     defined(INCLUDE_3C503) || defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
 
94
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
 
95
#endif
 
96
#endif
 
97
 
 
98
#if     defined(INCLUDE_3C503)
 
99
#define eth_probe       t503_probe
 
100
#if     defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || defined(INCLUDE_WD)
 
101
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
 
102
#endif
 
103
#endif
 
104
 
 
105
#if     defined(INCLUDE_NE)
 
106
#define eth_probe       ne_probe
 
107
#if     defined(INCLUDE_NS8390) || defined(INCLUDE_3C503) || defined(INCLUDE_WD)
 
108
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
 
109
#endif
 
110
#endif
 
111
 
 
112
#if     defined(INCLUDE_NS8390)
 
113
#define eth_probe       nepci_probe
 
114
#if     defined(INCLUDE_NE) || defined(INCLUDE_3C503) || defined(INCLUDE_WD)
 
115
Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
 
116
#endif
 
117
#endif
 
118
 
 
119
#if     defined(INCLUDE_3C503)
 
120
#define ASIC_PIO        _3COM_RFMSB
 
121
#else
 
122
#if     defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
 
123
#define ASIC_PIO        NE_DATA
 
124
#endif
 
125
#endif
 
126
 
 
127
#if     defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM)) || (defined(INCLUDE_WD) && defined(WD_790_PIO))
 
128
/**************************************************************************
 
129
ETH_PIO_READ - Read a frame via Programmed I/O
 
130
**************************************************************************/
 
131
static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt)
 
132
{
 
133
#ifdef  INCLUDE_WD
 
134
        outb(src & 0xff, eth_asic_base + WD_GP2);
 
135
        outb(src >> 8, eth_asic_base + WD_GP2);
 
136
#else
 
137
        outb(D8390_COMMAND_RD2 |
 
138
                D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
 
139
        outb(cnt, eth_nic_base + D8390_P0_RBCR0);
 
140
        outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1);
 
141
        outb(src, eth_nic_base + D8390_P0_RSAR0);
 
142
        outb(src>>8, eth_nic_base + D8390_P0_RSAR1);
 
143
        outb(D8390_COMMAND_RD0 |
 
144
                D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
 
145
 
 
146
#ifdef  INCLUDE_3C503
 
147
        outb(src & 0xff, eth_asic_base + _3COM_DALSB);
 
148
        outb(src >> 8, eth_asic_base + _3COM_DAMSB);
 
149
        outb(t503_output | _3COM_CR_START, eth_asic_base + _3COM_CR);
 
150
#endif
 
151
#endif
 
152
 
 
153
        if (eth_flags & FLAG_16BIT)
 
154
                cnt = (cnt + 1) >> 1;
 
155
 
 
156
        while(cnt--) {
 
157
#ifdef  INCLUDE_3C503
 
158
                while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0)
 
159
                        ;
 
160
#endif
 
161
 
 
162
                if (eth_flags & FLAG_16BIT) {
 
163
                        *((unsigned short *)dst) = inw(eth_asic_base + ASIC_PIO);
 
164
                        dst += 2;
 
165
                }
 
166
                else
 
167
                        *(dst++) = inb(eth_asic_base + ASIC_PIO);
 
168
        }
 
169
 
 
170
#ifdef  INCLUDE_3C503
 
171
        outb(t503_output, eth_asic_base + _3COM_CR);
 
172
#endif
 
173
}
 
174
 
 
175
/**************************************************************************
 
176
ETH_PIO_WRITE - Write a frame via Programmed I/O
 
177
**************************************************************************/
 
178
static void eth_pio_write(const unsigned char *src, unsigned int dst, unsigned int cnt)
 
179
{
 
180
#ifdef  COMPEX_RL2000_FIX
 
181
        unsigned int x;
 
182
#endif  /* COMPEX_RL2000_FIX */
 
183
#ifdef  INCLUDE_WD
 
184
        outb(dst & 0xff, eth_asic_base + WD_GP2);
 
185
        outb(dst >> 8, eth_asic_base + WD_GP2);
 
186
#else
 
187
        outb(D8390_COMMAND_RD2 |
 
188
                D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
 
189
        outb(D8390_ISR_RDC, eth_nic_base + D8390_P0_ISR);
 
190
        outb(cnt, eth_nic_base + D8390_P0_RBCR0);
 
191
        outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1);
 
192
        outb(dst, eth_nic_base + D8390_P0_RSAR0);
 
193
        outb(dst>>8, eth_nic_base + D8390_P0_RSAR1);
 
194
        outb(D8390_COMMAND_RD1 |
 
195
                D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
 
196
 
 
197
#ifdef  INCLUDE_3C503
 
198
        outb(dst & 0xff, eth_asic_base + _3COM_DALSB);
 
199
        outb(dst >> 8, eth_asic_base + _3COM_DAMSB);
 
200
 
 
201
        outb(t503_output | _3COM_CR_DDIR | _3COM_CR_START, eth_asic_base + _3COM_CR);
 
202
#endif
 
203
#endif
 
204
 
 
205
        if (eth_flags & FLAG_16BIT)
 
206
                cnt = (cnt + 1) >> 1;
 
207
 
 
208
        while(cnt--)
 
209
        {
 
210
#ifdef  INCLUDE_3C503
 
211
                while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0)
 
212
                        ;
 
213
#endif
 
214
 
 
215
                if (eth_flags & FLAG_16BIT) {
 
216
                        outw(*((unsigned short *)src), eth_asic_base + ASIC_PIO);
 
217
                        src += 2;
 
218
                }
 
219
                else
 
220
                        outb(*(src++), eth_asic_base + ASIC_PIO);
 
221
        }
 
222
 
 
223
#ifdef  INCLUDE_3C503
 
224
        outb(t503_output, eth_asic_base + _3COM_CR);
 
225
#else
 
226
#ifdef  COMPEX_RL2000_FIX
 
227
        for (x = 0;
 
228
                x < COMPEX_RL2000_TRIES &&
 
229
                (inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
 
230
                != D8390_ISR_RDC;
 
231
                ++x);
 
232
        if (x >= COMPEX_RL2000_TRIES)
 
233
                printf("Warning: Compex RL2000 aborted wait!\n");
 
234
#endif  /* COMPEX_RL2000_FIX */
 
235
#ifndef INCLUDE_WD
 
236
        while((inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
 
237
                != D8390_ISR_RDC);
 
238
#endif
 
239
#endif
 
240
}
 
241
#else
 
242
/**************************************************************************
 
243
ETH_PIO_READ - Dummy routine when NE2000 not compiled in
 
244
**************************************************************************/
 
245
static void eth_pio_read(unsigned int src __unused, unsigned char *dst  __unused, unsigned int cnt __unused) {}
 
246
#endif
 
247
 
 
248
 
 
249
/**************************************************************************
 
250
enable_multycast - Enable Multicast
 
251
**************************************************************************/
 
252
static void enable_multicast(unsigned short eth_nic_base) 
 
253
{
 
254
        unsigned char mcfilter[8];
 
255
        int i;
 
256
        memset(mcfilter, 0xFF, 8);
 
257
        outb(4, eth_nic_base+D8390_P0_RCR);     
 
258
        outb(D8390_COMMAND_RD2 + D8390_COMMAND_PS1, eth_nic_base + D8390_P0_COMMAND);
 
259
        for(i=0;i<8;i++)
 
260
        {
 
261
                outb(mcfilter[i], eth_nic_base + 8 + i);
 
262
                if(inb(eth_nic_base + 8 + i)!=mcfilter[i])
 
263
                        printf("Error SMC 83C690 Multicast filter read/write mishap %d\n",i);
 
264
        }
 
265
        outb(D8390_COMMAND_RD2 + D8390_COMMAND_PS0, eth_nic_base + D8390_P0_COMMAND);
 
266
        outb(4 | 0x08, eth_nic_base+D8390_P0_RCR);
 
267
}
 
268
 
 
269
/**************************************************************************
 
270
NS8390_RESET - Reset adapter
 
271
**************************************************************************/
 
272
static void ns8390_reset(struct nic *nic)
 
273
{
 
274
        int i;
 
275
 
 
276
        eth_drain_receiver = 0;
 
277
#ifdef  INCLUDE_WD
 
278
        if (eth_flags & FLAG_790)
 
279
                outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
 
280
        else
 
281
#endif
 
282
                outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
 
283
                        D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
 
284
        if (eth_flags & FLAG_16BIT)
 
285
                outb(0x49, eth_nic_base+D8390_P0_DCR);
 
286
        else
 
287
                outb(0x48, eth_nic_base+D8390_P0_DCR);
 
288
        outb(0, eth_nic_base+D8390_P0_RBCR0);
 
289
        outb(0, eth_nic_base+D8390_P0_RBCR1);
 
290
        outb(0x20, eth_nic_base+D8390_P0_RCR);  /* monitor mode */
 
291
        outb(2, eth_nic_base+D8390_P0_TCR);
 
292
        outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR);
 
293
        outb(eth_rx_start, eth_nic_base+D8390_P0_PSTART);
 
294
#ifdef  INCLUDE_WD
 
295
        if (eth_flags & FLAG_790) {
 
296
#ifdef  WD_790_PIO
 
297
                outb(0x10, eth_asic_base + 0x06); /* disable interrupts, enable PIO */
 
298
                outb(0x01, eth_nic_base + 0x09); /* enable ring read auto-wrap */
 
299
#else
 
300
                outb(0, eth_nic_base + 0x09);
 
301
#endif
 
302
        }
 
303
#endif
 
304
        outb(eth_memsize, eth_nic_base+D8390_P0_PSTOP);
 
305
        outb(eth_memsize - 1, eth_nic_base+D8390_P0_BOUND);
 
306
        outb(0xFF, eth_nic_base+D8390_P0_ISR);
 
307
        outb(0, eth_nic_base+D8390_P0_IMR);
 
308
#ifdef  INCLUDE_WD
 
309
        if (eth_flags & FLAG_790)
 
310
                outb(D8390_COMMAND_PS1 |
 
311
                        D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
 
312
        else
 
313
#endif
 
314
                outb(D8390_COMMAND_PS1 |
 
315
                        D8390_COMMAND_RD2 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
 
316
        for (i=0; i<ETH_ALEN; i++)
 
317
                outb(nic->node_addr[i], eth_nic_base+D8390_P1_PAR0+i);
 
318
        for (i=0; i<ETH_ALEN; i++)
 
319
                outb(0xFF, eth_nic_base+D8390_P1_MAR0+i);
 
320
        outb(eth_rx_start, eth_nic_base+D8390_P1_CURR);
 
321
#ifdef  INCLUDE_WD
 
322
        if (eth_flags & FLAG_790)
 
323
                outb(D8390_COMMAND_PS0 |
 
324
                        D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
 
325
        else
 
326
#endif
 
327
                outb(D8390_COMMAND_PS0 |
 
328
                        D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
 
329
        outb(0xFF, eth_nic_base+D8390_P0_ISR);
 
330
        outb(0, eth_nic_base+D8390_P0_TCR);     /* transmitter on */
 
331
        outb(4, eth_nic_base+D8390_P0_RCR);     /* allow rx broadcast frames */
 
332
 
 
333
        enable_multicast(eth_nic_base);
 
334
 
 
335
#ifdef  INCLUDE_3C503
 
336
        /*
 
337
         * No way to tell whether or not we're supposed to use
 
338
         * the 3Com's transceiver unless the user tells us.
 
339
         * 'flags' should have some compile time default value
 
340
         * which can be changed from the command menu.
 
341
         */
 
342
        t503_output = (nic->flags) ? 0 : _3COM_CR_XSEL;
 
343
        outb(t503_output, eth_asic_base + _3COM_CR);
 
344
#endif
 
345
}
 
346
 
 
347
static int ns8390_poll(struct nic *nic, int retrieve);
 
348
 
 
349
#ifndef INCLUDE_3C503
 
350
/**************************************************************************
 
351
ETH_RX_OVERRUN - Bring adapter back to work after an RX overrun
 
352
**************************************************************************/
 
353
static void eth_rx_overrun(struct nic *nic)
 
354
{
 
355
        int start_time;
 
356
 
 
357
#ifdef  INCLUDE_WD
 
358
        if (eth_flags & FLAG_790)
 
359
                outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
 
360
        else
 
361
#endif
 
362
                outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
 
363
                        D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
 
364
 
 
365
        /* wait for at least 1.6ms - we wait one timer tick */
 
366
        start_time = currticks();
 
367
        while (currticks() - start_time <= 1)
 
368
                /* Nothing */;
 
369
 
 
370
        outb(0, eth_nic_base+D8390_P0_RBCR0);   /* reset byte counter */
 
371
        outb(0, eth_nic_base+D8390_P0_RBCR1);
 
372
 
 
373
        /*
 
374
         * Linux driver checks for interrupted TX here. This is not necessary,
 
375
         * because the transmit routine waits until the frame is sent.
 
376
         */
 
377
 
 
378
        /* enter loopback mode and restart NIC */
 
379
        outb(2, eth_nic_base+D8390_P0_TCR);
 
380
#ifdef  INCLUDE_WD
 
381
        if (eth_flags & FLAG_790)
 
382
                outb(D8390_COMMAND_PS0 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
 
383
        else
 
384
#endif
 
385
                outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
 
386
                        D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
 
387
 
 
388
        /* clear the RX ring, acknowledge overrun interrupt */
 
389
        eth_drain_receiver = 1;
 
390
        while (ns8390_poll(nic, 1))
 
391
                /* Nothing */;
 
392
        eth_drain_receiver = 0;
 
393
        outb(D8390_ISR_OVW, eth_nic_base+D8390_P0_ISR);
 
394
 
 
395
        /* leave loopback mode - no packets to be resent (see Linux driver) */
 
396
        outb(0, eth_nic_base+D8390_P0_TCR);
 
397
}
 
398
#endif  /* INCLUDE_3C503 */
 
399
 
 
400
/**************************************************************************
 
401
NS8390_TRANSMIT - Transmit a frame
 
402
**************************************************************************/
 
403
static void ns8390_transmit(
 
404
        struct nic *nic,
 
405
        const char *d,                  /* Destination */
 
406
        unsigned int t,                 /* Type */
 
407
        unsigned int s,                 /* size */
 
408
        const char *p)                  /* Packet */
 
409
{
 
410
#if defined(INCLUDE_3C503) || (defined(INCLUDE_WD) && ! defined(WD_790_PIO))
 
411
        Address         eth_vmem = bus_to_virt(eth_bmem);
 
412
#endif
 
413
#ifdef  INCLUDE_3C503
 
414
        if (!(eth_flags & FLAG_PIO)) {
 
415
                memcpy((char *)eth_vmem, d, ETH_ALEN);  /* dst */
 
416
                memcpy((char *)eth_vmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
 
417
                *((char *)eth_vmem+12) = t>>8;          /* type */
 
418
                *((char *)eth_vmem+13) = t;
 
419
                memcpy((char *)eth_vmem+ETH_HLEN, p, s);
 
420
                s += ETH_HLEN;
 
421
                while (s < ETH_ZLEN) *((char *)eth_vmem+(s++)) = 0;
 
422
        }
 
423
#endif
 
424
 
 
425
#ifdef  INCLUDE_WD
 
426
        if (eth_flags & FLAG_16BIT) {
 
427
                outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
 
428
                inb(0x84);
 
429
        }
 
430
#ifndef WD_790_PIO
 
431
        /* Memory interface */
 
432
        if (eth_flags & FLAG_790) {
 
433
                outb(WD_MSR_MENB, eth_asic_base + WD_MSR);
 
434
                inb(0x84);
 
435
        }
 
436
        inb(0x84);
 
437
        memcpy((char *)eth_vmem, d, ETH_ALEN);  /* dst */
 
438
        memcpy((char *)eth_vmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
 
439
        *((char *)eth_vmem+12) = t>>8;          /* type */
 
440
        *((char *)eth_vmem+13) = t;
 
441
        memcpy((char *)eth_vmem+ETH_HLEN, p, s);
 
442
        s += ETH_HLEN;
 
443
        while (s < ETH_ZLEN) *((char *)eth_vmem+(s++)) = 0;
 
444
        if (eth_flags & FLAG_790) {
 
445
                outb(0, eth_asic_base + WD_MSR);
 
446
                inb(0x84);
 
447
        }
 
448
#else
 
449
        inb(0x84);
 
450
#endif
 
451
#endif
 
452
 
 
453
#if     defined(INCLUDE_3C503)
 
454
        if (eth_flags & FLAG_PIO)
 
455
#endif
 
456
#if     defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM)) || (defined(INCLUDE_WD) && defined(WD_790_PIO))
 
457
        {
 
458
                /* Programmed I/O */
 
459
                unsigned short type;
 
460
                type = (t >> 8) | (t << 8);
 
461
                eth_pio_write( (unsigned char *) d, eth_tx_start<<8, ETH_ALEN);
 
462
                eth_pio_write(nic->node_addr, (eth_tx_start<<8)+ETH_ALEN, ETH_ALEN);
 
463
                /* bcc generates worse code without (const+const) below */
 
464
                eth_pio_write((unsigned char *)&type, (eth_tx_start<<8)+(ETH_ALEN+ETH_ALEN), 2);
 
465
                eth_pio_write( (unsigned char *) p, (eth_tx_start<<8)+ETH_HLEN, s);
 
466
                s += ETH_HLEN;
 
467
                if (s < ETH_ZLEN) s = ETH_ZLEN;
 
468
        }
 
469
#endif
 
470
#if     defined(INCLUDE_3C503)
 
471
#endif
 
472
 
 
473
#ifdef  INCLUDE_WD
 
474
        if (eth_flags & FLAG_16BIT) {
 
475
                outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
 
476
                inb(0x84);
 
477
        }
 
478
        if (eth_flags & FLAG_790)
 
479
                outb(D8390_COMMAND_PS0 |
 
480
                        D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
 
481
        else
 
482
#endif
 
483
                outb(D8390_COMMAND_PS0 |
 
484
                        D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
 
485
        outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR);
 
486
        outb(s, eth_nic_base+D8390_P0_TBCR0);
 
487
        outb(s>>8, eth_nic_base+D8390_P0_TBCR1);
 
488
#ifdef  INCLUDE_WD
 
489
        if (eth_flags & FLAG_790)
 
490
                outb(D8390_COMMAND_PS0 |
 
491
                        D8390_COMMAND_TXP | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
 
492
        else
 
493
#endif
 
494
                outb(D8390_COMMAND_PS0 |
 
495
                        D8390_COMMAND_TXP | D8390_COMMAND_RD2 |
 
496
                        D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
 
497
}
 
498
 
 
499
/**************************************************************************
 
500
NS8390_POLL - Wait for a frame
 
501
**************************************************************************/
 
502
static int ns8390_poll(struct nic *nic, int retrieve)
 
503
{
 
504
        int ret = 0;
 
505
        unsigned char rstat, curr, next;
 
506
        unsigned short len, frag;
 
507
        unsigned short pktoff;
 
508
        unsigned char *p;
 
509
        struct ringbuffer pkthdr;
 
510
 
 
511
#ifndef INCLUDE_3C503
 
512
        /* avoid infinite recursion: see eth_rx_overrun() */
 
513
        if (!eth_drain_receiver && (inb(eth_nic_base+D8390_P0_ISR) & D8390_ISR_OVW)) {
 
514
                eth_rx_overrun(nic);
 
515
                return(0);
 
516
        }
 
517
#endif  /* INCLUDE_3C503 */
 
518
        rstat = inb(eth_nic_base+D8390_P0_RSR);
 
519
        if (!(rstat & D8390_RSTAT_PRX)) return(0);
 
520
        next = inb(eth_nic_base+D8390_P0_BOUND)+1;
 
521
        if (next >= eth_memsize) next = eth_rx_start;
 
522
        outb(D8390_COMMAND_PS1, eth_nic_base+D8390_P0_COMMAND);
 
523
        curr = inb(eth_nic_base+D8390_P1_CURR);
 
524
        outb(D8390_COMMAND_PS0, eth_nic_base+D8390_P0_COMMAND);
 
525
        if (curr >= eth_memsize) curr=eth_rx_start;
 
526
        if (curr == next) return(0);
 
527
 
 
528
        if ( ! retrieve ) return 1;
 
529
 
 
530
#ifdef  INCLUDE_WD
 
531
        if (eth_flags & FLAG_16BIT) {
 
532
                outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
 
533
                inb(0x84);
 
534
        }
 
535
#ifndef WD_790_PIO
 
536
        if (eth_flags & FLAG_790) {
 
537
                outb(WD_MSR_MENB, eth_asic_base + WD_MSR);
 
538
                inb(0x84);
 
539
        }
 
540
#endif
 
541
        inb(0x84);
 
542
#endif
 
543
        pktoff = next << 8;
 
544
        if (eth_flags & FLAG_PIO)
 
545
                eth_pio_read(pktoff, (unsigned char *)&pkthdr, 4);
 
546
        else
 
547
                memcpy(&pkthdr, bus_to_virt(eth_rmem + pktoff), 4);
 
548
        pktoff += sizeof(pkthdr);
 
549
        /* incoming length includes FCS so must sub 4 */
 
550
        len = pkthdr.len - 4;
 
551
        if ((pkthdr.status & D8390_RSTAT_PRX) == 0 || len < ETH_ZLEN
 
552
                || len > ETH_FRAME_LEN) {
 
553
                printf("Bogus packet, ignoring\n");
 
554
                return (0);
 
555
        }
 
556
        else {
 
557
                p = nic->packet;
 
558
                nic->packetlen = len;           /* available to caller */
 
559
                frag = (eth_memsize << 8) - pktoff;
 
560
                if (len > frag) {               /* We have a wrap-around */
 
561
                        /* read first part */
 
562
                        if (eth_flags & FLAG_PIO)
 
563
                                eth_pio_read(pktoff, p, frag);
 
564
                        else
 
565
                                memcpy(p, bus_to_virt(eth_rmem + pktoff), frag);
 
566
                        pktoff = eth_rx_start << 8;
 
567
                        p += frag;
 
568
                        len -= frag;
 
569
                }
 
570
                /* read second part */
 
571
                if (eth_flags & FLAG_PIO)
 
572
                        eth_pio_read(pktoff, p, len);
 
573
                else
 
574
                        memcpy(p, bus_to_virt(eth_rmem + pktoff), len);
 
575
                ret = 1;
 
576
        }
 
577
#ifdef  INCLUDE_WD
 
578
#ifndef WD_790_PIO
 
579
        if (eth_flags & FLAG_790) {
 
580
                outb(0, eth_asic_base + WD_MSR);
 
581
                inb(0x84);
 
582
        }
 
583
#endif
 
584
        if (eth_flags & FLAG_16BIT) {
 
585
                outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
 
586
                inb(0x84);
 
587
        }
 
588
        inb(0x84);
 
589
#endif
 
590
        next = pkthdr.next;             /* frame number of next packet */
 
591
        if (next == eth_rx_start)
 
592
                next = eth_memsize;
 
593
        outb(next-1, eth_nic_base+D8390_P0_BOUND);
 
594
        return(ret);
 
595
}
 
596
 
 
597
/**************************************************************************
 
598
NS8390_DISABLE - Turn off adapter
 
599
**************************************************************************/
 
600
static void ns8390_disable ( struct nic *nic ) {
 
601
        ns8390_reset(nic);
 
602
}
 
603
 
 
604
/**************************************************************************
 
605
NS8390_IRQ - Enable, Disable, or Force interrupts
 
606
**************************************************************************/
 
607
static void ns8390_irq(struct nic *nic __unused, irq_action_t action __unused)
 
608
{
 
609
  switch ( action ) {
 
610
  case DISABLE :
 
611
    break;
 
612
  case ENABLE :
 
613
    break;
 
614
  case FORCE :
 
615
    break;
 
616
  }
 
617
}
 
618
 
 
619
static struct nic_operations ns8390_operations;
 
620
static struct nic_operations ns8390_operations = {
 
621
        .connect        = dummy_connect,
 
622
        .poll           = ns8390_poll,
 
623
        .transmit       = ns8390_transmit,
 
624
        .irq            = ns8390_irq,
 
625
};
 
626
 
 
627
/**************************************************************************
 
628
ETH_PROBE - Look for an adapter
 
629
**************************************************************************/
 
630
#ifdef  INCLUDE_NS8390
 
631
static int eth_probe (struct nic *nic, struct pci_device *pci)
 
632
#else
 
633
static int eth_probe (struct dev *dev, unsigned short *probe_addrs __unused)
 
634
#endif
 
635
{
 
636
        int i;
 
637
#ifdef INCLUDE_NS8390
 
638
        unsigned short pci_probe_addrs[] = { pci->ioaddr, 0 };
 
639
        unsigned short *probe_addrs = pci_probe_addrs;
 
640
#endif
 
641
        eth_vendor = VENDOR_NONE;
 
642
        eth_drain_receiver = 0;
 
643
 
 
644
        nic->irqno  = 0;
 
645
 
 
646
#ifdef  INCLUDE_WD
 
647
{
 
648
        /******************************************************************
 
649
        Search for WD/SMC cards
 
650
        ******************************************************************/
 
651
        struct wd_board *brd;
 
652
        unsigned short chksum;
 
653
        unsigned char c;
 
654
        for (eth_asic_base = WD_LOW_BASE; eth_asic_base <= WD_HIGH_BASE;
 
655
                eth_asic_base += 0x20) {
 
656
                chksum = 0;
 
657
                for (i=8; i<16; i++)
 
658
                        chksum += inb(eth_asic_base+i);
 
659
                /* Extra checks to avoid soundcard */
 
660
                if ((chksum & 0xFF) == 0xFF &&
 
661
                        inb(eth_asic_base+8) != 0xFF &&
 
662
                        inb(eth_asic_base+9) != 0xFF)
 
663
                        break;
 
664
        }
 
665
        if (eth_asic_base > WD_HIGH_BASE)
 
666
                return (0);
 
667
        /* We've found a board */
 
668
        eth_vendor = VENDOR_WD;
 
669
        eth_nic_base = eth_asic_base + WD_NIC_ADDR;
 
670
 
 
671
        nic->ioaddr = eth_nic_base;
 
672
 
 
673
        c = inb(eth_asic_base+WD_BID);  /* Get board id */
 
674
        for (brd = wd_boards; brd->name; brd++)
 
675
                if (brd->id == c) break;
 
676
        if (!brd->name) {
 
677
                printf("Unknown WD/SMC NIC type %hhX\n", c);
 
678
                return (0);     /* Unknown type */
 
679
        }
 
680
        eth_flags = brd->flags;
 
681
        eth_memsize = brd->memsize;
 
682
        eth_tx_start = 0;
 
683
        eth_rx_start = D8390_TXBUF_SIZE;
 
684
        if ((c == TYPE_WD8013EP) &&
 
685
                (inb(eth_asic_base + WD_ICR) & WD_ICR_16BIT)) {
 
686
                        eth_flags = FLAG_16BIT;
 
687
                        eth_memsize = MEM_16384;
 
688
        }
 
689
        if ((c & WD_SOFTCONFIG) && (!(eth_flags & FLAG_790))) {
 
690
                eth_bmem = (0x80000 |
 
691
                 ((inb(eth_asic_base + WD_MSR) & 0x3F) << 13));
 
692
        } else
 
693
                eth_bmem = WD_DEFAULT_MEM;
 
694
        if (brd->id == TYPE_SMC8216T || brd->id == TYPE_SMC8216C) {
 
695
                /* from Linux driver, 8416BT detects as 8216 sometimes */
 
696
                unsigned int addr = inb(eth_asic_base + 0xb);
 
697
                if (((addr >> 4) & 3) == 0) {
 
698
                        brd += 2;
 
699
                        eth_memsize = brd->memsize;
 
700
                }
 
701
        }
 
702
        outb(0x80, eth_asic_base + WD_MSR);     /* Reset */
 
703
        for (i=0; i<ETH_ALEN; i++) {
 
704
                nic->node_addr[i] = inb(i+eth_asic_base+WD_LAR);
 
705
        }
 
706
        DBG ( "\n%s base %4.4x", brd->name, eth_asic_base );
 
707
        if (eth_flags & FLAG_790) {
 
708
#ifdef  WD_790_PIO
 
709
                DBG ( ", PIO mode, addr %s\n", eth_ntoa ( nic->node_addr ) );
 
710
                eth_bmem = 0;
 
711
                eth_flags |= FLAG_PIO;          /* force PIO mode */
 
712
                outb(0, eth_asic_base+WD_MSR);
 
713
#else
 
714
                DBG ( ", Memory %x, MAC Addr %s\n", eth_bmem, eth_ntoa ( nic->node_addr) );
 
715
 
 
716
                outb(WD_MSR_MENB, eth_asic_base+WD_MSR);
 
717
                outb((inb(eth_asic_base+0x04) |
 
718
                        0x80), eth_asic_base+0x04);
 
719
                outb(((unsigned)(eth_bmem >> 13) & 0x0F) |
 
720
                        ((unsigned)(eth_bmem >> 11) & 0x40) |
 
721
                        (inb(eth_asic_base+0x0B) & 0xB0), eth_asic_base+0x0B);
 
722
                outb((inb(eth_asic_base+0x04) &
 
723
                        ~0x80), eth_asic_base+0x04);
 
724
#endif
 
725
        } else {
 
726
 
 
727
                DBG (", Memory %x, MAC Addr %s\n", eth_bmem, eth_ntoa ( nic->node_addr) );
 
728
 
 
729
                outb(((unsigned)(eth_bmem >> 13) & 0x3F) | 0x40, eth_asic_base+WD_MSR);
 
730
        }
 
731
        if (eth_flags & FLAG_16BIT) {
 
732
                if (eth_flags & FLAG_790) {
 
733
                        eth_laar = inb(eth_asic_base + WD_LAAR);
 
734
                        outb(WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
 
735
                } else {
 
736
                        outb((eth_laar =
 
737
                                WD_LAAR_L16EN | 1), eth_asic_base + WD_LAAR);
 
738
/*
 
739
        The previous line used to be
 
740
                                WD_LAAR_M16EN | WD_LAAR_L16EN | 1));
 
741
        jluke@deakin.edu.au reported that removing WD_LAAR_M16EN made
 
742
        it work for WD8013s.  This seems to work for my 8013 boards. I
 
743
        don't know what is really happening.  I wish I had data sheets
 
744
        or more time to decode the Linux driver. - Ken
 
745
*/
 
746
                }
 
747
                inb(0x84);
 
748
        }
 
749
}
 
750
#endif
 
751
#ifdef  INCLUDE_3C503
 
752
#ifdef  T503_AUI
 
753
        nic->flags = 1;         /* aui */
 
754
#else
 
755
        nic->flags = 0;         /* no aui */
 
756
#endif
 
757
        /******************************************************************
 
758
        Search for 3Com 3c503 if no WD/SMC cards
 
759
        ******************************************************************/
 
760
        if (eth_vendor == VENDOR_NONE) {
 
761
                int     idx;
 
762
                int     iobase_reg, membase_reg;
 
763
                static unsigned short   base[] = {
 
764
                        0x300, 0x310, 0x330, 0x350,
 
765
                        0x250, 0x280, 0x2A0, 0x2E0, 0 };
 
766
 
 
767
                /* Loop through possible addresses checking each one */
 
768
 
 
769
                for (idx = 0; (eth_nic_base = base[idx]) != 0; ++idx) {
 
770
 
 
771
                        eth_asic_base = eth_nic_base + _3COM_ASIC_OFFSET;
 
772
/*
 
773
 * Note that we use the same settings for both 8 and 16 bit cards:
 
774
 * both have an 8K bank of memory at page 1 while only the 16 bit
 
775
 * cards have a bank at page 0.
 
776
 */
 
777
                        eth_memsize = MEM_16384;
 
778
                        eth_tx_start = 32;
 
779
                        eth_rx_start = 32 + D8390_TXBUF_SIZE;
 
780
 
 
781
                /* Check our base address. iobase and membase should */
 
782
                /* both have a maximum of 1 bit set or be 0. */
 
783
 
 
784
                        iobase_reg = inb(eth_asic_base + _3COM_BCFR);
 
785
                        membase_reg = inb(eth_asic_base + _3COM_PCFR);
 
786
 
 
787
                        if ((iobase_reg & (iobase_reg - 1)) ||
 
788
                                (membase_reg & (membase_reg - 1)))
 
789
                                continue;               /* nope */
 
790
 
 
791
                /* Now get the shared memory address */
 
792
 
 
793
                        eth_flags = 0;
 
794
 
 
795
                        switch (membase_reg) {
 
796
                                case _3COM_PCFR_DC000:
 
797
                                        eth_bmem = 0xdc000;
 
798
                                        break;
 
799
                                case _3COM_PCFR_D8000:
 
800
                                        eth_bmem = 0xd8000;
 
801
                                        break;
 
802
                                case _3COM_PCFR_CC000:
 
803
                                        eth_bmem = 0xcc000;
 
804
                                        break;
 
805
                                case _3COM_PCFR_C8000:
 
806
                                        eth_bmem = 0xc8000;
 
807
                                        break;
 
808
                                case _3COM_PCFR_PIO:
 
809
                                        eth_flags |= FLAG_PIO;
 
810
                                        eth_bmem = 0;
 
811
                                        break;
 
812
                                default:
 
813
                                        continue;       /* nope */
 
814
                                }
 
815
                        break;
 
816
                }
 
817
 
 
818
                if (base[idx] == 0)             /* not found */
 
819
                        return (0);
 
820
#ifndef T503_SHMEM
 
821
                eth_flags |= FLAG_PIO;          /* force PIO mode */
 
822
                eth_bmem = 0;
 
823
#endif
 
824
                eth_vendor = VENDOR_3COM;
 
825
 
 
826
 
 
827
        /* Need this to make ns8390_poll() happy. */
 
828
 
 
829
                eth_rmem = eth_bmem - 0x2000;
 
830
 
 
831
        /* Reset NIC and ASIC */
 
832
 
 
833
                outb(_3COM_CR_RST | _3COM_CR_XSEL, eth_asic_base + _3COM_CR );
 
834
                outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR );
 
835
 
 
836
        /* Get our ethernet address */
 
837
 
 
838
                outb(_3COM_CR_EALO | _3COM_CR_XSEL, eth_asic_base + _3COM_CR);
 
839
                nic->ioaddr = eth_nic_base;
 
840
                DBG ( "\n3Com 3c503 base %4.4x, ", eth_nic_base );
 
841
                if (eth_flags & FLAG_PIO)
 
842
                        DBG ( "PIO mode" );
 
843
                else
 
844
                        DBG ( "memory %4.4x", eth_bmem );
 
845
                for (i=0; i<ETH_ALEN; i++) {
 
846
                        nic->node_addr[i] = inb(eth_nic_base+i);
 
847
                }
 
848
                DBG ( ", %s, MAC Addr %s\n", nic->flags ? "AUI" : "internal xcvr",
 
849
                      eth_ntoa ( nic->node_addr ) );
 
850
 
 
851
                outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR);
 
852
        /*
 
853
         * Initialize GA configuration register. Set bank and enable shared
 
854
         * mem. We always use bank 1. Disable interrupts.
 
855
         */
 
856
                outb(_3COM_GACFR_RSEL |
 
857
                        _3COM_GACFR_MBS0 | _3COM_GACFR_TCM | _3COM_GACFR_NIM, eth_asic_base + _3COM_GACFR);
 
858
 
 
859
                outb(0xff, eth_asic_base + _3COM_VPTR2);
 
860
                outb(0xff, eth_asic_base + _3COM_VPTR1);
 
861
                outb(0x00, eth_asic_base + _3COM_VPTR0);
 
862
        /*
 
863
         * Clear memory and verify that it worked (we use only 8K)
 
864
         */
 
865
 
 
866
                if (!(eth_flags & FLAG_PIO)) {
 
867
                        memset(bus_to_virt(eth_bmem), 0, 0x2000);
 
868
                        for(i = 0; i < 0x2000; ++i)
 
869
                                if (*((char *)(bus_to_virt(eth_bmem+i)))) {
 
870
                                        printf ("Failed to clear 3c503 shared mem.\n");
 
871
                                        return (0);
 
872
                                }
 
873
                }
 
874
        /*
 
875
         * Initialize GA page/start/stop registers.
 
876
         */
 
877
                outb(eth_tx_start, eth_asic_base + _3COM_PSTR);
 
878
                outb(eth_memsize, eth_asic_base + _3COM_PSPR);
 
879
        }
 
880
#endif
 
881
#if     defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
 
882
{
 
883
        /******************************************************************
 
884
        Search for NE1000/2000 if no WD/SMC or 3com cards
 
885
        ******************************************************************/
 
886
        unsigned char c;
 
887
        if (eth_vendor == VENDOR_NONE) {
 
888
                unsigned char romdata[16];
 
889
                unsigned char testbuf[32];
 
890
                int idx;
 
891
                static unsigned char test[] = "NE*000 memory";
 
892
                static unsigned short base[] = {
 
893
#ifdef  NE_SCAN
 
894
                        NE_SCAN,
 
895
#endif
 
896
                        0 };
 
897
                /* if no addresses supplied, fall back on defaults */
 
898
                if (probe_addrs == NULL || probe_addrs[0] == 0)
 
899
                        probe_addrs = base;
 
900
                eth_bmem = 0;           /* No shared memory */
 
901
                for (idx = 0; (eth_nic_base = probe_addrs[idx]) != 0; ++idx) {
 
902
                        eth_flags = FLAG_PIO;
 
903
                        eth_asic_base = eth_nic_base + NE_ASIC_OFFSET;
 
904
                        eth_memsize = MEM_16384;
 
905
                        eth_tx_start = 32;
 
906
                        eth_rx_start = 32 + D8390_TXBUF_SIZE;
 
907
                        c = inb(eth_asic_base + NE_RESET);
 
908
                        outb(c, eth_asic_base + NE_RESET);
 
909
                        (void) inb(0x84);
 
910
                        outb(D8390_COMMAND_STP |
 
911
                                D8390_COMMAND_RD2, eth_nic_base + D8390_P0_COMMAND);
 
912
                        outb(D8390_RCR_MON, eth_nic_base + D8390_P0_RCR);
 
913
                        outb(D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR);
 
914
                        outb(MEM_8192, eth_nic_base + D8390_P0_PSTART);
 
915
                        outb(MEM_16384, eth_nic_base + D8390_P0_PSTOP);
 
916
#ifdef  NS8390_FORCE_16BIT
 
917
                        eth_flags |= FLAG_16BIT;        /* force 16-bit mode */
 
918
#endif
 
919
 
 
920
                        eth_pio_write( (unsigned char *) test, 8192, sizeof(test));
 
921
                        eth_pio_read(8192, testbuf, sizeof(test));
 
922
                        if (!memcmp(test, testbuf, sizeof(test)))
 
923
                                break;
 
924
                        eth_flags |= FLAG_16BIT;
 
925
                        eth_memsize = MEM_32768;
 
926
                        eth_tx_start = 64;
 
927
                        eth_rx_start = 64 + D8390_TXBUF_SIZE;
 
928
                        outb(D8390_DCR_WTS |
 
929
                                D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR);
 
930
                        outb(MEM_16384, eth_nic_base + D8390_P0_PSTART);
 
931
                        outb(MEM_32768, eth_nic_base + D8390_P0_PSTOP);
 
932
                        eth_pio_write( (unsigned char *) test, 16384, sizeof(test));
 
933
                        eth_pio_read(16384, testbuf, sizeof(test));
 
934
                        if (!memcmp(testbuf, test, sizeof(test)))
 
935
                                break;
 
936
                }
 
937
                if (eth_nic_base == 0)
 
938
                        return (0);
 
939
                if (eth_nic_base > ISA_MAX_ADDR)        /* PCI probably */
 
940
                        eth_flags |= FLAG_16BIT;
 
941
                eth_vendor = VENDOR_NOVELL;
 
942
                eth_pio_read(0, romdata, sizeof(romdata));
 
943
                for (i=0; i<ETH_ALEN; i++) {
 
944
                        nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)];
 
945
                }
 
946
                nic->ioaddr = eth_nic_base;
 
947
                DBG ( "\nNE%c000 base %4.4x, MAC Addr %s\n",
 
948
                      (eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base,
 
949
                      eth_ntoa ( nic->node_addr ) );
 
950
        }
 
951
}
 
952
#endif
 
953
        if (eth_vendor == VENDOR_NONE)
 
954
                return(0);
 
955
        if (eth_vendor != VENDOR_3COM)
 
956
                eth_rmem = eth_bmem;
 
957
        ns8390_reset(nic);
 
958
        nic->nic_op     = &ns8390_operations;
 
959
 
 
960
        /* Based on PnP ISA map */
 
961
#ifdef  INCLUDE_WD
 
962
        dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
 
963
        dev->devid.device_id = htons(0x812a);
 
964
#endif
 
965
#ifdef  INCLUDE_3C503
 
966
        dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
 
967
        dev->devid.device_id = htons(0x80f3);
 
968
#endif
 
969
#ifdef  INCLUDE_NE
 
970
        dev->devid.vendor_id = htons(GENERIC_ISAPNP_VENDOR);
 
971
        dev->devid.device_id = htons(0x80d6);
 
972
#endif
 
973
        return 1;
 
974
}
 
975
 
 
976
#ifdef  INCLUDE_WD
 
977
struct isa_driver wd_driver __isa_driver = {
 
978
        .type    = NIC_DRIVER,
 
979
        .name    = "WD",
 
980
        .probe   = wd_probe,
 
981
        .ioaddrs = 0, 
 
982
};
 
983
ISA_ROM("wd","WD8003/8013, SMC8216/8416, SMC 83c790 (EtherEZ)");
 
984
#endif
 
985
 
 
986
#ifdef  INCLUDE_3C503
 
987
struct isa_driver t503_driver __isa_driver = {
 
988
        .type    = NIC_DRIVER,
 
989
        .name    = "3C503",
 
990
        .probe   = t503_probe,
 
991
        .ioaddrs = 0, 
 
992
};
 
993
ISA_ROM("3c503","3Com503, Etherlink II[/16]");
 
994
#endif
 
995
 
 
996
#ifdef  INCLUDE_NE
 
997
struct isa_driver ne_driver __isa_driver = {
 
998
        .type    = NIC_DRIVER,
 
999
        .name    = "NE*000",
 
1000
        .probe   = ne_probe,
 
1001
        .ioaddrs = 0, 
 
1002
};
 
1003
ISA_ROM("ne","NE1000/2000 and clones");
 
1004
#endif
 
1005
 
 
1006
#ifdef  INCLUDE_NS8390
 
1007
static struct pci_device_id nepci_nics[] = {
 
1008
/* A few NE2000 PCI clones, list not exhaustive */
 
1009
PCI_ROM(0x10ec, 0x8029, "rtl8029",      "Realtek 8029", 0),
 
1010
PCI_ROM(0x1186, 0x0300, "dlink-528",    "D-Link DE-528", 0),
 
1011
PCI_ROM(0x1050, 0x0940, "winbond940",   "Winbond NE2000-PCI", 0),               /* Winbond 86C940 / 89C940 */
 
1012
PCI_ROM(0x1050, 0x5a5a, "winbond940f",  "Winbond W89c940F", 0),         /* Winbond 89C940F */
 
1013
PCI_ROM(0x11f6, 0x1401, "compexrl2000", "Compex ReadyLink 2000", 0),
 
1014
PCI_ROM(0x8e2e, 0x3000, "ktiet32p2",    "KTI ET32P2", 0),
 
1015
PCI_ROM(0x4a14, 0x5000, "nv5000sc",     "NetVin NV5000SC", 0),
 
1016
PCI_ROM(0x12c3, 0x0058, "holtek80232",  "Holtek HT80232", 0),
 
1017
PCI_ROM(0x12c3, 0x5598, "holtek80229",  "Holtek HT80229", 0),
 
1018
PCI_ROM(0x10bd, 0x0e34, "surecom-ne34", "Surecom NE34", 0),
 
1019
PCI_ROM(0x1106, 0x0926, "via86c926",    "Via 86c926", 0),
 
1020
};
 
1021
 
 
1022
PCI_DRIVER ( nepci_driver, nepci_nics, PCI_NO_CLASS );
 
1023
 
 
1024
DRIVER ( "NE2000/PCI", nic_driver, pci_driver, nepci_driver,
 
1025
         nepci_probe, ns8390_disable );
 
1026
 
 
1027
#endif /* INCLUDE_NS8390 */
 
1028
 
 
1029
#endif
 
1030
 
 
1031
/*
 
1032
 * Local variables:
 
1033
 *  c-basic-offset: 8
 
1034
 *  c-indent-level: 8
 
1035
 *  tab-width: 8
 
1036
 * End:
 
1037
 */