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/systm.h> 32#include <sys/kernel.h> 33#include <sys/socket.h> 34#include <sys/lock.h> 35#include <sys/module.h> 36#include <sys/mutex.h> 37#include <sys/bus.h> 38 39#include <machine/bus.h> 40#include <machine/resource.h> 41#include <sys/rman.h> 42 43#include <net/if.h> 44#include <net/if_media.h> 45 46#include <dev/mca/mca_busreg.h> 47#include <dev/mca/mca_busvar.h> 48 49#include <dev/ep/if_epreg.h> 50#include <dev/ep/if_epvar.h> 51 52#define EP_MCA_627C 0x627C 53#define EP_MCA_627D 0x627D 54#define EP_MCA_62DB 0x62db 55#define EP_MCA_62F6 0x62f6 56#define EP_MCA_62F7 0x62f7 57 58static struct mca_ident ep_mca_devs[] = { 59 {EP_MCA_627C, "3Com 3C529 Network Adapter"}, 60 {EP_MCA_627D, "3Com 3C529-TP Network Adapter"}, 61 62 /* 63 * These are from the linux 3c509 driver. 64 * I have not seen the ADFs for them and have 65 * not tested or even seen the hardware. 66 * Someone with the ADFs should replace the names with 67 * whatever is in the AdapterName field of the ADF. 68 * (and fix the media setup for the cards as well.) 69 */ 70 {EP_MCA_62DB, "3Com 3c529 EtherLink III (test mode)"}, 71 {EP_MCA_62F6, "3Com 3c529 EtherLink III (TP or coax)"}, 72 {EP_MCA_62F7, "3Com 3c529 EtherLink III (TP)"}, 73 74 {0, NULL}, 75}; 76 77#define EP_MCA_IOPORT_POS MCA_ADP_POS(MCA_POS2) 78#define EP_MCA_IOPORT_MASK 0xfc 79#define EP_MCA_IOPORT_SIZE EP_IOSIZE 80#define EP_MCA_IOPORT(pos) ((((uint32_t)pos & EP_MCA_IOPORT_MASK) \ 81 | 0x02) << 8) 82 83#define EP_MCA_IRQ_POS MCA_ADP_POS(MCA_POS3) 84#define EP_MCA_IRQ_MASK 0x0f 85#define EP_MCA_IRQ(pos) (pos & EP_MCA_IRQ_MASK) 86 87#define EP_MCA_MEDIA_POS MCA_ADP_POS(MCA_POS2) 88#define EP_MCA_MEDIA_MASK 0x03 89#define EP_MCA_MEDIA(pos) (pos & EP_MCA_MEDIA_MASK) 90 91static int 92ep_mca_probe(device_t dev) 93{ 94 const char *desc; 95 uint32_t iobase = 0; 96 uint8_t irq = 0; 97 uint8_t pos; 98 99 desc = mca_match_id(mca_get_id(dev), ep_mca_devs); 100 if (!desc) 101 return (ENXIO); 102 device_set_desc(dev, desc); 103 104 pos = mca_pos_read(dev, EP_MCA_IOPORT_POS); 105 iobase = EP_MCA_IOPORT(pos); 106 107 pos = mca_pos_read(dev, EP_MCA_IRQ_POS); 108 irq = EP_MCA_IRQ(pos); 109 110 mca_add_iospace(dev, iobase, EP_MCA_IOPORT_SIZE); 111 mca_add_irq(dev, irq); 112 113 return (0); 114} 115 116static int 117ep_mca_attach(device_t dev) 118{ 119 struct ep_softc *sc = device_get_softc(dev); 120 int error = 0; 121 122 if ((error = ep_alloc(dev))) 123 goto bad; 124 sc->stat = F_ACCESS_32_BITS; 125 126 ep_get_media(sc); 127 128 GO_WINDOW(sc, 0); 129 SET_IRQ(sc, rman_get_start(sc->irq)); 130 131 if ((error = ep_attach(sc))) 132 goto bad; 133 if ((error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, NULL, ep_intr, 134 sc, &sc->ep_intrhand))) { 135 device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); 136 goto bad; 137 } 138 return (0); 139bad: 140 ep_free(dev); 141 return (error); 142} 143 144static device_method_t ep_mca_methods[] = { 145 /* Device interface */ 146 DEVMETHOD(device_probe, ep_mca_probe), 147 DEVMETHOD(device_attach, ep_mca_attach), 148 DEVMETHOD(device_detach, ep_detach), 149 150 DEVMETHOD_END 151}; 152 153static driver_t ep_mca_driver = { 154 "ep", 155 ep_mca_methods, 156 sizeof(struct ep_softc), 157}; 158 159static devclass_t ep_devclass; 160 161DRIVER_MODULE(ep, mca, ep_mca_driver, ep_devclass, 0, 0); 162