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