2
Ported to U-Boot by Christian Pellegrin <chri@ascensit.com>
4
Based on sources from the Linux kernel (pcnet_cs.c, 8390.h) and
5
eCOS(if_dp83902a.c, if_dp83902a.h). Both of these 2 wonderful world
6
are GPL, so this is, of course, GPL.
8
==========================================================================
12
Ethernet device driver for NS DP83902a ethernet controller
14
==========================================================================
15
####ECOSGPLCOPYRIGHTBEGIN####
16
-------------------------------------------
17
This file is part of eCos, the Embedded Configurable Operating System.
18
Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
20
eCos is free software; you can redistribute it and/or modify it under
21
the terms of the GNU General Public License as published by the Free
22
Software Foundation; either version 2 or (at your option) any later version.
24
eCos is distributed in the hope that it will be useful, but WITHOUT ANY
25
WARRANTY; without even the implied warranty of MERCHANTABILITY or
26
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29
You should have received a copy of the GNU General Public License along
30
with eCos; if not, write to the Free Software Foundation, Inc.,
31
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
33
As a special exception, if other files instantiate templates or use macros
34
or inline functions from this file, or you compile this file and link it
35
with other works to produce a work based on this file, this file does not
36
by itself cause the resulting work to be covered by the GNU General Public
37
License. However the source code for this file must still be made available
38
in accordance with section (3) of the GNU General Public License.
40
This exception does not invalidate any other reasons why a work based on
41
this file might be covered by the GNU General Public License.
43
Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
44
at http://sources.redhat.com/ecos/ecos-license/
45
-------------------------------------------
46
####ECOSGPLCOPYRIGHTEND####
47
####BSDCOPYRIGHTBEGIN####
49
-------------------------------------------
51
Portions of this software may have been derived from OpenBSD or other sources,
52
and are covered by the appropriate copyright disclaimers included herein.
54
-------------------------------------------
56
####BSDCOPYRIGHTEND####
57
==========================================================================
58
#####DESCRIPTIONBEGIN####
61
Contributors: gthomas, jskov, rsandifo
66
FIXME: Will fail if pinged with large packets (1520 bytes)
70
####DESCRIPTIONEND####
72
==========================================================================
78
/* NE2000 base header file */
79
#include "ne2000_base.h"
81
/* find prom (taken from pc_net_cs.c from Linux) */
85
typedef struct hw_info_t {
91
#define DELAY_OUTPUT 0x01
92
#define HAS_MISC_REG 0x02
93
#define USE_BIG_BUF 0x04
94
#define HAS_IBM_MISC 0x08
95
#define IS_DL10019 0x10
96
#define IS_DL10022 0x20
98
#define USE_SHMEM 0x80 /* autodetected */
100
#define AM79C9XX_HOME_PHY 0x00006B90 /* HomePNA PHY */
101
#define AM79C9XX_ETH_PHY 0x00006B70 /* 10baseT PHY */
102
#define MII_PHYID_REV_MASK 0xfffffff0
103
#define MII_PHYID_REG1 0x02
104
#define MII_PHYID_REG2 0x03
106
static hw_info_t hw_info[] = {
107
{ /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT },
108
{ /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 },
109
{ /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 },
110
{ /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94,
111
DELAY_OUTPUT | HAS_IBM_MISC },
112
{ /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 },
113
{ /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 },
114
{ /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 },
115
{ /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 },
116
{ /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 },
117
{ /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 },
118
{ /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48,
119
HAS_MISC_REG | HAS_IBM_MISC },
120
{ /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 },
121
{ /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 },
122
{ /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a,
123
HAS_MISC_REG | HAS_IBM_MISC },
124
{ /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac,
125
HAS_MISC_REG | HAS_IBM_MISC },
126
{ /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29,
127
HAS_MISC_REG | HAS_IBM_MISC },
128
{ /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a,
129
HAS_MISC_REG | HAS_IBM_MISC },
130
{ /* IBM FME */ 0x0374, 0x00, 0x04, 0xac,
131
HAS_MISC_REG | HAS_IBM_MISC },
132
{ /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87,
133
HAS_MISC_REG | HAS_IBM_MISC },
134
{ /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17,
135
HAS_MISC_REG | HAS_IBM_MISC },
136
{ /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8,
137
HAS_MISC_REG | HAS_IBM_MISC },
138
{ /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0,
139
HAS_MISC_REG | HAS_IBM_MISC },
140
{ /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0,
141
HAS_MISC_REG | HAS_IBM_MISC },
142
{ /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 },
143
{ /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 },
144
{ /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0,
145
HAS_MISC_REG | HAS_IBM_MISC },
146
{ /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f,
147
HAS_MISC_REG | HAS_IBM_MISC },
148
{ /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 },
149
{ /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 },
150
{ /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 },
151
{ /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 },
152
{ /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65,
153
HAS_MISC_REG | HAS_IBM_MISC },
154
{ /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45,
155
HAS_MISC_REG | HAS_IBM_MISC },
156
{ /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 },
157
{ /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 },
158
{ /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 },
159
{ /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b,
160
DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF },
161
{ /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 },
162
{ /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 },
163
{ /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 },
164
{ /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 },
165
{ /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 },
166
{ /* Qemu */ 0x0, 0x52, 0x54, 0x00, 0 },
167
{ /* RTL8019AS */ 0x0, 0x0, 0x18, 0x5f, 0 }
170
#define NR_INFO (sizeof(hw_info)/sizeof(hw_info_t))
172
#define PCNET_CMD 0x00
173
#define PCNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */
174
#define PCNET_RESET 0x1f /* Issue a read to reset, a write to clear. */
175
#define PCNET_MISC 0x18 /* For IBM CCAE and Socket EA cards */
177
static void pcnet_reset_8390(u8* addr)
181
n2k_outb(E8390_NODMA + E8390_PAGE0+E8390_STOP, E8390_CMD);
182
PRINTK("cmd (at %lx) is %x\n", addr + E8390_CMD, n2k_inb(E8390_CMD));
183
n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD);
184
PRINTK("cmd (at %lx) is %x\n", addr + E8390_CMD, n2k_inb(E8390_CMD));
185
n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
186
PRINTK("cmd (at %lx) is %x\n", addr + E8390_CMD, n2k_inb(E8390_CMD));
187
n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);
189
n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET);
191
for (i = 0; i < 100; i++) {
192
if ((r = (n2k_inb(EN0_ISR) & ENISR_RESET)) != 0)
194
PRINTK("got %x in reset\n", r);
197
n2k_outb(ENISR_RESET, EN0_ISR); /* Ack intr. */
200
printf("pcnet_reset_8390() did not complete.\n");
201
} /* pcnet_reset_8390 */
203
int get_prom(u8* mac_addr, u8* base_addr)
208
u_char value, offset;
210
{E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
211
{0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */
212
{0x00, EN0_RCNTLO}, /* Clear the count regs. */
214
{0x00, EN0_IMR}, /* Mask completion irq. */
216
{E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
217
{E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
220
{0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
222
{E8390_RREAD+E8390_START, E8390_CMD},
225
PRINTK ("trying to get MAC via prom reading\n");
227
pcnet_reset_8390 (base_addr);
231
for (i = 0; i < ARRAY_SIZE(program_seq); i++)
232
n2k_outb (program_seq[i].value, program_seq[i].offset);
235
for (i = 0; i < 32; i++) {
236
prom[i] = n2k_inb (PCNET_DATAPORT);
237
PRINTK (" %02x", prom[i]);
240
for (i = 0; i < NR_INFO; i++) {
241
if ((prom[0] == hw_info[i].a0) &&
242
(prom[2] == hw_info[i].a1) &&
243
(prom[4] == hw_info[i].a2)) {
244
PRINTK ("matched board %d\n", i);
248
if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) {
249
PRINTK ("on exit i is %d/%ld\n", i, NR_INFO);
250
PRINTK ("MAC address is ");
251
for (j = 0; j < 6; j++) {
252
mac_addr[j] = prom[j << 1];
253
PRINTK ("%02x:", mac_addr[i]);
256
return (i < NR_INFO) ? i : 0;