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/ic/hme.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: hme.c,v 1.49.2.1 2007/05/27 20:34:48 bouyer Exp $      */
    2 
    3 /*-
    4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Paul Kranenburg.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 /*
   40  * HME Ethernet module driver.
   41  */
   42 
   43 #include <sys/cdefs.h>
   44 __KERNEL_RCSID(0, "$NetBSD: hme.c,v 1.49.2.1 2007/05/27 20:34:48 bouyer Exp $");
   45 
   46 /* #define HMEDEBUG */
   47 
   48 #include "opt_inet.h"
   49 #include "opt_ns.h"
   50 #include "bpfilter.h"
   51 #include "rnd.h"
   52 
   53 #include <sys/param.h>
   54 #include <sys/systm.h>
   55 #include <sys/kernel.h>
   56 #include <sys/mbuf.h>
   57 #include <sys/syslog.h>
   58 #include <sys/socket.h>
   59 #include <sys/device.h>
   60 #include <sys/malloc.h>
   61 #include <sys/ioctl.h>
   62 #include <sys/errno.h>
   63 #if NRND > 0
   64 #include <sys/rnd.h>
   65 #endif
   66 
   67 #include <net/if.h>
   68 #include <net/if_dl.h>
   69 #include <net/if_ether.h>
   70 #include <net/if_media.h>
   71 
   72 #ifdef INET
   73 #include <netinet/in.h>
   74 #include <netinet/if_inarp.h>
   75 #include <netinet/in_systm.h>
   76 #include <netinet/in_var.h>
   77 #include <netinet/ip.h>
   78 #include <netinet/tcp.h>
   79 #include <netinet/udp.h>
   80 #endif
   81 
   82 #ifdef NS
   83 #include <netns/ns.h>
   84 #include <netns/ns_if.h>
   85 #endif
   86 
   87 #if NBPFILTER > 0
   88 #include <net/bpf.h>
   89 #include <net/bpfdesc.h>
   90 #endif
   91 
   92 #include <dev/mii/mii.h>
   93 #include <dev/mii/miivar.h>
   94 
   95 #include <machine/bus.h>
   96 
   97 #include <dev/ic/hmereg.h>
   98 #include <dev/ic/hmevar.h>
   99 
  100 void            hme_start(struct ifnet *);
  101 void            hme_stop(struct hme_softc *);
  102 int             hme_ioctl(struct ifnet *, u_long, caddr_t);
  103 void            hme_tick(void *);
  104 void            hme_watchdog(struct ifnet *);
  105 void            hme_shutdown(void *);
  106 void            hme_init(struct hme_softc *);
  107 void            hme_meminit(struct hme_softc *);
  108 void            hme_mifinit(struct hme_softc *);
  109 void            hme_reset(struct hme_softc *);
  110 void            hme_setladrf(struct hme_softc *);
  111 
  112 /* MII methods & callbacks */
  113 static int      hme_mii_readreg(struct device *, int, int);
  114 static void     hme_mii_writereg(struct device *, int, int, int);
  115 static void     hme_mii_statchg(struct device *);
  116 
  117 int             hme_mediachange(struct ifnet *);
  118 void            hme_mediastatus(struct ifnet *, struct ifmediareq *);
  119 
  120 struct mbuf     *hme_get(struct hme_softc *, int, uint32_t);
  121 int             hme_put(struct hme_softc *, int, struct mbuf *);
  122 void            hme_read(struct hme_softc *, int, uint32_t);
  123 int             hme_eint(struct hme_softc *, u_int);
  124 int             hme_rint(struct hme_softc *);
  125 int             hme_tint(struct hme_softc *);
  126 
  127 static int      ether_cmp(u_char *, u_char *);
  128 
  129 /* Default buffer copy routines */
  130 void    hme_copytobuf_contig(struct hme_softc *, void *, int, int);
  131 void    hme_copyfrombuf_contig(struct hme_softc *, void *, int, int);
  132 void    hme_zerobuf_contig(struct hme_softc *, int, int);
  133 
  134 
  135 void
  136 hme_config(sc)
  137         struct hme_softc *sc;
  138 {
  139         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
  140         struct mii_data *mii = &sc->sc_mii;
  141         struct mii_softc *child;
  142         bus_dma_tag_t dmatag = sc->sc_dmatag;
  143         bus_dma_segment_t seg;
  144         bus_size_t size;
  145         int rseg, error;
  146 
  147         /*
  148          * HME common initialization.
  149          *
  150          * hme_softc fields that must be initialized by the front-end:
  151          *
  152          * the bus tag:
  153          *      sc_bustag
  154          *
  155          * the DMA bus tag:
  156          *      sc_dmatag
  157          *
  158          * the bus handles:
  159          *      sc_seb          (Shared Ethernet Block registers)
  160          *      sc_erx          (Receiver Unit registers)
  161          *      sc_etx          (Transmitter Unit registers)
  162          *      sc_mac          (MAC registers)
  163          *      sc_mif          (Management Interface registers)
  164          *
  165          * the maximum bus burst size:
  166          *      sc_burst
  167          *
  168          * (notyet:DMA capable memory for the ring descriptors & packet buffers:
  169          *      rb_membase, rb_dmabase)
  170          *
  171          * the local Ethernet address:
  172          *      sc_enaddr
  173          *
  174          */
  175 
  176         /* Make sure the chip is stopped. */
  177         hme_stop(sc);
  178 
  179 
  180         /*
  181          * Allocate descriptors and buffers
  182          * XXX - do all this differently.. and more configurably,
  183          * eg. use things as `dma_load_mbuf()' on transmit,
  184          *     and a pool of `EXTMEM' mbufs (with buffers DMA-mapped
  185          *     all the time) on the receiver side.
  186          *
  187          * Note: receive buffers must be 64-byte aligned.
  188          * Also, apparently, the buffers must extend to a DMA burst
  189          * boundary beyond the maximum packet size.
  190          */
  191 #define _HME_NDESC      128
  192 #define _HME_BUFSZ      1600
  193 
  194         /* Note: the # of descriptors must be a multiple of 16 */
  195         sc->sc_rb.rb_ntbuf = _HME_NDESC;
  196         sc->sc_rb.rb_nrbuf = _HME_NDESC;
  197 
  198         /*
  199          * Allocate DMA capable memory
  200          * Buffer descriptors must be aligned on a 2048 byte boundary;
  201          * take this into account when calculating the size. Note that
  202          * the maximum number of descriptors (256) occupies 2048 bytes,
  203          * so we allocate that much regardless of _HME_NDESC.
  204          */
  205         size =  2048 +                                  /* TX descriptors */
  206                 2048 +                                  /* RX descriptors */
  207                 sc->sc_rb.rb_ntbuf * _HME_BUFSZ +       /* TX buffers */
  208                 sc->sc_rb.rb_nrbuf * _HME_BUFSZ;        /* RX buffers */
  209 
  210         /* Allocate DMA buffer */
  211         if ((error = bus_dmamem_alloc(dmatag, size,
  212                                       2048, 0,
  213                                       &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
  214                 printf("%s: DMA buffer alloc error %d\n",
  215                         sc->sc_dev.dv_xname, error);
  216                 return;
  217         }
  218 
  219         /* Map DMA memory in CPU addressable space */
  220         if ((error = bus_dmamem_map(dmatag, &seg, rseg, size,
  221                                     &sc->sc_rb.rb_membase,
  222                                     BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
  223                 printf("%s: DMA buffer map error %d\n",
  224                         sc->sc_dev.dv_xname, error);
  225                 bus_dmamap_unload(dmatag, sc->sc_dmamap);
  226                 bus_dmamem_free(dmatag, &seg, rseg);
  227                 return;
  228         }
  229 
  230         if ((error = bus_dmamap_create(dmatag, size, 1, size, 0,
  231                                     BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) {
  232                 printf("%s: DMA map create error %d\n",
  233                         sc->sc_dev.dv_xname, error);
  234                 return;
  235         }
  236 
  237         /* Load the buffer */
  238         if ((error = bus_dmamap_load(dmatag, sc->sc_dmamap,
  239             sc->sc_rb.rb_membase, size, NULL,
  240             BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
  241                 printf("%s: DMA buffer map load error %d\n",
  242                         sc->sc_dev.dv_xname, error);
  243                 bus_dmamem_free(dmatag, &seg, rseg);
  244                 return;
  245         }
  246         sc->sc_rb.rb_dmabase = sc->sc_dmamap->dm_segs[0].ds_addr;
  247 
  248         printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname,
  249             ether_sprintf(sc->sc_enaddr));
  250 
  251         /* Initialize ifnet structure. */
  252         strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
  253         ifp->if_softc = sc;
  254         ifp->if_start = hme_start;
  255         ifp->if_ioctl = hme_ioctl;
  256         ifp->if_watchdog = hme_watchdog;
  257         ifp->if_flags =
  258             IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
  259         sc->sc_if_flags = ifp->if_flags;
  260         ifp->if_capabilities |= IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_UDPv4_Rx |
  261                                 IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
  262         IFQ_SET_READY(&ifp->if_snd);
  263 
  264         /* Initialize ifmedia structures and MII info */
  265         mii->mii_ifp = ifp;
  266         mii->mii_readreg = hme_mii_readreg;
  267         mii->mii_writereg = hme_mii_writereg;
  268         mii->mii_statchg = hme_mii_statchg;
  269 
  270         ifmedia_init(&mii->mii_media, 0, hme_mediachange, hme_mediastatus);
  271 
  272         hme_mifinit(sc);
  273 
  274         mii_attach(&sc->sc_dev, mii, 0xffffffff,
  275                         MII_PHY_ANY, MII_OFFSET_ANY, MIIF_FORCEANEG);
  276 
  277         child = LIST_FIRST(&mii->mii_phys);
  278         if (child == NULL) {
  279                 /* No PHY attached */
  280                 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
  281                 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
  282         } else {
  283                 /*
  284                  * Walk along the list of attached MII devices and
  285                  * establish an `MII instance' to `phy number'
  286                  * mapping. We'll use this mapping in media change
  287                  * requests to determine which phy to use to program
  288                  * the MIF configuration register.
  289                  */
  290                 for (; child != NULL; child = LIST_NEXT(child, mii_list)) {
  291                         /*
  292                          * Note: we support just two PHYs: the built-in
  293                          * internal device and an external on the MII
  294                          * connector.
  295                          */
  296                         if (child->mii_phy > 1 || child->mii_inst > 1) {
  297                                 printf("%s: cannot accomodate MII device %s"
  298                                        " at phy %d, instance %d\n",
  299                                        sc->sc_dev.dv_xname,
  300                                        child->mii_dev.dv_xname,
  301                                        child->mii_phy, child->mii_inst);
  302                                 continue;
  303                         }
  304 
  305                         sc->sc_phys[child->mii_inst] = child->mii_phy;
  306                 }
  307 
  308                 /*
  309                  * XXX - we can really do the following ONLY if the
  310                  * phy indeed has the auto negotiation capability!!
  311                  */
  312                 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO);
  313         }
  314 
  315         /* claim 802.1q capability */
  316         sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU;
  317 
  318         /* Attach the interface. */
  319         if_attach(ifp);
  320         ether_ifattach(ifp, sc->sc_enaddr);
  321 
  322         sc->sc_sh = shutdownhook_establish(hme_shutdown, sc);
  323         if (sc->sc_sh == NULL)
  324                 panic("hme_config: can't establish shutdownhook");
  325 
  326 #if NRND > 0
  327         rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
  328                           RND_TYPE_NET, 0);
  329 #endif
  330 
  331         callout_init(&sc->sc_tick_ch);
  332 }
  333 
  334 void
  335 hme_tick(arg)
  336         void *arg;
  337 {
  338         struct hme_softc *sc = arg;
  339         int s;
  340 
  341         s = splnet();
  342         mii_tick(&sc->sc_mii);
  343         splx(s);
  344 
  345         callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc);
  346 }
  347 
  348 void
  349 hme_reset(sc)
  350         struct hme_softc *sc;
  351 {
  352         int s;
  353 
  354         s = splnet();
  355         hme_init(sc);
  356         splx(s);
  357 }
  358 
  359 void
  360 hme_stop(sc)
  361         struct hme_softc *sc;
  362 {
  363         bus_space_tag_t t = sc->sc_bustag;
  364         bus_space_handle_t seb = sc->sc_seb;
  365         int n;
  366 
  367         callout_stop(&sc->sc_tick_ch);
  368         mii_down(&sc->sc_mii);
  369 
  370         /* Mask all interrupts */
  371         bus_space_write_4(t, seb, HME_SEBI_IMASK, 0xffffffff);
  372 
  373         /* Reset transmitter and receiver */
  374         bus_space_write_4(t, seb, HME_SEBI_RESET,
  375                           (HME_SEB_RESET_ETX | HME_SEB_RESET_ERX));
  376 
  377         for (n = 0; n < 20; n++) {
  378                 u_int32_t v = bus_space_read_4(t, seb, HME_SEBI_RESET);
  379                 if ((v & (HME_SEB_RESET_ETX | HME_SEB_RESET_ERX)) == 0)
  380                         return;
  381                 DELAY(20);
  382         }
  383 
  384         printf("%s: hme_stop: reset failed\n", sc->sc_dev.dv_xname);
  385 }
  386 
  387 void
  388 hme_meminit(sc)
  389         struct hme_softc *sc;
  390 {
  391         bus_addr_t txbufdma, rxbufdma;
  392         bus_addr_t dma;
  393         caddr_t p;
  394         unsigned int ntbuf, nrbuf, i;
  395         struct hme_ring *hr = &sc->sc_rb;
  396 
  397         p = hr->rb_membase;
  398         dma = hr->rb_dmabase;
  399 
  400         ntbuf = hr->rb_ntbuf;
  401         nrbuf = hr->rb_nrbuf;
  402 
  403         /*
  404          * Allocate transmit descriptors
  405          */
  406         hr->rb_txd = p;
  407         hr->rb_txddma = dma;
  408         p += ntbuf * HME_XD_SIZE;
  409         dma += ntbuf * HME_XD_SIZE;
  410         /* We have reserved descriptor space until the next 2048 byte boundary.*/
  411         dma = (bus_addr_t)roundup((u_long)dma, 2048);
  412         p = (caddr_t)roundup((u_long)p, 2048);
  413 
  414         /*
  415          * Allocate receive descriptors
  416          */
  417         hr->rb_rxd = p;
  418         hr->rb_rxddma = dma;
  419         p += nrbuf * HME_XD_SIZE;
  420         dma += nrbuf * HME_XD_SIZE;
  421         /* Again move forward to the next 2048 byte boundary.*/
  422         dma = (bus_addr_t)roundup((u_long)dma, 2048);
  423         p = (caddr_t)roundup((u_long)p, 2048);
  424 
  425 
  426         /*
  427          * Allocate transmit buffers
  428          */
  429         hr->rb_txbuf = p;
  430         txbufdma = dma;
  431         p += ntbuf * _HME_BUFSZ;
  432         dma += ntbuf * _HME_BUFSZ;
  433 
  434         /*
  435          * Allocate receive buffers
  436          */
  437         hr->rb_rxbuf = p;
  438         rxbufdma = dma;
  439         p += nrbuf * _HME_BUFSZ;
  440         dma += nrbuf * _HME_BUFSZ;
  441 
  442         /*
  443          * Initialize transmit buffer descriptors
  444          */
  445         for (i = 0; i < ntbuf; i++) {
  446                 HME_XD_SETADDR(sc->sc_pci, hr->rb_txd, i, txbufdma + i * _HME_BUFSZ);
  447                 HME_XD_SETFLAGS(sc->sc_pci, hr->rb_txd, i, 0);
  448         }
  449 
  450         /*
  451          * Initialize receive buffer descriptors
  452          */
  453         for (i = 0; i < nrbuf; i++) {
  454                 HME_XD_SETADDR(sc->sc_pci, hr->rb_rxd, i, rxbufdma + i * _HME_BUFSZ);
  455                 HME_XD_SETFLAGS(sc->sc_pci, hr->rb_rxd, i,
  456                                 HME_XD_OWN | HME_XD_ENCODE_RSIZE(_HME_BUFSZ));
  457         }
  458 
  459         hr->rb_tdhead = hr->rb_tdtail = 0;
  460         hr->rb_td_nbusy = 0;
  461         hr->rb_rdtail = 0;
  462 }
  463 
  464 /*
  465  * Initialization of interface; set up initialization block
  466  * and transmit/receive descriptor rings.
  467  */
  468 void
  469 hme_init(sc)
  470         struct hme_softc *sc;
  471 {
  472         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
  473         bus_space_tag_t t = sc->sc_bustag;
  474         bus_space_handle_t seb = sc->sc_seb;
  475         bus_space_handle_t etx = sc->sc_etx;
  476         bus_space_handle_t erx = sc->sc_erx;
  477         bus_space_handle_t mac = sc->sc_mac;
  478         u_int8_t *ea;
  479         u_int32_t v;
  480 
  481         /*
  482          * Initialization sequence. The numbered steps below correspond
  483          * to the sequence outlined in section 6.3.5.1 in the Ethernet
  484          * Channel Engine manual (part of the PCIO manual).
  485          * See also the STP2002-STQ document from Sun Microsystems.
  486          */
  487 
  488         /* step 1 & 2. Reset the Ethernet Channel */
  489         hme_stop(sc);
  490 
  491         /* Re-initialize the MIF */
  492         hme_mifinit(sc);
  493 
  494         /* Call MI reset function if any */
  495         if (sc->sc_hwreset)
  496                 (*sc->sc_hwreset)(sc);
  497 
  498 #if 0
  499         /* Mask all MIF interrupts, just in case */
  500         bus_space_write_4(t, mif, HME_MIFI_IMASK, 0xffff);
  501 #endif
  502 
  503         /* step 3. Setup data structures in host memory */
  504         hme_meminit(sc);
  505 
  506         /* step 4. TX MAC registers & counters */
  507         bus_space_write_4(t, mac, HME_MACI_NCCNT, 0);
  508         bus_space_write_4(t, mac, HME_MACI_FCCNT, 0);
  509         bus_space_write_4(t, mac, HME_MACI_EXCNT, 0);
  510         bus_space_write_4(t, mac, HME_MACI_LTCNT, 0);
  511         bus_space_write_4(t, mac, HME_MACI_TXSIZE,
  512             (sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU) ?
  513             ETHER_VLAN_ENCAP_LEN + ETHER_MAX_LEN : ETHER_MAX_LEN);
  514         sc->sc_ec_capenable = sc->sc_ethercom.ec_capenable;
  515 
  516         /* Load station MAC address */
  517         ea = sc->sc_enaddr;
  518         bus_space_write_4(t, mac, HME_MACI_MACADDR0, (ea[0] << 8) | ea[1]);
  519         bus_space_write_4(t, mac, HME_MACI_MACADDR1, (ea[2] << 8) | ea[3]);
  520         bus_space_write_4(t, mac, HME_MACI_MACADDR2, (ea[4] << 8) | ea[5]);
  521 
  522         /*
  523          * Init seed for backoff
  524          * (source suggested by manual: low 10 bits of MAC address)
  525          */
  526         v = ((ea[4] << 8) | ea[5]) & 0x3fff;
  527         bus_space_write_4(t, mac, HME_MACI_RANDSEED, v);
  528 
  529 
  530         /* Note: Accepting power-on default for other MAC registers here.. */
  531 
  532 
  533         /* step 5. RX MAC registers & counters */
  534         hme_setladrf(sc);
  535 
  536         /* step 6 & 7. Program Descriptor Ring Base Addresses */
  537         bus_space_write_4(t, etx, HME_ETXI_RING, sc->sc_rb.rb_txddma);
  538         bus_space_write_4(t, etx, HME_ETXI_RSIZE, sc->sc_rb.rb_ntbuf);
  539 
  540         bus_space_write_4(t, erx, HME_ERXI_RING, sc->sc_rb.rb_rxddma);
  541         bus_space_write_4(t, mac, HME_MACI_RXSIZE,
  542             (sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU) ?
  543             ETHER_VLAN_ENCAP_LEN + ETHER_MAX_LEN : ETHER_MAX_LEN);
  544 
  545         /* step 8. Global Configuration & Interrupt Mask */
  546         bus_space_write_4(t, seb, HME_SEBI_IMASK,
  547                         ~(
  548                           /*HME_SEB_STAT_GOTFRAME | HME_SEB_STAT_SENTFRAME |*/
  549                           HME_SEB_STAT_HOSTTOTX |
  550                           HME_SEB_STAT_RXTOHOST |
  551                           HME_SEB_STAT_TXALL |
  552                           HME_SEB_STAT_TXPERR |
  553                           HME_SEB_STAT_RCNTEXP |
  554                           /*HME_SEB_STAT_MIFIRQ |*/
  555                           HME_SEB_STAT_ALL_ERRORS ));
  556 
  557         switch (sc->sc_burst) {
  558         default:
  559                 v = 0;
  560                 break;
  561         case 16:
  562                 v = HME_SEB_CFG_BURST16;
  563                 break;
  564         case 32:
  565                 v = HME_SEB_CFG_BURST32;
  566                 break;
  567         case 64:
  568                 v = HME_SEB_CFG_BURST64;
  569                 break;
  570         }
  571         bus_space_write_4(t, seb, HME_SEBI_CFG, v);
  572 
  573         /* step 9. ETX Configuration: use mostly default values */
  574 
  575         /* Enable DMA */
  576         v = bus_space_read_4(t, etx, HME_ETXI_CFG);
  577         v |= HME_ETX_CFG_DMAENABLE;
  578         bus_space_write_4(t, etx, HME_ETXI_CFG, v);
  579 
  580         /* Transmit Descriptor ring size: in increments of 16 */
  581         bus_space_write_4(t, etx, HME_ETXI_RSIZE, _HME_NDESC / 16 - 1);
  582 
  583 
  584         /* step 10. ERX Configuration */
  585         v = bus_space_read_4(t, erx, HME_ERXI_CFG);
  586 
  587         /* Encode Receive Descriptor ring size: four possible values */
  588         switch (_HME_NDESC /*XXX*/) {
  589         case 32:
  590                 v |= HME_ERX_CFG_RINGSIZE32;
  591                 break;
  592         case 64:
  593                 v |= HME_ERX_CFG_RINGSIZE64;
  594                 break;
  595         case 128:
  596                 v |= HME_ERX_CFG_RINGSIZE128;
  597                 break;
  598         case 256:
  599                 v |= HME_ERX_CFG_RINGSIZE256;
  600                 break;
  601         default:
  602                 printf("hme: invalid Receive Descriptor ring size\n");
  603                 break;
  604         }
  605 
  606         /* Enable DMA */
  607         v |= HME_ERX_CFG_DMAENABLE;
  608 
  609         /* set h/w rx checksum start offset (# of half-words) */
  610 #ifdef INET
  611         v |= (((ETHER_HDR_LEN + sizeof(struct ip) +
  612                 ((sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU) ?
  613                 ETHER_VLAN_ENCAP_LEN : 0)) / 2) << HME_ERX_CFG_CSUMSHIFT) &
  614                 HME_ERX_CFG_CSUMSTART;
  615 #endif
  616         bus_space_write_4(t, erx, HME_ERXI_CFG, v);
  617 
  618         /* step 11. XIF Configuration */
  619         v = bus_space_read_4(t, mac, HME_MACI_XIF);
  620         v |= HME_MAC_XIF_OE;
  621         bus_space_write_4(t, mac, HME_MACI_XIF, v);
  622 
  623         /* step 12. RX_MAC Configuration Register */
  624         v = bus_space_read_4(t, mac, HME_MACI_RXCFG);
  625         v |= HME_MAC_RXCFG_ENABLE | HME_MAC_RXCFG_PSTRIP;
  626         bus_space_write_4(t, mac, HME_MACI_RXCFG, v);
  627 
  628         /* step 13. TX_MAC Configuration Register */
  629         v = bus_space_read_4(t, mac, HME_MACI_TXCFG);
  630         v |= (HME_MAC_TXCFG_ENABLE | HME_MAC_TXCFG_DGIVEUP);
  631         bus_space_write_4(t, mac, HME_MACI_TXCFG, v);
  632 
  633         /* step 14. Issue Transmit Pending command */
  634 
  635         /* Call MI initialization function if any */
  636         if (sc->sc_hwinit)
  637                 (*sc->sc_hwinit)(sc);
  638 
  639         /* Set the current media. */
  640         mii_mediachg(&sc->sc_mii);
  641 
  642         /* Start the one second timer. */
  643         callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc);
  644 
  645         ifp->if_flags |= IFF_RUNNING;
  646         ifp->if_flags &= ~IFF_OACTIVE;
  647         sc->sc_if_flags = ifp->if_flags;
  648         ifp->if_timer = 0;
  649         hme_start(ifp);
  650 }
  651 
  652 /*
  653  * Compare two Ether/802 addresses for equality, inlined and unrolled for
  654  * speed.
  655  */
  656 static __inline__ int
  657 ether_cmp(a, b)
  658         u_char *a, *b;
  659 {
  660 
  661         if (a[5] != b[5] || a[4] != b[4] || a[3] != b[3] ||
  662             a[2] != b[2] || a[1] != b[1] || a[0] != b[0])
  663                 return (0);
  664         return (1);
  665 }
  666 
  667 
  668 /*
  669  * Routine to copy from mbuf chain to transmit buffer in
  670  * network buffer memory.
  671  * Returns the amount of data copied.
  672  */
  673 int
  674 hme_put(sc, ri, m)
  675         struct hme_softc *sc;
  676         int ri;                 /* Ring index */
  677         struct mbuf *m;
  678 {
  679         struct mbuf *n;
  680         int len, tlen = 0;
  681         caddr_t bp;
  682 
  683         bp = sc->sc_rb.rb_txbuf + (ri % sc->sc_rb.rb_ntbuf) * _HME_BUFSZ;
  684         for (; m; m = n) {
  685                 len = m->m_len;
  686                 if (len == 0) {
  687                         MFREE(m, n);
  688                         continue;
  689                 }
  690                 memcpy(bp, mtod(m, caddr_t), len);
  691                 bp += len;
  692                 tlen += len;
  693                 MFREE(m, n);
  694         }
  695         return (tlen);
  696 }
  697 
  698 /*
  699  * Pull data off an interface.
  700  * Len is length of data, with local net header stripped.
  701  * We copy the data into mbufs.  When full cluster sized units are present
  702  * we copy into clusters.
  703  */
  704 struct mbuf *
  705 hme_get(sc, ri, flags)
  706         struct hme_softc *sc;
  707         int ri;
  708         u_int32_t flags;
  709 {
  710         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
  711         struct mbuf *m, *m0, *newm;
  712         caddr_t bp;
  713         int len, totlen;
  714 
  715         totlen = HME_XD_DECODE_RSIZE(flags);
  716         MGETHDR(m0, M_DONTWAIT, MT_DATA);
  717         if (m0 == 0)
  718                 return (0);
  719         m0->m_pkthdr.rcvif = ifp;
  720         m0->m_pkthdr.len = totlen;
  721         len = MHLEN;
  722         m = m0;
  723 
  724         bp = sc->sc_rb.rb_rxbuf + (ri % sc->sc_rb.rb_nrbuf) * _HME_BUFSZ;
  725 
  726         while (totlen > 0) {
  727                 if (totlen >= MINCLSIZE) {
  728                         MCLGET(m, M_DONTWAIT);
  729                         if ((m->m_flags & M_EXT) == 0)
  730                                 goto bad;
  731                         len = MCLBYTES;
  732                 }
  733 
  734                 if (m == m0) {
  735                         caddr_t newdata = (caddr_t)
  736                             ALIGN(m->m_data + sizeof(struct ether_header)) -
  737                             sizeof(struct ether_header);
  738                         len -= newdata - m->m_data;
  739                         m->m_data = newdata;
  740                 }
  741 
  742                 m->m_len = len = min(totlen, len);
  743                 memcpy(mtod(m, caddr_t), bp, len);
  744                 bp += len;
  745 
  746                 totlen -= len;
  747                 if (totlen > 0) {
  748                         MGET(newm, M_DONTWAIT, MT_DATA);
  749                         if (newm == 0)
  750                                 goto bad;
  751                         len = MLEN;
  752                         m = m->m_next = newm;
  753                 }
  754         }
  755 
  756 #ifdef INET
  757         /* hardware checksum */
  758         if (ifp->if_csum_flags_rx & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) {
  759                 struct ether_header *eh;
  760                 struct ip *ip;
  761                 struct udphdr *uh;
  762                 uint16_t *opts;
  763                 int32_t hlen, pktlen;
  764                 uint32_t temp;
  765 
  766                 if (sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU) {
  767                         pktlen = m0->m_pkthdr.len - ETHER_HDR_LEN -
  768                                 ETHER_VLAN_ENCAP_LEN;
  769                         eh = (struct ether_header *) mtod(m0, caddr_t) +
  770                                 ETHER_VLAN_ENCAP_LEN;
  771                 } else {
  772                         pktlen = m0->m_pkthdr.len - ETHER_HDR_LEN;
  773                         eh = mtod(m0, struct ether_header *);
  774                 }
  775                 if (ntohs(eh->ether_type) != ETHERTYPE_IP)
  776                         goto swcsum;
  777                 ip = (struct ip *) ((caddr_t) eh + ETHER_HDR_LEN);
  778 
  779                 /* IPv4 only */
  780                 if (ip->ip_v != IPVERSION)
  781                         goto swcsum;
  782 
  783                 hlen = ip->ip_hl << 2;
  784                 if (hlen < sizeof(struct ip))
  785                         goto swcsum;
  786 
  787                 /*
  788                  * bail if too short, has random trailing garbage, truncated,
  789                  * fragment, or has ethernet pad.
  790                  */
  791                 if ((ntohs(ip->ip_len) < hlen) || (ntohs(ip->ip_len) != pktlen)
  792                     || (ntohs(ip->ip_off) & (IP_MF | IP_OFFMASK)))
  793                         goto swcsum;
  794 
  795                 switch (ip->ip_p) {
  796                 case IPPROTO_TCP:
  797                         if (! (ifp->if_csum_flags_rx & M_CSUM_TCPv4))
  798                                 goto swcsum;
  799                         if (pktlen < (hlen + sizeof(struct tcphdr)))
  800                                 goto swcsum;
  801                         m0->m_pkthdr.csum_flags = M_CSUM_TCPv4;
  802                         break;
  803                 case IPPROTO_UDP:
  804                         if (! (ifp->if_csum_flags_rx & M_CSUM_UDPv4))
  805                                 goto swcsum;
  806                         if (pktlen < (hlen + sizeof(struct udphdr)))
  807                                 goto swcsum;
  808                         uh = (struct udphdr *)((caddr_t)ip + hlen);
  809                         /* no checksum */
  810                         if (uh->uh_sum == 0)
  811                                 goto swcsum;
  812                         m0->m_pkthdr.csum_flags = M_CSUM_UDPv4;
  813                         break;
  814                 default:
  815                         goto swcsum;
  816                 }
  817 
  818                 /* w/ M_CSUM_NO_PSEUDOHDR, the uncomplemented sum is expected */
  819                 m0->m_pkthdr.csum_data = (~flags) & HME_XD_RXCKSUM;
  820 
  821                 /* if the pkt had ip options, we have to deduct them */
  822                 if (hlen > sizeof(struct ip)) {
  823                         uint32_t optsum;
  824 
  825                         optsum = 0;
  826                         temp = hlen - sizeof(struct ip);
  827                         opts = (uint16_t *) ((caddr_t) ip + sizeof(struct ip));
  828 
  829                         while (temp > 1) {
  830                                 optsum += ntohs(*opts++);
  831                                 temp -= 2;
  832                         }
  833                         while (optsum >> 16)
  834                                 optsum = (optsum >> 16) + (optsum & 0xffff);
  835 
  836                         /* Deduct the ip opts sum from the hwsum (rfc 1624). */
  837                         m0->m_pkthdr.csum_data = ~((~m0->m_pkthdr.csum_data) -
  838                                                    ~optsum);
  839 
  840                         while (m0->m_pkthdr.csum_data >> 16)
  841                                 m0->m_pkthdr.csum_data =
  842                                         (m0->m_pkthdr.csum_data >> 16) +
  843                                         (m0->m_pkthdr.csum_data & 0xffff);
  844                 }
  845 
  846                 m0->m_pkthdr.csum_flags |= M_CSUM_DATA | M_CSUM_NO_PSEUDOHDR;
  847         }
  848 swcsum:
  849                 m0->m_pkthdr.csum_flags = 0;
  850 #endif
  851 
  852         return (m0);
  853 
  854 bad:
  855         m_freem(m0);
  856         return (0);
  857 }
  858 
  859 /*
  860  * Pass a packet to the higher levels.
  861  */
  862 void
  863 hme_read(sc, ix, flags)
  864         struct hme_softc *sc;
  865         int ix;
  866         u_int32_t flags;
  867 {
  868         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
  869         struct mbuf *m;
  870         int len;
  871 
  872         len = HME_XD_DECODE_RSIZE(flags);
  873         if (len <= sizeof(struct ether_header) ||
  874             len > ((sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU) ?
  875             ETHER_VLAN_ENCAP_LEN + ETHERMTU + sizeof(struct ether_header) :
  876             ETHERMTU + sizeof(struct ether_header))) {
  877 #ifdef HMEDEBUG
  878                 printf("%s: invalid packet size %d; dropping\n",
  879                     sc->sc_dev.dv_xname, len);
  880 #endif
  881                 ifp->if_ierrors++;
  882                 return;
  883         }
  884 
  885         /* Pull packet off interface. */
  886         m = hme_get(sc, ix, flags);
  887         if (m == 0) {
  888                 ifp->if_ierrors++;
  889                 return;
  890         }
  891 
  892         ifp->if_ipackets++;
  893 
  894 #if NBPFILTER > 0
  895         /*
  896          * Check if there's a BPF listener on this interface.
  897          * If so, hand off the raw packet to BPF.
  898          */
  899         if (ifp->if_bpf)
  900                 bpf_mtap(ifp->if_bpf, m);
  901 #endif
  902 
  903         /* Pass the packet up. */
  904         (*ifp->if_input)(ifp, m);
  905 }
  906 
  907 void
  908 hme_start(ifp)
  909         struct ifnet *ifp;
  910 {
  911         struct hme_softc *sc = (struct hme_softc *)ifp->if_softc;
  912         caddr_t txd = sc->sc_rb.rb_txd;
  913         struct mbuf *m;
  914         unsigned int txflags;
  915         unsigned int ri, len;
  916         unsigned int ntbuf = sc->sc_rb.rb_ntbuf;
  917 
  918         if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
  919                 return;
  920 
  921         ri = sc->sc_rb.rb_tdhead;
  922 
  923         for (;;) {
  924                 IFQ_DEQUEUE(&ifp->if_snd, m);
  925                 if (m == 0)
  926                         break;
  927 
  928 #if NBPFILTER > 0
  929                 /*
  930                  * If BPF is listening on this interface, let it see the
  931                  * packet before we commit it to the wire.
  932                  */
  933                 if (ifp->if_bpf)
  934                         bpf_mtap(ifp->if_bpf, m);
  935 #endif
  936 
  937 #ifdef INET
  938                 /* collect bits for h/w csum, before hme_put frees the mbuf */
  939                 if (ifp->if_csum_flags_tx & (M_CSUM_TCPv4 | M_CSUM_UDPv4) &&
  940                     m->m_pkthdr.csum_flags & (M_CSUM_TCPv4 | M_CSUM_UDPv4)) {
  941                         struct ether_header *eh;
  942                         uint16_t offset, start;
  943 
  944                         eh = mtod(m, struct ether_header *);
  945                         switch (ntohs(eh->ether_type)) {
  946                         case ETHERTYPE_IP:
  947                                 start = ETHER_HDR_LEN;
  948                                 break;
  949                         case ETHERTYPE_VLAN:
  950                                 start = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
  951                                 break;
  952                         default:
  953                                 /* unsupported, drop it */
  954                                 m_free(m);
  955                                 continue;
  956                         }
  957                         start += M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data);
  958                         offset = M_CSUM_DATA_IPv4_OFFSET(m->m_pkthdr.csum_data)
  959                             + start;
  960                         txflags = HME_XD_TXCKSUM |
  961                                   (offset << HME_XD_TXCSSTUFFSHIFT) |
  962                                   (start << HME_XD_TXCSSTARTSHIFT);
  963                 } else
  964 #endif
  965                         txflags = 0;
  966 
  967                 /*
  968                  * Copy the mbuf chain into the transmit buffer.
  969                  */
  970                 len = hme_put(sc, ri, m);
  971 
  972                 /*
  973                  * Initialize transmit registers and start transmission
  974                  */
  975                 HME_XD_SETFLAGS(sc->sc_pci, txd, ri,
  976                         HME_XD_OWN | HME_XD_SOP | HME_XD_EOP |
  977                         HME_XD_ENCODE_TSIZE(len) | txflags);
  978 
  979                 /*if (sc->sc_rb.rb_td_nbusy <= 0)*/
  980                 bus_space_write_4(sc->sc_bustag, sc->sc_etx, HME_ETXI_PENDING,
  981                                   HME_ETX_TP_DMAWAKEUP);
  982 
  983                 if (++ri == ntbuf)
  984                         ri = 0;
  985 
  986                 if (++sc->sc_rb.rb_td_nbusy == ntbuf) {
  987                         ifp->if_flags |= IFF_OACTIVE;
  988                         break;
  989                 }
  990         }
  991 
  992         sc->sc_rb.rb_tdhead = ri;
  993 }
  994 
  995 /*
  996  * Transmit interrupt.
  997  */
  998 int
  999 hme_tint(sc)
 1000         struct hme_softc *sc;
 1001 {
 1002         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 1003         bus_space_tag_t t = sc->sc_bustag;
 1004         bus_space_handle_t mac = sc->sc_mac;
 1005         unsigned int ri, txflags;
 1006 
 1007         /*
 1008          * Unload collision counters
 1009          */
 1010         ifp->if_collisions +=
 1011                 bus_space_read_4(t, mac, HME_MACI_NCCNT) +
 1012                 bus_space_read_4(t, mac, HME_MACI_FCCNT) +
 1013                 bus_space_read_4(t, mac, HME_MACI_EXCNT) +
 1014                 bus_space_read_4(t, mac, HME_MACI_LTCNT);
 1015 
 1016         /*
 1017          * then clear the hardware counters.
 1018          */
 1019         bus_space_write_4(t, mac, HME_MACI_NCCNT, 0);
 1020         bus_space_write_4(t, mac, HME_MACI_FCCNT, 0);
 1021         bus_space_write_4(t, mac, HME_MACI_EXCNT, 0);
 1022         bus_space_write_4(t, mac, HME_MACI_LTCNT, 0);
 1023 
 1024         /* Fetch current position in the transmit ring */
 1025         ri = sc->sc_rb.rb_tdtail;
 1026 
 1027         for (;;) {
 1028                 if (sc->sc_rb.rb_td_nbusy <= 0)
 1029                         break;
 1030 
 1031                 txflags = HME_XD_GETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri);
 1032 
 1033                 if (txflags & HME_XD_OWN)
 1034                         break;
 1035 
 1036                 ifp->if_flags &= ~IFF_OACTIVE;
 1037                 ifp->if_opackets++;
 1038 
 1039                 if (++ri == sc->sc_rb.rb_ntbuf)
 1040                         ri = 0;
 1041 
 1042                 --sc->sc_rb.rb_td_nbusy;
 1043         }
 1044 
 1045         /* Update ring */
 1046         sc->sc_rb.rb_tdtail = ri;
 1047 
 1048         hme_start(ifp);
 1049 
 1050         if (sc->sc_rb.rb_td_nbusy == 0)
 1051                 ifp->if_timer = 0;
 1052 
 1053         return (1);
 1054 }
 1055 
 1056 /*
 1057  * Receive interrupt.
 1058  */
 1059 int
 1060 hme_rint(sc)
 1061         struct hme_softc *sc;
 1062 {
 1063         caddr_t xdr = sc->sc_rb.rb_rxd;
 1064         unsigned int nrbuf = sc->sc_rb.rb_nrbuf;
 1065         unsigned int ri;
 1066         u_int32_t flags;
 1067 
 1068         ri = sc->sc_rb.rb_rdtail;
 1069 
 1070         /*
 1071          * Process all buffers with valid data.
 1072          */
 1073         for (;;) {
 1074                 flags = HME_XD_GETFLAGS(sc->sc_pci, xdr, ri);
 1075                 if (flags & HME_XD_OWN)
 1076                         break;
 1077 
 1078                 if (flags & HME_XD_OFL) {
 1079                         printf("%s: buffer overflow, ri=%d; flags=0x%x\n",
 1080                                         sc->sc_dev.dv_xname, ri, flags);
 1081                 } else
 1082                         hme_read(sc, ri, flags);
 1083 
 1084                 /* This buffer can be used by the hardware again */
 1085                 HME_XD_SETFLAGS(sc->sc_pci, xdr, ri,
 1086                                 HME_XD_OWN | HME_XD_ENCODE_RSIZE(_HME_BUFSZ));
 1087 
 1088                 if (++ri == nrbuf)
 1089                         ri = 0;
 1090         }
 1091 
 1092         sc->sc_rb.rb_rdtail = ri;
 1093 
 1094         return (1);
 1095 }
 1096 
 1097 int
 1098 hme_eint(sc, status)
 1099         struct hme_softc *sc;
 1100         u_int status;
 1101 {
 1102         char bits[128];
 1103 
 1104         if ((status & HME_SEB_STAT_MIFIRQ) != 0) {
 1105                 bus_space_tag_t t = sc->sc_bustag;
 1106                 bus_space_handle_t mif = sc->sc_mif;
 1107                 u_int32_t cf, st, sm;
 1108                 cf = bus_space_read_4(t, mif, HME_MIFI_CFG);
 1109                 st = bus_space_read_4(t, mif, HME_MIFI_STAT);
 1110                 sm = bus_space_read_4(t, mif, HME_MIFI_SM);
 1111                 printf("%s: XXXlink status changed: cfg=%x, stat %x, sm %x\n",
 1112                         sc->sc_dev.dv_xname, cf, st, sm);
 1113                 return (1);
 1114         }
 1115 
 1116         printf("%s: status=%s\n", sc->sc_dev.dv_xname,
 1117                 bitmask_snprintf(status, HME_SEB_STAT_BITS, bits,sizeof(bits)));
 1118         return (1);
 1119 }
 1120 
 1121 int
 1122 hme_intr(v)
 1123         void *v;
 1124 {
 1125         struct hme_softc *sc = (struct hme_softc *)v;
 1126         bus_space_tag_t t = sc->sc_bustag;
 1127         bus_space_handle_t seb = sc->sc_seb;
 1128         u_int32_t status;
 1129         int r = 0;
 1130 
 1131         status = bus_space_read_4(t, seb, HME_SEBI_STAT);
 1132 
 1133         if ((status & HME_SEB_STAT_ALL_ERRORS) != 0)
 1134                 r |= hme_eint(sc, status);
 1135 
 1136         if ((status & (HME_SEB_STAT_TXALL | HME_SEB_STAT_HOSTTOTX)) != 0)
 1137                 r |= hme_tint(sc);
 1138 
 1139         if ((status & HME_SEB_STAT_RXTOHOST) != 0)
 1140                 r |= hme_rint(sc);
 1141 
 1142 #if NRND > 0
 1143         rnd_add_uint32(&sc->rnd_source, status);
 1144 #endif
 1145 
 1146         return (r);
 1147 }
 1148 
 1149 
 1150 void
 1151 hme_watchdog(ifp)
 1152         struct ifnet *ifp;
 1153 {
 1154         struct hme_softc *sc = ifp->if_softc;
 1155 
 1156         log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
 1157         ++ifp->if_oerrors;
 1158 
 1159         hme_reset(sc);
 1160 }
 1161 
 1162 /*
 1163  * Initialize the MII Management Interface
 1164  */
 1165 void
 1166 hme_mifinit(sc)
 1167         struct hme_softc *sc;
 1168 {
 1169         bus_space_tag_t t = sc->sc_bustag;
 1170         bus_space_handle_t mif = sc->sc_mif;
 1171         bus_space_handle_t mac = sc->sc_mac;
 1172         int instance, phy;
 1173         u_int32_t v;
 1174 
 1175         if (sc->sc_media.ifm_cur != NULL) {
 1176                 instance = IFM_INST(sc->sc_media.ifm_cur->ifm_media);
 1177                 phy = sc->sc_phys[instance];
 1178         } else
 1179                 /* No media set yet, pick phy arbitrarily.. */
 1180                 phy = HME_PHYAD_EXTERNAL;
 1181 
 1182         /* Configure the MIF in frame mode, no poll, current phy select */
 1183         v = 0;
 1184         if (phy == HME_PHYAD_EXTERNAL)
 1185                 v |= HME_MIF_CFG_PHY;
 1186         bus_space_write_4(t, mif, HME_MIFI_CFG, v);
 1187 
 1188         /* If an external transceiver is selected, enable its MII drivers */
 1189         v = bus_space_read_4(t, mac, HME_MACI_XIF);
 1190         v &= ~HME_MAC_XIF_MIIENABLE;
 1191         if (phy == HME_PHYAD_EXTERNAL)
 1192                 v |= HME_MAC_XIF_MIIENABLE;
 1193         bus_space_write_4(t, mac, HME_MACI_XIF, v);
 1194 }
 1195 
 1196 /*
 1197  * MII interface
 1198  */
 1199 static int
 1200 hme_mii_readreg(self, phy, reg)
 1201         struct device *self;
 1202         int phy, reg;
 1203 {
 1204         struct hme_softc *sc = (void *)self;
 1205         bus_space_tag_t t = sc->sc_bustag;
 1206         bus_space_handle_t mif = sc->sc_mif;
 1207         bus_space_handle_t mac = sc->sc_mac;
 1208         u_int32_t v, xif_cfg, mifi_cfg;
 1209         int n;
 1210 
 1211         /* We can at most have two PHYs */
 1212         if (phy != HME_PHYAD_EXTERNAL && phy != HME_PHYAD_INTERNAL)
 1213                 return (0);
 1214 
 1215         /* Select the desired PHY in the MIF configuration register */
 1216         v = mifi_cfg = bus_space_read_4(t, mif, HME_MIFI_CFG);
 1217         v &= ~HME_MIF_CFG_PHY;
 1218         if (phy == HME_PHYAD_EXTERNAL)
 1219                 v |= HME_MIF_CFG_PHY;
 1220         bus_space_write_4(t, mif, HME_MIFI_CFG, v);
 1221 
 1222         /* Enable MII drivers on external transceiver */
 1223         v = xif_cfg = bus_space_read_4(t, mac, HME_MACI_XIF);
 1224         if (phy == HME_PHYAD_EXTERNAL)
 1225                 v |= HME_MAC_XIF_MIIENABLE;
 1226         else
 1227                 v &= ~HME_MAC_XIF_MIIENABLE;
 1228         bus_space_write_4(t, mac, HME_MACI_XIF, v);
 1229 
 1230 #if 0
 1231 /* This doesn't work reliably; the MDIO_1 bit is off most of the time */
 1232         /*
 1233          * Check whether a transceiver is connected by testing
 1234          * the MIF configuration register's MDI_X bits. Note that
 1235          * MDI_0 (int) == 0x100 and MDI_1 (ext) == 0x200; see hmereg.h
 1236          */
 1237         mif_mdi_bit = 1 << (8 + (1 - phy));
 1238         delay(100);
 1239         v = bus_space_read_4(t, mif, HME_MIFI_CFG);
 1240         if ((v & mif_mdi_bit) == 0)
 1241                 return (0);
 1242 #endif
 1243 
 1244         /* Construct the frame command */
 1245         v = (MII_COMMAND_START << HME_MIF_FO_ST_SHIFT) |
 1246             HME_MIF_FO_TAMSB |
 1247             (MII_COMMAND_READ << HME_MIF_FO_OPC_SHIFT) |
 1248             (phy << HME_MIF_FO_PHYAD_SHIFT) |
 1249             (reg << HME_MIF_FO_REGAD_SHIFT);
 1250 
 1251         bus_space_write_4(t, mif, HME_MIFI_FO, v);
 1252         for (n = 0; n < 100; n++) {
 1253                 DELAY(1);
 1254                 v = bus_space_read_4(t, mif, HME_MIFI_FO);
 1255                 if (v & HME_MIF_FO_TALSB) {
 1256                         v &= HME_MIF_FO_DATA;
 1257                         goto out;
 1258                 }
 1259         }
 1260 
 1261         v = 0;
 1262         printf("%s: mii_read timeout\n", sc->sc_dev.dv_xname);
 1263 
 1264 out:
 1265         /* Restore MIFI_CFG register */
 1266         bus_space_write_4(t, mif, HME_MIFI_CFG, mifi_cfg);
 1267         /* Restore XIF register */
 1268         bus_space_write_4(t, mac, HME_MACI_XIF, xif_cfg);
 1269         return (v);
 1270 }
 1271 
 1272 static void
 1273 hme_mii_writereg(self, phy, reg, val)
 1274         struct device *self;
 1275         int phy, reg, val;
 1276 {
 1277         struct hme_softc *sc = (void *)self;
 1278         bus_space_tag_t t = sc->sc_bustag;
 1279         bus_space_handle_t mif = sc->sc_mif;
 1280         bus_space_handle_t mac = sc->sc_mac;
 1281         u_int32_t v, xif_cfg, mifi_cfg;
 1282         int n;
 1283 
 1284         /* We can at most have two PHYs */
 1285         if (phy != HME_PHYAD_EXTERNAL && phy != HME_PHYAD_INTERNAL)
 1286                 return;
 1287 
 1288         /* Select the desired PHY in the MIF configuration register */
 1289         v = mifi_cfg = bus_space_read_4(t, mif, HME_MIFI_CFG);
 1290         v &= ~HME_MIF_CFG_PHY;
 1291         if (phy == HME_PHYAD_EXTERNAL)
 1292                 v |= HME_MIF_CFG_PHY;
 1293         bus_space_write_4(t, mif, HME_MIFI_CFG, v);
 1294 
 1295         /* Enable MII drivers on external transceiver */
 1296         v = xif_cfg = bus_space_read_4(t, mac, HME_MACI_XIF);
 1297         if (phy == HME_PHYAD_EXTERNAL)
 1298                 v |= HME_MAC_XIF_MIIENABLE;
 1299         else
 1300                 v &= ~HME_MAC_XIF_MIIENABLE;
 1301         bus_space_write_4(t, mac, HME_MACI_XIF, v);
 1302 
 1303 #if 0
 1304 /* This doesn't work reliably; the MDIO_1 bit is off most of the time */
 1305         /*
 1306          * Check whether a transceiver is connected by testing
 1307          * the MIF configuration register's MDI_X bits. Note that
 1308          * MDI_0 (int) == 0x100 and MDI_1 (ext) == 0x200; see hmereg.h
 1309          */
 1310         mif_mdi_bit = 1 << (8 + (1 - phy));
 1311         delay(100);
 1312         v = bus_space_read_4(t, mif, HME_MIFI_CFG);
 1313         if ((v & mif_mdi_bit) == 0)
 1314                 return;
 1315 #endif
 1316 
 1317         /* Construct the frame command */
 1318         v = (MII_COMMAND_START << HME_MIF_FO_ST_SHIFT)  |
 1319             HME_MIF_FO_TAMSB                            |
 1320             (MII_COMMAND_WRITE << HME_MIF_FO_OPC_SHIFT) |
 1321             (phy << HME_MIF_FO_PHYAD_SHIFT)             |
 1322             (reg << HME_MIF_FO_REGAD_SHIFT)             |
 1323             (val & HME_MIF_FO_DATA);
 1324 
 1325         bus_space_write_4(t, mif, HME_MIFI_FO, v);
 1326         for (n = 0; n < 100; n++) {
 1327                 DELAY(1);
 1328                 v = bus_space_read_4(t, mif, HME_MIFI_FO);
 1329                 if (v & HME_MIF_FO_TALSB)
 1330                         goto out;
 1331         }
 1332 
 1333         printf("%s: mii_write timeout\n", sc->sc_dev.dv_xname);
 1334 out:
 1335         /* Restore MIFI_CFG register */
 1336         bus_space_write_4(t, mif, HME_MIFI_CFG, mifi_cfg);
 1337         /* Restore XIF register */
 1338         bus_space_write_4(t, mac, HME_MACI_XIF, xif_cfg);
 1339 }
 1340 
 1341 static void
 1342 hme_mii_statchg(dev)
 1343         struct device *dev;
 1344 {
 1345         struct hme_softc *sc = (void *)dev;
 1346         bus_space_tag_t t = sc->sc_bustag;
 1347         bus_space_handle_t mac = sc->sc_mac;
 1348         u_int32_t v;
 1349 
 1350 #ifdef HMEDEBUG
 1351         if (sc->sc_debug)
 1352                 printf("hme_mii_statchg: status change\n");
 1353 #endif
 1354 
 1355         /* Set the MAC Full Duplex bit appropriately */
 1356         /* Apparently the hme chip is SIMPLEX if working in full duplex mode,
 1357            but not otherwise. */
 1358         v = bus_space_read_4(t, mac, HME_MACI_TXCFG);
 1359         if ((IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) != 0) {
 1360                 v |= HME_MAC_TXCFG_FULLDPLX;
 1361                 sc->sc_ethercom.ec_if.if_flags |= IFF_SIMPLEX;
 1362         } else {
 1363                 v &= ~HME_MAC_TXCFG_FULLDPLX;
 1364                 sc->sc_ethercom.ec_if.if_flags &= ~IFF_SIMPLEX;
 1365         }
 1366         sc->sc_if_flags = sc->sc_ethercom.ec_if.if_flags;
 1367         bus_space_write_4(t, mac, HME_MACI_TXCFG, v);
 1368 }
 1369 
 1370 int
 1371 hme_mediachange(ifp)
 1372         struct ifnet *ifp;
 1373 {
 1374         struct hme_softc *sc = ifp->if_softc;
 1375         bus_space_tag_t t = sc->sc_bustag;
 1376         bus_space_handle_t mif = sc->sc_mif;
 1377         bus_space_handle_t mac = sc->sc_mac;
 1378         int instance = IFM_INST(sc->sc_mii.mii_media.ifm_cur->ifm_media);
 1379         int phy = sc->sc_phys[instance];
 1380         u_int32_t v;
 1381 
 1382 #ifdef HMEDEBUG
 1383         if (sc->sc_debug)
 1384                 printf("hme_mediachange: phy = %d\n", phy);
 1385 #endif
 1386         if (IFM_TYPE(sc->sc_media.ifm_media) != IFM_ETHER)
 1387                 return (EINVAL);
 1388 
 1389         /* Select the current PHY in the MIF configuration register */
 1390         v = bus_space_read_4(t, mif, HME_MIFI_CFG);
 1391         v &= ~HME_MIF_CFG_PHY;
 1392         if (phy == HME_PHYAD_EXTERNAL)
 1393                 v |= HME_MIF_CFG_PHY;
 1394         bus_space_write_4(t, mif, HME_MIFI_CFG, v);
 1395 
 1396         /* If an external transceiver is selected, enable its MII drivers */
 1397         v = bus_space_read_4(t, mac, HME_MACI_XIF);
 1398         v &= ~HME_MAC_XIF_MIIENABLE;
 1399         if (phy == HME_PHYAD_EXTERNAL)
 1400                 v |= HME_MAC_XIF_MIIENABLE;
 1401         bus_space_write_4(t, mac, HME_MACI_XIF, v);
 1402 
 1403         return (mii_mediachg(&sc->sc_mii));
 1404 }
 1405 
 1406 void
 1407 hme_mediastatus(ifp, ifmr)
 1408         struct ifnet *ifp;
 1409         struct ifmediareq *ifmr;
 1410 {
 1411         struct hme_softc *sc = ifp->if_softc;
 1412 
 1413         if ((ifp->if_flags & IFF_UP) == 0)
 1414                 return;
 1415 
 1416         mii_pollstat(&sc->sc_mii);
 1417         ifmr->ifm_active = sc->sc_mii.mii_media_active;
 1418         ifmr->ifm_status = sc->sc_mii.mii_media_status;
 1419 }
 1420 
 1421 /*
 1422  * Process an ioctl request.
 1423  */
 1424 int
 1425 hme_ioctl(ifp, cmd, data)
 1426         struct ifnet *ifp;
 1427         u_long cmd;
 1428         caddr_t data;
 1429 {
 1430         struct hme_softc *sc = ifp->if_softc;
 1431         struct ifaddr *ifa = (struct ifaddr *)data;
 1432         struct ifreq *ifr = (struct ifreq *)data;
 1433         int s, error = 0;
 1434 
 1435         s = splnet();
 1436 
 1437         switch (cmd) {
 1438 
 1439         case SIOCSIFADDR:
 1440                 switch (ifa->ifa_addr->sa_family) {
 1441 #ifdef INET
 1442                 case AF_INET:
 1443                         if (ifp->if_flags & IFF_UP)
 1444                                 hme_setladrf(sc);
 1445                         else {
 1446                                 ifp->if_flags |= IFF_UP;
 1447                                 hme_init(sc);
 1448                         }
 1449                         arp_ifinit(ifp, ifa);
 1450                         break;
 1451 #endif
 1452 #ifdef NS
 1453                 case AF_NS:
 1454                     {
 1455                         struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
 1456 
 1457                         if (ns_nullhost(*ina))
 1458                                 ina->x_host =
 1459                                     *(union ns_host *)LLADDR(ifp->if_sadl);
 1460                         else {
 1461                                 memcpy(LLADDR(ifp->if_sadl),
 1462                                     ina->x_host.c_host, sizeof(sc->sc_enaddr));
 1463                         }
 1464                         /* Set new address. */
 1465                         if (ifp->if_flags & IFF_UP)
 1466                                 hme_setladrf(sc);
 1467                         else {
 1468                                 ifp->if_flags |= IFF_UP;
 1469                                 hme_init(sc);
 1470                         }
 1471                         break;
 1472                     }
 1473 #endif
 1474                 default:
 1475                         ifp->if_flags |= IFF_UP;
 1476                         hme_init(sc);
 1477                         break;
 1478                 }
 1479                 break;
 1480 
 1481         case SIOCSIFFLAGS:
 1482 #ifdef HMEDEBUG
 1483                 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0;
 1484 #endif
 1485 
 1486                 if ((ifp->if_flags & IFF_UP) == 0 &&
 1487                     (ifp->if_flags & IFF_RUNNING) != 0) {
 1488                         /*
 1489                          * If interface is marked down and it is running, then
 1490                          * stop it.
 1491                          */
 1492                         hme_stop(sc);
 1493                         ifp->if_flags &= ~IFF_RUNNING;
 1494                 } else if ((ifp->if_flags & IFF_UP) != 0 &&
 1495                            (ifp->if_flags & IFF_RUNNING) == 0) {
 1496                         /*
 1497                          * If interface is marked up and it is stopped, then
 1498                          * start it.
 1499                          */
 1500                         hme_init(sc);
 1501                 } else if ((ifp->if_flags & IFF_UP) != 0) {
 1502                         /*
 1503                          * If setting debug or promiscuous mode, do not reset
 1504                          * the chip; for everything else, call hme_init()
 1505                          * which will trigger a reset.
 1506                          */
 1507 #define RESETIGN (IFF_CANTCHANGE | IFF_DEBUG)
 1508                         if (ifp->if_flags != sc->sc_if_flags) {
 1509                                 if ((ifp->if_flags & (~RESETIGN))
 1510                                     == (sc->sc_if_flags & (~RESETIGN)))
 1511                                         hme_setladrf(sc);
 1512                                 else
 1513                                         hme_init(sc);
 1514                         }
 1515 #undef RESETIGN
 1516                 }
 1517 
 1518                 if (sc->sc_ec_capenable != sc->sc_ethercom.ec_capenable)
 1519                         hme_init(sc);
 1520 
 1521                 break;
 1522 
 1523         case SIOCADDMULTI:
 1524         case SIOCDELMULTI:
 1525                 error = (cmd == SIOCADDMULTI) ?
 1526                     ether_addmulti(ifr, &sc->sc_ethercom) :
 1527                     ether_delmulti(ifr, &sc->sc_ethercom);
 1528 
 1529                 if (error == ENETRESET) {
 1530                         /*
 1531                          * Multicast list has changed; set the hardware filter
 1532                          * accordingly.
 1533                          */
 1534                         if (ifp->if_flags & IFF_RUNNING)
 1535                                 hme_setladrf(sc);
 1536                         error = 0;
 1537                 }
 1538                 break;
 1539 
 1540         case SIOCGIFMEDIA:
 1541         case SIOCSIFMEDIA:
 1542                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
 1543                 break;
 1544 
 1545         default:
 1546                 error = EINVAL;
 1547                 break;
 1548         }
 1549 
 1550         sc->sc_if_flags = ifp->if_flags;
 1551         splx(s);
 1552         return (error);
 1553 }
 1554 
 1555 void
 1556 hme_shutdown(arg)
 1557         void *arg;
 1558 {
 1559 
 1560         hme_stop((struct hme_softc *)arg);
 1561 }
 1562 
 1563 /*
 1564  * Set up the logical address filter.
 1565  */
 1566 void
 1567 hme_setladrf(sc)
 1568         struct hme_softc *sc;
 1569 {
 1570         struct ifnet *ifp = &sc->sc_ethercom.ec_if;
 1571         struct ether_multi *enm;
 1572         struct ether_multistep step;
 1573         struct ethercom *ec = &sc->sc_ethercom;
 1574         bus_space_tag_t t = sc->sc_bustag;
 1575         bus_space_handle_t mac = sc->sc_mac;
 1576         u_char *cp;
 1577         u_int32_t crc;
 1578         u_int32_t hash[4];
 1579         u_int32_t v;
 1580         int len;
 1581 
 1582         /* Clear hash table */
 1583         hash[3] = hash[2] = hash[1] = hash[0] = 0;
 1584 
 1585         /* Get current RX configuration */
 1586         v = bus_space_read_4(t, mac, HME_MACI_RXCFG);
 1587 
 1588         if ((ifp->if_flags & IFF_PROMISC) != 0) {
 1589                 /* Turn on promiscuous mode; turn off the hash filter */
 1590                 v |= HME_MAC_RXCFG_PMISC;
 1591                 v &= ~HME_MAC_RXCFG_HENABLE;
 1592                 ifp->if_flags |= IFF_ALLMULTI;
 1593                 goto chipit;
 1594         }
 1595 
 1596         /* Turn off promiscuous mode; turn on the hash filter */
 1597         v &= ~HME_MAC_RXCFG_PMISC;
 1598         v |= HME_MAC_RXCFG_HENABLE;
 1599 
 1600         /*
 1601          * Set up multicast address filter by passing all multicast addresses
 1602          * through a crc generator, and then using the high order 6 bits as an
 1603          * index into the 64 bit logical address filter.  The high order bit
 1604          * selects the word, while the rest of the bits select the bit within
 1605          * the word.
 1606          */
 1607 
 1608         ETHER_FIRST_MULTI(step, ec, enm);
 1609         while (enm != NULL) {
 1610                 if (ether_cmp(enm->enm_addrlo, enm->enm_addrhi)) {
 1611                         /*
 1612                          * We must listen to a range of multicast addresses.
 1613                          * For now, just accept all multicasts, rather than
 1614                          * trying to set only those filter bits needed to match
 1615                          * the range.  (At this time, the only use of address
 1616                          * ranges is for IP multicast routing, for which the
 1617                          * range is big enough to require all bits set.)
 1618                          */
 1619                         hash[3] = hash[2] = hash[1] = hash[0] = 0xffff;
 1620                         ifp->if_flags |= IFF_ALLMULTI;
 1621                         goto chipit;
 1622                 }
 1623 
 1624                 cp = enm->enm_addrlo;
 1625                 crc = 0xffffffff;
 1626                 for (len = sizeof(enm->enm_addrlo); --len >= 0;) {
 1627                         int octet = *cp++;
 1628                         int i;
 1629 
 1630 #define MC_POLY_LE      0xedb88320UL    /* mcast crc, little endian */
 1631                         for (i = 0; i < 8; i++) {
 1632                                 if ((crc & 1) ^ (octet & 1)) {
 1633                                         crc >>= 1;
 1634                                         crc ^= MC_POLY_LE;
 1635                                 } else {
 1636                                         crc >>= 1;
 1637                                 }
 1638                                 octet >>= 1;
 1639                         }
 1640                 }
 1641                 /* Just want the 6 most significant bits. */
 1642                 crc >>= 26;
 1643 
 1644                 /* Set the corresponding bit in the filter. */
 1645                 hash[crc >> 4] |= 1 << (crc & 0xf);
 1646 
 1647                 ETHER_NEXT_MULTI(step, enm);
 1648         }
 1649 
 1650         ifp->if_flags &= ~IFF_ALLMULTI;
 1651 
 1652 chipit:
 1653         /* Now load the hash table into the chip */
 1654         bus_space_write_4(t, mac, HME_MACI_HASHTAB0, hash[0]);
 1655         bus_space_write_4(t, mac, HME_MACI_HASHTAB1, hash[1]);
 1656         bus_space_write_4(t, mac, HME_MACI_HASHTAB2, hash[2]);
 1657         bus_space_write_4(t, mac, HME_MACI_HASHTAB3, hash[3]);
 1658         bus_space_write_4(t, mac, HME_MACI_RXCFG, v);
 1659 }
 1660 
 1661 /*
 1662  * Routines for accessing the transmit and receive buffers.
 1663  * The various CPU and adapter configurations supported by this
 1664  * driver require three different access methods for buffers
 1665  * and descriptors:
 1666  *      (1) contig (contiguous data; no padding),
 1667  *      (2) gap2 (two bytes of data followed by two bytes of padding),
 1668  *      (3) gap16 (16 bytes of data followed by 16 bytes of padding).
 1669  */
 1670 
 1671 #if 0
 1672 /*
 1673  * contig: contiguous data with no padding.
 1674  *
 1675  * Buffers may have any alignment.
 1676  */
 1677 
 1678 void
 1679 hme_copytobuf_contig(sc, from, ri, len)
 1680         struct hme_softc *sc;
 1681         void *from;
 1682         int ri, len;
 1683 {
 1684         volatile caddr_t buf = sc->sc_rb.rb_txbuf + (ri * _HME_BUFSZ);
 1685 
 1686         /*
 1687          * Just call memcpy() to do the work.
 1688          */
 1689         memcpy(buf, from, len);
 1690 }
 1691 
 1692 void
 1693 hme_copyfrombuf_contig(sc, to, boff, len)
 1694         struct hme_softc *sc;
 1695         void *to;
 1696         int boff, len;
 1697 {
 1698         volatile caddr_t buf = sc->sc_rb.rb_rxbuf + (ri * _HME_BUFSZ);
 1699 
 1700         /*
 1701          * Just call memcpy() to do the work.
 1702          */
 1703         memcpy(to, buf, len);
 1704 }
 1705 #endif

Cache object: 2742e378bc79c2ec17e182a394077dae


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