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/mips/idt/if_kr.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) 2007 
    3  *      Oleksandr Tymoshenko <gonzo@freebsd.org>. All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   17  * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
   18  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   20  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   22  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   23  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   24  * THE POSSIBILITY OF SUCH DAMAGE.
   25  *
   26  * $Id: $
   27  * 
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD: releng/8.0/sys/mips/idt/if_kr.c 194342 2009-06-17 10:23:25Z bz $");
   32 
   33 /*
   34  * RC32434 Ethernet interface driver
   35  */
   36 #include <sys/param.h>
   37 #include <sys/endian.h>
   38 #include <sys/systm.h>
   39 #include <sys/sockio.h>
   40 #include <sys/mbuf.h>
   41 #include <sys/malloc.h>
   42 #include <sys/kernel.h>
   43 #include <sys/module.h>
   44 #include <sys/socket.h>
   45 #include <sys/taskqueue.h>
   46 
   47 #include <net/if.h>
   48 #include <net/if_arp.h>
   49 #include <net/ethernet.h>
   50 #include <net/if_dl.h>
   51 #include <net/if_media.h>
   52 #include <net/if_types.h>
   53 
   54 #include <net/bpf.h>
   55 
   56 #include <machine/bus.h>
   57 #include <machine/resource.h>
   58 #include <sys/bus.h>
   59 #include <sys/rman.h>
   60 
   61 #include <dev/mii/mii.h>
   62 #include <dev/mii/miivar.h>
   63 
   64 #include <dev/pci/pcireg.h>
   65 #include <dev/pci/pcivar.h>
   66 
   67 MODULE_DEPEND(kr, ether, 1, 1, 1);
   68 MODULE_DEPEND(kr, miibus, 1, 1, 1);
   69 
   70 #include "miibus_if.h"
   71 
   72 #include <mips/idt/if_krreg.h>
   73 
   74 #define KR_DEBUG
   75 
   76 static int kr_attach(device_t);
   77 static int kr_detach(device_t);
   78 static int kr_ifmedia_upd(struct ifnet *);
   79 static void kr_ifmedia_sts(struct ifnet *, struct ifmediareq *);
   80 static int kr_ioctl(struct ifnet *, u_long, caddr_t);
   81 static void kr_init(void *);
   82 static void kr_init_locked(struct kr_softc *);
   83 static void kr_link_task(void *, int);
   84 static int kr_miibus_readreg(device_t, int, int);
   85 static void kr_miibus_statchg(device_t);
   86 static int kr_miibus_writereg(device_t, int, int, int);
   87 static int kr_probe(device_t);
   88 static void kr_reset(struct kr_softc *);
   89 static int kr_resume(device_t);
   90 static int kr_rx_ring_init(struct kr_softc *);
   91 static int kr_tx_ring_init(struct kr_softc *);
   92 static int kr_shutdown(device_t);
   93 static void kr_start(struct ifnet *);
   94 static void kr_start_locked(struct ifnet *);
   95 static void kr_stop(struct kr_softc *);
   96 static int kr_suspend(device_t);
   97 
   98 static void kr_rx(struct kr_softc *);
   99 static void kr_tx(struct kr_softc *);
  100 static void kr_rx_intr(void *);
  101 static void kr_tx_intr(void *);
  102 static void kr_rx_und_intr(void *);
  103 static void kr_tx_ovr_intr(void *);
  104 static void kr_tick(void *);
  105 
  106 static void kr_dmamap_cb(void *, bus_dma_segment_t *, int, int);
  107 static int kr_dma_alloc(struct kr_softc *);
  108 static void kr_dma_free(struct kr_softc *);
  109 static int kr_newbuf(struct kr_softc *, int);
  110 static __inline void kr_fixup_rx(struct mbuf *);
  111 
  112 static device_method_t kr_methods[] = {
  113         /* Device interface */
  114         DEVMETHOD(device_probe,         kr_probe),
  115         DEVMETHOD(device_attach,        kr_attach),
  116         DEVMETHOD(device_detach,        kr_detach),
  117         DEVMETHOD(device_suspend,       kr_suspend),
  118         DEVMETHOD(device_resume,        kr_resume),
  119         DEVMETHOD(device_shutdown,      kr_shutdown),
  120 
  121         /* bus interface */
  122         DEVMETHOD(bus_print_child,      bus_generic_print_child),
  123         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
  124 
  125         /* MII interface */
  126         DEVMETHOD(miibus_readreg,       kr_miibus_readreg),
  127         DEVMETHOD(miibus_writereg,      kr_miibus_writereg),
  128         DEVMETHOD(miibus_statchg,       kr_miibus_statchg),
  129 
  130         { 0, 0 }
  131 };
  132 
  133 static driver_t kr_driver = {
  134         "kr",
  135         kr_methods,
  136         sizeof(struct kr_softc)
  137 };
  138 
  139 static devclass_t kr_devclass;
  140 
  141 DRIVER_MODULE(kr, obio, kr_driver, kr_devclass, 0, 0);
  142 DRIVER_MODULE(miibus, kr, miibus_driver, miibus_devclass, 0, 0);
  143 
  144 static int 
  145 kr_probe(device_t dev)
  146 {
  147 
  148         device_set_desc(dev, "RC32434 Ethernet interface");
  149         return (0);
  150 }
  151 
  152 static int
  153 kr_attach(device_t dev)
  154 {
  155         uint8_t                 eaddr[ETHER_ADDR_LEN];
  156         struct ifnet            *ifp;
  157         struct kr_softc         *sc;
  158         int                     error = 0, rid;
  159         int                     unit;
  160 
  161         sc = device_get_softc(dev);
  162         unit = device_get_unit(dev);
  163         sc->kr_dev = dev;
  164 
  165         mtx_init(&sc->kr_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
  166             MTX_DEF);
  167         callout_init_mtx(&sc->kr_stat_callout, &sc->kr_mtx, 0);
  168         TASK_INIT(&sc->kr_link_task, 0, kr_link_task, sc);
  169         pci_enable_busmaster(dev);
  170 
  171         /* Map control/status registers. */
  172         sc->kr_rid = 0;
  173         sc->kr_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->kr_rid, 
  174             RF_ACTIVE);
  175 
  176         if (sc->kr_res == NULL) {
  177                 device_printf(dev, "couldn't map memory\n");
  178                 error = ENXIO;
  179                 goto fail;
  180         }
  181 
  182         sc->kr_btag = rman_get_bustag(sc->kr_res);
  183         sc->kr_bhandle = rman_get_bushandle(sc->kr_res);
  184 
  185         /* Allocate interrupts */
  186         rid = 0;
  187         sc->kr_rx_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, KR_RX_IRQ,
  188             KR_RX_IRQ, 1, RF_SHAREABLE | RF_ACTIVE);
  189 
  190         if (sc->kr_rx_irq == NULL) {
  191                 device_printf(dev, "couldn't map rx interrupt\n");
  192                 error = ENXIO;
  193                 goto fail;
  194         }
  195 
  196         rid = 0;
  197         sc->kr_tx_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, KR_TX_IRQ,
  198             KR_TX_IRQ, 1, RF_SHAREABLE | RF_ACTIVE);
  199 
  200         if (sc->kr_tx_irq == NULL) {
  201                 device_printf(dev, "couldn't map tx interrupt\n");
  202                 error = ENXIO;
  203                 goto fail;
  204         }
  205 
  206         rid = 0;
  207         sc->kr_rx_und_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 
  208             KR_RX_UND_IRQ, KR_RX_UND_IRQ, 1, RF_SHAREABLE | RF_ACTIVE);
  209 
  210         if (sc->kr_rx_und_irq == NULL) {
  211                 device_printf(dev, "couldn't map rx underrun interrupt\n");
  212                 error = ENXIO;
  213                 goto fail;
  214         }
  215 
  216         rid = 0;
  217         sc->kr_tx_ovr_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 
  218             KR_TX_OVR_IRQ, KR_TX_OVR_IRQ, 1, RF_SHAREABLE | RF_ACTIVE);
  219 
  220         if (sc->kr_tx_ovr_irq == NULL) {
  221                 device_printf(dev, "couldn't map tx overrun interrupt\n");
  222                 error = ENXIO;
  223                 goto fail;
  224         }
  225 
  226         /* Allocate ifnet structure. */
  227         ifp = sc->kr_ifp = if_alloc(IFT_ETHER);
  228 
  229         if (ifp == NULL) {
  230                 device_printf(dev, "couldn't allocate ifnet structure\n");
  231                 error = ENOSPC;
  232                 goto fail;
  233         }
  234         ifp->if_softc = sc;
  235         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
  236         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  237         ifp->if_ioctl = kr_ioctl;
  238         ifp->if_start = kr_start;
  239         ifp->if_init = kr_init;
  240 
  241         /* XXX: add real size */
  242         IFQ_SET_MAXLEN(&ifp->if_snd, 9);
  243         ifp->if_snd.ifq_maxlen = 9;
  244         IFQ_SET_READY(&ifp->if_snd);
  245 
  246         ifp->if_capenable = ifp->if_capabilities;
  247 
  248         eaddr[0] = 0x00;
  249         eaddr[1] = 0x0C;
  250         eaddr[2] = 0x42;
  251         eaddr[3] = 0x09;
  252         eaddr[4] = 0x5E;
  253         eaddr[5] = 0x6B;
  254 
  255         if (kr_dma_alloc(sc) != 0) {
  256                 error = ENXIO;
  257                 goto fail;
  258         }
  259 
  260         /* TODO: calculate prescale */
  261         CSR_WRITE_4(sc, KR_ETHMCP, (165000000 / (1250000 + 1)) & ~1);
  262 
  263         CSR_WRITE_4(sc, KR_MIIMCFG, KR_MIIMCFG_R);
  264         DELAY(1000);
  265         CSR_WRITE_4(sc, KR_MIIMCFG, 0);
  266 
  267         /* Do MII setup. */
  268         if (mii_phy_probe(dev, &sc->kr_miibus,
  269             kr_ifmedia_upd, kr_ifmedia_sts)) {
  270                 device_printf(dev, "MII without any phy!\n");
  271                 error = ENXIO;
  272                 goto fail;
  273         }
  274 
  275         /* Call MI attach routine. */
  276         ether_ifattach(ifp, eaddr);
  277 
  278         /* Hook interrupt last to avoid having to lock softc */
  279         error = bus_setup_intr(dev, sc->kr_rx_irq, INTR_TYPE_NET | INTR_MPSAFE,
  280             NULL, kr_rx_intr, sc, &sc->kr_rx_intrhand);
  281 
  282         if (error) {
  283                 device_printf(dev, "couldn't set up rx irq\n");
  284                 ether_ifdetach(ifp);
  285                 goto fail;
  286         }
  287 
  288         error = bus_setup_intr(dev, sc->kr_tx_irq, INTR_TYPE_NET | INTR_MPSAFE,
  289             NULL, kr_tx_intr, sc, &sc->kr_tx_intrhand);
  290 
  291         if (error) {
  292                 device_printf(dev, "couldn't set up tx irq\n");
  293                 ether_ifdetach(ifp);
  294                 goto fail;
  295         }
  296 
  297         error = bus_setup_intr(dev, sc->kr_rx_und_irq, 
  298             INTR_TYPE_NET | INTR_MPSAFE, NULL, kr_rx_und_intr, sc, 
  299             &sc->kr_rx_und_intrhand);
  300 
  301         if (error) {
  302                 device_printf(dev, "couldn't set up rx underrun irq\n");
  303                 ether_ifdetach(ifp);
  304                 goto fail;
  305         }
  306 
  307         error = bus_setup_intr(dev, sc->kr_tx_ovr_irq, 
  308             INTR_TYPE_NET | INTR_MPSAFE, NULL, kr_tx_ovr_intr, sc, 
  309             &sc->kr_tx_ovr_intrhand);
  310 
  311         if (error) {
  312                 device_printf(dev, "couldn't set up tx overrun irq\n");
  313                 ether_ifdetach(ifp);
  314                 goto fail;
  315         }
  316 
  317 fail:
  318         if (error) 
  319                 kr_detach(dev);
  320 
  321         return (error);
  322 }
  323 
  324 static int
  325 kr_detach(device_t dev)
  326 {
  327         struct kr_softc         *sc = device_get_softc(dev);
  328         struct ifnet            *ifp = sc->kr_ifp;
  329 
  330         KASSERT(mtx_initialized(&sc->kr_mtx), ("vr mutex not initialized"));
  331 
  332         /* These should only be active if attach succeeded */
  333         if (device_is_attached(dev)) {
  334                 KR_LOCK(sc);
  335                 sc->kr_detach = 1;
  336                 kr_stop(sc);
  337                 KR_UNLOCK(sc);
  338                 taskqueue_drain(taskqueue_swi, &sc->kr_link_task);
  339                 ether_ifdetach(ifp);
  340         }
  341         if (sc->kr_miibus)
  342                 device_delete_child(dev, sc->kr_miibus);
  343         bus_generic_detach(dev);
  344 
  345         if (sc->kr_rx_intrhand)
  346                 bus_teardown_intr(dev, sc->kr_rx_irq, sc->kr_rx_intrhand);
  347         if (sc->kr_rx_irq)
  348                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->kr_rx_irq);
  349         if (sc->kr_tx_intrhand)
  350                 bus_teardown_intr(dev, sc->kr_tx_irq, sc->kr_tx_intrhand);
  351         if (sc->kr_tx_irq)
  352                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->kr_tx_irq);
  353         if (sc->kr_rx_und_intrhand)
  354                 bus_teardown_intr(dev, sc->kr_rx_und_irq, 
  355                     sc->kr_rx_und_intrhand);
  356         if (sc->kr_rx_und_irq)
  357                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->kr_rx_und_irq);
  358         if (sc->kr_tx_ovr_intrhand)
  359                 bus_teardown_intr(dev, sc->kr_tx_ovr_irq, 
  360                     sc->kr_tx_ovr_intrhand);
  361         if (sc->kr_tx_ovr_irq)
  362                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->kr_tx_ovr_irq);
  363 
  364         if (sc->kr_res)
  365                 bus_release_resource(dev, SYS_RES_MEMORY, sc->kr_rid, 
  366                     sc->kr_res);
  367 
  368         if (ifp)
  369                 if_free(ifp);
  370 
  371         kr_dma_free(sc);
  372 
  373         mtx_destroy(&sc->kr_mtx);
  374 
  375         return (0);
  376 
  377 }
  378 
  379 static int
  380 kr_suspend(device_t dev)
  381 {
  382 
  383         panic("%s", __func__);
  384         return 0;
  385 }
  386 
  387 static int
  388 kr_resume(device_t dev)
  389 {
  390 
  391         panic("%s", __func__);
  392         return 0;
  393 }
  394 
  395 static int
  396 kr_shutdown(device_t dev)
  397 {
  398         struct kr_softc *sc;
  399 
  400         sc = device_get_softc(dev);
  401 
  402         KR_LOCK(sc);
  403         kr_stop(sc);
  404         KR_UNLOCK(sc);
  405 
  406         return (0);
  407 }
  408 
  409 static int
  410 kr_miibus_readreg(device_t dev, int phy, int reg)
  411 {
  412         struct kr_softc * sc = device_get_softc(dev);
  413         int i, result;
  414 
  415         i = KR_MII_TIMEOUT;
  416         while ((CSR_READ_4(sc, KR_MIIMIND) & KR_MIIMIND_BSY) && i)
  417                 i--;
  418 
  419         if (i == 0)
  420                 device_printf(dev, "phy mii is busy %d:%d\n", phy, reg);
  421 
  422         CSR_WRITE_4(sc, KR_MIIMADDR, (phy << 8) | reg);
  423 
  424         i = KR_MII_TIMEOUT;
  425         while ((CSR_READ_4(sc, KR_MIIMIND) & KR_MIIMIND_BSY) && i)
  426                 i--;
  427 
  428         if (i == 0)
  429                 device_printf(dev, "phy mii is busy %d:%d\n", phy, reg);
  430 
  431         CSR_WRITE_4(sc, KR_MIIMCMD, KR_MIIMCMD_RD);
  432 
  433         i = KR_MII_TIMEOUT;
  434         while ((CSR_READ_4(sc, KR_MIIMIND) & KR_MIIMIND_BSY) && i)
  435                 i--;
  436 
  437         if (i == 0)
  438                 device_printf(dev, "phy mii read is timed out %d:%d\n", phy, 
  439                     reg);
  440 
  441         if (CSR_READ_4(sc, KR_MIIMIND) & KR_MIIMIND_NV)
  442                 printf("phy mii readreg failed %d:%d: data not valid\n",
  443                     phy, reg);
  444 
  445         result = CSR_READ_4(sc , KR_MIIMRDD);
  446         CSR_WRITE_4(sc, KR_MIIMCMD, 0);
  447 
  448         return (result);
  449 }
  450 
  451 static int
  452 kr_miibus_writereg(device_t dev, int phy, int reg, int data)
  453 {
  454         struct kr_softc * sc = device_get_softc(dev);
  455         int i;
  456 
  457         i = KR_MII_TIMEOUT;
  458         while ((CSR_READ_4(sc, KR_MIIMIND) & KR_MIIMIND_BSY) && i)
  459                 i--;
  460 
  461         if (i == 0)
  462                 device_printf(dev, "phy mii is busy %d:%d\n", phy, reg);
  463 
  464         CSR_WRITE_4(sc, KR_MIIMADDR, (phy << 8) | reg);
  465 
  466         i = KR_MII_TIMEOUT;
  467         while ((CSR_READ_4(sc, KR_MIIMIND) & KR_MIIMIND_BSY) && i)
  468                 i--;
  469 
  470         if (i == 0)
  471                 device_printf(dev, "phy mii is busy %d:%d\n", phy, reg);
  472 
  473         CSR_WRITE_4(sc, KR_MIIMWTD, data);
  474 
  475         i = KR_MII_TIMEOUT;
  476         while ((CSR_READ_4(sc, KR_MIIMIND) & KR_MIIMIND_BSY) && i)
  477                 i--;
  478 
  479         if (i == 0)
  480                 device_printf(dev, "phy mii is busy %d:%d\n", phy, reg);
  481 
  482         return (0);
  483 }
  484 
  485 static void
  486 kr_miibus_statchg(device_t dev)
  487 {
  488         struct kr_softc         *sc;
  489 
  490         sc = device_get_softc(dev);
  491         taskqueue_enqueue(taskqueue_swi, &sc->kr_link_task);
  492 }
  493 
  494 static void
  495 kr_link_task(void *arg, int pending)
  496 {
  497         struct kr_softc         *sc;
  498         struct mii_data         *mii;
  499         struct ifnet            *ifp;
  500         /* int                  lfdx, mfdx; */
  501 
  502         sc = (struct kr_softc *)arg;
  503 
  504         KR_LOCK(sc);
  505         mii = device_get_softc(sc->kr_miibus);
  506         ifp = sc->kr_ifp;
  507         if (mii == NULL || ifp == NULL ||
  508             (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
  509                 KR_UNLOCK(sc);
  510                 return;
  511         }
  512 
  513         if (mii->mii_media_status & IFM_ACTIVE) {
  514                 if (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
  515                         sc->kr_link_status = 1;
  516         } else
  517                 sc->kr_link_status = 0;
  518 
  519         KR_UNLOCK(sc);
  520 }
  521 
  522 static void
  523 kr_reset(struct kr_softc *sc)
  524 {
  525         int             i;
  526 
  527         CSR_WRITE_4(sc, KR_ETHINTFC, 0);
  528 
  529         for (i = 0; i < KR_TIMEOUT; i++) {
  530                 DELAY(10);
  531                 if (!(CSR_READ_4(sc, KR_ETHINTFC) & ETH_INTFC_RIP))
  532                         break;
  533         }
  534 
  535         if (i == KR_TIMEOUT)
  536                 device_printf(sc->kr_dev, "reset time out\n");
  537 }
  538 
  539 static void
  540 kr_init(void *xsc)
  541 {
  542         struct kr_softc  *sc = xsc;
  543 
  544         KR_LOCK(sc);
  545         kr_init_locked(sc);
  546         KR_UNLOCK(sc);
  547 }
  548 
  549 static void
  550 kr_init_locked(struct kr_softc *sc)
  551 {
  552         struct ifnet            *ifp = sc->kr_ifp;
  553         struct mii_data         *mii;
  554 
  555         KR_LOCK_ASSERT(sc);
  556 
  557         mii = device_get_softc(sc->kr_miibus);
  558 
  559         kr_stop(sc);
  560         kr_reset(sc);
  561 
  562         CSR_WRITE_4(sc, KR_ETHINTFC, ETH_INTFC_EN);
  563 
  564         /* Init circular RX list. */
  565         if (kr_rx_ring_init(sc) != 0) {
  566                 device_printf(sc->kr_dev,
  567                     "initialization failed: no memory for rx buffers\n");
  568                 kr_stop(sc);
  569                 return;
  570         }
  571 
  572         /* Init tx descriptors. */
  573         kr_tx_ring_init(sc);
  574 
  575         KR_DMA_WRITE_REG(KR_DMA_RXCHAN, DMA_S, 0);
  576         KR_DMA_WRITE_REG(KR_DMA_RXCHAN, DMA_NDPTR, 0);
  577         KR_DMA_WRITE_REG(KR_DMA_RXCHAN, DMA_DPTR, 
  578             sc->kr_rdata.kr_rx_ring_paddr);
  579 
  580 
  581         KR_DMA_CLEARBITS_REG(KR_DMA_RXCHAN, DMA_SM, 
  582             DMA_SM_H | DMA_SM_E | DMA_SM_D) ;
  583 
  584         KR_DMA_WRITE_REG(KR_DMA_TXCHAN, DMA_S, 0);
  585         KR_DMA_WRITE_REG(KR_DMA_TXCHAN, DMA_NDPTR, 0);
  586         KR_DMA_WRITE_REG(KR_DMA_TXCHAN, DMA_DPTR, 0);
  587         KR_DMA_CLEARBITS_REG(KR_DMA_TXCHAN, DMA_SM, 
  588             DMA_SM_F | DMA_SM_E);
  589 
  590 
  591         /* Accept only packets destined for THIS Ethernet device address */
  592         CSR_WRITE_4(sc, KR_ETHARC, 1);
  593 
  594         /* 
  595          * Set all Ethernet address registers to the same initial values
  596          * set all four addresses to 66-88-aa-cc-dd-ee 
  597          */
  598         CSR_WRITE_4(sc, KR_ETHSAL0, 0x42095E6B);
  599         CSR_WRITE_4(sc, KR_ETHSAH0, 0x0000000C);
  600 
  601         CSR_WRITE_4(sc, KR_ETHSAL1, 0x42095E6B);
  602         CSR_WRITE_4(sc, KR_ETHSAH1, 0x0000000C);
  603 
  604         CSR_WRITE_4(sc, KR_ETHSAL2, 0x42095E6B);
  605         CSR_WRITE_4(sc, KR_ETHSAH2, 0x0000000C);
  606 
  607         CSR_WRITE_4(sc, KR_ETHSAL3, 0x42095E6B);
  608         CSR_WRITE_4(sc, KR_ETHSAH3, 0x0000000C);
  609 
  610         CSR_WRITE_4(sc, KR_ETHMAC2, 
  611             KR_ETH_MAC2_PEN | KR_ETH_MAC2_CEN | KR_ETH_MAC2_FD);
  612 
  613         CSR_WRITE_4(sc, KR_ETHIPGT, KR_ETHIPGT_FULL_DUPLEX);
  614         CSR_WRITE_4(sc, KR_ETHIPGR, 0x12); /* minimum value */
  615 
  616         CSR_WRITE_4(sc, KR_MIIMCFG, KR_MIIMCFG_R);
  617         DELAY(1000);
  618         CSR_WRITE_4(sc, KR_MIIMCFG, 0);
  619 
  620         /* TODO: calculate prescale */
  621         CSR_WRITE_4(sc, KR_ETHMCP, (165000000 / (1250000 + 1)) & ~1);
  622 
  623         /* FIFO Tx threshold level */
  624         CSR_WRITE_4(sc, KR_ETHFIFOTT, 0x30);
  625 
  626         CSR_WRITE_4(sc, KR_ETHMAC1, KR_ETH_MAC1_RE);
  627 
  628         sc->kr_link_status = 0;
  629         mii_mediachg(mii);
  630 
  631         ifp->if_drv_flags |= IFF_DRV_RUNNING;
  632         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
  633 
  634         callout_reset(&sc->kr_stat_callout, hz, kr_tick, sc);
  635 }
  636 
  637 static void
  638 kr_start(struct ifnet *ifp)
  639 {
  640         struct kr_softc  *sc;
  641 
  642         sc = ifp->if_softc;
  643 
  644         KR_LOCK(sc);
  645         kr_start_locked(ifp);
  646         KR_UNLOCK(sc);
  647 }
  648 
  649 /*
  650  * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
  651  * pointers to the fragment pointers.
  652  */
  653 static int
  654 kr_encap(struct kr_softc *sc, struct mbuf **m_head)
  655 {
  656         struct kr_txdesc        *txd;
  657         struct kr_desc          *desc, *prev_desc;
  658         bus_dma_segment_t       txsegs[KR_MAXFRAGS];
  659         uint32_t                link_addr;
  660         int                     error, i, nsegs, prod, si, prev_prod;
  661 
  662         KR_LOCK_ASSERT(sc);
  663 
  664         prod = sc->kr_cdata.kr_tx_prod;
  665         txd = &sc->kr_cdata.kr_txdesc[prod];
  666         error = bus_dmamap_load_mbuf_sg(sc->kr_cdata.kr_tx_tag, txd->tx_dmamap,
  667             *m_head, txsegs, &nsegs, BUS_DMA_NOWAIT);
  668         if (error == EFBIG) {
  669                 panic("EFBIG");
  670         } else if (error != 0)
  671                 return (error);
  672         if (nsegs == 0) {
  673                 m_freem(*m_head);
  674                 *m_head = NULL;
  675                 return (EIO);
  676         }
  677 
  678         /* Check number of available descriptors. */
  679         if (sc->kr_cdata.kr_tx_cnt + nsegs >= (KR_TX_RING_CNT - 1)) {
  680                 bus_dmamap_unload(sc->kr_cdata.kr_tx_tag, txd->tx_dmamap);
  681                 return (ENOBUFS);
  682         }
  683 
  684         txd->tx_m = *m_head;
  685         bus_dmamap_sync(sc->kr_cdata.kr_tx_tag, txd->tx_dmamap,
  686             BUS_DMASYNC_PREWRITE);
  687 
  688         si = prod;
  689 
  690         /* 
  691          * Make a list of descriptors for this packet. DMA controller will
  692          * walk through it while kr_link is not zero. The last one should
  693          * have COF flag set, to pickup next chain from NDPTR
  694          */
  695         prev_prod = prod;
  696         desc = prev_desc = NULL;
  697         for (i = 0; i < nsegs; i++) {
  698                 desc = &sc->kr_rdata.kr_tx_ring[prod];
  699                 desc->kr_ctl = KR_DMASIZE(txsegs[i].ds_len) | KR_CTL_IOF;
  700                 if (i == 0)
  701                         desc->kr_devcs = KR_DMATX_DEVCS_FD;
  702                 desc->kr_ca = txsegs[i].ds_addr;
  703                 desc->kr_link = 0;
  704                 /* link with previous descriptor */
  705                 if (prev_desc)
  706                         prev_desc->kr_link = KR_TX_RING_ADDR(sc, prod);
  707 
  708                 sc->kr_cdata.kr_tx_cnt++;
  709                 prev_desc = desc;
  710                 KR_INC(prod, KR_TX_RING_CNT);
  711         }
  712 
  713         /* 
  714          * Set COF for last descriptor and mark last fragment with LD flag
  715          */
  716         if (desc) {
  717                 desc->kr_ctl |=  KR_CTL_COF;
  718                 desc->kr_devcs |= KR_DMATX_DEVCS_LD;
  719         }
  720 
  721         /* Update producer index. */
  722         sc->kr_cdata.kr_tx_prod = prod;
  723 
  724         /* Sync descriptors. */
  725         bus_dmamap_sync(sc->kr_cdata.kr_tx_ring_tag,
  726             sc->kr_cdata.kr_tx_ring_map,
  727             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  728 
  729         /* Start transmitting */
  730         /* Check if new list is queued in NDPTR */
  731         if (KR_DMA_READ_REG(KR_DMA_TXCHAN, DMA_NDPTR) == 0) {
  732                 /* NDPTR is not busy - start new list */
  733                 KR_DMA_WRITE_REG(KR_DMA_TXCHAN, DMA_NDPTR, 
  734                     KR_TX_RING_ADDR(sc, si));
  735         }
  736         else {
  737                 link_addr = KR_TX_RING_ADDR(sc, si);
  738                 /* Get previous descriptor */
  739                 si = (si + KR_TX_RING_CNT - 1) % KR_TX_RING_CNT;
  740                 desc = &sc->kr_rdata.kr_tx_ring[si];
  741                 desc->kr_link = link_addr;
  742         }
  743 
  744         return (0);
  745 }
  746 
  747 static void
  748 kr_start_locked(struct ifnet *ifp)
  749 {
  750         struct kr_softc         *sc;
  751         struct mbuf             *m_head;
  752         int                     enq;
  753 
  754         sc = ifp->if_softc;
  755 
  756         KR_LOCK_ASSERT(sc);
  757 
  758         if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
  759             IFF_DRV_RUNNING || sc->kr_link_status == 0 )
  760                 return;
  761 
  762         for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
  763             sc->kr_cdata.kr_tx_cnt < KR_TX_RING_CNT - 2; ) {
  764                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
  765                 if (m_head == NULL)
  766                         break;
  767                 /*
  768                  * Pack the data into the transmit ring. If we
  769                  * don't have room, set the OACTIVE flag and wait
  770                  * for the NIC to drain the ring.
  771                  */
  772                 if (kr_encap(sc, &m_head)) {
  773                         if (m_head == NULL)
  774                                 break;
  775                         IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
  776                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
  777                         break;
  778                 }
  779 
  780                 enq++;
  781                 /*
  782                  * If there's a BPF listener, bounce a copy of this frame
  783                  * to him.
  784                  */
  785                 ETHER_BPF_MTAP(ifp, m_head);
  786         }
  787 }
  788 
  789 static void
  790 kr_stop(struct kr_softc *sc)
  791 {
  792         struct ifnet        *ifp;
  793 
  794         KR_LOCK_ASSERT(sc);
  795 
  796 
  797         ifp = sc->kr_ifp;
  798         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
  799         callout_stop(&sc->kr_stat_callout);
  800 
  801         /* mask out RX interrupts */
  802         KR_DMA_SETBITS_REG(KR_DMA_RXCHAN, DMA_SM, 
  803             DMA_SM_D | DMA_SM_H | DMA_SM_E);
  804 
  805         /* mask out TX interrupts */
  806         KR_DMA_SETBITS_REG(KR_DMA_TXCHAN, DMA_SM, 
  807             DMA_SM_F | DMA_SM_E);
  808 
  809         /* Abort RX DMA transactions */
  810         if (KR_DMA_READ_REG(KR_DMA_RXCHAN, DMA_C) & DMA_C_R) {
  811                 /* Set ABORT bit if trunsuction is in progress */
  812                 KR_DMA_WRITE_REG(KR_DMA_RXCHAN, DMA_C, DMA_C_ABORT);
  813                 /* XXX: Add timeout */
  814                 while ((KR_DMA_READ_REG(KR_DMA_RXCHAN, DMA_S) & DMA_S_H) == 0)
  815                         DELAY(10);
  816                 KR_DMA_WRITE_REG(KR_DMA_RXCHAN, DMA_S, 0);
  817         }
  818         KR_DMA_WRITE_REG(KR_DMA_RXCHAN, DMA_DPTR, 0);
  819         KR_DMA_WRITE_REG(KR_DMA_RXCHAN, DMA_NDPTR, 0);
  820 
  821         /* Abort TX DMA transactions */
  822         if (KR_DMA_READ_REG(KR_DMA_TXCHAN, DMA_C) & DMA_C_R) {
  823                 /* Set ABORT bit if trunsuction is in progress */
  824                 KR_DMA_WRITE_REG(KR_DMA_TXCHAN, DMA_C, DMA_C_ABORT);
  825                 /* XXX: Add timeout */
  826                 while ((KR_DMA_READ_REG(KR_DMA_TXCHAN, DMA_S) & DMA_S_H) == 0)
  827                         DELAY(10);
  828                 KR_DMA_WRITE_REG(KR_DMA_TXCHAN, DMA_S, 0);
  829         }
  830         KR_DMA_WRITE_REG(KR_DMA_TXCHAN, DMA_DPTR, 0);
  831         KR_DMA_WRITE_REG(KR_DMA_TXCHAN, DMA_NDPTR, 0);
  832 
  833         CSR_WRITE_4(sc, KR_ETHINTFC, 0);
  834 }
  835 
  836 
  837 static int
  838 kr_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
  839 {
  840         struct kr_softc         *sc = ifp->if_softc;
  841         struct ifreq            *ifr = (struct ifreq *) data;
  842         struct mii_data         *mii;
  843         int                     error;
  844 
  845         switch (command) {
  846         case SIOCSIFFLAGS:
  847 #if 0
  848                 KR_LOCK(sc);
  849                 if (ifp->if_flags & IFF_UP) {
  850                         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
  851                                 if ((ifp->if_flags ^ sc->kr_if_flags) &
  852                                     (IFF_PROMISC | IFF_ALLMULTI))
  853                                         kr_set_filter(sc);
  854                         } else {
  855                                 if (sc->kr_detach == 0)
  856                                         kr_init_locked(sc);
  857                         }
  858                 } else {
  859                         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
  860                                 kr_stop(sc);
  861                 }
  862                 sc->kr_if_flags = ifp->if_flags;
  863                 KR_UNLOCK(sc);
  864 #endif
  865                 error = 0;
  866                 break;
  867         case SIOCADDMULTI:
  868         case SIOCDELMULTI:
  869 #if 0
  870                 KR_LOCK(sc);
  871                 kr_set_filter(sc);
  872                 KR_UNLOCK(sc);
  873 #endif
  874                 error = 0;
  875                 break;
  876         case SIOCGIFMEDIA:
  877         case SIOCSIFMEDIA:
  878                 mii = device_get_softc(sc->kr_miibus);
  879                 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
  880                 break;
  881         case SIOCSIFCAP:
  882                 error = 0;
  883 #if 0
  884                 mask = ifr->ifr_reqcap ^ ifp->if_capenable;
  885                 if ((mask & IFCAP_HWCSUM) != 0) {
  886                         ifp->if_capenable ^= IFCAP_HWCSUM;
  887                         if ((IFCAP_HWCSUM & ifp->if_capenable) &&
  888                             (IFCAP_HWCSUM & ifp->if_capabilities))
  889                                 ifp->if_hwassist = KR_CSUM_FEATURES;
  890                         else
  891                                 ifp->if_hwassist = 0;
  892                 }
  893                 if ((mask & IFCAP_VLAN_HWTAGGING) != 0) {
  894                         ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
  895                         if (IFCAP_VLAN_HWTAGGING & ifp->if_capenable &&
  896                             IFCAP_VLAN_HWTAGGING & ifp->if_capabilities &&
  897                             ifp->if_drv_flags & IFF_DRV_RUNNING) {
  898                                 KR_LOCK(sc);
  899                                 kr_vlan_setup(sc);
  900                                 KR_UNLOCK(sc);
  901                         }
  902                 }
  903                 VLAN_CAPABILITIES(ifp);
  904 #endif
  905                 break;
  906         default:
  907                 error = ether_ioctl(ifp, command, data);
  908                 break;
  909         }
  910 
  911         return (error);
  912 }
  913 
  914 /*
  915  * Set media options.
  916  */
  917 static int
  918 kr_ifmedia_upd(struct ifnet *ifp)
  919 {
  920         struct kr_softc         *sc;
  921         struct mii_data         *mii;
  922         struct mii_softc        *miisc;
  923         int                     error;
  924 
  925         sc = ifp->if_softc;
  926         KR_LOCK(sc);
  927         mii = device_get_softc(sc->kr_miibus);
  928         if (mii->mii_instance) {
  929                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
  930                         mii_phy_reset(miisc);
  931         }
  932         error = mii_mediachg(mii);
  933         KR_UNLOCK(sc);
  934 
  935         return (error);
  936 }
  937 
  938 /*
  939  * Report current media status.
  940  */
  941 static void
  942 kr_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
  943 {
  944         struct kr_softc         *sc = ifp->if_softc;
  945         struct mii_data         *mii;
  946 
  947         mii = device_get_softc(sc->kr_miibus);
  948         KR_LOCK(sc);
  949         mii_pollstat(mii);
  950         KR_UNLOCK(sc);
  951         ifmr->ifm_active = mii->mii_media_active;
  952         ifmr->ifm_status = mii->mii_media_status;
  953 }
  954 
  955 struct kr_dmamap_arg {
  956         bus_addr_t      kr_busaddr;
  957 };
  958 
  959 static void
  960 kr_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
  961 {
  962         struct kr_dmamap_arg    *ctx;
  963 
  964         if (error != 0)
  965                 return;
  966         ctx = arg;
  967         ctx->kr_busaddr = segs[0].ds_addr;
  968 }
  969 
  970 static int
  971 kr_dma_alloc(struct kr_softc *sc)
  972 {
  973         struct kr_dmamap_arg    ctx;
  974         struct kr_txdesc        *txd;
  975         struct kr_rxdesc        *rxd;
  976         int                     error, i;
  977 
  978         /* Create parent DMA tag. */
  979         error = bus_dma_tag_create(
  980             bus_get_dma_tag(sc->kr_dev),        /* parent */
  981             1, 0,                       /* alignment, boundary */
  982             BUS_SPACE_MAXADDR_32BIT,    /* lowaddr */
  983             BUS_SPACE_MAXADDR,          /* highaddr */
  984             NULL, NULL,                 /* filter, filterarg */
  985             BUS_SPACE_MAXSIZE_32BIT,    /* maxsize */
  986             0,                          /* nsegments */
  987             BUS_SPACE_MAXSIZE_32BIT,    /* maxsegsize */
  988             0,                          /* flags */
  989             NULL, NULL,                 /* lockfunc, lockarg */
  990             &sc->kr_cdata.kr_parent_tag);
  991         if (error != 0) {
  992                 device_printf(sc->kr_dev, "failed to create parent DMA tag\n");
  993                 goto fail;
  994         }
  995         /* Create tag for Tx ring. */
  996         error = bus_dma_tag_create(
  997             sc->kr_cdata.kr_parent_tag, /* parent */
  998             KR_RING_ALIGN, 0,           /* alignment, boundary */
  999             BUS_SPACE_MAXADDR,          /* lowaddr */
 1000             BUS_SPACE_MAXADDR,          /* highaddr */
 1001             NULL, NULL,                 /* filter, filterarg */
 1002             KR_TX_RING_SIZE,            /* maxsize */
 1003             1,                          /* nsegments */
 1004             KR_TX_RING_SIZE,            /* maxsegsize */
 1005             0,                          /* flags */
 1006             NULL, NULL,                 /* lockfunc, lockarg */
 1007             &sc->kr_cdata.kr_tx_ring_tag);
 1008         if (error != 0) {
 1009                 device_printf(sc->kr_dev, "failed to create Tx ring DMA tag\n");
 1010                 goto fail;
 1011         }
 1012 
 1013         /* Create tag for Rx ring. */
 1014         error = bus_dma_tag_create(
 1015             sc->kr_cdata.kr_parent_tag, /* parent */
 1016             KR_RING_ALIGN, 0,           /* alignment, boundary */
 1017             BUS_SPACE_MAXADDR,          /* lowaddr */
 1018             BUS_SPACE_MAXADDR,          /* highaddr */
 1019             NULL, NULL,                 /* filter, filterarg */
 1020             KR_RX_RING_SIZE,            /* maxsize */
 1021             1,                          /* nsegments */
 1022             KR_RX_RING_SIZE,            /* maxsegsize */
 1023             0,                          /* flags */
 1024             NULL, NULL,                 /* lockfunc, lockarg */
 1025             &sc->kr_cdata.kr_rx_ring_tag);
 1026         if (error != 0) {
 1027                 device_printf(sc->kr_dev, "failed to create Rx ring DMA tag\n");
 1028                 goto fail;
 1029         }
 1030 
 1031         /* Create tag for Tx buffers. */
 1032         error = bus_dma_tag_create(
 1033             sc->kr_cdata.kr_parent_tag, /* parent */
 1034             sizeof(uint32_t), 0,        /* alignment, boundary */
 1035             BUS_SPACE_MAXADDR,          /* lowaddr */
 1036             BUS_SPACE_MAXADDR,          /* highaddr */
 1037             NULL, NULL,                 /* filter, filterarg */
 1038             MCLBYTES * KR_MAXFRAGS,     /* maxsize */
 1039             KR_MAXFRAGS,                /* nsegments */
 1040             MCLBYTES,                   /* maxsegsize */
 1041             0,                          /* flags */
 1042             NULL, NULL,                 /* lockfunc, lockarg */
 1043             &sc->kr_cdata.kr_tx_tag);
 1044         if (error != 0) {
 1045                 device_printf(sc->kr_dev, "failed to create Tx DMA tag\n");
 1046                 goto fail;
 1047         }
 1048 
 1049         /* Create tag for Rx buffers. */
 1050         error = bus_dma_tag_create(
 1051             sc->kr_cdata.kr_parent_tag, /* parent */
 1052             KR_RX_ALIGN, 0,             /* alignment, boundary */
 1053             BUS_SPACE_MAXADDR,          /* lowaddr */
 1054             BUS_SPACE_MAXADDR,          /* highaddr */
 1055             NULL, NULL,                 /* filter, filterarg */
 1056             MCLBYTES,                   /* maxsize */
 1057             1,                          /* nsegments */
 1058             MCLBYTES,                   /* maxsegsize */
 1059             0,                          /* flags */
 1060             NULL, NULL,                 /* lockfunc, lockarg */
 1061             &sc->kr_cdata.kr_rx_tag);
 1062         if (error != 0) {
 1063                 device_printf(sc->kr_dev, "failed to create Rx DMA tag\n");
 1064                 goto fail;
 1065         }
 1066 
 1067         /* Allocate DMA'able memory and load the DMA map for Tx ring. */
 1068         error = bus_dmamem_alloc(sc->kr_cdata.kr_tx_ring_tag,
 1069             (void **)&sc->kr_rdata.kr_tx_ring, BUS_DMA_WAITOK |
 1070             BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->kr_cdata.kr_tx_ring_map);
 1071         if (error != 0) {
 1072                 device_printf(sc->kr_dev,
 1073                     "failed to allocate DMA'able memory for Tx ring\n");
 1074                 goto fail;
 1075         }
 1076 
 1077         ctx.kr_busaddr = 0;
 1078         error = bus_dmamap_load(sc->kr_cdata.kr_tx_ring_tag,
 1079             sc->kr_cdata.kr_tx_ring_map, sc->kr_rdata.kr_tx_ring,
 1080             KR_TX_RING_SIZE, kr_dmamap_cb, &ctx, 0);
 1081         if (error != 0 || ctx.kr_busaddr == 0) {
 1082                 device_printf(sc->kr_dev,
 1083                     "failed to load DMA'able memory for Tx ring\n");
 1084                 goto fail;
 1085         }
 1086         sc->kr_rdata.kr_tx_ring_paddr = ctx.kr_busaddr;
 1087 
 1088         /* Allocate DMA'able memory and load the DMA map for Rx ring. */
 1089         error = bus_dmamem_alloc(sc->kr_cdata.kr_rx_ring_tag,
 1090             (void **)&sc->kr_rdata.kr_rx_ring, BUS_DMA_WAITOK |
 1091             BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->kr_cdata.kr_rx_ring_map);
 1092         if (error != 0) {
 1093                 device_printf(sc->kr_dev,
 1094                     "failed to allocate DMA'able memory for Rx ring\n");
 1095                 goto fail;
 1096         }
 1097 
 1098         ctx.kr_busaddr = 0;
 1099         error = bus_dmamap_load(sc->kr_cdata.kr_rx_ring_tag,
 1100             sc->kr_cdata.kr_rx_ring_map, sc->kr_rdata.kr_rx_ring,
 1101             KR_RX_RING_SIZE, kr_dmamap_cb, &ctx, 0);
 1102         if (error != 0 || ctx.kr_busaddr == 0) {
 1103                 device_printf(sc->kr_dev,
 1104                     "failed to load DMA'able memory for Rx ring\n");
 1105                 goto fail;
 1106         }
 1107         sc->kr_rdata.kr_rx_ring_paddr = ctx.kr_busaddr;
 1108 
 1109         /* Create DMA maps for Tx buffers. */
 1110         for (i = 0; i < KR_TX_RING_CNT; i++) {
 1111                 txd = &sc->kr_cdata.kr_txdesc[i];
 1112                 txd->tx_m = NULL;
 1113                 txd->tx_dmamap = NULL;
 1114                 error = bus_dmamap_create(sc->kr_cdata.kr_tx_tag, 0,
 1115                     &txd->tx_dmamap);
 1116                 if (error != 0) {
 1117                         device_printf(sc->kr_dev,
 1118                             "failed to create Tx dmamap\n");
 1119                         goto fail;
 1120                 }
 1121         }
 1122         /* Create DMA maps for Rx buffers. */
 1123         if ((error = bus_dmamap_create(sc->kr_cdata.kr_rx_tag, 0,
 1124             &sc->kr_cdata.kr_rx_sparemap)) != 0) {
 1125                 device_printf(sc->kr_dev,
 1126                     "failed to create spare Rx dmamap\n");
 1127                 goto fail;
 1128         }
 1129         for (i = 0; i < KR_RX_RING_CNT; i++) {
 1130                 rxd = &sc->kr_cdata.kr_rxdesc[i];
 1131                 rxd->rx_m = NULL;
 1132                 rxd->rx_dmamap = NULL;
 1133                 error = bus_dmamap_create(sc->kr_cdata.kr_rx_tag, 0,
 1134                     &rxd->rx_dmamap);
 1135                 if (error != 0) {
 1136                         device_printf(sc->kr_dev,
 1137                             "failed to create Rx dmamap\n");
 1138                         goto fail;
 1139                 }
 1140         }
 1141 
 1142 fail:
 1143         return (error);
 1144 }
 1145 
 1146 static void
 1147 kr_dma_free(struct kr_softc *sc)
 1148 {
 1149         struct kr_txdesc        *txd;
 1150         struct kr_rxdesc        *rxd;
 1151         int                     i;
 1152 
 1153         /* Tx ring. */
 1154         if (sc->kr_cdata.kr_tx_ring_tag) {
 1155                 if (sc->kr_cdata.kr_tx_ring_map)
 1156                         bus_dmamap_unload(sc->kr_cdata.kr_tx_ring_tag,
 1157                             sc->kr_cdata.kr_tx_ring_map);
 1158                 if (sc->kr_cdata.kr_tx_ring_map &&
 1159                     sc->kr_rdata.kr_tx_ring)
 1160                         bus_dmamem_free(sc->kr_cdata.kr_tx_ring_tag,
 1161                             sc->kr_rdata.kr_tx_ring,
 1162                             sc->kr_cdata.kr_tx_ring_map);
 1163                 sc->kr_rdata.kr_tx_ring = NULL;
 1164                 sc->kr_cdata.kr_tx_ring_map = NULL;
 1165                 bus_dma_tag_destroy(sc->kr_cdata.kr_tx_ring_tag);
 1166                 sc->kr_cdata.kr_tx_ring_tag = NULL;
 1167         }
 1168         /* Rx ring. */
 1169         if (sc->kr_cdata.kr_rx_ring_tag) {
 1170                 if (sc->kr_cdata.kr_rx_ring_map)
 1171                         bus_dmamap_unload(sc->kr_cdata.kr_rx_ring_tag,
 1172                             sc->kr_cdata.kr_rx_ring_map);
 1173                 if (sc->kr_cdata.kr_rx_ring_map &&
 1174                     sc->kr_rdata.kr_rx_ring)
 1175                         bus_dmamem_free(sc->kr_cdata.kr_rx_ring_tag,
 1176                             sc->kr_rdata.kr_rx_ring,
 1177                             sc->kr_cdata.kr_rx_ring_map);
 1178                 sc->kr_rdata.kr_rx_ring = NULL;
 1179                 sc->kr_cdata.kr_rx_ring_map = NULL;
 1180                 bus_dma_tag_destroy(sc->kr_cdata.kr_rx_ring_tag);
 1181                 sc->kr_cdata.kr_rx_ring_tag = NULL;
 1182         }
 1183         /* Tx buffers. */
 1184         if (sc->kr_cdata.kr_tx_tag) {
 1185                 for (i = 0; i < KR_TX_RING_CNT; i++) {
 1186                         txd = &sc->kr_cdata.kr_txdesc[i];
 1187                         if (txd->tx_dmamap) {
 1188                                 bus_dmamap_destroy(sc->kr_cdata.kr_tx_tag,
 1189                                     txd->tx_dmamap);
 1190                                 txd->tx_dmamap = NULL;
 1191                         }
 1192                 }
 1193                 bus_dma_tag_destroy(sc->kr_cdata.kr_tx_tag);
 1194                 sc->kr_cdata.kr_tx_tag = NULL;
 1195         }
 1196         /* Rx buffers. */
 1197         if (sc->kr_cdata.kr_rx_tag) {
 1198                 for (i = 0; i < KR_RX_RING_CNT; i++) {
 1199                         rxd = &sc->kr_cdata.kr_rxdesc[i];
 1200                         if (rxd->rx_dmamap) {
 1201                                 bus_dmamap_destroy(sc->kr_cdata.kr_rx_tag,
 1202                                     rxd->rx_dmamap);
 1203                                 rxd->rx_dmamap = NULL;
 1204                         }
 1205                 }
 1206                 if (sc->kr_cdata.kr_rx_sparemap) {
 1207                         bus_dmamap_destroy(sc->kr_cdata.kr_rx_tag,
 1208                             sc->kr_cdata.kr_rx_sparemap);
 1209                         sc->kr_cdata.kr_rx_sparemap = 0;
 1210                 }
 1211                 bus_dma_tag_destroy(sc->kr_cdata.kr_rx_tag);
 1212                 sc->kr_cdata.kr_rx_tag = NULL;
 1213         }
 1214 
 1215         if (sc->kr_cdata.kr_parent_tag) {
 1216                 bus_dma_tag_destroy(sc->kr_cdata.kr_parent_tag);
 1217                 sc->kr_cdata.kr_parent_tag = NULL;
 1218         }
 1219 }
 1220 
 1221 /*
 1222  * Initialize the transmit descriptors.
 1223  */
 1224 static int
 1225 kr_tx_ring_init(struct kr_softc *sc)
 1226 {
 1227         struct kr_ring_data     *rd;
 1228         struct kr_txdesc        *txd;
 1229         bus_addr_t              addr;
 1230         int                     i;
 1231 
 1232         sc->kr_cdata.kr_tx_prod = 0;
 1233         sc->kr_cdata.kr_tx_cons = 0;
 1234         sc->kr_cdata.kr_tx_cnt = 0;
 1235         sc->kr_cdata.kr_tx_pkts = 0;
 1236 
 1237         rd = &sc->kr_rdata;
 1238         bzero(rd->kr_tx_ring, KR_TX_RING_SIZE);
 1239         for (i = 0; i < KR_TX_RING_CNT; i++) {
 1240                 if (i == KR_TX_RING_CNT - 1)
 1241                         addr = KR_TX_RING_ADDR(sc, 0);
 1242                 else
 1243                         addr = KR_TX_RING_ADDR(sc, i + 1);
 1244                 rd->kr_tx_ring[i].kr_ctl = KR_CTL_IOF;
 1245                 rd->kr_tx_ring[i].kr_ca = 0;
 1246                 rd->kr_tx_ring[i].kr_devcs = 0;
 1247                 rd->kr_tx_ring[i].kr_link = 0;
 1248                 txd = &sc->kr_cdata.kr_txdesc[i];
 1249                 txd->tx_m = NULL;
 1250         }
 1251 
 1252         bus_dmamap_sync(sc->kr_cdata.kr_tx_ring_tag,
 1253             sc->kr_cdata.kr_tx_ring_map,
 1254             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1255 
 1256         return (0);
 1257 }
 1258 
 1259 /*
 1260  * Initialize the RX descriptors and allocate mbufs for them. Note that
 1261  * we arrange the descriptors in a closed ring, so that the last descriptor
 1262  * points back to the first.
 1263  */
 1264 static int
 1265 kr_rx_ring_init(struct kr_softc *sc)
 1266 {
 1267         struct kr_ring_data     *rd;
 1268         struct kr_rxdesc        *rxd;
 1269         bus_addr_t              addr;
 1270         int                     i;
 1271 
 1272         sc->kr_cdata.kr_rx_cons = 0;
 1273 
 1274         rd = &sc->kr_rdata;
 1275         bzero(rd->kr_rx_ring, KR_RX_RING_SIZE);
 1276         for (i = 0; i < KR_RX_RING_CNT; i++) {
 1277                 rxd = &sc->kr_cdata.kr_rxdesc[i];
 1278                 rxd->rx_m = NULL;
 1279                 rxd->desc = &rd->kr_rx_ring[i];
 1280                 if (i == KR_RX_RING_CNT - 1)
 1281                         addr = KR_RX_RING_ADDR(sc, 0);
 1282                 else
 1283                         addr = KR_RX_RING_ADDR(sc, i + 1);
 1284                 rd->kr_rx_ring[i].kr_ctl = KR_CTL_IOD;
 1285                 if (i == KR_RX_RING_CNT - 1)
 1286                         rd->kr_rx_ring[i].kr_ctl |= KR_CTL_COD;
 1287                 rd->kr_rx_ring[i].kr_devcs = 0;
 1288                 rd->kr_rx_ring[i].kr_ca = 0;
 1289                 rd->kr_rx_ring[i].kr_link = addr;
 1290                 if (kr_newbuf(sc, i) != 0)
 1291                         return (ENOBUFS);
 1292         }
 1293 
 1294         bus_dmamap_sync(sc->kr_cdata.kr_rx_ring_tag,
 1295             sc->kr_cdata.kr_rx_ring_map,
 1296             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1297 
 1298         return (0);
 1299 }
 1300 
 1301 /*
 1302  * Initialize an RX descriptor and attach an MBUF cluster.
 1303  */
 1304 static int
 1305 kr_newbuf(struct kr_softc *sc, int idx)
 1306 {
 1307         struct kr_desc          *desc;
 1308         struct kr_rxdesc        *rxd;
 1309         struct mbuf             *m;
 1310         bus_dma_segment_t       segs[1];
 1311         bus_dmamap_t            map;
 1312         int                     nsegs;
 1313 
 1314         m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
 1315         if (m == NULL)
 1316                 return (ENOBUFS);
 1317         m->m_len = m->m_pkthdr.len = MCLBYTES;
 1318         m_adj(m, sizeof(uint64_t));
 1319 
 1320         if (bus_dmamap_load_mbuf_sg(sc->kr_cdata.kr_rx_tag,
 1321             sc->kr_cdata.kr_rx_sparemap, m, segs, &nsegs, 0) != 0) {
 1322                 m_freem(m);
 1323                 return (ENOBUFS);
 1324         }
 1325         KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs));
 1326 
 1327         rxd = &sc->kr_cdata.kr_rxdesc[idx];
 1328         if (rxd->rx_m != NULL) {
 1329                 bus_dmamap_sync(sc->kr_cdata.kr_rx_tag, rxd->rx_dmamap,
 1330                     BUS_DMASYNC_POSTREAD);
 1331                 bus_dmamap_unload(sc->kr_cdata.kr_rx_tag, rxd->rx_dmamap);
 1332         }
 1333         map = rxd->rx_dmamap;
 1334         rxd->rx_dmamap = sc->kr_cdata.kr_rx_sparemap;
 1335         sc->kr_cdata.kr_rx_sparemap = map;
 1336         bus_dmamap_sync(sc->kr_cdata.kr_rx_tag, rxd->rx_dmamap,
 1337             BUS_DMASYNC_PREREAD);
 1338         rxd->rx_m = m;
 1339         desc = rxd->desc;
 1340         desc->kr_ca = segs[0].ds_addr;
 1341         desc->kr_ctl |= KR_DMASIZE(segs[0].ds_len);
 1342         rxd->saved_ca = desc->kr_ca ;
 1343         rxd->saved_ctl = desc->kr_ctl ;
 1344 
 1345         return (0);
 1346 }
 1347 
 1348 static __inline void
 1349 kr_fixup_rx(struct mbuf *m)
 1350 {
 1351         int             i;
 1352         uint16_t        *src, *dst;
 1353 
 1354         src = mtod(m, uint16_t *);
 1355         dst = src - 1;
 1356 
 1357         for (i = 0; i < (m->m_len / sizeof(uint16_t) + 1); i++)
 1358                 *dst++ = *src++;
 1359 
 1360         m->m_data -= ETHER_ALIGN;
 1361 }
 1362 
 1363 
 1364 static void
 1365 kr_tx(struct kr_softc *sc)
 1366 {
 1367         struct kr_txdesc        *txd;
 1368         struct kr_desc          *cur_tx;
 1369         struct ifnet            *ifp;
 1370         uint32_t                ctl, devcs;
 1371         int                     cons, prod;
 1372 
 1373         KR_LOCK_ASSERT(sc);
 1374 
 1375         cons = sc->kr_cdata.kr_tx_cons;
 1376         prod = sc->kr_cdata.kr_tx_prod;
 1377         if (cons == prod)
 1378                 return;
 1379 
 1380         bus_dmamap_sync(sc->kr_cdata.kr_tx_ring_tag,
 1381             sc->kr_cdata.kr_tx_ring_map,
 1382             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 1383 
 1384         ifp = sc->kr_ifp;
 1385         /*
 1386          * Go through our tx list and free mbufs for those
 1387          * frames that have been transmitted.
 1388          */
 1389         for (; cons != prod; KR_INC(cons, KR_TX_RING_CNT)) {
 1390                 cur_tx = &sc->kr_rdata.kr_tx_ring[cons];
 1391                 ctl = cur_tx->kr_ctl;
 1392                 devcs = cur_tx->kr_devcs;
 1393                 /* Check if descriptor has "finished" flag */
 1394                 if ((ctl & KR_CTL_F) == 0)
 1395                         break;
 1396 
 1397                 sc->kr_cdata.kr_tx_cnt--;
 1398                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 1399 
 1400                 txd = &sc->kr_cdata.kr_txdesc[cons];
 1401 
 1402                 if (devcs & KR_DMATX_DEVCS_TOK)
 1403                         ifp->if_opackets++;
 1404                 else {
 1405                         ifp->if_oerrors++;
 1406                         /* collisions: medium busy, late collision */
 1407                         if ((devcs & KR_DMATX_DEVCS_EC) || 
 1408                             (devcs & KR_DMATX_DEVCS_LC))
 1409                                 ifp->if_collisions++;
 1410                 }
 1411 
 1412                 bus_dmamap_sync(sc->kr_cdata.kr_tx_tag, txd->tx_dmamap,
 1413                     BUS_DMASYNC_POSTWRITE);
 1414                 bus_dmamap_unload(sc->kr_cdata.kr_tx_tag, txd->tx_dmamap);
 1415 
 1416                 /* Free only if it's first descriptor in list */
 1417                 if (txd->tx_m)
 1418                         m_freem(txd->tx_m);
 1419                 txd->tx_m = NULL;
 1420 
 1421                 /* reset descriptor */
 1422                 cur_tx->kr_ctl = KR_CTL_IOF;
 1423                 cur_tx->kr_devcs = 0;
 1424                 cur_tx->kr_ca = 0;
 1425                 cur_tx->kr_link = 0; 
 1426         }
 1427 
 1428         sc->kr_cdata.kr_tx_cons = cons;
 1429 
 1430         bus_dmamap_sync(sc->kr_cdata.kr_tx_ring_tag,
 1431             sc->kr_cdata.kr_tx_ring_map, BUS_DMASYNC_PREWRITE);
 1432 }
 1433 
 1434 
 1435 static void
 1436 kr_rx(struct kr_softc *sc)
 1437 {
 1438         struct kr_rxdesc        *rxd;
 1439         struct ifnet            *ifp = sc->kr_ifp;
 1440         int                     cons, prog, packet_len, count, error;
 1441         struct kr_desc          *cur_rx;
 1442         struct mbuf             *m;
 1443 
 1444         KR_LOCK_ASSERT(sc);
 1445 
 1446         cons = sc->kr_cdata.kr_rx_cons;
 1447 
 1448         bus_dmamap_sync(sc->kr_cdata.kr_rx_ring_tag,
 1449             sc->kr_cdata.kr_rx_ring_map,
 1450             BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 1451 
 1452         for (prog = 0; prog < KR_RX_RING_CNT; KR_INC(cons, KR_RX_RING_CNT)) {
 1453                 cur_rx = &sc->kr_rdata.kr_rx_ring[cons];
 1454                 rxd = &sc->kr_cdata.kr_rxdesc[cons];
 1455                 m = rxd->rx_m;
 1456 
 1457                 if ((cur_rx->kr_ctl & KR_CTL_D) == 0)
 1458                        break;   
 1459 
 1460                 prog++;
 1461 
 1462                 packet_len = KR_PKTSIZE(cur_rx->kr_devcs);
 1463                 count = m->m_len - KR_DMASIZE(cur_rx->kr_ctl);
 1464                 /* Assume it's error */
 1465                 error = 1;
 1466 
 1467                 if (packet_len != count)
 1468                         ifp->if_ierrors++;
 1469                 else if (count < 64)
 1470                         ifp->if_ierrors++;
 1471                 else if ((cur_rx->kr_devcs & KR_DMARX_DEVCS_LD) == 0)
 1472                         ifp->if_ierrors++;
 1473                 else if ((cur_rx->kr_devcs & KR_DMARX_DEVCS_ROK) != 0) {
 1474                         error = 0;
 1475                         bus_dmamap_sync(sc->kr_cdata.kr_rx_tag, rxd->rx_dmamap,
 1476                             BUS_DMASYNC_PREREAD);
 1477                         m = rxd->rx_m;
 1478                         kr_fixup_rx(m);
 1479                         m->m_pkthdr.rcvif = ifp;
 1480                         /* Skip 4 bytes of CRC */
 1481                         m->m_pkthdr.len = m->m_len = packet_len - ETHER_CRC_LEN;
 1482                         ifp->if_ipackets++;
 1483 
 1484                         KR_UNLOCK(sc);
 1485                         (*ifp->if_input)(ifp, m);
 1486                         KR_LOCK(sc);
 1487                 }
 1488 
 1489                 if (error) {
 1490                         /* Restore CONTROL and CA values, reset DEVCS */
 1491                         cur_rx->kr_ctl = rxd->saved_ctl;
 1492                         cur_rx->kr_ca = rxd->saved_ca;
 1493                         cur_rx->kr_devcs = 0;
 1494                 }
 1495                 else {
 1496                         /* Reinit descriptor */
 1497                         cur_rx->kr_ctl = KR_CTL_IOD;
 1498                         if (cons == KR_RX_RING_CNT - 1)
 1499                                 cur_rx->kr_ctl |= KR_CTL_COD;
 1500                         cur_rx->kr_devcs = 0;
 1501                         cur_rx->kr_ca = 0;
 1502                         if (kr_newbuf(sc, cons) != 0) {
 1503                                 device_printf(sc->kr_dev, 
 1504                                     "Failed to allocate buffer\n");
 1505                                 break;
 1506                         }
 1507                 }
 1508 
 1509                 bus_dmamap_sync(sc->kr_cdata.kr_rx_ring_tag,
 1510                     sc->kr_cdata.kr_rx_ring_map,
 1511                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 1512 
 1513         }
 1514 
 1515         if (prog > 0) {
 1516                 sc->kr_cdata.kr_rx_cons = cons;
 1517 
 1518                 bus_dmamap_sync(sc->kr_cdata.kr_rx_ring_tag,
 1519                     sc->kr_cdata.kr_rx_ring_map,
 1520                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1521         }
 1522 }
 1523 
 1524 static void
 1525 kr_rx_intr(void *arg)
 1526 {
 1527         struct kr_softc         *sc = arg;
 1528         uint32_t                status;
 1529 
 1530         KR_LOCK(sc);
 1531 
 1532         /* mask out interrupts */
 1533         KR_DMA_SETBITS_REG(KR_DMA_RXCHAN, DMA_SM, 
 1534             DMA_SM_D | DMA_SM_H | DMA_SM_E);
 1535 
 1536         status = KR_DMA_READ_REG(KR_DMA_RXCHAN, DMA_S);
 1537         if (status & (DMA_S_D | DMA_S_E | DMA_S_H)) {
 1538                 kr_rx(sc);
 1539 
 1540                 if (status & DMA_S_E)
 1541                         device_printf(sc->kr_dev, "RX DMA error\n");
 1542         }
 1543 
 1544         /* Reread status */
 1545         status = KR_DMA_READ_REG(KR_DMA_RXCHAN, DMA_S);
 1546 
 1547         /* restart DMA RX  if it has been halted */
 1548         if (status & DMA_S_H) {
 1549                 KR_DMA_WRITE_REG(KR_DMA_RXCHAN, DMA_DPTR, 
 1550                     KR_RX_RING_ADDR(sc, sc->kr_cdata.kr_rx_cons));
 1551         }
 1552 
 1553         KR_DMA_WRITE_REG(KR_DMA_RXCHAN, DMA_S, ~status);
 1554 
 1555         /* Enable F, H, E interrupts */
 1556         KR_DMA_CLEARBITS_REG(KR_DMA_RXCHAN, DMA_SM, 
 1557             DMA_SM_D | DMA_SM_H | DMA_SM_E);
 1558 
 1559         KR_UNLOCK(sc);
 1560 }
 1561 
 1562 static void
 1563 kr_tx_intr(void *arg)
 1564 {
 1565         struct kr_softc         *sc = arg;
 1566         uint32_t                status;
 1567 
 1568         KR_LOCK(sc);
 1569 
 1570         /* mask out interrupts */
 1571         KR_DMA_SETBITS_REG(KR_DMA_TXCHAN, DMA_SM, 
 1572             DMA_SM_F | DMA_SM_E);
 1573 
 1574         status = KR_DMA_READ_REG(KR_DMA_TXCHAN, DMA_S);
 1575         if (status & (DMA_S_F | DMA_S_E)) {
 1576                 kr_tx(sc);
 1577                 if (status & DMA_S_E)
 1578                         device_printf(sc->kr_dev, "DMA error\n");
 1579         }
 1580 
 1581         KR_DMA_WRITE_REG(KR_DMA_TXCHAN, DMA_S, ~status);
 1582 
 1583         /* Enable F, E interrupts */
 1584         KR_DMA_CLEARBITS_REG(KR_DMA_TXCHAN, DMA_SM, 
 1585             DMA_SM_F | DMA_SM_E);
 1586 
 1587         KR_UNLOCK(sc);
 1588 
 1589 }
 1590 
 1591 static void
 1592 kr_rx_und_intr(void *arg)
 1593 {
 1594 
 1595         panic("interrupt: %s\n", __func__);
 1596 }
 1597 
 1598 static void
 1599 kr_tx_ovr_intr(void *arg)
 1600 {
 1601 
 1602         panic("interrupt: %s\n", __func__);
 1603 }
 1604 
 1605 static void
 1606 kr_tick(void *xsc)
 1607 {
 1608         struct kr_softc         *sc = xsc;
 1609         struct mii_data         *mii;
 1610 
 1611         KR_LOCK_ASSERT(sc);
 1612 
 1613         mii = device_get_softc(sc->kr_miibus);
 1614         mii_tick(mii);
 1615         callout_reset(&sc->kr_stat_callout, hz, kr_tick, sc);
 1616 }

Cache object: ccbb3ef23986a16365ce0b80a6c64b2c


[ 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.