1 /* $NetBSD: if_sn_nubus.c,v 1.29 2008/04/23 13:29:45 tsutsui 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.29 2008/04/23 13:29:45 tsutsui 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 <net/if.h> 42 #include <net/if_ether.h> 43 44 #include <machine/bus.h> 45 #include <machine/viareg.h> 46 47 #include <dev/ic/dp83932reg.h> 48 #include <dev/ic/dp83932var.h> 49 50 #include <mac68k/nubus/nubus.h> 51 #include <mac68k/dev/if_snvar.h> 52 53 static int sn_nubus_match(device_t, cfdata_t, void *); 54 static void sn_nubus_attach(device_t, device_t, void *); 55 static int sn_nb_card_vendor(bus_space_tag_t, bus_space_handle_t, 56 struct nubus_attach_args *); 57 58 CFATTACH_DECL_NEW(sn_nubus, sizeof(struct sonic_softc), 59 sn_nubus_match, sn_nubus_attach, NULL, NULL); 60 61 62 static int 63 sn_nubus_match(device_t parent, cfdata_t cf, void *aux) 64 { 65 struct nubus_attach_args *na = aux; 66 bus_space_handle_t bsh; 67 int rv; 68 69 if (bus_space_map(na->na_tag, 70 NUBUS_SLOT2PA(na->slot), NBMEMSIZE, 0, &bsh)) 71 return 0; 72 73 rv = 0; 74 75 if (na->category == NUBUS_CATEGORY_NETWORK && 76 na->type == NUBUS_TYPE_ETHERNET) { 77 switch (sn_nb_card_vendor(na->na_tag, bsh, na)) { 78 default: 79 break; 80 81 case SN_VENDOR_APPLE: 82 case SN_VENDOR_APPLE16: 83 case SN_VENDOR_ASANTELC: 84 case SN_VENDOR_DAYNA: 85 rv = 1; 86 break; 87 } 88 } 89 90 bus_space_unmap(na->na_tag, bsh, NBMEMSIZE); 91 92 return rv; 93 } 94 95 /* 96 * Install interface into kernel networking data structures 97 */ 98 static void 99 sn_nubus_attach(device_t parent, device_t self, void *aux) 100 { 101 struct sonic_softc *sc = device_private(self); 102 struct nubus_attach_args *na = aux; 103 int i, success, offset; 104 bus_space_tag_t bst; 105 bus_space_handle_t bsh, tmp_bsh; 106 uint8_t myaddr[ETHER_ADDR_LEN]; 107 const char *cardtype; 108 109 bst = na->na_tag; 110 if (bus_space_map(bst, NUBUS_SLOT2PA(na->slot), NBMEMSIZE, 0, &bsh)) { 111 aprint_error(": failed to map memory space.\n"); 112 return; 113 } 114 115 sc->sc_dev = self; 116 sc->sc_st = bst; 117 sc->sc_dmat = na->na_dmat; 118 119 cardtype = nubus_get_card_name(bst, bsh, na->fmt); 120 121 success = 0; 122 offset = 0; 123 124 switch (sn_nb_card_vendor(bst, bsh, na)) { 125 case SN_VENDOR_DAYNA: 126 sc->sc_dcr = DCR_BMS | DCR_RFT1 | DCR_TFT0; 127 sc->sc_dcr2 = 0; 128 sc->sc_32bit = 1; /* 32 bit card */ 129 130 if (bus_space_subregion(bst, bsh, 131 0x00180000, SONIC_NREGS * 4, &sc->sc_sh)) { 132 aprint_error(": failed to map register space.\n"); 133 break; 134 } 135 136 if (bus_space_subregion(bst, bsh, 137 0x00ffe004, ETHER_ADDR_LEN, &tmp_bsh)) { 138 aprint_error(": failed to map ROM space.\n"); 139 break; 140 } 141 142 sn_get_enaddr(bst, tmp_bsh, 0, myaddr); 143 144 offset = 2; 145 success = 1; 146 break; 147 148 case SN_VENDOR_APPLE: 149 sc->sc_dcr = DCR_BMS | DCR_RFT1 | DCR_TFT0; 150 sc->sc_dcr2 = 0; 151 sc->sc_32bit = 1; /* 32 bit card */ 152 153 if (bus_space_subregion(bst, bsh, 154 0x0, SONIC_NREGS * 4, &sc->sc_sh)) { 155 aprint_error(": failed to map register space.\n"); 156 break; 157 } 158 159 if (bus_space_subregion(bst, bsh, 160 0x40000, ETHER_ADDR_LEN, &tmp_bsh)) { 161 aprint_error(": failed to map ROM space.\n"); 162 break; 163 } 164 165 sn_get_enaddr(bst, tmp_bsh, 0, myaddr); 166 167 offset = 0; 168 success = 1; 169 break; 170 171 case SN_VENDOR_APPLE16: 172 sc->sc_dcr = DCR_EXBUS | DCR_BMS | DCR_PO1 | 173 DCR_RFT1 | DCR_TFT0; 174 sc->sc_dcr2 = 0; 175 sc->sc_32bit = 0; /* 16 bit card */ 176 177 if (bus_space_subregion(bst, bsh, 178 0x0, SONIC_NREGS * 4, &sc->sc_sh)) { 179 aprint_error(": failed to map register space.\n"); 180 break; 181 } 182 183 if (bus_space_subregion(bst, bsh, 184 0x40000, ETHER_ADDR_LEN, &tmp_bsh)) { 185 aprint_error(": failed to map ROM space.\n"); 186 break; 187 } 188 189 sn_get_enaddr(bst, tmp_bsh, 0, myaddr); 190 191 offset = 0; 192 success = 1; 193 break; 194 195 case SN_VENDOR_ASANTELC: /* Macintosh LC Ethernet Adapter */ 196 sc->sc_dcr = DCR_BMS | DCR_PO1 | DCR_RFT1 | DCR_TFT0; 197 sc->sc_dcr2 = 0; 198 sc->sc_32bit = 0; /* 16 bit card */ 199 200 if (bus_space_subregion(bst, bsh, 201 0x0, SONIC_NREGS * 4, &sc->sc_sh)) { 202 aprint_error(": failed to map register space.\n"); 203 break; 204 } 205 206 if (bus_space_subregion(bst, bsh, 207 0x400000, ETHER_ADDR_LEN, &tmp_bsh)) { 208 aprint_error(": failed to map ROM space.\n"); 209 break; 210 } 211 212 sn_get_enaddr(bst, tmp_bsh, 0, myaddr); 213 214 offset = 0; 215 success = 1; 216 break; 217 218 default: 219 /* 220 * You can't actually get this default, the snmatch 221 * will fail for unknown hardware. If you're adding support 222 * for a new card, the following defaults are a 223 * good starting point. 224 */ 225 sc->sc_dcr = DCR_SBUS | DCR_BMS | DCR_RFT1 | DCR_TFT0; 226 sc->sc_dcr2 = 0; 227 sc->sc_32bit = 1; 228 success = 0; 229 aprint_error(": unknown card: attachment incomplete.\n"); 230 } 231 232 if (!success) { 233 bus_space_unmap(bst, bsh, NBMEMSIZE); 234 return; 235 } 236 237 /* Regs are addressed as words, big endian. */ 238 for (i = 0; i < SONIC_NREGS; i++) { 239 sc->sc_regmap[i] = (bus_size_t)((i * 4) + offset); 240 } 241 242 sc->sc_bigendian = 1; 243 244 aprint_error(": %s\n", cardtype); 245 246 add_nubus_intr(na->slot, (void (*)(void *))sonic_intr, (void *)sc); 247 248 sonic_attach(sc, myaddr); 249 250 return; 251 } 252 253 static int 254 sn_nb_card_vendor(bus_space_tag_t bst, bus_space_handle_t bsh, 255 struct nubus_attach_args *na) 256 { 257 int vendor = SN_VENDOR_UNKNOWN; 258 259 switch (na->drsw) { 260 case NUBUS_DRSW_3COM: 261 if (na->drhw == NUBUS_DRHW_APPLE_SNT) 262 vendor = SN_VENDOR_APPLE; 263 else if (na->drhw == NUBUS_DRHW_APPLE_SN) 264 vendor = SN_VENDOR_APPLE16; 265 break; 266 case NUBUS_DRSW_APPLE: 267 if (na->drhw == NUBUS_DRHW_ASANTE_LC) 268 vendor = SN_VENDOR_ASANTELC; 269 else 270 vendor = SN_VENDOR_APPLE; 271 break; 272 case NUBUS_DRSW_TECHWORKS: 273 vendor = SN_VENDOR_APPLE; 274 break; 275 case NUBUS_DRSW_GATOR: 276 if (na->drhw == NUBUS_DRHW_KINETICS && 277 strncmp(nubus_get_card_name(bst, bsh, na->fmt), 278 "EtherPort", 9) != 0) 279 vendor = SN_VENDOR_DAYNA; 280 break; 281 case NUBUS_DRSW_DAYNA: 282 vendor = SN_VENDOR_DAYNA; 283 break; 284 } 285 286 return vendor; 287 } 288