1/* $NetBSD: if_sn_obio.c,v 1.29 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_obio.c,v 1.29 2021/02/20 09:36:30 rin Exp $"); 35 36#include <sys/param.h> 37#include <sys/device.h> 38#include <sys/systm.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/cpu.h> 48#include <machine/viareg.h> 49 50#include <dev/ic/dp83932reg.h> 51#include <dev/ic/dp83932var.h> 52 53#include <mac68k/obio/obiovar.h> 54#include <mac68k/dev/if_snvar.h> 55 56#define SONIC_REG_BASE 0x50F0A000 57#define SONIC_PROM_BASE 0x50F08000 58#define SONIC_SLOTNO 9 59 60static int sn_obio_match(device_t, cfdata_t, void *); 61static void sn_obio_attach(device_t, device_t, void *); 62static int sn_obio_getaddr(struct sonic_softc *, uint8_t *); 63static int sn_obio_getaddr_kludge(struct sonic_softc *, uint8_t *); 64 65CFATTACH_DECL_NEW(sn_obio, sizeof(struct sonic_softc), 66 sn_obio_match, sn_obio_attach, NULL, NULL); 67 68static int 69sn_obio_match(device_t parent, cfdata_t cf, void *aux) 70{ 71 struct obio_attach_args *oa = aux; 72 bus_space_handle_t bsh; 73 int found = 0; 74 75 if (!mac68k_machine.sonic) 76 return 0; 77 78 if (bus_space_map(oa->oa_tag, 79 SONIC_REG_BASE, SONIC_NREGS * 4, 0, &bsh)) 80 return 0; 81 82 if (mac68k_bus_space_probe(oa->oa_tag, bsh, 0, 4)) 83 found = 1; 84 85 bus_space_unmap(oa->oa_tag, bsh, SONIC_NREGS * 4); 86 87 return found; 88} 89 90/* 91 * Install interface into kernel networking data structures 92 */ 93static void 94sn_obio_attach(device_t parent, device_t self, void *aux) 95{ 96 struct sonic_softc *sc = device_private(self); 97 struct obio_attach_args *oa = aux; 98 uint8_t myaddr[ETHER_ADDR_LEN]; 99 int i; 100 101 sc->sc_dev = self; 102 sc->sc_st = oa->oa_tag; 103 sc->sc_dmat = oa->oa_dmat; 104 105 if (bus_space_map(sc->sc_st, 106 SONIC_REG_BASE, SONIC_NREGS * 4, 0, &sc->sc_sh)) { 107 aprint_error(": failed to map space for SONIC regs.\n"); 108 return; 109 } 110 111 /* regs are addressed as words, big-endian. */ 112 for (i = 0; i < SONIC_NREGS; i++) { 113 sc->sc_regmap[i] = (bus_size_t)((i * 4) + 2); 114 } 115 116 sc->sc_bigendian = 1; 117 118 sc->sc_dcr = DCR_BMS | DCR_RFT1 | DCR_TFT0; 119 sc->sc_dcr2 = 0; 120 121 switch (current_mac_model->machineid) { 122 case MACH_MACC610: 123 case MACH_MACC650: 124 case MACH_MACQ610: 125 case MACH_MACQ650: 126 case MACH_MACQ700: 127 case MACH_MACQ800: 128 case MACH_MACQ900: 129 case MACH_MACQ950: 130 sc->sc_dcr |= DCR_EXBUS; 131 sc->sc_32bit = 1; 132 break; 133 134 case MACH_MACLC575: 135 case MACH_MACP580: 136 case MACH_MACQ630: 137 /* Apple Comm Slot cards; assume they are 32 bit */ 138 sc->sc_dcr |= DCR_EXBUS | DCR_USR1 | DCR_USR0; 139 sc->sc_32bit = 1; 140 break; 141 142 case MACH_MACPB500: 143 sc->sc_dcr |= DCR_SBUS | DCR_LBR; 144 sc->sc_32bit = 0; /* 16 bit interface */ 145 break; 146 147 default: 148 aprint_error(": unsupported machine type\n"); 149 return; 150 } 151 152 if (sn_obio_getaddr(sc, myaddr) && 153 sn_obio_getaddr_kludge(sc, myaddr)) { /* XXX kludge for PB */ 154 aprint_error(": failed to get MAC address.\n"); 155 bus_space_unmap(sc->sc_st, sc->sc_sh, SONIC_NREGS * 4); 156 return; 157 } 158 159 aprint_normal(": integrated SONIC Ethernet adapter\n"); 160 161 if (mac68k_machine.aux_interrupts) { 162 intr_establish(sonic_intr, (void *)sc, 3); 163 } else { 164 add_nubus_intr(SONIC_SLOTNO, (void (*)(void *))sonic_intr, 165 (void *)sc); 166 } 167 168 sonic_attach(sc, myaddr); 169} 170 171static int 172sn_obio_getaddr(struct sonic_softc *sc, uint8_t *lladdr) 173{ 174 bus_space_handle_t bsh; 175 176 if (bus_space_map(sc->sc_st, SONIC_PROM_BASE, PAGE_SIZE, 0, &bsh)) { 177 aprint_error(": failed to map space to read SONIC address.\n"); 178 aprint_normal("%s:", device_xname(sc->sc_dev)); 179 return -1; 180 } 181 182 if (!mac68k_bus_space_probe(sc->sc_st, bsh, 0, 1)) { 183 bus_space_unmap(sc->sc_st, bsh, PAGE_SIZE); 184 return -1; 185 } 186 187 sn_get_enaddr(sc->sc_st, bsh, 0, lladdr); 188 189 bus_space_unmap(sc->sc_st, bsh, PAGE_SIZE); 190 191 return 0; 192} 193 194/* 195 * Assume that the SONIC was initialized in MacOS. This should go away 196 * when we can properly get the MAC address on the PBs. 197 */ 198static int 199sn_obio_getaddr_kludge(struct sonic_softc *sc, u_int8_t *lladdr) 200{ 201 int i, ors = 0; 202 203 /* Shut down NIC */ 204 CSR_WRITE(sc, SONIC_CR, CR_RST); 205 206 /* For some reason, Apple fills top first. */ 207 CSR_WRITE(sc, SONIC_CEP, 15); 208 209 i = CSR_READ(sc, SONIC_CAP2); 210 211 ors |= i; 212 lladdr[5] = i >> 8; 213 lladdr[4] = i; 214 215 i = CSR_READ(sc, SONIC_CAP1); 216 217 ors |= i; 218 lladdr[3] = i >> 8; 219 lladdr[2] = i; 220 221 i = CSR_READ(sc, SONIC_CAP0); 222 223 ors |= i; 224 lladdr[1] = i >> 8; 225 lladdr[0] = i; 226 227 CSR_WRITE(sc, SONIC_CR, 0); 228 229 if (ors == 0) 230 return -1; 231 232 return 0; 233} 234