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

Cache object: 3be99fb2e56419d235097e53309b0a46


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