2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2005, M. Warner Losh
6 * Copyright (c) 1995, David Greenman
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice unmodified, this list of conditions, and the following
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/sockio.h>
42 #include <sys/kernel.h>
43 #include <sys/socket.h>
44 #include <sys/syslog.h>
48 #include <machine/bus.h>
50 #include <machine/resource.h>
52 #include <net/ethernet.h>
54 #include <net/if_arp.h>
55 #include <net/if_dl.h>
56 #include <net/if_mib.h>
57 #include <net/if_media.h>
61 #include <dev/ed/if_edreg.h>
62 #include <dev/ed/if_edvar.h>
64 static int ed_probe_gwether(device_t);
67 * Probe and vendor-specific initialization routine for NE1000/2000 boards
70 ed_probe_Novell_generic(device_t dev, int flags)
72 struct ed_softc *sc = device_get_softc(dev);
76 static char test_pattern[32] = "THIS is A memory TEST pattern";
80 if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) {
81 ed_asic_outb(sc, ED_NOVELL_RESET, 0);
84 tmp = ed_asic_inb(sc, ED_NOVELL_RESET);
87 * I don't know if this is necessary; probably cruft leftover from
88 * Clarkson packet driver code. Doesn't do a thing on the boards I've
91 ed_asic_outb(sc, ED_NOVELL_RESET, tmp);
95 * This is needed because some NE clones apparently don't reset the
96 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
97 * - this makes the probe invasive! ...Done against my better
100 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
103 /* Make sure that we really have an 8390 based board */
104 if (!ed_probe_generic8390(sc))
107 sc->vendor = ED_VENDOR_NOVELL;
109 sc->cr_proto = ED_CR_RD2;
112 * Test the ability to read and write to the NIC memory. This has the
113 * side affect of determining if this is an NE1000 or an NE2000.
117 * This prevents packets from being stored in the NIC memory when the
118 * readmem routine turns on the start bit in the CR.
120 ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON);
122 /* Temporarily initialize DCR for byte operations */
123 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
125 ed_nic_outb(sc, ED_P0_PSTART, 8192 / ED_PAGE_SIZE);
126 ed_nic_outb(sc, ED_P0_PSTOP, 16384 / ED_PAGE_SIZE);
129 * Some devices identify themselves. Some of those devices
130 * can't handle being probed, so we allow forcing a mode. If
131 * these flags are set, force it, otherwise probe.
133 if (flags & ED_FLAGS_FORCE_8BIT_MODE) {
135 sc->type = ED_TYPE_NE1000;
136 sc->type_str = "NE1000";
137 } else if (flags & ED_FLAGS_FORCE_16BIT_MODE) {
139 sc->type = ED_TYPE_NE2000;
140 sc->type_str = "NE2000";
141 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
142 ed_nic_outb(sc, ED_P0_PSTART, 16384 / ED_PAGE_SIZE);
143 ed_nic_outb(sc, ED_P0_PSTOP, 32768 / ED_PAGE_SIZE);
146 * Write a test pattern in byte mode. If this fails, then there
147 * probably isn't any memory at 8k - which likely means that the board
150 ed_pio_writemem(sc, test_pattern, 8192, sizeof(test_pattern));
151 ed_pio_readmem(sc, 8192, test_buffer, sizeof(test_pattern));
153 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {
154 sc->type = ED_TYPE_NE1000;
155 sc->type_str = "NE1000";
158 /* Not an NE1000 - try NE2000 */
160 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
161 ed_nic_outb(sc, ED_P0_PSTART, 16384 / ED_PAGE_SIZE);
162 ed_nic_outb(sc, ED_P0_PSTOP, 32768 / ED_PAGE_SIZE);
164 * Write a test pattern in word mode. If this also fails, then
165 * we don't know what this board is.
167 ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern));
168 ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern));
169 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {
170 sc->type = ED_TYPE_NE2000;
171 sc->type_str = "NE2000";
177 sc->chip_type = ED_CHIP_TYPE_DP8390;
179 /* 8k of memory plus an additional 8k if 16bit */
180 memsize = 8192 + sc->isa16bit * 8192;
181 sc->mem_size = memsize;
183 /* NIC memory doesn't start at zero on an NE board */
184 /* The start address is tied to the bus width */
185 sc->mem_start = 8192 + sc->isa16bit * 8192;
186 sc->mem_end = sc->mem_start + memsize;
187 sc->tx_page_start = memsize / ED_PAGE_SIZE;
189 if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) {
190 error = ed_probe_gwether(dev);
196 * Use one xmit buffer if < 16k, two buffers otherwise (if not told
199 if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING))
204 sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
205 sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE;
207 sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
208 /* clear any pending interrupts that might have occurred above */
209 ed_nic_outb(sc, ED_P0_ISR, 0xff);
211 sc->sc_write_mbufs = ed_pio_write_mbufs;
216 ed_probe_Novell(device_t dev, int port_rid, int flags)
218 struct ed_softc *sc = device_get_softc(dev);
221 error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS);
225 sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
226 sc->nic_offset = ED_NOVELL_NIC_OFFSET;
228 return ed_probe_Novell_generic(dev, flags);
232 ed_probe_gwether(device_t dev)
235 bus_size_t mstart = 0;
236 char pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE], tbuf[ED_PAGE_SIZE];
237 struct ed_softc *sc = device_get_softc(dev);
239 for (i = 0; i < ED_PAGE_SIZE; i++)
242 /* Clear all the memory. */
243 for (x = 1; x < 256; x++)
244 ed_pio_writemem(sc, pbuf0, x * 256, ED_PAGE_SIZE);
246 /* Search for the start of RAM. */
247 for (x = 1; x < 256; x++) {
248 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
249 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
250 for (i = 0; i < ED_PAGE_SIZE; i++)
252 ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE);
253 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
254 if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) {
255 mstart = x * ED_PAGE_SIZE;
256 msize = ED_PAGE_SIZE;
262 device_printf(dev, "Cannot find start of RAM.\n");
266 /* Probe the size of RAM. */
267 for (x = (mstart / ED_PAGE_SIZE) + 1; x < 256; x++) {
268 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
269 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
270 for (i = 0; i < ED_PAGE_SIZE; i++)
272 ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE);
273 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
274 if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0)
275 msize += ED_PAGE_SIZE;
286 "Cannot find any RAM, start : %d, x = %d.\n",
292 "RAM start at %d, size : %d.\n", (int)mstart, msize);
294 sc->mem_size = msize;
295 sc->mem_start = mstart;
296 sc->mem_end = msize + mstart;
297 sc->tx_page_start = mstart / ED_PAGE_SIZE;
302 ed_Novell_read_mac(struct ed_softc *sc)
308 * Most ne1000/ne2000 compatible cards have their MAC address
309 * located in the first few words of the address space. This seems
310 * universally true for ISA and PCI implementations, but PC Card
311 * devices seem to have more variance.
313 ed_pio_readmem(sc, 0, romdata, 16);
314 for (n = 0; n < ETHER_ADDR_LEN; n++)
315 sc->enaddr[n] = romdata[n * (sc->isa16bit + 1)];