1 /* $OpenBSD: if_ep_eisa.c,v 1.22 2006/06/17 17:58:39 brad Exp $ */ 2 /* $NetBSD: if_ep_eisa.c,v 1.13 1997/04/18 00:50:33 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 1997 Jonathan Stone <jonathan@NetBSD.org> 6 * Copyright (c) 1994 Herb Peyerl <hpeyerl@beer.org> 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by Herb Peyerl. 20 * 4. The name of Herb Peyerl may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include "bpfilter.h" 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/mbuf.h> 40 #include <sys/socket.h> 41 #include <sys/ioctl.h> 42 #include <sys/errno.h> 43 #include <sys/syslog.h> 44 #include <sys/selinfo.h> 45 #include <sys/timeout.h> 46 #include <sys/device.h> 47 48 #include <net/if.h> 49 #include <net/if_dl.h> 50 #include <net/if_types.h> 51 #include <net/netisr.h> 52 #include <net/if_media.h> 53 54 #ifdef INET 55 #include <netinet/in.h> 56 #include <netinet/in_systm.h> 57 #include <netinet/in_var.h> 58 #include <netinet/ip.h> 59 #include <netinet/if_ether.h> 60 #endif 61 62 #if NBPFILTER > 0 63 #include <net/bpf.h> 64 #endif 65 66 #include <machine/cpu.h> 67 #include <machine/bus.h> 68 #include <machine/intr.h> 69 70 #include <dev/mii/mii.h> 71 #include <dev/mii/miivar.h> 72 73 #include <dev/ic/elink3var.h> 74 #include <dev/ic/elink3reg.h> 75 76 #include <dev/eisa/eisareg.h> 77 #include <dev/eisa/eisavar.h> 78 #include <dev/eisa/eisadevs.h> 79 80 int ep_eisa_match(struct device *, void *, void *); 81 void ep_eisa_attach(struct device *, struct device *, void *); 82 83 struct cfattach ep_eisa_ca = { 84 sizeof(struct ep_softc), ep_eisa_match, ep_eisa_attach 85 }; 86 87 /* XXX move these somewhere else */ 88 #define EISA_CONTROL 0x0c84 89 #define EISA_RESET 0x04 90 #define EISA_ERROR 0x02 91 #define EISA_ENABLE 0x01 92 93 int 94 ep_eisa_match(parent, match, aux) 95 struct device *parent; 96 void *match, *aux; 97 { 98 struct eisa_attach_args *ea = aux; 99 100 /* must match one of our known ID strings */ 101 if (strcmp(ea->ea_idstring, "TCM5090") && 102 strcmp(ea->ea_idstring, "TCM5091") && 103 strcmp(ea->ea_idstring, "TCM5092") && 104 strcmp(ea->ea_idstring, "TCM5093") && 105 strcmp(ea->ea_idstring, "TCM5094") && 106 strcmp(ea->ea_idstring, "TCM5095") && 107 strcmp(ea->ea_idstring, "TCM5098") && 108 strcmp(ea->ea_idstring, "TCM5920") && 109 strcmp(ea->ea_idstring, "TCM5970") && 110 strcmp(ea->ea_idstring, "TCM5971") && 111 strcmp(ea->ea_idstring, "TCM5972")) 112 return (0); 113 114 return (1); 115 } 116 117 void 118 ep_eisa_attach(parent, self, aux) 119 struct device *parent, *self; 120 void *aux; 121 { 122 struct ep_softc *sc = (void *)self; 123 struct eisa_attach_args *ea = aux; 124 bus_space_tag_t iot = ea->ea_iot; 125 bus_space_handle_t ioh; 126 u_int16_t k; 127 eisa_chipset_tag_t ec = ea->ea_ec; 128 eisa_intr_handle_t ih; 129 const char *model, *intrstr; 130 int chipset; 131 u_int irq; 132 133 /* Map i/o space. */ 134 if (bus_space_map(iot, EISA_SLOT_ADDR(ea->ea_slot), 135 EISA_SLOT_SIZE, 0, &ioh)) 136 panic(": can't map i/o space"); 137 138 sc->bustype = EP_BUS_EISA; 139 sc->sc_ioh = ioh; 140 sc->sc_iot = iot; 141 142 bus_space_write_1(iot, ioh, EISA_CONTROL, EISA_ENABLE); 143 delay(4000); 144 145 /* XXX What is this doing?! Reading the i/o address? */ 146 k = bus_space_read_2(iot, ioh, EP_W0_ADDRESS_CFG); 147 k = (k & 0x1f) * 0x10 + 0x200; 148 149 /* Read the IRQ from the card. */ 150 irq = bus_space_read_2(iot, ioh, EP_W0_RESOURCE_CFG) >> 12; 151 152 chipset = EP_CHIPSET_3C509; /* assume dumb chipset */ 153 if (strcmp(ea->ea_idstring, "TCM5090") == 0) 154 model = EISA_PRODUCT_TCM5090; 155 else if (strcmp(ea->ea_idstring, "TCM5091") == 0) 156 model = EISA_PRODUCT_TCM5091; 157 else if (strcmp(ea->ea_idstring, "TCM5092") == 0) 158 model = EISA_PRODUCT_TCM5092; 159 else if (strcmp(ea->ea_idstring, "TCM5093") == 0) 160 model = EISA_PRODUCT_TCM5093; 161 else if (strcmp(ea->ea_idstring, "TCM5094") == 0) 162 model = EISA_PRODUCT_TCM5094; 163 else if (strcmp(ea->ea_idstring, "TCM5095") == 0) 164 model = EISA_PRODUCT_TCM5095; 165 else if (strcmp(ea->ea_idstring, "TCM5098") == 0) 166 model = EISA_PRODUCT_TCM5098; 167 else if (strcmp(ea->ea_idstring, "TCM5920") == 0) { 168 model = EISA_PRODUCT_TCM5920; 169 chipset = EP_CHIPSET_VORTEX; 170 } else if (strcmp(ea->ea_idstring, "TCM5970") == 0) { 171 model = EISA_PRODUCT_TCM5970; 172 chipset = EP_CHIPSET_VORTEX; 173 } else if (strcmp(ea->ea_idstring, "TCM5971") == 0) { 174 model = EISA_PRODUCT_TCM5971; 175 chipset = EP_CHIPSET_VORTEX; 176 } else if (strcmp(ea->ea_idstring, "TCM5972") == 0) { 177 model = EISA_PRODUCT_TCM5972; 178 chipset = EP_CHIPSET_VORTEX; 179 } else 180 model = "unknown model!"; 181 182 if (eisa_intr_map(ec, irq, &ih)) { 183 printf(": couldn't map interrupt (%u)\n", irq); 184 bus_space_unmap(iot, ioh, EISA_SLOT_SIZE); 185 return; 186 } 187 intrstr = eisa_intr_string(ec, ih); 188 sc->sc_ih = eisa_intr_establish(ec, ih, IST_EDGE, IPL_NET, 189 epintr, sc, sc->sc_dev.dv_xname); 190 if (sc->sc_ih == NULL) { 191 printf(": couldn't establish interrupt"); 192 if (intrstr != NULL) 193 printf(" at %s", intrstr); 194 printf("\n"); 195 bus_space_unmap(iot, ioh, EISA_SLOT_SIZE); 196 return; 197 } 198 199 printf(": %s,", model); 200 if (intrstr != NULL) 201 printf(" %s,", intrstr); 202 203 epconfig(sc, chipset, NULL); 204 /* XXX because epconfig() will not print a newline for vortex chips */ 205 if (chipset == EP_CHIPSET_VORTEX) 206 printf("\n"); 207 } 208