1 /* $OpenBSD: if_ep_eisa.c,v 1.26 2015/11/24 17:11:39 mpi 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_media.h> 50 51 #include <netinet/in.h> 52 #include <netinet/if_ether.h> 53 54 #if NBPFILTER > 0 55 #include <net/bpf.h> 56 #endif 57 58 #include <machine/cpu.h> 59 #include <machine/bus.h> 60 #include <machine/intr.h> 61 62 #include <dev/mii/mii.h> 63 #include <dev/mii/miivar.h> 64 65 #include <dev/ic/elink3var.h> 66 #include <dev/ic/elink3reg.h> 67 68 #include <dev/eisa/eisareg.h> 69 #include <dev/eisa/eisavar.h> 70 #include <dev/eisa/eisadevs.h> 71 72 int ep_eisa_match(struct device *, void *, void *); 73 void ep_eisa_attach(struct device *, struct device *, void *); 74 75 struct cfattach ep_eisa_ca = { 76 sizeof(struct ep_softc), ep_eisa_match, ep_eisa_attach 77 }; 78 79 /* XXX move these somewhere else */ 80 #define EISA_CONTROL 0x0c84 81 #define EISA_RESET 0x04 82 #define EISA_ERROR 0x02 83 #define EISA_ENABLE 0x01 84 85 int 86 ep_eisa_match(parent, match, aux) 87 struct device *parent; 88 void *match, *aux; 89 { 90 struct eisa_attach_args *ea = aux; 91 92 /* must match one of our known ID strings */ 93 if (strcmp(ea->ea_idstring, "TCM5090") && 94 strcmp(ea->ea_idstring, "TCM5091") && 95 strcmp(ea->ea_idstring, "TCM5092") && 96 strcmp(ea->ea_idstring, "TCM5093") && 97 strcmp(ea->ea_idstring, "TCM5094") && 98 strcmp(ea->ea_idstring, "TCM5095") && 99 strcmp(ea->ea_idstring, "TCM5098") && 100 strcmp(ea->ea_idstring, "TCM5920") && 101 strcmp(ea->ea_idstring, "TCM5970") && 102 strcmp(ea->ea_idstring, "TCM5971") && 103 strcmp(ea->ea_idstring, "TCM5972")) 104 return (0); 105 106 return (1); 107 } 108 109 void 110 ep_eisa_attach(parent, self, aux) 111 struct device *parent, *self; 112 void *aux; 113 { 114 struct ep_softc *sc = (void *)self; 115 struct eisa_attach_args *ea = aux; 116 bus_space_tag_t iot = ea->ea_iot; 117 bus_space_handle_t ioh; 118 u_int16_t k; 119 eisa_chipset_tag_t ec = ea->ea_ec; 120 eisa_intr_handle_t ih; 121 const char *model, *intrstr; 122 int chipset; 123 u_int irq; 124 125 /* Map i/o space. */ 126 if (bus_space_map(iot, EISA_SLOT_ADDR(ea->ea_slot), 127 EISA_SLOT_SIZE, 0, &ioh)) 128 panic(": can't map i/o space"); 129 130 sc->bustype = EP_BUS_EISA; 131 sc->sc_ioh = ioh; 132 sc->sc_iot = iot; 133 134 bus_space_write_1(iot, ioh, EISA_CONTROL, EISA_ENABLE); 135 delay(4000); 136 137 /* XXX What is this doing?! Reading the i/o address? */ 138 k = bus_space_read_2(iot, ioh, EP_W0_ADDRESS_CFG); 139 k = (k & 0x1f) * 0x10 + 0x200; 140 141 /* Read the IRQ from the card. */ 142 irq = bus_space_read_2(iot, ioh, EP_W0_RESOURCE_CFG) >> 12; 143 144 chipset = EP_CHIPSET_3C509; /* assume dumb chipset */ 145 if (strcmp(ea->ea_idstring, "TCM5090") == 0) 146 model = EISA_PRODUCT_TCM5090; 147 else if (strcmp(ea->ea_idstring, "TCM5091") == 0) 148 model = EISA_PRODUCT_TCM5091; 149 else if (strcmp(ea->ea_idstring, "TCM5092") == 0) 150 model = EISA_PRODUCT_TCM5092; 151 else if (strcmp(ea->ea_idstring, "TCM5093") == 0) 152 model = EISA_PRODUCT_TCM5093; 153 else if (strcmp(ea->ea_idstring, "TCM5094") == 0) 154 model = EISA_PRODUCT_TCM5094; 155 else if (strcmp(ea->ea_idstring, "TCM5095") == 0) 156 model = EISA_PRODUCT_TCM5095; 157 else if (strcmp(ea->ea_idstring, "TCM5098") == 0) 158 model = EISA_PRODUCT_TCM5098; 159 else if (strcmp(ea->ea_idstring, "TCM5920") == 0) { 160 model = EISA_PRODUCT_TCM5920; 161 chipset = EP_CHIPSET_VORTEX; 162 } else if (strcmp(ea->ea_idstring, "TCM5970") == 0) { 163 model = EISA_PRODUCT_TCM5970; 164 chipset = EP_CHIPSET_VORTEX; 165 } else if (strcmp(ea->ea_idstring, "TCM5971") == 0) { 166 model = EISA_PRODUCT_TCM5971; 167 chipset = EP_CHIPSET_VORTEX; 168 } else if (strcmp(ea->ea_idstring, "TCM5972") == 0) { 169 model = EISA_PRODUCT_TCM5972; 170 chipset = EP_CHIPSET_VORTEX; 171 } else 172 model = "unknown model!"; 173 174 if (eisa_intr_map(ec, irq, &ih)) { 175 printf(": couldn't map interrupt (%u)\n", irq); 176 bus_space_unmap(iot, ioh, EISA_SLOT_SIZE); 177 return; 178 } 179 intrstr = eisa_intr_string(ec, ih); 180 sc->sc_ih = eisa_intr_establish(ec, ih, IST_EDGE, IPL_NET, 181 epintr, sc, sc->sc_dev.dv_xname); 182 if (sc->sc_ih == NULL) { 183 printf(": couldn't establish interrupt"); 184 if (intrstr != NULL) 185 printf(" at %s", intrstr); 186 printf("\n"); 187 bus_space_unmap(iot, ioh, EISA_SLOT_SIZE); 188 return; 189 } 190 191 printf(": %s,", model); 192 if (intrstr != NULL) 193 printf(" %s,", intrstr); 194 195 epconfig(sc, chipset, NULL); 196 /* XXX because epconfig() will not print a newline for vortex chips */ 197 if (chipset == EP_CHIPSET_VORTEX) 198 printf("\n"); 199 } 200