1 1.17 thorpej /* $NetBSD: depca_eisa.c,v 1.17 2021/07/24 19:14:35 thorpej Exp $ */ 2 1.1 thorpej 3 1.1 thorpej /*- 4 1.1 thorpej * Copyright (c) 2000 The NetBSD Foundation, Inc. 5 1.1 thorpej * All rights reserved. 6 1.1 thorpej * 7 1.1 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.1 thorpej * by Jason R. Thorpe. 9 1.1 thorpej * 10 1.1 thorpej * Redistribution and use in source and binary forms, with or without 11 1.1 thorpej * modification, are permitted provided that the following conditions 12 1.1 thorpej * are met: 13 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 14 1.1 thorpej * notice, this list of conditions and the following disclaimer. 15 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 17 1.1 thorpej * documentation and/or other materials provided with the distribution. 18 1.1 thorpej * 19 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 thorpej * POSSIBILITY OF SUCH DAMAGE. 30 1.1 thorpej */ 31 1.1 thorpej 32 1.1 thorpej /* 33 1.1 thorpej * EISA bus front-end for the Digital DEPCA Ethernet controller. 34 1.1 thorpej */ 35 1.2 lukem 36 1.2 lukem #include <sys/cdefs.h> 37 1.17 thorpej __KERNEL_RCSID(0, "$NetBSD: depca_eisa.c,v 1.17 2021/07/24 19:14:35 thorpej Exp $"); 38 1.1 thorpej 39 1.1 thorpej #include "opt_inet.h" 40 1.1 thorpej 41 1.1 thorpej #include <sys/param.h> 42 1.1 thorpej #include <sys/systm.h> 43 1.1 thorpej #include <sys/mbuf.h> 44 1.1 thorpej #include <sys/syslog.h> 45 1.1 thorpej #include <sys/socket.h> 46 1.1 thorpej #include <sys/device.h> 47 1.1 thorpej 48 1.1 thorpej #include <net/if.h> 49 1.1 thorpej #include <net/if_media.h> 50 1.1 thorpej #include <net/if_ether.h> 51 1.1 thorpej 52 1.1 thorpej #ifdef INET 53 1.7 perry #include <netinet/in.h> 54 1.1 thorpej #include <netinet/if_inarp.h> 55 1.1 thorpej #endif 56 1.1 thorpej 57 1.10 ad #include <sys/bus.h> 58 1.10 ad #include <sys/intr.h> 59 1.1 thorpej 60 1.1 thorpej #include <dev/eisa/eisareg.h> 61 1.1 thorpej #include <dev/eisa/eisavar.h> 62 1.1 thorpej #include <dev/eisa/eisadevs.h> 63 1.1 thorpej 64 1.1 thorpej #include <dev/ic/lancereg.h> 65 1.1 thorpej #include <dev/ic/lancevar.h> 66 1.1 thorpej #include <dev/ic/am7990reg.h> 67 1.1 thorpej #include <dev/ic/am7990var.h> 68 1.1 thorpej #include <dev/ic/depcareg.h> 69 1.1 thorpej #include <dev/ic/depcavar.h> 70 1.1 thorpej 71 1.11 tsutsui static int depca_eisa_match(device_t, cfdata_t, void *); 72 1.11 tsutsui static void depca_eisa_attach(device_t, device_t, void *); 73 1.1 thorpej 74 1.1 thorpej struct depca_eisa_softc { 75 1.1 thorpej struct depca_softc sc_depca; 76 1.1 thorpej 77 1.1 thorpej eisa_chipset_tag_t sc_ec; 78 1.1 thorpej int sc_irq; 79 1.1 thorpej int sc_ist; 80 1.1 thorpej }; 81 1.1 thorpej 82 1.11 tsutsui CFATTACH_DECL_NEW(depca_eisa, sizeof(struct depca_eisa_softc), 83 1.5 thorpej depca_eisa_match, depca_eisa_attach, NULL, NULL); 84 1.1 thorpej 85 1.6 thorpej static void *depca_eisa_intr_establish(struct depca_softc *, 86 1.6 thorpej struct lance_softc *); 87 1.1 thorpej 88 1.6 thorpej static int 89 1.11 tsutsui depca_eisa_match(device_t parent, cfdata_t cf, void *aux) 90 1.1 thorpej { 91 1.1 thorpej struct eisa_attach_args *ea = aux; 92 1.1 thorpej 93 1.1 thorpej return (strcmp(ea->ea_idstring, "DEC4220") == 0); 94 1.1 thorpej } 95 1.1 thorpej 96 1.1 thorpej #define DEPCA_ECU_FUNC_NETINTR 0 97 1.1 thorpej #define DEPCA_ECU_FUNC_NETBUF 1 98 1.1 thorpej 99 1.6 thorpej static void 100 1.11 tsutsui depca_eisa_attach(device_t parent, device_t self, void *aux) 101 1.1 thorpej { 102 1.9 thorpej struct depca_eisa_softc *esc = device_private(self); 103 1.11 tsutsui struct depca_softc *sc = &esc->sc_depca; 104 1.1 thorpej struct eisa_attach_args *ea = aux; 105 1.1 thorpej struct eisa_cfg_mem ecm; 106 1.1 thorpej struct eisa_cfg_irq eci; 107 1.1 thorpej 108 1.11 tsutsui sc->sc_dev = self; 109 1.16 thorpej aprint_naive("\n"); 110 1.16 thorpej aprint_normal(": DEC DE422 Ethernet\n"); 111 1.1 thorpej 112 1.1 thorpej sc->sc_iot = ea->ea_iot; 113 1.1 thorpej sc->sc_memt = ea->ea_memt; 114 1.1 thorpej 115 1.1 thorpej esc->sc_ec = ea->ea_ec; 116 1.1 thorpej 117 1.1 thorpej sc->sc_intr_establish = depca_eisa_intr_establish; 118 1.1 thorpej 119 1.1 thorpej if (eisa_conf_read_mem(ea->ea_ec, ea->ea_slot, 120 1.1 thorpej DEPCA_ECU_FUNC_NETBUF, 0, &ecm) != 0) { 121 1.11 tsutsui aprint_error_dev(self, "unable to find network buffer\n"); 122 1.1 thorpej return; 123 1.1 thorpej } 124 1.1 thorpej 125 1.11 tsutsui aprint_normal_dev(self, "shared memory at 0x%lx-0x%lx\n", 126 1.1 thorpej ecm.ecm_addr, ecm.ecm_addr + ecm.ecm_size - 1); 127 1.1 thorpej 128 1.1 thorpej sc->sc_memsize = ecm.ecm_size; 129 1.1 thorpej 130 1.1 thorpej if (bus_space_map(sc->sc_iot, EISA_SLOT_ADDR(ea->ea_slot) + 0xc00, 16, 131 1.1 thorpej 0, &sc->sc_ioh) != 0) { 132 1.11 tsutsui aprint_error_dev(self, "unable to map i/o space\n"); 133 1.1 thorpej return; 134 1.1 thorpej } 135 1.1 thorpej if (bus_space_map(sc->sc_memt, ecm.ecm_addr, sc->sc_memsize, 136 1.1 thorpej 0, &sc->sc_memh) != 0) { 137 1.11 tsutsui aprint_error_dev(self, "unable to map memory space\n"); 138 1.1 thorpej return; 139 1.1 thorpej } 140 1.1 thorpej 141 1.1 thorpej if (eisa_conf_read_irq(ea->ea_ec, ea->ea_slot, 142 1.1 thorpej DEPCA_ECU_FUNC_NETINTR, 0, &eci) != 0) { 143 1.11 tsutsui aprint_error_dev(self, "unable to determine IRQ\n"); 144 1.1 thorpej return; 145 1.1 thorpej } 146 1.1 thorpej 147 1.1 thorpej esc->sc_irq = eci.eci_irq; 148 1.1 thorpej esc->sc_ist = eci.eci_ist; 149 1.1 thorpej 150 1.1 thorpej depca_attach(sc); 151 1.1 thorpej } 152 1.1 thorpej 153 1.6 thorpej static void * 154 1.14 chs depca_eisa_intr_establish(struct depca_softc *sc, struct lance_softc *child) 155 1.1 thorpej { 156 1.14 chs struct depca_eisa_softc *esc = (struct depca_eisa_softc *)sc; 157 1.1 thorpej eisa_intr_handle_t ih; 158 1.1 thorpej const char *intrstr; 159 1.1 thorpej void *rv; 160 1.15 christos char intrbuf[EISA_INTRSTR_LEN]; 161 1.1 thorpej 162 1.1 thorpej if (eisa_intr_map(esc->sc_ec, esc->sc_irq, &ih)) { 163 1.14 chs aprint_error_dev(sc->sc_dev, 164 1.11 tsutsui "unable to map interrupt (%d)\n", esc->sc_irq); 165 1.1 thorpej return (NULL); 166 1.1 thorpej } 167 1.15 christos intrstr = eisa_intr_string(esc->sc_ec, ih, intrbuf, sizeof(intrbuf)); 168 1.1 thorpej rv = eisa_intr_establish(esc->sc_ec, ih, esc->sc_ist, IPL_NET, 169 1.1 thorpej (esc->sc_ist == IST_LEVEL) ? am7990_intr : depca_intredge, child); 170 1.1 thorpej if (rv == NULL) { 171 1.14 chs aprint_error_dev(sc->sc_dev, 172 1.11 tsutsui "unable to establish interrupt"); 173 1.1 thorpej if (intrstr != NULL) 174 1.11 tsutsui aprint_error(" at %s", intrstr); 175 1.11 tsutsui aprint_error("\n"); 176 1.1 thorpej return (NULL); 177 1.1 thorpej } 178 1.17 thorpej if (intrstr != NULL) { 179 1.17 thorpej aprint_normal_dev(sc->sc_dev, 180 1.17 thorpej "interrupting at %s (%s trigger)\n", 181 1.17 thorpej (esc->sc_ist == IST_LEVEL) ? "level" : "edge", intrstr); 182 1.17 thorpej } 183 1.1 thorpej 184 1.1 thorpej return (rv); 185 1.1 thorpej } 186