1 /* $NetBSD: if_tlp_eisa.c,v 1.8 2002/01/12 16:22:28 tsutsui Exp $ */ 2 3 /*- 4 * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * EISA bus front-end for the Digital Semiconductor ``Tulip'' (21x4x) 42 * Ethernet controller family driver. 43 */ 44 45 #include <sys/cdefs.h> 46 __KERNEL_RCSID(0, "$NetBSD: if_tlp_eisa.c,v 1.8 2002/01/12 16:22:28 tsutsui Exp $"); 47 48 #include "opt_inet.h" 49 #include "opt_ns.h" 50 #include "bpfilter.h" 51 52 #include <sys/param.h> 53 #include <sys/systm.h> 54 #include <sys/mbuf.h> 55 #include <sys/malloc.h> 56 #include <sys/kernel.h> 57 #include <sys/socket.h> 58 #include <sys/ioctl.h> 59 #include <sys/errno.h> 60 #include <sys/device.h> 61 62 #include <machine/endian.h> 63 64 #include <net/if.h> 65 #include <net/if_dl.h> 66 #include <net/if_media.h> 67 #include <net/if_ether.h> 68 69 #if NBPFILTER > 0 70 #include <net/bpf.h> 71 #endif 72 73 #ifdef INET 74 #include <netinet/in.h> 75 #include <netinet/if_inarp.h> 76 #endif 77 78 #ifdef NS 79 #include <netns/ns.h> 80 #include <netns/ns_if.h> 81 #endif 82 83 #include <machine/bus.h> 84 #include <machine/intr.h> 85 86 #include <dev/mii/miivar.h> 87 #include <dev/mii/mii_bitbang.h> 88 89 #include <dev/ic/tulipreg.h> 90 #include <dev/ic/tulipvar.h> 91 92 #include <dev/eisa/eisareg.h> 93 #include <dev/eisa/eisavar.h> 94 #include <dev/eisa/eisadevs.h> 95 96 #include <dev/pci/pcireg.h> 97 98 /* 99 * DE425 configuration registers; literal offsets from CSR base. 100 * This is effectively the 21040 PCI configuration space interleaved 101 * into the CSR space (CSRs are space 16 bytes on the DE425). 102 * 103 * What a cool address decoder hack they must have on that board... 104 */ 105 #define DE425_CFID 0x08 /* Configuration ID */ 106 #define DE425_CFCS 0x0c /* Configuration Command-Status */ 107 #define DE425_CFRV 0x18 /* Configuration Revision */ 108 #define DE425_CFLT 0x1c /* Configuration Latency Timer */ 109 #define DE425_CBIO 0x28 /* Configuration Base I/O Address */ 110 #define DE425_CFDA 0x2c /* Configuration Driver Area */ 111 #define DE425_ENETROM 0xc90 /* Offset in I/O space for ENETROM */ 112 #define DE425_CFG0 0xc88 /* IRQ Configuration Register */ 113 114 struct tulip_eisa_softc { 115 struct tulip_softc sc_tulip; /* real Tulip softc */ 116 117 /* EISA-specific goo. */ 118 void *sc_ih; /* interrupt handle */ 119 }; 120 121 int tlp_eisa_match __P((struct device *, struct cfdata *, void *)); 122 void tlp_eisa_attach __P((struct device *, struct device *, void *)); 123 124 struct cfattach tlp_eisa_ca = { 125 sizeof(struct tulip_eisa_softc), tlp_eisa_match, tlp_eisa_attach, 126 }; 127 128 const int tlp_eisa_irqs[] = { 5, 9, 10, 11 }; 129 130 const struct tulip_eisa_product { 131 const char *tep_eisaid; /* EISA ID */ 132 const char *tep_name; /* device name */ 133 tulip_chip_t tep_chip; /* base Tulip chip type */ 134 } tlp_eisa_products[] = { 135 { "DEC4250", "DEC DE425", 136 TULIP_CHIP_DE425 }, 137 138 { NULL, NULL, 139 TULIP_CHIP_INVALID }, 140 }; 141 142 const struct tulip_eisa_product *tlp_eisa_lookup 143 __P((const struct eisa_attach_args *)); 144 145 const struct tulip_eisa_product * 146 tlp_eisa_lookup(ea) 147 const struct eisa_attach_args *ea; 148 { 149 const struct tulip_eisa_product *tep; 150 151 for (tep = tlp_eisa_products; 152 tep->tep_chip != TULIP_CHIP_INVALID; tep++) 153 if (strcmp(ea->ea_idstring, tep->tep_eisaid) == 0) 154 return (tep); 155 return (NULL); 156 } 157 158 int 159 tlp_eisa_match(parent, match, aux) 160 struct device *parent; 161 struct cfdata *match; 162 void *aux; 163 { 164 struct eisa_attach_args *ea = aux; 165 166 if (tlp_eisa_lookup(ea) != NULL) 167 return (1); 168 169 return (0); 170 } 171 172 void 173 tlp_eisa_attach(parent, self, aux) 174 struct device *parent, *self; 175 void *aux; 176 { 177 static const u_int8_t testpat[] = 178 { 0xff, 0, 0x55, 0xaa, 0xff, 0, 0x55, 0xaa }; 179 struct tulip_eisa_softc *esc = (void *) self; 180 struct tulip_softc *sc = &esc->sc_tulip; 181 struct eisa_attach_args *ea = aux; 182 eisa_chipset_tag_t ec = ea->ea_ec; 183 eisa_intr_handle_t ih; 184 bus_space_tag_t iot = ea->ea_iot; 185 bus_space_handle_t ioh; 186 const char *intrstr; 187 const struct tulip_eisa_product *tep; 188 u_int8_t enaddr[ETHER_ADDR_LEN], tmpbuf[sizeof(testpat)]; 189 u_int32_t val; 190 int irq, i, cnt; 191 192 /* 193 * Map the device. 194 */ 195 if (bus_space_map(iot, EISA_SLOT_ADDR(ea->ea_slot), 196 EISA_SLOT_SIZE, 0, &ioh)) { 197 printf(": unable to map I/O space\n"); 198 return; 199 } 200 201 sc->sc_st = iot; 202 sc->sc_sh = ioh; 203 204 tep = tlp_eisa_lookup(ea); 205 if (tep == NULL) { 206 printf("\n"); 207 panic("tlp_eisa_attach: impossible"); 208 } 209 sc->sc_chip = tep->tep_chip; 210 211 /* 212 * DE425's registers are 16 bytes long; the PCI configuration 213 * space registers are interleaved in the I/O space. 214 */ 215 sc->sc_regshift = 4; 216 217 /* 218 * No power management hooks. 219 */ 220 sc->sc_flags |= TULIPF_ENABLED; 221 222 /* 223 * CBIO must map the EISA slot, and I/O access and Bus Mastering 224 * must be enabled. 225 */ 226 bus_space_write_4(iot, ioh, DE425_CBIO, EISA_SLOT_ADDR(ea->ea_slot)); 227 bus_space_write_4(iot, ioh, DE425_CFCS, 228 bus_space_read_4(iot, ioh, DE425_CFCS) | 229 PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MASTER_ENABLE); 230 231 /* 232 * Get revision info. 233 */ 234 sc->sc_rev = bus_space_read_4(iot, ioh, DE425_CFRV) & 0xff; 235 236 printf(": %s Ethernet, pass %d.%d\n", 237 tep->tep_name, (sc->sc_rev >> 4) & 0xf, sc->sc_rev & 0xf); 238 239 sc->sc_dmat = ea->ea_dmat; 240 241 /* 242 * EISA doesn't have a cache line register. 243 */ 244 sc->sc_cacheline = 0; 245 246 /* 247 * Find the beginning of the Ethernet Address ROM. 248 */ 249 for (i = 0, cnt = 0; i < sizeof(testpat) && cnt < 32; cnt++) { 250 tmpbuf[i] = bus_space_read_1(iot, ioh, DE425_ENETROM); 251 if (tmpbuf[i] == testpat[i]) 252 i++; 253 else 254 i = 0; 255 } 256 257 /* 258 * ...and now read the contents of the Ethernet Address ROM. 259 */ 260 sc->sc_srom = malloc(32, M_DEVBUF, M_WAITOK|M_ZERO); 261 for (i = 0; i < 32; i++) 262 sc->sc_srom[i] = bus_space_read_1(iot, ioh, DE425_ENETROM); 263 264 /* 265 * None of the DE425 boards have the new-style SROMs. 266 */ 267 if (tlp_parse_old_srom(sc, enaddr) == 0) { 268 printf("%s: unable to decode old-style SROM\n", 269 sc->sc_dev.dv_xname); 270 return; 271 } 272 273 /* 274 * All DE425 boards use the 21040 media switch. 275 */ 276 sc->sc_mediasw = &tlp_21040_mediasw; 277 278 /* 279 * Figure out which IRQ we want to use, and determine of it's 280 * edge- or level-triggered. 281 */ 282 val = bus_space_read_4(iot, ioh, DE425_CFG0); 283 irq = tlp_eisa_irqs[(val >> 1) & 0x03]; 284 285 /* 286 * Map and establish our interrupt. 287 */ 288 if (eisa_intr_map(ec, irq, &ih)) { 289 printf("%s: unable to map interrupt (%u)\n", 290 sc->sc_dev.dv_xname, irq); 291 return; 292 } 293 intrstr = eisa_intr_string(ec, ih); 294 esc->sc_ih = eisa_intr_establish(ec, ih, 295 (val & 0x01) ? IST_EDGE : IST_LEVEL, IPL_NET, tlp_intr, sc); 296 if (esc->sc_ih == NULL) { 297 printf("%s: unable to establish interrupt", 298 sc->sc_dev.dv_xname); 299 if (intrstr != NULL) 300 printf(" at %s", intrstr); 301 printf("\n"); 302 return; 303 } 304 if (intrstr != NULL) 305 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, 306 intrstr); 307 308 /* 309 * Finish off the attach. 310 */ 311 tlp_attach(sc, enaddr); 312 } 313