The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/hme/if_hme_sbus.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    3  * All rights reserved.
    4  *
    5  * This code is derived from software contributed to The NetBSD Foundation
    6  * by Paul Kranenburg.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *        This product includes software developed by the NetBSD
   19  *        Foundation, Inc. and its contributors.
   20  * 4. Neither the name of The NetBSD Foundation nor the names of its
   21  *    contributors may be used to endorse or promote products derived
   22  *    from this software without specific prior written permission.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   26  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   27  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   28  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   34  * POSSIBILITY OF SUCH DAMAGE.
   35  *
   36  *      from: NetBSD: if_hme_sbus.c,v 1.9 2001/11/13 06:58:17 lukem Exp
   37  *
   38  * $FreeBSD: releng/5.1/sys/dev/hme/if_hme_sbus.c 113506 2003-04-15 06:37:30Z mdodd $
   39  */
   40 
   41 /*
   42  * SBus front-end device driver for the HME ethernet device.
   43  */
   44 
   45 #include <sys/param.h>
   46 #include <sys/systm.h>
   47 #include <sys/bus.h>
   48 #include <sys/kernel.h>
   49 #include <sys/resource.h>
   50 #include <sys/socket.h>
   51 
   52 #include <machine/bus.h>
   53 #include <machine/ofw_machdep.h>
   54 #include <machine/resource.h>
   55 
   56 #include <sys/rman.h>
   57 
   58 #include <ofw/openfirm.h>
   59 
   60 #include <net/ethernet.h>
   61 #include <net/if.h>
   62 #include <net/if_arp.h>
   63 #include <net/if_dl.h>
   64 #include <net/if_media.h>
   65 
   66 #include <mii/mii.h>
   67 #include <mii/miivar.h>
   68 
   69 #include <sparc64/sbus/sbusvar.h>
   70 
   71 #include <hme/if_hmereg.h>
   72 #include <hme/if_hmevar.h>
   73 
   74 #include "miibus_if.h"
   75 
   76 struct hme_sbus_softc {
   77         struct  hme_softc       hsc_hme;        /* HME device */
   78         struct  resource        *hsc_seb_res;
   79         int                     hsc_seb_rid;
   80         struct  resource        *hsc_etx_res;
   81         int                     hsc_etx_rid;
   82         struct  resource        *hsc_erx_res;
   83         int                     hsc_erx_rid;
   84         struct  resource        *hsc_mac_res;
   85         int                     hsc_mac_rid;
   86         struct  resource        *hsc_mif_res;
   87         int                     hsc_mif_rid;
   88         struct  resource        *hsc_ires;
   89         int                     hsc_irid;
   90         void                    *hsc_ih;
   91 };
   92 
   93 static int hme_sbus_probe(device_t);
   94 static int hme_sbus_attach(device_t);
   95 static int hme_sbus_detach(device_t);
   96 static int hme_sbus_suspend(device_t);
   97 static int hme_sbus_resume(device_t);
   98 
   99 static device_method_t hme_sbus_methods[] = {
  100         /* Device interface */
  101         DEVMETHOD(device_probe,         hme_sbus_probe),
  102         DEVMETHOD(device_attach,        hme_sbus_attach),
  103         DEVMETHOD(device_detach,        hme_sbus_detach),
  104         DEVMETHOD(device_suspend,       hme_sbus_suspend),
  105         DEVMETHOD(device_resume,        hme_sbus_resume),
  106         /* Can just use the suspend method here. */
  107         DEVMETHOD(device_shutdown,      hme_sbus_suspend),
  108 
  109         /* bus interface */
  110         DEVMETHOD(bus_print_child,      bus_generic_print_child),
  111         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
  112 
  113         /* MII interface */
  114         DEVMETHOD(miibus_readreg,       hme_mii_readreg),
  115         DEVMETHOD(miibus_writereg,      hme_mii_writereg),
  116         DEVMETHOD(miibus_statchg,       hme_mii_statchg),
  117 
  118         { 0, 0 }
  119 };
  120 
  121 static driver_t hme_sbus_driver = {
  122         "hme",
  123         hme_sbus_methods,
  124         sizeof(struct hme_sbus_softc)
  125 };
  126 
  127 DRIVER_MODULE(hme, sbus, hme_sbus_driver, hme_devclass, 0, 0);
  128 MODULE_DEPEND(hme, ether, 1, 1, 1);
  129 
  130 static int
  131 hme_sbus_probe(device_t dev)
  132 {
  133         char *name;
  134 
  135         name = sbus_get_name(dev);
  136         if (strcmp(name, "SUNW,qfe") == 0 ||
  137             strcmp(name, "SUNW,hme") == 0) {
  138                 device_set_desc(dev, "Sun HME 10/100 Ethernet");
  139                 return (0);
  140         }
  141         return (ENXIO);
  142 }
  143 
  144 static int
  145 hme_sbus_attach(device_t dev)
  146 {
  147         struct hme_sbus_softc *hsc = device_get_softc(dev);
  148         struct hme_softc *sc = &hsc->hsc_hme;
  149         u_int32_t burst;
  150         u_long start, count;
  151         int error;
  152 
  153         /*
  154          * Map five register banks:
  155          *
  156          *      bank 0: HME SEB registers
  157          *      bank 1: HME ETX registers
  158          *      bank 2: HME ERX registers
  159          *      bank 3: HME MAC registers
  160          *      bank 4: HME MIF registers
  161          *
  162          */
  163         sc->sc_sebo = sc->sc_etxo = sc->sc_erxo = sc->sc_maco = sc->sc_mifo = 0;
  164         hsc->hsc_seb_rid = 0;
  165         hsc->hsc_seb_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
  166             &hsc->hsc_seb_rid, 0, ~0, 1, RF_ACTIVE);
  167         if (hsc->hsc_seb_res == NULL) {
  168                 device_printf(dev, "cannot map SEB registers\n");
  169                 return (ENXIO);
  170         }
  171         sc->sc_sebt = rman_get_bustag(hsc->hsc_seb_res);
  172         sc->sc_sebh = rman_get_bushandle(hsc->hsc_seb_res);
  173 
  174         hsc->hsc_etx_rid = 1;
  175         hsc->hsc_etx_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
  176             &hsc->hsc_etx_rid, 0, ~0, 1, RF_ACTIVE);
  177         if (hsc->hsc_etx_res == NULL) {
  178                 device_printf(dev, "cannot map ETX registers\n");
  179                 goto fail_seb_res;
  180         }
  181         sc->sc_etxt = rman_get_bustag(hsc->hsc_etx_res);
  182         sc->sc_etxh = rman_get_bushandle(hsc->hsc_etx_res);
  183 
  184         hsc->hsc_erx_rid = 2;
  185         hsc->hsc_erx_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
  186             &hsc->hsc_erx_rid, 0, ~0, 1, RF_ACTIVE);
  187         if (hsc->hsc_erx_res == NULL) {
  188                 device_printf(dev, "cannot map ERX registers\n");
  189                 goto fail_etx_res;
  190         }
  191         sc->sc_erxt = rman_get_bustag(hsc->hsc_erx_res);
  192         sc->sc_erxh = rman_get_bushandle(hsc->hsc_erx_res);
  193 
  194         hsc->hsc_mac_rid = 3;
  195         hsc->hsc_mac_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
  196             &hsc->hsc_mac_rid, 0, ~0, 1, RF_ACTIVE);
  197         if (hsc->hsc_mac_res == NULL) {
  198                 device_printf(dev, "cannot map MAC registers\n");
  199                 goto fail_erx_res;
  200         }
  201         sc->sc_mact = rman_get_bustag(hsc->hsc_mac_res);
  202         sc->sc_mach = rman_get_bushandle(hsc->hsc_mac_res);
  203 
  204         /*
  205          * At least on some HMEs, the MIF registers seem to be inside the MAC
  206          * range, so map try to kluge around it.
  207          */
  208         hsc->hsc_mif_rid = 4;
  209         hsc->hsc_mif_res = bus_alloc_resource(dev, SYS_RES_MEMORY,
  210             &hsc->hsc_mif_rid, 0, ~0, 1, RF_ACTIVE);
  211         if (hsc->hsc_mif_res == NULL) {
  212                 if (bus_get_resource(dev, SYS_RES_MEMORY, hsc->hsc_mif_rid,
  213                     &start, &count) != 0) {
  214                         device_printf(dev, "cannot get MIF registers\n");
  215                         goto fail_mac_res;
  216                 }
  217                 if (start < rman_get_start(hsc->hsc_mac_res) ||
  218                     start + count - 1 > rman_get_end(hsc->hsc_mac_res)) {
  219                         device_printf(dev, "cannot move MIF registers to MAC "
  220                             "bank\n");
  221                         goto fail_mac_res;
  222                 }
  223                 sc->sc_mift = sc->sc_mact;
  224                 sc->sc_mifh = sc->sc_mach;
  225                 sc->sc_mifo = sc->sc_maco + start -
  226                     rman_get_start(hsc->hsc_mac_res);
  227         } else {
  228                 sc->sc_mift = rman_get_bustag(hsc->hsc_mif_res);
  229                 sc->sc_mifh = rman_get_bushandle(hsc->hsc_mif_res);
  230         }
  231 
  232         hsc->hsc_irid = 0;
  233         hsc->hsc_ires = bus_alloc_resource(dev, SYS_RES_IRQ, &hsc->hsc_irid, 0,
  234             ~0, 1, RF_SHAREABLE | RF_ACTIVE);
  235         if (hsc->hsc_ires == NULL) {
  236                 device_printf(dev, "could not allocate interrupt\n");
  237                 error = ENXIO;
  238                 goto fail_mif_res;
  239         }
  240 
  241 
  242         OF_getetheraddr(dev, sc->sc_arpcom.ac_enaddr);
  243 
  244         burst = sbus_get_burstsz(dev);
  245         /* Translate into plain numerical format */
  246         sc->sc_burst =  (burst & SBUS_BURST_32) ? 32 :
  247             (burst & SBUS_BURST_16) ? 16 : 0;
  248 
  249         sc->sc_pci = 0; /* XXX: should all be done in bus_dma. */
  250         sc->sc_dev = dev;
  251 
  252         if ((error = hme_config(sc)) != 0) {
  253                 device_printf(dev, "could not be configured\n");
  254                 goto fail_ires;
  255         }
  256 
  257 
  258         if ((error = bus_setup_intr(dev, hsc->hsc_ires, INTR_TYPE_NET, hme_intr,
  259              sc, &hsc->hsc_ih)) != 0) {
  260                 device_printf(dev, "couldn't establish interrupt\n");
  261                 hme_detach(sc);
  262                 goto fail_ires;
  263         }
  264         return (0);
  265 
  266 fail_ires:
  267         bus_release_resource(dev, SYS_RES_IRQ, hsc->hsc_irid, hsc->hsc_ires);
  268 fail_mif_res:
  269         if (hsc->hsc_mif_res != NULL) {
  270                 bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_mif_rid,
  271                     hsc->hsc_mif_res);
  272         }
  273 fail_mac_res:
  274         bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_mac_rid,
  275             hsc->hsc_mac_res);
  276 fail_erx_res:
  277         bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_erx_rid,
  278             hsc->hsc_erx_res);
  279 fail_etx_res:
  280         bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_etx_rid,
  281             hsc->hsc_etx_res);
  282 fail_seb_res:
  283         bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_seb_rid,
  284             hsc->hsc_seb_res);
  285         return (ENXIO);
  286 }
  287 
  288 static int
  289 hme_sbus_detach(device_t dev)
  290 {
  291         struct hme_sbus_softc *hsc = device_get_softc(dev);
  292         struct hme_softc *sc = &hsc->hsc_hme;
  293 
  294         hme_detach(sc);
  295 
  296         bus_teardown_intr(dev, hsc->hsc_ires, hsc->hsc_ih);
  297         if (hsc->hsc_mif_res != NULL) {
  298                 bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_mif_rid,
  299                     hsc->hsc_mif_res);
  300         }
  301         bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_mac_rid,
  302             hsc->hsc_mac_res);
  303         bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_erx_rid,
  304             hsc->hsc_erx_res);
  305         bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_etx_rid,
  306             hsc->hsc_etx_res);
  307         bus_release_resource(dev, SYS_RES_MEMORY, hsc->hsc_seb_rid,
  308             hsc->hsc_seb_res);
  309         return (0);
  310 }
  311 
  312 static int
  313 hme_sbus_suspend(device_t dev)
  314 {
  315         struct hme_sbus_softc *hsc = device_get_softc(dev);
  316         struct hme_softc *sc = &hsc->hsc_hme;
  317 
  318         hme_suspend(sc);
  319         return (0);
  320 }
  321 
  322 static int
  323 hme_sbus_resume(device_t dev)
  324 {
  325         struct hme_sbus_softc *hsc = device_get_softc(dev);
  326         struct hme_softc *sc = &hsc->hsc_hme;
  327 
  328         hme_resume(sc);
  329         return (0);
  330 }

Cache object: 6341d1149b7798e8eee444eac836e150


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.