if_ed.c (50808) | if_ed.c (50852) |
---|---|
1/* 2 * Copyright (c) 1995, David Greenman 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * | 1/* 2 * Copyright (c) 1995, David Greenman 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * |
27 * $FreeBSD: head/sys/dev/ed/if_ed.c 50808 1999-09-02 15:06:23Z kato $ | 27 * $FreeBSD: head/sys/dev/ed/if_ed.c 50852 1999-09-03 19:10:56Z peter $ |
28 */ 29 30/* 31 * Device driver for National Semiconductor DS8390/WD83C690 based ethernet 32 * adapters. By David Greenman, 29-April-1993 33 * 34 * Currently supports the Western Digital/SMC 8003 and 8013 series, 35 * the SMC Elite Ultra (8216), the 3Com 3c503, the NE1000 and NE2000, 36 * and a variety of similar clones. 37 * 38 */ 39 | 28 */ 29 30/* 31 * Device driver for National Semiconductor DS8390/WD83C690 based ethernet 32 * adapters. By David Greenman, 29-April-1993 33 * 34 * Currently supports the Western Digital/SMC 8003 and 8013 series, 35 * the SMC Elite Ultra (8216), the 3Com 3c503, the NE1000 and NE2000, 36 * and a variety of similar clones. 37 * 38 */ 39 |
40#include "ed.h" | |
41#include "bpf.h" | 40#include "bpf.h" |
42#include "pnp.h" | |
43 | 41 |
44#ifndef EXTRA_ED 45# if NPNP > 0 46# define EXTRA_ED 8 47# else 48# define EXTRA_ED 0 49# endif 50#endif 51 52#define NEDTOT (NED + EXTRA_ED) 53 | |
54#include <sys/param.h> 55#include <sys/systm.h> | 42#include <sys/param.h> 43#include <sys/systm.h> |
44#include <sys/kernel.h> |
|
56#include <sys/sockio.h> 57#include <sys/malloc.h> 58#include <sys/mbuf.h> 59#include <sys/socket.h> 60#include <sys/syslog.h> 61 | 45#include <sys/sockio.h> 46#include <sys/malloc.h> 47#include <sys/mbuf.h> 48#include <sys/socket.h> 49#include <sys/syslog.h> 50 |
51#include <sys/module.h> 52#include <sys/bus.h> 53 54#include <machine/bus.h> 55#include <sys/rman.h> 56#include <machine/resource.h> 57 |
|
62#include <net/ethernet.h> 63#include <net/if.h> 64#include <net/if_arp.h> 65#include <net/if_dl.h> 66#include <net/if_mib.h> 67 68#if NBPF > 0 69#include <net/bpf.h> 70#endif 71#include "opt_bdg.h" 72#ifdef BRIDGE 73#include <net/bridge.h> 74#endif 75 76#include <machine/clock.h> 77#include <machine/md_var.h> 78 | 58#include <net/ethernet.h> 59#include <net/if.h> 60#include <net/if_arp.h> 61#include <net/if_dl.h> 62#include <net/if_mib.h> 63 64#if NBPF > 0 65#include <net/bpf.h> 66#endif 67#include "opt_bdg.h" 68#ifdef BRIDGE 69#include <net/bridge.h> 70#endif 71 72#include <machine/clock.h> 73#include <machine/md_var.h> 74 |
79#include <i386/isa/isa_device.h> 80#include <i386/isa/icu.h> | |
81#include <i386/isa/if_edreg.h> | 75#include <i386/isa/if_edreg.h> |
76#include <i386/isa/if_edvar.h> |
|
82 | 77 |
83#if NPNP > 0 84#include <i386/isa/pnp.h> 85#endif | 78#include <isa/isavar.h> 79#include <isa/pnpvar.h> |
86 | 80 |
87/* 88 * ed_softc: per line info and status 89 */ 90struct ed_softc { 91 struct arpcom arpcom; /* ethernet common */ | 81static int ed_alloc_port __P((device_t, int, int)); 82static int ed_alloc_memory __P((device_t, int, int)); 83static int ed_alloc_irq __P((device_t, int, int)); 84static void ed_release_resources __P((device_t)); |
92 | 85 |
93 char *type_str; /* pointer to type string */ 94 u_char vendor; /* interface vendor */ 95 u_char type; /* interface type code */ 96 u_char gone; /* HW missing, presumed having a good time */ 97 98 u_short asic_addr; /* ASIC I/O bus address */ 99 u_short nic_addr; /* NIC (DS8390) I/O bus address */ 100 101/* 102 * The following 'proto' variable is part of a work-around for 8013EBT asics 103 * being write-only. It's sort of a prototype/shadow of the real thing. 104 */ 105 u_char wd_laar_proto; 106 u_char cr_proto; 107 u_char isa16bit; /* width of access to card 0=8 or 1=16 */ 108 int is790; /* set by the probe code if the card is 790 109 * based */ 110 111/* 112 * HP PC LAN PLUS card support. 113 */ 114 115 u_short hpp_options; /* flags controlling behaviour of the HP card */ 116 u_short hpp_id; /* software revision and other fields */ 117 caddr_t hpp_mem_start; /* Memory-mapped IO register address */ 118 119 caddr_t mem_start; /* NIC memory start address */ 120 caddr_t mem_end; /* NIC memory end address */ 121 u_long mem_size; /* total NIC memory size */ 122 caddr_t mem_ring; /* start of RX ring-buffer (in NIC mem) */ 123 124 u_char mem_shared; /* NIC memory is shared with host */ 125 u_char xmit_busy; /* transmitter is busy */ 126 u_char txb_cnt; /* number of transmit buffers */ 127 u_char txb_inuse; /* number of TX buffers currently in-use */ 128 129 u_char txb_new; /* pointer to where new buffer will be added */ 130 u_char txb_next_tx; /* pointer to next buffer ready to xmit */ 131 u_short txb_len[8]; /* buffered xmit buffer lengths */ 132 u_char tx_page_start; /* first page of TX buffer area */ 133 u_char rec_page_start; /* first page of RX ring-buffer */ 134 u_char rec_page_stop; /* last page of RX ring-buffer */ 135 u_char next_packet; /* pointer to next unread RX packet */ 136 struct ifmib_iso_8802_3 mibdata; /* stuff for network mgmt */ 137}; 138 139static struct ed_softc ed_softc[NEDTOT]; 140 | |
141static int ed_attach __P((struct ed_softc *, int, int)); | 86static int ed_attach __P((struct ed_softc *, int, int)); |
142static int ed_attach_isa __P((struct isa_device *)); | 87static int ed_isa_attach __P((device_t)); |
143 144static void ed_init __P((void *)); | 88 89static void ed_init __P((void *)); |
145static ointhand2_t edintr; | 90static driver_intr_t edintr; |
146static int ed_ioctl __P((struct ifnet *, u_long, caddr_t)); | 91static int ed_ioctl __P((struct ifnet *, u_long, caddr_t)); |
147static int ed_probe __P((struct isa_device *)); | 92static int ed_isa_probe __P((device_t)); |
148static void ed_start __P((struct ifnet *)); 149static void ed_reset __P((struct ifnet *)); 150static void ed_watchdog __P((struct ifnet *)); 151 152static void ed_stop __P((struct ed_softc *)); 153static int ed_probe_generic8390 __P((struct ed_softc *)); | 93static void ed_start __P((struct ifnet *)); 94static void ed_reset __P((struct ifnet *)); 95static void ed_watchdog __P((struct ifnet *)); 96 97static void ed_stop __P((struct ed_softc *)); 98static int ed_probe_generic8390 __P((struct ed_softc *)); |
154static int ed_probe_WD80x3 __P((struct isa_device *)); 155static int ed_probe_3Com __P((struct isa_device *)); 156static int ed_probe_Novell __P((struct isa_device *)); 157static int ed_probe_Novell_generic __P((struct ed_softc *, int, int, int)); 158static int ed_probe_HP_pclanp __P((struct isa_device *)); | 99static int ed_probe_WD80x3 __P((device_t)); 100static int ed_probe_3Com __P((device_t)); 101static int ed_probe_Novell __P((device_t)); 102static int ed_probe_Novell_generic __P((device_t, int, int)); 103static int ed_probe_HP_pclanp __P((device_t)); |
159 160#include "pci.h" 161#if NPCI > 0 | 104 105#include "pci.h" 106#if NPCI > 0 |
162void *ed_attach_NE2000_pci __P((int, int)); | 107int ed_attach_NE2000_pci __P((device_t, int)); |
163#endif 164 165#include "card.h" | 108#endif 109 110#include "card.h" |
166#if NCARD > 0 | 111#if NCARDxx > 0 |
167static int ed_probe_pccard __P((struct isa_device *, u_char *)); 168#endif 169 170static void ds_getmcaf __P((struct ed_softc *, u_long *)); 171 172static void ed_get_packet __P((struct ed_softc *, char *, /* u_short */ int, int)); 173 174static __inline void ed_rint __P((struct ed_softc *)); --- 7 unchanged lines hidden (view full) --- 182 int)); 183 184static void ed_pio_readmem __P((struct ed_softc *, int, unsigned char *, 185 /* u_short */ int)); 186static void ed_pio_writemem __P((struct ed_softc *, char *, 187 /* u_short */ int, /* u_short */ int)); 188static u_short ed_pio_write_mbufs __P((struct ed_softc *, struct mbuf *, 189 int)); | 112static int ed_probe_pccard __P((struct isa_device *, u_char *)); 113#endif 114 115static void ds_getmcaf __P((struct ed_softc *, u_long *)); 116 117static void ed_get_packet __P((struct ed_softc *, char *, /* u_short */ int, int)); 118 119static __inline void ed_rint __P((struct ed_softc *)); --- 7 unchanged lines hidden (view full) --- 127 int)); 128 129static void ed_pio_readmem __P((struct ed_softc *, int, unsigned char *, 130 /* u_short */ int)); 131static void ed_pio_writemem __P((struct ed_softc *, char *, 132 /* u_short */ int, /* u_short */ int)); 133static u_short ed_pio_write_mbufs __P((struct ed_softc *, struct mbuf *, 134 int)); |
190void edintr_sc __P((struct ed_softc *)); | |
191 192static void ed_setrcr __P((struct ed_softc *)); 193 194static u_long ds_crc __P((u_char *ep)); 195 | 135 136static void ed_setrcr __P((struct ed_softc *)); 137 138static u_long ds_crc __P((u_char *ep)); 139 |
196#if (NCARD > 0) || (NPNP > 0) 197#include <sys/kernel.h> 198#endif 199#if NCARD > 0 | 140#if NCARDxx > 0 |
200#include <sys/select.h> 201#include <sys/module.h> 202#include <pccard/cardinfo.h> 203#include <pccard/slot.h> 204 205/* 206 * PC-Card (PCMCIA) specific code. 207 */ --- 24 unchanged lines hidden (view full) --- 232 if (ed_probe_pccard(&devi->isahd, devi->misc) == 0) 233 return(ENXIO); 234 e = 0; 235 for (i = 0; i < ETHER_ADDR_LEN; ++i) 236 e |= devi->misc[i]; 237 if (e) 238 for (i = 0; i < ETHER_ADDR_LEN; ++i) 239 sc->arpcom.ac_enaddr[i] = devi->misc[i]; | 141#include <sys/select.h> 142#include <sys/module.h> 143#include <pccard/cardinfo.h> 144#include <pccard/slot.h> 145 146/* 147 * PC-Card (PCMCIA) specific code. 148 */ --- 24 unchanged lines hidden (view full) --- 173 if (ed_probe_pccard(&devi->isahd, devi->misc) == 0) 174 return(ENXIO); 175 e = 0; 176 for (i = 0; i < ETHER_ADDR_LEN; ++i) 177 e |= devi->misc[i]; 178 if (e) 179 for (i = 0; i < ETHER_ADDR_LEN; ++i) 180 sc->arpcom.ac_enaddr[i] = devi->misc[i]; |
240 if (ed_attach_isa(&devi->isahd) == 0) | 181 if (ed_isa_attach(&devi->isahd) == 0) |
241 return(ENXIO); 242 243 return(0); 244} 245 246/* 247 * edunload - unload the driver and clear the table. 248 * XXX TODO: --- 21 unchanged lines hidden (view full) --- 270 271/* 272 * card_intr - Shared interrupt called from 273 * front end of PC-Card handler. 274 */ 275static int 276card_intr(struct pccard_devinfo *devi) 277{ | 182 return(ENXIO); 183 184 return(0); 185} 186 187/* 188 * edunload - unload the driver and clear the table. 189 * XXX TODO: --- 21 unchanged lines hidden (view full) --- 211 212/* 213 * card_intr - Shared interrupt called from 214 * front end of PC-Card handler. 215 */ 216static int 217card_intr(struct pccard_devinfo *devi) 218{ |
278 edintr_sc(&ed_softc[devi->isahd.id_unit]); | 219 edintr(&ed_softc[devi->isahd.id_unit]); |
279 return(1); 280} 281#endif /* NCARD > 0 */ 282 | 220 return(1); 221} 222#endif /* NCARD > 0 */ 223 |
283struct isa_driver eddriver = { 284 ed_probe, 285 ed_attach_isa, 286 "ed", 287 1 /* We are ultra sensitive */ 288}; 289 | |
290/* 291 * Interrupt conversion table for WD/SMC ASIC/83C584 | 224/* 225 * Interrupt conversion table for WD/SMC ASIC/83C584 |
292 * (IRQ* are defined in icu.h) | |
293 */ | 226 */ |
294static unsigned short ed_intr_mask[] = { 295 IRQ9, 296 IRQ3, 297 IRQ5, 298 IRQ7, 299 IRQ10, 300 IRQ11, 301 IRQ15, 302 IRQ4 | 227static unsigned short ed_intr_val[] = { 228 9, 229 3, 230 5, 231 7, 232 10, 233 11, 234 15, 235 4 |
303}; 304 305/* 306 * Interrupt conversion table for 83C790 307 */ | 236}; 237 238/* 239 * Interrupt conversion table for 83C790 240 */ |
308static unsigned short ed_790_intr_mask[] = { | 241static unsigned short ed_790_intr_val[] = { |
309 0, | 242 0, |
310 IRQ9, 311 IRQ3, 312 IRQ5, 313 IRQ7, 314 IRQ10, 315 IRQ11, 316 IRQ15 | 243 9, 244 3, 245 5, 246 7, 247 10, 248 11, 249 15 |
317}; 318 319/* 320 * Interrupt conversion table for the HP PC LAN+ 321 */ 322 | 250}; 251 252/* 253 * Interrupt conversion table for the HP PC LAN+ 254 */ 255 |
323static unsigned short ed_hpp_intr_mask[] = { | 256static unsigned short ed_hpp_intr_val[] = { |
324 0, /* 0 */ 325 0, /* 1 */ 326 0, /* 2 */ | 257 0, /* 0 */ 258 0, /* 1 */ 259 0, /* 2 */ |
327 IRQ3, /* 3 */ 328 IRQ4, /* 4 */ 329 IRQ5, /* 5 */ 330 IRQ6, /* 6 */ 331 IRQ7, /* 7 */ | 260 3, /* 3 */ 261 4, /* 4 */ 262 5, /* 5 */ 263 6, /* 6 */ 264 7, /* 7 */ |
332 0, /* 8 */ | 265 0, /* 8 */ |
333 IRQ9, /* 9 */ 334 IRQ10, /* 10 */ 335 IRQ11, /* 11 */ 336 IRQ12, /* 12 */ | 266 9, /* 9 */ 267 10, /* 10 */ 268 11, /* 11 */ 269 12, /* 12 */ |
337 0, /* 13 */ 338 0, /* 14 */ | 270 0, /* 13 */ 271 0, /* 14 */ |
339 IRQ15 /* 15 */ | 272 15 /* 15 */ |
340}; 341 | 273}; 274 |
342/* 343 * Determine if the device is present 344 * 345 * on entry: 346 * a pointer to an isa_device struct 347 * on exit: 348 * NULL if device not found 349 * or # of i/o addresses used (if found) 350 */ | 275static struct isa_pnp_id ed_ids[] = { 276 { 0xd680d041, "NE2000 Compatible" }, /* PNP80d6 */ 277 { 0x1980635e, "WSC8019" }, /* WSC8019 */ 278 { 0x0131d805, "Acer ALN-101T" }, /* ANX3101 */ 279 { 0x01200507, "PLANET ENW-2401" }, /* AXE2001 */ 280 { 0x19808c4a, "Realtek Plug & Play Ethernet Card" }, /* RTL8019 */ 281 { 0x0090252a, "CNet NE2000 Compatible" }, /* JQE9000 */ 282 { 0x0020832e, "Kingston EtheRX KNE20 Plug & Play ISA" }, /* KTC2000 */ 283 { 0, NULL} 284}; 285 |
351static int | 286static int |
352ed_probe(isa_dev) 353 struct isa_device *isa_dev; | 287ed_isa_probe(dev) 288 device_t dev; |
354{ | 289{ |
355 int nports; | 290 struct ed_softc *sc = device_get_softc(dev); 291 int error = 0; |
356 | 292 |
357 nports = ed_probe_WD80x3(isa_dev); 358 if (nports) 359 return (nports); | 293 bzero(sc, sizeof(struct ed_softc)); |
360 | 294 |
361 nports = ed_probe_3Com(isa_dev); 362 if (nports) 363 return (nports); | 295 /* Check isapnp ids */ 296 error = ISA_PNP_PROBE(device_get_parent(dev), dev, ed_ids); |
364 | 297 |
365 nports = ed_probe_Novell(isa_dev); 366 if (nports) 367 return (nports); | 298 /* If the card had a PnP ID that didn't match any we know about */ 299 if (error == ENXIO) 300 goto end; |
368 | 301 |
369 nports = ed_probe_HP_pclanp(isa_dev); 370 if (nports) 371 return (nports); | 302 /* If we found a PnP card. */ 303 if (error == 0) { 304 error = ed_probe_Novell(dev); 305 goto end; 306 } 307 308 /* Heuristic probes */ |
372 | 309 |
373 return (0); | 310 error = ed_probe_WD80x3(dev); 311 if (error == 0) 312 goto end; 313 ed_release_resources(dev); 314 315 error = ed_probe_3Com(dev); 316 if (error == 0) 317 goto end; 318 ed_release_resources(dev); 319 320 error = ed_probe_Novell(dev); 321 if (error == 0) 322 goto end; 323 ed_release_resources(dev); 324 325 error = ed_probe_HP_pclanp(dev); 326 if (error == 0) 327 goto end; 328 ed_release_resources(dev); 329 330end: 331 if (error == 0) 332 error = ed_alloc_irq(dev, 0, 0); 333 334 ed_release_resources(dev); 335 return (error); |
374} 375 376/* 377 * Generic probe routine for testing for the existance of a DS8390. 378 * Must be called after the NIC has just been reset. This routine 379 * works by looking at certain register values that are guaranteed 380 * to be initialized a certain way after power-up or reset. Seems 381 * not to currently work on the 83C690. --- 27 unchanged lines hidden (view full) --- 409 410 return (1); 411} 412 413/* 414 * Probe and vendor-specific initialization routine for SMC/WD80x3 boards 415 */ 416static int | 336} 337 338/* 339 * Generic probe routine for testing for the existance of a DS8390. 340 * Must be called after the NIC has just been reset. This routine 341 * works by looking at certain register values that are guaranteed 342 * to be initialized a certain way after power-up or reset. Seems 343 * not to currently work on the 83C690. --- 27 unchanged lines hidden (view full) --- 371 372 return (1); 373} 374 375/* 376 * Probe and vendor-specific initialization routine for SMC/WD80x3 boards 377 */ 378static int |
417ed_probe_WD80x3(isa_dev) 418 struct isa_device *isa_dev; | 379ed_probe_WD80x3(dev) 380 device_t dev; |
419{ | 381{ |
420 struct ed_softc *sc = &ed_softc[isa_dev->id_unit]; | 382 struct ed_softc *sc = device_get_softc(dev); 383 int error; |
421 int i; | 384 int i; |
385 int flags = isa_get_flags(dev); |
|
422 u_int memsize, maddr; 423 u_char iptr, isa16bit, sum; | 386 u_int memsize, maddr; 387 u_char iptr, isa16bit, sum; |
388 u_long conf_maddr, conf_msize, irq, junk; |
|
424 | 389 |
425 sc->asic_addr = isa_dev->id_iobase; | 390 error = ed_alloc_port(dev, 0, ED_WD_IO_PORTS); 391 if (error) 392 return (error); 393 394 sc->asic_addr = rman_get_start(sc->port_res); |
426 sc->nic_addr = sc->asic_addr + ED_WD_NIC_OFFSET; 427 sc->is790 = 0; 428 429#ifdef TOSH_ETHER 430 outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_POW); 431 DELAY(10000); 432#endif 433 --- 10 unchanged lines hidden (view full) --- 444 445 /* 446 * Checksum is invalid. This often happens with cheap WD8003E 447 * clones. In this case, the checksum byte (the eighth byte) 448 * seems to always be zero. 449 */ 450 if (inb(sc->asic_addr + ED_WD_CARD_ID) != ED_TYPE_WD8003E || 451 inb(sc->asic_addr + ED_WD_PROM + 7) != 0) | 395 sc->nic_addr = sc->asic_addr + ED_WD_NIC_OFFSET; 396 sc->is790 = 0; 397 398#ifdef TOSH_ETHER 399 outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_POW); 400 DELAY(10000); 401#endif 402 --- 10 unchanged lines hidden (view full) --- 413 414 /* 415 * Checksum is invalid. This often happens with cheap WD8003E 416 * clones. In this case, the checksum byte (the eighth byte) 417 * seems to always be zero. 418 */ 419 if (inb(sc->asic_addr + ED_WD_CARD_ID) != ED_TYPE_WD8003E || 420 inb(sc->asic_addr + ED_WD_PROM + 7) != 0) |
452 return (0); | 421 return (ENXIO); |
453 } 454 /* reset card to force it into a known state. */ 455#ifdef TOSH_ETHER 456 outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST | ED_WD_MSR_POW); 457#else 458 outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST); 459#endif 460 DELAY(100); --- 118 unchanged lines hidden (view full) --- 579#ifdef TOSH_ETHER 580 && (sc->type != ED_TYPE_TOSHIBA1) && (sc->type != ED_TYPE_TOSHIBA4) 581#endif 582 && ((inb(sc->asic_addr + ED_WD_ICR) & ED_WD_ICR_16BIT) == 0)) { 583 isa16bit = 0; 584 memsize = 8192; 585 } 586 | 422 } 423 /* reset card to force it into a known state. */ 424#ifdef TOSH_ETHER 425 outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST | ED_WD_MSR_POW); 426#else 427 outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST); 428#endif 429 DELAY(100); --- 118 unchanged lines hidden (view full) --- 548#ifdef TOSH_ETHER 549 && (sc->type != ED_TYPE_TOSHIBA1) && (sc->type != ED_TYPE_TOSHIBA4) 550#endif 551 && ((inb(sc->asic_addr + ED_WD_ICR) & ED_WD_ICR_16BIT) == 0)) { 552 isa16bit = 0; 553 memsize = 8192; 554 } 555 |
556 error = ISA_GET_RESOURCE(device_get_parent(dev), dev, 557 SYS_RES_MEMORY, 0, 558 &conf_maddr, &conf_msize); 559 if (error) 560 return (error); 561 |
|
587#if ED_DEBUG 588 printf("type = %x type_str=%s isa16bit=%d memsize=%d id_msize=%d\n", | 562#if ED_DEBUG 563 printf("type = %x type_str=%s isa16bit=%d memsize=%d id_msize=%d\n", |
589 sc->type, sc->type_str, isa16bit, memsize, isa_dev->id_msize); | 564 sc->type, sc->type_str, isa16bit, memsize, conf_msize); |
590 for (i = 0; i < 8; i++) 591 printf("%x -> %x\n", i, inb(sc->asic_addr + i)); 592#endif 593 594 /* 595 * Allow the user to override the autoconfiguration 596 */ | 565 for (i = 0; i < 8; i++) 566 printf("%x -> %x\n", i, inb(sc->asic_addr + i)); 567#endif 568 569 /* 570 * Allow the user to override the autoconfiguration 571 */ |
597 if (isa_dev->id_msize) 598 memsize = isa_dev->id_msize; | 572 if (conf_msize > 1) 573 memsize = conf_msize; |
599 | 574 |
600 maddr = (u_int) isa_dev->id_maddr & 0xffffff; | 575 maddr = conf_maddr; |
601 if (maddr < 0xa0000 || maddr + memsize > 0x1000000) { | 576 if (maddr < 0xa0000 || maddr + memsize > 0x1000000) { |
602 printf("ed%d: Invalid ISA memory address range configured: 0x%x - 0x%x\n", 603 isa_dev->id_unit, maddr, maddr + memsize); 604 return 0; | 577 device_printf(dev, "Invalid ISA memory address range configured: 0x%x - 0x%x\n", 578 maddr, maddr + memsize); 579 return (ENXIO); |
605 } 606 607 /* 608 * (note that if the user specifies both of the following flags that 609 * '8bit' mode intentionally has precedence) 610 */ | 580 } 581 582 /* 583 * (note that if the user specifies both of the following flags that 584 * '8bit' mode intentionally has precedence) 585 */ |
611 if (isa_dev->id_flags & ED_FLAGS_FORCE_16BIT_MODE) | 586 if (flags & ED_FLAGS_FORCE_16BIT_MODE) |
612 isa16bit = 1; | 587 isa16bit = 1; |
613 if (isa_dev->id_flags & ED_FLAGS_FORCE_8BIT_MODE) | 588 if (flags & ED_FLAGS_FORCE_8BIT_MODE) |
614 isa16bit = 0; 615 616 /* 617 * If possible, get the assigned interrupt number from the card and 618 * use it. 619 */ 620 if ((sc->type & ED_WD_SOFTCONFIG) && (!sc->is790)) { 621 622 /* 623 * Assemble together the encoded interrupt number. 624 */ | 589 isa16bit = 0; 590 591 /* 592 * If possible, get the assigned interrupt number from the card and 593 * use it. 594 */ 595 if ((sc->type & ED_WD_SOFTCONFIG) && (!sc->is790)) { 596 597 /* 598 * Assemble together the encoded interrupt number. 599 */ |
625 iptr = (inb(isa_dev->id_iobase + ED_WD_ICR) & ED_WD_ICR_IR2) | 626 ((inb(isa_dev->id_iobase + ED_WD_IRR) & | 600 iptr = (inb(sc->asic_addr + ED_WD_ICR) & ED_WD_ICR_IR2) | 601 ((inb(sc->asic_addr + ED_WD_IRR) & |
627 (ED_WD_IRR_IR0 | ED_WD_IRR_IR1)) >> 5); 628 629 /* 630 * If no interrupt specified (or "?"), use what the board tells us. 631 */ | 602 (ED_WD_IRR_IR0 | ED_WD_IRR_IR1)) >> 5); 603 604 /* 605 * If no interrupt specified (or "?"), use what the board tells us. 606 */ |
632 if (isa_dev->id_irq <= 0) 633 isa_dev->id_irq = ed_intr_mask[iptr]; | 607 error = ISA_GET_RESOURCE(device_get_parent(dev), dev, 608 SYS_RES_IRQ, 0, 609 &irq, &junk); 610 if (error) { 611 ISA_SET_RESOURCE(device_get_parent(dev), dev, 612 SYS_RES_IRQ, 0, 613 ed_intr_val[iptr], 1); 614 } |
634 635 /* 636 * Enable the interrupt. 637 */ | 615 616 /* 617 * Enable the interrupt. 618 */ |
638 outb(isa_dev->id_iobase + ED_WD_IRR, 639 inb(isa_dev->id_iobase + ED_WD_IRR) | ED_WD_IRR_IEN); | 619 outb(sc->asic_addr + ED_WD_IRR, 620 inb(sc->asic_addr + ED_WD_IRR) | ED_WD_IRR_IEN); |
640 } 641 if (sc->is790) { | 621 } 622 if (sc->is790) { |
642 outb(isa_dev->id_iobase + ED_WD790_HWR, 643 inb(isa_dev->id_iobase + ED_WD790_HWR) | ED_WD790_HWR_SWH); 644 iptr = (((inb(isa_dev->id_iobase + ED_WD790_GCR) & ED_WD790_GCR_IR2) >> 4) | 645 (inb(isa_dev->id_iobase + ED_WD790_GCR) & | 623 outb(sc->asic_addr + ED_WD790_HWR, 624 inb(sc->asic_addr + ED_WD790_HWR) | ED_WD790_HWR_SWH); 625 iptr = (((inb(sc->asic_addr + ED_WD790_GCR) & ED_WD790_GCR_IR2) >> 4) | 626 (inb(sc->asic_addr + ED_WD790_GCR) & |
646 (ED_WD790_GCR_IR1 | ED_WD790_GCR_IR0)) >> 2); | 627 (ED_WD790_GCR_IR1 | ED_WD790_GCR_IR0)) >> 2); |
647 outb(isa_dev->id_iobase + ED_WD790_HWR, 648 inb(isa_dev->id_iobase + ED_WD790_HWR) & ~ED_WD790_HWR_SWH); | 628 outb(sc->asic_addr + ED_WD790_HWR, 629 inb(sc->asic_addr + ED_WD790_HWR) & ~ED_WD790_HWR_SWH); |
649 650 /* 651 * If no interrupt specified (or "?"), use what the board tells us. 652 */ | 630 631 /* 632 * If no interrupt specified (or "?"), use what the board tells us. 633 */ |
653 if (isa_dev->id_irq <= 0) 654 isa_dev->id_irq = ed_790_intr_mask[iptr]; | 634 error = ISA_GET_RESOURCE(device_get_parent(dev), dev, 635 SYS_RES_IRQ, 0, 636 &irq, &junk); 637 if (error) { 638 ISA_SET_RESOURCE(device_get_parent(dev), dev, 639 SYS_RES_IRQ, 0, 640 ed_790_intr_val[iptr], 1); 641 } |
655 656 /* 657 * Enable interrupts. 658 */ | 642 643 /* 644 * Enable interrupts. 645 */ |
659 outb(isa_dev->id_iobase + ED_WD790_ICR, 660 inb(isa_dev->id_iobase + ED_WD790_ICR) | ED_WD790_ICR_EIL); | 646 outb(sc->asic_addr + ED_WD790_ICR, 647 inb(sc->asic_addr + ED_WD790_ICR) | ED_WD790_ICR_EIL); |
661 } | 648 } |
662 if (isa_dev->id_irq <= 0) { 663 printf("ed%d: %s cards don't support auto-detected/assigned interrupts.\n", 664 isa_dev->id_unit, sc->type_str); 665 return (0); | 649 error = ISA_GET_RESOURCE(device_get_parent(dev), dev, 650 SYS_RES_IRQ, 0, 651 &irq, &junk); 652 if (error) { 653 device_printf(dev, "%s cards don't support auto-detected/assigned interrupts.\n", 654 sc->type_str); 655 return (ENXIO); |
666 } 667 sc->isa16bit = isa16bit; 668 sc->mem_shared = 1; | 656 } 657 sc->isa16bit = isa16bit; 658 sc->mem_shared = 1; |
669 isa_dev->id_msize = memsize; 670 sc->mem_start = (caddr_t) isa_dev->id_maddr; | |
671 | 659 |
660 error = ed_alloc_memory(dev, 0, memsize); 661 if (error) 662 return (error); 663 sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res); 664 |
|
672 /* 673 * allocate one xmit buffer if < 16k, two buffers otherwise 674 */ 675 if ((memsize < 16384) || | 665 /* 666 * allocate one xmit buffer if < 16k, two buffers otherwise 667 */ 668 if ((memsize < 16384) || |
676 (isa_dev->id_flags & ED_FLAGS_NO_MULTI_BUFFERING)) { | 669 (flags & ED_FLAGS_NO_MULTI_BUFFERING)) { |
677 sc->txb_cnt = 1; 678 } else { 679 sc->txb_cnt = 2; 680 } 681 sc->tx_page_start = ED_WD_PAGE_OFFSET; 682 sc->rec_page_start = ED_WD_PAGE_OFFSET + ED_TXBUF_SIZE * sc->txb_cnt; 683 sc->rec_page_stop = ED_WD_PAGE_OFFSET + memsize / ED_PAGE_SIZE; 684 sc->mem_ring = sc->mem_start + (ED_PAGE_SIZE * sc->rec_page_start); --- 67 unchanged lines hidden (view full) --- 752 753 /* 754 * Now zero memory and verify that it is clear 755 */ 756 bzero(sc->mem_start, memsize); 757 758 for (i = 0; i < memsize; ++i) { 759 if (sc->mem_start[i]) { | 670 sc->txb_cnt = 1; 671 } else { 672 sc->txb_cnt = 2; 673 } 674 sc->tx_page_start = ED_WD_PAGE_OFFSET; 675 sc->rec_page_start = ED_WD_PAGE_OFFSET + ED_TXBUF_SIZE * sc->txb_cnt; 676 sc->rec_page_stop = ED_WD_PAGE_OFFSET + memsize / ED_PAGE_SIZE; 677 sc->mem_ring = sc->mem_start + (ED_PAGE_SIZE * sc->rec_page_start); --- 67 unchanged lines hidden (view full) --- 745 746 /* 747 * Now zero memory and verify that it is clear 748 */ 749 bzero(sc->mem_start, memsize); 750 751 for (i = 0; i < memsize; ++i) { 752 if (sc->mem_start[i]) { |
760 printf("ed%d: failed to clear shared memory at %lx - check configuration\n", 761 isa_dev->id_unit, kvtop(sc->mem_start + i)); | 753 device_printf(dev, "failed to clear shared memory at %lx - check configuration\n", 754 kvtop(sc->mem_start + i)); |
762 763 /* 764 * Disable 16 bit access to shared memory 765 */ 766 if (isa16bit) { 767 if (sc->is790) { 768 outb(sc->asic_addr + ED_WD_MSR, 0x00); 769 } 770 outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto & 771 ~ED_WD_LAAR_M16EN); 772 } | 755 756 /* 757 * Disable 16 bit access to shared memory 758 */ 759 if (isa16bit) { 760 if (sc->is790) { 761 outb(sc->asic_addr + ED_WD_MSR, 0x00); 762 } 763 outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto & 764 ~ED_WD_LAAR_M16EN); 765 } |
773 return (0); | 766 return (ENXIO); |
774 } 775 } 776 777 /* 778 * Disable 16bit access to shared memory - we leave it 779 * disabled so that 1) machines reboot properly when the board 780 * is set 16 bit mode and there are conflicting 8bit 781 * devices/ROMS in the same 128k address space as this boards 782 * shared memory. and 2) so that other 8 bit devices with 783 * shared memory can be used in this 128k region, too. 784 */ 785 if (isa16bit) { 786 if (sc->is790) { 787 outb(sc->asic_addr + ED_WD_MSR, 0x00); 788 } 789 outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto & 790 ~ED_WD_LAAR_M16EN); 791 } | 767 } 768 } 769 770 /* 771 * Disable 16bit access to shared memory - we leave it 772 * disabled so that 1) machines reboot properly when the board 773 * is set 16 bit mode and there are conflicting 8bit 774 * devices/ROMS in the same 128k address space as this boards 775 * shared memory. and 2) so that other 8 bit devices with 776 * shared memory can be used in this 128k region, too. 777 */ 778 if (isa16bit) { 779 if (sc->is790) { 780 outb(sc->asic_addr + ED_WD_MSR, 0x00); 781 } 782 outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto & 783 ~ED_WD_LAAR_M16EN); 784 } |
792 return (ED_WD_IO_PORTS); | 785 return (0); |
793} 794 795/* 796 * Probe and vendor-specific initialization routine for 3Com 3c503 boards 797 */ 798static int | 786} 787 788/* 789 * Probe and vendor-specific initialization routine for 3Com 3c503 boards 790 */ 791static int |
799ed_probe_3Com(isa_dev) 800 struct isa_device *isa_dev; | 792ed_probe_3Com(dev) 793 device_t dev; |
801{ | 794{ |
802 struct ed_softc *sc = &ed_softc[isa_dev->id_unit]; | 795 struct ed_softc *sc = device_get_softc(dev); 796 int error; |
803 int i; | 797 int i; |
798 int flags = isa_get_flags(dev); |
|
804 u_int memsize; 805 u_char isa16bit; | 799 u_int memsize; 800 u_char isa16bit; |
801 u_long conf_maddr, conf_msize, irq, junk; |
|
806 | 802 |
807 sc->asic_addr = isa_dev->id_iobase + ED_3COM_ASIC_OFFSET; 808 sc->nic_addr = isa_dev->id_iobase + ED_3COM_NIC_OFFSET; | 803 error = ed_alloc_port(dev, 0, ED_3COM_IO_PORTS); 804 if (error) 805 return (error); |
809 | 806 |
807 sc->asic_addr = rman_get_start(sc->port_res) + ED_3COM_ASIC_OFFSET; 808 sc->nic_addr = rman_get_start(sc->port_res) + ED_3COM_NIC_OFFSET; 809 |
|
810 /* 811 * Verify that the kernel configured I/O address matches the board 812 * configured address 813 */ 814 switch (inb(sc->asic_addr + ED_3COM_BCFR)) { 815 case ED_3COM_BCFR_300: | 810 /* 811 * Verify that the kernel configured I/O address matches the board 812 * configured address 813 */ 814 switch (inb(sc->asic_addr + ED_3COM_BCFR)) { 815 case ED_3COM_BCFR_300: |
816 if (isa_dev->id_iobase != 0x300) 817 return (0); | 816 if (rman_get_start(sc->port_res) != 0x300) 817 return (ENXIO); |
818 break; 819 case ED_3COM_BCFR_310: | 818 break; 819 case ED_3COM_BCFR_310: |
820 if (isa_dev->id_iobase != 0x310) 821 return (0); | 820 if (rman_get_start(sc->port_res) != 0x310) 821 return (ENXIO); |
822 break; 823 case ED_3COM_BCFR_330: | 822 break; 823 case ED_3COM_BCFR_330: |
824 if (isa_dev->id_iobase != 0x330) 825 return (0); | 824 if (rman_get_start(sc->port_res) != 0x330) 825 return (ENXIO); |
826 break; 827 case ED_3COM_BCFR_350: | 826 break; 827 case ED_3COM_BCFR_350: |
828 if (isa_dev->id_iobase != 0x350) 829 return (0); | 828 if (rman_get_start(sc->port_res) != 0x350) 829 return (ENXIO); |
830 break; 831 case ED_3COM_BCFR_250: | 830 break; 831 case ED_3COM_BCFR_250: |
832 if (isa_dev->id_iobase != 0x250) 833 return (0); | 832 if (rman_get_start(sc->port_res) != 0x250) 833 return (ENXIO); |
834 break; 835 case ED_3COM_BCFR_280: | 834 break; 835 case ED_3COM_BCFR_280: |
836 if (isa_dev->id_iobase != 0x280) 837 return (0); | 836 if (rman_get_start(sc->port_res) != 0x280) 837 return (ENXIO); |
838 break; 839 case ED_3COM_BCFR_2A0: | 838 break; 839 case ED_3COM_BCFR_2A0: |
840 if (isa_dev->id_iobase != 0x2a0) 841 return (0); | 840 if (rman_get_start(sc->port_res) != 0x2a0) 841 return (ENXIO); |
842 break; 843 case ED_3COM_BCFR_2E0: | 842 break; 843 case ED_3COM_BCFR_2E0: |
844 if (isa_dev->id_iobase != 0x2e0) 845 return (0); | 844 if (rman_get_start(sc->port_res) != 0x2e0) 845 return (ENXIO); |
846 break; 847 default: | 846 break; 847 default: |
848 return (0); | 848 return (ENXIO); |
849 } 850 | 849 } 850 |
851 error = ISA_GET_RESOURCE(device_get_parent(dev), dev, 852 SYS_RES_MEMORY, 0, 853 &conf_maddr, &conf_msize); 854 if (error) 855 return (error); 856 |
|
851 /* 852 * Verify that the kernel shared memory address matches the board 853 * configured address. 854 */ 855 switch (inb(sc->asic_addr + ED_3COM_PCFR)) { 856 case ED_3COM_PCFR_DC000: | 857 /* 858 * Verify that the kernel shared memory address matches the board 859 * configured address. 860 */ 861 switch (inb(sc->asic_addr + ED_3COM_PCFR)) { 862 case ED_3COM_PCFR_DC000: |
857 if (kvtop(isa_dev->id_maddr) != 0xdc000) 858 return (0); | 863 if (conf_maddr != 0xdc000) 864 return (ENXIO); |
859 break; 860 case ED_3COM_PCFR_D8000: | 865 break; 866 case ED_3COM_PCFR_D8000: |
861 if (kvtop(isa_dev->id_maddr) != 0xd8000) 862 return (0); | 867 if (conf_maddr != 0xd8000) 868 return (ENXIO); |
863 break; 864 case ED_3COM_PCFR_CC000: | 869 break; 870 case ED_3COM_PCFR_CC000: |
865 if (kvtop(isa_dev->id_maddr) != 0xcc000) 866 return (0); | 871 if (conf_maddr != 0xcc000) 872 return (ENXIO); |
867 break; 868 case ED_3COM_PCFR_C8000: | 873 break; 874 case ED_3COM_PCFR_C8000: |
869 if (kvtop(isa_dev->id_maddr) != 0xc8000) 870 return (0); | 875 if (conf_maddr != 0xc8000) 876 return (ENXIO); |
871 break; 872 default: | 877 break; 878 default: |
873 return (0); | 879 return (ENXIO); |
874 } 875 876 877 /* 878 * Reset NIC and ASIC. Enable on-board transceiver throughout reset 879 * sequence because it'll lock up if the cable isn't connected if we 880 * don't. 881 */ --- 75 unchanged lines hidden (view full) --- 957 else 958 isa16bit = 0; 959 960 /* 961 * select page 0 registers 962 */ 963 outb(sc->nic_addr + ED_P2_CR, ED_CR_RD2 | ED_CR_STP); 964 | 880 } 881 882 883 /* 884 * Reset NIC and ASIC. Enable on-board transceiver throughout reset 885 * sequence because it'll lock up if the cable isn't connected if we 886 * don't. 887 */ --- 75 unchanged lines hidden (view full) --- 963 else 964 isa16bit = 0; 965 966 /* 967 * select page 0 registers 968 */ 969 outb(sc->nic_addr + ED_P2_CR, ED_CR_RD2 | ED_CR_STP); 970 |
965 sc->mem_start = (caddr_t) isa_dev->id_maddr; | 971 error = ed_alloc_memory(dev, 0, memsize); 972 if (error) 973 return (error); 974 975 sc->mem_start = (caddr_t) rman_get_virtual(sc->mem_res); |
966 sc->mem_size = memsize; 967 sc->mem_end = sc->mem_start + memsize; 968 969 /* 970 * We have an entire 8k window to put the transmit buffers on the 971 * 16bit boards. But since the 16bit 3c503's shared memory is only 972 * fast enough to overlap the loading of one full-size packet, trying 973 * to load more than 2 buffers can actually leave the transmitter idle 974 * during the load. So 2 seems the best value. (Although a mix of 975 * variable-sized packets might change this assumption. Nonetheless, 976 * we optimize for linear transfers of same-size packets.) 977 */ 978 if (isa16bit) { | 976 sc->mem_size = memsize; 977 sc->mem_end = sc->mem_start + memsize; 978 979 /* 980 * We have an entire 8k window to put the transmit buffers on the 981 * 16bit boards. But since the 16bit 3c503's shared memory is only 982 * fast enough to overlap the loading of one full-size packet, trying 983 * to load more than 2 buffers can actually leave the transmitter idle 984 * during the load. So 2 seems the best value. (Although a mix of 985 * variable-sized packets might change this assumption. Nonetheless, 986 * we optimize for linear transfers of same-size packets.) 987 */ 988 if (isa16bit) { |
979 if (isa_dev->id_flags & ED_FLAGS_NO_MULTI_BUFFERING) | 989 if (flags & ED_FLAGS_NO_MULTI_BUFFERING) |
980 sc->txb_cnt = 1; 981 else 982 sc->txb_cnt = 2; 983 984 sc->tx_page_start = ED_3COM_TX_PAGE_OFFSET_16BIT; 985 sc->rec_page_start = ED_3COM_RX_PAGE_OFFSET_16BIT; 986 sc->rec_page_stop = memsize / ED_PAGE_SIZE + 987 ED_3COM_RX_PAGE_OFFSET_16BIT; --- 14 unchanged lines hidden (view full) --- 1002 * doing DMA, but what the hell. 1003 */ 1004 outb(sc->asic_addr + ED_3COM_PSTR, sc->rec_page_start); 1005 outb(sc->asic_addr + ED_3COM_PSPR, sc->rec_page_stop); 1006 1007 /* 1008 * Set IRQ. 3c503 only allows a choice of irq 2-5. 1009 */ | 990 sc->txb_cnt = 1; 991 else 992 sc->txb_cnt = 2; 993 994 sc->tx_page_start = ED_3COM_TX_PAGE_OFFSET_16BIT; 995 sc->rec_page_start = ED_3COM_RX_PAGE_OFFSET_16BIT; 996 sc->rec_page_stop = memsize / ED_PAGE_SIZE + 997 ED_3COM_RX_PAGE_OFFSET_16BIT; --- 14 unchanged lines hidden (view full) --- 1012 * doing DMA, but what the hell. 1013 */ 1014 outb(sc->asic_addr + ED_3COM_PSTR, sc->rec_page_start); 1015 outb(sc->asic_addr + ED_3COM_PSPR, sc->rec_page_stop); 1016 1017 /* 1018 * Set IRQ. 3c503 only allows a choice of irq 2-5. 1019 */ |
1010 switch (isa_dev->id_irq) { 1011 case IRQ2: | 1020 error = ISA_GET_RESOURCE(device_get_parent(dev), dev, 1021 SYS_RES_IRQ, 0, 1022 &irq, &junk); 1023 if (error) 1024 return (error); 1025 1026 switch (irq) { 1027 case 2: |
1012 outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ2); 1013 break; | 1028 outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ2); 1029 break; |
1014 case IRQ3: | 1030 case 3: |
1015 outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ3); 1016 break; | 1031 outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ3); 1032 break; |
1017 case IRQ4: | 1033 case 4: |
1018 outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ4); 1019 break; | 1034 outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ4); 1035 break; |
1020 case IRQ5: | 1036 case 5: |
1021 outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ5); 1022 break; 1023 default: | 1037 outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ5); 1038 break; 1039 default: |
1024 printf("ed%d: Invalid irq configuration (%d) must be 3-5,9 for 3c503\n", 1025 isa_dev->id_unit, ffs(isa_dev->id_irq) - 1); 1026 return (0); | 1040 device_printf(dev, "Invalid irq configuration (%ld) must be 3-5,9 for 3c503\n", 1041 irq); 1042 return (ENXIO); |
1027 } 1028 1029 /* 1030 * Initialize GA configuration register. Set bank and enable shared 1031 * mem. 1032 */ 1033 outb(sc->asic_addr + ED_3COM_GACFR, ED_3COM_GACFR_RSEL | 1034 ED_3COM_GACFR_MBS0); --- 10 unchanged lines hidden (view full) --- 1045 1046 /* 1047 * Zero memory and verify that it is clear 1048 */ 1049 bzero(sc->mem_start, memsize); 1050 1051 for (i = 0; i < memsize; ++i) 1052 if (sc->mem_start[i]) { | 1043 } 1044 1045 /* 1046 * Initialize GA configuration register. Set bank and enable shared 1047 * mem. 1048 */ 1049 outb(sc->asic_addr + ED_3COM_GACFR, ED_3COM_GACFR_RSEL | 1050 ED_3COM_GACFR_MBS0); --- 10 unchanged lines hidden (view full) --- 1061 1062 /* 1063 * Zero memory and verify that it is clear 1064 */ 1065 bzero(sc->mem_start, memsize); 1066 1067 for (i = 0; i < memsize; ++i) 1068 if (sc->mem_start[i]) { |
1053 printf("ed%d: failed to clear shared memory at %lx - check configuration\n", 1054 isa_dev->id_unit, kvtop(sc->mem_start + i)); 1055 return (0); | 1069 device_printf(dev, "failed to clear shared memory at %lx - check configuration\n", 1070 kvtop(sc->mem_start + i)); 1071 return (ENXIO); |
1056 } | 1072 } |
1057 isa_dev->id_msize = memsize; 1058 return (ED_3COM_IO_PORTS); | 1073 return (0); |
1059} 1060 1061/* 1062 * Probe and vendor-specific initialization routine for NE1000/2000 boards 1063 */ 1064static int | 1074} 1075 1076/* 1077 * Probe and vendor-specific initialization routine for NE1000/2000 boards 1078 */ 1079static int |
1065ed_probe_Novell_generic(sc, port, unit, flags) 1066 struct ed_softc *sc; 1067 int port; 1068 int unit; | 1080ed_probe_Novell_generic(dev, port_rid, flags) 1081 device_t dev; 1082 int port_rid; |
1069 int flags; 1070{ | 1083 int flags; 1084{ |
1085 struct ed_softc *sc = device_get_softc(dev); |
|
1071 u_int memsize, n; 1072 u_char romdata[16], tmp; 1073 static char test_pattern[32] = "THIS is A memory TEST pattern"; 1074 char test_buffer[32]; | 1086 u_int memsize, n; 1087 u_char romdata[16], tmp; 1088 static char test_pattern[32] = "THIS is A memory TEST pattern"; 1089 char test_buffer[32]; |
1090 int error; |
|
1075 | 1091 |
1076 sc->asic_addr = port + ED_NOVELL_ASIC_OFFSET; 1077 sc->nic_addr = port + ED_NOVELL_NIC_OFFSET; | 1092 error = ed_alloc_port(dev, port_rid, ED_NOVELL_IO_PORTS); 1093 if (error) 1094 return (error); |
1078 | 1095 |
1096 sc->asic_addr = rman_get_start(sc->port_res) + ED_NOVELL_ASIC_OFFSET; 1097 sc->nic_addr = rman_get_start(sc->port_res) + ED_NOVELL_NIC_OFFSET; 1098 |
|
1079 /* XXX - do Novell-specific probe here */ 1080 1081 /* Reset the board */ 1082#ifdef GWETHER 1083 outb(sc->asic_addr + ED_NOVELL_RESET, 0); 1084 DELAY(200); 1085#endif /* GWETHER */ 1086 tmp = inb(sc->asic_addr + ED_NOVELL_RESET); --- 16 unchanged lines hidden (view full) --- 1103 * judgement. -DLG 1104 */ 1105 outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1106 1107 DELAY(5000); 1108 1109 /* Make sure that we really have an 8390 based board */ 1110 if (!ed_probe_generic8390(sc)) | 1099 /* XXX - do Novell-specific probe here */ 1100 1101 /* Reset the board */ 1102#ifdef GWETHER 1103 outb(sc->asic_addr + ED_NOVELL_RESET, 0); 1104 DELAY(200); 1105#endif /* GWETHER */ 1106 tmp = inb(sc->asic_addr + ED_NOVELL_RESET); --- 16 unchanged lines hidden (view full) --- 1123 * judgement. -DLG 1124 */ 1125 outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2 | ED_CR_STP); 1126 1127 DELAY(5000); 1128 1129 /* Make sure that we really have an 8390 based board */ 1130 if (!ed_probe_generic8390(sc)) |
1111 return (0); | 1131 return (ENXIO); |
1112 1113 sc->vendor = ED_VENDOR_NOVELL; 1114 sc->mem_shared = 0; 1115 sc->cr_proto = ED_CR_RD2; 1116 1117 /* 1118 * Test the ability to read and write to the NIC memory. This has the 1119 * side affect of determining if this is an NE1000 or an NE2000. --- 33 unchanged lines hidden (view full) --- 1153 /* 1154 * Write a test pattern in word mode. If this also fails, then 1155 * we don't know what this board is. 1156 */ 1157 ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern)); 1158 ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern)); 1159 1160 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) | 1132 1133 sc->vendor = ED_VENDOR_NOVELL; 1134 sc->mem_shared = 0; 1135 sc->cr_proto = ED_CR_RD2; 1136 1137 /* 1138 * Test the ability to read and write to the NIC memory. This has the 1139 * side affect of determining if this is an NE1000 or an NE2000. --- 33 unchanged lines hidden (view full) --- 1173 /* 1174 * Write a test pattern in word mode. If this also fails, then 1175 * we don't know what this board is. 1176 */ 1177 ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern)); 1178 ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern)); 1179 1180 if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) |
1161 return (0); /* not an NE2000 either */ | 1181 return (ENXIO); /* not an NE2000 either */ |
1162 1163 sc->type = ED_TYPE_NE2000; 1164 sc->type_str = "NE2000"; 1165 } else { 1166 sc->type = ED_TYPE_NE1000; 1167 sc->type_str = "NE1000"; 1168 } 1169 --- 38 unchanged lines hidden (view full) --- 1208 mstart = x * ED_PAGE_SIZE; 1209 msize = ED_PAGE_SIZE; 1210 break; 1211 } 1212 } 1213 } 1214 1215 if (mstart == 0) { | 1182 1183 sc->type = ED_TYPE_NE2000; 1184 sc->type_str = "NE2000"; 1185 } else { 1186 sc->type = ED_TYPE_NE1000; 1187 sc->type_str = "NE1000"; 1188 } 1189 --- 38 unchanged lines hidden (view full) --- 1228 mstart = x * ED_PAGE_SIZE; 1229 msize = ED_PAGE_SIZE; 1230 break; 1231 } 1232 } 1233 } 1234 1235 if (mstart == 0) { |
1216 printf("ed%d: Cannot find start of RAM.\n", unit); 1217 return 0; | 1236 device_printf(dev, "Cannot find start of RAM.\n"); 1237 return (ENXIO); |
1218 } 1219 /* Search for the start of RAM. */ 1220 for (x = (mstart / ED_PAGE_SIZE) + 1; x < 256; x++) { 1221 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); 1222 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) { 1223 for (i = 0; i < ED_PAGE_SIZE; i++) 1224 pbuf[i] = 255 - x; 1225 ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE); --- 4 unchanged lines hidden (view full) --- 1230 break; 1231 } 1232 } else { 1233 break; 1234 } 1235 } 1236 1237 if (msize == 0) { | 1238 } 1239 /* Search for the start of RAM. */ 1240 for (x = (mstart / ED_PAGE_SIZE) + 1; x < 256; x++) { 1241 ed_pio_readmem(sc, x * 256, tbuf, ED_PAGE_SIZE); 1242 if (bcmp(pbuf0, tbuf, ED_PAGE_SIZE) == 0) { 1243 for (i = 0; i < ED_PAGE_SIZE; i++) 1244 pbuf[i] = 255 - x; 1245 ed_pio_writemem(sc, pbuf, x * 256, ED_PAGE_SIZE); --- 4 unchanged lines hidden (view full) --- 1250 break; 1251 } 1252 } else { 1253 break; 1254 } 1255 } 1256 1257 if (msize == 0) { |
1238 printf("ed%d: Cannot find any RAM, start : %d, x = %d.\n", unit, mstart, x); 1239 return 0; | 1258 device_printf(dev, "Cannot find any RAM, start : %d, x = %d.\n", mstart, x); 1259 return (ENXIO); |
1240 } | 1260 } |
1241 printf("ed%d: RAM start at %d, size : %d.\n", unit, mstart, msize); | 1261 device_printf(dev, "RAM start at %d, size : %d.\n", mstart, msize); |
1242 1243 sc->mem_size = msize; 1244 sc->mem_start = (char *) mstart; 1245 sc->mem_end = (char *) (msize + mstart); 1246 sc->tx_page_start = mstart / ED_PAGE_SIZE; 1247 } 1248#endif /* GWETHER */ 1249 --- 19 unchanged lines hidden (view full) --- 1269 if (sc->arpcom.ac_enaddr[2] == 0x86) { 1270 sc->type_str = "Gateway AT"; 1271 } 1272#endif /* GWETHER */ 1273 1274 /* clear any pending interrupts that might have occurred above */ 1275 outb(sc->nic_addr + ED_P0_ISR, 0xff); 1276 | 1262 1263 sc->mem_size = msize; 1264 sc->mem_start = (char *) mstart; 1265 sc->mem_end = (char *) (msize + mstart); 1266 sc->tx_page_start = mstart / ED_PAGE_SIZE; 1267 } 1268#endif /* GWETHER */ 1269 --- 19 unchanged lines hidden (view full) --- 1289 if (sc->arpcom.ac_enaddr[2] == 0x86) { 1290 sc->type_str = "Gateway AT"; 1291 } 1292#endif /* GWETHER */ 1293 1294 /* clear any pending interrupts that might have occurred above */ 1295 outb(sc->nic_addr + ED_P0_ISR, 0xff); 1296 |
1277 return (ED_NOVELL_IO_PORTS); | 1297 return (0); |
1278} 1279 1280static int | 1298} 1299 1300static int |
1281ed_probe_Novell(isa_dev) 1282 struct isa_device *isa_dev; | 1301ed_probe_Novell(dev) 1302 device_t dev; |
1283{ | 1303{ |
1284 struct ed_softc *sc = &ed_softc[isa_dev->id_unit]; 1285 int nports; 1286 1287 nports = ed_probe_Novell_generic(sc, isa_dev->id_iobase, 1288 isa_dev->id_unit, isa_dev->id_flags); 1289 if (nports) 1290 isa_dev->id_maddr = 0; 1291 1292 return (nports); | 1304 return ed_probe_Novell_generic(dev, 0, isa_get_flags(dev)); |
1293} 1294 | 1305} 1306 |
1295#if NCARD > 0 | 1307#if NCARDxx > 0 |
1296/* 1297 * Probe framework for pccards. Replicates the standard framework, 1298 * minus the pccard driver registration and ignores the ether address 1299 * supplied (from the CIS), relying on the probe to find it instead. 1300 */ 1301static int 1302ed_probe_pccard(isa_dev, ether) 1303 struct isa_device *isa_dev; --- 34 unchanged lines hidden (view full) --- 1338 * is inactive. 1339 * 1340 * For more information; please consult the CRYNWR packet driver. 1341 * 1342 * The AUI port is turned on using the "link2" option on the ifconfig 1343 * command line. 1344 */ 1345static int | 1308/* 1309 * Probe framework for pccards. Replicates the standard framework, 1310 * minus the pccard driver registration and ignores the ether address 1311 * supplied (from the CIS), relying on the probe to find it instead. 1312 */ 1313static int 1314ed_probe_pccard(isa_dev, ether) 1315 struct isa_device *isa_dev; --- 34 unchanged lines hidden (view full) --- 1350 * is inactive. 1351 * 1352 * For more information; please consult the CRYNWR packet driver. 1353 * 1354 * The AUI port is turned on using the "link2" option on the ifconfig 1355 * command line. 1356 */ 1357static int |
1346ed_probe_HP_pclanp(isa_dev) 1347 struct isa_device *isa_dev; | 1358ed_probe_HP_pclanp(dev) 1359 device_t dev; |
1348{ | 1360{ |
1349 struct ed_softc *sc = &ed_softc[isa_dev->id_unit]; | 1361 struct ed_softc *sc = device_get_softc(dev); 1362 int error; |
1350 int n; /* temp var */ 1351 int memsize; /* mem on board */ 1352 u_char checksum; /* checksum of board address */ 1353 u_char irq; /* board configured IRQ */ 1354 char test_pattern[ED_HPP_TEST_SIZE]; /* read/write areas for */ 1355 char test_buffer[ED_HPP_TEST_SIZE]; /* probing card */ | 1363 int n; /* temp var */ 1364 int memsize; /* mem on board */ 1365 u_char checksum; /* checksum of board address */ 1366 u_char irq; /* board configured IRQ */ 1367 char test_pattern[ED_HPP_TEST_SIZE]; /* read/write areas for */ 1368 char test_buffer[ED_HPP_TEST_SIZE]; /* probing card */ |
1369 u_long conf_maddr, conf_msize, conf_irq, junk; |
|
1356 | 1370 |
1371 error = ed_alloc_port(dev, 0, ED_HPP_IO_PORTS); 1372 if (error) 1373 return (error); |
|
1357 1358 /* Fill in basic information */ | 1374 1375 /* Fill in basic information */ |
1359 sc->asic_addr = isa_dev->id_iobase + ED_HPP_ASIC_OFFSET; 1360 sc->nic_addr = isa_dev->id_iobase + ED_HPP_NIC_OFFSET; | 1376 sc->asic_addr = rman_get_start(sc->port_res) + ED_HPP_ASIC_OFFSET; 1377 sc->nic_addr = rman_get_start(sc->port_res) + ED_HPP_NIC_OFFSET; |
1361 sc->is790 = 0; 1362 sc->isa16bit = 0; /* the 8390 core needs to be in byte mode */ 1363 1364 /* 1365 * Look for the HP PCLAN+ signature: "0x50,0x48,0x00,0x53" 1366 */ 1367 1368 if ((inb(sc->asic_addr + ED_HPP_ID) != 0x50) || --- 63 unchanged lines hidden (view full) --- 1432 outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_HW); 1433 1434 irq = inb(sc->asic_addr + ED_HPP_HW_IRQ); 1435 1436 /* 1437 * Check for impossible IRQ. 1438 */ 1439 | 1378 sc->is790 = 0; 1379 sc->isa16bit = 0; /* the 8390 core needs to be in byte mode */ 1380 1381 /* 1382 * Look for the HP PCLAN+ signature: "0x50,0x48,0x00,0x53" 1383 */ 1384 1385 if ((inb(sc->asic_addr + ED_HPP_ID) != 0x50) || --- 63 unchanged lines hidden (view full) --- 1449 outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_HW); 1450 1451 irq = inb(sc->asic_addr + ED_HPP_HW_IRQ); 1452 1453 /* 1454 * Check for impossible IRQ. 1455 */ 1456 |
1440 if (irq >= (sizeof(ed_hpp_intr_mask) / sizeof(ed_hpp_intr_mask[0]))) | 1457 if (irq >= (sizeof(ed_hpp_intr_val) / sizeof(ed_hpp_intr_val[0]))) |
1441 return 0; 1442 1443 /* 1444 * If the kernel IRQ was specified with a '?' use the cards idea 1445 * of the IRQ. If the kernel IRQ was explicitly specified, it 1446 * should match that of the hardware. 1447 */ | 1458 return 0; 1459 1460 /* 1461 * If the kernel IRQ was specified with a '?' use the cards idea 1462 * of the IRQ. If the kernel IRQ was explicitly specified, it 1463 * should match that of the hardware. 1464 */ |
1465 error = ISA_GET_RESOURCE(device_get_parent(dev), dev, 1466 SYS_RES_IRQ, 0, 1467 &conf_irq, &junk); 1468 if (error) { 1469 ISA_SET_RESOURCE(device_get_parent(dev), dev, 1470 SYS_RES_IRQ, 0, 1471 ed_hpp_intr_val[irq], 1); 1472 } else { 1473 if (conf_irq != ed_hpp_intr_val[irq]) 1474 return (ENXIO); 1475 } |
|
1448 | 1476 |
1449 if (isa_dev->id_irq <= 0) 1450 isa_dev->id_irq = ed_hpp_intr_mask[irq]; 1451 else if (isa_dev->id_irq != ed_hpp_intr_mask[irq]) 1452 return 0; 1453 | |
1454 /* 1455 * Fill in softconfig info. 1456 */ 1457 1458 sc->vendor = ED_VENDOR_HP; 1459 sc->type = ED_TYPE_HP_PCLANPLUS; 1460 sc->type_str = "HP-PCLAN+"; 1461 1462 sc->mem_shared = 0; /* we DON'T have dual ported RAM */ 1463 sc->mem_start = 0; /* we use offsets inside the card RAM */ 1464 1465 sc->hpp_mem_start = NULL;/* no memory mapped I/O by default */ 1466 1467 /* | 1477 /* 1478 * Fill in softconfig info. 1479 */ 1480 1481 sc->vendor = ED_VENDOR_HP; 1482 sc->type = ED_TYPE_HP_PCLANPLUS; 1483 sc->type_str = "HP-PCLAN+"; 1484 1485 sc->mem_shared = 0; /* we DON'T have dual ported RAM */ 1486 sc->mem_start = 0; /* we use offsets inside the card RAM */ 1487 1488 sc->hpp_mem_start = NULL;/* no memory mapped I/O by default */ 1489 1490 /* |
1491 * The board has 32KB of memory. Is there a way to determine 1492 * this programmatically? 1493 */ 1494 1495 memsize = 32768; 1496 1497 /* |
|
1468 * Check if memory mapping of the I/O registers possible. 1469 */ 1470 1471 if (sc->hpp_options & ED_HPP_OPTION_MEM_ENABLE) 1472 { 1473 u_long mem_addr; 1474 1475 /* 1476 * determine the memory address from the board. 1477 */ 1478 1479 outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_HW); 1480 mem_addr = (inw(sc->asic_addr + ED_HPP_HW_MEM_MAP) << 8); 1481 1482 /* 1483 * Check that the kernel specified start of memory and 1484 * hardware's idea of it match. 1485 */ | 1498 * Check if memory mapping of the I/O registers possible. 1499 */ 1500 1501 if (sc->hpp_options & ED_HPP_OPTION_MEM_ENABLE) 1502 { 1503 u_long mem_addr; 1504 1505 /* 1506 * determine the memory address from the board. 1507 */ 1508 1509 outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_HW); 1510 mem_addr = (inw(sc->asic_addr + ED_HPP_HW_MEM_MAP) << 8); 1511 1512 /* 1513 * Check that the kernel specified start of memory and 1514 * hardware's idea of it match. 1515 */ |
1516 error = ISA_GET_RESOURCE(device_get_parent(dev), dev, 1517 SYS_RES_MEMORY, 0, 1518 &conf_maddr, &conf_msize); 1519 if (error) 1520 return (error); |
|
1486 | 1521 |
1487 if (mem_addr != kvtop(isa_dev->id_maddr)) | 1522 if (mem_addr != conf_maddr) |
1488 return 0; 1489 | 1523 return 0; 1524 |
1490 sc->hpp_mem_start = isa_dev->id_maddr; | 1525 error = ed_alloc_memory(dev, 0, memsize); 1526 if (error) 1527 return (error); 1528 1529 sc->hpp_mem_start = rman_get_virtual(sc->mem_res); |
1491 } 1492 1493 /* | 1530 } 1531 1532 /* |
1494 * The board has 32KB of memory. Is there a way to determine 1495 * this programmatically? 1496 */ 1497 1498 memsize = 32768; 1499 1500 /* | |
1501 * Fill in the rest of the soft config structure. 1502 */ 1503 1504 /* 1505 * The transmit page index. 1506 */ 1507 1508 sc->tx_page_start = ED_HPP_TX_PAGE_OFFSET; 1509 | 1533 * Fill in the rest of the soft config structure. 1534 */ 1535 1536 /* 1537 * The transmit page index. 1538 */ 1539 1540 sc->tx_page_start = ED_HPP_TX_PAGE_OFFSET; 1541 |
1510 if (isa_dev->id_flags & ED_FLAGS_NO_MULTI_BUFFERING) | 1542 if (isa_get_flags(dev) & ED_FLAGS_NO_MULTI_BUFFERING) |
1511 sc->txb_cnt = 1; 1512 else 1513 sc->txb_cnt = 2; 1514 1515 /* 1516 * Memory description 1517 */ 1518 --- 111 unchanged lines hidden (view full) --- 1630 /* 1631 * Restore normal pages. 1632 */ 1633 1634 outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_PERF); 1635 1636} 1637 | 1543 sc->txb_cnt = 1; 1544 else 1545 sc->txb_cnt = 2; 1546 1547 /* 1548 * Memory description 1549 */ 1550 --- 111 unchanged lines hidden (view full) --- 1662 /* 1663 * Restore normal pages. 1664 */ 1665 1666 outw(sc->asic_addr + ED_HPP_PAGING, ED_HPP_PAGE_PERF); 1667 1668} 1669 |
1670/* 1671 * Allocate a port resource with the given resource id. 1672 */ 1673static int 1674ed_alloc_port(dev, rid, size) 1675 device_t dev; 1676 int rid; 1677 int size; 1678{ 1679 struct ed_softc *sc = device_get_softc(dev); 1680 struct resource *res; |
|
1638 | 1681 |
1682 res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 1683 0ul, ~0ul, size, RF_ACTIVE); 1684 if (res) { 1685 sc->port_rid = rid; 1686 sc->port_res = res; 1687 sc->port_used = 1; 1688 return (0); 1689 } else { 1690 return (ENOENT); 1691 } 1692} 1693 |
|
1639/* | 1694/* |
1695 * Allocate a memory resource with the given resource id. 1696 */ 1697static int 1698ed_alloc_memory(dev, rid, size) 1699 device_t dev; 1700 int rid; 1701 int size; 1702{ 1703 struct ed_softc *sc = device_get_softc(dev); 1704 struct resource *res; 1705 1706 res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 1707 0ul, ~0ul, size, RF_ACTIVE); 1708 if (res) { 1709 sc->mem_rid = rid; 1710 sc->mem_res = res; 1711 sc->mem_used = 1; 1712 return (0); 1713 } else { 1714 return (ENOENT); 1715 } 1716} 1717 1718/* 1719 * Allocate an irq resource with the given resource id. 1720 */ 1721static int 1722ed_alloc_irq(dev, rid, flags) 1723 device_t dev; 1724 int rid; 1725 int flags; 1726{ 1727 struct ed_softc *sc = device_get_softc(dev); 1728 struct resource *res; 1729 1730 res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 1731 0ul, ~0ul, 1, (RF_ACTIVE | flags)); 1732 if (res) { 1733 sc->irq_rid = rid; 1734 sc->irq_res = res; 1735 return (0); 1736 } else { 1737 return (ENOENT); 1738 } 1739} 1740 1741/* 1742 * Release all resources 1743 */ 1744static void 1745ed_release_resources(dev) 1746 device_t dev; 1747{ 1748 struct ed_softc *sc = device_get_softc(dev); 1749 1750 if (sc->port_res) { 1751 bus_release_resource(dev, SYS_RES_IOPORT, 1752 sc->port_rid, sc->port_res); 1753 sc->port_res = 0; 1754 } 1755 if (sc->mem_res) { 1756 bus_release_resource(dev, SYS_RES_MEMORY, 1757 sc->mem_rid, sc->mem_res); 1758 sc->mem_res = 0; 1759 } 1760 if (sc->irq_res) { 1761 bus_release_resource(dev, SYS_RES_IRQ, 1762 sc->irq_rid, sc->irq_res); 1763 sc->irq_res = 0; 1764 } 1765} 1766 1767/* |
|
1640 * Install interface into kernel networking data structures 1641 */ 1642static int 1643ed_attach(sc, unit, flags) 1644 struct ed_softc *sc; 1645 int unit; 1646 int flags; 1647{ --- 75 unchanged lines hidden (view full) --- 1723 (ifp->if_flags & IFF_ALTPHYS)) ? " tranceiver disabled" : ""); 1724 1725 /* 1726 * If BPF is in the kernel, call the attach for it 1727 */ 1728#if NBPF > 0 1729 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); 1730#endif | 1768 * Install interface into kernel networking data structures 1769 */ 1770static int 1771ed_attach(sc, unit, flags) 1772 struct ed_softc *sc; 1773 int unit; 1774 int flags; 1775{ --- 75 unchanged lines hidden (view full) --- 1851 (ifp->if_flags & IFF_ALTPHYS)) ? " tranceiver disabled" : ""); 1852 1853 /* 1854 * If BPF is in the kernel, call the attach for it 1855 */ 1856#if NBPF > 0 1857 bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); 1858#endif |
1731 return 1; | 1859 return (0); |
1732} 1733 1734static int | 1860} 1861 1862static int |
1735ed_attach_isa(isa_dev) 1736 struct isa_device *isa_dev; | 1863ed_isa_attach(dev) 1864 device_t dev; |
1737{ | 1865{ |
1738 int unit = isa_dev->id_unit; 1739 struct ed_softc *sc = &ed_softc[unit]; 1740 int flags = isa_dev->id_flags; | 1866 struct ed_softc *sc = device_get_softc(dev); 1867 int flags = isa_get_flags(dev); 1868 int error; |
1741 | 1869 |
1742 isa_dev->id_ointr = edintr; 1743 return ed_attach(sc, unit, flags); | 1870 if (sc->port_used > 0) 1871 ed_alloc_port(dev, sc->port_rid, 1); 1872 if (sc->mem_used) 1873 ed_alloc_memory(dev, sc->mem_rid, 1); 1874 ed_alloc_irq(dev, sc->irq_rid, 0); 1875 1876 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, 1877 edintr, sc, &sc->irq_handle); 1878 if (error) { 1879 ed_release_resources(dev); 1880 return (error); 1881 } 1882 1883 return ed_attach(sc, device_get_unit(dev), flags); |
1744} 1745 1746#if NPCI > 0 | 1884} 1885 1886#if NPCI > 0 |
1747void * 1748ed_attach_NE2000_pci(unit, port) 1749 int unit; 1750 int port; | 1887int 1888ed_attach_NE2000_pci(dev, port_rid) 1889 device_t dev; 1890 int port_rid; |
1751{ | 1891{ |
1752 struct ed_softc *sc = malloc(sizeof *sc, M_DEVBUF, M_NOWAIT); 1753 int isa_flags = 0; | 1892 struct ed_softc *sc = device_get_softc(dev); 1893 int flags = 0; 1894 int error; |
1754 | 1895 |
1755 if (!sc) 1756 return sc; | 1896 error = ed_probe_Novell_generic(dev, port_rid, flags); 1897 if (error) 1898 return (error); |
1757 | 1899 |
1758 bzero(sc, sizeof *sc); 1759 if (ed_probe_Novell_generic(sc, port, unit, isa_flags) == 0 1760 || ed_attach(sc, unit, isa_flags) == 0) { 1761 free(sc, M_DEVBUF); 1762 return NULL; | 1900 error = ed_alloc_irq(dev, 0, RF_SHAREABLE); 1901 if (error) { 1902 ed_release_resources(dev); 1903 return (error); |
1763 } | 1904 } |
1764 return sc; | 1905 1906 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET, 1907 edintr, sc, &sc->irq_handle); 1908 if (error) { 1909 ed_release_resources(dev); 1910 return (error); 1911 } 1912 1913 return ed_attach(sc, device_get_unit(dev), flags); |
1765} 1766#endif 1767 1768/* 1769 * Reset interface. 1770 */ 1771static void 1772ed_reset(ifp) --- 555 unchanged lines hidden (view full) --- 2328 */ 2329 outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA); 2330 } 2331} 2332 2333/* 2334 * Ethernet interface interrupt processor 2335 */ | 1914} 1915#endif 1916 1917/* 1918 * Reset interface. 1919 */ 1920static void 1921ed_reset(ifp) --- 555 unchanged lines hidden (view full) --- 2477 */ 2478 outb(sc->nic_addr + ED_P0_CR, sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA); 2479 } 2480} 2481 2482/* 2483 * Ethernet interface interrupt processor 2484 */ |
2336void 2337edintr_sc(sc) 2338 struct ed_softc *sc; | 2485static void 2486edintr(arg) 2487 void *arg; |
2339{ | 2488{ |
2489 struct ed_softc *sc = (struct ed_softc*) arg; |
|
2340 struct ifnet *ifp = (struct ifnet *)sc; 2341 u_char isr; 2342 2343 if (sc->gone) 2344 return; 2345 /* 2346 * Set NIC to page 0 registers 2347 */ --- 222 unchanged lines hidden (view full) --- 2570 if (isr & ED_ISR_CNT) { 2571 (void) inb(sc->nic_addr + ED_P0_CNTR0); 2572 (void) inb(sc->nic_addr + ED_P0_CNTR1); 2573 (void) inb(sc->nic_addr + ED_P0_CNTR2); 2574 } 2575 } 2576} 2577 | 2490 struct ifnet *ifp = (struct ifnet *)sc; 2491 u_char isr; 2492 2493 if (sc->gone) 2494 return; 2495 /* 2496 * Set NIC to page 0 registers 2497 */ --- 222 unchanged lines hidden (view full) --- 2720 if (isr & ED_ISR_CNT) { 2721 (void) inb(sc->nic_addr + ED_P0_CNTR0); 2722 (void) inb(sc->nic_addr + ED_P0_CNTR1); 2723 (void) inb(sc->nic_addr + ED_P0_CNTR2); 2724 } 2725 } 2726} 2727 |
2578static void 2579edintr(unit) 2580 int unit; 2581{ 2582 edintr_sc (&ed_softc[unit]); 2583} 2584 | |
2585/* 2586 * Process an ioctl request. This code needs some work - it looks 2587 * pretty ugly. 2588 */ 2589static int 2590ed_ioctl(ifp, command, data) 2591 register struct ifnet *ifp; 2592 u_long command; --- 841 unchanged lines hidden (view full) --- 3434 if (ifma->ifma_addr->sa_family != AF_LINK) 3435 continue; 3436 index = ds_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)) 3437 >> 26; 3438 af[index >> 3] |= 1 << (index & 7); 3439 } 3440} 3441 | 2728/* 2729 * Process an ioctl request. This code needs some work - it looks 2730 * pretty ugly. 2731 */ 2732static int 2733ed_ioctl(ifp, command, data) 2734 register struct ifnet *ifp; 2735 u_long command; --- 841 unchanged lines hidden (view full) --- 3577 if (ifma->ifma_addr->sa_family != AF_LINK) 3578 continue; 3579 index = ds_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr)) 3580 >> 26; 3581 af[index >> 3] |= 1 << (index & 7); 3582 } 3583} 3584 |
3442/* 3443 * support PnP cards if we are using 'em 3444 */ | 3585static device_method_t ed_isa_methods[] = { 3586 /* Device interface */ 3587 DEVMETHOD(device_probe, ed_isa_probe), 3588 DEVMETHOD(device_attach, ed_isa_attach), |
3445 | 3589 |
3446#if NPNP > 0 3447 3448static pnpid_t edpnp_ids[] = { 3449 { 0xd680d041, "NE2000"}, 3450 { 0 } | 3590 { 0, 0 } |
3451}; 3452 | 3591}; 3592 |
3453static char *edpnp_probe(u_long csn, u_long vend_id); 3454static void edpnp_attach(u_long csn, u_long vend_id, char *name, 3455 struct isa_device *dev); 3456static u_long nedpnp = NED; 3457 3458static struct pnp_device edpnp = { 3459 "edpnp", 3460 edpnp_probe, 3461 edpnp_attach, 3462 &nedpnp, 3463 &net_imask | 3593static driver_t ed_isa_driver = { 3594 "ed", 3595 ed_isa_methods, 3596 sizeof(struct ed_softc) |
3464}; | 3597}; |
3465DATA_SET (pnpdevice_set, edpnp); | |
3466 | 3598 |
3467static char * 3468edpnp_probe(u_long csn, u_long vend_id) 3469{ 3470 pnpid_t *id; 3471 char *s = NULL; | 3599static devclass_t ed_isa_devclass; |
3472 | 3600 |
3473 for(id = edpnp_ids; id->vend_id != 0; id++) { 3474 if (vend_id == id->vend_id) { 3475 s = id->id_str; 3476 break; 3477 } 3478 } 3479 3480 if (s) { 3481 struct pnp_cinfo d; 3482 read_pnp_parms(&d, 0); 3483 if (d.enable == 0 || d.flags & 1) { 3484 printf("CSN %lu is disabled.\n", csn); 3485 return (NULL); 3486 } 3487 3488 } 3489 3490 return (s); 3491} 3492 3493static void 3494edpnp_attach(u_long csn, u_long vend_id, char *name, struct isa_device *dev) 3495{ 3496 struct pnp_cinfo d; 3497 3498 if (dev->id_unit >= NEDTOT) 3499 return; 3500 3501 if (read_pnp_parms(&d, 0) == 0) { 3502 printf("failed to read pnp parms\n"); 3503 return; 3504 } 3505 3506 write_pnp_parms(&d, 0); 3507 3508 enable_pnp_card(); 3509 3510 dev->id_iobase = d.port[0]; 3511 dev->id_irq = (1 << d.irq[0]); 3512 dev->id_ointr = edintr; 3513 dev->id_drq = -1; 3514 3515 if (dev->id_driver == NULL) { 3516 dev->id_driver = &eddriver; 3517 dev->id_id = isa_compat_nextid(); 3518 } 3519 3520 if ((dev->id_alive = ed_probe(dev)) != 0) 3521 ed_attach_isa(dev); 3522 else 3523 printf("ed%d: probe failed\n", dev->id_unit); 3524} 3525#endif | 3601DRIVER_MODULE(ed, isa, ed_isa_driver, ed_isa_devclass, 0, 0); |