if_ed_pci.c revision 151300
1101704Smjacob/*- 2139749Simp * Copyright (c) 1996 Stefan Esser <se@freebsd.org> 3101704Smjacob * All rights reserved. 4101704Smjacob * 5101704Smjacob * Redistribution and use in source and binary forms, with or without 6101704Smjacob * modification, are permitted provided that the following conditions 7101704Smjacob * are met: 8101704Smjacob * 1. Redistributions of source code must retain the above copyright 9101704Smjacob * notice immediately at the beginning of the file, without modification, 10101704Smjacob * this list of conditions, and the following disclaimer. 11101704Smjacob * 2. Redistributions in binary form must reproduce the above copyright 12101704Smjacob * notice, this list of conditions and the following disclaimer in the 13101704Smjacob * documentation and/or other materials provided with the distribution. 14101704Smjacob * 3. Absolutely no warranty of function or purpose is made by the author 15101704Smjacob * Stefan Esser. 16101704Smjacob * 4. Modifications may be freely made to this file if the above conditions 17101704Smjacob * are met. 18101704Smjacob */ 19101704Smjacob 20101704Smjacob#include <sys/cdefs.h> 21101704Smjacob__FBSDID("$FreeBSD: head/sys/dev/ed/if_ed_pci.c 151300 2005-10-13 22:12:34Z imp $"); 22101704Smjacob 23101704Smjacob#include <sys/param.h> 24101704Smjacob#include <sys/systm.h> 25101704Smjacob#include <sys/socket.h> 26101704Smjacob#include <sys/kernel.h> 27101704Smjacob 28156000Smjacob#include <sys/module.h> 29156000Smjacob#include <sys/bus.h> 30156000Smjacob 31156000Smjacob#include <machine/bus.h> 32156000Smjacob#include <sys/rman.h> 33156000Smjacob#include <machine/resource.h> 34156000Smjacob 35156000Smjacob#include <net/if.h> 36156000Smjacob#include <net/if_arp.h> 37156000Smjacob#include <net/if_media.h> 38156000Smjacob#include <net/if_mib.h> 39156000Smjacob 40156000Smjacob#include <dev/pci/pcireg.h> 41156000Smjacob#include <dev/pci/pcivar.h> 42156000Smjacob 43156000Smjacob#include <dev/ed/if_edvar.h> 44156000Smjacob#include <dev/ed/rtl80x9reg.h> 45156000Smjacob 46156000Smjacobstatic struct _pcsid 47156000Smjacob{ 48156000Smjacob uint32_t type; 49156000Smjacob const char *desc; 50156000Smjacob} pci_ids[] = 51156000Smjacob{ 52156000Smjacob { ED_RTL8029_PCI_ID, "RealTek 8029" }, 53156000Smjacob { 0x50004a14, "NetVin 5000" }, 54156000Smjacob { 0x09401050, "ProLAN" }, 55156000Smjacob { 0x140111f6, "Compex" }, 56156000Smjacob { 0x30008e2e, "KTI" }, 57156000Smjacob { 0x19808c4a, "Winbond W89C940" }, 58147883Sscottl { 0x0e3410bd, "Surecom NE-34" }, 59156000Smjacob { 0x09261106, "VIA VT86C926" }, 60156000Smjacob { 0x00000000, NULL } 61159052Smjacob}; 62159052Smjacob 63159052Smjacobstatic int ed_pci_probe(device_t); 64159052Smjacobstatic int ed_pci_attach(device_t); 65101704Smjacob 66101704Smjacobstatic int 67147883Sscottled_pci_probe(device_t dev) 68147883Sscottl{ 69147883Sscottl uint32_t type = pci_get_devid(dev); 70147883Sscottl struct _pcsid *ep =pci_ids; 71147883Sscottl 72147883Sscottl while (ep->type && ep->type != type) 73147883Sscottl ++ep; 74147883Sscottl if (ep->desc == NULL) 75147883Sscottl return (ENXIO); 76147883Sscottl device_set_desc(dev, ep->desc); 77147883Sscottl return (BUS_PROBE_DEFAULT); 78147883Sscottl} 79147883Sscottl 80147883Sscottlstatic int 81147883Sscottled_pci_attach(device_t dev) 82148679Sgibbs{ 83148679Sgibbs struct ed_softc *sc = device_get_softc(dev); 84148679Sgibbs int flags = 0; 85147883Sscottl int error = ENXIO; 86147883Sscottl 87147883Sscottl /* 88147883Sscottl * If this card claims to be a RTL8029, probe it as such. 89147883Sscottl * However, allow that probe to fail. Some versions of qemu 90147883Sscottl * claim to be a 8029 in the PCI register, but it doesn't 91147883Sscottl * implement the 8029 specific registers. In that case, fall 92147883Sscottl * back to a normal NE2000. 93147883Sscottl */ 94147883Sscottl if (pci_get_devid(dev) == ED_RTL8029_PCI_ID) 95147883Sscottl error = ed_probe_RTL80x9(dev, PCIR_BAR(0), flags); 96147883Sscottl if (error) 97101704Smjacob error = ed_probe_Novell(dev, PCIR_BAR(0), flags); 98101704Smjacob if (error) { 99101704Smjacob ed_release_resources(dev); 100101704Smjacob return (error); 101147883Sscottl } 102147883Sscottl ed_Novell_read_mac(sc); 103147883Sscottl 104147883Sscottl error = ed_alloc_irq(dev, 0, RF_SHAREABLE); 105147883Sscottl if (error) { 106147883Sscottl ed_release_resources(dev); 107147883Sscottl return (error); 108147883Sscottl } 109147883Sscottl error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, 110147883Sscottl edintr, sc, &sc->irq_handle); 111147883Sscottl if (error) { 112169293Smjacob ed_release_resources(dev); 113147883Sscottl return (error); 114147883Sscottl } 115147883Sscottl 116147883Sscottl error = ed_attach(dev); 117147883Sscottl if (error) 118147883Sscottl ed_release_resources(dev); 119147883Sscottl return (error); 120147883Sscottl} 121147883Sscottl 122147883Sscottlstatic device_method_t ed_pci_methods[] = { 123147883Sscottl /* Device interface */ 124147883Sscottl DEVMETHOD(device_probe, ed_pci_probe), 125147883Sscottl DEVMETHOD(device_attach, ed_pci_attach), 126147883Sscottl DEVMETHOD(device_detach, ed_detach), 127147883Sscottl 128157117Smjacob { 0, 0 } 129157117Smjacob}; 130159179Smjacob 131157117Smjacobstatic driver_t ed_pci_driver = { 132157117Smjacob "ed", 133207287Smarius ed_pci_methods, 134207287Smarius sizeof(struct ed_softc), 135207287Smarius}; 136207287Smarius 137207287SmariusDRIVER_MODULE(ed, pci, ed_pci_driver, ed_devclass, 0, 0); 138147883SscottlMODULE_DEPEND(ed, pci, 1, 1, 1); 139147883SscottlMODULE_DEPEND(ed, ether, 1, 1, 1); 140155521Smjacob