1 /* $NetBSD: if_smsh_gxio.c,v 1.2 2009/11/29 10:08:15 kiyohara Exp $ */ 2 /* 3 * Copyright (c) 2008 KIYOHARA Takashi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __KERNEL_RCSID(0, "$NetBSD: if_smsh_gxio.c,v 1.2 2009/11/29 10:08:15 kiyohara Exp $"); 30 31 #include <sys/param.h> 32 #include <sys/device.h> 33 #include <sys/errno.h> 34 #include <sys/bus.h> 35 #include <sys/systm.h> 36 37 #include <evbarm/gumstix/gumstixvar.h> 38 39 #include <net/if.h> 40 #include <net/if_ether.h> 41 #include <net/if_media.h> 42 43 #include <dev/mii/miivar.h> 44 45 #include <dev/ic/lan9118var.h> 46 #include <dev/ic/lan9118reg.h> 47 48 #include "locators.h" 49 50 51 static int smsh_gxio_match(device_t, struct cfdata *, void *); 52 static void smsh_gxio_attach(device_t, device_t, void *); 53 54 static int ether_serial_digit = 1; 55 56 struct smsh_gxio_softc { 57 struct lan9118_softc sc_smsh; 58 void *sc_ih; 59 60 /* 61 * Board independent DMA stuffs, if uses master DMA. 62 * We use PXA2x0's DMA. 63 */ 64 struct dmac_xfer *sc_txfer; 65 struct dmac_xfer *sc_rxfer; 66 }; 67 68 CFATTACH_DECL_NEW(smsh_gxio, sizeof(struct smsh_gxio_softc), 69 smsh_gxio_match, smsh_gxio_attach, NULL, NULL); 70 71 72 /* ARGSUSED */ 73 static int 74 smsh_gxio_match(device_t parent, struct cfdata *match, void *aux) 75 { 76 struct gxio_attach_args *gxa = aux; 77 bus_space_tag_t iot = gxa->gxa_iot; 78 bus_space_handle_t ioh; 79 uint32_t val; 80 int rv = 0; 81 82 /* Disallow wildcarded values. */ 83 if (gxa->gxa_addr == GXIOCF_ADDR_DEFAULT) 84 return 0; 85 if (gxa->gxa_gpirq == GXIOCF_GPIRQ_DEFAULT) 86 return 0; 87 88 if (bus_space_map(iot, gxa->gxa_addr, LAN9118_IOSIZE, 0, &ioh) != 0) 89 return 0; 90 91 bus_space_write_4(iot, ioh, LAN9118_BYTE_TEST, 0); 92 val = bus_space_read_4(iot, ioh, LAN9118_BYTE_TEST); 93 if (val == LAN9118_BYTE_TEST_VALUE) 94 /* Assume we have an SMSC LAN9117 */ 95 rv = 1; 96 if (ether_serial_digit > 15) 97 rv = 0; 98 99 bus_space_unmap(iot, ioh, LAN9118_IOSIZE); 100 return rv; 101 } 102 103 /* ARGSUSED */ 104 static void 105 smsh_gxio_attach(device_t parent, device_t self, void *aux) 106 { 107 struct smsh_gxio_softc *gsc = device_private(self); 108 struct lan9118_softc *sc = &gsc->sc_smsh; 109 struct gxio_attach_args *gxa = aux; 110 111 KASSERT(system_serial_high != 0 || system_serial_low != 0); 112 113 sc->sc_dev = self; 114 115 /* Map i/o space. */ 116 if (bus_space_map(gxa->gxa_iot, gxa->gxa_addr, LAN9118_IOSIZE, 0, 117 &sc->sc_ioh)) 118 panic("sms_gxio_attach: can't map i/o space"); 119 sc->sc_iot = gxa->gxa_iot; 120 121 sc->sc_enaddr[0] = ((system_serial_high >> 8) & 0xfe) | 0x02; 122 sc->sc_enaddr[1] = system_serial_high; 123 sc->sc_enaddr[2] = system_serial_low >> 24; 124 sc->sc_enaddr[3] = system_serial_low >> 16; 125 sc->sc_enaddr[4] = system_serial_low >> 8; 126 sc->sc_enaddr[5] = (system_serial_low & 0xc0) | 127 (1 << 4) | ((ether_serial_digit++) & 0x0f); 128 sc->sc_flags = LAN9118_FLAGS_NO_EEPROM; 129 if (lan9118_attach(sc) != 0) { 130 bus_space_unmap(sc->sc_iot, sc->sc_ioh, LAN9118_IOSIZE); 131 return; 132 } 133 134 /* Establish the interrupt handler. */ 135 gsc->sc_ih = gxio_intr_establish(gxa->gxa_sc, 136 gxa->gxa_gpirq, IST_EDGE_FALLING, IPL_NET, lan9118_intr, sc); 137 if (gsc->sc_ih == NULL) { 138 aprint_error_dev(self, 139 "couldn't establish interrupt handler\n"); 140 bus_space_unmap(sc->sc_iot, sc->sc_ioh, LAN9118_IOSIZE); 141 return; 142 } 143 } 144