1/*- 2 * Copyright (c) 1999 Matthew N. Dodd <winter@jurai.net> 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 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include <sys/param.h> 31#include <sys/kernel.h> 32#include <sys/socket.h> 33#include <sys/module.h> 34#include <sys/bus.h> 35 36#include <machine/bus.h> 37#include <machine/resource.h> 38#include <sys/rman.h> 39 40#include <net/if.h> 41#include <net/if_arp.h> 42#include <net/if_media.h> 43 44#include <dev/mca/mca_busreg.h> 45#include <dev/mca/mca_busvar.h> 46 47#include <dev/ep/if_epreg.h> 48#include <dev/ep/if_epvar.h> 49 50#define EP_MCA_627C 0x627C 51#define EP_MCA_627D 0x627D 52#define EP_MCA_62DB 0x62db 53#define EP_MCA_62F6 0x62f6 54#define EP_MCA_62F7 0x62f7 55 56static struct mca_ident ep_mca_devs[] = { 57 {EP_MCA_627C, "3Com 3C529 Network Adapter"}, 58 {EP_MCA_627D, "3Com 3C529-TP Network Adapter"}, 59 60 /* 61 * These are from the linux 3c509 driver. 62 * I have not seen the ADFs for them and have 63 * not tested or even seen the hardware. 64 * Someone with the ADFs should replace the names with 65 * whatever is in the AdapterName field of the ADF. 66 * (and fix the media setup for the cards as well.) 67 */ 68 {EP_MCA_62DB, "3Com 3c529 EtherLink III (test mode)"}, 69 {EP_MCA_62F6, "3Com 3c529 EtherLink III (TP or coax)"}, 70 {EP_MCA_62F7, "3Com 3c529 EtherLink III (TP)"}, 71 72 {0, NULL}, 73}; 74 75#define EP_MCA_IOPORT_POS MCA_ADP_POS(MCA_POS2) 76#define EP_MCA_IOPORT_MASK 0xfc 77#define EP_MCA_IOPORT_SIZE EP_IOSIZE 78#define EP_MCA_IOPORT(pos) ((((uint32_t)pos & EP_MCA_IOPORT_MASK) \ 79 | 0x02) << 8) 80 81#define EP_MCA_IRQ_POS MCA_ADP_POS(MCA_POS3) 82#define EP_MCA_IRQ_MASK 0x0f 83#define EP_MCA_IRQ(pos) (pos & EP_MCA_IRQ_MASK) 84 85#define EP_MCA_MEDIA_POS MCA_ADP_POS(MCA_POS2) 86#define EP_MCA_MEDIA_MASK 0x03 87#define EP_MCA_MEDIA(pos) (pos & EP_MCA_MEDIA_MASK) 88 89static int 90ep_mca_probe(device_t dev) 91{ 92 const char *desc; 93 uint32_t iobase = 0; 94 uint8_t irq = 0; 95 uint8_t pos; 96 97 desc = mca_match_id(mca_get_id(dev), ep_mca_devs); 98 if (!desc) 99 return (ENXIO); 100 device_set_desc(dev, desc); 101 102 pos = mca_pos_read(dev, EP_MCA_IOPORT_POS); 103 iobase = EP_MCA_IOPORT(pos); 104 105 pos = mca_pos_read(dev, EP_MCA_IRQ_POS); 106 irq = EP_MCA_IRQ(pos); 107 108 mca_add_iospace(dev, iobase, EP_MCA_IOPORT_SIZE); 109 mca_add_irq(dev, irq); 110 111 return (0); 112} 113 114static int 115ep_mca_attach(device_t dev) 116{ 117 struct ep_softc *sc = device_get_softc(dev); 118 int error = 0; 119 120 if ((error = ep_alloc(dev))) 121 goto bad; 122 sc->stat = F_ACCESS_32_BITS; 123 124 ep_get_media(sc); 125 126 GO_WINDOW(sc, 0); 127 SET_IRQ(sc, rman_get_start(sc->irq)); 128 129 if ((error = ep_attach(sc))) 130 goto bad; 131 if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, NULL, ep_intr, 132 sc, &sc->ep_intrhand))) { 133 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); 134 goto bad; 135 } 136 return (0); 137bad: 138 ep_free(dev); 139 return (error); 140} 141 142static device_method_t ep_mca_methods[] = { 143 /* Device interface */ 144 DEVMETHOD(device_probe, ep_mca_probe), 145 DEVMETHOD(device_attach, ep_mca_attach), 146 DEVMETHOD(device_detach, ep_detach), 147 148 DEVMETHOD_END 149}; 150 151static driver_t ep_mca_driver = { 152 "ep", 153 ep_mca_methods, 154 sizeof(struct ep_softc), 155}; 156 157static devclass_t ep_devclass; 158 159DRIVER_MODULE(ep, mca, ep_mca_driver, ep_devclass, 0, 0); 160