1 1.30 rin /* $NetBSD: if_sn_nubus.c,v 1.30 2021/02/20 09:36:30 rin Exp $ */ 2 1.1 briggs 3 1.1 briggs /* 4 1.1 briggs * Copyright (C) 1997 Allen Briggs 5 1.1 briggs * All rights reserved. 6 1.1 briggs * 7 1.1 briggs * Redistribution and use in source and binary forms, with or without 8 1.1 briggs * modification, are permitted provided that the following conditions 9 1.1 briggs * are met: 10 1.1 briggs * 1. Redistributions of source code must retain the above copyright 11 1.1 briggs * notice, this list of conditions and the following disclaimer. 12 1.1 briggs * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 briggs * notice, this list of conditions and the following disclaimer in the 14 1.1 briggs * documentation and/or other materials provided with the distribution. 15 1.1 briggs * 3. All advertising materials mentioning features or use of this software 16 1.1 briggs * must display the following acknowledgement: 17 1.1 briggs * This product includes software developed by Allen Briggs 18 1.1 briggs * 4. The name of the author may not be used to endorse or promote products 19 1.1 briggs * derived from this software without specific prior written permission. 20 1.1 briggs * 21 1.1 briggs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 1.1 briggs * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 1.1 briggs * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 1.1 briggs * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 1.1 briggs * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 1.1 briggs * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 1.1 briggs * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 1.1 briggs * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 1.1 briggs * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 1.1 briggs * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 1.1 briggs */ 32 1.23 lukem 33 1.23 lukem #include <sys/cdefs.h> 34 1.30 rin __KERNEL_RCSID(0, "$NetBSD: if_sn_nubus.c,v 1.30 2021/02/20 09:36:30 rin Exp $"); 35 1.1 briggs 36 1.1 briggs #include <sys/param.h> 37 1.27 tsutsui #include <sys/systm.h> 38 1.1 briggs #include <sys/device.h> 39 1.1 briggs #include <sys/ioctl.h> 40 1.1 briggs 41 1.30 rin #include <sys/rndsource.h> 42 1.30 rin 43 1.1 briggs #include <net/if.h> 44 1.2 is #include <net/if_ether.h> 45 1.1 briggs 46 1.1 briggs #include <machine/bus.h> 47 1.1 briggs #include <machine/viareg.h> 48 1.1 briggs 49 1.27 tsutsui #include <dev/ic/dp83932reg.h> 50 1.27 tsutsui #include <dev/ic/dp83932var.h> 51 1.27 tsutsui 52 1.18 scottr #include <mac68k/nubus/nubus.h> 53 1.16 scottr #include <mac68k/dev/if_snvar.h> 54 1.1 briggs 55 1.29 tsutsui static int sn_nubus_match(device_t, cfdata_t, void *); 56 1.29 tsutsui static void sn_nubus_attach(device_t, device_t, void *); 57 1.24 chs static int sn_nb_card_vendor(bus_space_tag_t, bus_space_handle_t, 58 1.24 chs struct nubus_attach_args *); 59 1.1 briggs 60 1.29 tsutsui CFATTACH_DECL_NEW(sn_nubus, sizeof(struct sonic_softc), 61 1.22 thorpej sn_nubus_match, sn_nubus_attach, NULL, NULL); 62 1.1 briggs 63 1.2 is 64 1.1 briggs static int 65 1.29 tsutsui sn_nubus_match(device_t parent, cfdata_t cf, void *aux) 66 1.1 briggs { 67 1.29 tsutsui struct nubus_attach_args *na = aux; 68 1.1 briggs bus_space_handle_t bsh; 69 1.1 briggs int rv; 70 1.1 briggs 71 1.10 scottr if (bus_space_map(na->na_tag, 72 1.10 scottr NUBUS_SLOT2PA(na->slot), NBMEMSIZE, 0, &bsh)) 73 1.29 tsutsui return 0; 74 1.1 briggs 75 1.1 briggs rv = 0; 76 1.1 briggs 77 1.1 briggs if (na->category == NUBUS_CATEGORY_NETWORK && 78 1.1 briggs na->type == NUBUS_TYPE_ETHERNET) { 79 1.13 scottr switch (sn_nb_card_vendor(na->na_tag, bsh, na)) { 80 1.1 briggs default: 81 1.1 briggs break; 82 1.1 briggs 83 1.11 scottr case SN_VENDOR_APPLE: 84 1.15 scottr case SN_VENDOR_APPLE16: 85 1.20 scottr case SN_VENDOR_ASANTELC: 86 1.11 scottr case SN_VENDOR_DAYNA: 87 1.1 briggs rv = 1; 88 1.1 briggs break; 89 1.1 briggs } 90 1.1 briggs } 91 1.1 briggs 92 1.1 briggs bus_space_unmap(na->na_tag, bsh, NBMEMSIZE); 93 1.1 briggs 94 1.1 briggs return rv; 95 1.1 briggs } 96 1.1 briggs 97 1.1 briggs /* 98 1.1 briggs * Install interface into kernel networking data structures 99 1.1 briggs */ 100 1.1 briggs static void 101 1.29 tsutsui sn_nubus_attach(device_t parent, device_t self, void *aux) 102 1.1 briggs { 103 1.29 tsutsui struct sonic_softc *sc = device_private(self); 104 1.27 tsutsui struct nubus_attach_args *na = aux; 105 1.10 scottr int i, success, offset; 106 1.1 briggs bus_space_tag_t bst; 107 1.10 scottr bus_space_handle_t bsh, tmp_bsh; 108 1.27 tsutsui uint8_t myaddr[ETHER_ADDR_LEN]; 109 1.25 rjs const char *cardtype; 110 1.1 briggs 111 1.1 briggs bst = na->na_tag; 112 1.1 briggs if (bus_space_map(bst, NUBUS_SLOT2PA(na->slot), NBMEMSIZE, 0, &bsh)) { 113 1.29 tsutsui aprint_error(": failed to map memory space.\n"); 114 1.1 briggs return; 115 1.1 briggs } 116 1.1 briggs 117 1.29 tsutsui sc->sc_dev = self; 118 1.27 tsutsui sc->sc_st = bst; 119 1.27 tsutsui sc->sc_dmat = na->na_dmat; 120 1.1 briggs 121 1.20 scottr cardtype = nubus_get_card_name(bst, bsh, na->fmt); 122 1.20 scottr 123 1.1 briggs success = 0; 124 1.27 tsutsui offset = 0; 125 1.1 briggs 126 1.13 scottr switch (sn_nb_card_vendor(bst, bsh, na)) { 127 1.11 scottr case SN_VENDOR_DAYNA: 128 1.27 tsutsui sc->sc_dcr = DCR_BMS | DCR_RFT1 | DCR_TFT0; 129 1.27 tsutsui sc->sc_dcr2 = 0; 130 1.27 tsutsui sc->sc_32bit = 1; /* 32 bit card */ 131 1.1 briggs 132 1.10 scottr if (bus_space_subregion(bst, bsh, 133 1.27 tsutsui 0x00180000, SONIC_NREGS * 4, &sc->sc_sh)) { 134 1.29 tsutsui aprint_error(": failed to map register space.\n"); 135 1.1 briggs break; 136 1.1 briggs } 137 1.1 briggs 138 1.10 scottr if (bus_space_subregion(bst, bsh, 139 1.10 scottr 0x00ffe004, ETHER_ADDR_LEN, &tmp_bsh)) { 140 1.29 tsutsui aprint_error(": failed to map ROM space.\n"); 141 1.1 briggs break; 142 1.1 briggs } 143 1.1 briggs 144 1.5 briggs sn_get_enaddr(bst, tmp_bsh, 0, myaddr); 145 1.5 briggs 146 1.7 briggs offset = 2; 147 1.1 briggs success = 1; 148 1.10 scottr break; 149 1.1 briggs 150 1.11 scottr case SN_VENDOR_APPLE: 151 1.27 tsutsui sc->sc_dcr = DCR_BMS | DCR_RFT1 | DCR_TFT0; 152 1.27 tsutsui sc->sc_dcr2 = 0; 153 1.27 tsutsui sc->sc_32bit = 1; /* 32 bit card */ 154 1.4 briggs 155 1.10 scottr if (bus_space_subregion(bst, bsh, 156 1.27 tsutsui 0x0, SONIC_NREGS * 4, &sc->sc_sh)) { 157 1.29 tsutsui aprint_error(": failed to map register space.\n"); 158 1.4 briggs break; 159 1.4 briggs } 160 1.4 briggs 161 1.10 scottr if (bus_space_subregion(bst, bsh, 162 1.10 scottr 0x40000, ETHER_ADDR_LEN, &tmp_bsh)) { 163 1.29 tsutsui aprint_error(": failed to map ROM space.\n"); 164 1.5 briggs break; 165 1.5 briggs } 166 1.5 briggs 167 1.5 briggs sn_get_enaddr(bst, tmp_bsh, 0, myaddr); 168 1.5 briggs 169 1.7 briggs offset = 0; 170 1.5 briggs success = 1; 171 1.10 scottr break; 172 1.15 scottr 173 1.15 scottr case SN_VENDOR_APPLE16: 174 1.27 tsutsui sc->sc_dcr = DCR_EXBUS | DCR_BMS | DCR_PO1 | 175 1.27 tsutsui DCR_RFT1 | DCR_TFT0; 176 1.27 tsutsui sc->sc_dcr2 = 0; 177 1.27 tsutsui sc->sc_32bit = 0; /* 16 bit card */ 178 1.15 scottr 179 1.15 scottr if (bus_space_subregion(bst, bsh, 180 1.27 tsutsui 0x0, SONIC_NREGS * 4, &sc->sc_sh)) { 181 1.29 tsutsui aprint_error(": failed to map register space.\n"); 182 1.15 scottr break; 183 1.15 scottr } 184 1.15 scottr 185 1.15 scottr if (bus_space_subregion(bst, bsh, 186 1.15 scottr 0x40000, ETHER_ADDR_LEN, &tmp_bsh)) { 187 1.29 tsutsui aprint_error(": failed to map ROM space.\n"); 188 1.15 scottr break; 189 1.15 scottr } 190 1.15 scottr 191 1.15 scottr sn_get_enaddr(bst, tmp_bsh, 0, myaddr); 192 1.15 scottr 193 1.15 scottr offset = 0; 194 1.15 scottr success = 1; 195 1.15 scottr break; 196 1.4 briggs 197 1.20 scottr case SN_VENDOR_ASANTELC: /* Macintosh LC Ethernet Adapter */ 198 1.27 tsutsui sc->sc_dcr = DCR_BMS | DCR_PO1 | DCR_RFT1 | DCR_TFT0; 199 1.27 tsutsui sc->sc_dcr2 = 0; 200 1.27 tsutsui sc->sc_32bit = 0; /* 16 bit card */ 201 1.20 scottr 202 1.20 scottr if (bus_space_subregion(bst, bsh, 203 1.27 tsutsui 0x0, SONIC_NREGS * 4, &sc->sc_sh)) { 204 1.29 tsutsui aprint_error(": failed to map register space.\n"); 205 1.20 scottr break; 206 1.20 scottr } 207 1.20 scottr 208 1.20 scottr if (bus_space_subregion(bst, bsh, 209 1.20 scottr 0x400000, ETHER_ADDR_LEN, &tmp_bsh)) { 210 1.29 tsutsui aprint_error(": failed to map ROM space.\n"); 211 1.20 scottr break; 212 1.20 scottr } 213 1.20 scottr 214 1.20 scottr sn_get_enaddr(bst, tmp_bsh, 0, myaddr); 215 1.20 scottr 216 1.20 scottr offset = 0; 217 1.20 scottr success = 1; 218 1.20 scottr break; 219 1.20 scottr 220 1.10 scottr default: 221 1.10 scottr /* 222 1.10 scottr * You can't actually get this default, the snmatch 223 1.10 scottr * will fail for unknown hardware. If you're adding support 224 1.10 scottr * for a new card, the following defaults are a 225 1.10 scottr * good starting point. 226 1.10 scottr */ 227 1.27 tsutsui sc->sc_dcr = DCR_SBUS | DCR_BMS | DCR_RFT1 | DCR_TFT0; 228 1.27 tsutsui sc->sc_dcr2 = 0; 229 1.27 tsutsui sc->sc_32bit = 1; 230 1.8 briggs success = 0; 231 1.29 tsutsui aprint_error(": unknown card: attachment incomplete.\n"); 232 1.10 scottr } 233 1.1 briggs 234 1.1 briggs if (!success) { 235 1.1 briggs bus_space_unmap(bst, bsh, NBMEMSIZE); 236 1.1 briggs return; 237 1.1 briggs } 238 1.1 briggs 239 1.3 briggs /* Regs are addressed as words, big endian. */ 240 1.27 tsutsui for (i = 0; i < SONIC_NREGS; i++) { 241 1.27 tsutsui sc->sc_regmap[i] = (bus_size_t)((i * 4) + offset); 242 1.3 briggs } 243 1.3 briggs 244 1.27 tsutsui sc->sc_bigendian = 1; 245 1.27 tsutsui 246 1.29 tsutsui aprint_error(": %s\n", cardtype); 247 1.20 scottr 248 1.27 tsutsui add_nubus_intr(na->slot, (void (*)(void *))sonic_intr, (void *)sc); 249 1.3 briggs 250 1.27 tsutsui sonic_attach(sc, myaddr); 251 1.3 briggs 252 1.3 briggs return; 253 1.1 briggs } 254 1.1 briggs 255 1.1 briggs static int 256 1.24 chs sn_nb_card_vendor(bus_space_tag_t bst, bus_space_handle_t bsh, 257 1.24 chs struct nubus_attach_args *na) 258 1.1 briggs { 259 1.11 scottr int vendor = SN_VENDOR_UNKNOWN; 260 1.1 briggs 261 1.1 briggs switch (na->drsw) { 262 1.1 briggs case NUBUS_DRSW_3COM: 263 1.17 briggs if (na->drhw == NUBUS_DRHW_APPLE_SNT) 264 1.11 scottr vendor = SN_VENDOR_APPLE; 265 1.17 briggs else if (na->drhw == NUBUS_DRHW_APPLE_SN) 266 1.15 scottr vendor = SN_VENDOR_APPLE16; 267 1.4 briggs break; 268 1.1 briggs case NUBUS_DRSW_APPLE: 269 1.20 scottr if (na->drhw == NUBUS_DRHW_ASANTE_LC) 270 1.20 scottr vendor = SN_VENDOR_ASANTELC; 271 1.20 scottr else 272 1.20 scottr vendor = SN_VENDOR_APPLE; 273 1.20 scottr break; 274 1.1 briggs case NUBUS_DRSW_TECHWORKS: 275 1.11 scottr vendor = SN_VENDOR_APPLE; 276 1.1 briggs break; 277 1.1 briggs case NUBUS_DRSW_GATOR: 278 1.11 scottr if (na->drhw == NUBUS_DRHW_KINETICS && 279 1.13 scottr strncmp(nubus_get_card_name(bst, bsh, na->fmt), 280 1.13 scottr "EtherPort", 9) != 0) 281 1.11 scottr vendor = SN_VENDOR_DAYNA; 282 1.3 briggs break; 283 1.3 briggs case NUBUS_DRSW_DAYNA: 284 1.11 scottr vendor = SN_VENDOR_DAYNA; 285 1.1 briggs break; 286 1.1 briggs } 287 1.11 scottr 288 1.1 briggs return vendor; 289 1.1 briggs } 290