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/pci/if_tl.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 /*      $NetBSD: if_tl.c,v 1.64.2.1 2004/06/22 15:24:54 tron Exp $      */
    2 
    3 /*
    4  * Copyright (c) 1997 Manuel Bouyer.  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 Manuel Bouyer.
   17  * 4. The name of the author may not be used to endorse or promote products
   18  *    derived from this software without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Texas Instruments ThunderLAN ethernet controller
   34  * ThunderLAN Programmer's Guide (TI Literature Number SPWU013A)
   35  * available from www.ti.com
   36  */
   37 
   38 #include <sys/cdefs.h>
   39 __KERNEL_RCSID(0, "$NetBSD: if_tl.c,v 1.64.2.1 2004/06/22 15:24:54 tron Exp $");
   40 
   41 #undef TLDEBUG
   42 #define TL_PRIV_STATS
   43 #undef TLDEBUG_RX
   44 #undef TLDEBUG_TX
   45 #undef TLDEBUG_ADDR
   46 
   47 #include "opt_inet.h"
   48 #include "opt_ns.h"
   49 
   50 #include <sys/param.h>
   51 #include <sys/systm.h>
   52 #include <sys/mbuf.h>
   53 #include <sys/protosw.h>
   54 #include <sys/socket.h>
   55 #include <sys/ioctl.h>
   56 #include <sys/errno.h>
   57 #include <sys/malloc.h>
   58 #include <sys/kernel.h>
   59 #include <sys/proc.h>   /* only for declaration of wakeup() used by vm.h */
   60 #include <sys/device.h>
   61 
   62 #include <net/if.h>
   63 #if defined(SIOCSIFMEDIA)
   64 #include <net/if_media.h>
   65 #endif
   66 #include <net/if_types.h>
   67 #include <net/if_dl.h>
   68 #include <net/route.h>
   69 #include <net/netisr.h>
   70 
   71 #include "bpfilter.h"
   72 #if NBPFILTER > 0
   73 #include <net/bpf.h>
   74 #include <net/bpfdesc.h>
   75 #endif
   76 
   77 #ifdef INET
   78 #include <netinet/in.h>
   79 #include <netinet/in_systm.h>
   80 #include <netinet/in_var.h>
   81 #include <netinet/ip.h>
   82 #endif
   83 
   84 #ifdef NS
   85 #include <netns/ns.h>
   86 #include <netns/ns_if.h>
   87 #endif
   88 
   89 #if defined(__NetBSD__)
   90 #include <net/if_ether.h>
   91 #include <uvm/uvm_extern.h>
   92 #if defined(INET)
   93 #include <netinet/if_inarp.h>
   94 #endif
   95 
   96 #include <machine/bus.h>
   97 #include <machine/intr.h>
   98 
   99 #include <dev/pci/pcireg.h>
  100 #include <dev/pci/pcivar.h>
  101 #include <dev/pci/pcidevs.h>
  102 
  103 #include <dev/i2c/i2cvar.h>
  104 #include <dev/i2c/i2c_bitbang.h>
  105 #include <dev/i2c/at24cxxvar.h>
  106 
  107 #include <dev/mii/mii.h>
  108 #include <dev/mii/miivar.h>
  109 
  110 #include <dev/mii/tlphyvar.h>
  111 
  112 #include <dev/pci/if_tlregs.h>
  113 #include <dev/pci/if_tlvar.h>
  114 #endif /* __NetBSD__ */
  115 
  116 /* number of transmit/receive buffers */
  117 #ifndef TL_NBUF
  118 #define TL_NBUF 32
  119 #endif
  120 
  121 static int tl_pci_match __P((struct device *, struct cfdata *, void *));
  122 static void tl_pci_attach __P((struct device *, struct device *, void *));
  123 static int tl_intr __P((void *));
  124 
  125 static int tl_ifioctl __P((struct ifnet *, ioctl_cmd_t, caddr_t));
  126 static int tl_mediachange __P((struct ifnet *));
  127 static void tl_mediastatus __P((struct ifnet *, struct ifmediareq *));
  128 static void tl_ifwatchdog __P((struct ifnet *));
  129 static void tl_shutdown __P((void*));
  130 
  131 static void tl_ifstart __P((struct ifnet *));
  132 static void tl_reset __P((tl_softc_t*));
  133 static int  tl_init __P((struct ifnet *));
  134 static void tl_stop __P((struct ifnet *, int));
  135 static void tl_restart __P((void  *));
  136 static int  tl_add_RxBuff __P((tl_softc_t*, struct Rx_list*, struct mbuf*));
  137 static void tl_read_stats __P((tl_softc_t*));
  138 static void tl_ticks __P((void*));
  139 static int tl_multicast_hash __P((u_int8_t*));
  140 static void tl_addr_filter __P((tl_softc_t*));
  141 
  142 static u_int32_t tl_intreg_read __P((tl_softc_t*, u_int32_t));
  143 static void tl_intreg_write __P((tl_softc_t*, u_int32_t, u_int32_t));
  144 static u_int8_t tl_intreg_read_byte __P((tl_softc_t*, u_int32_t));
  145 static void tl_intreg_write_byte __P((tl_softc_t*, u_int32_t, u_int8_t));
  146 
  147 void    tl_mii_sync __P((struct tl_softc *));
  148 void    tl_mii_sendbits __P((struct tl_softc *, u_int32_t, int));
  149 
  150 
  151 #if defined(TLDEBUG_RX)
  152 static void ether_printheader __P((struct ether_header*));
  153 #endif
  154 
  155 int tl_mii_read __P((struct device *, int, int));
  156 void tl_mii_write __P((struct device *, int, int, int));
  157 
  158 void tl_statchg __P((struct device *));
  159 
  160         /* I2C glue */
  161 static int tl_i2c_acquire_bus(void *, int);
  162 static void tl_i2c_release_bus(void *, int);
  163 static int tl_i2c_send_start(void *, int);
  164 static int tl_i2c_send_stop(void *, int);
  165 static int tl_i2c_initiate_xfer(void *, i2c_addr_t, int);
  166 static int tl_i2c_read_byte(void *, uint8_t *, int);
  167 static int tl_i2c_write_byte(void *, uint8_t, int);
  168 
  169         /* I2C bit-bang glue */
  170 static void tl_i2cbb_set_bits(void *, uint32_t);
  171 static void tl_i2cbb_set_dir(void *, uint32_t);
  172 static uint32_t tl_i2cbb_read(void *);
  173 static const struct i2c_bitbang_ops tl_i2cbb_ops = {
  174         tl_i2cbb_set_bits,
  175         tl_i2cbb_set_dir,
  176         tl_i2cbb_read,
  177         {
  178                 TL_NETSIO_EDATA,        /* SDA */
  179                 TL_NETSIO_ECLOCK,       /* SCL */
  180                 TL_NETSIO_ETXEN,        /* SDA is output */
  181                 0,                      /* SDA is input */
  182         }
  183 };
  184 
  185 static __inline void netsio_clr __P((tl_softc_t*, u_int8_t));
  186 static __inline void netsio_set __P((tl_softc_t*, u_int8_t));
  187 static __inline u_int8_t netsio_read __P((tl_softc_t*, u_int8_t));
  188 static __inline void netsio_clr(sc, bits)
  189         tl_softc_t* sc;
  190         u_int8_t bits;
  191 {
  192         tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetSio,
  193             tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetSio) & (~bits));
  194 }
  195 static __inline void netsio_set(sc, bits)
  196         tl_softc_t* sc;
  197         u_int8_t bits;
  198 {
  199         tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetSio,
  200             tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetSio) | bits);
  201 }
  202 static __inline u_int8_t netsio_read(sc, bits)
  203         tl_softc_t* sc;
  204         u_int8_t bits;
  205 {
  206         return (tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetSio) & bits);
  207 }
  208 
  209 CFATTACH_DECL(tl, sizeof(tl_softc_t),
  210     tl_pci_match, tl_pci_attach, NULL, NULL);
  211 
  212 const struct tl_product_desc tl_compaq_products[] = {
  213         { PCI_PRODUCT_COMPAQ_N100TX, TLPHY_MEDIA_NO_10_T,
  214           "Compaq Netelligent 10/100 TX" },
  215         { PCI_PRODUCT_COMPAQ_INT100TX, TLPHY_MEDIA_NO_10_T,
  216           "Integrated Compaq Netelligent 10/100 TX" },
  217         { PCI_PRODUCT_COMPAQ_N10T, TLPHY_MEDIA_10_5,
  218           "Compaq Netelligent 10 T" },
  219         { PCI_PRODUCT_COMPAQ_IntNF3P, TLPHY_MEDIA_10_2,
  220           "Compaq Integrated NetFlex 3/P" },
  221         { PCI_PRODUCT_COMPAQ_IntPL100TX, TLPHY_MEDIA_10_2|TLPHY_MEDIA_NO_10_T,
  222           "Compaq ProLiant Integrated Netelligent 10/100 TX" },
  223         { PCI_PRODUCT_COMPAQ_DPNet100TX, TLPHY_MEDIA_10_5|TLPHY_MEDIA_NO_10_T,
  224           "Compaq Dual Port Netelligent 10/100 TX" },
  225         { PCI_PRODUCT_COMPAQ_DP4000, TLPHY_MEDIA_10_5|TLPHY_MEDIA_NO_10_T,
  226           "Compaq Deskpro 4000 5233MMX" },
  227         { PCI_PRODUCT_COMPAQ_NF3P_BNC, TLPHY_MEDIA_10_2,
  228           "Compaq NetFlex 3/P w/ BNC" },
  229         { PCI_PRODUCT_COMPAQ_NF3P, TLPHY_MEDIA_10_5,
  230           "Compaq NetFlex 3/P" },
  231         { 0, 0, NULL },
  232 };
  233 
  234 const struct tl_product_desc tl_ti_products[] = {
  235         /*
  236          * Built-in Ethernet on the TI TravelMate 5000
  237          * docking station; better product description?
  238          */
  239         { PCI_PRODUCT_TI_TLAN, 0,
  240           "Texas Instruments ThunderLAN" },
  241         { 0, 0, NULL },
  242 };
  243 
  244 struct tl_vendor_desc {
  245         u_int32_t tv_vendor;
  246         const struct tl_product_desc *tv_products;
  247 };
  248 
  249 const struct tl_vendor_desc tl_vendors[] = {
  250         { PCI_VENDOR_COMPAQ, tl_compaq_products },
  251         { PCI_VENDOR_TI, tl_ti_products },
  252         { 0, NULL },
  253 };
  254 
  255 const struct tl_product_desc *tl_lookup_product __P((u_int32_t));
  256 
  257 const struct tl_product_desc *
  258 tl_lookup_product(id)
  259         u_int32_t id;
  260 {
  261         const struct tl_product_desc *tp;
  262         const struct tl_vendor_desc *tv;
  263 
  264         for (tv = tl_vendors; tv->tv_products != NULL; tv++)
  265                 if (PCI_VENDOR(id) == tv->tv_vendor)
  266                         break;
  267 
  268         if ((tp = tv->tv_products) == NULL)
  269                 return (NULL);
  270 
  271         for (; tp->tp_desc != NULL; tp++)
  272                 if (PCI_PRODUCT(id) == tp->tp_product)
  273                         break;
  274 
  275         if (tp->tp_desc == NULL)
  276                 return (NULL);
  277 
  278         return (tp);
  279 }
  280 
  281 static int
  282 tl_pci_match(parent, match, aux)
  283         struct device *parent;
  284         struct cfdata *match;
  285         void *aux;
  286 {
  287         struct pci_attach_args *pa = (struct pci_attach_args *) aux;
  288 
  289         if (tl_lookup_product(pa->pa_id) != NULL)
  290                 return (1);
  291 
  292         return (0);
  293 }
  294 
  295 static void
  296 tl_pci_attach(parent, self, aux)
  297         struct device * parent;
  298         struct device * self;
  299         void * aux;
  300 {
  301         tl_softc_t *sc = (tl_softc_t *)self;
  302         struct pci_attach_args * const pa = (struct pci_attach_args *) aux;
  303         const struct tl_product_desc *tp;
  304         struct ifnet * const ifp = &sc->tl_if;
  305         bus_space_tag_t iot, memt;
  306         bus_space_handle_t ioh, memh;
  307         pci_intr_handle_t intrhandle;
  308         const char *intrstr;
  309         int ioh_valid, memh_valid;
  310         int reg_io, reg_mem;
  311         pcireg_t reg10, reg14;
  312         pcireg_t csr;
  313 
  314         printf("\n");
  315 
  316         callout_init(&sc->tl_tick_ch);
  317         callout_init(&sc->tl_restart_ch);
  318 
  319         tp = tl_lookup_product(pa->pa_id);
  320         if (tp == NULL)
  321                 panic("tl_pci_attach: impossible");
  322         sc->tl_product = tp;
  323 
  324         /*
  325          * Map the card space. First we have to find the I/O and MEM
  326          * registers. I/O is supposed to be at 0x10, MEM at 0x14,
  327          * but some boards (Compaq Netflex 3/P PCI) seem to have it reversed.
  328          * The ThunderLAN manual is not consistent about this either (there
  329          * are both cases in code examples).
  330          */
  331         reg10 = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x10);
  332         reg14 = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x14);
  333         if (PCI_MAPREG_TYPE(reg10) == PCI_MAPREG_TYPE_IO)
  334                 reg_io = 0x10;
  335         else if (PCI_MAPREG_TYPE(reg14) == PCI_MAPREG_TYPE_IO)
  336                 reg_io = 0x14;
  337         else
  338                 reg_io = 0;
  339         if (PCI_MAPREG_TYPE(reg10) == PCI_MAPREG_TYPE_MEM)
  340                 reg_mem = 0x10;
  341         else if (PCI_MAPREG_TYPE(reg14) == PCI_MAPREG_TYPE_MEM)
  342                 reg_mem = 0x14;
  343         else
  344                 reg_mem = 0;
  345 
  346         if (reg_io != 0)
  347                 ioh_valid = (pci_mapreg_map(pa, reg_io, PCI_MAPREG_TYPE_IO,
  348                     0, &iot, &ioh, NULL, NULL) == 0);
  349         else
  350                 ioh_valid = 0;
  351         if (reg_mem != 0)
  352                 memh_valid = (pci_mapreg_map(pa, PCI_CBMA,
  353                     PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
  354                     0, &memt, &memh, NULL, NULL) == 0);
  355         else
  356                 memh_valid = 0;
  357 
  358         if (ioh_valid) {
  359                 sc->tl_bustag = iot;
  360                 sc->tl_bushandle = ioh;
  361         } else if (memh_valid) {
  362                 sc->tl_bustag = memt;
  363                 sc->tl_bushandle = memh;
  364         } else {
  365                 printf("%s: unable to map device registers\n",
  366                     sc->sc_dev.dv_xname);
  367                 return;
  368         }
  369         sc->tl_dmatag = pa->pa_dmat;
  370 
  371         /* Enable the device. */
  372         csr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
  373         pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_COMMAND_STATUS_REG,
  374             csr | PCI_COMMAND_MASTER_ENABLE);
  375 
  376         printf("%s: %s\n", sc->sc_dev.dv_xname, tp->tp_desc);
  377 
  378         tl_reset(sc);
  379 
  380         /* fill in the i2c tag */
  381         sc->sc_i2c.ic_cookie = sc;
  382         sc->sc_i2c.ic_acquire_bus = tl_i2c_acquire_bus;
  383         sc->sc_i2c.ic_release_bus = tl_i2c_release_bus;
  384         sc->sc_i2c.ic_send_start = tl_i2c_send_start;
  385         sc->sc_i2c.ic_send_stop = tl_i2c_send_stop;
  386         sc->sc_i2c.ic_initiate_xfer = tl_i2c_initiate_xfer;
  387         sc->sc_i2c.ic_read_byte = tl_i2c_read_byte;
  388         sc->sc_i2c.ic_write_byte = tl_i2c_write_byte;
  389 
  390 #ifdef TLDEBUG
  391         printf("default values of INTreg: 0x%x\n",
  392             tl_intreg_read(sc, TL_INT_Defaults));
  393 #endif
  394 
  395         /* read mac addr */
  396         if (seeprom_bootstrap_read(&sc->sc_i2c, 0x50, 0x83, 512/*?*/,
  397                                    sc->tl_enaddr, ETHER_ADDR_LEN)) {
  398                 printf("%s: error reading Ethernet address\n",
  399                     sc->sc_dev.dv_xname);
  400                         return;
  401         }
  402         printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
  403             ether_sprintf(sc->tl_enaddr));
  404 
  405         /* Map and establish interrupts */
  406         if (pci_intr_map(pa, &intrhandle)) {
  407                 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
  408                 return;
  409         }
  410         intrstr = pci_intr_string(pa->pa_pc, intrhandle);
  411         sc->tl_if.if_softc = sc;
  412         sc->tl_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET,
  413             tl_intr, sc);
  414         if (sc->tl_ih == NULL) {
  415                 printf("%s: couldn't establish interrupt",
  416                     sc->sc_dev.dv_xname);
  417                 if (intrstr != NULL)
  418                         printf(" at %s", intrstr);
  419                 printf("\n");
  420                 return;
  421         }
  422         printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
  423 
  424         /* init these pointers, so that tl_shutdown won't try to read them */
  425         sc->Rx_list = NULL;
  426         sc->Tx_list = NULL;
  427 
  428         /* allocate DMA-safe memory for control structs */
  429         if (bus_dmamem_alloc(sc->tl_dmatag,
  430                 PAGE_SIZE, 0, PAGE_SIZE,
  431                 &sc->ctrl_segs, 1, &sc->ctrl_nsegs, BUS_DMA_NOWAIT) != 0 ||
  432             bus_dmamem_map(sc->tl_dmatag, &sc->ctrl_segs,
  433                 sc->ctrl_nsegs, PAGE_SIZE, (caddr_t*)&sc->ctrl,
  434                 BUS_DMA_NOWAIT | BUS_DMA_COHERENT) != 0) {
  435                         printf("%s: can't allocate DMA memory for lists\n",
  436                             sc->sc_dev.dv_xname);
  437                         return;
  438         }
  439         /*
  440          * Add shutdown hook so that DMA is disabled prior to reboot. Not
  441          * doing
  442          * reboot before the driver initializes.
  443          */
  444         (void) shutdownhook_establish(tl_shutdown, ifp);
  445 
  446         /*
  447          * Initialize our media structures and probe the MII.
  448          *
  449          * Note that we don't care about the media instance.  We
  450          * are expecting to have multiple PHYs on the 10/100 cards,
  451          * and on those cards we exclude the internal PHY from providing
  452          * 10baseT.  By ignoring the instance, it allows us to not have
  453          * to specify it on the command line when switching media.
  454          */
  455         sc->tl_mii.mii_ifp = ifp;
  456         sc->tl_mii.mii_readreg = tl_mii_read;
  457         sc->tl_mii.mii_writereg = tl_mii_write;
  458         sc->tl_mii.mii_statchg = tl_statchg;
  459         ifmedia_init(&sc->tl_mii.mii_media, IFM_IMASK, tl_mediachange,
  460             tl_mediastatus);
  461         mii_attach(self, &sc->tl_mii, 0xffffffff, MII_PHY_ANY,
  462             MII_OFFSET_ANY, 0);
  463         if (LIST_FIRST(&sc->tl_mii.mii_phys) == NULL) {
  464                 ifmedia_add(&sc->tl_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
  465                 ifmedia_set(&sc->tl_mii.mii_media, IFM_ETHER|IFM_NONE);
  466         } else
  467                 ifmedia_set(&sc->tl_mii.mii_media, IFM_ETHER|IFM_AUTO);
  468 
  469         /*
  470          * We can support 802.1Q VLAN-sized frames.
  471          */
  472         sc->tl_ec.ec_capabilities |= ETHERCAP_VLAN_MTU;
  473 
  474         strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
  475         ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_NOTRAILERS|IFF_MULTICAST;
  476         ifp->if_ioctl = tl_ifioctl;
  477         ifp->if_start = tl_ifstart;
  478         ifp->if_watchdog = tl_ifwatchdog;
  479         ifp->if_init = tl_init;
  480         ifp->if_stop = tl_stop;
  481         ifp->if_timer = 0;
  482         IFQ_SET_READY(&ifp->if_snd);
  483         if_attach(ifp);
  484         ether_ifattach(&(sc)->tl_if, (sc)->tl_enaddr);
  485 }
  486 
  487 static void
  488 tl_reset(sc)
  489         tl_softc_t *sc;
  490 {
  491         int i;
  492 
  493         /* read stats */
  494         if (sc->tl_if.if_flags & IFF_RUNNING) {
  495                 callout_stop(&sc->tl_tick_ch);
  496                 tl_read_stats(sc);
  497         }
  498         /* Reset adapter */
  499         TL_HR_WRITE(sc, TL_HOST_CMD,
  500             TL_HR_READ(sc, TL_HOST_CMD) | HOST_CMD_Ad_Rst);
  501         DELAY(100000);
  502         /* Disable interrupts */
  503         TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_IntOff);
  504         /* setup aregs & hash */
  505         for (i = TL_INT_Areg0; i <= TL_INT_HASH2; i = i + 4)
  506                 tl_intreg_write(sc, i, 0);
  507 #ifdef TLDEBUG_ADDR
  508         printf("Areg & hash registers: \n");
  509         for (i = TL_INT_Areg0; i <= TL_INT_HASH2; i = i + 4)
  510                 printf("    reg %x: %x\n", i, tl_intreg_read(sc, i));
  511 #endif
  512         /* Setup NetConfig */
  513         tl_intreg_write(sc, TL_INT_NetConfig,
  514             TL_NETCONFIG_1F | TL_NETCONFIG_1chn | TL_NETCONFIG_PHY_EN);
  515         /* Bsize: accept default */
  516         /* TX commit in Acommit: accept default */
  517         /* Load Ld_tmr and Ld_thr */
  518         /* Ld_tmr = 3 */
  519         TL_HR_WRITE(sc, TL_HOST_CMD, 0x3 | HOST_CMD_LdTmr);
  520         /* Ld_thr = 0 */
  521         TL_HR_WRITE(sc, TL_HOST_CMD, 0x0 | HOST_CMD_LdThr);
  522         /* Unreset MII */
  523         netsio_set(sc, TL_NETSIO_NMRST);
  524         DELAY(100000);
  525         sc->tl_mii.mii_media_status &= ~IFM_ACTIVE;
  526 }
  527 
  528 static void tl_shutdown(v)
  529         void *v;
  530 {
  531         tl_stop(v, 1);
  532 }
  533 
  534 static void tl_stop(ifp, disable)
  535         struct ifnet *ifp;
  536         int disable;
  537 {
  538         tl_softc_t *sc = ifp->if_softc;
  539         struct Tx_list *Tx;
  540         int i;
  541 
  542         if ((ifp->if_flags & IFF_RUNNING) == 0)
  543                 return;
  544         /* disable interrupts */
  545         TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_IntOff);
  546         /* stop TX and RX channels */
  547         TL_HR_WRITE(sc, TL_HOST_CMD,
  548             HOST_CMD_STOP | HOST_CMD_RT | HOST_CMD_Nes);
  549         TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_STOP);
  550         DELAY(100000);
  551 
  552         /* stop statistics reading loop, read stats */
  553         callout_stop(&sc->tl_tick_ch);
  554         tl_read_stats(sc);
  555 
  556         /* Down the MII. */
  557         mii_down(&sc->tl_mii);
  558 
  559         /* deallocate memory allocations */
  560         if (sc->Rx_list) {
  561                 for (i=0; i< TL_NBUF; i++) {
  562                         if (sc->Rx_list[i].m) {
  563                                 bus_dmamap_unload(sc->tl_dmatag,
  564                                     sc->Rx_list[i].m_dmamap);
  565                                 m_freem(sc->Rx_list[i].m);
  566                         }
  567                         bus_dmamap_destroy(sc->tl_dmatag,
  568                             sc->Rx_list[i].m_dmamap);
  569                         sc->Rx_list[i].m = NULL;
  570                 }
  571                 free(sc->Rx_list, M_DEVBUF);
  572                 sc->Rx_list = NULL;
  573                 bus_dmamap_unload(sc->tl_dmatag, sc->Rx_dmamap);
  574                 bus_dmamap_destroy(sc->tl_dmatag, sc->Rx_dmamap);
  575                 sc->hw_Rx_list = NULL;
  576                 while ((Tx = sc->active_Tx) != NULL) {
  577                         Tx->hw_list->stat = 0;
  578                         bus_dmamap_unload(sc->tl_dmatag, Tx->m_dmamap);
  579                         bus_dmamap_destroy(sc->tl_dmatag, Tx->m_dmamap);
  580                         m_freem(Tx->m);
  581                         sc->active_Tx = Tx->next;
  582                         Tx->next = sc->Free_Tx;
  583                         sc->Free_Tx = Tx;
  584                 }
  585                 sc->last_Tx = NULL;
  586                 free(sc->Tx_list, M_DEVBUF);
  587                 sc->Tx_list = NULL;
  588                 bus_dmamap_unload(sc->tl_dmatag, sc->Tx_dmamap);
  589                 bus_dmamap_destroy(sc->tl_dmatag, sc->Tx_dmamap);
  590                 sc->hw_Tx_list = NULL;
  591         }
  592         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
  593         ifp->if_timer = 0;
  594         sc->tl_mii.mii_media_status &= ~IFM_ACTIVE;
  595 }
  596 
  597 static void tl_restart(v)
  598         void *v;
  599 {
  600         tl_init(v);
  601 }
  602 
  603 static int tl_init(ifp)
  604         struct ifnet *ifp;
  605 {
  606         tl_softc_t *sc = ifp->if_softc;
  607         int i, s, error;
  608         char *errstring;
  609         char *nullbuf;
  610 
  611         s = splnet();
  612         /* cancel any pending IO */
  613         tl_stop(ifp, 1);
  614         tl_reset(sc);
  615         if ((sc->tl_if.if_flags & IFF_UP) == 0) {
  616                 splx(s);
  617                 return 0;
  618         }
  619         /* Set various register to reasonable value */
  620         /* setup NetCmd in promisc mode if needed */
  621         i = (ifp->if_flags & IFF_PROMISC) ? TL_NETCOMMAND_CAF : 0;
  622         tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetCmd,
  623             TL_NETCOMMAND_NRESET | TL_NETCOMMAND_NWRAP | i);
  624         /* Max receive size : MCLBYTES */
  625         tl_intreg_write_byte(sc, TL_INT_MISC + TL_MISC_MaxRxL, MCLBYTES & 0xff);
  626         tl_intreg_write_byte(sc, TL_INT_MISC + TL_MISC_MaxRxH,
  627             (MCLBYTES >> 8) & 0xff);
  628 
  629         /* init MAC addr */
  630         for (i = 0; i < ETHER_ADDR_LEN; i++)
  631                 tl_intreg_write_byte(sc, TL_INT_Areg0 + i , sc->tl_enaddr[i]);
  632         /* add multicast filters */
  633         tl_addr_filter(sc);
  634 #ifdef TLDEBUG_ADDR
  635         printf("Wrote Mac addr, Areg & hash registers are now: \n");
  636         for (i = TL_INT_Areg0; i <= TL_INT_HASH2; i = i + 4)
  637                 printf("    reg %x: %x\n", i, tl_intreg_read(sc, i));
  638 #endif
  639 
  640         /* Pre-allocate receivers mbuf, make the lists */
  641         sc->Rx_list = malloc(sizeof(struct Rx_list) * TL_NBUF, M_DEVBUF,
  642             M_NOWAIT|M_ZERO);
  643         sc->Tx_list = malloc(sizeof(struct Tx_list) * TL_NBUF, M_DEVBUF,
  644             M_NOWAIT|M_ZERO);
  645         if (sc->Rx_list == NULL || sc->Tx_list == NULL) {
  646                 errstring = "out of memory for lists";
  647                 error = ENOMEM;
  648                 goto bad;
  649         }
  650         error = bus_dmamap_create(sc->tl_dmatag,
  651             sizeof(struct tl_Rx_list) * TL_NBUF, 1,
  652             sizeof(struct tl_Rx_list) * TL_NBUF, 0, BUS_DMA_WAITOK,
  653             &sc->Rx_dmamap);
  654         if (error == 0)
  655                 error = bus_dmamap_create(sc->tl_dmatag,
  656                     sizeof(struct tl_Tx_list) * TL_NBUF, 1,
  657                     sizeof(struct tl_Tx_list) * TL_NBUF, 0, BUS_DMA_WAITOK,
  658                     &sc->Tx_dmamap);
  659         if (error == 0)
  660                 error = bus_dmamap_create(sc->tl_dmatag, ETHER_MIN_TX, 1,
  661                     ETHER_MIN_TX, 0, BUS_DMA_WAITOK,
  662                     &sc->null_dmamap);
  663         if (error) {
  664                 errstring = "can't allocate DMA maps for lists";
  665                 goto bad;
  666         }
  667         memset(sc->ctrl, 0, PAGE_SIZE);
  668         sc->hw_Rx_list = (void *)sc->ctrl;
  669         sc->hw_Tx_list =
  670             (void *)(sc->ctrl + sizeof(struct tl_Rx_list) * TL_NBUF);
  671         nullbuf = sc->ctrl + sizeof(struct tl_Rx_list) * TL_NBUF +
  672             sizeof(struct tl_Tx_list) * TL_NBUF;
  673         error = bus_dmamap_load(sc->tl_dmatag, sc->Rx_dmamap,
  674             sc->hw_Rx_list, sizeof(struct tl_Rx_list) * TL_NBUF, NULL,
  675             BUS_DMA_WAITOK);
  676         if (error == 0)
  677                 error = bus_dmamap_load(sc->tl_dmatag, sc->Tx_dmamap,
  678                     sc->hw_Tx_list, sizeof(struct tl_Tx_list) * TL_NBUF, NULL,
  679                     BUS_DMA_WAITOK);
  680         if (error == 0)
  681                 error = bus_dmamap_load(sc->tl_dmatag, sc->null_dmamap,
  682                     nullbuf, ETHER_MIN_TX, NULL, BUS_DMA_WAITOK);
  683         if (error) {
  684                 errstring = "can't DMA map DMA memory for lists";
  685                 goto bad;
  686         }
  687         for (i=0; i< TL_NBUF; i++) {
  688                 error = bus_dmamap_create(sc->tl_dmatag, MCLBYTES,
  689                     1, MCLBYTES, 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
  690                     &sc->Rx_list[i].m_dmamap);
  691                 if (error == 0) {
  692                         error = bus_dmamap_create(sc->tl_dmatag, MCLBYTES,
  693                             TL_NSEG, MCLBYTES, 0,
  694                             BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW,
  695                             &sc->Tx_list[i].m_dmamap);
  696                 }
  697                 if (error) {
  698                         errstring = "can't allocate DMA maps for mbufs";
  699                         goto bad;
  700                 }
  701                 sc->Rx_list[i].hw_list = &sc->hw_Rx_list[i];
  702                 sc->Rx_list[i].hw_listaddr = sc->Rx_dmamap->dm_segs[0].ds_addr
  703                     + sizeof(struct tl_Rx_list) * i;
  704                 sc->Tx_list[i].hw_list = &sc->hw_Tx_list[i];
  705                 sc->Tx_list[i].hw_listaddr = sc->Tx_dmamap->dm_segs[0].ds_addr
  706                     + sizeof(struct tl_Tx_list) * i;
  707                 if (tl_add_RxBuff(sc, &sc->Rx_list[i], NULL) == 0) {
  708                         errstring = "out of mbuf for receive list";
  709                         error = ENOMEM;
  710                         goto bad;
  711                 }
  712                 if (i > 0) { /* chain the list */
  713                         sc->Rx_list[i - 1].next = &sc->Rx_list[i];
  714                         sc->hw_Rx_list[i - 1].fwd =
  715                             htole32(sc->Rx_list[i].hw_listaddr);
  716                         sc->Tx_list[i - 1].next = &sc->Tx_list[i];
  717                 }
  718         }
  719         sc->hw_Rx_list[TL_NBUF - 1].fwd = 0;
  720         sc->Rx_list[TL_NBUF - 1].next = NULL;
  721         sc->hw_Tx_list[TL_NBUF - 1].fwd = 0;
  722         sc->Tx_list[TL_NBUF - 1].next = NULL;
  723 
  724         sc->active_Rx = &sc->Rx_list[0];
  725         sc->last_Rx   = &sc->Rx_list[TL_NBUF - 1];
  726         sc->active_Tx = sc->last_Tx = NULL;
  727         sc->Free_Tx   = &sc->Tx_list[0];
  728         bus_dmamap_sync(sc->tl_dmatag, sc->Rx_dmamap, 0,
  729             sizeof(struct tl_Rx_list) * TL_NBUF,
  730             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  731         bus_dmamap_sync(sc->tl_dmatag, sc->Tx_dmamap, 0,
  732             sizeof(struct tl_Tx_list) * TL_NBUF,
  733             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  734         bus_dmamap_sync(sc->tl_dmatag, sc->null_dmamap, 0, ETHER_MIN_TX,
  735             BUS_DMASYNC_PREWRITE);
  736 
  737         /* set media */
  738         mii_mediachg(&sc->tl_mii);
  739 
  740         /* start ticks calls */
  741         callout_reset(&sc->tl_tick_ch, hz, tl_ticks, sc);
  742         /* write address of Rx list and enable interrupts */
  743         TL_HR_WRITE(sc, TL_HOST_CH_PARM, sc->Rx_list[0].hw_listaddr);
  744         TL_HR_WRITE(sc, TL_HOST_CMD,
  745             HOST_CMD_GO | HOST_CMD_RT | HOST_CMD_Nes | HOST_CMD_IntOn);
  746         sc->tl_if.if_flags |= IFF_RUNNING;
  747         sc->tl_if.if_flags &= ~IFF_OACTIVE;
  748         return 0;
  749 bad:
  750         printf("%s: %s\n", sc->sc_dev.dv_xname, errstring);
  751         splx(s);
  752         return error;
  753 }
  754 
  755 
  756 static u_int32_t
  757 tl_intreg_read(sc, reg)
  758         tl_softc_t *sc;
  759         u_int32_t reg;
  760 {
  761         TL_HR_WRITE(sc, TL_HOST_INTR_DIOADR, reg & TL_HOST_DIOADR_MASK);
  762         return TL_HR_READ(sc, TL_HOST_DIO_DATA);
  763 }
  764 
  765 static u_int8_t
  766 tl_intreg_read_byte(sc, reg)
  767         tl_softc_t *sc;
  768         u_int32_t reg;
  769 {
  770         TL_HR_WRITE(sc, TL_HOST_INTR_DIOADR,
  771             (reg & (~0x07)) & TL_HOST_DIOADR_MASK);
  772         return TL_HR_READ_BYTE(sc, TL_HOST_DIO_DATA + (reg & 0x07));
  773 }
  774 
  775 static void
  776 tl_intreg_write(sc, reg, val)
  777         tl_softc_t *sc;
  778         u_int32_t reg;
  779         u_int32_t val;
  780 {
  781         TL_HR_WRITE(sc, TL_HOST_INTR_DIOADR, reg & TL_HOST_DIOADR_MASK);
  782         TL_HR_WRITE(sc, TL_HOST_DIO_DATA, val);
  783 }
  784 
  785 static void
  786 tl_intreg_write_byte(sc, reg, val)
  787         tl_softc_t *sc;
  788         u_int32_t reg;
  789         u_int8_t val;
  790 {
  791         TL_HR_WRITE(sc, TL_HOST_INTR_DIOADR,
  792             (reg & (~0x03)) & TL_HOST_DIOADR_MASK);
  793         TL_HR_WRITE_BYTE(sc, TL_HOST_DIO_DATA + (reg & 0x03), val);
  794 }
  795 
  796 void
  797 tl_mii_sync(sc)
  798         struct tl_softc *sc;
  799 {
  800         int i;
  801 
  802         netsio_clr(sc, TL_NETSIO_MTXEN);
  803         for (i = 0; i < 32; i++) {
  804                 netsio_clr(sc, TL_NETSIO_MCLK);
  805                 netsio_set(sc, TL_NETSIO_MCLK);
  806         }
  807 }
  808 
  809 void
  810 tl_mii_sendbits(sc, data, nbits)
  811         struct tl_softc *sc;
  812         u_int32_t data;
  813         int nbits;
  814 {
  815         int i;
  816 
  817         netsio_set(sc, TL_NETSIO_MTXEN);
  818         for (i = 1 << (nbits - 1); i; i = i >>  1) {
  819                 netsio_clr(sc, TL_NETSIO_MCLK);
  820                 netsio_read(sc, TL_NETSIO_MCLK);
  821                 if (data & i)
  822                         netsio_set(sc, TL_NETSIO_MDATA);
  823                 else
  824                         netsio_clr(sc, TL_NETSIO_MDATA);
  825                 netsio_set(sc, TL_NETSIO_MCLK);
  826                 netsio_read(sc, TL_NETSIO_MCLK);
  827         }
  828 }
  829 
  830 int
  831 tl_mii_read(self, phy, reg)
  832         struct device *self;
  833         int phy, reg;
  834 {
  835         struct tl_softc *sc = (struct tl_softc *)self;
  836         int val = 0, i, err;
  837 
  838         /*
  839          * Read the PHY register by manually driving the MII control lines.
  840          */
  841 
  842         tl_mii_sync(sc);
  843         tl_mii_sendbits(sc, MII_COMMAND_START, 2);
  844         tl_mii_sendbits(sc, MII_COMMAND_READ, 2);
  845         tl_mii_sendbits(sc, phy, 5);
  846         tl_mii_sendbits(sc, reg, 5);
  847 
  848         netsio_clr(sc, TL_NETSIO_MTXEN);
  849         netsio_clr(sc, TL_NETSIO_MCLK);
  850         netsio_set(sc, TL_NETSIO_MCLK);
  851         netsio_clr(sc, TL_NETSIO_MCLK);
  852 
  853         err = netsio_read(sc, TL_NETSIO_MDATA);
  854         netsio_set(sc, TL_NETSIO_MCLK);
  855 
  856         /* Even if an error occurs, must still clock out the cycle. */
  857         for (i = 0; i < 16; i++) {
  858                 val <<= 1;
  859                 netsio_clr(sc, TL_NETSIO_MCLK);
  860                 if (err == 0 && netsio_read(sc, TL_NETSIO_MDATA))
  861                         val |= 1;
  862                 netsio_set(sc, TL_NETSIO_MCLK);
  863         }
  864         netsio_clr(sc, TL_NETSIO_MCLK);
  865         netsio_set(sc, TL_NETSIO_MCLK);
  866 
  867         return (err ? 0 : val);
  868 }
  869 
  870 void
  871 tl_mii_write(self, phy, reg, val)
  872         struct device *self;
  873         int phy, reg, val;
  874 {
  875         struct tl_softc *sc = (struct tl_softc *)self;
  876 
  877         /*
  878          * Write the PHY register by manually driving the MII control lines.
  879          */
  880 
  881         tl_mii_sync(sc);
  882         tl_mii_sendbits(sc, MII_COMMAND_START, 2);
  883         tl_mii_sendbits(sc, MII_COMMAND_WRITE, 2);
  884         tl_mii_sendbits(sc, phy, 5);
  885         tl_mii_sendbits(sc, reg, 5);
  886         tl_mii_sendbits(sc, MII_COMMAND_ACK, 2);
  887         tl_mii_sendbits(sc, val, 16);
  888 
  889         netsio_clr(sc, TL_NETSIO_MCLK);
  890         netsio_set(sc, TL_NETSIO_MCLK);
  891 }
  892 
  893 void
  894 tl_statchg(self)
  895         struct device *self;
  896 {
  897         tl_softc_t *sc = (struct tl_softc *)self;
  898         u_int32_t reg;
  899 
  900 #ifdef TLDEBUG
  901         printf("tl_statchg, media %x\n", sc->tl_ifmedia.ifm_media);
  902 #endif
  903 
  904         /*
  905          * We must keep the ThunderLAN and the PHY in sync as
  906          * to the status of full-duplex!
  907          */
  908         reg = tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetCmd);
  909         if (sc->tl_mii.mii_media_active & IFM_FDX)
  910                 reg |= TL_NETCOMMAND_DUPLEX;
  911         else
  912                 reg &= ~TL_NETCOMMAND_DUPLEX;
  913         tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetCmd, reg);
  914 }
  915 
  916 /********** I2C glue **********/
  917 
  918 static int
  919 tl_i2c_acquire_bus(void *cookie, int flags)
  920 {
  921 
  922         /* private bus */
  923         return (0);
  924 }
  925 
  926 static void
  927 tl_i2c_release_bus(void *cookie, int flags)
  928 {
  929 
  930         /* private bus */
  931 }
  932 
  933 static int
  934 tl_i2c_send_start(void *cookie, int flags)
  935 {
  936 
  937         return (i2c_bitbang_send_start(cookie, flags, &tl_i2cbb_ops));
  938 }
  939 
  940 static int
  941 tl_i2c_send_stop(void *cookie, int flags)
  942 {
  943 
  944         return (i2c_bitbang_send_stop(cookie, flags, &tl_i2cbb_ops));
  945 }
  946 
  947 static int
  948 tl_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
  949 {
  950 
  951         return (i2c_bitbang_initiate_xfer(cookie, addr, flags, &tl_i2cbb_ops));
  952 }
  953 
  954 static int
  955 tl_i2c_read_byte(void *cookie, uint8_t *valp, int flags)
  956 {
  957 
  958         return (i2c_bitbang_read_byte(cookie, valp, flags, &tl_i2cbb_ops));
  959 }
  960 
  961 static int
  962 tl_i2c_write_byte(void *cookie, uint8_t val, int flags)
  963 {
  964 
  965         return (i2c_bitbang_write_byte(cookie, val, flags, &tl_i2cbb_ops));
  966 }
  967 
  968 /********** I2C bit-bang glue **********/
  969 
  970 static void
  971 tl_i2cbb_set_bits(void *cookie, uint32_t bits)
  972 {
  973         struct tl_softc *sc = cookie;
  974         uint8_t reg;
  975 
  976         reg = tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetSio);
  977         reg = (reg & ~(TL_NETSIO_EDATA|TL_NETSIO_ECLOCK)) | bits;
  978         tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetSio, reg);
  979 }
  980 
  981 static void
  982 tl_i2cbb_set_dir(void *cookie, uint32_t bits)
  983 {
  984         struct tl_softc *sc = cookie;
  985         uint8_t reg;
  986 
  987         reg = tl_intreg_read_byte(sc, TL_INT_NET + TL_INT_NetSio);
  988         reg = (reg & ~TL_NETSIO_ETXEN) | bits;
  989         tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetSio, reg);
  990 }
  991 
  992 static uint32_t
  993 tl_i2cbb_read(void *cookie)
  994 {
  995 
  996         return (tl_intreg_read_byte(cookie, TL_INT_NET + TL_INT_NetSio));
  997 }
  998 
  999 /********** End of I2C stuff **********/
 1000 
 1001 static int
 1002 tl_intr(v)
 1003         void *v;
 1004 {
 1005         tl_softc_t *sc = v;
 1006         struct ifnet *ifp = &sc->tl_if;
 1007         struct Rx_list *Rx;
 1008         struct Tx_list *Tx;
 1009         struct mbuf *m;
 1010         u_int32_t int_type, int_reg;
 1011         int ack = 0;
 1012         int size;
 1013 
 1014         int_reg = TL_HR_READ(sc, TL_HOST_INTR_DIOADR);
 1015         int_type = int_reg  & TL_INTR_MASK;
 1016         if (int_type == 0)
 1017                 return 0;
 1018 #if defined(TLDEBUG_RX) || defined(TLDEBUG_TX)
 1019         printf("%s: interrupt type %x, intr_reg %x\n", sc->sc_dev.dv_xname,
 1020             int_type, int_reg);
 1021 #endif
 1022         /* disable interrupts */
 1023         TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_IntOff);
 1024         switch(int_type & TL_INTR_MASK) {
 1025         case TL_INTR_RxEOF:
 1026                 bus_dmamap_sync(sc->tl_dmatag, sc->Rx_dmamap, 0,
 1027                     sizeof(struct tl_Rx_list) * TL_NBUF,
 1028                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 1029                 while(le32toh(sc->active_Rx->hw_list->stat) &
 1030                     TL_RX_CSTAT_CPLT) {
 1031                         /* dequeue and requeue at end of list */
 1032                         ack++;
 1033                         Rx = sc->active_Rx;
 1034                         sc->active_Rx = Rx->next;
 1035                         bus_dmamap_sync(sc->tl_dmatag, Rx->m_dmamap, 0,
 1036                             Rx->m_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
 1037                         bus_dmamap_unload(sc->tl_dmatag, Rx->m_dmamap);
 1038                         m = Rx->m;
 1039                         size = le32toh(Rx->hw_list->stat) >> 16;
 1040 #ifdef TLDEBUG_RX
 1041                         printf("tl_intr: RX list complete, Rx %p, size=%d\n",
 1042                             Rx, size);
 1043 #endif
 1044                         if (tl_add_RxBuff(sc, Rx, m ) == 0) {
 1045                                 /*
 1046                                  * No new mbuf, reuse the same. This means
 1047                                  * that this packet
 1048                                  * is lost
 1049                                  */
 1050                                 m = NULL;
 1051 #ifdef TL_PRIV_STATS
 1052                                 sc->ierr_nomem++;
 1053 #endif
 1054 #ifdef TLDEBUG
 1055                                 printf("%s: out of mbuf, lost input packet\n",
 1056                                     sc->sc_dev.dv_xname);
 1057 #endif
 1058                         }
 1059                         Rx->next = NULL;
 1060                         Rx->hw_list->fwd = 0;
 1061                         sc->last_Rx->hw_list->fwd = htole32(Rx->hw_listaddr);
 1062                         sc->last_Rx->next = Rx;
 1063                         sc->last_Rx = Rx;
 1064 
 1065                         /* deliver packet */
 1066                         if (m) {
 1067                                 if (size < sizeof(struct ether_header)) {
 1068                                         m_freem(m);
 1069                                         continue;
 1070                                 }
 1071                                 m->m_pkthdr.rcvif = ifp;
 1072                                 m->m_pkthdr.len = m->m_len = size;
 1073 #ifdef TLDEBUG_RX
 1074                                 { struct ether_header *eh =
 1075                                     mtod(m, struct ether_header *);
 1076                                 printf("tl_intr: Rx packet:\n");
 1077                                 ether_printheader(eh); }
 1078 #endif
 1079 #if NBPFILTER > 0
 1080                                 if (ifp->if_bpf)
 1081                                         bpf_mtap(ifp->if_bpf, m);
 1082 #endif /* NBPFILTER > 0 */
 1083                                 (*ifp->if_input)(ifp, m);
 1084                         }
 1085                 }
 1086                 bus_dmamap_sync(sc->tl_dmatag, sc->Rx_dmamap, 0,
 1087                     sizeof(struct tl_Rx_list) * TL_NBUF,
 1088                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1089 #ifdef TLDEBUG_RX
 1090                 printf("TL_INTR_RxEOF: ack %d\n", ack);
 1091 #else
 1092                 if (ack == 0) {
 1093                         printf("%s: EOF intr without anything to read !\n",
 1094                             sc->sc_dev.dv_xname);
 1095                         tl_reset(sc);
 1096                         /* shedule reinit of the board */
 1097                         callout_reset(&sc->tl_restart_ch, 1, tl_restart, sc);
 1098                         return(1);
 1099                 }
 1100 #endif
 1101                 break;
 1102         case TL_INTR_RxEOC:
 1103                 ack++;
 1104                 bus_dmamap_sync(sc->tl_dmatag, sc->Rx_dmamap, 0,
 1105                     sizeof(struct tl_Rx_list) * TL_NBUF,
 1106                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 1107 #ifdef TLDEBUG_RX
 1108                 printf("TL_INTR_RxEOC: ack %d\n", ack);
 1109 #endif
 1110 #ifdef DIAGNOSTIC
 1111                 if (le32toh(sc->active_Rx->hw_list->stat) & TL_RX_CSTAT_CPLT) {
 1112                         printf("%s: Rx EOC interrupt and active Tx list not "
 1113                             "cleared\n", sc->sc_dev.dv_xname);
 1114                         return 0;
 1115                 } else
 1116 #endif
 1117                 {
 1118                 /*
 1119                  * write address of Rx list and send Rx GO command, ack
 1120                  * interrupt and enable interrupts in one command
 1121                  */
 1122                 TL_HR_WRITE(sc, TL_HOST_CH_PARM, sc->active_Rx->hw_listaddr);
 1123                 TL_HR_WRITE(sc, TL_HOST_CMD,
 1124                     HOST_CMD_GO | HOST_CMD_RT | HOST_CMD_Nes | ack | int_type |
 1125                     HOST_CMD_ACK | HOST_CMD_IntOn);
 1126                 return 1;
 1127                 }
 1128         case TL_INTR_TxEOF:
 1129         case TL_INTR_TxEOC:
 1130                 bus_dmamap_sync(sc->tl_dmatag, sc->Tx_dmamap, 0,
 1131                     sizeof(struct tl_Tx_list) * TL_NBUF,
 1132                     BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 1133                 while ((Tx = sc->active_Tx) != NULL) {
 1134                         if((le32toh(Tx->hw_list->stat) & TL_TX_CSTAT_CPLT) == 0)
 1135                                 break;
 1136                         ack++;
 1137 #ifdef TLDEBUG_TX
 1138                         printf("TL_INTR_TxEOC: list 0x%x done\n",
 1139                             (int)Tx->hw_listaddr);
 1140 #endif
 1141                         Tx->hw_list->stat = 0;
 1142                         bus_dmamap_sync(sc->tl_dmatag, Tx->m_dmamap, 0,
 1143                             Tx->m_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE);
 1144                         bus_dmamap_unload(sc->tl_dmatag, Tx->m_dmamap);
 1145                         m_freem(Tx->m);
 1146                         Tx->m = NULL;
 1147                         sc->active_Tx = Tx->next;
 1148                         if (sc->active_Tx == NULL)
 1149                                 sc->last_Tx = NULL;
 1150                         Tx->next = sc->Free_Tx;
 1151                         sc->Free_Tx = Tx;
 1152                 }
 1153                 bus_dmamap_sync(sc->tl_dmatag, sc->Tx_dmamap, 0,
 1154                     sizeof(struct tl_Tx_list) * TL_NBUF,
 1155                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1156                 /* if this was an EOC, ACK immediatly */
 1157                 if (ack)
 1158                         sc->tl_if.if_flags &= ~IFF_OACTIVE;
 1159                 if (int_type == TL_INTR_TxEOC) {
 1160 #ifdef TLDEBUG_TX
 1161                         printf("TL_INTR_TxEOC: ack %d (will be set to 1)\n",
 1162                             ack);
 1163 #endif
 1164                         TL_HR_WRITE(sc, TL_HOST_CMD, 1 | int_type |
 1165                             HOST_CMD_ACK | HOST_CMD_IntOn);
 1166                         if ( sc->active_Tx != NULL) {
 1167                                 /* needs a Tx go command */
 1168                                 TL_HR_WRITE(sc, TL_HOST_CH_PARM,
 1169                                     sc->active_Tx->hw_listaddr);
 1170                                 TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_GO);
 1171                         }
 1172                         sc->tl_if.if_timer = 0;
 1173                         if (IFQ_IS_EMPTY(&sc->tl_if.if_snd) == 0)
 1174                                 tl_ifstart(&sc->tl_if);
 1175                         return 1;
 1176                 }
 1177 #ifdef TLDEBUG
 1178                 else {
 1179                         printf("TL_INTR_TxEOF: ack %d\n", ack);
 1180                 }
 1181 #endif
 1182                 sc->tl_if.if_timer = 0;
 1183                 if (IFQ_IS_EMPTY(&sc->tl_if.if_snd) == 0)
 1184                         tl_ifstart(&sc->tl_if);
 1185                 break;
 1186         case TL_INTR_Stat:
 1187                 ack++;
 1188 #ifdef TLDEBUG
 1189                 printf("TL_INTR_Stat: ack %d\n", ack);
 1190 #endif
 1191                 tl_read_stats(sc);
 1192                 break;
 1193         case TL_INTR_Adc:
 1194                 if (int_reg & TL_INTVec_MASK) {
 1195                         /* adapter check conditions */
 1196                         printf("%s: check condition, intvect=0x%x, "
 1197                             "ch_param=0x%x\n", sc->sc_dev.dv_xname,
 1198                             int_reg & TL_INTVec_MASK,
 1199                             TL_HR_READ(sc, TL_HOST_CH_PARM));
 1200                         tl_reset(sc);
 1201                         /* shedule reinit of the board */
 1202                         callout_reset(&sc->tl_restart_ch, 1, tl_restart, sc);
 1203                         return(1);
 1204                 } else {
 1205                         u_int8_t netstat;
 1206                         /* Network status */
 1207                         netstat =
 1208                             tl_intreg_read_byte(sc, TL_INT_NET+TL_INT_NetSts);
 1209                         printf("%s: network status, NetSts=%x\n",
 1210                             sc->sc_dev.dv_xname, netstat);
 1211                         /* Ack interrupts */
 1212                         tl_intreg_write_byte(sc, TL_INT_NET+TL_INT_NetSts,
 1213                             netstat);
 1214                         ack++;
 1215                 }
 1216                 break;
 1217         default:
 1218                 printf("%s: unhandled interrupt code %x!\n",
 1219                     sc->sc_dev.dv_xname, int_type);
 1220                 ack++;
 1221         }
 1222 
 1223         if (ack) {
 1224                 /* Ack the interrupt and enable interrupts */
 1225                 TL_HR_WRITE(sc, TL_HOST_CMD, ack | int_type | HOST_CMD_ACK |
 1226                     HOST_CMD_IntOn);
 1227                 return 1;
 1228         }
 1229         /* ack = 0 ; interrupt was perhaps not our. Just enable interrupts */
 1230         TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_IntOn);
 1231         return 0;
 1232 }
 1233 
 1234 static int
 1235 tl_ifioctl(ifp, cmd, data)
 1236         struct ifnet *ifp;
 1237         ioctl_cmd_t cmd;
 1238         caddr_t data;
 1239 {
 1240         struct tl_softc *sc = ifp->if_softc;
 1241         struct ifreq *ifr = (struct ifreq *)data;
 1242         int s, error;
 1243 
 1244         s = splnet();
 1245         switch(cmd) {
 1246         case SIOCSIFMEDIA:
 1247         case SIOCGIFMEDIA:
 1248                 error = ifmedia_ioctl(ifp, ifr, &sc->tl_mii.mii_media, cmd);
 1249                 break;
 1250         default:
 1251                 error = ether_ioctl(ifp, cmd, data);
 1252                 if (error == ENETRESET) {
 1253                         tl_addr_filter(sc);
 1254                         error = 0;
 1255                 }
 1256         }
 1257         splx(s);
 1258         return error;
 1259 }
 1260 
 1261 static void
 1262 tl_ifstart(ifp)
 1263         struct ifnet *ifp;
 1264 {
 1265         tl_softc_t *sc = ifp->if_softc;
 1266         struct mbuf *mb_head;
 1267         struct Tx_list *Tx;
 1268         int segment, size;
 1269         int again, error;
 1270 
 1271         if ((sc->tl_if.if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
 1272                 return;
 1273 txloop:
 1274         /* If we don't have more space ... */
 1275         if (sc->Free_Tx == NULL) {
 1276 #ifdef TLDEBUG
 1277                 printf("tl_ifstart: No free TX list\n");
 1278 #endif
 1279                 sc->tl_if.if_flags |= IFF_OACTIVE;
 1280                 return;
 1281         }
 1282         /* Grab a paquet for output */
 1283         IFQ_DEQUEUE(&ifp->if_snd, mb_head);
 1284         if (mb_head == NULL) {
 1285 #ifdef TLDEBUG_TX
 1286                 printf("tl_ifstart: nothing to send\n");
 1287 #endif
 1288                 return;
 1289         }
 1290         Tx = sc->Free_Tx;
 1291         sc->Free_Tx = Tx->next;
 1292         Tx->next = NULL;
 1293         again = 0;
 1294         /*
 1295          * Go through each of the mbufs in the chain and initialize
 1296          * the transmit list descriptors with the physical address
 1297          * and size of the mbuf.
 1298          */
 1299 tbdinit:
 1300         memset(Tx->hw_list, 0, sizeof(struct tl_Tx_list));
 1301         Tx->m = mb_head;
 1302         size = mb_head->m_pkthdr.len;
 1303         if ((error = bus_dmamap_load_mbuf(sc->tl_dmatag, Tx->m_dmamap, mb_head,
 1304             BUS_DMA_NOWAIT)) || (size < ETHER_MIN_TX &&
 1305             Tx->m_dmamap->dm_nsegs == TL_NSEG)) {
 1306                 struct mbuf *mn;
 1307                 /*
 1308                  * We ran out of segments, or we will. We have to recopy this
 1309                  * mbuf chain first.
 1310                  */
 1311                  if (error == 0)
 1312                         bus_dmamap_unload(sc->tl_dmatag, Tx->m_dmamap);
 1313                  if (again) {
 1314                         /* already copyed, can't do much more */
 1315                         m_freem(mb_head);
 1316                         goto bad;
 1317                 }
 1318                 again = 1;
 1319 #ifdef TLDEBUG_TX
 1320                 printf("tl_ifstart: need to copy mbuf\n");
 1321 #endif
 1322 #ifdef TL_PRIV_STATS
 1323                 sc->oerr_mcopy++;
 1324 #endif
 1325                 MGETHDR(mn, M_DONTWAIT, MT_DATA);
 1326                 if (mn == NULL) {
 1327                         m_freem(mb_head);
 1328                         goto bad;
 1329                 }
 1330                 if (mb_head->m_pkthdr.len > MHLEN) {
 1331                         MCLGET(mn, M_DONTWAIT);
 1332                         if ((mn->m_flags & M_EXT) == 0) {
 1333                                 m_freem(mn);
 1334                                 m_freem(mb_head);
 1335                                 goto bad;
 1336                         }
 1337                 }
 1338                 m_copydata(mb_head, 0, mb_head->m_pkthdr.len,
 1339                     mtod(mn, caddr_t));
 1340                 mn->m_pkthdr.len = mn->m_len = mb_head->m_pkthdr.len;
 1341                 m_freem(mb_head);
 1342                 mb_head = mn;
 1343                 goto tbdinit;
 1344         }
 1345         for (segment = 0; segment < Tx->m_dmamap->dm_nsegs; segment++) {
 1346                 Tx->hw_list->seg[segment].data_addr =
 1347                     htole32(Tx->m_dmamap->dm_segs[segment].ds_addr);
 1348                 Tx->hw_list->seg[segment].data_count =
 1349                     htole32(Tx->m_dmamap->dm_segs[segment].ds_len);
 1350         }
 1351         bus_dmamap_sync(sc->tl_dmatag, Tx->m_dmamap, 0,
 1352             Tx->m_dmamap->dm_mapsize,
 1353             BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1354         /* We are at end of mbuf chain. check the size and
 1355          * see if it needs to be extended
 1356          */
 1357         if (size < ETHER_MIN_TX) {
 1358 #ifdef DIAGNOSTIC
 1359                 if (segment >= TL_NSEG) {
 1360                         panic("tl_ifstart: to much segmets (%d)", segment);
 1361                 }
 1362 #endif
 1363                 /*
 1364                  * add the nullbuf in the seg
 1365                  */
 1366                 Tx->hw_list->seg[segment].data_count =
 1367                     htole32(ETHER_MIN_TX - size);
 1368                 Tx->hw_list->seg[segment].data_addr =
 1369                     htole32(sc->null_dmamap->dm_segs[0].ds_addr);
 1370                 size = ETHER_MIN_TX;
 1371                 segment++;
 1372         }
 1373         /* The list is done, finish the list init */
 1374         Tx->hw_list->seg[segment - 1].data_count |=
 1375             htole32(TL_LAST_SEG);
 1376         Tx->hw_list->stat = htole32((size << 16) | 0x3000);
 1377 #ifdef TLDEBUG_TX
 1378         printf("%s: sending, Tx : stat = 0x%x\n", sc->sc_dev.dv_xname,
 1379             le32toh(Tx->hw_list->stat));
 1380 #if 0
 1381         for(segment = 0; segment < TL_NSEG; segment++) {
 1382                 printf("    seg %d addr 0x%x len 0x%x\n",
 1383                     segment,
 1384                     le32toh(Tx->hw_list->seg[segment].data_addr),
 1385                     le32toh(Tx->hw_list->seg[segment].data_count));
 1386         }
 1387 #endif
 1388 #endif
 1389         if (sc->active_Tx == NULL) {
 1390                 sc->active_Tx = sc->last_Tx = Tx;
 1391 #ifdef TLDEBUG_TX
 1392                 printf("%s: Tx GO, addr=0x%ux\n", sc->sc_dev.dv_xname,
 1393                     (int)Tx->hw_listaddr);
 1394 #endif
 1395                 bus_dmamap_sync(sc->tl_dmatag, sc->Tx_dmamap, 0,
 1396                     sizeof(struct tl_Tx_list) * TL_NBUF,
 1397                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1398                 TL_HR_WRITE(sc, TL_HOST_CH_PARM, Tx->hw_listaddr);
 1399                 TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_GO);
 1400         } else {
 1401 #ifdef TLDEBUG_TX
 1402                 printf("%s: Tx addr=0x%ux queued\n", sc->sc_dev.dv_xname,
 1403                     (int)Tx->hw_listaddr);
 1404 #endif
 1405                 sc->last_Tx->hw_list->fwd = htole32(Tx->hw_listaddr);
 1406                 bus_dmamap_sync(sc->tl_dmatag, sc->Tx_dmamap, 0,
 1407                     sizeof(struct tl_Tx_list) * TL_NBUF,
 1408                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 1409                 sc->last_Tx->next = Tx;
 1410                 sc->last_Tx = Tx;
 1411 #ifdef DIAGNOSTIC
 1412                 if (sc->last_Tx->hw_list->fwd & 0x7)
 1413                         printf("%s: physical addr 0x%x of list not properly "
 1414                            "aligned\n",
 1415                            sc->sc_dev.dv_xname, sc->last_Rx->hw_list->fwd);
 1416 #endif
 1417         }
 1418 #if NBPFILTER > 0
 1419         /* Pass packet to bpf if there is a listener */
 1420         if (ifp->if_bpf)
 1421                 bpf_mtap(ifp->if_bpf, mb_head);
 1422 #endif
 1423         /*
 1424          * Set a 5 second timer just in case we don't hear from the card again.
 1425          */
 1426         ifp->if_timer = 5;
 1427         goto txloop;
 1428 bad:
 1429 #ifdef TLDEBUG
 1430         printf("tl_ifstart: Out of mbuf, Tx pkt lost\n");
 1431 #endif
 1432         Tx->next = sc->Free_Tx;
 1433         sc->Free_Tx = Tx;
 1434         return;
 1435 }
 1436 
 1437 static void
 1438 tl_ifwatchdog(ifp)
 1439         struct ifnet *ifp;
 1440 {
 1441         tl_softc_t *sc = ifp->if_softc;
 1442 
 1443         if ((ifp->if_flags & IFF_RUNNING) == 0)
 1444                 return;
 1445         printf("%s: device timeout\n", sc->sc_dev.dv_xname);
 1446         ifp->if_oerrors++;
 1447         tl_init(ifp);
 1448 }
 1449 
 1450 static int
 1451 tl_mediachange(ifp)
 1452         struct ifnet *ifp;
 1453 {
 1454 
 1455         if (ifp->if_flags & IFF_UP)
 1456                 tl_init(ifp);
 1457         return (0);
 1458 }
 1459 
 1460 static void
 1461 tl_mediastatus(ifp, ifmr)
 1462         struct ifnet *ifp;
 1463         struct ifmediareq *ifmr;
 1464 {
 1465         tl_softc_t *sc = ifp->if_softc;
 1466 
 1467         mii_pollstat(&sc->tl_mii);
 1468         ifmr->ifm_active = sc->tl_mii.mii_media_active;
 1469         ifmr->ifm_status = sc->tl_mii.mii_media_status;
 1470 }
 1471 
 1472 static int tl_add_RxBuff(sc, Rx, oldm)
 1473         tl_softc_t *sc;
 1474         struct Rx_list *Rx;
 1475         struct mbuf *oldm;
 1476 {
 1477         struct mbuf *m;
 1478         int error;
 1479 
 1480         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1481         if (m != NULL) {
 1482                 MCLGET(m, M_DONTWAIT);
 1483                 if ((m->m_flags & M_EXT) == 0) {
 1484                         m_freem(m);
 1485                         if (oldm == NULL)
 1486                                 return 0;
 1487                         m = oldm;
 1488                         m->m_data = m->m_ext.ext_buf;
 1489                 }
 1490         } else {
 1491                 if (oldm == NULL)
 1492                         return 0;
 1493                 m = oldm;
 1494                 m->m_data = m->m_ext.ext_buf;
 1495         }
 1496 
 1497         /* (re)init the Rx_list struct */
 1498 
 1499         Rx->m = m;
 1500         if ((error = bus_dmamap_load(sc->tl_dmatag, Rx->m_dmamap,
 1501             m->m_ext.ext_buf, m->m_ext.ext_size, NULL, BUS_DMA_NOWAIT)) != 0) {
 1502                 printf("%s: bus_dmamap_load() failed (error %d) for "
 1503                     "tl_add_RxBuff\n", sc->sc_dev.dv_xname, error);
 1504                 printf("size %d (%d)\n", m->m_pkthdr.len, MCLBYTES);
 1505                 m_freem(m);
 1506                 Rx->m = NULL;
 1507                 return 0;
 1508         }
 1509         bus_dmamap_sync(sc->tl_dmatag, Rx->m_dmamap, 0,
 1510             Rx->m_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
 1511         /*
 1512          * Move the data pointer up so that the incoming data packet
 1513          * will be 32-bit aligned.
 1514          */
 1515         m->m_data += 2;
 1516 
 1517         Rx->hw_list->stat =
 1518             htole32(((Rx->m_dmamap->dm_segs[0].ds_len - 2) << 16) | 0x3000);
 1519         Rx->hw_list->seg.data_count =
 1520             htole32(Rx->m_dmamap->dm_segs[0].ds_len - 2);
 1521         Rx->hw_list->seg.data_addr =
 1522             htole32(Rx->m_dmamap->dm_segs[0].ds_addr + 2);
 1523         return (m != oldm);
 1524 }
 1525 
 1526 static void tl_ticks(v)
 1527         void *v;
 1528 {
 1529         tl_softc_t *sc = v;
 1530 
 1531         tl_read_stats(sc);
 1532 
 1533         /* Tick the MII. */
 1534         mii_tick(&sc->tl_mii);
 1535 
 1536         /* read statistics every seconds */
 1537         callout_reset(&sc->tl_tick_ch, hz, tl_ticks, sc);
 1538 }
 1539 
 1540 static void
 1541 tl_read_stats(sc)
 1542         tl_softc_t *sc;
 1543 {
 1544         u_int32_t reg;
 1545         int ierr_overr;
 1546         int ierr_code;
 1547         int ierr_crc;
 1548         int oerr_underr;
 1549         int oerr_deferred;
 1550         int oerr_coll;
 1551         int oerr_multicoll;
 1552         int oerr_exesscoll;
 1553         int oerr_latecoll;
 1554         int oerr_carrloss;
 1555         struct ifnet *ifp = &sc->tl_if;
 1556 
 1557         reg =  tl_intreg_read(sc, TL_INT_STATS_TX);
 1558         ifp->if_opackets += reg & 0x00ffffff;
 1559         oerr_underr = reg >> 24;
 1560 
 1561         reg =  tl_intreg_read(sc, TL_INT_STATS_RX);
 1562         ifp->if_ipackets += reg & 0x00ffffff;
 1563         ierr_overr = reg >> 24;
 1564 
 1565         reg =  tl_intreg_read(sc, TL_INT_STATS_FERR);
 1566         ierr_crc = (reg & TL_FERR_CRC) >> 16;
 1567         ierr_code = (reg & TL_FERR_CODE) >> 24;
 1568         oerr_deferred = (reg & TL_FERR_DEF);
 1569 
 1570         reg =  tl_intreg_read(sc, TL_INT_STATS_COLL);
 1571         oerr_multicoll = (reg & TL_COL_MULTI);
 1572         oerr_coll = (reg & TL_COL_SINGLE) >> 16;
 1573 
 1574         reg =  tl_intreg_read(sc, TL_INT_LERR);
 1575         oerr_exesscoll = (reg & TL_LERR_ECOLL);
 1576         oerr_latecoll = (reg & TL_LERR_LCOLL) >> 8;
 1577         oerr_carrloss = (reg & TL_LERR_CL) >> 16;
 1578 
 1579 
 1580         ifp->if_oerrors += oerr_underr + oerr_exesscoll + oerr_latecoll +
 1581            oerr_carrloss;
 1582         ifp->if_collisions += oerr_coll + oerr_multicoll;
 1583         ifp->if_ierrors += ierr_overr + ierr_code + ierr_crc;
 1584 
 1585         if (ierr_overr)
 1586                 printf("%s: receiver ring buffer overrun\n",
 1587                     sc->sc_dev.dv_xname);
 1588         if (oerr_underr)
 1589                 printf("%s: transmit buffer underrun\n",
 1590                     sc->sc_dev.dv_xname);
 1591 #ifdef TL_PRIV_STATS
 1592         sc->ierr_overr          += ierr_overr;
 1593         sc->ierr_code           += ierr_code;
 1594         sc->ierr_crc            += ierr_crc;
 1595         sc->oerr_underr         += oerr_underr;
 1596         sc->oerr_deferred       += oerr_deferred;
 1597         sc->oerr_coll           += oerr_coll;
 1598         sc->oerr_multicoll      += oerr_multicoll;
 1599         sc->oerr_exesscoll      += oerr_exesscoll;
 1600         sc->oerr_latecoll       += oerr_latecoll;
 1601         sc->oerr_carrloss       += oerr_carrloss;
 1602 #endif
 1603 }
 1604 
 1605 static void tl_addr_filter(sc)
 1606         tl_softc_t *sc;
 1607 {
 1608         struct ether_multistep step;
 1609         struct ether_multi *enm;
 1610         u_int32_t hash[2] = {0, 0};
 1611         int i;
 1612 
 1613         sc->tl_if.if_flags &= ~IFF_ALLMULTI;
 1614         ETHER_FIRST_MULTI(step, &sc->tl_ec, enm);
 1615         while (enm != NULL) {
 1616 #ifdef TLDEBUG
 1617                 printf("tl_addr_filter: addrs %s %s\n",
 1618                    ether_sprintf(enm->enm_addrlo),
 1619                    ether_sprintf(enm->enm_addrhi));
 1620 #endif
 1621                 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 6) == 0) {
 1622                         i = tl_multicast_hash(enm->enm_addrlo);
 1623                         hash[i/32] |= 1 << (i%32);
 1624                 } else {
 1625                         hash[0] = hash[1] = 0xffffffff;
 1626                         sc->tl_if.if_flags |= IFF_ALLMULTI;
 1627                         break;
 1628                 }
 1629                 ETHER_NEXT_MULTI(step, enm);
 1630         }
 1631 #ifdef TLDEBUG
 1632         printf("tl_addr_filer: hash1 %x has2 %x\n", hash[0], hash[1]);
 1633 #endif
 1634         tl_intreg_write(sc, TL_INT_HASH1, hash[0]);
 1635         tl_intreg_write(sc, TL_INT_HASH2, hash[1]);
 1636 }
 1637 
 1638 static int tl_multicast_hash(a)
 1639         u_int8_t *a;
 1640 {
 1641         int hash;
 1642 
 1643 #define DA(addr,bit) (addr[5 - (bit/8)] & (1 << bit%8))
 1644 #define xor8(a,b,c,d,e,f,g,h) (((a != 0) + (b != 0) + (c != 0) + (d != 0) + (e != 0) + (f != 0) + (g != 0) + (h != 0)) & 1)
 1645 
 1646         hash  = xor8( DA(a,0), DA(a, 6), DA(a,12), DA(a,18), DA(a,24), DA(a,30),
 1647             DA(a,36), DA(a,42));
 1648         hash |= xor8( DA(a,1), DA(a, 7), DA(a,13), DA(a,19), DA(a,25), DA(a,31),
 1649             DA(a,37), DA(a,43)) << 1;
 1650         hash |= xor8( DA(a,2), DA(a, 8), DA(a,14), DA(a,20), DA(a,26), DA(a,32),
 1651             DA(a,38), DA(a,44)) << 2;
 1652         hash |= xor8( DA(a,3), DA(a, 9), DA(a,15), DA(a,21), DA(a,27), DA(a,33),
 1653             DA(a,39), DA(a,45)) << 3;
 1654         hash |= xor8( DA(a,4), DA(a,10), DA(a,16), DA(a,22), DA(a,28), DA(a,34),
 1655             DA(a,40), DA(a,46)) << 4;
 1656         hash |= xor8( DA(a,5), DA(a,11), DA(a,17), DA(a,23), DA(a,29), DA(a,35),
 1657             DA(a,41), DA(a,47)) << 5;
 1658 
 1659         return hash;
 1660 }
 1661 
 1662 #if defined(TLDEBUG_RX)
 1663 void
 1664 ether_printheader(eh)
 1665         struct ether_header *eh;
 1666 {
 1667         u_char *c = (char*)eh;
 1668         int i;
 1669         for (i=0; i<sizeof(struct ether_header); i++)
 1670                 printf("%x ", (u_int)c[i]);
 1671                 printf("\n");
 1672 }
 1673 #endif

Cache object: 33c6de52d072fbfd8eb3a218c8c4a69e


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