xref: /trueos/sys/dev/ed/if_ed_novell.c (revision 8fe640108653f13042f1b15213769e338aa524f6)
1 /*-
2  * Copyright (c) 2005, M. Warner Losh
3  * All rights reserved.
4  * Copyright (c) 1995, David Greenman
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice unmodified, this list of conditions, and the following
12  *    disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include "opt_ed.h"
35 
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/sockio.h>
39 #include <sys/mbuf.h>
40 #include <sys/kernel.h>
41 #include <sys/socket.h>
42 #include <sys/syslog.h>
43 
44 #include <sys/bus.h>
45 
46 #include <machine/bus.h>
47 #include <sys/rman.h>
48 #include <machine/resource.h>
49 
50 #include <net/ethernet.h>
51 #include <net/if.h>
52 #include <net/if_arp.h>
53 #include <net/if_dl.h>
54 #include <net/if_mib.h>
55 #include <net/if_media.h>
56 
57 #include <net/bpf.h>
58 
59 #include <dev/ed/if_edreg.h>
60 #include <dev/ed/if_edvar.h>
61 
62 static int ed_probe_gwether(device_t);
63 
64 /*
65  * Probe and vendor-specific initialization routine for NE1000/2000 boards
66  */
67 int
ed_probe_Novell_generic(device_t dev,int flags)68 ed_probe_Novell_generic(device_t dev, int flags)
69 {
70 	struct ed_softc *sc = device_get_softc(dev);
71 	u_int   memsize;
72 	int	error;
73 	u_char  tmp;
74 	static char test_pattern[32] = "THIS is A memory TEST pattern";
75 	char    test_buffer[32];
76 
77 	/* Reset the board */
78 	if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) {
79 		ed_asic_outb(sc, ED_NOVELL_RESET, 0);
80 		DELAY(200);
81 	}
82 	tmp = ed_asic_inb(sc, ED_NOVELL_RESET);
83 
84 	/*
85 	 * I don't know if this is necessary; probably cruft leftover from
86 	 * Clarkson packet driver code. Doesn't do a thing on the boards I've
87 	 * tested. -DG
88 	 */
89 	ed_asic_outb(sc, ED_NOVELL_RESET, tmp);
90 	DELAY(5000);
91 
92 	/*
93 	 * This is needed because some NE clones apparently don't reset the
94 	 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
95 	 * - this makes the probe invasive! ...Done against my better
96 	 * judgement. -DLG
97 	 */
98 	ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
99 	DELAY(5000);
100 
101 	/* Make sure that we really have an 8390 based board */
102 	if (!ed_probe_generic8390(sc))
103 		return (ENXIO);
104 
105 	sc->vendor = ED_VENDOR_NOVELL;
106 	sc->mem_shared = 0;
107 	sc->cr_proto = ED_CR_RD2;
108 
109 	/*
110 	 * Test the ability to read and write to the NIC memory. This has the
111 	 * side affect of determining if this is an NE1000 or an NE2000.
112 	 */
113 
114 	/*
115 	 * This prevents packets from being stored in the NIC memory when the
116 	 * readmem routine turns on the start bit in the CR.
117 	 */
118 	ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON);
119 
120 	/* Temporarily initialize DCR for byte operations */
121 	ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
122 
123 	ed_nic_outb(sc, ED_P0_PSTART, 8192 / ED_PAGE_SIZE);
124 	ed_nic_outb(sc, ED_P0_PSTOP, 16384 / ED_PAGE_SIZE);
125 
126 	/*
127 	 * Some devices identify themselves.  Some of those devices
128 	 * can't handle being probed, so we allow forcing a mode.  If
129 	 * these flags are set, force it, otherwise probe.
130 	 */
131 	if (flags & ED_FLAGS_FORCE_8BIT_MODE) {
132 		sc->isa16bit = 0;
133 		sc->type = ED_TYPE_NE1000;
134 		sc->type_str = "NE1000";
135 	} else if (flags & ED_FLAGS_FORCE_16BIT_MODE) {
136 		sc->isa16bit = 1;
137 		sc->type = ED_TYPE_NE2000;
138 		sc->type_str = "NE2000";
139 		ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
140 		ed_nic_outb(sc, ED_P0_PSTART, 16384 / ED_PAGE_SIZE);
141 		ed_nic_outb(sc, ED_P0_PSTOP, 32768 / ED_PAGE_SIZE);
142 	} else {
143 		/*
144 		 * Write a test pattern in byte mode. If this fails, then there
145 		 * probably isn't any memory at 8k - which likely means that the board
146 		 * is an NE2000.
147 		 */
148 		ed_pio_writemem(sc, test_pattern, 8192, sizeof(test_pattern));
149 		ed_pio_readmem(sc, 8192, test_buffer, sizeof(test_pattern));
150 
151 		if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {
152 			sc->type = ED_TYPE_NE1000;
153 			sc->type_str = "NE1000";
154 			sc->isa16bit = 0;
155 		} else {
156 			/* Not an NE1000 - try NE2000 */
157 			sc->isa16bit = 1;
158 			ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
159 			ed_nic_outb(sc, ED_P0_PSTART, 16384 / ED_PAGE_SIZE);
160 			ed_nic_outb(sc, ED_P0_PSTOP, 32768 / ED_PAGE_SIZE);
161 			/*
162 			 * Write a test pattern in word mode. If this also fails, then
163 			 * we don't know what this board is.
164 			 */
165 			ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern));
166 			ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern));
167 			if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {
168 				sc->type = ED_TYPE_NE2000;
169 				sc->type_str = "NE2000";
170 			} else {
171 				return (ENXIO);
172 			}
173 		}
174 	}
175 	sc->chip_type = ED_CHIP_TYPE_DP8390;
176 
177 	/* 8k of memory plus an additional 8k if 16bit */
178 	memsize = 8192 + sc->isa16bit * 8192;
179 	sc->mem_size = memsize;
180 
181 	/* NIC memory doesn't start at zero on an NE board */
182 	/* The start address is tied to the bus width */
183 	sc->mem_start = 8192 + sc->isa16bit * 8192;
184 	sc->mem_end = sc->mem_start + memsize;
185 	sc->tx_page_start = memsize / ED_PAGE_SIZE;
186 
187 	if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) {
188 		error = ed_probe_gwether(dev);
189 		if (error)
190 			return (error);
191 	}
192 
193 	/*
194 	 * Use one xmit buffer if < 16k, two buffers otherwise (if not told
195 	 * otherwise).
196 	 */
197 	if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING))
198 		sc->txb_cnt = 1;
199 	else
200 		sc->txb_cnt = 2;
201 
202 	sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
203 	sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE;
204 
205 	sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
206 	/* clear any pending interrupts that might have occurred above */
207 	ed_nic_outb(sc, ED_P0_ISR, 0xff);
208 
209 	sc->sc_write_mbufs = ed_pio_write_mbufs;
210 	return (0);
211 }
212 
213 int
ed_probe_Novell(device_t dev,int port_rid,int flags)214 ed_probe_Novell(device_t dev, int port_rid, int flags)
215 {
216 	struct ed_softc *sc = device_get_softc(dev);
217 	int	error;
218 
219 	error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS);
220 	if (error)
221 		return (error);
222 
223 	sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
224 	sc->nic_offset  = ED_NOVELL_NIC_OFFSET;
225 
226 	return ed_probe_Novell_generic(dev, flags);
227 }
228 
229 static int
ed_probe_gwether(device_t dev)230 ed_probe_gwether(device_t dev)
231 {
232 	int     x, i, msize = 0;
233 	bus_size_t mstart = 0;
234 	char    pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE], tbuf[ED_PAGE_SIZE];
235 	struct ed_softc *sc = device_get_softc(dev);
236 
237 	for (i = 0; i < ED_PAGE_SIZE; i++)
238 		pbuf0[i] = 0;
239 
240 	/* Clear all the memory. */
241 	for (x = 1; x < 256; x++)
242 		ed_pio_writemem(sc, pbuf0, x * 256, ED_PAGE_SIZE);
243 
244 	/* Search for the start of RAM. */
245 	for (x = 1; x < 256; x++) {
246 		ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
247 		if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
248 			for (i = 0; i < ED_PAGE_SIZE; i++)
249 				pbuf[i] = 255 - x;
250 			ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE);
251 			ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
252 			if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) {
253 				mstart = x * ED_PAGE_SIZE;
254 				msize = ED_PAGE_SIZE;
255 				break;
256 			}
257 		}
258 	}
259 	if (mstart == 0) {
260 		device_printf(dev, "Cannot find start of RAM.\n");
261 		return (ENXIO);
262 	}
263 
264 	/* Probe the size of RAM. */
265 	for (x = (mstart / ED_PAGE_SIZE) + 1; x < 256; x++) {
266 		ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
267 		if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
268 			for (i = 0; i < ED_PAGE_SIZE; i++)
269 				pbuf[i] = 255 - x;
270 			ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE);
271 			ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
272 			if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0)
273 				msize += ED_PAGE_SIZE;
274 			else {
275 				break;
276 			}
277 		} else {
278 			break;
279 		}
280 	}
281 
282 	if (msize == 0) {
283 		device_printf(dev,
284 		    "Cannot find any RAM, start : %d, x = %d.\n",
285 		    (int)mstart, x);
286 		return (ENXIO);
287 	}
288 	if (bootverbose)
289 		device_printf(dev,
290 		    "RAM start at %d, size : %d.\n", (int)mstart, msize);
291 
292 	sc->mem_size = msize;
293 	sc->mem_start = mstart;
294 	sc->mem_end = msize + mstart;
295 	sc->tx_page_start = mstart / ED_PAGE_SIZE;
296 	return 0;
297 }
298 
299 void
ed_Novell_read_mac(struct ed_softc * sc)300 ed_Novell_read_mac(struct ed_softc *sc)
301 {
302 	int n;
303 	uint8_t romdata[16];
304 
305 	/*
306 	 * Most ne1000/ne2000 compatible cards have their MAC address
307 	 * located in the first few words of the address space.  This seems
308 	 * universally true for ISA and PCI implementations, but PC Card
309 	 * devices seem to have more variance.
310 	 */
311 	ed_pio_readmem(sc, 0, romdata, 16);
312 	for (n = 0; n < ETHER_ADDR_LEN; n++)
313 		sc->enaddr[n] = romdata[n * (sc->isa16bit + 1)];
314 }
315