if_ed_novell.c revision 330897
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2005, M. Warner Losh
5 * All rights reserved.
6 * Copyright (c) 1995, David Greenman
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice unmodified, this list of conditions, and the following
14 *    disclaimer.
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.
18 *
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
29 * SUCH DAMAGE.
30 */
31
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: stable/11/sys/dev/ed/if_ed_novell.c 330897 2018-03-14 03:19:51Z eadler $");
35
36#include "opt_ed.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/sockio.h>
41#include <sys/mbuf.h>
42#include <sys/kernel.h>
43#include <sys/socket.h>
44#include <sys/syslog.h>
45
46#include <sys/bus.h>
47
48#include <machine/bus.h>
49#include <sys/rman.h>
50#include <machine/resource.h>
51
52#include <net/ethernet.h>
53#include <net/if.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>
58
59#include <net/bpf.h>
60
61#include <dev/ed/if_edreg.h>
62#include <dev/ed/if_edvar.h>
63
64static int ed_probe_gwether(device_t);
65
66/*
67 * Probe and vendor-specific initialization routine for NE1000/2000 boards
68 */
69int
70ed_probe_Novell_generic(device_t dev, int flags)
71{
72	struct ed_softc *sc = device_get_softc(dev);
73	u_int   memsize;
74	int	error;
75	u_char  tmp;
76	static char test_pattern[32] = "THIS is A memory TEST pattern";
77	char    test_buffer[32];
78
79	/* Reset the board */
80	if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) {
81		ed_asic_outb(sc, ED_NOVELL_RESET, 0);
82		DELAY(200);
83	}
84	tmp = ed_asic_inb(sc, ED_NOVELL_RESET);
85
86	/*
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
89	 * tested. -DG
90	 */
91	ed_asic_outb(sc, ED_NOVELL_RESET, tmp);
92	DELAY(5000);
93
94	/*
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
98	 * judgement. -DLG
99	 */
100	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
101	DELAY(5000);
102
103	/* Make sure that we really have an 8390 based board */
104	if (!ed_probe_generic8390(sc))
105		return (ENXIO);
106
107	sc->vendor = ED_VENDOR_NOVELL;
108	sc->mem_shared = 0;
109	sc->cr_proto = ED_CR_RD2;
110
111	/*
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.
114	 */
115
116	/*
117	 * This prevents packets from being stored in the NIC memory when the
118	 * readmem routine turns on the start bit in the CR.
119	 */
120	ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON);
121
122	/* Temporarily initialize DCR for byte operations */
123	ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
124
125	ed_nic_outb(sc, ED_P0_PSTART, 8192 / ED_PAGE_SIZE);
126	ed_nic_outb(sc, ED_P0_PSTOP, 16384 / ED_PAGE_SIZE);
127
128	/*
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.
132	 */
133	if (flags & ED_FLAGS_FORCE_8BIT_MODE) {
134		sc->isa16bit = 0;
135		sc->type = ED_TYPE_NE1000;
136		sc->type_str = "NE1000";
137	} else if (flags & ED_FLAGS_FORCE_16BIT_MODE) {
138		sc->isa16bit = 1;
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);
144	} else {
145		/*
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
148		 * is an NE2000.
149		 */
150		ed_pio_writemem(sc, test_pattern, 8192, sizeof(test_pattern));
151		ed_pio_readmem(sc, 8192, test_buffer, sizeof(test_pattern));
152
153		if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {
154			sc->type = ED_TYPE_NE1000;
155			sc->type_str = "NE1000";
156			sc->isa16bit = 0;
157		} else {
158			/* Not an NE1000 - try NE2000 */
159			sc->isa16bit = 1;
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);
163			/*
164			 * Write a test pattern in word mode. If this also fails, then
165			 * we don't know what this board is.
166			 */
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";
172			} else {
173				return (ENXIO);
174			}
175		}
176	}
177	sc->chip_type = ED_CHIP_TYPE_DP8390;
178
179	/* 8k of memory plus an additional 8k if 16bit */
180	memsize = 8192 + sc->isa16bit * 8192;
181	sc->mem_size = memsize;
182
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;
188
189	if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) {
190		error = ed_probe_gwether(dev);
191		if (error)
192			return (error);
193	}
194
195	/*
196	 * Use one xmit buffer if < 16k, two buffers otherwise (if not told
197	 * otherwise).
198	 */
199	if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING))
200		sc->txb_cnt = 1;
201	else
202		sc->txb_cnt = 2;
203
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;
206
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);
210
211	sc->sc_write_mbufs = ed_pio_write_mbufs;
212	return (0);
213}
214
215int
216ed_probe_Novell(device_t dev, int port_rid, int flags)
217{
218	struct ed_softc *sc = device_get_softc(dev);
219	int	error;
220
221	error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS);
222	if (error)
223		return (error);
224
225	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
226	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
227
228	return ed_probe_Novell_generic(dev, flags);
229}
230
231static int
232ed_probe_gwether(device_t dev)
233{
234	int     x, i, msize = 0;
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);
238
239	for (i = 0; i < ED_PAGE_SIZE; i++)
240		pbuf0[i] = 0;
241
242	/* Clear all the memory. */
243	for (x = 1; x < 256; x++)
244		ed_pio_writemem(sc, pbuf0, x * 256, ED_PAGE_SIZE);
245
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++)
251				pbuf[i] = 255 - x;
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;
257				break;
258			}
259		}
260	}
261	if (mstart == 0) {
262		device_printf(dev, "Cannot find start of RAM.\n");
263		return (ENXIO);
264	}
265
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++)
271				pbuf[i] = 255 - x;
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;
276			else {
277				break;
278			}
279		} else {
280			break;
281		}
282	}
283
284	if (msize == 0) {
285		device_printf(dev,
286		    "Cannot find any RAM, start : %d, x = %d.\n",
287		    (int)mstart, x);
288		return (ENXIO);
289	}
290	if (bootverbose)
291		device_printf(dev,
292		    "RAM start at %d, size : %d.\n", (int)mstart, msize);
293
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;
298	return 0;
299}
300
301void
302ed_Novell_read_mac(struct ed_softc *sc)
303{
304	int n;
305	uint8_t romdata[16];
306
307	/*
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.
312	 */
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)];
316}
317