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