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