Deleted Added
full compact
if_ed_novell.c (147256) if_ed_novell.c (149558)
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>
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: head/sys/dev/ed/if_ed_novell.c 147256 2005-06-10 16:49:24Z brooks $");
32__FBSDID("$FreeBSD: head/sys/dev/ed/if_ed_novell.c 149558 2005-08-28 23:56:25Z imp $");
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
62static int ed_probe_gwether(device_t);
63
64/*
65 * Probe and vendor-specific initialization routine for NE1000/2000 boards
66 */
67static int
68ed_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 [note that an outb(0x84, 0) seems to work here, and is
88 * non-invasive...but some boards don't seem to reset and I don't have
89 * complete documentation on what the 'right' thing to do is...so we
90 * do the invasive thing for now. Yuck.]
91 */
92 ed_asic_outb(sc, ED_NOVELL_RESET, tmp);
93 DELAY(5000);
94
95 /*
96 * This is needed because some NE clones apparently don't reset the
97 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
98 * - this makes the probe invasive! ...Done against my better
99 * judgement. -DLG
100 */
101 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
102 DELAY(5000);
103
104 /* Make sure that we really have an 8390 based board */
105 if (!ed_probe_generic8390(sc))
106 return (ENXIO);
107
108 sc->vendor = ED_VENDOR_NOVELL;
109 sc->mem_shared = 0;
110 sc->cr_proto = ED_CR_RD2;
111
112 /*
113 * Test the ability to read and write to the NIC memory. This has the
114 * side affect of determining if this is an NE1000 or an NE2000.
115 */
116
117 /*
118 * This prevents packets from being stored in the NIC memory when the
119 * readmem routine turns on the start bit in the CR.
120 */
121 ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON);
122
123 /* Temporarily initialize DCR for byte operations */
124 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
125
126 ed_nic_outb(sc, ED_P0_PSTART, 8192 / ED_PAGE_SIZE);
127 ed_nic_outb(sc, ED_P0_PSTOP, 16384 / ED_PAGE_SIZE);
128
129 sc->isa16bit = 0;
130
131 /*
132 * Write a test pattern in byte mode. If this fails, then there
133 * probably isn't any memory at 8k - which likely means that the board
134 * is an NE2000.
135 */
136 ed_pio_writemem(sc, test_pattern, 8192, sizeof(test_pattern));
137 ed_pio_readmem(sc, 8192, test_buffer, sizeof(test_pattern));
138
139 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {
140 sc->type = ED_TYPE_NE1000;
141 sc->type_str = "NE1000";
142 } else {
143
144 /* Not an NE1000 - try NE2000 */
145 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
146 ed_nic_outb(sc, ED_P0_PSTART, 16384 / ED_PAGE_SIZE);
147 ed_nic_outb(sc, ED_P0_PSTOP, 32768 / ED_PAGE_SIZE);
148
149 sc->isa16bit = 1;
150
151 /*
152 * Write a test pattern in word mode. If this also fails, then
153 * we don't know what this board is.
154 */
155 ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern));
156 ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern));
157 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {
158 sc->type = ED_TYPE_NE2000;
159 sc->type_str = "NE2000";
160 } else {
161 return (ENXIO);
162 }
163 }
164 sc->chip_type = ED_CHIP_TYPE_DP8390;
165
166 /* 8k of memory plus an additional 8k if 16bit */
167 memsize = 8192 + sc->isa16bit * 8192;
168 sc->mem_size = memsize;
169
170 /* NIC memory doesn't start at zero on an NE board */
171 /* The start address is tied to the bus width */
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
62static int ed_probe_gwether(device_t);
63
64/*
65 * Probe and vendor-specific initialization routine for NE1000/2000 boards
66 */
67static int
68ed_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 [note that an outb(0x84, 0) seems to work here, and is
88 * non-invasive...but some boards don't seem to reset and I don't have
89 * complete documentation on what the 'right' thing to do is...so we
90 * do the invasive thing for now. Yuck.]
91 */
92 ed_asic_outb(sc, ED_NOVELL_RESET, tmp);
93 DELAY(5000);
94
95 /*
96 * This is needed because some NE clones apparently don't reset the
97 * NIC properly (or the NIC chip doesn't reset fully on power-up) XXX
98 * - this makes the probe invasive! ...Done against my better
99 * judgement. -DLG
100 */
101 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
102 DELAY(5000);
103
104 /* Make sure that we really have an 8390 based board */
105 if (!ed_probe_generic8390(sc))
106 return (ENXIO);
107
108 sc->vendor = ED_VENDOR_NOVELL;
109 sc->mem_shared = 0;
110 sc->cr_proto = ED_CR_RD2;
111
112 /*
113 * Test the ability to read and write to the NIC memory. This has the
114 * side affect of determining if this is an NE1000 or an NE2000.
115 */
116
117 /*
118 * This prevents packets from being stored in the NIC memory when the
119 * readmem routine turns on the start bit in the CR.
120 */
121 ed_nic_outb(sc, ED_P0_RCR, ED_RCR_MON);
122
123 /* Temporarily initialize DCR for byte operations */
124 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
125
126 ed_nic_outb(sc, ED_P0_PSTART, 8192 / ED_PAGE_SIZE);
127 ed_nic_outb(sc, ED_P0_PSTOP, 16384 / ED_PAGE_SIZE);
128
129 sc->isa16bit = 0;
130
131 /*
132 * Write a test pattern in byte mode. If this fails, then there
133 * probably isn't any memory at 8k - which likely means that the board
134 * is an NE2000.
135 */
136 ed_pio_writemem(sc, test_pattern, 8192, sizeof(test_pattern));
137 ed_pio_readmem(sc, 8192, test_buffer, sizeof(test_pattern));
138
139 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {
140 sc->type = ED_TYPE_NE1000;
141 sc->type_str = "NE1000";
142 } else {
143
144 /* Not an NE1000 - try NE2000 */
145 ed_nic_outb(sc, ED_P0_DCR, ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
146 ed_nic_outb(sc, ED_P0_PSTART, 16384 / ED_PAGE_SIZE);
147 ed_nic_outb(sc, ED_P0_PSTOP, 32768 / ED_PAGE_SIZE);
148
149 sc->isa16bit = 1;
150
151 /*
152 * Write a test pattern in word mode. If this also fails, then
153 * we don't know what this board is.
154 */
155 ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern));
156 ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern));
157 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) {
158 sc->type = ED_TYPE_NE2000;
159 sc->type_str = "NE2000";
160 } else {
161 return (ENXIO);
162 }
163 }
164 sc->chip_type = ED_CHIP_TYPE_DP8390;
165
166 /* 8k of memory plus an additional 8k if 16bit */
167 memsize = 8192 + sc->isa16bit * 8192;
168 sc->mem_size = memsize;
169
170 /* NIC memory doesn't start at zero on an NE board */
171 /* The start address is tied to the bus width */
172 sc->mem_start = (char *) 8192 + sc->isa16bit * 8192;
172 sc->mem_start = 8192 + sc->isa16bit * 8192;
173 sc->mem_end = sc->mem_start + memsize;
174 sc->tx_page_start = memsize / ED_PAGE_SIZE;
175
176 if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) {
177 error = ed_probe_gwether(dev);
178 if (error)
179 return (error);
180 }
181
182 /*
183 * Use one xmit buffer if < 16k, two buffers otherwise (if not told
184 * otherwise).
185 */
186 if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING))
187 sc->txb_cnt = 1;
188 else
189 sc->txb_cnt = 2;
190
191 sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
192 sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE;
193
194 sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
195 /* clear any pending interrupts that might have occurred above */
196 ed_nic_outb(sc, ED_P0_ISR, 0xff);
197
198 return (0);
199}
200
201int
202ed_probe_Novell(device_t dev, int port_rid, int flags)
203{
204 struct ed_softc *sc = device_get_softc(dev);
205 int error;
206
207 error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS);
208 if (error)
209 return (error);
210
211 sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
212 sc->nic_offset = ED_NOVELL_NIC_OFFSET;
213
214 return ed_probe_Novell_generic(dev, flags);
215}
216
217static int
218ed_probe_gwether(device_t dev)
219{
220 int x, i, msize = 0;
173 sc->mem_end = sc->mem_start + memsize;
174 sc->tx_page_start = memsize / ED_PAGE_SIZE;
175
176 if (ED_FLAGS_GETTYPE(flags) == ED_FLAGS_GWETHER) {
177 error = ed_probe_gwether(dev);
178 if (error)
179 return (error);
180 }
181
182 /*
183 * Use one xmit buffer if < 16k, two buffers otherwise (if not told
184 * otherwise).
185 */
186 if ((memsize < 16384) || (flags & ED_FLAGS_NO_MULTI_BUFFERING))
187 sc->txb_cnt = 1;
188 else
189 sc->txb_cnt = 2;
190
191 sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
192 sc->rec_page_stop = sc->tx_page_start + memsize / ED_PAGE_SIZE;
193
194 sc->mem_ring = sc->mem_start + sc->txb_cnt * ED_PAGE_SIZE * ED_TXBUF_SIZE;
195 /* clear any pending interrupts that might have occurred above */
196 ed_nic_outb(sc, ED_P0_ISR, 0xff);
197
198 return (0);
199}
200
201int
202ed_probe_Novell(device_t dev, int port_rid, int flags)
203{
204 struct ed_softc *sc = device_get_softc(dev);
205 int error;
206
207 error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS);
208 if (error)
209 return (error);
210
211 sc->asic_offset = ED_NOVELL_ASIC_OFFSET;
212 sc->nic_offset = ED_NOVELL_NIC_OFFSET;
213
214 return ed_probe_Novell_generic(dev, flags);
215}
216
217static int
218ed_probe_gwether(device_t dev)
219{
220 int x, i, msize = 0;
221 long mstart = 0;
221 bus_size_t mstart = 0;
222 char pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE], tbuf[ED_PAGE_SIZE];
223 struct ed_softc *sc = device_get_softc(dev);
224
225 for (i = 0; i < ED_PAGE_SIZE; i++)
226 pbuf0[i] = 0;
227
228 /* Clear all the memory. */
229 for (x = 1; x < 256; x++)
230 ed_pio_writemem(sc, pbuf0, x * 256, ED_PAGE_SIZE);
231
232 /* Search for the start of RAM. */
233 for (x = 1; x < 256; x++) {
234 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
235 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
236 for (i = 0; i < ED_PAGE_SIZE; i++)
237 pbuf[i] = 255 - x;
238 ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE);
239 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
240 if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) {
241 mstart = x * ED_PAGE_SIZE;
242 msize = ED_PAGE_SIZE;
243 break;
244 }
245 }
246 }
247 if (mstart == 0) {
248 device_printf(dev, "Cannot find start of RAM.\n");
249 return (ENXIO);
250 }
251
252 /* Probe the size of RAM. */
253 for (x = (mstart / ED_PAGE_SIZE) + 1; x < 256; x++) {
254 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
255 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
256 for (i = 0; i < ED_PAGE_SIZE; i++)
257 pbuf[i] = 255 - x;
258 ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE);
259 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
260 if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0)
261 msize += ED_PAGE_SIZE;
262 else {
263 break;
264 }
265 } else {
266 break;
267 }
268 }
269
270 if (msize == 0) {
271 device_printf(dev,
222 char pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE], tbuf[ED_PAGE_SIZE];
223 struct ed_softc *sc = device_get_softc(dev);
224
225 for (i = 0; i < ED_PAGE_SIZE; i++)
226 pbuf0[i] = 0;
227
228 /* Clear all the memory. */
229 for (x = 1; x < 256; x++)
230 ed_pio_writemem(sc, pbuf0, x * 256, ED_PAGE_SIZE);
231
232 /* Search for the start of RAM. */
233 for (x = 1; x < 256; x++) {
234 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
235 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
236 for (i = 0; i < ED_PAGE_SIZE; i++)
237 pbuf[i] = 255 - x;
238 ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE);
239 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
240 if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) {
241 mstart = x * ED_PAGE_SIZE;
242 msize = ED_PAGE_SIZE;
243 break;
244 }
245 }
246 }
247 if (mstart == 0) {
248 device_printf(dev, "Cannot find start of RAM.\n");
249 return (ENXIO);
250 }
251
252 /* Probe the size of RAM. */
253 for (x = (mstart / ED_PAGE_SIZE) + 1; x < 256; x++) {
254 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
255 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) {
256 for (i = 0; i < ED_PAGE_SIZE; i++)
257 pbuf[i] = 255 - x;
258 ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE);
259 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE);
260 if (bcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0)
261 msize += ED_PAGE_SIZE;
262 else {
263 break;
264 }
265 } else {
266 break;
267 }
268 }
269
270 if (msize == 0) {
271 device_printf(dev,
272 "Cannot find any RAM, start : %ld, x = %d.\n", mstart, x);
272 "Cannot find any RAM, start : %d, x = %d.\n",
273 (int)mstart, x);
273 return (ENXIO);
274 }
274 return (ENXIO);
275 }
275 device_printf(dev, "RAM start at %ld, size : %d.\n", mstart, msize);
276 if (bootverbose)
277 device_printf(dev,
278 "RAM start at %d, size : %d.\n", (int)mstart, msize);
276
277 sc->mem_size = msize;
279
280 sc->mem_size = msize;
278 sc->mem_start = (caddr_t)(uintptr_t) mstart;
279 sc->mem_end = (caddr_t)(uintptr_t) (msize + mstart);
281 sc->mem_start = mstart;
282 sc->mem_end = msize + mstart;
280 sc->tx_page_start = mstart / ED_PAGE_SIZE;
281 return 0;
282}
283
284void
285ed_Novell_read_mac(struct ed_softc *sc)
286{
287 int n;
288 uint8_t romdata[16];
289
290 /*
291 * Pull the MAC address out of the roms that are on the isa
292 * version of these cards.
293 */
294 ed_pio_readmem(sc, 0, romdata, 16);
295 for (n = 0; n < ETHER_ADDR_LEN; n++)
296 sc->enaddr[n] = romdata[n * (sc->isa16bit + 1)];
297}
283 sc->tx_page_start = mstart / ED_PAGE_SIZE;
284 return 0;
285}
286
287void
288ed_Novell_read_mac(struct ed_softc *sc)
289{
290 int n;
291 uint8_t romdata[16];
292
293 /*
294 * Pull the MAC address out of the roms that are on the isa
295 * version of these cards.
296 */
297 ed_pio_readmem(sc, 0, romdata, 16);
298 for (n = 0; n < ETHER_ADDR_LEN; n++)
299 sc->enaddr[n] = romdata[n * (sc->isa16bit + 1)];
300}