root/dev/pci/if_cas.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cas_match
  2. cas_pci_enaddr
  3. cas_attach
  4. cas_config
  5. cas_tick
  6. cas_bitwait
  7. cas_reset
  8. cas_rxdrain
  9. cas_stop
  10. cas_reset_rx
  11. cas_reset_tx
  12. cas_disable_rx
  13. cas_disable_tx
  14. cas_meminit
  15. cas_ringsize
  16. cas_cringsize
  17. cas_init
  18. cas_init_regs
  19. cas_rint
  20. cas_add_rxbuf
  21. cas_eint
  22. cas_pint
  23. cas_intr
  24. cas_watchdog
  25. cas_mifinit
  26. cas_mii_readreg
  27. cas_mii_writereg
  28. cas_mii_statchg
  29. cas_pcs_readreg
  30. cas_pcs_writereg
  31. cas_mediachange
  32. cas_mediastatus
  33. cas_ioctl
  34. cas_shutdown
  35. cas_setladrf
  36. cas_encap
  37. cas_tint
  38. cas_start

    1 /*      $OpenBSD: if_cas.c,v 1.8 2007/04/18 21:08:35 kettenis Exp $     */
    2 
    3 /*
    4  *
    5  * Copyright (C) 2007 Mark Kettenis.
    6  * Copyright (C) 2001 Eduardo Horvath.
    7  * All rights reserved.
    8  *
    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  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR  BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  */
   32 
   33 /*
   34  * Driver for Sun Cassini ethernet controllers.
   35  */
   36 
   37 #include "bpfilter.h"
   38 
   39 #include <sys/param.h>
   40 #include <sys/systm.h>
   41 #include <sys/timeout.h>
   42 #include <sys/mbuf.h>
   43 #include <sys/syslog.h>
   44 #include <sys/malloc.h>
   45 #include <sys/kernel.h>
   46 #include <sys/socket.h>
   47 #include <sys/ioctl.h>
   48 #include <sys/errno.h>
   49 #include <sys/device.h>
   50 
   51 #include <machine/endian.h>
   52 
   53 #include <net/if.h>
   54 #include <net/if_dl.h>
   55 #include <net/if_media.h>
   56 
   57 #ifdef INET
   58 #include <netinet/in.h>
   59 #include <netinet/if_ether.h>
   60 #endif
   61 
   62 #if NBPFILTER > 0
   63 #include <net/bpf.h>
   64 #endif
   65 
   66 #include <machine/bus.h>
   67 #include <machine/intr.h>
   68 
   69 #include <dev/mii/mii.h>
   70 #include <dev/mii/miivar.h>
   71 #include <dev/mii/mii_bitbang.h>
   72 
   73 #include <dev/pci/if_casreg.h>
   74 #include <dev/pci/if_casvar.h>
   75 
   76 #include <dev/pci/pcivar.h>
   77 #include <dev/pci/pcireg.h>
   78 #include <dev/pci/pcidevs.h>
   79 
   80 #ifdef __sparc64__
   81 #include <dev/ofw/openfirm.h>
   82 #endif
   83 
   84 #define TRIES   10000
   85 
   86 struct cfdriver cas_cd = {
   87         NULL, "cas", DV_IFNET
   88 };
   89 
   90 int     cas_match(struct device *, void *, void *);
   91 void    cas_attach(struct device *, struct device *, void *);
   92 int     cas_pci_enaddr(struct cas_softc *, struct pci_attach_args *);
   93 
   94 struct cfattach cas_ca = {
   95         sizeof(struct cas_softc), cas_match, cas_attach
   96 };
   97 
   98 void            cas_config(struct cas_softc *);
   99 void            cas_start(struct ifnet *);
  100 void            cas_stop(struct ifnet *, int);
  101 int             cas_ioctl(struct ifnet *, u_long, caddr_t);
  102 void            cas_tick(void *);
  103 void            cas_watchdog(struct ifnet *);
  104 void            cas_shutdown(void *);
  105 int             cas_init(struct ifnet *);
  106 void            cas_init_regs(struct cas_softc *);
  107 int             cas_ringsize(int);
  108 int             cas_cringsize(int);
  109 int             cas_meminit(struct cas_softc *);
  110 void            cas_mifinit(struct cas_softc *);
  111 int             cas_bitwait(struct cas_softc *, bus_space_handle_t, int,
  112                     u_int32_t, u_int32_t);
  113 void            cas_reset(struct cas_softc *);
  114 int             cas_reset_rx(struct cas_softc *);
  115 int             cas_reset_tx(struct cas_softc *);
  116 int             cas_disable_rx(struct cas_softc *);
  117 int             cas_disable_tx(struct cas_softc *);
  118 void            cas_rxdrain(struct cas_softc *);
  119 int             cas_add_rxbuf(struct cas_softc *, int idx);
  120 void            cas_setladrf(struct cas_softc *);
  121 int             cas_encap(struct cas_softc *, struct mbuf *, u_int32_t *);
  122 
  123 /* MII methods & callbacks */
  124 int             cas_mii_readreg(struct device *, int, int);
  125 void            cas_mii_writereg(struct device *, int, int, int);
  126 void            cas_mii_statchg(struct device *);
  127 int             cas_pcs_readreg(struct device *, int, int);
  128 void            cas_pcs_writereg(struct device *, int, int, int);
  129 
  130 int             cas_mediachange(struct ifnet *);
  131 void            cas_mediastatus(struct ifnet *, struct ifmediareq *);
  132 
  133 int             cas_eint(struct cas_softc *, u_int);
  134 int             cas_rint(struct cas_softc *);
  135 int             cas_tint(struct cas_softc *, u_int32_t);
  136 int             cas_pint(struct cas_softc *);
  137 int             cas_intr(void *);
  138 
  139 #ifdef CAS_DEBUG
  140 #define DPRINTF(sc, x)  if ((sc)->sc_arpcom.ac_if.if_flags & IFF_DEBUG) \
  141                                 printf x
  142 #else
  143 #define DPRINTF(sc, x)  /* nothing */
  144 #endif
  145 
  146 const struct pci_matchid cas_pci_devices[] = {
  147         { PCI_VENDOR_SUN, PCI_PRODUCT_SUN_CASSINI }
  148 };
  149 
  150 int
  151 cas_match(struct device *parent, void *cf, void *aux)
  152 {
  153         return (pci_matchbyid((struct pci_attach_args *)aux, cas_pci_devices,
  154             sizeof(cas_pci_devices)/sizeof(cas_pci_devices[0])));
  155 }
  156 
  157 #define PROMHDR_PTR_DATA        0x18
  158 #define PROMDATA_PTR_VPD        0x08
  159 #define PROMDATA_DATA2          0x0a
  160 
  161 static const u_int8_t cas_promhdr[] = { 0x55, 0xaa };
  162 static const u_int8_t cas_promdat[] = {
  163         'P', 'C', 'I', 'R',
  164         PCI_VENDOR_SUN & 0xff, PCI_VENDOR_SUN >> 8,
  165         PCI_PRODUCT_SUN_CASSINI & 0xff, PCI_PRODUCT_SUN_CASSINI >> 8
  166 };
  167 
  168 static const u_int8_t cas_promdat2[] = {
  169         0x18, 0x00,                     /* structure length */
  170         0x00,                           /* structure revision */
  171         0x00,                           /* interface revision */
  172         PCI_SUBCLASS_NETWORK_ETHERNET,  /* subclass code */
  173         PCI_CLASS_NETWORK               /* class code */
  174 };
  175 
  176 int
  177 cas_pci_enaddr(struct cas_softc *sc, struct pci_attach_args *pa)
  178 {
  179         struct pci_vpd_largeres *res;
  180         struct pci_vpd *vpd;
  181         bus_space_handle_t romh;
  182         bus_space_tag_t romt;
  183         bus_size_t romsize;
  184         u_int8_t buf[32], *desc;
  185         pcireg_t address, mask;
  186         int dataoff, vpdoff, len;
  187         int rv = -1;
  188 
  189         address = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
  190         pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, 0xfffffffe);
  191         mask = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
  192         address |= PCI_ROM_ENABLE;
  193         pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, address);
  194 
  195         romt = pa->pa_memt;
  196         romsize = PCI_ROM_SIZE(mask);
  197         if (bus_space_map(romt, PCI_ROM_ADDR(address), romsize, 0, &romh)) {
  198                 romsize = 0;
  199                 goto fail;
  200         }
  201 
  202         bus_space_read_region_1(romt, romh, 0, buf, sizeof(buf));
  203         if (bcmp(buf, cas_promhdr, sizeof(cas_promhdr)))
  204                 goto fail;
  205 
  206         dataoff = buf[PROMHDR_PTR_DATA] | (buf[PROMHDR_PTR_DATA + 1] << 8);
  207         if (dataoff < 0x1c)
  208                 goto fail;
  209 
  210         bus_space_read_region_1(romt, romh, dataoff, buf, sizeof(buf));
  211         if (bcmp(buf, cas_promdat, sizeof(cas_promdat)) ||
  212             bcmp(buf + PROMDATA_DATA2, cas_promdat2, sizeof(cas_promdat2)))
  213                 goto fail;
  214 
  215         vpdoff = buf[PROMDATA_PTR_VPD] | (buf[PROMDATA_PTR_VPD + 1] << 8);
  216         if (vpdoff < 0x1c)
  217                 goto fail;
  218 
  219 next:
  220         bus_space_read_region_1(romt, romh, vpdoff, buf, sizeof(buf));
  221         if (!PCI_VPDRES_ISLARGE(buf[0]))
  222                 goto fail;
  223 
  224         res = (struct pci_vpd_largeres *)buf;
  225         vpdoff += sizeof(*res);
  226 
  227         len = ((res->vpdres_len_msb << 8) + res->vpdres_len_lsb);
  228         switch(PCI_VPDRES_LARGE_NAME(res->vpdres_byte0)) {
  229         case PCI_VPDRES_TYPE_IDENTIFIER_STRING:
  230                 /* Skip identifier string. */
  231                 vpdoff += len;
  232                 goto next;
  233 
  234         case PCI_VPDRES_TYPE_VPD:
  235                 while (len > 0) {
  236                         bus_space_read_region_1(romt, romh, vpdoff,
  237                              buf, sizeof(buf));
  238 
  239                         vpd = (struct pci_vpd *)buf;
  240                         vpdoff += sizeof(*vpd) + vpd->vpd_len;
  241                         len -= sizeof(*vpd) + vpd->vpd_len;
  242 
  243                         /*
  244                          * We're looking for an "Enhanced" VPD...
  245                          */
  246                         if (vpd->vpd_key0 != 'Z')
  247                                 continue;
  248 
  249                         desc = buf + sizeof(*vpd);
  250 
  251                         /* 
  252                          * ...which is an instance property...
  253                          */
  254                         if (desc[0] != 'I')
  255                                 continue;
  256                         desc += 3;
  257 
  258                         /* 
  259                          * ...that's a byte array with the proper
  260                          * length for a MAC address...
  261                          */
  262                         if (desc[0] != 'B' || desc[1] != ETHER_ADDR_LEN)
  263                                 continue;
  264                         desc += 2;
  265 
  266                         /*
  267                          * ...named "local-mac-address".
  268                          */
  269                         if (strcmp(desc, "local-mac-address") != 0)
  270                                 continue;
  271                         desc += strlen("local-mac-address") + 1;
  272                                         
  273                         bcopy(desc, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN);
  274                         rv = 0;
  275                 }
  276                 break;
  277 
  278         default:
  279                 goto fail;
  280         }
  281 
  282  fail:
  283         if (romsize != 0)
  284                 bus_space_unmap(romt, romh, romsize);
  285 
  286         address = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_ROM_REG);
  287         address &= ~PCI_ROM_ENABLE;
  288         pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_ROM_REG, address);
  289 
  290         return (rv);
  291 }
  292 
  293 void
  294 cas_attach(struct device *parent, struct device *self, void *aux)
  295 {
  296         struct pci_attach_args *pa = aux;
  297         struct cas_softc *sc = (void *)self;
  298         pci_intr_handle_t ih;
  299 #ifdef __sparc64__
  300         /* XXX the following declarations should be elsewhere */
  301         extern void myetheraddr(u_char *);
  302 #endif
  303         const char *intrstr = NULL;
  304         bus_size_t size;
  305         int gotenaddr = 0;
  306 
  307         sc->sc_dmatag = pa->pa_dmat;
  308 
  309 #define PCI_CAS_BASEADDR        0x10
  310         if (pci_mapreg_map(pa, PCI_CAS_BASEADDR, PCI_MAPREG_TYPE_MEM, 0,
  311             &sc->sc_memt, &sc->sc_memh, NULL, &size, 0) != 0) {
  312                 printf(": could not map registers\n");
  313                 return;
  314         }
  315 
  316         if (cas_pci_enaddr(sc, pa) == 0)
  317                 gotenaddr = 1;
  318 
  319 #ifdef __sparc64__
  320         if (!gotenaddr) {
  321                 if (OF_getprop(PCITAG_NODE(pa->pa_tag), "local-mac-address",
  322                     sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN) <= 0)
  323                         myetheraddr(sc->sc_arpcom.ac_enaddr);
  324                 gotenaddr = 1;
  325         }
  326 #endif
  327 #ifdef __powerpc__
  328         if (!gotenaddr) {
  329                 pci_ether_hw_addr(pa->pa_pc, sc->sc_arpcom.ac_enaddr);
  330                 gotenaddr = 1;
  331         }
  332 #endif
  333 
  334         sc->sc_burst = 16;      /* XXX */
  335 
  336         if (pci_intr_map(pa, &ih) != 0) {
  337                 printf(": couldn't map interrupt\n");
  338                 bus_space_unmap(sc->sc_memt, sc->sc_memh, size);
  339                 return;
  340         }
  341         intrstr = pci_intr_string(pa->pa_pc, ih);
  342         sc->sc_ih = pci_intr_establish(pa->pa_pc,
  343             ih, IPL_NET, cas_intr, sc, self->dv_xname);
  344         if (sc->sc_ih == NULL) {
  345                 printf(": couldn't establish interrupt");
  346                 if (intrstr != NULL)
  347                         printf(" at %s", intrstr);
  348                 printf("\n");
  349                 bus_space_unmap(sc->sc_memt, sc->sc_memh, size);
  350                 return;
  351         }
  352 
  353         printf(": %s", intrstr);
  354 
  355         /*
  356          * call the main configure
  357          */
  358         cas_config(sc);
  359 }
  360 
  361 /*
  362  * cas_config:
  363  *
  364  *      Attach a Cassini interface to the system.
  365  */
  366 void
  367 cas_config(struct cas_softc *sc)
  368 {
  369         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
  370         struct mii_data *mii = &sc->sc_mii;
  371         struct mii_softc *child;
  372         int i, error;
  373 
  374         /* Make sure the chip is stopped. */
  375         ifp->if_softc = sc;
  376         cas_reset(sc);
  377 
  378         /*
  379          * Allocate the control data structures, and create and load the
  380          * DMA map for it.
  381          */
  382         if ((error = bus_dmamem_alloc(sc->sc_dmatag,
  383             sizeof(struct cas_control_data), CAS_PAGE_SIZE, 0, &sc->sc_cdseg,
  384             1, &sc->sc_cdnseg, 0)) != 0) {
  385                 printf("\n%s: unable to allocate control data, error = %d\n",
  386                     sc->sc_dev.dv_xname, error);
  387                 goto fail_0;
  388         }
  389 
  390         /* XXX should map this in with correct endianness */
  391         if ((error = bus_dmamem_map(sc->sc_dmatag, &sc->sc_cdseg, sc->sc_cdnseg,
  392             sizeof(struct cas_control_data), (caddr_t *)&sc->sc_control_data,
  393             BUS_DMA_COHERENT)) != 0) {
  394                 printf("\n%s: unable to map control data, error = %d\n",
  395                     sc->sc_dev.dv_xname, error);
  396                 goto fail_1;
  397         }
  398 
  399         if ((error = bus_dmamap_create(sc->sc_dmatag,
  400             sizeof(struct cas_control_data), 1,
  401             sizeof(struct cas_control_data), 0, 0, &sc->sc_cddmamap)) != 0) {
  402                 printf("\n%s: unable to create control data DMA map, "
  403                     "error = %d\n", sc->sc_dev.dv_xname, error);
  404                 goto fail_2;
  405         }
  406 
  407         if ((error = bus_dmamap_load(sc->sc_dmatag, sc->sc_cddmamap,
  408             sc->sc_control_data, sizeof(struct cas_control_data), NULL,
  409             0)) != 0) {
  410                 printf("\n%s: unable to load control data DMA map, error = %d\n",
  411                     sc->sc_dev.dv_xname, error);
  412                 goto fail_3;
  413         }
  414 
  415         /*
  416          * Create the receive buffer DMA maps.
  417          */
  418         for (i = 0; i < CAS_NRXDESC; i++) {
  419                 bus_dma_segment_t seg;
  420                 caddr_t kva;
  421                 int rseg;
  422 
  423                 if ((error = bus_dmamem_alloc(sc->sc_dmatag, CAS_PAGE_SIZE,
  424                     CAS_PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
  425                         printf("\n%s: unable to alloc rx DMA mem %d, "
  426                             "error = %d\n", sc->sc_dev.dv_xname, i, error);
  427                         goto fail_5;
  428                 }
  429                 sc->sc_rxsoft[i].rxs_dmaseg = seg;
  430 
  431                 if ((error = bus_dmamem_map(sc->sc_dmatag, &seg, rseg,
  432                     CAS_PAGE_SIZE, &kva, BUS_DMA_NOWAIT)) != 0) {
  433                         printf("\n%s: unable to alloc rx DMA mem %d, "
  434                             "error = %d\n", sc->sc_dev.dv_xname, i, error);
  435                         goto fail_5;
  436                 }
  437                 sc->sc_rxsoft[i].rxs_kva = kva;
  438 
  439                 if ((error = bus_dmamap_create(sc->sc_dmatag, CAS_PAGE_SIZE, 1,
  440                     CAS_PAGE_SIZE, 0, 0, &sc->sc_rxsoft[i].rxs_dmamap)) != 0) {
  441                         printf("\n%s: unable to create rx DMA map %d, "
  442                             "error = %d\n", sc->sc_dev.dv_xname, i, error);
  443                         goto fail_5;
  444                 }
  445 
  446                 if ((error = bus_dmamap_load(sc->sc_dmatag,
  447                    sc->sc_rxsoft[i].rxs_dmamap, kva, CAS_PAGE_SIZE, NULL,
  448                    BUS_DMA_NOWAIT)) != 0) {
  449                         printf("\n%s: unable to load rx DMA map %d, "
  450                             "error = %d\n", sc->sc_dev.dv_xname, i, error);
  451                         goto fail_5;
  452                 }
  453         }
  454 
  455         /*
  456          * Create the transmit buffer DMA maps.
  457          */
  458         for (i = 0; i < CAS_NTXDESC; i++) {
  459                 if ((error = bus_dmamap_create(sc->sc_dmatag, MCLBYTES,
  460                     CAS_NTXSEGS, MCLBYTES, 0, BUS_DMA_NOWAIT,
  461                     &sc->sc_txd[i].sd_map)) != 0) {
  462                         printf("\n%s: unable to create tx DMA map %d, "
  463                             "error = %d\n", sc->sc_dev.dv_xname, i, error);
  464                         goto fail_6;
  465                 }
  466                 sc->sc_txd[i].sd_mbuf = NULL;
  467         }
  468 
  469         /*
  470          * From this point forward, the attachment cannot fail.  A failure
  471          * before this point releases all resources that may have been
  472          * allocated.
  473          */
  474 
  475         /* Announce ourselves. */
  476         printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
  477 
  478         /* Get RX FIFO size */
  479         sc->sc_rxfifosize = 16 * 1024;
  480 
  481         /* Initialize ifnet structure. */
  482         strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof ifp->if_xname);
  483         ifp->if_softc = sc;
  484         ifp->if_flags =
  485             IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
  486         ifp->if_start = cas_start;
  487         ifp->if_ioctl = cas_ioctl;
  488         ifp->if_watchdog = cas_watchdog;
  489         IFQ_SET_MAXLEN(&ifp->if_snd, CAS_NTXDESC - 1);
  490         IFQ_SET_READY(&ifp->if_snd);
  491 
  492         ifp->if_capabilities = IFCAP_VLAN_MTU;
  493 
  494         /* Initialize ifmedia structures and MII info */
  495         mii->mii_ifp = ifp;
  496         mii->mii_readreg = cas_mii_readreg;
  497         mii->mii_writereg = cas_mii_writereg;
  498         mii->mii_statchg = cas_mii_statchg;
  499 
  500         ifmedia_init(&mii->mii_media, 0, cas_mediachange, cas_mediastatus);
  501 
  502         bus_space_write_4(sc->sc_memt, sc->sc_memh, CAS_MII_DATAPATH_MODE, 0);
  503 
  504         cas_mifinit(sc);
  505 
  506         if (sc->sc_mif_config & CAS_MIF_CONFIG_MDI1) {
  507                 sc->sc_mif_config |= CAS_MIF_CONFIG_PHY_SEL;
  508                 bus_space_write_4(sc->sc_memt, sc->sc_memh,
  509                     CAS_MIF_CONFIG, sc->sc_mif_config);
  510         }
  511 
  512         mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
  513             MII_OFFSET_ANY, 0);
  514 
  515         child = LIST_FIRST(&mii->mii_phys);
  516         if (child == NULL &&
  517             sc->sc_mif_config & (CAS_MIF_CONFIG_MDI0|CAS_MIF_CONFIG_MDI1)) {
  518                 /* 
  519                  * Try the external PCS SERDES if we didn't find any
  520                  * MII devices.
  521                  */
  522                 bus_space_write_4(sc->sc_memt, sc->sc_memh,
  523                     CAS_MII_DATAPATH_MODE, CAS_MII_DATAPATH_SERDES);
  524 
  525                 bus_space_write_4(sc->sc_memt, sc->sc_memh,
  526                     CAS_MII_SLINK_CONTROL,
  527                     CAS_MII_SLINK_LOOPBACK|CAS_MII_SLINK_EN_SYNC_D);
  528 
  529                 bus_space_write_4(sc->sc_memt, sc->sc_memh,
  530                      CAS_MII_CONFIG, CAS_MII_CONFIG_ENABLE);
  531 
  532                 mii->mii_readreg = cas_pcs_readreg;
  533                 mii->mii_writereg = cas_pcs_writereg;
  534 
  535                 mii_attach(&sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY,
  536                     MII_OFFSET_ANY, MIIF_NOISOLATE);
  537         }
  538 
  539         child = LIST_FIRST(&mii->mii_phys);
  540         if (child == NULL) {
  541                 /* No PHY attached */
  542                 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
  543                 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
  544         } else {
  545                 /*
  546                  * Walk along the list of attached MII devices and
  547                  * establish an `MII instance' to `phy number'
  548                  * mapping. We'll use this mapping in media change
  549                  * requests to determine which phy to use to program
  550                  * the MIF configuration register.
  551                  */
  552                 for (; child != NULL; child = LIST_NEXT(child, mii_list)) {
  553                         /*
  554                          * Note: we support just two PHYs: the built-in
  555                          * internal device and an external on the MII
  556                          * connector.
  557                          */
  558                         if (child->mii_phy > 1 || child->mii_inst > 1) {
  559                                 printf("%s: cannot accommodate MII device %s"
  560                                        " at phy %d, instance %d\n",
  561                                        sc->sc_dev.dv_xname,
  562                                        child->mii_dev.dv_xname,
  563                                        child->mii_phy, child->mii_inst);
  564                                 continue;
  565                         }
  566 
  567                         sc->sc_phys[child->mii_inst] = child->mii_phy;
  568                 }
  569 
  570                 /*
  571                  * XXX - we can really do the following ONLY if the
  572                  * phy indeed has the auto negotiation capability!!
  573                  */
  574                 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO);
  575         }
  576 
  577         /* Attach the interface. */
  578         if_attach(ifp);
  579         ether_ifattach(ifp);
  580 
  581         sc->sc_sh = shutdownhook_establish(cas_shutdown, sc);
  582         if (sc->sc_sh == NULL)
  583                 panic("cas_config: can't establish shutdownhook");
  584 
  585         timeout_set(&sc->sc_tick_ch, cas_tick, sc);
  586         return;
  587 
  588         /*
  589          * Free any resources we've allocated during the failed attach
  590          * attempt.  Do this in reverse order and fall through.
  591          */
  592  fail_6:
  593         for (i = 0; i < CAS_NTXDESC; i++) {
  594                 if (sc->sc_txd[i].sd_map != NULL)
  595                         bus_dmamap_destroy(sc->sc_dmatag,
  596                             sc->sc_txd[i].sd_map);
  597         }
  598  fail_5:
  599         for (i = 0; i < CAS_NRXDESC; i++) {
  600                 if (sc->sc_rxsoft[i].rxs_dmamap != NULL)
  601                         bus_dmamap_destroy(sc->sc_dmatag,
  602                             sc->sc_rxsoft[i].rxs_dmamap);
  603         }
  604         bus_dmamap_unload(sc->sc_dmatag, sc->sc_cddmamap);
  605  fail_3:
  606         bus_dmamap_destroy(sc->sc_dmatag, sc->sc_cddmamap);
  607  fail_2:
  608         bus_dmamem_unmap(sc->sc_dmatag, (caddr_t)sc->sc_control_data,
  609             sizeof(struct cas_control_data));
  610  fail_1:
  611         bus_dmamem_free(sc->sc_dmatag, &sc->sc_cdseg, sc->sc_cdnseg);
  612  fail_0:
  613         return;
  614 }
  615 
  616 
  617 void
  618 cas_tick(void *arg)
  619 {
  620         struct cas_softc *sc = arg;
  621         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
  622         bus_space_tag_t t = sc->sc_memt;
  623         bus_space_handle_t mac = sc->sc_memh;
  624         int s;
  625 
  626         /* unload collisions counters */
  627         ifp->if_collisions +=
  628             bus_space_read_4(t, mac, CAS_MAC_NORM_COLL_CNT) +
  629             bus_space_read_4(t, mac, CAS_MAC_FIRST_COLL_CNT) +
  630             bus_space_read_4(t, mac, CAS_MAC_EXCESS_COLL_CNT) +
  631             bus_space_read_4(t, mac, CAS_MAC_LATE_COLL_CNT);
  632 
  633         /* clear the hardware counters */
  634         bus_space_write_4(t, mac, CAS_MAC_NORM_COLL_CNT, 0);
  635         bus_space_write_4(t, mac, CAS_MAC_FIRST_COLL_CNT, 0);
  636         bus_space_write_4(t, mac, CAS_MAC_EXCESS_COLL_CNT, 0);
  637         bus_space_write_4(t, mac, CAS_MAC_LATE_COLL_CNT, 0);
  638 
  639         s = splnet();
  640         mii_tick(&sc->sc_mii);
  641         splx(s);
  642 
  643         timeout_add(&sc->sc_tick_ch, hz);
  644 }
  645 
  646 int
  647 cas_bitwait(struct cas_softc *sc, bus_space_handle_t h, int r,
  648     u_int32_t clr, u_int32_t set)
  649 {
  650         int i;
  651         u_int32_t reg;
  652 
  653         for (i = TRIES; i--; DELAY(100)) {
  654                 reg = bus_space_read_4(sc->sc_memt, h, r);
  655                 if ((reg & clr) == 0 && (reg & set) == set)
  656                         return (1);
  657         }
  658 
  659         return (0);
  660 }
  661 
  662 void
  663 cas_reset(struct cas_softc *sc)
  664 {
  665         bus_space_tag_t t = sc->sc_memt;
  666         bus_space_handle_t h = sc->sc_memh;
  667         int s;
  668 
  669         s = splnet();
  670         DPRINTF(sc, ("%s: cas_reset\n", sc->sc_dev.dv_xname));
  671         cas_reset_rx(sc);
  672         cas_reset_tx(sc);
  673 
  674         /* Do a full reset */
  675         bus_space_write_4(t, h, CAS_RESET, CAS_RESET_RX|CAS_RESET_TX);
  676         if (!cas_bitwait(sc, h, CAS_RESET, CAS_RESET_RX | CAS_RESET_TX, 0))
  677                 printf("%s: cannot reset device\n", sc->sc_dev.dv_xname);
  678         splx(s);
  679 }
  680 
  681 
  682 /*
  683  * cas_rxdrain:
  684  *
  685  *      Drain the receive queue.
  686  */
  687 void
  688 cas_rxdrain(struct cas_softc *sc)
  689 {
  690         /* Nothing to do yet. */
  691 }
  692 
  693 /*
  694  * Reset the whole thing.
  695  */
  696 void
  697 cas_stop(struct ifnet *ifp, int disable)
  698 {
  699         struct cas_softc *sc = (struct cas_softc *)ifp->if_softc;
  700         struct cas_sxd *sd;
  701         u_int32_t i;
  702 
  703         DPRINTF(sc, ("%s: cas_stop\n", sc->sc_dev.dv_xname));
  704 
  705         timeout_del(&sc->sc_tick_ch);
  706 
  707         /*
  708          * Mark the interface down and cancel the watchdog timer.
  709          */
  710         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
  711         ifp->if_timer = 0;
  712 
  713         mii_down(&sc->sc_mii);
  714 
  715         cas_reset_rx(sc);
  716         cas_reset_tx(sc);
  717 
  718         /*
  719          * Release any queued transmit buffers.
  720          */
  721         for (i = 0; i < CAS_NTXDESC; i++) {
  722                 sd = &sc->sc_txd[i];
  723                 if (sd->sd_mbuf != NULL) {
  724                         bus_dmamap_sync(sc->sc_dmatag, sd->sd_map, 0,
  725                             sd->sd_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
  726                         bus_dmamap_unload(sc->sc_dmatag, sd->sd_map);
  727                         m_freem(sd->sd_mbuf);
  728                         sd->sd_mbuf = NULL;
  729                 }
  730         }
  731         sc->sc_tx_cnt = sc->sc_tx_prod = sc->sc_tx_cons = 0;
  732 
  733         if (disable)
  734                 cas_rxdrain(sc);
  735 }
  736 
  737 
  738 /*
  739  * Reset the receiver
  740  */
  741 int
  742 cas_reset_rx(struct cas_softc *sc)
  743 {
  744         bus_space_tag_t t = sc->sc_memt;
  745         bus_space_handle_t h = sc->sc_memh;
  746 
  747         /*
  748          * Resetting while DMA is in progress can cause a bus hang, so we
  749          * disable DMA first.
  750          */
  751         cas_disable_rx(sc);
  752         bus_space_write_4(t, h, CAS_RX_CONFIG, 0);
  753         /* Wait till it finishes */
  754         if (!cas_bitwait(sc, h, CAS_RX_CONFIG, 1, 0))
  755                 printf("%s: cannot disable rx dma\n", sc->sc_dev.dv_xname);
  756         /* Wait 5ms extra. */
  757         delay(5000);
  758 
  759         /* Finally, reset the ERX */
  760         bus_space_write_4(t, h, CAS_RESET, CAS_RESET_RX);
  761         /* Wait till it finishes */
  762         if (!cas_bitwait(sc, h, CAS_RESET, CAS_RESET_RX, 0)) {
  763                 printf("%s: cannot reset receiver\n", sc->sc_dev.dv_xname);
  764                 return (1);
  765         }
  766         return (0);
  767 }
  768 
  769 
  770 /*
  771  * Reset the transmitter
  772  */
  773 int
  774 cas_reset_tx(struct cas_softc *sc)
  775 {
  776         bus_space_tag_t t = sc->sc_memt;
  777         bus_space_handle_t h = sc->sc_memh;
  778 
  779         /*
  780          * Resetting while DMA is in progress can cause a bus hang, so we
  781          * disable DMA first.
  782          */
  783         cas_disable_tx(sc);
  784         bus_space_write_4(t, h, CAS_TX_CONFIG, 0);
  785         /* Wait till it finishes */
  786         if (!cas_bitwait(sc, h, CAS_TX_CONFIG, 1, 0))
  787                 printf("%s: cannot disable tx dma\n", sc->sc_dev.dv_xname);
  788         /* Wait 5ms extra. */
  789         delay(5000);
  790 
  791         /* Finally, reset the ETX */
  792         bus_space_write_4(t, h, CAS_RESET, CAS_RESET_TX);
  793         /* Wait till it finishes */
  794         if (!cas_bitwait(sc, h, CAS_RESET, CAS_RESET_TX, 0)) {
  795                 printf("%s: cannot reset transmitter\n",
  796                         sc->sc_dev.dv_xname);
  797                 return (1);
  798         }
  799         return (0);
  800 }
  801 
  802 /*
  803  * disable receiver.
  804  */
  805 int
  806 cas_disable_rx(struct cas_softc *sc)
  807 {
  808         bus_space_tag_t t = sc->sc_memt;
  809         bus_space_handle_t h = sc->sc_memh;
  810         u_int32_t cfg;
  811 
  812         /* Flip the enable bit */
  813         cfg = bus_space_read_4(t, h, CAS_MAC_RX_CONFIG);
  814         cfg &= ~CAS_MAC_RX_ENABLE;
  815         bus_space_write_4(t, h, CAS_MAC_RX_CONFIG, cfg);
  816 
  817         /* Wait for it to finish */
  818         return (cas_bitwait(sc, h, CAS_MAC_RX_CONFIG, CAS_MAC_RX_ENABLE, 0));
  819 }
  820 
  821 /*
  822  * disable transmitter.
  823  */
  824 int
  825 cas_disable_tx(struct cas_softc *sc)
  826 {
  827         bus_space_tag_t t = sc->sc_memt;
  828         bus_space_handle_t h = sc->sc_memh;
  829         u_int32_t cfg;
  830 
  831         /* Flip the enable bit */
  832         cfg = bus_space_read_4(t, h, CAS_MAC_TX_CONFIG);
  833         cfg &= ~CAS_MAC_TX_ENABLE;
  834         bus_space_write_4(t, h, CAS_MAC_TX_CONFIG, cfg);
  835 
  836         /* Wait for it to finish */
  837         return (cas_bitwait(sc, h, CAS_MAC_TX_CONFIG, CAS_MAC_TX_ENABLE, 0));
  838 }
  839 
  840 /*
  841  * Initialize interface.
  842  */
  843 int
  844 cas_meminit(struct cas_softc *sc)
  845 {
  846         struct cas_rxsoft *rxs;
  847         int i, error;
  848 
  849         rxs = (void *)&error;
  850 
  851         /*
  852          * Initialize the transmit descriptor ring.
  853          */
  854         for (i = 0; i < CAS_NTXDESC; i++) {
  855                 sc->sc_txdescs[i].cd_flags = 0;
  856                 sc->sc_txdescs[i].cd_addr = 0;
  857         }
  858         CAS_CDTXSYNC(sc, 0, CAS_NTXDESC,
  859             BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  860 
  861         /*
  862          * Initialize the receive descriptor and receive job
  863          * descriptor rings.
  864          */
  865         for (i = 0; i < CAS_NRXDESC; i++)
  866                 CAS_INIT_RXDESC(sc, i, i);
  867         sc->sc_rxdptr = 0;
  868         sc->sc_rxptr = 0;
  869 
  870         /*
  871          * Initialize the receive completion ring.
  872          */
  873         for (i = 0; i < CAS_NRXCOMP; i++) {
  874                 sc->sc_rxcomps[i].cc_word[0] = 0;
  875                 sc->sc_rxcomps[i].cc_word[1] = 0;
  876                 sc->sc_rxcomps[i].cc_word[2] = 0;
  877                 sc->sc_rxcomps[i].cc_word[3] = CAS_DMA_WRITE(CAS_RC3_OWN);
  878                 CAS_CDRXCSYNC(sc, i,
  879                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
  880         }
  881 
  882         return (0);
  883 }
  884 
  885 int
  886 cas_ringsize(int sz)
  887 {
  888         switch (sz) {
  889         case 32:
  890                 return CAS_RING_SZ_32;
  891         case 64:
  892                 return CAS_RING_SZ_64;
  893         case 128:
  894                 return CAS_RING_SZ_128;
  895         case 256:
  896                 return CAS_RING_SZ_256;
  897         case 512:
  898                 return CAS_RING_SZ_512;
  899         case 1024:
  900                 return CAS_RING_SZ_1024;
  901         case 2048:
  902                 return CAS_RING_SZ_2048;
  903         case 4096:
  904                 return CAS_RING_SZ_4096;
  905         case 8192:
  906                 return CAS_RING_SZ_8192;
  907         default:
  908                 printf("cas: invalid Receive Descriptor ring size %d\n", sz);
  909                 return CAS_RING_SZ_32;
  910         }
  911 }
  912 
  913 int
  914 cas_cringsize(int sz)
  915 {
  916         int i;
  917 
  918         for (i = 0; i < 9; i++)
  919                 if (sz == (128 << i))
  920                         return i;
  921 
  922         printf("cas: invalid completion ring size %d\n", sz);
  923         return 128;
  924 }
  925 
  926 /*
  927  * Initialization of interface; set up initialization block
  928  * and transmit/receive descriptor rings.
  929  */
  930 int
  931 cas_init(struct ifnet *ifp)
  932 {
  933 
  934         struct cas_softc *sc = (struct cas_softc *)ifp->if_softc;
  935         bus_space_tag_t t = sc->sc_memt;
  936         bus_space_handle_t h = sc->sc_memh;
  937         int s;
  938         u_int max_frame_size;
  939         u_int32_t v;
  940 
  941         s = splnet();
  942 
  943         DPRINTF(sc, ("%s: cas_init: calling stop\n", sc->sc_dev.dv_xname));
  944         /*
  945          * Initialization sequence. The numbered steps below correspond
  946          * to the sequence outlined in section 6.3.5.1 in the Ethernet
  947          * Channel Engine manual (part of the PCIO manual).
  948          * See also the STP2002-STQ document from Sun Microsystems.
  949          */
  950 
  951         /* step 1 & 2. Reset the Ethernet Channel */
  952         cas_stop(ifp, 0);
  953         cas_reset(sc);
  954         DPRINTF(sc, ("%s: cas_init: restarting\n", sc->sc_dev.dv_xname));
  955 
  956         /* Re-initialize the MIF */
  957         cas_mifinit(sc);
  958 
  959         /* step 3. Setup data structures in host memory */
  960         cas_meminit(sc);
  961 
  962         /* step 4. TX MAC registers & counters */
  963         cas_init_regs(sc);
  964         max_frame_size = ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN;
  965         v = (max_frame_size) | (0x2000 << 16) /* Burst size */;
  966         bus_space_write_4(t, h, CAS_MAC_MAC_MAX_FRAME, v);
  967 
  968         /* step 5. RX MAC registers & counters */
  969         cas_setladrf(sc);
  970 
  971         /* step 6 & 7. Program Descriptor Ring Base Addresses */
  972         KASSERT((CAS_CDTXADDR(sc, 0) & 0x1fff) == 0);
  973         bus_space_write_4(t, h, CAS_TX_RING_PTR_HI,
  974             (((uint64_t)CAS_CDTXADDR(sc,0)) >> 32));
  975         bus_space_write_4(t, h, CAS_TX_RING_PTR_LO, CAS_CDTXADDR(sc, 0));
  976 
  977         KASSERT((CAS_CDRXADDR(sc, 0) & 0x1fff) == 0);
  978         bus_space_write_4(t, h, CAS_RX_DRING_PTR_HI,
  979             (((uint64_t)CAS_CDRXADDR(sc,0)) >> 32));
  980         bus_space_write_4(t, h, CAS_RX_DRING_PTR_LO, CAS_CDRXADDR(sc, 0));
  981 
  982         KASSERT((CAS_CDRXCADDR(sc, 0) & 0x1fff) == 0);
  983         bus_space_write_4(t, h, CAS_RX_CRING_PTR_HI,
  984             (((uint64_t)CAS_CDRXCADDR(sc,0)) >> 32));
  985         bus_space_write_4(t, h, CAS_RX_CRING_PTR_LO, CAS_CDRXCADDR(sc, 0));
  986 
  987         /* step 8. Global Configuration & Interrupt Mask */
  988         bus_space_write_4(t, h, CAS_INTMASK,
  989                       ~(CAS_INTR_TX_INTME|CAS_INTR_TX_EMPTY|
  990                         CAS_INTR_TX_TAG_ERR|
  991                         CAS_INTR_RX_DONE|CAS_INTR_RX_NOBUF|
  992                         CAS_INTR_RX_TAG_ERR|
  993                         CAS_INTR_RX_COMP_FULL|CAS_INTR_PCS|
  994                         CAS_INTR_MAC_CONTROL|CAS_INTR_MIF|
  995                         CAS_INTR_BERR));
  996         bus_space_write_4(t, h, CAS_MAC_RX_MASK,
  997             CAS_MAC_RX_DONE|CAS_MAC_RX_FRAME_CNT);
  998         bus_space_write_4(t, h, CAS_MAC_TX_MASK, CAS_MAC_TX_XMIT_DONE);
  999         bus_space_write_4(t, h, CAS_MAC_CONTROL_MASK, 0); /* XXXX */
 1000 
 1001         /* step 9. ETX Configuration: use mostly default values */
 1002 
 1003         /* Enable DMA */
 1004         v = cas_ringsize(CAS_NTXDESC /*XXX*/) << 10;
 1005         bus_space_write_4(t, h, CAS_TX_CONFIG,
 1006             v|CAS_TX_CONFIG_TXDMA_EN|(1<<24)|(1<<29));
 1007         bus_space_write_4(t, h, CAS_TX_KICK, 0);
 1008 
 1009         /* step 10. ERX Configuration */
 1010 
 1011         /* Encode Receive Descriptor ring size */
 1012         v = cas_ringsize(CAS_NRXDESC) << CAS_RX_CONFIG_RXDRNG_SZ_SHIFT;
 1013 
 1014         /* Encode Receive Completion ring size */
 1015         v |= cas_cringsize(CAS_NRXCOMP) << CAS_RX_CONFIG_RXCRNG_SZ_SHIFT;
 1016 
 1017         /* Enable DMA */
 1018         bus_space_write_4(t, h, CAS_RX_CONFIG,
 1019             v|(2<<CAS_RX_CONFIG_FBOFF_SHFT)|CAS_RX_CONFIG_RXDMA_EN);
 1020 
 1021         /*
 1022          * The following value is for an OFF Threshold of about 3/4 full
 1023          * and an ON Threshold of 1/4 full.
 1024          */
 1025         bus_space_write_4(t, h, CAS_RX_PAUSE_THRESH,
 1026             (3 * sc->sc_rxfifosize / 256) |
 1027             (   (sc->sc_rxfifosize / 256) << 12));
 1028         bus_space_write_4(t, h, CAS_RX_BLANKING, (6<<12)|6);
 1029 
 1030         /* step 11. Configure Media */
 1031         mii_mediachg(&sc->sc_mii);
 1032 
 1033         /* step 12. RX_MAC Configuration Register */
 1034         v = bus_space_read_4(t, h, CAS_MAC_RX_CONFIG);
 1035         v |= CAS_MAC_RX_ENABLE | CAS_MAC_RX_STRIP_CRC;
 1036         bus_space_write_4(t, h, CAS_MAC_RX_CONFIG, v);
 1037 
 1038         /* step 14. Issue Transmit Pending command */
 1039 
 1040         /* step 15.  Give the receiver a swift kick */
 1041         bus_space_write_4(t, h, CAS_RX_KICK, CAS_NRXDESC-4);
 1042 
 1043         /* Start the one second timer. */
 1044         timeout_add(&sc->sc_tick_ch, hz);
 1045 
 1046         ifp->if_flags |= IFF_RUNNING;
 1047         ifp->if_flags &= ~IFF_OACTIVE;
 1048         ifp->if_timer = 0;
 1049         splx(s);
 1050 
 1051         return (0);
 1052 }
 1053 
 1054 void
 1055 cas_init_regs(struct cas_softc *sc)
 1056 {
 1057         bus_space_tag_t t = sc->sc_memt;
 1058         bus_space_handle_t h = sc->sc_memh;
 1059         u_int32_t v, r;
 1060 
 1061         /* These regs are not cleared on reset */
 1062         sc->sc_inited = 0;
 1063         if (!sc->sc_inited) {
 1064 
 1065                 /* Wooo.  Magic values. */
 1066                 bus_space_write_4(t, h, CAS_MAC_IPG0, 0);
 1067                 bus_space_write_4(t, h, CAS_MAC_IPG1, 8);
 1068                 bus_space_write_4(t, h, CAS_MAC_IPG2, 4);
 1069 
 1070                 bus_space_write_4(t, h, CAS_MAC_MAC_MIN_FRAME, ETHER_MIN_LEN);
 1071                 /* Max frame and max burst size */
 1072                 v = ETHER_MAX_LEN | (0x2000 << 16) /* Burst size */;
 1073                 bus_space_write_4(t, h, CAS_MAC_MAC_MAX_FRAME, v);
 1074 
 1075                 bus_space_write_4(t, h, CAS_MAC_PREAMBLE_LEN, 0x7);
 1076                 bus_space_write_4(t, h, CAS_MAC_JAM_SIZE, 0x4);
 1077                 bus_space_write_4(t, h, CAS_MAC_ATTEMPT_LIMIT, 0x10);
 1078                 /* Dunno.... */
 1079                 bus_space_write_4(t, h, CAS_MAC_CONTROL_TYPE, 0x8088);
 1080                 bus_space_write_4(t, h, CAS_MAC_RANDOM_SEED,
 1081                     ((sc->sc_arpcom.ac_enaddr[5]<<8)|sc->sc_arpcom.ac_enaddr[4])&0x3ff);
 1082 
 1083                 /* Secondary MAC addresses set to 0:0:0:0:0:0 */
 1084                 for (r = CAS_MAC_ADDR3; r < CAS_MAC_ADDR42; r += 4)
 1085                         bus_space_write_4(t, h, r, 0);
 1086 
 1087                 /* MAC control addr set to 0:1:c2:0:1:80 */
 1088                 bus_space_write_4(t, h, CAS_MAC_ADDR42, 0x0001);
 1089                 bus_space_write_4(t, h, CAS_MAC_ADDR43, 0xc200);
 1090                 bus_space_write_4(t, h, CAS_MAC_ADDR44, 0x0180);
 1091 
 1092                 /* MAC filter addr set to 0:0:0:0:0:0 */
 1093                 bus_space_write_4(t, h, CAS_MAC_ADDR_FILTER0, 0);
 1094                 bus_space_write_4(t, h, CAS_MAC_ADDR_FILTER1, 0);
 1095                 bus_space_write_4(t, h, CAS_MAC_ADDR_FILTER2, 0);
 1096 
 1097                 bus_space_write_4(t, h, CAS_MAC_ADR_FLT_MASK1_2, 0);
 1098                 bus_space_write_4(t, h, CAS_MAC_ADR_FLT_MASK0, 0);
 1099 
 1100                 /* Hash table initialized to 0 */
 1101                 for (r = CAS_MAC_HASH0; r <= CAS_MAC_HASH15; r += 4)
 1102                         bus_space_write_4(t, h, r, 0);
 1103 
 1104                 sc->sc_inited = 1;
 1105         }
 1106 
 1107         /* Counters need to be zeroed */
 1108         bus_space_write_4(t, h, CAS_MAC_NORM_COLL_CNT, 0);
 1109         bus_space_write_4(t, h, CAS_MAC_FIRST_COLL_CNT, 0);
 1110         bus_space_write_4(t, h, CAS_MAC_EXCESS_COLL_CNT, 0);
 1111         bus_space_write_4(t, h, CAS_MAC_LATE_COLL_CNT, 0);
 1112         bus_space_write_4(t, h, CAS_MAC_DEFER_TMR_CNT, 0);
 1113         bus_space_write_4(t, h, CAS_MAC_PEAK_ATTEMPTS, 0);
 1114         bus_space_write_4(t, h, CAS_MAC_RX_FRAME_COUNT, 0);
 1115         bus_space_write_4(t, h, CAS_MAC_RX_LEN_ERR_CNT, 0);
 1116         bus_space_write_4(t, h, CAS_MAC_RX_ALIGN_ERR, 0);
 1117         bus_space_write_4(t, h, CAS_MAC_RX_CRC_ERR_CNT, 0);
 1118         bus_space_write_4(t, h, CAS_MAC_RX_CODE_VIOL, 0);
 1119 
 1120         /* Un-pause stuff */
 1121         bus_space_write_4(t, h, CAS_MAC_SEND_PAUSE_CMD, 0);
 1122 
 1123         /*
 1124          * Set the station address.
 1125          */
 1126         bus_space_write_4(t, h, CAS_MAC_ADDR0, 
 1127                 (sc->sc_arpcom.ac_enaddr[4]<<8) | sc->sc_arpcom.ac_enaddr[5]);
 1128         bus_space_write_4(t, h, CAS_MAC_ADDR1, 
 1129                 (sc->sc_arpcom.ac_enaddr[2]<<8) | sc->sc_arpcom.ac_enaddr[3]);
 1130         bus_space_write_4(t, h, CAS_MAC_ADDR2, 
 1131                 (sc->sc_arpcom.ac_enaddr[0]<<8) | sc->sc_arpcom.ac_enaddr[1]);
 1132 }
 1133 
 1134 /*
 1135  * Receive interrupt.
 1136  */
 1137 int
 1138 cas_rint(struct cas_softc *sc)
 1139 {
 1140         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
 1141         bus_space_tag_t t = sc->sc_memt;
 1142         bus_space_handle_t h = sc->sc_memh;
 1143         struct cas_rxsoft *rxs;
 1144         struct mbuf *m;
 1145         u_int64_t word[4];
 1146         int len, off, idx;
 1147         int i, skip;
 1148         caddr_t cp;
 1149 
 1150         for (i = sc->sc_rxptr;; i = CAS_NEXTRX(i + skip)) {
 1151                 CAS_CDRXCSYNC(sc, i,
 1152                     BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
 1153 
 1154                 word[0] = CAS_DMA_READ(sc->sc_rxcomps[i].cc_word[0]);
 1155                 word[1] = CAS_DMA_READ(sc->sc_rxcomps[i].cc_word[1]);
 1156                 word[2] = CAS_DMA_READ(sc->sc_rxcomps[i].cc_word[2]);
 1157                 word[3] = CAS_DMA_READ(sc->sc_rxcomps[i].cc_word[3]);
 1158 
 1159                 /* Stop if the hardware still owns the descriptor. */
 1160                 if ((word[0] & CAS_RC0_TYPE) == 0 || word[3] & CAS_RC3_OWN)
 1161                         break;
 1162 
 1163                 len = CAS_RC1_HDR_LEN(word[1]);
 1164                 if (len > 0) {
 1165                         off = CAS_RC1_HDR_OFF(word[1]);
 1166                         idx = CAS_RC1_HDR_IDX(word[1]);
 1167                         rxs = &sc->sc_rxsoft[idx];
 1168 
 1169                         DPRINTF(sc, ("hdr at idx %d, off %d, len %d\n",
 1170                             idx, off, len));
 1171 
 1172                         bus_dmamap_sync(sc->sc_dmatag, rxs->rxs_dmamap, 0,
 1173                             rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
 1174 
 1175                         cp = rxs->rxs_kva + off * 256;
 1176                         m = m_devget(cp, len + ETHER_ALIGN, 0, ifp, NULL);
 1177                         
 1178                         if (word[0] & CAS_RC0_RELEASE_HDR)
 1179                                 cas_add_rxbuf(sc, idx);
 1180 
 1181                         if (m != NULL) {
 1182                                 m_adj(m, ETHER_ALIGN);
 1183 
 1184 #if NBPFILTER > 0
 1185                                 /*
 1186                                  * Pass this up to any BPF listeners, but only
 1187                                  * pass it up the stack if its for us.
 1188                                  */
 1189                                 if (ifp->if_bpf)
 1190                                         bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
 1191 #endif /* NPBFILTER > 0 */
 1192 
 1193                                 ifp->if_ipackets++;
 1194                                 ether_input_mbuf(ifp, m);
 1195                         } else
 1196                                 ifp->if_ierrors++;
 1197                 }
 1198 
 1199                 len = CAS_RC0_DATA_LEN(word[0]);
 1200                 if (len > 0) {
 1201                         off = CAS_RC0_DATA_OFF(word[0]);
 1202                         idx = CAS_RC0_DATA_IDX(word[0]);
 1203                         rxs = &sc->sc_rxsoft[idx];
 1204 
 1205                         DPRINTF(sc, ("data at idx %d, off %d, len %d\n",
 1206                             idx, off, len));
 1207 
 1208                         bus_dmamap_sync(sc->sc_dmatag, rxs->rxs_dmamap, 0,
 1209                             rxs->rxs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
 1210 
 1211                         /* XXX We should not be copying the packet here. */
 1212                         cp = rxs->rxs_kva + off;
 1213                         m = m_devget(cp, len + ETHER_ALIGN, 0, ifp, NULL);
 1214 
 1215                         if (word[0] & CAS_RC0_RELEASE_DATA)
 1216                                 cas_add_rxbuf(sc, idx);
 1217 
 1218                         if (m != NULL) {
 1219                                 m_adj(m, ETHER_ALIGN);
 1220 
 1221 #if NBPFILTER > 0
 1222                                 /*
 1223                                  * Pass this up to any BPF listeners, but only
 1224                                  * pass it up the stack if its for us.
 1225                                  */
 1226                                 if (ifp->if_bpf)
 1227                                         bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
 1228 #endif /* NPBFILTER > 0 */
 1229 
 1230                                 ifp->if_ipackets++;
 1231                                 ether_input_mbuf(ifp, m);
 1232                         } else
 1233                                 ifp->if_ierrors++;
 1234                 }
 1235 
 1236                 if (word[0] & CAS_RC0_SPLIT)
 1237                         printf("split packet\n");
 1238 
 1239                 skip = CAS_RC0_SKIP(word[0]);
 1240         }
 1241 
 1242         while (sc->sc_rxptr != i) {
 1243                 sc->sc_rxcomps[sc->sc_rxptr].cc_word[0] = 0;
 1244                 sc->sc_rxcomps[sc->sc_rxptr].cc_word[1] = 0;
 1245                 sc->sc_rxcomps[sc->sc_rxptr].cc_word[2] = 0;
 1246                 sc->sc_rxcomps[sc->sc_rxptr].cc_word[3] =
 1247                     CAS_DMA_WRITE(CAS_RC3_OWN);
 1248                 CAS_CDRXCSYNC(sc, sc->sc_rxptr,
 1249                     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
 1250 
 1251                 sc->sc_rxptr = CAS_NEXTRX(sc->sc_rxptr);
 1252         }
 1253 
 1254         bus_space_write_4(t, h, CAS_RX_COMP_TAIL, sc->sc_rxptr);
 1255 
 1256         DPRINTF(sc, ("cas_rint: done sc->rxptr %d, complete %d\n",
 1257                 sc->sc_rxptr, bus_space_read_4(t, h, CAS_RX_COMPLETION)));
 1258 
 1259         return (1);
 1260 }
 1261 
 1262 /*
 1263  * cas_add_rxbuf:
 1264  *
 1265  *      Add a receive buffer to the indicated descriptor.
 1266  */
 1267 int
 1268 cas_add_rxbuf(struct cas_softc *sc, int idx)
 1269 {
 1270         bus_space_tag_t t = sc->sc_memt;
 1271         bus_space_handle_t h = sc->sc_memh;
 1272 
 1273         CAS_INIT_RXDESC(sc, sc->sc_rxdptr, idx);
 1274 
 1275         if ((sc->sc_rxdptr % 4) == 0)
 1276                 bus_space_write_4(t, h, CAS_RX_KICK, sc->sc_rxdptr);
 1277 
 1278         sc->sc_rxdptr++;
 1279         return (0);
 1280 }
 1281 
 1282 int
 1283 cas_eint(struct cas_softc *sc, u_int status)
 1284 {
 1285         if ((status & CAS_INTR_MIF) != 0) {
 1286 #ifdef CAS_DEBUG
 1287                 printf("%s: link status changed\n", sc->sc_dev.dv_xname);
 1288 #endif
 1289                 return (1);
 1290         }
 1291 
 1292         printf("%s: status=%b\n", sc->sc_dev.dv_xname, status, CAS_INTR_BITS);
 1293         return (1);
 1294 }
 1295 
 1296 int
 1297 cas_pint(struct cas_softc *sc)
 1298 {
 1299         bus_space_tag_t t = sc->sc_memt;
 1300         bus_space_handle_t seb = sc->sc_memh;
 1301         u_int32_t status;
 1302 
 1303         status = bus_space_read_4(t, seb, CAS_MII_INTERRUP_STATUS);
 1304         status |= bus_space_read_4(t, seb, CAS_MII_INTERRUP_STATUS);
 1305 #ifdef CAS_DEBUG
 1306         if (status)
 1307                 printf("%s: link status changed\n", sc->sc_dev.dv_xname);
 1308 #endif
 1309         return (1);
 1310 }
 1311 
 1312 int
 1313 cas_intr(void *v)
 1314 {
 1315         struct cas_softc *sc = (struct cas_softc *)v;
 1316         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
 1317         bus_space_tag_t t = sc->sc_memt;
 1318         bus_space_handle_t seb = sc->sc_memh;
 1319         u_int32_t status;
 1320         int r = 0;
 1321 
 1322         status = bus_space_read_4(t, seb, CAS_STATUS);
 1323         DPRINTF(sc, ("%s: cas_intr: cplt %xstatus %b\n",
 1324                 sc->sc_dev.dv_xname, (status>>19), status, CAS_INTR_BITS));
 1325 
 1326         if ((status & CAS_INTR_PCS) != 0)
 1327                 r |= cas_pint(sc);
 1328 
 1329         if ((status & (CAS_INTR_TX_TAG_ERR | CAS_INTR_RX_TAG_ERR |
 1330             CAS_INTR_RX_COMP_FULL | CAS_INTR_BERR)) != 0)
 1331                 r |= cas_eint(sc, status);
 1332 
 1333         if ((status & (CAS_INTR_TX_EMPTY | CAS_INTR_TX_INTME)) != 0)
 1334                 r |= cas_tint(sc, status);
 1335 
 1336         if ((status & (CAS_INTR_RX_DONE | CAS_INTR_RX_NOBUF)) != 0)
 1337                 r |= cas_rint(sc);
 1338 
 1339         /* We should eventually do more than just print out error stats. */
 1340         if (status & CAS_INTR_TX_MAC) {
 1341                 int txstat = bus_space_read_4(t, seb, CAS_MAC_TX_STATUS);
 1342 #ifdef CAS_DEBUG
 1343                 if (txstat & ~CAS_MAC_TX_XMIT_DONE)
 1344                         printf("%s: MAC tx fault, status %x\n",
 1345                             sc->sc_dev.dv_xname, txstat);
 1346 #endif
 1347                 if (txstat & (CAS_MAC_TX_UNDERRUN | CAS_MAC_TX_PKT_TOO_LONG))
 1348                         cas_init(ifp);
 1349         }
 1350         if (status & CAS_INTR_RX_MAC) {
 1351                 int rxstat = bus_space_read_4(t, seb, CAS_MAC_RX_STATUS);
 1352 #ifdef CAS_DEBUG
 1353                 if (rxstat & ~CAS_MAC_RX_DONE)
 1354                         printf("%s: MAC rx fault, status %x\n",
 1355                             sc->sc_dev.dv_xname, rxstat);
 1356 #endif
 1357                 /*
 1358                  * On some chip revisions CAS_MAC_RX_OVERFLOW happen often
 1359                  * due to a silicon bug so handle them silently.
 1360                  */
 1361                 if (rxstat & CAS_MAC_RX_OVERFLOW) {
 1362                         ifp->if_ierrors++;
 1363                         cas_init(ifp);
 1364                 }
 1365 #ifdef CAS_DEBUG
 1366                 else if (rxstat & ~(CAS_MAC_RX_DONE | CAS_MAC_RX_FRAME_CNT))
 1367                         printf("%s: MAC rx fault, status %x\n",
 1368                             sc->sc_dev.dv_xname, rxstat);
 1369 #endif
 1370         }
 1371         return (r);
 1372 }
 1373 
 1374 
 1375 void
 1376 cas_watchdog(struct ifnet *ifp)
 1377 {
 1378         struct cas_softc *sc = ifp->if_softc;
 1379 
 1380         DPRINTF(sc, ("cas_watchdog: CAS_RX_CONFIG %x CAS_MAC_RX_STATUS %x "
 1381                 "CAS_MAC_RX_CONFIG %x\n",
 1382                 bus_space_read_4(sc->sc_memt, sc->sc_memh, CAS_RX_CONFIG),
 1383                 bus_space_read_4(sc->sc_memt, sc->sc_memh, CAS_MAC_RX_STATUS),
 1384                 bus_space_read_4(sc->sc_memt, sc->sc_memh, CAS_MAC_RX_CONFIG)));
 1385 
 1386         log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
 1387         ++ifp->if_oerrors;
 1388 
 1389         /* Try to get more packets going. */
 1390         cas_init(ifp);
 1391 }
 1392 
 1393 /*
 1394  * Initialize the MII Management Interface
 1395  */
 1396 void
 1397 cas_mifinit(struct cas_softc *sc)
 1398 {
 1399         bus_space_tag_t t = sc->sc_memt;
 1400         bus_space_handle_t mif = sc->sc_memh;
 1401 
 1402         /* Configure the MIF in frame mode */
 1403         sc->sc_mif_config = bus_space_read_4(t, mif, CAS_MIF_CONFIG);
 1404         sc->sc_mif_config &= ~CAS_MIF_CONFIG_BB_ENA;
 1405         bus_space_write_4(t, mif, CAS_MIF_CONFIG, sc->sc_mif_config);
 1406 }
 1407 
 1408 /*
 1409  * MII interface
 1410  *
 1411  * The Cassini MII interface supports at least three different operating modes:
 1412  *
 1413  * Bitbang mode is implemented using data, clock and output enable registers.
 1414  *
 1415  * Frame mode is implemented by loading a complete frame into the frame
 1416  * register and polling the valid bit for completion.
 1417  *
 1418  * Polling mode uses the frame register but completion is indicated by
 1419  * an interrupt.
 1420  *
 1421  */
 1422 int
 1423 cas_mii_readreg(struct device *self, int phy, int reg)
 1424 {
 1425         struct cas_softc *sc = (void *)self;
 1426         bus_space_tag_t t = sc->sc_memt;
 1427         bus_space_handle_t mif = sc->sc_memh;
 1428         int n;
 1429         u_int32_t v;
 1430 
 1431 #ifdef CAS_DEBUG
 1432         if (sc->sc_debug)
 1433                 printf("cas_mii_readreg: phy %d reg %d\n", phy, reg);
 1434 #endif
 1435 
 1436         /* Construct the frame command */
 1437         v = (reg << CAS_MIF_REG_SHIFT)  | (phy << CAS_MIF_PHY_SHIFT) |
 1438                 CAS_MIF_FRAME_READ;
 1439 
 1440         bus_space_write_4(t, mif, CAS_MIF_FRAME, v);
 1441         for (n = 0; n < 100; n++) {
 1442                 DELAY(1);
 1443                 v = bus_space_read_4(t, mif, CAS_MIF_FRAME);
 1444                 if (v & CAS_MIF_FRAME_TA0)
 1445                         return (v & CAS_MIF_FRAME_DATA);
 1446         }
 1447 
 1448         printf("%s: mii_read timeout\n", sc->sc_dev.dv_xname);
 1449         return (0);
 1450 }
 1451 
 1452 void
 1453 cas_mii_writereg(struct device *self, int phy, int reg, int val)
 1454 {
 1455         struct cas_softc *sc = (void *)self;
 1456         bus_space_tag_t t = sc->sc_memt;
 1457         bus_space_handle_t mif = sc->sc_memh;
 1458         int n;
 1459         u_int32_t v;
 1460 
 1461 #ifdef CAS_DEBUG
 1462         if (sc->sc_debug)
 1463                 printf("cas_mii_writereg: phy %d reg %d val %x\n",
 1464                         phy, reg, val);
 1465 #endif
 1466 
 1467 #if 0
 1468         /* Select the desired PHY in the MIF configuration register */
 1469         v = bus_space_read_4(t, mif, CAS_MIF_CONFIG);
 1470         /* Clear PHY select bit */
 1471         v &= ~CAS_MIF_CONFIG_PHY_SEL;
 1472         if (phy == CAS_PHYAD_EXTERNAL)
 1473                 /* Set PHY select bit to get at external device */
 1474                 v |= CAS_MIF_CONFIG_PHY_SEL;
 1475         bus_space_write_4(t, mif, CAS_MIF_CONFIG, v);
 1476 #endif
 1477         /* Construct the frame command */
 1478         v = CAS_MIF_FRAME_WRITE                 |
 1479             (phy << CAS_MIF_PHY_SHIFT)          |
 1480             (reg << CAS_MIF_REG_SHIFT)          |
 1481             (val & CAS_MIF_FRAME_DATA);
 1482 
 1483         bus_space_write_4(t, mif, CAS_MIF_FRAME, v);
 1484         for (n = 0; n < 100; n++) {
 1485                 DELAY(1);
 1486                 v = bus_space_read_4(t, mif, CAS_MIF_FRAME);
 1487                 if (v & CAS_MIF_FRAME_TA0)
 1488                         return;
 1489         }
 1490 
 1491         printf("%s: mii_write timeout\n", sc->sc_dev.dv_xname);
 1492 }
 1493 
 1494 void
 1495 cas_mii_statchg(struct device *dev)
 1496 {
 1497         struct cas_softc *sc = (void *)dev;
 1498 #ifdef CAS_DEBUG
 1499         int instance = IFM_INST(sc->sc_mii.mii_media.ifm_cur->ifm_media);
 1500 #endif
 1501         bus_space_tag_t t = sc->sc_memt;
 1502         bus_space_handle_t mac = sc->sc_memh;
 1503         u_int32_t v;
 1504 
 1505 #ifdef CAS_DEBUG
 1506         if (sc->sc_debug)
 1507                 printf("cas_mii_statchg: status change: phy = %d\n",
 1508                     sc->sc_phys[instance]);
 1509 #endif
 1510 
 1511         /* Set tx full duplex options */
 1512         bus_space_write_4(t, mac, CAS_MAC_TX_CONFIG, 0);
 1513         delay(10000); /* reg must be cleared and delay before changing. */
 1514         v = CAS_MAC_TX_ENA_IPG0|CAS_MAC_TX_NGU|CAS_MAC_TX_NGU_LIMIT|
 1515                 CAS_MAC_TX_ENABLE;
 1516         if ((IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) != 0) {
 1517                 v |= CAS_MAC_TX_IGN_CARRIER|CAS_MAC_TX_IGN_COLLIS;
 1518         }
 1519         bus_space_write_4(t, mac, CAS_MAC_TX_CONFIG, v);
 1520 
 1521         /* XIF Configuration */
 1522         v = CAS_MAC_XIF_TX_MII_ENA;
 1523         v |= CAS_MAC_XIF_LINK_LED;
 1524 
 1525         /* MII needs echo disable if half duplex. */
 1526         if ((IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) != 0)
 1527                 /* turn on full duplex LED */
 1528                 v |= CAS_MAC_XIF_FDPLX_LED;
 1529         else
 1530                 /* half duplex -- disable echo */
 1531                 v |= CAS_MAC_XIF_ECHO_DISABL;
 1532 
 1533         switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) {
 1534         case IFM_1000_T:  /* Gigabit using GMII interface */
 1535         case IFM_1000_SX:
 1536                 v |= CAS_MAC_XIF_GMII_MODE;
 1537                 break;
 1538         default:
 1539                 v &= ~CAS_MAC_XIF_GMII_MODE;
 1540         }
 1541         bus_space_write_4(t, mac, CAS_MAC_XIF_CONFIG, v);
 1542 }
 1543 
 1544 int
 1545 cas_pcs_readreg(struct device *self, int phy, int reg)
 1546 {
 1547         struct cas_softc *sc = (void *)self;
 1548         bus_space_tag_t t = sc->sc_memt;
 1549         bus_space_handle_t pcs = sc->sc_memh;
 1550 
 1551 #ifdef CAS_DEBUG
 1552         if (sc->sc_debug)
 1553                 printf("cas_pcs_readreg: phy %d reg %d\n", phy, reg);
 1554 #endif
 1555 
 1556         if (phy != CAS_PHYAD_EXTERNAL)
 1557                 return (0);
 1558 
 1559         switch (reg) {
 1560         case MII_BMCR:
 1561                 reg = CAS_MII_CONTROL;
 1562                 break;
 1563         case MII_BMSR:
 1564                 reg = CAS_MII_STATUS;
 1565                 break;
 1566         case MII_ANAR:
 1567                 reg = CAS_MII_ANAR;
 1568                 break;
 1569         case MII_ANLPAR:
 1570                 reg = CAS_MII_ANLPAR;
 1571                 break;
 1572         case MII_EXTSR:
 1573                 return (EXTSR_1000XFDX|EXTSR_1000XHDX);
 1574         default:
 1575                 return (0);
 1576         }
 1577 
 1578         return bus_space_read_4(t, pcs, reg);
 1579 }
 1580 
 1581 void
 1582 cas_pcs_writereg(struct device *self, int phy, int reg, int val)
 1583 {
 1584         struct cas_softc *sc = (void *)self;
 1585         bus_space_tag_t t = sc->sc_memt;
 1586         bus_space_handle_t pcs = sc->sc_memh;
 1587 
 1588 #ifdef CAS_DEBUG
 1589         if (sc->sc_debug)
 1590                 printf("cas_pcs_writereg: phy %d reg %d val %x\n",
 1591                         phy, reg, val);
 1592 #endif
 1593 
 1594         if (phy != CAS_PHYAD_EXTERNAL)
 1595                 return;
 1596 
 1597         switch (reg) {
 1598         case MII_BMCR:
 1599                 reg = CAS_MII_CONTROL;
 1600                 break;
 1601         case MII_BMSR:
 1602                 reg = CAS_MII_STATUS;
 1603                 break;
 1604         case MII_ANAR:
 1605                 reg = CAS_MII_ANAR;
 1606                 break;
 1607         case MII_ANLPAR:
 1608                 reg = CAS_MII_ANLPAR;
 1609                 break;
 1610         default:
 1611                 return;
 1612         }
 1613 
 1614         bus_space_write_4(t, pcs, reg, val);
 1615 
 1616         if (reg == CAS_MII_ANAR) {
 1617                 bus_space_write_4(t, pcs, CAS_MII_SLINK_CONTROL,
 1618                     CAS_MII_SLINK_LOOPBACK|CAS_MII_SLINK_EN_SYNC_D);
 1619                 bus_space_write_4(t, pcs, CAS_MII_CONFIG,
 1620                     CAS_MII_CONFIG_ENABLE);
 1621         }
 1622 }
 1623 
 1624 int
 1625 cas_mediachange(struct ifnet *ifp)
 1626 {
 1627         struct cas_softc *sc = ifp->if_softc;
 1628         struct mii_data *mii = &sc->sc_mii;
 1629 
 1630         if (mii->mii_instance) {
 1631                 struct mii_softc *miisc;
 1632                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
 1633                         mii_phy_reset(miisc);
 1634         }
 1635 
 1636         return (mii_mediachg(&sc->sc_mii));
 1637 }
 1638 
 1639 void
 1640 cas_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
 1641 {
 1642         struct cas_softc *sc = ifp->if_softc;
 1643 
 1644         mii_pollstat(&sc->sc_mii);
 1645         ifmr->ifm_active = sc->sc_mii.mii_media_active;
 1646         ifmr->ifm_status = sc->sc_mii.mii_media_status;
 1647 }
 1648 
 1649 /*
 1650  * Process an ioctl request.
 1651  */
 1652 int
 1653 cas_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 1654 {
 1655         struct cas_softc *sc = ifp->if_softc;
 1656         struct ifaddr *ifa = (struct ifaddr *)data;
 1657         struct ifreq *ifr = (struct ifreq *)data;
 1658         int s, error = 0;
 1659 
 1660         s = splnet();
 1661 
 1662         if ((error = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data)) > 0) {
 1663                 splx(s);
 1664                 return (error);
 1665         }
 1666 
 1667         switch (cmd) {
 1668 
 1669         case SIOCSIFADDR:
 1670                 ifp->if_flags |= IFF_UP;
 1671                 if ((ifp->if_flags & IFF_RUNNING) == 0)
 1672                         cas_init(ifp);
 1673 #ifdef INET
 1674                 if (ifa->ifa_addr->sa_family == AF_INET)
 1675                         arp_ifinit(&sc->sc_arpcom, ifa);
 1676 #endif
 1677                 break;
 1678 
 1679         case SIOCSIFFLAGS:
 1680                 if (ifp->if_flags & IFF_UP) {
 1681                         if ((ifp->if_flags & IFF_RUNNING) &&
 1682                             ((ifp->if_flags ^ sc->sc_if_flags) &
 1683                              (IFF_ALLMULTI | IFF_PROMISC)) != 0)
 1684                                 cas_setladrf(sc);
 1685                         else {
 1686                                 if ((ifp->if_flags & IFF_RUNNING) == 0)
 1687                                         cas_init(ifp);
 1688                         }
 1689                 } else {
 1690                         if (ifp->if_flags & IFF_RUNNING)
 1691                                 cas_stop(ifp, 1);
 1692                 }
 1693                 sc->sc_if_flags = ifp->if_flags;
 1694 
 1695 #ifdef CAS_DEBUG
 1696                 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0;
 1697 #endif
 1698                 break;
 1699 
 1700         case SIOCSIFMTU:
 1701                 if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
 1702                         error = EINVAL;
 1703                 } else if (ifp->if_mtu != ifr->ifr_mtu) {
 1704                         ifp->if_mtu = ifr->ifr_mtu;
 1705                 }
 1706                 break;
 1707 
 1708         case SIOCADDMULTI:
 1709         case SIOCDELMULTI:
 1710                 error = (cmd == SIOCADDMULTI) ?
 1711                     ether_addmulti(ifr, &sc->sc_arpcom) :
 1712                     ether_delmulti(ifr, &sc->sc_arpcom);
 1713 
 1714                 if (error == ENETRESET) {
 1715                         /*
 1716                          * Multicast list has changed; set the hardware filter
 1717                          * accordingly.
 1718                          */
 1719                         if (ifp->if_flags & IFF_RUNNING)
 1720                                 cas_setladrf(sc);
 1721                         error = 0;
 1722                 }
 1723                 break;
 1724 
 1725         case SIOCGIFMEDIA:
 1726         case SIOCSIFMEDIA:
 1727                 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
 1728                 break;
 1729 
 1730         default:
 1731                 error = EINVAL;
 1732                 break;
 1733         }
 1734 
 1735         splx(s);
 1736         return (error);
 1737 }
 1738 
 1739 
 1740 void
 1741 cas_shutdown(void *arg)
 1742 {
 1743         struct cas_softc *sc = (struct cas_softc *)arg;
 1744         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
 1745 
 1746         cas_stop(ifp, 1);
 1747 }
 1748 
 1749 /*
 1750  * Set up the logical address filter.
 1751  */
 1752 void
 1753 cas_setladrf(struct cas_softc *sc)
 1754 {
 1755         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
 1756         struct ether_multi *enm;
 1757         struct ether_multistep step;
 1758         struct arpcom *ac = &sc->sc_arpcom;
 1759         bus_space_tag_t t = sc->sc_memt;
 1760         bus_space_handle_t h = sc->sc_memh;
 1761         u_int32_t crc, hash[16], v;
 1762         int i;
 1763 
 1764         /* Get current RX configuration */
 1765         v = bus_space_read_4(t, h, CAS_MAC_RX_CONFIG);
 1766 
 1767 
 1768         /*
 1769          * Turn off promiscuous mode, promiscuous group mode (all multicast),
 1770          * and hash filter.  Depending on the case, the right bit will be
 1771          * enabled.
 1772          */
 1773         v &= ~(CAS_MAC_RX_PROMISCUOUS|CAS_MAC_RX_HASH_FILTER|
 1774             CAS_MAC_RX_PROMISC_GRP);
 1775 
 1776         if ((ifp->if_flags & IFF_PROMISC) != 0) {
 1777                 /* Turn on promiscuous mode */
 1778                 v |= CAS_MAC_RX_PROMISCUOUS;
 1779                 ifp->if_flags |= IFF_ALLMULTI;
 1780                 goto chipit;
 1781         }
 1782 
 1783         /*
 1784          * Set up multicast address filter by passing all multicast addresses
 1785          * through a crc generator, and then using the high order 8 bits as an
 1786          * index into the 256 bit logical address filter.  The high order 4
 1787          * bits selects the word, while the other 4 bits select the bit within
 1788          * the word (where bit 0 is the MSB).
 1789          */
 1790 
 1791         /* Clear hash table */
 1792         for (i = 0; i < 16; i++)
 1793                 hash[i] = 0;
 1794 
 1795 
 1796         ETHER_FIRST_MULTI(step, ac, enm);
 1797         while (enm != NULL) {
 1798                 if (bcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
 1799                         /*
 1800                          * We must listen to a range of multicast addresses.
 1801                          * For now, just accept all multicasts, rather than
 1802                          * trying to set only those filter bits needed to match
 1803                          * the range.  (At this time, the only use of address
 1804                          * ranges is for IP multicast routing, for which the
 1805                          * range is big enough to require all bits set.)
 1806                          * XXX use the addr filter for this
 1807                          */
 1808                         ifp->if_flags |= IFF_ALLMULTI;
 1809                         v |= CAS_MAC_RX_PROMISC_GRP;
 1810                         goto chipit;
 1811                 }
 1812 
 1813                 crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN);
 1814 
 1815                 /* Just want the 8 most significant bits. */
 1816                 crc >>= 24;
 1817 
 1818                 /* Set the corresponding bit in the filter. */
 1819                 hash[crc >> 4] |= 1 << (15 - (crc & 15));
 1820 
 1821                 ETHER_NEXT_MULTI(step, enm);
 1822         }
 1823 
 1824         v |= CAS_MAC_RX_HASH_FILTER;
 1825         ifp->if_flags &= ~IFF_ALLMULTI;
 1826 
 1827         /* Now load the hash table into the chip (if we are using it) */
 1828         for (i = 0; i < 16; i++) {
 1829                 bus_space_write_4(t, h,
 1830                     CAS_MAC_HASH0 + i * (CAS_MAC_HASH1-CAS_MAC_HASH0),
 1831                     hash[i]);
 1832         }
 1833 
 1834 chipit:
 1835         bus_space_write_4(t, h, CAS_MAC_RX_CONFIG, v);
 1836 }
 1837 
 1838 int
 1839 cas_encap(struct cas_softc *sc, struct mbuf *mhead, u_int32_t *bixp)
 1840 {
 1841         u_int64_t flags;
 1842         u_int32_t cur, frag, i;
 1843         bus_dmamap_t map;
 1844 
 1845         cur = frag = *bixp;
 1846         map = sc->sc_txd[cur].sd_map;
 1847 
 1848         if (bus_dmamap_load_mbuf(sc->sc_dmatag, map, mhead,
 1849             BUS_DMA_NOWAIT) != 0) {
 1850                 return (ENOBUFS);
 1851         }
 1852 
 1853         if ((sc->sc_tx_cnt + map->dm_nsegs) > (CAS_NTXDESC - 2)) {
 1854                 bus_dmamap_unload(sc->sc_dmatag, map);
 1855                 return (ENOBUFS);
 1856         }
 1857 
 1858         bus_dmamap_sync(sc->sc_dmatag, map, 0, map->dm_mapsize,
 1859             BUS_DMASYNC_PREWRITE);
 1860 
 1861         for (i = 0; i < map->dm_nsegs; i++) {
 1862                 sc->sc_txdescs[frag].cd_addr =
 1863                     CAS_DMA_WRITE(map->dm_segs[i].ds_addr);
 1864                 flags = (map->dm_segs[i].ds_len & CAS_TD_BUFSIZE) |
 1865                     (i == 0 ? CAS_TD_START_OF_PACKET : 0) |
 1866                     ((i == (map->dm_nsegs - 1)) ? CAS_TD_END_OF_PACKET : 0);
 1867                 sc->sc_txdescs[frag].cd_flags = CAS_DMA_WRITE(flags);
 1868                 bus_dmamap_sync(sc->sc_dmatag, sc->sc_cddmamap,
 1869                     CAS_CDTXOFF(frag), sizeof(struct cas_desc),
 1870                     BUS_DMASYNC_PREWRITE);
 1871                 cur = frag;
 1872                 if (++frag == CAS_NTXDESC)
 1873                         frag = 0;
 1874         }
 1875 
 1876         sc->sc_tx_cnt += map->dm_nsegs;
 1877         sc->sc_txd[*bixp].sd_map = sc->sc_txd[cur].sd_map;
 1878         sc->sc_txd[cur].sd_map = map;
 1879         sc->sc_txd[cur].sd_mbuf = mhead;
 1880 
 1881         bus_space_write_4(sc->sc_memt, sc->sc_memh, CAS_TX_KICK, frag);
 1882 
 1883         *bixp = frag;
 1884 
 1885         /* sync descriptors */
 1886 
 1887         return (0);
 1888 }
 1889 
 1890 /*
 1891  * Transmit interrupt.
 1892  */
 1893 int
 1894 cas_tint(struct cas_softc *sc, u_int32_t status)
 1895 {
 1896         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
 1897         struct cas_sxd *sd;
 1898         u_int32_t cons, hwcons;
 1899 
 1900         hwcons = status >> 19;
 1901         cons = sc->sc_tx_cons;
 1902         while (cons != hwcons) {
 1903                 sd = &sc->sc_txd[cons];
 1904                 if (sd->sd_mbuf != NULL) {
 1905                         bus_dmamap_sync(sc->sc_dmatag, sd->sd_map, 0,
 1906                             sd->sd_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
 1907                         bus_dmamap_unload(sc->sc_dmatag, sd->sd_map);
 1908                         m_freem(sd->sd_mbuf);
 1909                         sd->sd_mbuf = NULL;
 1910                 }
 1911                 sc->sc_tx_cnt--;
 1912                 ifp->if_opackets++;
 1913                 if (++cons == CAS_NTXDESC)
 1914                         cons = 0;
 1915         }
 1916         sc->sc_tx_cons = cons;
 1917 
 1918         cas_start(ifp);
 1919 
 1920         if (sc->sc_tx_cnt == 0)
 1921                 ifp->if_timer = 0;
 1922 
 1923         return (1);
 1924 }
 1925 
 1926 void
 1927 cas_start(struct ifnet *ifp)
 1928 {
 1929         struct cas_softc *sc = ifp->if_softc;
 1930         struct mbuf *m;
 1931         u_int32_t bix;
 1932 
 1933         if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
 1934                 return;
 1935 
 1936         bix = sc->sc_tx_prod;
 1937         while (sc->sc_txd[bix].sd_mbuf == NULL) {
 1938                 IFQ_POLL(&ifp->if_snd, m);
 1939                 if (m == NULL)
 1940                         break;
 1941 
 1942 #if NBPFILTER > 0
 1943                 /*
 1944                  * If BPF is listening on this interface, let it see the
 1945                  * packet before we commit it to the wire.
 1946                  */
 1947                 if (ifp->if_bpf)
 1948                         bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
 1949 #endif
 1950 
 1951                 /*
 1952                  * Encapsulate this packet and start it going...
 1953                  * or fail...
 1954                  */
 1955                 if (cas_encap(sc, m, &bix)) {
 1956                         ifp->if_timer = 2;
 1957                         break;
 1958                 }
 1959 
 1960                 IFQ_DEQUEUE(&ifp->if_snd, m);
 1961                 ifp->if_timer = 5;
 1962         }
 1963 
 1964         sc->sc_tx_prod = bix;
 1965 }

/* [<][>][^][v][top][bottom][index][help] */