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/netif/pcn/if_pcn.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) 2000 Berkeley Software Design, Inc.
    3  * Copyright (c) 1997, 1998, 1999, 2000
    4  *      Bill Paul <wpaul@osd.bsdi.com>.  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  * 3. All advertising materials mentioning features or use of this software
   15  *    must display the following acknowledgement:
   16  *      This product includes software developed by Bill Paul.
   17  * 4. Neither the name of the author nor the names of any co-contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
   25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   31  * THE POSSIBILITY OF SUCH DAMAGE.
   32  *
   33  * $FreeBSD: src/sys/pci/if_pcn.c,v 1.5.2.10 2003/03/05 18:42:33 njl Exp $
   34  */
   35 
   36 /*
   37  * AMD Am79c972 fast ethernet PCI NIC driver. Datatheets are available
   38  * from http://www.amd.com.
   39  *
   40  * Written by Bill Paul <wpaul@osd.bsdi.com>
   41  */
   42 
   43 /*
   44  * The AMD PCnet/PCI controllers are more advanced and functional
   45  * versions of the venerable 7990 LANCE. The PCnet/PCI chips retain
   46  * backwards compatibility with the LANCE and thus can be made
   47  * to work with older LANCE drivers. This is in fact how the
   48  * PCnet/PCI chips were supported in FreeBSD originally. The trouble
   49  * is that the PCnet/PCI devices offer several performance enhancements
   50  * which can't be exploited in LANCE compatibility mode. Chief among
   51  * these enhancements is the ability to perform PCI DMA operations
   52  * using 32-bit addressing (which eliminates the need for ISA
   53  * bounce-buffering), and special receive buffer alignment (which
   54  * allows the receive handler to pass packets to the upper protocol
   55  * layers without copying on both the x86 and alpha platforms).
   56  */
   57 
   58 #include <sys/param.h>
   59 #include <sys/systm.h>
   60 #include <sys/sockio.h>
   61 #include <sys/mbuf.h>
   62 #include <sys/malloc.h>
   63 #include <sys/kernel.h>
   64 #include <sys/interrupt.h>
   65 #include <sys/socket.h>
   66 #include <sys/serialize.h>
   67 #include <sys/bus.h>
   68 #include <sys/rman.h>
   69 #include <sys/thread2.h>
   70 
   71 #include <net/if.h>
   72 #include <net/ifq_var.h>
   73 #include <net/if_arp.h>
   74 #include <net/ethernet.h>
   75 #include <net/if_dl.h>
   76 #include <net/if_media.h>
   77 
   78 #include <net/bpf.h>
   79 
   80 #include <vm/vm.h>              /* for vtophys */
   81 #include <vm/pmap.h>            /* for vtophys */
   82 
   83 #include <machine/clock.h>      /* for DELAY */
   84 
   85 #include "../mii_layer/mii.h"
   86 #include "../mii_layer/miivar.h"
   87 
   88 #include "pcidevs.h"
   89 #include <bus/pci/pcireg.h>
   90 #include <bus/pci/pcivar.h>
   91 
   92 #define PCN_USEIOSPACE
   93 
   94 #include "if_pcnreg.h"
   95 
   96 /* "controller miibus0" required.  See GENERIC if you get errors here. */
   97 #include "miibus_if.h"
   98 
   99 /*
  100  * Various supported device vendors/types and their names.
  101  */
  102 static struct pcn_type pcn_devs[] = {
  103         { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PCNET_PCI,
  104                 "AMD PCnet/PCI 10/100BaseTX" },
  105         { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_PCNET_HOME,
  106                 "AMD PCnet/Home HomePNA" },
  107         { 0, 0, NULL }
  108 };
  109 
  110 static u_int32_t pcn_csr_read   (struct pcn_softc *, int);
  111 static u_int16_t pcn_csr_read16 (struct pcn_softc *, int);
  112 static u_int16_t pcn_bcr_read16 (struct pcn_softc *, int);
  113 static void pcn_csr_write       (struct pcn_softc *, int, int);
  114 static u_int32_t pcn_bcr_read   (struct pcn_softc *, int);
  115 static void pcn_bcr_write       (struct pcn_softc *, int, int);
  116 
  117 static int pcn_probe            (device_t);
  118 static int pcn_attach           (device_t);
  119 static int pcn_detach           (device_t);
  120 
  121 static int pcn_newbuf           (struct pcn_softc *, int, struct mbuf *);
  122 static int pcn_encap            (struct pcn_softc *,
  123                                         struct mbuf *, u_int32_t *);
  124 static void pcn_rxeof           (struct pcn_softc *);
  125 static void pcn_txeof           (struct pcn_softc *);
  126 static void pcn_intr            (void *);
  127 static void pcn_tick            (void *);
  128 static void pcn_start           (struct ifnet *, struct ifaltq_subque *);
  129 static int pcn_ioctl            (struct ifnet *, u_long, caddr_t,
  130                                         struct ucred *);
  131 static void pcn_init            (void *);
  132 static void pcn_stop            (struct pcn_softc *);
  133 static void pcn_watchdog        (struct ifnet *);
  134 static void pcn_shutdown        (device_t);
  135 static int pcn_ifmedia_upd      (struct ifnet *);
  136 static void pcn_ifmedia_sts     (struct ifnet *, struct ifmediareq *);
  137 
  138 static int pcn_miibus_readreg   (device_t, int, int);
  139 static int pcn_miibus_writereg  (device_t, int, int, int);
  140 static void pcn_miibus_statchg  (device_t);
  141 
  142 static void pcn_setfilt         (struct ifnet *);
  143 static void pcn_setmulti        (struct pcn_softc *);
  144 static u_int32_t pcn_crc        (caddr_t);
  145 static void pcn_reset           (struct pcn_softc *);
  146 static int pcn_list_rx_init     (struct pcn_softc *);
  147 static int pcn_list_tx_init     (struct pcn_softc *);
  148 
  149 #ifdef PCN_USEIOSPACE
  150 #define PCN_RES                 SYS_RES_IOPORT
  151 #define PCN_RID                 PCN_PCI_LOIO
  152 #else
  153 #define PCN_RES                 SYS_RES_MEMORY
  154 #define PCN_RID                 PCN_PCI_LOMEM
  155 #endif
  156 
  157 static device_method_t pcn_methods[] = {
  158         /* Device interface */
  159         DEVMETHOD(device_probe,         pcn_probe),
  160         DEVMETHOD(device_attach,        pcn_attach),
  161         DEVMETHOD(device_detach,        pcn_detach),
  162         DEVMETHOD(device_shutdown,      pcn_shutdown),
  163 
  164         /* bus interface */
  165         DEVMETHOD(bus_print_child,      bus_generic_print_child),
  166         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
  167 
  168         /* MII interface */
  169         DEVMETHOD(miibus_readreg,       pcn_miibus_readreg),
  170         DEVMETHOD(miibus_writereg,      pcn_miibus_writereg),
  171         DEVMETHOD(miibus_statchg,       pcn_miibus_statchg),
  172 
  173         DEVMETHOD_END
  174 };
  175 
  176 static driver_t pcn_driver = {
  177         "pcn",
  178         pcn_methods,
  179         sizeof(struct pcn_softc)
  180 };
  181 
  182 static devclass_t pcn_devclass;
  183 
  184 DECLARE_DUMMY_MODULE(if_pcn);
  185 DRIVER_MODULE(if_pcn, pci, pcn_driver, pcn_devclass, NULL, NULL);
  186 DRIVER_MODULE(miibus, pcn, miibus_driver, miibus_devclass, NULL, NULL);
  187 
  188 #define PCN_CSR_SETBIT(sc, reg, x)                      \
  189         pcn_csr_write(sc, reg, pcn_csr_read(sc, reg) | (x))
  190 
  191 #define PCN_CSR_CLRBIT(sc, reg, x)                      \
  192         pcn_csr_write(sc, reg, pcn_csr_read(sc, reg) & ~(x))
  193 
  194 #define PCN_BCR_SETBIT(sc, reg, x)                      \
  195         pcn_bcr_write(sc, reg, pcn_bcr_read(sc, reg) | (x))
  196 
  197 #define PCN_BCR_CLRBIT(sc, reg, x)                      \
  198         pcn_bcr_write(sc, reg, pcn_bcr_read(sc, reg) & ~(x))
  199 
  200 static u_int32_t
  201 pcn_csr_read(struct pcn_softc *sc, int reg)
  202 {
  203         CSR_WRITE_4(sc, PCN_IO32_RAP, reg);
  204         return(CSR_READ_4(sc, PCN_IO32_RDP));
  205 }
  206 
  207 static u_int16_t
  208 pcn_csr_read16(struct pcn_softc *sc, int reg)
  209 {
  210         CSR_WRITE_2(sc, PCN_IO16_RAP, reg);
  211         return(CSR_READ_2(sc, PCN_IO16_RDP));
  212 }
  213 
  214 static void
  215 pcn_csr_write(struct pcn_softc *sc, int reg, int val)
  216 {
  217         CSR_WRITE_4(sc, PCN_IO32_RAP, reg);
  218         CSR_WRITE_4(sc, PCN_IO32_RDP, val);
  219         return;
  220 }
  221 
  222 static u_int32_t
  223 pcn_bcr_read(struct pcn_softc *sc, int reg)
  224 {
  225         CSR_WRITE_4(sc, PCN_IO32_RAP, reg);
  226         return(CSR_READ_4(sc, PCN_IO32_BDP));
  227 }
  228 
  229 static u_int16_t
  230 pcn_bcr_read16(struct pcn_softc *sc, int reg)
  231 {
  232         CSR_WRITE_2(sc, PCN_IO16_RAP, reg);
  233         return(CSR_READ_2(sc, PCN_IO16_BDP));
  234 }
  235 
  236 static void
  237 pcn_bcr_write(struct pcn_softc *sc, int reg, int val)
  238 {
  239         CSR_WRITE_4(sc, PCN_IO32_RAP, reg);
  240         CSR_WRITE_4(sc, PCN_IO32_BDP, val);
  241         return;
  242 }
  243 
  244 static int
  245 pcn_miibus_readreg(device_t dev, int phy, int reg)
  246 {
  247         struct pcn_softc        *sc;
  248         int                     val;
  249 
  250         sc = device_get_softc(dev);
  251 
  252         if (sc->pcn_phyaddr && phy > sc->pcn_phyaddr)
  253                 return(0);
  254 
  255         pcn_bcr_write(sc, PCN_BCR_MIIADDR, reg | (phy << 5));
  256         val = pcn_bcr_read(sc, PCN_BCR_MIIDATA) & 0xFFFF;
  257         if (val == 0xFFFF)
  258                 return(0);
  259 
  260         sc->pcn_phyaddr = phy;
  261 
  262         return(val);
  263 }
  264 
  265 static int
  266 pcn_miibus_writereg(device_t dev, int phy, int reg, int data)
  267 {
  268         struct pcn_softc        *sc;
  269 
  270         sc = device_get_softc(dev);
  271 
  272         pcn_bcr_write(sc, PCN_BCR_MIIADDR, reg | (phy << 5));
  273         pcn_bcr_write(sc, PCN_BCR_MIIDATA, data);
  274 
  275         return(0);
  276 }
  277 
  278 static void
  279 pcn_miibus_statchg(device_t dev)
  280 {
  281         struct pcn_softc        *sc;
  282         struct mii_data         *mii;
  283 
  284         sc = device_get_softc(dev);
  285         mii = device_get_softc(sc->pcn_miibus);
  286 
  287         if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
  288                 PCN_BCR_SETBIT(sc, PCN_BCR_DUPLEX, PCN_DUPLEX_FDEN);
  289         } else {
  290                 PCN_BCR_CLRBIT(sc, PCN_BCR_DUPLEX, PCN_DUPLEX_FDEN);
  291         }
  292 
  293         return;
  294 }
  295 
  296 #define DC_POLY         0xEDB88320
  297 
  298 static u_int32_t
  299 pcn_crc(caddr_t addr)
  300 {
  301         u_int32_t               idx, bit, data, crc;
  302 
  303         /* Compute CRC for the address value. */
  304         crc = 0xFFFFFFFF; /* initial value */
  305 
  306         for (idx = 0; idx < 6; idx++) {
  307                 for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1)
  308                         crc = (crc >> 1) ^ (((crc ^ data) & 1) ? DC_POLY : 0);
  309         }
  310 
  311         return ((crc >> 26) & 0x3F);
  312 }
  313 
  314 static void
  315 pcn_setmulti(struct pcn_softc *sc)
  316 {
  317         struct ifnet            *ifp;
  318         struct ifmultiaddr      *ifma;
  319         u_int32_t               h, i;
  320         u_int16_t               hashes[4] = { 0, 0, 0, 0 };
  321 
  322         ifp = &sc->arpcom.ac_if;
  323 
  324         PCN_CSR_SETBIT(sc, PCN_CSR_EXTCTL1, PCN_EXTCTL1_SPND);
  325 
  326         if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) {
  327                 for (i = 0; i < 4; i++)
  328                         pcn_csr_write(sc, PCN_CSR_MAR0 + i, 0xFFFF);
  329                 PCN_CSR_CLRBIT(sc, PCN_CSR_EXTCTL1, PCN_EXTCTL1_SPND);
  330                 return;
  331         }
  332 
  333         /* first, zot all the existing hash bits */
  334         for (i = 0; i < 4; i++)
  335                 pcn_csr_write(sc, PCN_CSR_MAR0 + i, 0);
  336 
  337         /* now program new ones */
  338         TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
  339                 if (ifma->ifma_addr->sa_family != AF_LINK)
  340                         continue;
  341                 h = pcn_crc(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
  342                 hashes[h >> 4] |= 1 << (h & 0xF);
  343         }
  344 
  345         for (i = 0; i < 4; i++)
  346                 pcn_csr_write(sc, PCN_CSR_MAR0 + i, hashes[i]);
  347 
  348         PCN_CSR_CLRBIT(sc, PCN_CSR_EXTCTL1, PCN_EXTCTL1_SPND);
  349 
  350         return;
  351 }
  352 
  353 static void
  354 pcn_reset(struct pcn_softc *sc)
  355 {
  356         /*
  357          * Issue a reset by reading from the RESET register.
  358          * Note that we don't know if the chip is operating in
  359          * 16-bit or 32-bit mode at this point, so we attempt
  360          * to reset the chip both ways. If one fails, the other
  361          * will succeed.
  362          */
  363         CSR_READ_2(sc, PCN_IO16_RESET);
  364         CSR_READ_4(sc, PCN_IO32_RESET);
  365 
  366         /* Wait a little while for the chip to get its brains in order. */
  367         DELAY(1000);
  368 
  369         /* Select 32-bit (DWIO) mode */
  370         CSR_WRITE_4(sc, PCN_IO32_RDP, 0);
  371 
  372         /* Select software style 3. */
  373         pcn_bcr_write(sc, PCN_BCR_SSTYLE, PCN_SWSTYLE_PCNETPCI_BURST);
  374 
  375         return;
  376 }
  377 
  378 /*
  379  * Probe for an AMD chip. Check the PCI vendor and device
  380  * IDs against our list and return a device name if we find a match.
  381  */
  382 static int
  383 pcn_probe(device_t dev)
  384 {
  385         struct pcn_type         *t;
  386         struct pcn_softc        *sc;
  387         int                     rid;
  388         u_int32_t               chip_id;
  389 
  390         t = pcn_devs;
  391         sc = device_get_softc(dev);
  392 
  393         while(t->pcn_name != NULL) {
  394                 if ((pci_get_vendor(dev) == t->pcn_vid) &&
  395                     (pci_get_device(dev) == t->pcn_did)) {
  396                         /*
  397                          * Temporarily map the I/O space
  398                          * so we can read the chip ID register.
  399                          */
  400                         rid = PCN_RID;
  401                         sc->pcn_res = bus_alloc_resource_any(dev, PCN_RES,
  402                             &rid, RF_ACTIVE);
  403                         if (sc->pcn_res == NULL) {
  404                                 device_printf(dev,
  405                                     "couldn't map ports/memory\n");
  406                                 return(ENXIO);
  407                         }
  408                         sc->pcn_btag = rman_get_bustag(sc->pcn_res);
  409                         sc->pcn_bhandle = rman_get_bushandle(sc->pcn_res);
  410                         /*
  411                          * Note: we can *NOT* put the chip into
  412                          * 32-bit mode yet. The lnc driver will only
  413                          * work in 16-bit mode, and once the chip
  414                          * goes into 32-bit mode, the only way to
  415                          * get it out again is with a hardware reset.
  416                          * So if pcn_probe() is called before the
  417                          * lnc driver's probe routine, the chip will
  418                          * be locked into 32-bit operation and the lnc
  419                          * driver will be unable to attach to it.
  420                          * Note II: if the chip happens to already
  421                          * be in 32-bit mode, we still need to check
  422                          * the chip ID, but first we have to detect
  423                          * 32-bit mode using only 16-bit operations.
  424                          * The safest way to do this is to read the
  425                          * PCI subsystem ID from BCR23/24 and compare
  426                          * that with the value read from PCI config
  427                          * space.   
  428                          */
  429                         chip_id = pcn_bcr_read16(sc, PCN_BCR_PCISUBSYSID);
  430                         chip_id <<= 16;
  431                         chip_id |= pcn_bcr_read16(sc, PCN_BCR_PCISUBVENID);
  432                         /*
  433                          * Note III: the test for 0x10001000 is a hack to
  434                          * pacify VMware, who's pseudo-PCnet interface is
  435                          * broken. Reading the subsystem register from PCI
  436                          * config space yeilds 0x00000000 while reading the
  437                          * same value from I/O space yeilds 0x10001000. It's
  438                          * not supposed to be that way.
  439                          */
  440                         if (chip_id == pci_read_config(dev,
  441                             PCIR_SUBVEND_0, 4) || chip_id == 0x10001000) {
  442                                 /* We're in 16-bit mode. */
  443                                 chip_id = pcn_csr_read16(sc, PCN_CSR_CHIPID1);
  444                                 chip_id <<= 16;
  445                                 chip_id |= pcn_csr_read16(sc, PCN_CSR_CHIPID0);
  446                         } else {
  447                                 /* We're in 32-bit mode. */
  448                                 chip_id = pcn_csr_read(sc, PCN_CSR_CHIPID1);
  449                                 chip_id <<= 16;
  450                                 chip_id |= pcn_csr_read(sc, PCN_CSR_CHIPID0);
  451                         }
  452                         bus_release_resource(dev, PCN_RES,
  453                             PCN_RID, sc->pcn_res);
  454                         chip_id >>= 12;
  455                         sc->pcn_type = chip_id & PART_MASK;
  456                         switch(sc->pcn_type) {
  457                         case Am79C971:
  458                         case Am79C972:
  459                         case Am79C973:
  460                         case Am79C975:
  461                         case Am79C976:
  462                         case Am79C978:
  463                                 break;
  464                         default:
  465                                 return(ENXIO);
  466                                 break;
  467                         }
  468                         device_set_desc(dev, t->pcn_name);
  469                         return(0);
  470                 }
  471                 t++;
  472         }
  473 
  474         return(ENXIO);
  475 }
  476 
  477 /*
  478  * Attach the interface. Allocate softc structures, do ifmedia
  479  * setup and ethernet/BPF attach.
  480  */
  481 static int
  482 pcn_attach(device_t dev)
  483 {
  484         uint8_t                 eaddr[ETHER_ADDR_LEN];
  485         u_int32_t               command;
  486         struct pcn_softc        *sc;
  487         struct ifnet            *ifp;
  488         int                     unit, error = 0, rid;
  489 
  490         sc = device_get_softc(dev);
  491         unit = device_get_unit(dev);
  492 
  493         /*
  494          * Handle power management nonsense.
  495          */
  496 
  497         command = pci_read_config(dev, PCN_PCI_CAPID, 4) & 0x000000FF;
  498         if (command == 0x01) {
  499 
  500                 command = pci_read_config(dev, PCN_PCI_PWRMGMTCTRL, 4);
  501                 if (command & PCN_PSTATE_MASK) {
  502                         u_int32_t               iobase, membase, irq;
  503 
  504                         /* Save important PCI config data. */
  505                         iobase = pci_read_config(dev, PCN_PCI_LOIO, 4);
  506                         membase = pci_read_config(dev, PCN_PCI_LOMEM, 4);
  507                         irq = pci_read_config(dev, PCN_PCI_INTLINE, 4);
  508 
  509                         /* Reset the power state. */
  510                         kprintf("pcn%d: chip is in D%d power mode "
  511                         "-- setting to D0\n", unit, command & PCN_PSTATE_MASK);
  512                         command &= 0xFFFFFFFC;
  513                         pci_write_config(dev, PCN_PCI_PWRMGMTCTRL, command, 4);
  514 
  515                         /* Restore PCI config data. */
  516                         pci_write_config(dev, PCN_PCI_LOIO, iobase, 4);
  517                         pci_write_config(dev, PCN_PCI_LOMEM, membase, 4);
  518                         pci_write_config(dev, PCN_PCI_INTLINE, irq, 4);
  519                 }
  520         }
  521 
  522         /*
  523          * Map control/status registers.
  524          */
  525         command = pci_read_config(dev, PCIR_COMMAND, 4);
  526         command |= (PCIM_CMD_PORTEN|PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN);
  527         pci_write_config(dev, PCIR_COMMAND, command, 4);
  528         command = pci_read_config(dev, PCIR_COMMAND, 4);
  529 
  530 #ifdef PCN_USEIOSPACE
  531         if (!(command & PCIM_CMD_PORTEN)) {
  532                 kprintf("pcn%d: failed to enable I/O ports!\n", unit);
  533                 error = ENXIO;
  534                 return(error);
  535         }
  536 #else
  537         if (!(command & PCIM_CMD_MEMEN)) {
  538                 kprintf("pcn%d: failed to enable memory mapping!\n", unit);
  539                 error = ENXIO;
  540                 return(error);
  541         }
  542 #endif
  543 
  544         rid = PCN_RID;
  545         sc->pcn_res = bus_alloc_resource_any(dev, PCN_RES, &rid, RF_ACTIVE);
  546 
  547         if (sc->pcn_res == NULL) {
  548                 kprintf("pcn%d: couldn't map ports/memory\n", unit);
  549                 error = ENXIO;
  550                 return(error);
  551         }
  552 
  553         sc->pcn_btag = rman_get_bustag(sc->pcn_res);
  554         sc->pcn_bhandle = rman_get_bushandle(sc->pcn_res);
  555 
  556         /* Allocate interrupt */
  557         rid = 0;
  558         sc->pcn_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
  559             RF_SHAREABLE | RF_ACTIVE);
  560 
  561         if (sc->pcn_irq == NULL) {
  562                 kprintf("pcn%d: couldn't map interrupt\n", unit);
  563                 error = ENXIO;
  564                 goto fail;
  565         }
  566 
  567         /* Reset the adapter. */
  568         pcn_reset(sc);
  569 
  570         /*
  571          * Get station address from the EEPROM.
  572          */
  573         *(uint32_t *)eaddr = CSR_READ_4(sc, PCN_IO32_APROM00);
  574         *(uint16_t *)(eaddr + 4) = CSR_READ_2(sc, PCN_IO32_APROM01);
  575 
  576         sc->pcn_unit = unit;
  577         callout_init(&sc->pcn_stat_timer);
  578 
  579         sc->pcn_ldata = contigmalloc(sizeof(struct pcn_list_data), M_DEVBUF,
  580             M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0);
  581 
  582         if (sc->pcn_ldata == NULL) {
  583                 kprintf("pcn%d: no memory for list buffers!\n", unit);
  584                 error = ENXIO;
  585                 goto fail;
  586         }
  587         bzero(sc->pcn_ldata, sizeof(struct pcn_list_data));
  588 
  589         ifp = &sc->arpcom.ac_if;
  590         ifp->if_softc = sc;
  591         if_initname(ifp, "pcn", unit);
  592         ifp->if_mtu = ETHERMTU;
  593         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  594         ifp->if_ioctl = pcn_ioctl;
  595         ifp->if_start = pcn_start;
  596         ifp->if_watchdog = pcn_watchdog;
  597         ifp->if_init = pcn_init;
  598         ifp->if_baudrate = 10000000;
  599         ifq_set_maxlen(&ifp->if_snd, PCN_TX_LIST_CNT - 1);
  600         ifq_set_ready(&ifp->if_snd);
  601 
  602         /*
  603          * Do MII setup.
  604          */
  605         if (mii_phy_probe(dev, &sc->pcn_miibus,
  606             pcn_ifmedia_upd, pcn_ifmedia_sts)) {
  607                 kprintf("pcn%d: MII without any PHY!\n", sc->pcn_unit);
  608                 error = ENXIO;
  609                 goto fail;
  610         }
  611 
  612         /*
  613          * Call MI attach routine.
  614          */
  615         ether_ifattach(ifp, eaddr, NULL);
  616 
  617         ifq_set_cpuid(&ifp->if_snd, rman_get_cpuid(sc->pcn_irq));
  618 
  619         error = bus_setup_intr(dev, sc->pcn_irq, INTR_MPSAFE,
  620                                pcn_intr, sc, &sc->pcn_intrhand, 
  621                                ifp->if_serializer);
  622         if (error) {
  623                 ether_ifdetach(ifp);
  624                 device_printf(dev, "couldn't set up irq\n");
  625                 goto fail;
  626         }
  627 
  628         return (0);
  629 fail:
  630         pcn_detach(dev);
  631         return(error);
  632 }
  633 
  634 static int
  635 pcn_detach(device_t dev)
  636 {
  637         struct pcn_softc *sc = device_get_softc(dev);
  638         struct ifnet *ifp = &sc->arpcom.ac_if;
  639 
  640         if (device_is_attached(dev)) {
  641                 lwkt_serialize_enter(ifp->if_serializer);
  642                 pcn_reset(sc);
  643                 pcn_stop(sc);
  644                 bus_teardown_intr(dev, sc->pcn_irq, sc->pcn_intrhand);
  645                 lwkt_serialize_exit(ifp->if_serializer);
  646 
  647                 ether_ifdetach(ifp);
  648         }
  649 
  650         if (sc->pcn_miibus != NULL)
  651                 device_delete_child(dev, sc->pcn_miibus);
  652         bus_generic_detach(dev);
  653 
  654         if (sc->pcn_irq)
  655                 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->pcn_irq);
  656         if (sc->pcn_res)
  657                 bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res);
  658 
  659         if (sc->pcn_ldata) {
  660                 contigfree(sc->pcn_ldata, sizeof(struct pcn_list_data),
  661                            M_DEVBUF);
  662         }
  663 
  664         return(0);
  665 }
  666 
  667 /*
  668  * Initialize the transmit descriptors.
  669  */
  670 static int
  671 pcn_list_tx_init(struct pcn_softc *sc)
  672 {
  673         struct pcn_list_data    *ld;
  674         struct pcn_ring_data    *cd;
  675         int                     i;
  676 
  677         cd = &sc->pcn_cdata;
  678         ld = sc->pcn_ldata;
  679 
  680         for (i = 0; i < PCN_TX_LIST_CNT; i++) {
  681                 cd->pcn_tx_chain[i] = NULL;
  682                 ld->pcn_tx_list[i].pcn_tbaddr = 0;
  683                 ld->pcn_tx_list[i].pcn_txctl = 0;
  684                 ld->pcn_tx_list[i].pcn_txstat = 0;
  685         }
  686 
  687         cd->pcn_tx_prod = cd->pcn_tx_cons = cd->pcn_tx_cnt = 0;
  688 
  689         return(0);
  690 }
  691 
  692 
  693 /*
  694  * Initialize the RX descriptors and allocate mbufs for them.
  695  */
  696 static int
  697 pcn_list_rx_init(struct pcn_softc *sc)
  698 {
  699         struct pcn_ring_data    *cd;
  700         int                     i;
  701 
  702         cd = &sc->pcn_cdata;
  703 
  704         for (i = 0; i < PCN_RX_LIST_CNT; i++) {
  705                 if (pcn_newbuf(sc, i, NULL) == ENOBUFS)
  706                         return(ENOBUFS);
  707         }
  708 
  709         cd->pcn_rx_prod = 0;
  710 
  711         return(0);
  712 }
  713 
  714 /*
  715  * Initialize an RX descriptor and attach an MBUF cluster.
  716  */
  717 static int
  718 pcn_newbuf(struct pcn_softc *sc, int idx, struct mbuf *m)
  719 {
  720         struct mbuf             *m_new = NULL;
  721         struct pcn_rx_desc      *c;
  722 
  723         c = &sc->pcn_ldata->pcn_rx_list[idx];
  724 
  725         if (m == NULL) {
  726                 MGETHDR(m_new, MB_DONTWAIT, MT_DATA);
  727                 if (m_new == NULL)
  728                         return(ENOBUFS);
  729 
  730                 MCLGET(m_new, MB_DONTWAIT);
  731                 if (!(m_new->m_flags & M_EXT)) {
  732                         m_freem(m_new);
  733                         return(ENOBUFS);
  734                 }
  735                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
  736         } else {
  737                 m_new = m;
  738                 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
  739                 m_new->m_data = m_new->m_ext.ext_buf;
  740         }
  741 
  742         m_adj(m_new, ETHER_ALIGN);
  743 
  744         sc->pcn_cdata.pcn_rx_chain[idx] = m_new;
  745         c->pcn_rbaddr = vtophys(mtod(m_new, caddr_t));
  746         c->pcn_bufsz = (~(PCN_RXLEN) + 1) & PCN_RXLEN_BUFSZ;
  747         c->pcn_bufsz |= PCN_RXLEN_MBO;
  748         c->pcn_rxstat = PCN_RXSTAT_STP|PCN_RXSTAT_ENP|PCN_RXSTAT_OWN;
  749 
  750         return(0);
  751 }
  752 
  753 /*
  754  * A frame has been uploaded: pass the resulting mbuf chain up to
  755  * the higher level protocols.
  756  */
  757 static void
  758 pcn_rxeof(struct pcn_softc *sc)
  759 {
  760         struct mbuf             *m;
  761         struct ifnet            *ifp;
  762         struct pcn_rx_desc      *cur_rx;
  763         int                     i;
  764 
  765         ifp = &sc->arpcom.ac_if;
  766         i = sc->pcn_cdata.pcn_rx_prod;
  767 
  768         while(PCN_OWN_RXDESC(&sc->pcn_ldata->pcn_rx_list[i])) {
  769                 cur_rx = &sc->pcn_ldata->pcn_rx_list[i];
  770                 m = sc->pcn_cdata.pcn_rx_chain[i];
  771                 sc->pcn_cdata.pcn_rx_chain[i] = NULL;
  772 
  773                 /*
  774                  * If an error occurs, update stats, clear the
  775                  * status word and leave the mbuf cluster in place:
  776                  * it should simply get re-used next time this descriptor
  777                  * comes up in the ring.
  778                  */
  779                 if (cur_rx->pcn_rxstat & PCN_RXSTAT_ERR) {
  780                         IFNET_STAT_INC(ifp, ierrors, 1);
  781                         pcn_newbuf(sc, i, m);
  782                         PCN_INC(i, PCN_RX_LIST_CNT);
  783                         continue;
  784                 }
  785 
  786                 if (pcn_newbuf(sc, i, NULL)) {
  787                         /* Ran out of mbufs; recycle this one. */
  788                         pcn_newbuf(sc, i, m);
  789                         IFNET_STAT_INC(ifp, ierrors, 1);
  790                         PCN_INC(i, PCN_RX_LIST_CNT);
  791                         continue;
  792                 }
  793 
  794                 PCN_INC(i, PCN_RX_LIST_CNT);
  795 
  796                 /* No errors; receive the packet. */
  797                 IFNET_STAT_INC(ifp, ipackets, 1);
  798                 m->m_len = m->m_pkthdr.len =
  799                     cur_rx->pcn_rxlen - ETHER_CRC_LEN;
  800                 m->m_pkthdr.rcvif = ifp;
  801 
  802                 ifp->if_input(ifp, m);
  803         }
  804 
  805         sc->pcn_cdata.pcn_rx_prod = i;
  806 
  807         return;
  808 }
  809 
  810 /*
  811  * A frame was downloaded to the chip. It's safe for us to clean up
  812  * the list buffers.
  813  */
  814 
  815 static void
  816 pcn_txeof(struct pcn_softc *sc)
  817 {
  818         struct pcn_tx_desc      *cur_tx = NULL;
  819         struct ifnet            *ifp;
  820         u_int32_t               idx;
  821 
  822         ifp = &sc->arpcom.ac_if;
  823 
  824         /*
  825          * Go through our tx list and free mbufs for those
  826          * frames that have been transmitted.
  827          */
  828         idx = sc->pcn_cdata.pcn_tx_cons;
  829         while (idx != sc->pcn_cdata.pcn_tx_prod) {
  830                 cur_tx = &sc->pcn_ldata->pcn_tx_list[idx];
  831 
  832                 if (!PCN_OWN_TXDESC(cur_tx))
  833                         break;
  834 
  835                 if (!(cur_tx->pcn_txctl & PCN_TXCTL_ENP)) {
  836                         sc->pcn_cdata.pcn_tx_cnt--;
  837                         PCN_INC(idx, PCN_TX_LIST_CNT);
  838                         continue;
  839                 }
  840 
  841                 if (cur_tx->pcn_txctl & PCN_TXCTL_ERR) {
  842                         IFNET_STAT_INC(ifp, oerrors, 1);
  843                         if (cur_tx->pcn_txstat & PCN_TXSTAT_EXDEF)
  844                                 IFNET_STAT_INC(ifp, collisions, 1);
  845                         if (cur_tx->pcn_txstat & PCN_TXSTAT_RTRY)
  846                                 IFNET_STAT_INC(ifp, collisions, 1);
  847                 }
  848 
  849                 IFNET_STAT_INC(ifp, collisions,
  850                     cur_tx->pcn_txstat & PCN_TXSTAT_TRC);
  851 
  852                 IFNET_STAT_INC(ifp, opackets, 1);
  853                 if (sc->pcn_cdata.pcn_tx_chain[idx] != NULL) {
  854                         m_freem(sc->pcn_cdata.pcn_tx_chain[idx]);
  855                         sc->pcn_cdata.pcn_tx_chain[idx] = NULL;
  856                 }
  857 
  858                 sc->pcn_cdata.pcn_tx_cnt--;
  859                 PCN_INC(idx, PCN_TX_LIST_CNT);
  860         }
  861 
  862         if (idx != sc->pcn_cdata.pcn_tx_cons) {
  863                 /* Some buffers have been freed. */
  864                 sc->pcn_cdata.pcn_tx_cons = idx;
  865                 ifq_clr_oactive(&ifp->if_snd);
  866         }
  867         ifp->if_timer = (sc->pcn_cdata.pcn_tx_cnt == 0) ? 0 : 5;
  868 
  869         return;
  870 }
  871 
  872 static void
  873 pcn_tick(void *xsc)
  874 {
  875         struct pcn_softc *sc = xsc;
  876         struct mii_data *mii;
  877         struct ifnet *ifp = &sc->arpcom.ac_if;
  878 
  879         lwkt_serialize_enter(ifp->if_serializer);
  880 
  881         mii = device_get_softc(sc->pcn_miibus);
  882         mii_tick(mii);
  883 
  884         if (sc->pcn_link && !(mii->mii_media_status & IFM_ACTIVE))
  885                 sc->pcn_link = 0;
  886 
  887         if (!sc->pcn_link) {
  888                 mii_pollstat(mii);
  889                 if (mii->mii_media_status & IFM_ACTIVE &&
  890                     IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
  891                         sc->pcn_link++;
  892                         if (!ifq_is_empty(&ifp->if_snd))
  893                                 if_devstart(ifp);
  894                 }
  895         }
  896         callout_reset(&sc->pcn_stat_timer, hz, pcn_tick, sc);
  897 
  898         lwkt_serialize_exit(ifp->if_serializer);
  899 }
  900 
  901 static void
  902 pcn_intr(void *arg)
  903 {
  904         struct pcn_softc        *sc;
  905         struct ifnet            *ifp;
  906         u_int32_t               status;
  907 
  908         sc = arg;
  909         ifp = &sc->arpcom.ac_if;
  910 
  911         /* Supress unwanted interrupts */
  912         if (!(ifp->if_flags & IFF_UP)) {
  913                 pcn_stop(sc);
  914                 return;
  915         }
  916 
  917         CSR_WRITE_4(sc, PCN_IO32_RAP, PCN_CSR_CSR);
  918 
  919         while ((status = CSR_READ_4(sc, PCN_IO32_RDP)) & PCN_CSR_INTR) {
  920                 CSR_WRITE_4(sc, PCN_IO32_RDP, status);
  921 
  922                 if (status & PCN_CSR_RINT)
  923                         pcn_rxeof(sc);
  924 
  925                 if (status & PCN_CSR_TINT)
  926                         pcn_txeof(sc);
  927 
  928                 if (status & PCN_CSR_ERR) {
  929                         pcn_init(sc);
  930                         break;
  931                 }
  932         }
  933 
  934         if (!ifq_is_empty(&ifp->if_snd))
  935                 if_devstart(ifp);
  936 }
  937 
  938 /*
  939  * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
  940  * pointers to the fragment pointers.
  941  */
  942 static int
  943 pcn_encap(struct pcn_softc *sc, struct mbuf *m_head, u_int32_t *txidx)
  944 {
  945         struct pcn_tx_desc      *f = NULL;
  946         struct mbuf             *m;
  947         int                     frag, cur, cnt = 0;
  948 
  949         /*
  950          * Start packing the mbufs in this chain into
  951          * the fragment pointers. Stop when we run out
  952          * of fragments or hit the end of the mbuf chain.
  953          */
  954         cur = frag = *txidx;
  955 
  956         for (m = m_head; m != NULL; m = m->m_next) {
  957                 if (m->m_len != 0) {
  958                         if ((PCN_TX_LIST_CNT -
  959                             (sc->pcn_cdata.pcn_tx_cnt + cnt)) < 2)
  960                                 break;
  961                         f = &sc->pcn_ldata->pcn_tx_list[frag];
  962                         f->pcn_txctl = (~(m->m_len) + 1) & PCN_TXCTL_BUFSZ;
  963                         f->pcn_txctl |= PCN_TXCTL_MBO;
  964                         f->pcn_tbaddr = vtophys(mtod(m, vm_offset_t));
  965                         if (cnt == 0)
  966                                 f->pcn_txctl |= PCN_TXCTL_STP;
  967                         else
  968                                 f->pcn_txctl |= PCN_TXCTL_OWN;
  969                         cur = frag;
  970                         PCN_INC(frag, PCN_TX_LIST_CNT);
  971                         cnt++;
  972                 }
  973         }
  974         /* Caller should make sure that 'm_head' is not excessive fragmented */
  975         KASSERT(m == NULL, ("too many fragments"));
  976 
  977         sc->pcn_cdata.pcn_tx_chain[cur] = m_head;
  978         sc->pcn_ldata->pcn_tx_list[cur].pcn_txctl |=
  979             PCN_TXCTL_ENP|PCN_TXCTL_ADD_FCS|PCN_TXCTL_MORE_LTINT;
  980         sc->pcn_ldata->pcn_tx_list[*txidx].pcn_txctl |= PCN_TXCTL_OWN;
  981         sc->pcn_cdata.pcn_tx_cnt += cnt;
  982         *txidx = frag;
  983 
  984         return(0);
  985 }
  986 
  987 /*
  988  * Main transmit routine. To avoid having to do mbuf copies, we put pointers
  989  * to the mbuf data regions directly in the transmit lists. We also save a
  990  * copy of the pointers since the transmit list fragment pointers are
  991  * physical addresses.
  992  */
  993 static void
  994 pcn_start(struct ifnet *ifp, struct ifaltq_subque *ifsq)
  995 {
  996         struct pcn_softc        *sc;
  997         struct mbuf             *m_head = NULL, *m_defragged;
  998         u_int32_t               idx;
  999         int need_trans;
 1000 
 1001         ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq);
 1002 
 1003         sc = ifp->if_softc;
 1004 
 1005         if (!sc->pcn_link) {
 1006                 ifq_purge(&ifp->if_snd);
 1007                 return;
 1008         }
 1009 
 1010         idx = sc->pcn_cdata.pcn_tx_prod;
 1011 
 1012         if ((ifp->if_flags & IFF_RUNNING) == 0 || ifq_is_oactive(&ifp->if_snd))
 1013                 return;
 1014 
 1015         need_trans = 0;
 1016         while (sc->pcn_cdata.pcn_tx_chain[idx] == NULL) {
 1017                 struct mbuf *m;
 1018                 int cnt;
 1019 
 1020                 m_defragged = NULL;
 1021                 m_head = ifq_dequeue(&ifp->if_snd);
 1022                 if (m_head == NULL)
 1023                         break;
 1024 
 1025 again:
 1026                 cnt = 0;
 1027                 for (m = m_head; m != NULL; m = m->m_next)
 1028                         ++cnt;
 1029                 if ((PCN_TX_LIST_CNT -
 1030                     (sc->pcn_cdata.pcn_tx_cnt + cnt)) < 2) {
 1031                         if (m_defragged != NULL) {
 1032                                 /*
 1033                                  * Even after defragmentation, there
 1034                                  * are still too many fragments, so
 1035                                  * drop this packet.
 1036                                  */
 1037                                 m_freem(m_head);
 1038                                 ifq_set_oactive(&ifp->if_snd);
 1039                                 break;
 1040                         }
 1041 
 1042                         m_defragged = m_defrag(m_head, MB_DONTWAIT);
 1043                         if (m_defragged == NULL) {
 1044                                 m_freem(m_head);
 1045                                 continue;
 1046                         }
 1047                         m_head = m_defragged;
 1048 
 1049                         /* Recount # of fragments */
 1050                         goto again;
 1051                 }
 1052 
 1053                 pcn_encap(sc, m_head, &idx);
 1054                 need_trans = 1;
 1055 
 1056                 BPF_MTAP(ifp, m_head);
 1057         }
 1058 
 1059         if (!need_trans)
 1060                 return;
 1061 
 1062         /* Transmit */
 1063         sc->pcn_cdata.pcn_tx_prod = idx;
 1064         pcn_csr_write(sc, PCN_CSR_CSR, PCN_CSR_TX|PCN_CSR_INTEN);
 1065 
 1066         /*
 1067          * Set a timeout in case the chip goes out to lunch.
 1068          */
 1069         ifp->if_timer = 5;
 1070 }
 1071 
 1072 void
 1073 pcn_setfilt(struct ifnet *ifp)
 1074 {
 1075         struct pcn_softc        *sc;
 1076 
 1077         sc = ifp->if_softc;
 1078 
 1079         /* If we want promiscuous mode, set the allframes bit. */
 1080         if (ifp->if_flags & IFF_PROMISC) {
 1081                 PCN_CSR_SETBIT(sc, PCN_CSR_MODE, PCN_MODE_PROMISC);
 1082         } else {
 1083                 PCN_CSR_CLRBIT(sc, PCN_CSR_MODE, PCN_MODE_PROMISC);
 1084         }
 1085 
 1086         /* Set the capture broadcast bit to capture broadcast frames. */
 1087         if (ifp->if_flags & IFF_BROADCAST) {
 1088                 PCN_CSR_CLRBIT(sc, PCN_CSR_MODE, PCN_MODE_RXNOBROAD);
 1089         } else {
 1090                 PCN_CSR_SETBIT(sc, PCN_CSR_MODE, PCN_MODE_RXNOBROAD);
 1091         }
 1092 
 1093         return;
 1094 }
 1095 
 1096 static void
 1097 pcn_init(void *xsc)
 1098 {
 1099         struct pcn_softc        *sc = xsc;
 1100         struct ifnet            *ifp = &sc->arpcom.ac_if;
 1101         struct mii_data         *mii = NULL;
 1102 
 1103         /*
 1104          * Cancel pending I/O and free all RX/TX buffers.
 1105          */
 1106         pcn_stop(sc);
 1107         pcn_reset(sc);
 1108 
 1109         mii = device_get_softc(sc->pcn_miibus);
 1110 
 1111         /* Set MAC address */
 1112         pcn_csr_write(sc, PCN_CSR_PAR0,
 1113             ((u_int16_t *)sc->arpcom.ac_enaddr)[0]);
 1114         pcn_csr_write(sc, PCN_CSR_PAR1,
 1115             ((u_int16_t *)sc->arpcom.ac_enaddr)[1]);
 1116         pcn_csr_write(sc, PCN_CSR_PAR2,
 1117             ((u_int16_t *)sc->arpcom.ac_enaddr)[2]);
 1118 
 1119         /* Init circular RX list. */
 1120         if (pcn_list_rx_init(sc) == ENOBUFS) {
 1121                 kprintf("pcn%d: initialization failed: no "
 1122                     "memory for rx buffers\n", sc->pcn_unit);
 1123                 pcn_stop(sc);
 1124 
 1125                 return;
 1126         }
 1127 
 1128         /* Set up RX filter. */
 1129         pcn_setfilt(ifp);
 1130 
 1131         /*
 1132          * Init tx descriptors.
 1133          */
 1134         pcn_list_tx_init(sc);
 1135 
 1136         /* Set up the mode register. */
 1137         pcn_csr_write(sc, PCN_CSR_MODE, PCN_PORT_MII);
 1138 
 1139         /*
 1140          * Load the multicast filter.
 1141          */
 1142         pcn_setmulti(sc);
 1143 
 1144         /*
 1145          * Load the addresses of the RX and TX lists.
 1146          */
 1147         pcn_csr_write(sc, PCN_CSR_RXADDR0,
 1148             vtophys(&sc->pcn_ldata->pcn_rx_list[0]) & 0xFFFF);
 1149         pcn_csr_write(sc, PCN_CSR_RXADDR1,
 1150             (vtophys(&sc->pcn_ldata->pcn_rx_list[0]) >> 16) & 0xFFFF);
 1151         pcn_csr_write(sc, PCN_CSR_TXADDR0,
 1152             vtophys(&sc->pcn_ldata->pcn_tx_list[0]) & 0xFFFF);
 1153         pcn_csr_write(sc, PCN_CSR_TXADDR1,
 1154             (vtophys(&sc->pcn_ldata->pcn_tx_list[0]) >> 16) & 0xFFFF);
 1155 
 1156         /* Set the RX and TX ring sizes. */
 1157         pcn_csr_write(sc, PCN_CSR_RXRINGLEN, (~PCN_RX_LIST_CNT) + 1);
 1158         pcn_csr_write(sc, PCN_CSR_TXRINGLEN, (~PCN_TX_LIST_CNT) + 1);
 1159 
 1160         /* We're not using the initialization block. */
 1161         pcn_csr_write(sc, PCN_CSR_IAB1, 0);
 1162 
 1163         /* Enable fast suspend mode. */
 1164         PCN_CSR_SETBIT(sc, PCN_CSR_EXTCTL2, PCN_EXTCTL2_FASTSPNDE);
 1165 
 1166         /*
 1167          * Enable burst read and write. Also set the no underflow
 1168          * bit. This will avoid transmit underruns in certain
 1169          * conditions while still providing decent performance.
 1170          */
 1171         PCN_BCR_SETBIT(sc, PCN_BCR_BUSCTL, PCN_BUSCTL_NOUFLOW|
 1172             PCN_BUSCTL_BREAD|PCN_BUSCTL_BWRITE);
 1173 
 1174         /* Enable graceful recovery from underflow. */
 1175         PCN_CSR_SETBIT(sc, PCN_CSR_IMR, PCN_IMR_DXSUFLO);
 1176 
 1177         /* Enable auto-padding of short TX frames. */
 1178         PCN_CSR_SETBIT(sc, PCN_CSR_TFEAT, PCN_TFEAT_PAD_TX);
 1179 
 1180         /* Disable MII autoneg (we handle this ourselves). */
 1181         PCN_BCR_SETBIT(sc, PCN_BCR_MIICTL, PCN_MIICTL_DANAS);
 1182 
 1183         if (sc->pcn_type == Am79C978)
 1184                 pcn_bcr_write(sc, PCN_BCR_PHYSEL,
 1185                     PCN_PHYSEL_PCNET|PCN_PHY_HOMEPNA);
 1186 
 1187         /* Enable interrupts and start the controller running. */
 1188         pcn_csr_write(sc, PCN_CSR_CSR, PCN_CSR_INTEN|PCN_CSR_START);
 1189 
 1190         mii_mediachg(mii);
 1191 
 1192         ifp->if_flags |= IFF_RUNNING;
 1193         ifq_clr_oactive(&ifp->if_snd);
 1194 
 1195         callout_reset(&sc->pcn_stat_timer, hz, pcn_tick, sc);
 1196 }
 1197 
 1198 /*
 1199  * Set media options.
 1200  */
 1201 static int
 1202 pcn_ifmedia_upd(struct ifnet *ifp)
 1203 {
 1204         struct pcn_softc        *sc;
 1205         struct mii_data         *mii;
 1206 
 1207         sc = ifp->if_softc;
 1208         mii = device_get_softc(sc->pcn_miibus);
 1209 
 1210         sc->pcn_link = 0;
 1211         if (mii->mii_instance) {
 1212                 struct mii_softc        *miisc;
 1213                 for (miisc = LIST_FIRST(&mii->mii_phys); miisc != NULL;
 1214                     miisc = LIST_NEXT(miisc, mii_list))
 1215                         mii_phy_reset(miisc);
 1216         }
 1217         mii_mediachg(mii);
 1218 
 1219         return(0);
 1220 }
 1221 
 1222 /*
 1223  * Report current media status.
 1224  */
 1225 static void
 1226 pcn_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 1227 {
 1228         struct pcn_softc        *sc;
 1229         struct mii_data         *mii;
 1230 
 1231         sc = ifp->if_softc;
 1232 
 1233         mii = device_get_softc(sc->pcn_miibus);
 1234         mii_pollstat(mii);
 1235         ifmr->ifm_active = mii->mii_media_active;
 1236         ifmr->ifm_status = mii->mii_media_status;
 1237 
 1238         return;
 1239 }
 1240 
 1241 static int
 1242 pcn_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
 1243 {
 1244         struct pcn_softc        *sc = ifp->if_softc;
 1245         struct ifreq            *ifr = (struct ifreq *) data;
 1246         struct mii_data         *mii = NULL;
 1247         int                     error = 0;
 1248 
 1249         switch(command) {
 1250         case SIOCSIFFLAGS:
 1251                 if (ifp->if_flags & IFF_UP) {
 1252                         if (ifp->if_flags & IFF_RUNNING &&
 1253                             ifp->if_flags & IFF_PROMISC &&
 1254                             !(sc->pcn_if_flags & IFF_PROMISC)) {
 1255                                 PCN_CSR_SETBIT(sc, PCN_CSR_EXTCTL1,
 1256                                     PCN_EXTCTL1_SPND);
 1257                                 pcn_setfilt(ifp);
 1258                                 PCN_CSR_CLRBIT(sc, PCN_CSR_EXTCTL1,
 1259                                     PCN_EXTCTL1_SPND);
 1260                                 pcn_csr_write(sc, PCN_CSR_CSR,
 1261                                     PCN_CSR_INTEN|PCN_CSR_START);
 1262                         } else if (ifp->if_flags & IFF_RUNNING &&
 1263                             !(ifp->if_flags & IFF_PROMISC) &&
 1264                                 sc->pcn_if_flags & IFF_PROMISC) {
 1265                                 PCN_CSR_SETBIT(sc, PCN_CSR_EXTCTL1,
 1266                                     PCN_EXTCTL1_SPND);
 1267                                 pcn_setfilt(ifp);
 1268                                 PCN_CSR_CLRBIT(sc, PCN_CSR_EXTCTL1,
 1269                                     PCN_EXTCTL1_SPND);
 1270                                 pcn_csr_write(sc, PCN_CSR_CSR,
 1271                                     PCN_CSR_INTEN|PCN_CSR_START);
 1272                         } else if (!(ifp->if_flags & IFF_RUNNING))
 1273                                 pcn_init(sc);
 1274                 } else {
 1275                         if (ifp->if_flags & IFF_RUNNING)
 1276                                 pcn_stop(sc);
 1277                 }
 1278                 sc->pcn_if_flags = ifp->if_flags;
 1279                 error = 0;
 1280                 break;
 1281         case SIOCADDMULTI:
 1282         case SIOCDELMULTI:
 1283                 pcn_setmulti(sc);
 1284                 error = 0;
 1285                 break;
 1286         case SIOCGIFMEDIA:
 1287         case SIOCSIFMEDIA:
 1288                 mii = device_get_softc(sc->pcn_miibus);
 1289                 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
 1290                 break;
 1291         default:
 1292                 error = ether_ioctl(ifp, command, data);
 1293                 break;
 1294         }
 1295         return(error);
 1296 }
 1297 
 1298 static void
 1299 pcn_watchdog(struct ifnet *ifp)
 1300 {
 1301         struct pcn_softc        *sc;
 1302 
 1303         sc = ifp->if_softc;
 1304 
 1305         IFNET_STAT_INC(ifp, oerrors, 1);
 1306         kprintf("pcn%d: watchdog timeout\n", sc->pcn_unit);
 1307 
 1308         pcn_stop(sc);
 1309         pcn_reset(sc);
 1310         pcn_init(sc);
 1311 
 1312         if (!ifq_is_empty(&ifp->if_snd))
 1313                 if_devstart(ifp);
 1314 }
 1315 
 1316 /*
 1317  * Stop the adapter and free any mbufs allocated to the
 1318  * RX and TX lists.
 1319  */
 1320 static void
 1321 pcn_stop(struct pcn_softc *sc)
 1322 {
 1323         int             i;
 1324         struct ifnet            *ifp;
 1325 
 1326         ifp = &sc->arpcom.ac_if;
 1327         ifp->if_timer = 0;
 1328 
 1329         callout_stop(&sc->pcn_stat_timer);
 1330         PCN_CSR_SETBIT(sc, PCN_CSR_CSR, PCN_CSR_STOP);
 1331         sc->pcn_link = 0;
 1332 
 1333         /*
 1334          * Free data in the RX lists.
 1335          */
 1336         for (i = 0; i < PCN_RX_LIST_CNT; i++) {
 1337                 if (sc->pcn_cdata.pcn_rx_chain[i] != NULL) {
 1338                         m_freem(sc->pcn_cdata.pcn_rx_chain[i]);
 1339                         sc->pcn_cdata.pcn_rx_chain[i] = NULL;
 1340                 }
 1341         }
 1342         bzero((char *)&sc->pcn_ldata->pcn_rx_list,
 1343                 sizeof(sc->pcn_ldata->pcn_rx_list));
 1344 
 1345         /*
 1346          * Free the TX list buffers.
 1347          */
 1348         for (i = 0; i < PCN_TX_LIST_CNT; i++) {
 1349                 if (sc->pcn_cdata.pcn_tx_chain[i] != NULL) {
 1350                         m_freem(sc->pcn_cdata.pcn_tx_chain[i]);
 1351                         sc->pcn_cdata.pcn_tx_chain[i] = NULL;
 1352                 }
 1353         }
 1354 
 1355         bzero((char *)&sc->pcn_ldata->pcn_tx_list,
 1356                 sizeof(sc->pcn_ldata->pcn_tx_list));
 1357 
 1358         ifp->if_flags &= ~IFF_RUNNING;
 1359         ifq_clr_oactive(&ifp->if_snd);
 1360 
 1361         return;
 1362 }
 1363 
 1364 /*
 1365  * Stop all chip I/O so that the kernel's probe routines don't
 1366  * get confused by errant DMAs when rebooting.
 1367  */
 1368 static void
 1369 pcn_shutdown(device_t dev)
 1370 {
 1371         struct pcn_softc *sc = device_get_softc(dev);
 1372         struct ifnet *ifp = &sc->arpcom.ac_if;
 1373 
 1374         lwkt_serialize_enter(ifp->if_serializer);
 1375         pcn_reset(sc);
 1376         pcn_stop(sc);
 1377         lwkt_serialize_exit(ifp->if_serializer);
 1378 }
 1379 

Cache object: e0f443ae3cc5caf8e41968d71625b9cd


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