Deleted Added
full compact
if_ed_3c503.c (147256) if_ed_3c503.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#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#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/ed/if_ed_3c503.c 147256 2005-06-10 16:49:24Z brooks $");
31__FBSDID("$FreeBSD: head/sys/dev/ed/if_ed_3c503.c 149558 2005-08-28 23:56:25Z imp $");
32
33#include "opt_ed.h"
34
35#ifdef ED_3C503
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/sockio.h>
40#include <sys/mbuf.h>
41#include <sys/kernel.h>
42#include <sys/socket.h>
43#include <sys/syslog.h>
44
45#include <sys/bus.h>
46
47#include <machine/bus.h>
48#include <sys/rman.h>
49#include <machine/resource.h>
50
51#include <net/ethernet.h>
52#include <net/if.h>
53#include <net/if_arp.h>
54#include <net/if_dl.h>
55#include <net/if_mib.h>
56#include <net/if_media.h>
57
58#include <net/bpf.h>
59
60#include <dev/ed/if_edreg.h>
61#include <dev/ed/if_edvar.h>
62
63/*
64 * Probe and vendor-specific initialization routine for 3Com 3c503 boards
65 */
66int
67ed_probe_3Com(device_t dev, int port_rid, int flags)
68{
69 struct ed_softc *sc = device_get_softc(dev);
70 int error;
71 int i;
72 u_int memsize;
73 u_char isa16bit;
74 u_long conf_maddr, conf_msize, irq, junk, pmem;
75
76 error = ed_alloc_port(dev, 0, ED_3COM_IO_PORTS);
77 if (error)
78 return (error);
79
80 sc->asic_offset = ED_3COM_ASIC_OFFSET;
81 sc->nic_offset = ED_3COM_NIC_OFFSET;
82
83 /*
84 * Verify that the kernel configured I/O address matches the board
85 * configured address
86 */
87 switch (ed_asic_inb(sc, ED_3COM_BCFR)) {
88 case ED_3COM_BCFR_300:
89 if (rman_get_start(sc->port_res) != 0x300)
90 return (ENXIO);
91 break;
92 case ED_3COM_BCFR_310:
93 if (rman_get_start(sc->port_res) != 0x310)
94 return (ENXIO);
95 break;
96 case ED_3COM_BCFR_330:
97 if (rman_get_start(sc->port_res) != 0x330)
98 return (ENXIO);
99 break;
100 case ED_3COM_BCFR_350:
101 if (rman_get_start(sc->port_res) != 0x350)
102 return (ENXIO);
103 break;
104 case ED_3COM_BCFR_250:
105 if (rman_get_start(sc->port_res) != 0x250)
106 return (ENXIO);
107 break;
108 case ED_3COM_BCFR_280:
109 if (rman_get_start(sc->port_res) != 0x280)
110 return (ENXIO);
111 break;
112 case ED_3COM_BCFR_2A0:
113 if (rman_get_start(sc->port_res) != 0x2a0)
114 return (ENXIO);
115 break;
116 case ED_3COM_BCFR_2E0:
117 if (rman_get_start(sc->port_res) != 0x2e0)
118 return (ENXIO);
119 break;
120 default:
121 return (ENXIO);
122 }
123
124 error = bus_get_resource(dev, SYS_RES_MEMORY, 0,
125 &conf_maddr, &conf_msize);
126 if (error)
127 return (error);
128
129 /*
130 * Verify that the kernel shared memory address matches the board
131 * configured address.
132 */
133 switch (ed_asic_inb(sc, ED_3COM_PCFR)) {
134 case ED_3COM_PCFR_DC000:
135 if (conf_maddr != 0xdc000)
136 return (ENXIO);
137 break;
138 case ED_3COM_PCFR_D8000:
139 if (conf_maddr != 0xd8000)
140 return (ENXIO);
141 break;
142 case ED_3COM_PCFR_CC000:
143 if (conf_maddr != 0xcc000)
144 return (ENXIO);
145 break;
146 case ED_3COM_PCFR_C8000:
147 if (conf_maddr != 0xc8000)
148 return (ENXIO);
149 break;
150 default:
151 return (ENXIO);
152 }
153
154
155 /*
156 * Reset NIC and ASIC. Enable on-board transceiver throughout reset
157 * sequence because it'll lock up if the cable isn't connected if we
158 * don't.
159 */
160 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_RST | ED_3COM_CR_XSEL);
161
162 /*
163 * Wait for a while, then un-reset it
164 */
165 DELAY(50);
166
167 /*
168 * The 3Com ASIC defaults to rather strange settings for the CR after
169 * a reset - it's important to set it again after the following outb
170 * (this is done when we map the PROM below).
171 */
172 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL);
173
174 /*
175 * Wait a bit for the NIC to recover from the reset
176 */
177 DELAY(5000);
178
179 sc->vendor = ED_VENDOR_3COM;
180 sc->type_str = "3c503";
181 sc->mem_shared = 1;
182 sc->cr_proto = ED_CR_RD2;
183
184 /*
185 * Hmmm...a 16bit 3Com board has 16k of memory, but only an 8k window
186 * to it.
187 */
188 memsize = 8192;
189
190 /*
191 * Get station address from on-board ROM
192 */
193
194 /*
195 * First, map ethernet address PROM over the top of where the NIC
196 * registers normally appear.
197 */
198 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_EALO | ED_3COM_CR_XSEL);
199
200 for (i = 0; i < ETHER_ADDR_LEN; ++i)
201 sc->enaddr[i] = ed_nic_inb(sc, i);
202
203 /*
204 * Unmap PROM - select NIC registers. The proper setting of the
205 * tranceiver is set in ed_init so that the attach code is given a
206 * chance to set the default based on a compile-time config option
207 */
208 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL);
209
210 /*
211 * Determine if this is an 8bit or 16bit board
212 */
213
214 /*
215 * select page 0 registers
216 */
217 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
218
219 /*
220 * Attempt to clear WTS bit. If it doesn't clear, then this is a 16bit
221 * board.
222 */
223 ed_nic_outb(sc, ED_P0_DCR, 0);
224
225 /*
226 * select page 2 registers
227 */
228 ed_nic_outb(sc, ED_P0_CR, ED_CR_PAGE_2 | ED_CR_RD2 | ED_CR_STP);
229
230 /*
231 * The 3c503 forces the WTS bit to a one if this is a 16bit board
232 */
233 if (ed_nic_inb(sc, ED_P2_DCR) & ED_DCR_WTS)
234 isa16bit = 1;
235 else
236 isa16bit = 0;
237
238 /*
239 * select page 0 registers
240 */
241 ed_nic_outb(sc, ED_P2_CR, ED_CR_RD2 | ED_CR_STP);
242
243 error = ed_alloc_memory(dev, 0, memsize);
244 if (error)
245 return (error);
246
247 pmem = rman_get_start(sc->mem_res);
248 error = ed_isa_mem_ok(dev, pmem, memsize);
249 if (error)
250 return (error);
251
32
33#include "opt_ed.h"
34
35#ifdef ED_3C503
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/sockio.h>
40#include <sys/mbuf.h>
41#include <sys/kernel.h>
42#include <sys/socket.h>
43#include <sys/syslog.h>
44
45#include <sys/bus.h>
46
47#include <machine/bus.h>
48#include <sys/rman.h>
49#include <machine/resource.h>
50
51#include <net/ethernet.h>
52#include <net/if.h>
53#include <net/if_arp.h>
54#include <net/if_dl.h>
55#include <net/if_mib.h>
56#include <net/if_media.h>
57
58#include <net/bpf.h>
59
60#include <dev/ed/if_edreg.h>
61#include <dev/ed/if_edvar.h>
62
63/*
64 * Probe and vendor-specific initialization routine for 3Com 3c503 boards
65 */
66int
67ed_probe_3Com(device_t dev, int port_rid, int flags)
68{
69 struct ed_softc *sc = device_get_softc(dev);
70 int error;
71 int i;
72 u_int memsize;
73 u_char isa16bit;
74 u_long conf_maddr, conf_msize, irq, junk, pmem;
75
76 error = ed_alloc_port(dev, 0, ED_3COM_IO_PORTS);
77 if (error)
78 return (error);
79
80 sc->asic_offset = ED_3COM_ASIC_OFFSET;
81 sc->nic_offset = ED_3COM_NIC_OFFSET;
82
83 /*
84 * Verify that the kernel configured I/O address matches the board
85 * configured address
86 */
87 switch (ed_asic_inb(sc, ED_3COM_BCFR)) {
88 case ED_3COM_BCFR_300:
89 if (rman_get_start(sc->port_res) != 0x300)
90 return (ENXIO);
91 break;
92 case ED_3COM_BCFR_310:
93 if (rman_get_start(sc->port_res) != 0x310)
94 return (ENXIO);
95 break;
96 case ED_3COM_BCFR_330:
97 if (rman_get_start(sc->port_res) != 0x330)
98 return (ENXIO);
99 break;
100 case ED_3COM_BCFR_350:
101 if (rman_get_start(sc->port_res) != 0x350)
102 return (ENXIO);
103 break;
104 case ED_3COM_BCFR_250:
105 if (rman_get_start(sc->port_res) != 0x250)
106 return (ENXIO);
107 break;
108 case ED_3COM_BCFR_280:
109 if (rman_get_start(sc->port_res) != 0x280)
110 return (ENXIO);
111 break;
112 case ED_3COM_BCFR_2A0:
113 if (rman_get_start(sc->port_res) != 0x2a0)
114 return (ENXIO);
115 break;
116 case ED_3COM_BCFR_2E0:
117 if (rman_get_start(sc->port_res) != 0x2e0)
118 return (ENXIO);
119 break;
120 default:
121 return (ENXIO);
122 }
123
124 error = bus_get_resource(dev, SYS_RES_MEMORY, 0,
125 &conf_maddr, &conf_msize);
126 if (error)
127 return (error);
128
129 /*
130 * Verify that the kernel shared memory address matches the board
131 * configured address.
132 */
133 switch (ed_asic_inb(sc, ED_3COM_PCFR)) {
134 case ED_3COM_PCFR_DC000:
135 if (conf_maddr != 0xdc000)
136 return (ENXIO);
137 break;
138 case ED_3COM_PCFR_D8000:
139 if (conf_maddr != 0xd8000)
140 return (ENXIO);
141 break;
142 case ED_3COM_PCFR_CC000:
143 if (conf_maddr != 0xcc000)
144 return (ENXIO);
145 break;
146 case ED_3COM_PCFR_C8000:
147 if (conf_maddr != 0xc8000)
148 return (ENXIO);
149 break;
150 default:
151 return (ENXIO);
152 }
153
154
155 /*
156 * Reset NIC and ASIC. Enable on-board transceiver throughout reset
157 * sequence because it'll lock up if the cable isn't connected if we
158 * don't.
159 */
160 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_RST | ED_3COM_CR_XSEL);
161
162 /*
163 * Wait for a while, then un-reset it
164 */
165 DELAY(50);
166
167 /*
168 * The 3Com ASIC defaults to rather strange settings for the CR after
169 * a reset - it's important to set it again after the following outb
170 * (this is done when we map the PROM below).
171 */
172 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL);
173
174 /*
175 * Wait a bit for the NIC to recover from the reset
176 */
177 DELAY(5000);
178
179 sc->vendor = ED_VENDOR_3COM;
180 sc->type_str = "3c503";
181 sc->mem_shared = 1;
182 sc->cr_proto = ED_CR_RD2;
183
184 /*
185 * Hmmm...a 16bit 3Com board has 16k of memory, but only an 8k window
186 * to it.
187 */
188 memsize = 8192;
189
190 /*
191 * Get station address from on-board ROM
192 */
193
194 /*
195 * First, map ethernet address PROM over the top of where the NIC
196 * registers normally appear.
197 */
198 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_EALO | ED_3COM_CR_XSEL);
199
200 for (i = 0; i < ETHER_ADDR_LEN; ++i)
201 sc->enaddr[i] = ed_nic_inb(sc, i);
202
203 /*
204 * Unmap PROM - select NIC registers. The proper setting of the
205 * tranceiver is set in ed_init so that the attach code is given a
206 * chance to set the default based on a compile-time config option
207 */
208 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL);
209
210 /*
211 * Determine if this is an 8bit or 16bit board
212 */
213
214 /*
215 * select page 0 registers
216 */
217 ed_nic_outb(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_STP);
218
219 /*
220 * Attempt to clear WTS bit. If it doesn't clear, then this is a 16bit
221 * board.
222 */
223 ed_nic_outb(sc, ED_P0_DCR, 0);
224
225 /*
226 * select page 2 registers
227 */
228 ed_nic_outb(sc, ED_P0_CR, ED_CR_PAGE_2 | ED_CR_RD2 | ED_CR_STP);
229
230 /*
231 * The 3c503 forces the WTS bit to a one if this is a 16bit board
232 */
233 if (ed_nic_inb(sc, ED_P2_DCR) & ED_DCR_WTS)
234 isa16bit = 1;
235 else
236 isa16bit = 0;
237
238 /*
239 * select page 0 registers
240 */
241 ed_nic_outb(sc, ED_P2_CR, ED_CR_RD2 | ED_CR_STP);
242
243 error = ed_alloc_memory(dev, 0, memsize);
244 if (error)
245 return (error);
246
247 pmem = rman_get_start(sc->mem_res);
248 error = ed_isa_mem_ok(dev, pmem, memsize);
249 if (error)
250 return (error);
251
252 sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res);
252 sc->mem_start = 0;
253 sc->mem_size = memsize;
254 sc->mem_end = sc->mem_start + memsize;
255
256 /*
257 * We have an entire 8k window to put the transmit buffers on the
258 * 16bit boards. But since the 16bit 3c503's shared memory is only
259 * fast enough to overlap the loading of one full-size packet, trying
260 * to load more than 2 buffers can actually leave the transmitter idle
261 * during the load. So 2 seems the best value. (Although a mix of
262 * variable-sized packets might change this assumption. Nonetheless,
263 * we optimize for linear transfers of same-size packets.)
264 */
265 if (isa16bit) {
266 if (flags & ED_FLAGS_NO_MULTI_BUFFERING)
267 sc->txb_cnt = 1;
268 else
269 sc->txb_cnt = 2;
270
271 sc->tx_page_start = ED_3COM_TX_PAGE_OFFSET_16BIT;
272 sc->rec_page_start = ED_3COM_RX_PAGE_OFFSET_16BIT;
273 sc->rec_page_stop = memsize / ED_PAGE_SIZE +
274 ED_3COM_RX_PAGE_OFFSET_16BIT;
275 sc->mem_ring = sc->mem_start;
276 } else {
277 sc->txb_cnt = 1;
278 sc->tx_page_start = ED_3COM_TX_PAGE_OFFSET_8BIT;
279 sc->rec_page_start = ED_TXBUF_SIZE + ED_3COM_TX_PAGE_OFFSET_8BIT;
280 sc->rec_page_stop = memsize / ED_PAGE_SIZE +
281 ED_3COM_TX_PAGE_OFFSET_8BIT;
282 sc->mem_ring = sc->mem_start + (ED_PAGE_SIZE * ED_TXBUF_SIZE);
283 }
284
285 sc->isa16bit = isa16bit;
286
287 /*
288 * Initialize GA page start/stop registers. Probably only needed if
289 * doing DMA, but what the hell.
290 */
291 ed_asic_outb(sc, ED_3COM_PSTR, sc->rec_page_start);
292 ed_asic_outb(sc, ED_3COM_PSPR, sc->rec_page_stop);
293
294 /*
295 * Set IRQ. 3c503 only allows a choice of irq 2-5.
296 */
297 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, &junk);
298 if (error)
299 return (error);
300
301 switch (irq) {
302 case 2:
303 case 9:
304 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ2);
305 break;
306 case 3:
307 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ3);
308 break;
309 case 4:
310 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ4);
311 break;
312 case 5:
313 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ5);
314 break;
315 default:
316 device_printf(dev, "Invalid irq configuration (%ld) must be 3-5,9 for 3c503\n",
317 irq);
318 return (ENXIO);
319 }
320
321 /*
322 * Initialize GA configuration register. Set bank and enable shared
323 * mem.
324 */
325 ed_asic_outb(sc, ED_3COM_GACFR, ED_3COM_GACFR_RSEL |
326 ED_3COM_GACFR_MBS0);
327
328 /*
329 * Initialize "Vector Pointer" registers. These gawd-awful things are
330 * compared to 20 bits of the address on ISA, and if they match, the
331 * shared memory is disabled. We set them to 0xffff0...allegedly the
332 * reset vector.
333 */
334 ed_asic_outb(sc, ED_3COM_VPTR2, 0xff);
335 ed_asic_outb(sc, ED_3COM_VPTR1, 0xff);
336 ed_asic_outb(sc, ED_3COM_VPTR0, 0x00);
337
338 return (ed_clear_memory(dev));
339}
340
341#endif /* ED_3C503 */
253 sc->mem_size = memsize;
254 sc->mem_end = sc->mem_start + memsize;
255
256 /*
257 * We have an entire 8k window to put the transmit buffers on the
258 * 16bit boards. But since the 16bit 3c503's shared memory is only
259 * fast enough to overlap the loading of one full-size packet, trying
260 * to load more than 2 buffers can actually leave the transmitter idle
261 * during the load. So 2 seems the best value. (Although a mix of
262 * variable-sized packets might change this assumption. Nonetheless,
263 * we optimize for linear transfers of same-size packets.)
264 */
265 if (isa16bit) {
266 if (flags & ED_FLAGS_NO_MULTI_BUFFERING)
267 sc->txb_cnt = 1;
268 else
269 sc->txb_cnt = 2;
270
271 sc->tx_page_start = ED_3COM_TX_PAGE_OFFSET_16BIT;
272 sc->rec_page_start = ED_3COM_RX_PAGE_OFFSET_16BIT;
273 sc->rec_page_stop = memsize / ED_PAGE_SIZE +
274 ED_3COM_RX_PAGE_OFFSET_16BIT;
275 sc->mem_ring = sc->mem_start;
276 } else {
277 sc->txb_cnt = 1;
278 sc->tx_page_start = ED_3COM_TX_PAGE_OFFSET_8BIT;
279 sc->rec_page_start = ED_TXBUF_SIZE + ED_3COM_TX_PAGE_OFFSET_8BIT;
280 sc->rec_page_stop = memsize / ED_PAGE_SIZE +
281 ED_3COM_TX_PAGE_OFFSET_8BIT;
282 sc->mem_ring = sc->mem_start + (ED_PAGE_SIZE * ED_TXBUF_SIZE);
283 }
284
285 sc->isa16bit = isa16bit;
286
287 /*
288 * Initialize GA page start/stop registers. Probably only needed if
289 * doing DMA, but what the hell.
290 */
291 ed_asic_outb(sc, ED_3COM_PSTR, sc->rec_page_start);
292 ed_asic_outb(sc, ED_3COM_PSPR, sc->rec_page_stop);
293
294 /*
295 * Set IRQ. 3c503 only allows a choice of irq 2-5.
296 */
297 error = bus_get_resource(dev, SYS_RES_IRQ, 0, &irq, &junk);
298 if (error)
299 return (error);
300
301 switch (irq) {
302 case 2:
303 case 9:
304 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ2);
305 break;
306 case 3:
307 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ3);
308 break;
309 case 4:
310 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ4);
311 break;
312 case 5:
313 ed_asic_outb(sc, ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ5);
314 break;
315 default:
316 device_printf(dev, "Invalid irq configuration (%ld) must be 3-5,9 for 3c503\n",
317 irq);
318 return (ENXIO);
319 }
320
321 /*
322 * Initialize GA configuration register. Set bank and enable shared
323 * mem.
324 */
325 ed_asic_outb(sc, ED_3COM_GACFR, ED_3COM_GACFR_RSEL |
326 ED_3COM_GACFR_MBS0);
327
328 /*
329 * Initialize "Vector Pointer" registers. These gawd-awful things are
330 * compared to 20 bits of the address on ISA, and if they match, the
331 * shared memory is disabled. We set them to 0xffff0...allegedly the
332 * reset vector.
333 */
334 ed_asic_outb(sc, ED_3COM_VPTR2, 0xff);
335 ed_asic_outb(sc, ED_3COM_VPTR1, 0xff);
336 ed_asic_outb(sc, ED_3COM_VPTR0, 0x00);
337
338 return (ed_clear_memory(dev));
339}
340
341#endif /* ED_3C503 */