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/pci/if_tx.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 /*      $OpenBSD: if_tx.c,v 1.3 1998/10/10 04:30:09 jason Exp $ */
    2 /* $FreeBSD: src/sys/pci/if_tx.c,v 1.1.2.8 1999/09/05 08:21:12 peter Exp $ */
    3 
    4 /*-
    5  * Copyright (c) 1997 Semen Ustimenko (semen@iclub.nsu.ru)
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  *
   30  */
   31 
   32 /*
   33  * EtherPower II 10/100  Fast Ethernet (tx0)
   34  * (aka SMC9432TX based on SMC83c170 EPIC chip)
   35  * 
   36  * Thanks are going to Steve Bauer and Jason Wright.
   37  *
   38  * todo:
   39  *      Deal with bus mastering, i.e. i realy don't know what to do with
   40  *          it and how it can improve performance.
   41  *      Implement FULL IFF_MULTICAST support.
   42  *      Test, test and test again:-(
   43  *      
   44  */
   45 
   46 /* We should define compile time options before if_txvar.h included */
   47 /*#define       EPIC_NOIFMEDIA  1*/
   48 /*#define       EPIC_USEIOSPACE 1*/
   49 #define EARLY_RX        1
   50 /*#define       EPIC_DEBUG      1*/
   51 
   52 #if defined(EPIC_DEBUG)
   53 #define dprintf(a) printf a
   54 #else
   55 #define dprintf(a)
   56 #endif
   57 
   58 /* Macro to get either mbuf cluster or nothing */
   59 #define EPIC_MGETCLUSTER(m) \
   60         { MGETHDR((m),M_DONTWAIT,MT_DATA); \
   61           if (m) { \
   62             MCLGET((m),M_DONTWAIT); \
   63             if( NULL == ((m)->m_flags & M_EXT) ){ \
   64               m_freem(m); \
   65               (m) = NULL; \
   66             } \
   67           } \
   68         }
   69 
   70 #include "bpfilter.h"
   71 #include "pci.h"
   72 
   73 #if NPCI > 0
   74 #include <sys/param.h>
   75 #include <sys/systm.h>
   76 #include <sys/mbuf.h>
   77 #include <sys/malloc.h>
   78 #include <sys/kernel.h>
   79 #include <sys/socket.h>
   80 #include <sys/sockio.h>
   81 
   82 #include <net/if.h>
   83 #include <net/if_dl.h>
   84 #include <net/if_types.h>
   85 
   86 #if !defined(SIOCSIFMEDIA) || defined(EPIC_NOIFMEDIA)
   87 #define EPIC_NOIFMEDIA  1
   88 #else
   89 #include <net/if_media.h>
   90 #endif
   91 
   92 #ifdef INET
   93 #include <netinet/in.h>
   94 #include <netinet/in_systm.h>
   95 #include <netinet/in_var.h>
   96 #include <netinet/ip.h>
   97 #endif
   98 
   99 #ifdef IPX
  100 #include <netipx/ipx.h>
  101 #include <netipx/ipx_if.h>
  102 #endif
  103 
  104 #ifdef NS
  105 #include <netns/ns.h>
  106 #include <netns/ns_if.h>
  107 #endif
  108 
  109 #if NBPFILTER > 0
  110 #include <net/bpf.h>
  111 #include <net/bpfdesc.h>
  112 #endif
  113 
  114 #if defined(__OpenBSD__)
  115 #include <sys/ioctl.h>
  116 #include <sys/errno.h>
  117 #include <sys/device.h>
  118 
  119 #include <netinet/if_ether.h>
  120 
  121 #include <vm/vm.h>
  122 
  123 #include <dev/pci/pcivar.h>
  124 #include <dev/pci/pcireg.h>
  125 #include <dev/pci/pcidevs.h>
  126 
  127 #include <dev/pci/if_txvar.h>
  128 #else /* __FreeBSD__ */
  129 #include <net/if_mib.h>
  130 #include <netinet/in.h>
  131 #include <netinet/if_ether.h>
  132 #include <vm/vm.h>
  133 #include <vm/pmap.h>
  134 #include <machine/clock.h>
  135 
  136 #include <pci/pcivar.h>
  137 #include <pci/if_txvar.h>
  138 #endif
  139 
  140 #if defined(__FreeBSD__)
  141 #if __FreeBSD_version >= 300000
  142 #define EPIC_IFIOCTL_CMD_TYPE u_long
  143 #else
  144 #define EPIC_IFIOCTL_CMD_TYPE int
  145 #endif
  146 #define EPIC_INTR_RET_TYPE void
  147 #else /* __OpenBSD__ */
  148 #define EPIC_IFIOCTL_CMD_TYPE u_long
  149 #define EPIC_INTR_RET_TYPE int
  150 #endif
  151 
  152 static int epic_ifioctl __P((register struct ifnet *, EPIC_IFIOCTL_CMD_TYPE, caddr_t));
  153 static EPIC_INTR_RET_TYPE epic_intr __P((void *));
  154 static int epic_common_attach __P((epic_softc_t *));
  155 static void epic_ifstart __P((struct ifnet *));
  156 static void epic_ifwatchdog __P((struct ifnet *));
  157 static int epic_init __P((epic_softc_t *));
  158 static void epic_stop __P((epic_softc_t *));
  159 static __inline void epic_rx_done __P((epic_softc_t *));
  160 static __inline void epic_tx_done __P((epic_softc_t *));
  161 static int epic_init_rings __P((epic_softc_t *));
  162 static void epic_free_rings __P((epic_softc_t *));
  163 static void epic_stop_activity __P((epic_softc_t *));
  164 static void epic_start_activity __P((epic_softc_t *));
  165 static void epic_set_rx_mode __P((epic_softc_t *));
  166 static void epic_set_tx_mode __P((epic_softc_t *));
  167 static void epic_set_mc_table __P((epic_softc_t *));
  168 static void epic_set_media_speed __P((epic_softc_t *));
  169 static void epic_init_phy __P((epic_softc_t *));
  170 static void epic_dump_state __P((epic_softc_t *));
  171 static int epic_autoneg __P((epic_softc_t *));
  172 static int epic_read_eeprom __P((epic_softc_t *,u_int16_t));
  173 static void epic_output_eepromw __P((epic_softc_t *, u_int16_t));
  174 static u_int16_t epic_input_eepromw __P((epic_softc_t *));
  175 static u_int8_t epic_eeprom_clock __P((epic_softc_t *,u_int8_t));
  176 static void epic_write_eepromreg __P((epic_softc_t *,u_int8_t));
  177 static u_int8_t epic_read_eepromreg __P((epic_softc_t *));
  178 static u_int16_t epic_read_phy_register __P((epic_softc_t *, u_int16_t));
  179 static void epic_write_phy_register __P((epic_softc_t *, u_int16_t, u_int16_t));
  180 
  181 #if !defined(EPIC_NOIFMEDIA)
  182 static int epic_ifmedia_change __P((struct ifnet *));
  183 static void epic_ifmedia_status __P((struct ifnet *, struct ifmediareq *));
  184 #endif
  185 
  186 /* -------------------------------------------------------------------------
  187    OS-specific part
  188    ------------------------------------------------------------------------- */
  189 
  190 #if defined(__OpenBSD__)
  191 /* -----------------------------OpenBSD------------------------------------- */
  192 
  193 static int epic_openbsd_probe __P((struct device *,void *,void *));
  194 static void epic_openbsd_attach __P((struct device *, struct device *, void *));
  195 static void epic_shutdown __P((void *));
  196 
  197 struct cfattach tx_ca = {
  198         sizeof(epic_softc_t), epic_openbsd_probe, epic_openbsd_attach 
  199 };
  200 struct cfdriver tx_cd = {
  201         NULL,"tx",DV_IFNET
  202 };
  203 
  204 /* Synopsis: Check if device id corresponds with SMC83C170 id. */
  205 static int 
  206 epic_openbsd_probe(
  207     struct device *parent,
  208     void *match,
  209     void *aux )
  210 {
  211         struct pci_attach_args *pa = aux;
  212         if( PCI_VENDOR(pa->pa_id) != SMC_VENDORID )
  213                 return 0;
  214 
  215         if( PCI_PRODUCT(pa->pa_id) == CHIPID_83C170 )
  216                 return 1;
  217 
  218         return 0;
  219 }
  220 
  221 static void
  222 epic_openbsd_attach(
  223     struct device *parent,
  224     struct device *self,
  225     void *aux )
  226 {
  227         epic_softc_t *sc = (epic_softc_t*)self;
  228         struct pci_attach_args *pa = aux;
  229         pci_chipset_tag_t pc = pa->pa_pc;
  230         pci_intr_handle_t ih;
  231         const char *intrstr = NULL;
  232         struct ifnet *ifp;
  233         bus_space_tag_t iot = pa->pa_iot;
  234         bus_addr_t iobase;
  235         bus_size_t iosize; 
  236         int i;
  237 #if !defined(EPIC_NOIFMEDIA)
  238         int tmp;
  239 #endif
  240 
  241         if( pci_io_find(pc, pa->pa_tag, PCI_CBIO, &iobase, &iosize)) {
  242                 printf(": can't find i/o space\n");
  243                 return;
  244         }
  245         if( bus_space_map(iot, iobase, iosize, 0, &sc->sc_sh)) {
  246                 printf(": can't map i/o space\n");
  247                 return;
  248         }
  249         sc->sc_st = iot;
  250 
  251         ifp = &sc->sc_if;
  252         bcopy(sc->sc_dev.dv_xname, ifp->if_xname,IFNAMSIZ);
  253         ifp->if_softc = sc;
  254         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  255         ifp->if_ioctl = epic_ifioctl;
  256         ifp->if_start = epic_ifstart;
  257         ifp->if_watchdog = epic_ifwatchdog;
  258 
  259         /* Do common attach procedure */
  260         if( epic_common_attach(sc) ) return;
  261 
  262         /* Map interrupt */
  263         if( pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin,
  264             pa->pa_intrline, &ih)) {
  265                 printf(": can't map interrupt\n");
  266                 return;
  267         }
  268         intrstr = pci_intr_string(pc, ih);
  269         sc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, epic_intr, sc, 
  270             self->dv_xname);
  271 
  272         if( NULL == sc->sc_ih ) {
  273                 printf(": can't establish interrupt");
  274                 if( intrstr )printf(" at %s",intrstr);
  275                 printf("\n");
  276                 return;
  277         } 
  278         printf(": %s",intrstr);
  279 
  280         /* Display some info */
  281         printf(" address %s",ether_sprintf(sc->sc_macaddr));
  282         /* Read current media config and display it too */
  283         i = PHY_READ_2( sc, DP83840_BMCR );
  284 #if !defined(EPIC_NOIFMEDIA)
  285         tmp = IFM_ETHER;
  286 #endif
  287         if( i & BMCR_AUTONEGOTIATION ){
  288                 printf(", Auto-Neg ");
  289 
  290                 /* To avoid bug in QS6612 read LPAR enstead of BMSR */
  291                 i = PHY_READ_2( sc, DP83840_LPAR );
  292                 if( i & (ANAR_100_TX|ANAR_100_TX_FD) ) printf("100Mbps");
  293                 else printf("10Mbps");
  294                 if( i & (ANAR_10_FD|ANAR_100_TX_FD) ) printf(" FD");
  295 #if !defined(EPIC_NOIFMEDIA)
  296                 tmp |= IFM_AUTO;
  297 #endif
  298         } else {
  299 #if defined(EPIC_NOIFMEDIA)
  300                 ifp->if_flags |= IFF_LINK0;
  301 #endif
  302                 if( i & BMCR_100MBPS ) {
  303                         printf(", 100Mbps");
  304 #if !defined(EPIC_NOIFMEDIA)
  305                         tmp |= IFM_100_TX;
  306 #else
  307                         ifp->if_flags |= IFF_LINK2;
  308 #endif
  309                 } else {
  310                         printf(", 10Mbps");
  311 #if !defined(EPIC_NOIFMEDIA)
  312                         tmp |= IFM_10_T;
  313 #endif
  314                 }
  315                 if( i & BMCR_FULL_DUPLEX ) {
  316                         printf(" FD");
  317 #if !defined(EPIC_NOIFMEDIA)
  318                         tmp |= IFM_FDX;
  319 #else
  320                         ifp->if_flags |= IFF_LINK1;
  321 #endif
  322                 }
  323         }
  324 
  325         /* Init ifmedia interface */
  326 #if !defined(EPIC_NOIFMEDIA)
  327         ifmedia_init(&sc->ifmedia,0,epic_ifmedia_change,epic_ifmedia_status);
  328         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_10_T,0,NULL);
  329         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_10_T|IFM_LOOP,0,NULL);
  330         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_10_T|IFM_FDX,0,NULL);
  331         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_100_TX,0,NULL);
  332         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_100_TX|IFM_LOOP,0,NULL);
  333         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_100_TX|IFM_FDX,0,NULL);
  334         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_AUTO,0,NULL);
  335         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_LOOP,0,NULL);
  336         ifmedia_set(&sc->ifmedia, tmp);
  337 #endif
  338 
  339         /* Attach os interface and bpf */
  340         if_attach(ifp);
  341         ether_ifattach(ifp);
  342 #if NBPFILTER > 0
  343         bpfattach(&sc->sc_if.if_bpf, ifp, DLT_EN10MB,
  344             sizeof(struct ether_header));
  345 #endif
  346 
  347         /* Set shutdown routine to stop DMA process */ 
  348         shutdownhook_establish(epic_shutdown, sc);
  349         printf("\n");
  350 }
  351 
  352 /* Simple call epic_stop() */
  353 static void
  354 epic_shutdown(
  355     void *sc)
  356 {
  357         epic_stop(sc);
  358 }
  359 
  360 #else /* __FreeBSD__ */
  361 /* -----------------------------FreeBSD------------------------------------- */
  362 
  363 static char* epic_freebsd_probe __P((pcici_t, pcidi_t));
  364 static void epic_freebsd_attach __P((pcici_t, int));
  365 static void epic_shutdown __P((int, void *));
  366 
  367 /* Global variables */
  368 static u_long epic_pci_count;
  369 static struct pci_device txdevice = { 
  370         "tx",
  371         epic_freebsd_probe,
  372         epic_freebsd_attach,
  373         &epic_pci_count,
  374         NULL };
  375 
  376 /* Append this driver to pci drivers list */
  377 DATA_SET ( pcidevice_set, txdevice );
  378 
  379 /* Synopsis: Check if device id corresponds with SMC83C170 id.  */
  380 static char*
  381 epic_freebsd_probe(
  382     pcici_t config_id,
  383     pcidi_t device_id)
  384 {
  385         if( PCI_VENDORID(device_id) != SMC_VENDORID )
  386                 return NULL;
  387 
  388         if( PCI_CHIPID(device_id) == CHIPID_83C170 )
  389                 return "SMC 83c170";
  390 
  391         return NULL;
  392 }
  393 
  394 /*
  395  * Do FreeBSD-specific attach routine, like map registers, alloc softc
  396  * structure and etc.
  397  */
  398 static void
  399 epic_freebsd_attach(
  400     pcici_t config_id,
  401     int unit)
  402 {
  403         struct ifnet *ifp;
  404         epic_softc_t *sc;
  405 #if defined(EPIC_USEIOSPACE)
  406         u_int32_t iobase;
  407 #else
  408         caddr_t pmembase;
  409 #endif
  410         int i,k,s,tmp;
  411         u_int32_t pool;
  412 
  413         printf("tx%d",unit);
  414 
  415         /* Allocate memory for softc, hardware descriptors and frag lists */
  416         sc = (epic_softc_t *) malloc( sizeof(epic_softc_t), M_DEVBUF, M_NOWAIT);
  417         if (sc == NULL) return;
  418 
  419         /* Preinitialize softc structure */
  420         bzero(sc, sizeof(epic_softc_t));                
  421         sc->unit = unit;
  422 
  423         /* Fill ifnet structure */
  424         ifp = &sc->sc_if;
  425         ifp->if_unit = unit;
  426         ifp->if_name = "tx";
  427         ifp->if_softc = sc;
  428         ifp->if_flags = IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST;
  429         ifp->if_ioctl = epic_ifioctl;
  430         ifp->if_start = epic_ifstart;
  431         ifp->if_watchdog = epic_ifwatchdog;
  432         ifp->if_init = (if_init_f_t*)epic_init;
  433         ifp->if_timer = 0;
  434         ifp->if_output = ether_output;
  435 
  436         /* Get iobase or membase */
  437 #if defined(EPIC_USEIOSPACE)
  438         if (!pci_map_port(config_id, PCI_CBIO,(u_short *) &(sc->iobase))) {
  439                 printf(": cannot map port\n");
  440                 free(sc, M_DEVBUF);
  441                 return;
  442         }
  443 #else
  444         if (!pci_map_mem(config_id, PCI_CBMA,(vm_offset_t *) &(sc->csr),(vm_offset_t *) &pmembase)) {
  445                 printf(": cannot map memory\n"); 
  446                 free(sc, M_DEVBUF);
  447                 return;
  448         }
  449 #endif
  450 
  451         if( epic_common_attach(sc) ) return;
  452 
  453         /* Display ethernet address ,... */
  454         printf(": address %02x:%02x:%02x:%02x:%02x:%02x,",
  455                 sc->sc_macaddr[0],sc->sc_macaddr[1],sc->sc_macaddr[2],
  456                 sc->sc_macaddr[3],sc->sc_macaddr[4],sc->sc_macaddr[5]);
  457 
  458         /* board type and ... */
  459         printf(" type ");
  460         for(i=0x2c;i<0x32;i++) {
  461                 tmp = epic_read_eeprom( sc, i );
  462                 if( ' ' == (u_int8_t)tmp ) break;
  463                 printf("%c",(u_int8_t)tmp);
  464                 tmp >>= 8;
  465                 if( ' ' == (u_int8_t)tmp ) break;
  466                 printf("%c",(u_int8_t)tmp);
  467         }
  468 
  469         /* Read current media config and display it too */
  470         i = PHY_READ_2( sc, DP83840_BMCR );
  471 #if !defined(EPIC_NOIFMEDIA)
  472         tmp = IFM_ETHER;
  473 #endif
  474         if( i & BMCR_AUTONEGOTIATION ){
  475                 printf(", Auto-Neg ");
  476 
  477                 /* To avoid bug in QS6612 read LPAR enstead of BMSR */
  478                 i = PHY_READ_2( sc, DP83840_LPAR );
  479                 if( i & (ANAR_100_TX|ANAR_100_TX_FD) ) printf("100Mbps ");
  480                 else printf("10Mbps ");
  481                 if( i & (ANAR_10_FD|ANAR_100_TX_FD) ) printf("FD");
  482 #if !defined(EPIC_NOIFMEDIA)
  483                 tmp |= IFM_AUTO;
  484 #endif
  485         } else {
  486 #if defined(EPIC_NOIFMEDIA)
  487                 ifp->if_flags |= IFF_LINK0;
  488 #endif
  489                 if( i & BMCR_100MBPS ) {
  490                         printf(", 100Mbps ");
  491 #if !defined(EPIC_NOIFMEDIA)
  492                         tmp |= IFM_100_TX;
  493 #else
  494                         ifp->if_flags |= IFF_LINK2;
  495 #endif
  496                 } else {
  497                         printf(", 10Mbps ");
  498 #if !defined(EPIC_NOIFMEDIA)
  499                         tmp |= IFM_10_T;
  500 #endif
  501                 }
  502                 if( i & BMCR_FULL_DUPLEX ) {
  503                         printf("FD");
  504 #if !defined(EPIC_NOIFMEDIA)
  505                         tmp |= IFM_FDX;
  506 #else
  507                         ifp->if_flags |= IFF_LINK1;
  508 #endif
  509                 }
  510         }
  511 
  512         /* Init ifmedia interface */
  513 #if !defined(EPIC_NOIFMEDIA)
  514         ifmedia_init(&sc->ifmedia,0,epic_ifmedia_change,epic_ifmedia_status);
  515         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_10_T,0,NULL);
  516         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_10_T|IFM_LOOP,0,NULL);
  517         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_10_T|IFM_FDX,0,NULL);
  518         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_100_TX,0,NULL);
  519         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_100_TX|IFM_LOOP,0,NULL);
  520         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_100_TX|IFM_FDX,0,NULL);
  521         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_AUTO,0,NULL);
  522         ifmedia_add(&sc->ifmedia,IFM_ETHER|IFM_LOOP,0,NULL);
  523         ifmedia_set(&sc->ifmedia, tmp);
  524 #endif
  525 
  526         s = splimp();
  527 
  528         /* Map interrupt */
  529         if( !pci_map_int(config_id, epic_intr, (void*)sc, &net_imask) ) {
  530                 printf(": couldn't map interrupt\n");
  531                 free(sc, M_DEVBUF);
  532                 return;
  533         }
  534 
  535         /* Set shut down routine to stop DMA processes on reboot */
  536         at_shutdown(epic_shutdown, sc, SHUTDOWN_POST_SYNC);
  537 
  538         /*  Attach to if manager */
  539         if_attach(ifp);
  540         ether_ifattach(ifp);
  541 
  542 #if NBPFILTER > 0
  543         bpfattach(ifp,DLT_EN10MB, sizeof(struct ether_header));
  544 #endif
  545 
  546         splx(s);
  547 
  548         printf("\n");
  549 
  550         return;
  551 }
  552 
  553 static void
  554 epic_shutdown(
  555     int howto,
  556     void *sc)
  557 {
  558         epic_stop(sc);
  559 }
  560 
  561 #endif /* __OpenBSD__ */
  562 
  563 /* ------------------------------------------------------------------------
  564    OS-independing part
  565    ------------------------------------------------------------------------ */
  566 
  567 /*
  568  * This is if_ioctl handler. 
  569  */
  570 static int
  571 epic_ifioctl __P((
  572     register struct ifnet * ifp,
  573     EPIC_IFIOCTL_CMD_TYPE command,
  574     caddr_t data))
  575 {
  576         epic_softc_t *sc = ifp->if_softc;
  577         int x, error = 0;
  578 
  579         x = splimp();
  580 
  581         switch (command) {
  582 #if defined(__FreeBSD__)
  583         case SIOCSIFADDR:
  584         case SIOCGIFADDR:
  585         case SIOCSIFMTU:
  586                 error = ether_ioctl(ifp, command, data);
  587                 break;
  588 #else /* __OpenBSD__ */
  589         case SIOCSIFADDR: {
  590                 struct ifaddr *ifa = (struct ifaddr *)data;
  591                 
  592                 ifp->if_flags |= IFF_UP;
  593                 switch(ifa->ifa_addr->sa_family) {
  594 #if INET
  595                 case AF_INET:
  596                         epic_stop(sc);
  597                         epic_init(sc);
  598                         arp_ifinit(&sc->arpcom,ifa);
  599                         break;
  600 #endif /* __FreeBSD__ */
  601 #if NS
  602                 case AF_NS: {
  603                         register struct ns_addr * ina = &IA_SNS(ifa)->sns_addr;
  604 
  605                         if( ns_nullhost(*ina) ) 
  606                                 ina->x_host = 
  607                                     *(union ns_host *) LLADDR(ifp->if_sadl);
  608                         else
  609                                 bcopy(ina->x_host.c_host, LLADDR(ifp->if_sadl),
  610                                     ifp->if_addrlen);
  611 
  612                         epic_stop(sc);
  613                         epic_init(sc);
  614                         break;
  615                 }
  616 #endif
  617                 default:
  618                         epic_stop(sc);
  619                         epic_init(sc);          
  620                         break;
  621                 }
  622         }
  623 #endif
  624 
  625         case SIOCSIFFLAGS:
  626                 /*
  627                  * If the interface is marked up and stopped, then start it.
  628                  * If it is marked down and running, then stop it.
  629                  */
  630                 if (ifp->if_flags & IFF_UP) {
  631                         if ((ifp->if_flags & IFF_RUNNING) == 0) {
  632                                 epic_init(sc);
  633                                 break;
  634                         }
  635                 } else {
  636                         if (ifp->if_flags & IFF_RUNNING) {
  637                                 epic_stop(sc);
  638                                 break;
  639                         }
  640                 }
  641 
  642                 /* Handle IFF_PROMISC flag */
  643                 epic_set_rx_mode(sc);
  644 
  645 #if defined(EPIC_NOIFMEDIA)
  646                 /* Handle IFF_LINKx flags */
  647                 epic_set_media_speed(sc);
  648 #endif
  649                 break;
  650 
  651         case SIOCADDMULTI:
  652         case SIOCDELMULTI:
  653                 /* Update out multicast list */
  654 #if defined(__FreeBSD__) && __FreeBSD_version >= 300000
  655                 epic_set_mc_table(sc);
  656                 error = 0;
  657 #else
  658                 error = (command == SIOCADDMULTI) ?
  659                     ether_addmulti((struct ifreq *)data, &sc->arpcom) :
  660                     ether_delmulti((struct ifreq *)data, &sc->arpcom);
  661 
  662                 if (error == ENETRESET) {
  663                         epic_set_mc_table(sc);
  664                         error = 0;
  665                 }
  666 #endif
  667                 break;
  668 
  669 #if !defined(EPIC_NOIFMEDIA)
  670         case SIOCSIFMEDIA:
  671         case SIOCGIFMEDIA:
  672                 error = ifmedia_ioctl(ifp, (struct ifreq *)data, 
  673                     &sc->ifmedia, command);
  674                 break;
  675 #endif
  676 
  677         default:
  678                 error = EINVAL;
  679         }
  680         splx(x);
  681 
  682         return error;
  683 }
  684 
  685 /*
  686  * OS-independed part of attach process. allocate memory for descriptors
  687  * and frag lists, wake up chip, read MAC address and PHY identyfier.
  688  * Return -1 on failure.
  689  */
  690 static int
  691 epic_common_attach(
  692     epic_softc_t *sc)
  693 {
  694         int i;
  695         caddr_t pool;
  696 
  697         i = sizeof(struct epic_frag_list)*TX_RING_SIZE +
  698             sizeof(struct epic_rx_desc)*RX_RING_SIZE + 
  699             sizeof(struct epic_tx_desc)*TX_RING_SIZE + PAGE_SIZE,
  700         sc->pool = (epic_softc_t *) malloc( i, M_DEVBUF, M_NOWAIT);
  701 
  702         if (sc->pool == NULL) {
  703                 printf(": can't allocate memory for buffers\n");
  704                 return -1;
  705         }
  706         bzero(sc->pool, i);
  707 
  708         /* Align pool on PAGE_SIZE */
  709         pool = (caddr_t)sc->pool;
  710         pool = (caddr_t)((u_int32_t)(pool + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1));
  711 
  712         /* Distribute memory */
  713         sc->tx_flist = (void *)pool;
  714         pool += sizeof(struct epic_frag_list)*TX_RING_SIZE;
  715         sc->rx_desc = (void *)pool;
  716         pool += sizeof(struct epic_rx_desc)*RX_RING_SIZE;
  717         sc->tx_desc = (void *)pool;
  718 
  719         /* Bring the chip out of low-power mode. */
  720         CSR_WRITE_4( sc, GENCTL, 0x0000 );
  721 
  722         /* Magic?!  If we don't set this bit the MII interface won't work. */
  723         CSR_WRITE_4( sc, TEST1, 0x0008 );
  724 
  725         /* Read mac address from EEPROM */
  726         for (i = 0; i < ETHER_ADDR_LEN / sizeof(u_int16_t); i++)
  727                 ((u_int16_t *)sc->sc_macaddr)[i] = epic_read_eeprom(sc,i);
  728 
  729         /* Identify PHY */
  730         sc->phyid = PHY_READ_2(sc, DP83840_PHYIDR1 )<<6;
  731         sc->phyid|= (PHY_READ_2( sc, DP83840_PHYIDR2 )>>10)&0x3F;
  732         if( QS6612_OUI != sc->phyid ) 
  733                 printf(": WARNING! PHY unknown (0x%x)",sc->phyid);
  734 
  735         sc->tx_threshold = TRANSMIT_THRESHOLD;
  736         sc->txcon = TXCON_DEFAULT;
  737 
  738         return 0;
  739 }
  740 
  741 /*
  742  * This is if_start handler. It takes mbufs from if_snd queue
  743  * and quque them for transmit, one by one, until TX ring become full
  744  * or quque become empty.
  745  */
  746 static void
  747 epic_ifstart(struct ifnet * const ifp){
  748         epic_softc_t *sc = ifp->if_softc;
  749         struct epic_tx_buffer *buf;
  750         struct epic_tx_desc *desc;
  751         struct epic_frag_list *flist;
  752         struct mbuf *m0;
  753         register struct mbuf *m;
  754         register int i;
  755 
  756         /* If no link is established, simply free all mbufs in queue */
  757         PHY_READ_2( sc, DP83840_BMSR );
  758         if( !(BMSR_LINK_STATUS & PHY_READ_2( sc, DP83840_BMSR )) ){
  759                 IF_DEQUEUE( &ifp->if_snd, m0 );
  760                 while( m0 ) {
  761                         m_freem(m0);
  762                         IF_DEQUEUE( &ifp->if_snd, m0 );
  763                 }
  764                 return;
  765         }
  766 
  767         /* Link is OK, queue packets to NIC */
  768         while( sc->pending_txs < TX_RING_SIZE  ){
  769                 buf = sc->tx_buffer + sc->cur_tx;
  770                 desc = sc->tx_desc + sc->cur_tx;
  771                 flist = sc->tx_flist + sc->cur_tx;
  772 
  773                 /* Get next packet to send */
  774                 IF_DEQUEUE( &ifp->if_snd, m0 );
  775 
  776                 /* If nothing to send, return */
  777                 if( NULL == m0 ) return;
  778 
  779                 /* If descriptor is busy, set IFF_OACTIVE and exit */
  780                 if( desc->status & 0x8000 ) {
  781                         dprintf((EPIC_FORMAT ": desc is busy in ifstart, up and down interface please\n",EPIC_ARGS(sc)));
  782                         break;
  783                 }
  784 
  785                 if( buf->mbuf ) {
  786                         dprintf((EPIC_FORMAT ": mbuf not freed in ifstart, up and down interface plase\n",EPIC_ARGS(sc)));
  787                         break;
  788                 }
  789 
  790                 /* Fill fragments list */
  791                 for( m=m0, i=0;
  792                     (NULL != m) && (i < EPIC_MAX_FRAGS);
  793                     m = m->m_next, i++ ) {
  794                         flist->frag[i].fraglen = m->m_len; 
  795                         flist->frag[i].fragaddr = vtophys( mtod(m, caddr_t) );
  796                 }
  797                 flist->numfrags = i;
  798 
  799                 /* If packet was more than EPIC_MAX_FRAGS parts, */
  800                 /* recopy packet to new allocated mbuf cluster */
  801                 if( NULL != m ){
  802                         EPIC_MGETCLUSTER(m);
  803                         if( NULL == m ){
  804                                 printf(EPIC_FORMAT ": cannot allocate mbuf cluster\n",EPIC_ARGS(sc));
  805                                 m_freem(m0);
  806                                 ifp->if_oerrors++;
  807                                 continue;
  808                         }
  809 
  810                         m_copydata( m0, 0, m0->m_pkthdr.len, mtod(m,caddr_t) );
  811                         flist->frag[0].fraglen = 
  812                              m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
  813                         m->m_pkthdr.rcvif = ifp;
  814 
  815                         flist->numfrags = 1;
  816                         flist->frag[0].fragaddr = vtophys( mtod(m, caddr_t) );
  817                         m_freem(m0);
  818                         m0 = m;
  819                 }
  820 
  821                 buf->mbuf = m0;
  822                 sc->pending_txs++;
  823                 sc->cur_tx = ( sc->cur_tx + 1 ) & TX_RING_MASK;
  824                 desc->control = 0x01;
  825                 desc->txlength = 
  826                     max(m0->m_pkthdr.len,ETHER_MIN_LEN-ETHER_CRC_LEN);
  827                 desc->status = 0x8000;
  828                 CSR_WRITE_4( sc, COMMAND, COMMAND_TXQUEUED );
  829 
  830                 /* Set watchdog timer */
  831                 ifp->if_timer = 8;
  832 
  833 #if NBPFILTER > 0
  834                 if( ifp->if_bpf ) 
  835 #if defined(__FreeBSD__)
  836                         bpf_mtap( ifp, m0 );
  837 #else /* __OpenBSD__ */
  838                         bpf_mtap( ifp->if_bpf, m0 );
  839 #endif /* __FreeBSD__ */
  840 #endif
  841         }
  842 
  843         ifp->if_flags |= IFF_OACTIVE;
  844 
  845         return;
  846         
  847 }
  848 
  849 /*
  850  *
  851  * splimp() invoked before epic_intr_normal()
  852  */
  853 static __inline void
  854 epic_rx_done __P((
  855         epic_softc_t *sc ))
  856 {
  857         u_int16_t len;
  858         struct epic_rx_buffer *buf;
  859         struct epic_rx_desc *desc;
  860         struct mbuf *m;
  861         struct ether_header *eh;
  862 
  863         while( !(sc->rx_desc[sc->cur_rx].status & 0x8000) ) { 
  864                 buf = sc->rx_buffer + sc->cur_rx;
  865                 desc = sc->rx_desc + sc->cur_rx;
  866 
  867                 /* Switch to next descriptor */
  868                 sc->cur_rx = (sc->cur_rx+1) & RX_RING_MASK;
  869 
  870                 /* Check for errors, this should happend */
  871                 /* only if SAVE_ERRORED_PACKETS is set, */
  872                 /* normaly rx errors generate RXE interrupt */
  873                 if( !(desc->status & 1) ) {
  874                         dprintf((EPIC_FORMAT ": Rx error status: 0x%x\n",EPIC_ARGS(sc),desc->status));
  875                         sc->sc_if.if_ierrors++;
  876                         desc->status = 0x8000;
  877                         continue;
  878                 }
  879 
  880                 /* Save packet length and mbuf contained packet */ 
  881                 len = desc->rxlength - ETHER_CRC_LEN;
  882                 m = buf->mbuf;
  883 
  884                 /* Try to get mbuf cluster */
  885                 EPIC_MGETCLUSTER( buf->mbuf );
  886                 if( NULL == buf->mbuf ) { 
  887                         printf(EPIC_FORMAT ": cannot allocate mbuf cluster\n",EPIC_ARGS(sc));
  888                         buf->mbuf = m;
  889                         desc->status = 0x8000;
  890                         sc->sc_if.if_ierrors++;
  891                         continue;
  892                 }
  893 
  894                 /* Point to new mbuf, and give descriptor to chip */
  895                 desc->bufaddr = vtophys( mtod( buf->mbuf, caddr_t ) );
  896                 desc->status = 0x8000;
  897                 
  898                 /* First mbuf in packet holds the ethernet and packet headers */
  899                 eh = mtod( m, struct ether_header * );
  900                 m->m_pkthdr.rcvif = &(sc->sc_if);
  901                 m->m_pkthdr.len = m->m_len = len;
  902 
  903 #if NBPFILTER > 0
  904                 /* Give mbuf to BPFILTER */
  905                 if( sc->sc_if.if_bpf ) 
  906 #if defined(__FreeBSD__)
  907                         bpf_mtap( &sc->sc_if, m );
  908 #else /* __OpenBSD__ */
  909                         bpf_mtap( sc->sc_if.if_bpf, m );
  910 #endif /* __FreeBSD__ */
  911 
  912                 /* Accept only our packets, broadcasts and multicasts */
  913                 if( (eh->ether_dhost[0] & 1) == 0 &&
  914                     bcmp(eh->ether_dhost,sc->sc_macaddr,ETHER_ADDR_LEN)){
  915                         m_freem(m);
  916                         continue;
  917                 }
  918 #endif
  919 
  920                 /* Second mbuf holds packet ifself */
  921                 m->m_pkthdr.len = m->m_len = len - sizeof(struct ether_header);
  922                 m->m_data += sizeof( struct ether_header );
  923 
  924                 /* Give mbuf to OS */
  925                 ether_input(&sc->sc_if, eh, m);
  926 
  927                 /* Successfuly received frame */
  928                 sc->sc_if.if_ipackets++;
  929         }
  930 
  931         return;
  932 }
  933 
  934 /*
  935  * Synopsis: Do last phase of transmission. I.e. if desc is 
  936  * transmitted, decrease pending_txs counter, free mbuf contained
  937  * packet, switch to next descriptor and repeat until no packets
  938  * are pending or descriptro is not transmitted yet.
  939  */
  940 static __inline void
  941 epic_tx_done __P(( 
  942     register epic_softc_t *sc ))
  943 {
  944         struct epic_tx_buffer *buf;
  945         struct epic_tx_desc *desc;
  946         u_int16_t status;
  947 
  948         while( sc->pending_txs > 0 ){
  949                 buf = sc->tx_buffer + sc->dirty_tx;
  950                 desc = sc->tx_desc + sc->dirty_tx;
  951                 status = desc->status;
  952 
  953                 /* If packet is not transmitted, thou followed */
  954                 /* packets are not transmitted too */
  955                 if( status & 0x8000 ) break;
  956 
  957                 /* Packet is transmitted. Switch to next and */
  958                 /* free mbuf */
  959                 sc->pending_txs--;
  960                 sc->dirty_tx = (sc->dirty_tx + 1) & TX_RING_MASK;
  961                 m_freem( buf->mbuf );
  962                 buf->mbuf = NULL;
  963 
  964                 /* Check for errors and collisions */
  965                 if( status & 0x0001 ) sc->sc_if.if_opackets++;
  966                 else sc->sc_if.if_oerrors++;
  967                 sc->sc_if.if_collisions += (status >> 8) & 0x1F;
  968 #if defined(EPIC_DEBUG)
  969                 if( (status & 0x1001) == 0x1001 ) 
  970                         dprintf((EPIC_FORMAT ": frame not transmitted due collisions\n",EPIC_ARGS(sc)));
  971 #endif
  972         }
  973 
  974         if( sc->pending_txs < TX_RING_SIZE ) 
  975                 sc->sc_if.if_flags &= ~IFF_OACTIVE;
  976 }
  977 
  978 /*
  979  * Interrupt function
  980  *
  981  * splimp() assumed to be done 
  982  */
  983 static EPIC_INTR_RET_TYPE
  984 epic_intr (
  985     void *arg)
  986 {
  987     epic_softc_t * sc = (epic_softc_t *) arg;
  988     int status,i=4;
  989 #if defined(__OpenBSD__)
  990     int claimed = 0;
  991 #endif
  992 
  993 
  994     while( i-- && ((status = CSR_READ_4(sc, INTSTAT)) & INTSTAT_INT_ACTV) ){
  995 #if defined(__OpenBSD__)
  996         claimed = 1;
  997 #endif
  998         CSR_WRITE_4( sc, INTSTAT, status );
  999 
 1000         if( status & (INTSTAT_RQE|INTSTAT_RCC|INTSTAT_OVW) ) {
 1001             epic_rx_done( sc );
 1002             if( status & (INTSTAT_RQE|INTSTAT_OVW) ){
 1003 #if defined(EPIC_DEBUG)
 1004                 if( status & INTSTAT_OVW ) 
 1005                     printf(EPIC_FORMAT ": RX buffer overflow\n",EPIC_ARGS(sc));
 1006                 if( status & INTSTAT_RQE ) 
 1007                     printf(EPIC_FORMAT ": RX FIFO overflow\n",EPIC_ARGS(sc));
 1008                 if( sc->sc_if.if_flags & IFF_DEBUG ) 
 1009                     epic_dump_state(sc);
 1010 #endif
 1011                 if( !(CSR_READ_4( sc, COMMAND ) & COMMAND_RXQUEUED) )
 1012                     CSR_WRITE_4( sc, COMMAND, COMMAND_RXQUEUED );
 1013                 sc->sc_if.if_ierrors++;
 1014             }
 1015         }
 1016 
 1017         if( status & (INTSTAT_TXC|INTSTAT_TCC|INTSTAT_TQE) ) {
 1018             epic_tx_done( sc );
 1019             if(!(sc->sc_if.if_flags & IFF_OACTIVE) &&
 1020                 sc->sc_if.if_snd.ifq_head )
 1021                     epic_ifstart( &sc->sc_if );
 1022         }
 1023 
 1024         if( (status & INTSTAT_GP2) && (QS6612_OUI == sc->phyid) ) {
 1025             u_int32_t phystatus = PHY_READ_2( sc, QS6612_INTSTAT );
 1026 
 1027             if( phystatus & INTSTAT_AN_COMPLETE ) {
 1028                 u_int32_t bmcr;
 1029                 if( epic_autoneg(sc) == EPIC_FULL_DUPLEX ) {
 1030                     bmcr = BMCR_FULL_DUPLEX | PHY_READ_2( sc, DP83840_BMCR );
 1031                     sc->txcon |= TXCON_FULL_DUPLEX;
 1032                     CSR_WRITE_4( sc, TXCON, sc->txcon );
 1033                 } else {
 1034                     /* Default to half-duplex */
 1035                     bmcr = ~BMCR_FULL_DUPLEX & PHY_READ_2( sc, DP83840_BMCR );
 1036                     sc->txcon &= ~TXCON_FULL_DUPLEX;
 1037                     CSR_WRITE_4( sc, TXCON, sc->txcon );
 1038                 }
 1039 
 1040                 /* There is apparently QS6612 chip bug: */
 1041                 /* BMCR_FULL_DUPLEX flag is not updated by */
 1042                 /* autonegotiation process, so update it by hands */
 1043                 /* so we can rely on it in epic_ifmedia_status() */
 1044                 PHY_WRITE_2( sc, DP83840_BMCR, bmcr );
 1045             }
 1046 
 1047             PHY_READ_2(sc, DP83840_BMSR);
 1048             if( !(PHY_READ_2(sc, DP83840_BMSR) & BMSR_LINK_STATUS) ) {
 1049                 dprintf((EPIC_FORMAT ": WARNING! link down\n",EPIC_ARGS(sc)));
 1050                 sc->flags |= EPIC_LINK_DOWN;
 1051             } else {
 1052                 dprintf((EPIC_FORMAT ": link up\n",EPIC_ARGS(sc)));
 1053                 sc->flags &= ~EPIC_LINK_DOWN;
 1054             }
 1055 
 1056             /* We should clear GP2 int again after we clear it on PHY */
 1057             CSR_WRITE_4( sc, INTSTAT, INTSTAT_GP2 ); 
 1058         }
 1059 
 1060         /* Check for errors */
 1061         if( status & (INTSTAT_FATAL|INTSTAT_PMA|INTSTAT_PTA|
 1062                       INTSTAT_APE|INTSTAT_DPE|INTSTAT_TXU|INTSTAT_RXE) ){
 1063             if( status & (INTSTAT_FATAL|INTSTAT_PMA|INTSTAT_PTA|
 1064                           INTSTAT_APE|INTSTAT_DPE) ){
 1065                 printf(EPIC_FORMAT ": PCI fatal error occured (%s%s%s%s)\n",
 1066                     EPIC_ARGS(sc),
 1067                     (status&INTSTAT_PMA)?"PMA":"",
 1068                     (status&INTSTAT_PTA)?" PTA":"",
 1069                     (status&INTSTAT_APE)?" APE":"",
 1070                     (status&INTSTAT_DPE)?" DPE":""
 1071                 );
 1072 
 1073                 epic_dump_state(sc);
 1074 
 1075                 epic_stop(sc);
 1076                 epic_init(sc);
 1077                 
 1078                 break;
 1079             }
 1080 
 1081             if (status & INTSTAT_RXE) {
 1082                 dprintf((EPIC_FORMAT ": CRC/Alignment error\n",EPIC_ARGS(sc)));
 1083                 sc->sc_if.if_ierrors++;
 1084             }
 1085 
 1086             /* Tx FIFO underflow. Increase tx threshold, */
 1087             /* if it grown above 2048, disable EARLY_TX */
 1088             if (status & INTSTAT_TXU) {
 1089                 if( sc->tx_threshold > 0x800 ) {
 1090                     sc->txcon &= ~TXCON_EARLY_TRANSMIT_ENABLE;
 1091                     dprintf((EPIC_FORMAT ": TX underrun error, early tx disabled\n",EPIC_ARGS(sc)));
 1092                 } else {
 1093                     sc->tx_threshold += 0x40;
 1094                     dprintf((EPIC_FORMAT ": TX underrun error, tx threshold increased to %d\n",EPIC_ARGS(sc),sc->tx_threshold));
 1095                 }
 1096 
 1097                 epic_stop_activity(sc);
 1098                 epic_set_tx_mode(sc);
 1099                 epic_start_activity(sc);
 1100                 sc->sc_if.if_oerrors++;
 1101 
 1102                 /* Restart the transmit process. */
 1103                 /* CSR_WRITE_4(sc, COMMAND, COMMAND_TXUGO|COMMAND_TXQUEUED); */
 1104             }
 1105         }
 1106     }
 1107 
 1108     /* If no packets are pending, thus no timeouts */
 1109     if( sc->pending_txs == 0 ) sc->sc_if.if_timer = 0;
 1110 
 1111 #if defined(__OpenBSD__)
 1112     return claimed;
 1113 #endif
 1114 }
 1115 
 1116 /*
 1117  * Synopsis: This one is called if packets wasn't transmitted
 1118  * during timeout. Try to deallocate transmitted packets, and 
 1119  * if success continue to work.
 1120  *
 1121  * splimp() invoked here
 1122  */
 1123 static void
 1124 epic_ifwatchdog __P((
 1125     struct ifnet *ifp))
 1126 {
 1127         epic_softc_t *sc = ifp->if_softc;
 1128         int x;
 1129 
 1130         x = splimp();
 1131 
 1132         printf(EPIC_FORMAT ": device timeout %d packets, ",
 1133             EPIC_ARGS(sc),sc->pending_txs);
 1134 
 1135         /* Try to finish queued packets */
 1136         epic_tx_done( sc );
 1137 
 1138         /* If not successful */
 1139         if( sc->pending_txs > 0 ){
 1140 #if defined(EPIC_DEBUG)
 1141                 if( ifp->if_flags & IFF_DEBUG ) epic_dump_state(sc);
 1142 #endif
 1143                 ifp->if_oerrors+=sc->pending_txs;
 1144 
 1145                 /* Reinitialize board */
 1146                 printf("reinitialization\n");
 1147                 epic_stop(sc);
 1148                 epic_init(sc);
 1149 
 1150         } else 
 1151                 printf("seems we can continue normaly\n");
 1152 
 1153         /* Start output */
 1154         if( ifp->if_snd.ifq_head ) epic_ifstart( ifp );
 1155 
 1156         splx(x);
 1157 }
 1158 
 1159 #if defined(SIOCSIFMEDIA) && !defined(EPIC_NOIFMEDIA)
 1160 static int
 1161 epic_ifmedia_change __P((
 1162     struct ifnet * ifp))
 1163 {
 1164         epic_softc_t *sc = (epic_softc_t *)(ifp->if_softc);
 1165 
 1166         if (IFM_TYPE(sc->ifmedia.ifm_media) != IFM_ETHER)
 1167                 return (EINVAL);
 1168 
 1169         epic_set_media_speed(sc);
 1170 
 1171         return 0;
 1172 }
 1173 
 1174 static void
 1175 epic_ifmedia_status __P((
 1176     struct ifnet * ifp,
 1177     struct ifmediareq *ifmr))
 1178 {
 1179         epic_softc_t *sc = ifp->if_softc;
 1180         u_int32_t bmcr;
 1181         u_int32_t bmsr;
 1182 
 1183         bmcr = PHY_READ_2( sc, DP83840_BMCR );
 1184 
 1185         PHY_READ_2( sc, DP83840_BMSR );
 1186         bmsr = PHY_READ_2( sc, DP83840_BMSR );
 1187 
 1188         ifmr->ifm_active = IFM_ETHER;
 1189         ifmr->ifm_status = IFM_AVALID;
 1190 
 1191         if( !(bmsr & BMSR_LINK_STATUS) ) { 
 1192                 ifmr->ifm_active |= 
 1193                     (bmcr&BMCR_AUTONEGOTIATION)?IFM_AUTO:IFM_NONE;
 1194                 return;
 1195         }
 1196 
 1197         ifmr->ifm_status |= IFM_ACTIVE;
 1198         ifmr->ifm_active |= (bmcr&BMCR_100MBPS)?IFM_100_TX:IFM_10_T;
 1199         ifmr->ifm_active |= (bmcr&BMCR_FULL_DUPLEX)?IFM_FDX:0;
 1200         ifmr->ifm_active |= ((CSR_READ_4(sc,TXCON)&TXCON_LOOPBACK_MODE)==TXCON_LOOPBACK_MODE_INT)?IFM_LOOP:0;
 1201 }
 1202 #endif
 1203 
 1204 /*
 1205  * Reset chip, PHY, allocate rings
 1206  * 
 1207  * splimp() invoked here
 1208  */
 1209 static int 
 1210 epic_init __P((
 1211     epic_softc_t * sc))
 1212 {       
 1213         struct ifnet *ifp = &sc->sc_if;
 1214         int s;
 1215  
 1216         s = splimp();
 1217 
 1218         /* Soft reset the chip */
 1219         CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET );
 1220 
 1221         /* Reset takes 15 pci ticks which depends on processor speed */
 1222         DELAY(1);
 1223 
 1224         /* Wake up */
 1225         CSR_WRITE_4( sc, GENCTL, 0 );
 1226 
 1227         /* ?????? */
 1228         CSR_WRITE_4( sc, TEST1, 0x0008);
 1229 
 1230         /* Initialize rings */
 1231         if( epic_init_rings( sc ) ) {
 1232                 printf(EPIC_FORMAT ": failed to init rings\n",EPIC_ARGS(sc));
 1233                 splx(s);
 1234                 return -1;
 1235         }       
 1236 
 1237         /* Give rings to EPIC */
 1238         CSR_WRITE_4( sc, PRCDAR, vtophys( sc->rx_desc ) );
 1239         CSR_WRITE_4( sc, PTCDAR, vtophys( sc->tx_desc ) );
 1240 
 1241         /* Put node address to EPIC */
 1242         CSR_WRITE_4( sc, LAN0, ((u_int16_t *)sc->sc_macaddr)[0] );
 1243         CSR_WRITE_4( sc, LAN1, ((u_int16_t *)sc->sc_macaddr)[1] );
 1244         CSR_WRITE_4( sc, LAN2, ((u_int16_t *)sc->sc_macaddr)[2] );
 1245 
 1246         /* Set tx mode, includeing transmit threshold */
 1247         epic_set_tx_mode(sc);
 1248 
 1249         /* Compute and set RXCON. */
 1250         epic_set_rx_mode( sc );
 1251 
 1252         /* Set media speed mode */
 1253         epic_init_phy( sc );
 1254         epic_set_media_speed( sc );
 1255 
 1256         /* Set multicast table */
 1257         epic_set_mc_table( sc );
 1258 
 1259         /* Enable interrupts by setting the interrupt mask. */
 1260         CSR_WRITE_4( sc, INTMASK,
 1261                 INTSTAT_RCC | INTSTAT_RQE | INTSTAT_OVW | INTSTAT_RXE |
 1262                 INTSTAT_TXC | INTSTAT_TCC | INTSTAT_TQE | INTSTAT_TXU |
 1263                 INTSTAT_FATAL |
 1264                 ((QS6612_OUI == sc->phyid)?INTSTAT_GP2:0) );
 1265 
 1266         /* Enable interrupts,  set for PCI read multiple and etc */
 1267         CSR_WRITE_4( sc, GENCTL,
 1268                 GENCTL_ENABLE_INTERRUPT | GENCTL_MEMORY_READ_MULTIPLE |
 1269                 GENCTL_ONECOPY | GENCTL_RECEIVE_FIFO_THRESHOLD64 );
 1270 
 1271         /* Mark interface running ... */
 1272         if( ifp->if_flags & IFF_UP ) ifp->if_flags |= IFF_RUNNING;
 1273         else ifp->if_flags &= ~IFF_RUNNING;
 1274 
 1275         /* ... and free */
 1276         ifp->if_flags &= ~IFF_OACTIVE;
 1277 
 1278         /* Start Rx process */
 1279         epic_start_activity(sc);
 1280 
 1281         splx(s);
 1282         return 0;
 1283 }
 1284 
 1285 /*
 1286  * Synopsis: calculate and set Rx mode
 1287  */
 1288 static void
 1289 epic_set_rx_mode(
 1290     epic_softc_t * sc)
 1291 {
 1292         u_int32_t flags = sc->sc_if.if_flags;
 1293         u_int32_t rxcon = RXCON_DEFAULT | RXCON_RECEIVE_MULTICAST_FRAMES | RXCON_RECEIVE_BROADCAST_FRAMES;
 1294 
 1295         rxcon |= (flags & IFF_PROMISC)?RXCON_PROMISCUOUS_MODE:0;
 1296 
 1297         CSR_WRITE_4( sc, RXCON, rxcon );
 1298 
 1299         return;
 1300 }
 1301 
 1302 /*
 1303  * Synopsis: Reset PHY and do PHY-special initialization:
 1304  */
 1305 static void
 1306 epic_init_phy __P((
 1307     epic_softc_t * sc))
 1308 {
 1309         u_int32_t i;
 1310 
 1311         /* Reset PHY */
 1312         PHY_WRITE_2( sc, DP83840_BMCR, BMCR_RESET );
 1313         for(i=0;i<0x100000;i++)
 1314                 if( !(PHY_READ_2( sc, DP83840_BMCR ) & BMCR_RESET) ) break;
 1315 
 1316         if( PHY_READ_2( sc, DP83840_BMCR ) & BMCR_RESET )
 1317                 printf(EPIC_FORMAT ": WARNING! cannot reset PHY\n",EPIC_ARGS(sc));
 1318 
 1319         switch( sc->phyid ){
 1320         case QS6612_OUI:
 1321                 /* Init QS6612 and EPIC to generate interrupt when AN complete*/
 1322                 CSR_WRITE_4( sc, NVCTL, NVCTL_GP1_OUTPUT_ENABLE );
 1323                 PHY_READ_2( sc, QS6612_INTSTAT );
 1324                 PHY_WRITE_2( sc, QS6612_INTMASK, INTMASK_THUNDERLAN | INTSTAT_AN_COMPLETE | INTSTAT_LINK_STATUS );
 1325 
 1326                 /* Enable QS6612 extended cable length capabilites */
 1327                 PHY_WRITE_2( sc, QS6612_MCTL, PHY_READ_2( sc,QS6612_MCTL ) | MCTL_BTEXT );
 1328                 break;
 1329         default:
 1330                 break;
 1331         }
 1332 }
 1333 
 1334 /*
 1335  * Synopsis: Set PHY to media type specified by IFF_LINK* flags or
 1336  * ifmedia structure.
 1337  */
 1338 static void
 1339 epic_set_media_speed __P((
 1340     epic_softc_t * sc))
 1341 {
 1342         u_int16_t media;
 1343 
 1344 #if !defined(EPIC_NOIFMEDIA)
 1345         u_int32_t tgtmedia = sc->ifmedia.ifm_cur->ifm_media;
 1346 
 1347         if( IFM_SUBTYPE(tgtmedia) != IFM_AUTO ){
 1348                 /* Set mode */
 1349                 media = (IFM_SUBTYPE(tgtmedia)==IFM_100_TX) ? BMCR_100MBPS : 0;
 1350                 media|= (tgtmedia&IFM_FDX) ? BMCR_FULL_DUPLEX : 0;
 1351 
 1352                 sc->sc_if.if_baudrate = 
 1353                         (IFM_SUBTYPE(tgtmedia)==IFM_100_TX)?100000000:10000000;
 1354 
 1355                 PHY_WRITE_2( sc, DP83840_BMCR, media );
 1356 
 1357                 if( tgtmedia & IFM_FDX ) sc->txcon |= TXCON_FULL_DUPLEX;
 1358                 else sc->txcon &= ~TXCON_FULL_DUPLEX;
 1359                 if( tgtmedia & IFM_LOOP ) sc->txcon |= TXCON_LOOPBACK_MODE_INT;
 1360                 else sc->txcon &= ~TXCON_LOOPBACK_MODE_INT;
 1361                 
 1362                 CSR_WRITE_4( sc, TXCON, sc->txcon );
 1363         }
 1364 #else /* EPIC_NOIFMEDIA */
 1365         struct ifnet *ifp = &sc->sc_if;
 1366 
 1367         if( ifp->if_flags & IFF_LINK0 ) {
 1368                 /* Set mode */
 1369                 media = (ifp->if_flags & IFF_LINK2) ? BMCR_100MBPS : 0;
 1370                 media|= (ifp->if_flags & IFF_LINK1) ? BMCR_FULL_DUPLEX : 0;
 1371 
 1372                 sc->sc_if.if_baudrate = 
 1373                         (ifp->if_flags & IFF_LINK2)?100000000:10000000;
 1374 
 1375                 PHY_WRITE_2( sc, DP83840_BMCR, media );
 1376 
 1377                 if( ifp->if_flags & IFF_LINK2 ) sc->txcon |= TXCON_FULL_DUPLEX;
 1378                 else sc->txcon &= ~TXCON_FULL_DUPLEX; 
 1379  
 1380                 CSR_WRITE_4( sc, TXCON, sc->txcon );
 1381         }
 1382 #endif /* !EPIC_NOIFMEDIA */
 1383           else {
 1384                 sc->sc_if.if_baudrate = 100000000;
 1385 
 1386                 sc->txcon &= ~TXCON_FULL_DUPLEX; 
 1387                 CSR_WRITE_4(sc, TXCON, sc->txcon);
 1388 
 1389                 /* Set and restart autoneg */
 1390                 PHY_WRITE_2( sc, DP83840_BMCR,
 1391                         BMCR_AUTONEGOTIATION | BMCR_RESTART_AUTONEG );
 1392 
 1393                 /* If it is not QS6612 PHY, try to get result of autoneg. */
 1394                 if( QS6612_OUI != sc->phyid ) {
 1395                         /* Wait 3 seconds for the autoneg to finish
 1396                          * This is the recommended time from the DP83840A data
 1397                          * sheet Section 7.1
 1398                          */
 1399                         DELAY(3000000);
 1400                         
 1401                         if( epic_autoneg(sc) == EPIC_FULL_DUPLEX ) {
 1402                                 sc->txcon |= TXCON_FULL_DUPLEX;
 1403                                 CSR_WRITE_4(sc, TXCON, sc->txcon);
 1404                         }
 1405                 }
 1406                 /* Else it will be done when GP2 int occured */
 1407         }
 1408 
 1409         return;
 1410 }
 1411 
 1412 /*
 1413  * This functions get results of the autoneg processes of the phy
 1414  * It implements the workaround that is described in section 7.2 & 7.3 of the 
 1415  * DP83840A data sheet
 1416  * http://www.national.com/ds/DP/DP83840A.pdf
 1417  */
 1418 static int 
 1419 epic_autoneg(
 1420     epic_softc_t * sc)
 1421 {
 1422         u_int16_t media;
 1423         u_int16_t i;
 1424 
 1425         /* BMSR must be read twice to update the link status bit
 1426          * since that bit is a latch bit
 1427          */
 1428         PHY_READ_2( sc, DP83840_BMSR);
 1429         i = PHY_READ_2( sc, DP83840_BMSR);
 1430         
 1431         if ((i & BMSR_LINK_STATUS) && (i & BMSR_AUTONEG_COMPLETE)){
 1432                 i = PHY_READ_2( sc, DP83840_LPAR );
 1433 
 1434                 if ( i & (ANAR_100_TX_FD|ANAR_10_FD) )
 1435                         return  EPIC_FULL_DUPLEX;
 1436                 else
 1437                         return EPIC_HALF_DUPLEX;
 1438         } else {   
 1439                 /*Auto-negotiation or link status is not 1
 1440                   Thus the auto-negotiation failed and one
 1441                   must take other means to fix it.
 1442                  */
 1443 
 1444                 /* ANER must be read twice to get the correct reading for the 
 1445                  * Multiple link fault bit -- it is a latched bit
 1446                  */
 1447                 PHY_READ_2( sc, DP83840_ANER );
 1448                 i = PHY_READ_2( sc, DP83840_ANER );
 1449         
 1450                 if ( i & ANER_MULTIPLE_LINK_FAULT ) {
 1451                         /* it can be forced to 100Mb/s Half-Duplex */
 1452                         media = PHY_READ_2( sc, DP83840_BMCR );
 1453                         media &= ~(BMCR_AUTONEGOTIATION | BMCR_FULL_DUPLEX);
 1454                         media |= BMCR_100MBPS;
 1455                         PHY_WRITE_2( sc, DP83840_BMCR, media );
 1456                 
 1457                         /* read BMSR again to determine link status */
 1458                         PHY_READ_2( sc, DP83840_BMSR );
 1459                         i=PHY_READ_2( sc, DP83840_BMSR );
 1460                 
 1461                         if (i & BMSR_LINK_STATUS){
 1462                                 /* port is linked to the non Auto-Negotiation
 1463                                  * 100Mbs partner.
 1464                                  */
 1465                                 return EPIC_HALF_DUPLEX;
 1466                         }
 1467                         else {
 1468                                 media = PHY_READ_2( sc, DP83840_BMCR);
 1469                                 media &= ~(BMCR_AUTONEGOTIATION | BMCR_FULL_DUPLEX | BMCR_100MBPS);
 1470                                 PHY_WRITE_2( sc, DP83840_BMCR, media);
 1471                                 PHY_READ_2( sc, DP83840_BMSR );
 1472                                 i = PHY_READ_2( sc, DP83840_BMSR );
 1473 
 1474                                 if (i & BMSR_LINK_STATUS) {
 1475                                         /*port is linked to the non
 1476                                          * Auto-Negotiation10Mbs partner
 1477                                          */
 1478                                         return EPIC_HALF_DUPLEX;
 1479                                 }
 1480                         }
 1481                 }
 1482                 /* If we get here we are most likely not connected
 1483                  * so lets default it to half duplex
 1484                  */
 1485                 return EPIC_HALF_DUPLEX;
 1486         }
 1487         
 1488 }
 1489 
 1490 /*
 1491  */
 1492 static void
 1493 epic_set_tx_mode (
 1494     epic_softc_t *sc )
 1495 {
 1496 
 1497     if( sc->txcon & TXCON_EARLY_TRANSMIT_ENABLE )
 1498         CSR_WRITE_4( sc, ETXTHR, sc->tx_threshold );
 1499 
 1500     CSR_WRITE_4( sc, TXCON, sc->txcon );
 1501 }
 1502 
 1503 /*
 1504  * Synopsis: This function should update multicast hash table.
 1505  * I suppose there is a bug in chips MC filter so this function
 1506  * only set it to receive all MC packets. The second problem is
 1507  * that we should wait for TX and RX processes to stop before
 1508  * reprogramming MC filter. The epic_stop_activity() and 
 1509  * epic_start_activity() should help to do this.
 1510  */
 1511 static void
 1512 epic_set_mc_table (
 1513     epic_softc_t * sc)
 1514 {
 1515         struct ifnet *ifp = &sc->sc_if;
 1516 
 1517         if( ifp->if_flags & IFF_MULTICAST ){
 1518                 CSR_WRITE_4( sc, MC0, 0xFFFF );
 1519                 CSR_WRITE_4( sc, MC1, 0xFFFF );
 1520                 CSR_WRITE_4( sc, MC2, 0xFFFF );
 1521                 CSR_WRITE_4( sc, MC3, 0xFFFF );
 1522         }
 1523 
 1524         return;
 1525 }
 1526 
 1527 
 1528 /* 
 1529  * Synopsis: Start receive process and transmit, if need
 1530  */
 1531 static void
 1532 epic_start_activity __P((
 1533     epic_softc_t * sc))
 1534 {
 1535         /* Start rx process */
 1536         CSR_WRITE_4( sc, COMMAND, COMMAND_RXQUEUED | COMMAND_START_RX | (sc->pending_txs?COMMAND_TXQUEUED:0));
 1537 }
 1538 
 1539 /*
 1540  * Synopsis: Completely stop Rx and Tx processes. If TQE is set additional
 1541  * packet needs to be queued to stop Tx DMA.
 1542  */
 1543 static void
 1544 epic_stop_activity __P((
 1545     epic_softc_t * sc))
 1546 {
 1547     int i;
 1548 
 1549     /* Turn it to loopback mode */      
 1550     CSR_WRITE_4( sc, TXCON, TXCON_SLOT_TIME|TXCON_LOOPBACK_MODE_INT );
 1551 
 1552     /* Stop Tx and Rx DMA */
 1553     CSR_WRITE_4(sc,COMMAND,COMMAND_STOP_RX|COMMAND_STOP_RDMA|COMMAND_STOP_TDMA);
 1554 
 1555     /* Wait only Rx DMA */
 1556     dprintf((EPIC_FORMAT ": waiting Rx DMA to stop\n",EPIC_ARGS(sc)));
 1557     for(i=0;i<0x1000;i++) {
 1558         if( (CSR_READ_4(sc,INTSTAT) & INTSTAT_RXIDLE) == INTSTAT_RXIDLE )
 1559             break;
 1560         DELAY(1);
 1561     }
 1562 
 1563     if( !(CSR_READ_4(sc,INTSTAT)&INTSTAT_RXIDLE) ) 
 1564         printf(EPIC_FORMAT ": can't stop RX DMA\n",EPIC_ARGS(sc));
 1565 
 1566     /* May need to queue one more packet if TQE */
 1567     if( (CSR_READ_4( sc, INTSTAT ) & INTSTAT_TQE) &&
 1568        !(CSR_READ_4( sc, INTSTAT ) & INTSTAT_TXIDLE) ){
 1569         dprintf((EPIC_FORMAT ": queue last packet\n",EPIC_ARGS(sc)));
 1570 
 1571         sc->tx_desc[sc->cur_tx].bufaddr = vtophys( sc );
 1572         sc->tx_desc[sc->cur_tx].buflength = ETHER_MIN_LEN-ETHER_CRC_LEN;
 1573         sc->tx_desc[sc->cur_tx].control = 0x14;
 1574         sc->tx_desc[sc->cur_tx].txlength = ETHER_MIN_LEN-ETHER_CRC_LEN;
 1575         sc->tx_desc[sc->cur_tx].status = 0x8000;
 1576         sc->cur_tx = (sc->cur_tx + 1) & TX_RING_MASK;
 1577         sc->pending_txs++;
 1578 
 1579         CSR_WRITE_4( sc, COMMAND, COMMAND_TXQUEUED );
 1580 
 1581         dprintf((EPIC_FORMAT ": waiting Tx DMA to stop\n",EPIC_ARGS(sc)));
 1582         /* Wait TX DMA to stop */
 1583         for(i=0;i<0x1000;i++) {
 1584             if( (CSR_READ_4(sc,INTSTAT)&INTSTAT_TXIDLE) == INTSTAT_TXIDLE ) {
 1585                 sc->pending_txs--;
 1586                 break;
 1587             }
 1588             DELAY(1);
 1589         }
 1590 
 1591         if( !(CSR_READ_4(sc,INTSTAT)&INTSTAT_TXIDLE) )
 1592             printf(EPIC_FORMAT ": can't stop TX DMA\n",EPIC_ARGS(sc));
 1593 
 1594         /* Restore old TX state */
 1595         CSR_WRITE_4( sc, TXCON, sc->txcon );
 1596     }
 1597 }
 1598 
 1599 /*
 1600  *  Synopsis: Shut down board and deallocates rings.
 1601  *
 1602  *  splimp() invoked here
 1603  */
 1604 static void
 1605 epic_stop __P((
 1606     epic_softc_t * sc))
 1607 {
 1608         int s;
 1609 
 1610         s = splimp();
 1611 
 1612         sc->sc_if.if_timer = 0;
 1613 
 1614         /* Disable interrupts */
 1615         CSR_WRITE_4( sc, INTMASK, 0 );
 1616         CSR_WRITE_4( sc, GENCTL, 0 );
 1617 
 1618         /* Try to stop Rx and TX processes */
 1619         epic_stop_activity(sc);
 1620 
 1621         /* Reset chip */
 1622         CSR_WRITE_4( sc, GENCTL, GENCTL_SOFT_RESET );
 1623         DELAY(10);
 1624 
 1625         /* Free memory allocated for rings */
 1626         epic_free_rings(sc);
 1627 
 1628         /* Mark as stoped */
 1629         sc->sc_if.if_flags &= ~IFF_RUNNING;
 1630 
 1631         splx(s);
 1632         return;
 1633 }
 1634 
 1635 /*
 1636  * Synopsis: This function should free all memory allocated for rings.
 1637  */ 
 1638 static void
 1639 epic_free_rings __P((
 1640     epic_softc_t * sc))
 1641 {
 1642         int i;
 1643 
 1644         for(i=0;i<RX_RING_SIZE;i++){
 1645                 struct epic_rx_buffer *buf = sc->rx_buffer + i;
 1646                 struct epic_rx_desc *desc = sc->rx_desc + i;
 1647                 
 1648                 desc->status = 0;
 1649                 desc->buflength = 0;
 1650                 desc->bufaddr = 0;
 1651 
 1652                 if( buf->mbuf ) m_freem( buf->mbuf );
 1653                 buf->mbuf = NULL;
 1654         }
 1655 
 1656         for(i=0;i<TX_RING_SIZE;i++){
 1657                 struct epic_tx_buffer *buf = sc->tx_buffer + i;
 1658                 struct epic_tx_desc *desc = sc->tx_desc + i;
 1659 
 1660                 desc->status = 0;
 1661                 desc->buflength = 0;
 1662                 desc->bufaddr = 0;
 1663 
 1664                 if( buf->mbuf ) m_freem( buf->mbuf );
 1665                 buf->mbuf = NULL;
 1666         }
 1667 }
 1668 
 1669 /*
 1670  * Synopsis:  Allocates mbufs for Rx ring and point Rx descs to them.
 1671  * Point Tx descs to fragment lists. Check that all descs and fraglists
 1672  * are bounded and aligned properly.
 1673  */
 1674 static int
 1675 epic_init_rings(epic_softc_t * sc){
 1676         int i;
 1677 
 1678         sc->cur_rx = sc->cur_tx = sc->dirty_tx = sc->pending_txs = 0;
 1679 
 1680         for (i = 0; i < RX_RING_SIZE; i++) {
 1681                 struct epic_rx_buffer *buf = sc->rx_buffer + i;
 1682                 struct epic_rx_desc *desc = sc->rx_desc + i;
 1683 
 1684                 desc->status = 0;               /* Owned by driver */
 1685                 desc->next = vtophys( sc->rx_desc + ((i+1) & RX_RING_MASK) );
 1686 
 1687                 if( (desc->next & 3) || ((desc->next & 0xFFF) + sizeof(struct epic_rx_desc) > 0x1000 ) )
 1688                         printf(EPIC_FORMAT ": WARNING! rx_desc is misbound or misaligned\n",EPIC_ARGS(sc));
 1689 
 1690                 EPIC_MGETCLUSTER( buf->mbuf );
 1691                 if( NULL == buf->mbuf ) {
 1692                         epic_free_rings(sc);
 1693                         return -1;
 1694                 }
 1695                 desc->bufaddr = vtophys( mtod(buf->mbuf,caddr_t) );
 1696 
 1697                 desc->buflength = ETHER_MAX_FRAME_LEN;
 1698                 desc->status = 0x8000;                  /* Give to EPIC */
 1699 
 1700         }
 1701 
 1702         for (i = 0; i < TX_RING_SIZE; i++) {
 1703                 struct epic_tx_buffer *buf = sc->tx_buffer + i;
 1704                 struct epic_tx_desc *desc = sc->tx_desc + i;
 1705 
 1706                 desc->status = 0;
 1707                 desc->next = vtophys( sc->tx_desc + ( (i+1) & TX_RING_MASK ) );
 1708 
 1709                 if( (desc->next & 3) || ((desc->next & 0xFFF) + sizeof(struct epic_tx_desc) > 0x1000 ) )
 1710                         printf(EPIC_FORMAT ": WARNING! tx_desc is misbound or misaligned\n",EPIC_ARGS(sc));
 1711 
 1712                 buf->mbuf = NULL;
 1713                 desc->bufaddr = vtophys( sc->tx_flist + i );
 1714                 if( (desc->bufaddr & 3) || ((desc->bufaddr & 0xFFF) + sizeof(struct epic_frag_list) > 0x1000 ) )
 1715                         printf(EPIC_FORMAT ": WARNING! frag_list is misbound or misaligned\n",EPIC_ARGS(sc));
 1716         }
 1717 
 1718         return 0;
 1719 }
 1720 
 1721 /*
 1722  * EEPROM operation functions
 1723  */
 1724 static void epic_write_eepromreg __P((
 1725     epic_softc_t *sc,
 1726     u_int8_t val))
 1727 {
 1728         u_int16_t i;
 1729 
 1730         CSR_WRITE_1( sc, EECTL, val );
 1731 
 1732         for( i=0;i<0xFF; i++)
 1733                 if( !(CSR_READ_1( sc, EECTL ) & 0x20) ) break;
 1734 
 1735         return;
 1736 }
 1737 
 1738 static u_int8_t
 1739 epic_read_eepromreg __P((
 1740     epic_softc_t *sc))
 1741 {
 1742         return CSR_READ_1( sc,EECTL );
 1743 }  
 1744 
 1745 static u_int8_t
 1746 epic_eeprom_clock __P((
 1747     epic_softc_t *sc,
 1748     u_int8_t val))
 1749 {
 1750         epic_write_eepromreg( sc, val );
 1751         epic_write_eepromreg( sc, (val | 0x4) );
 1752         epic_write_eepromreg( sc, val );
 1753         
 1754         return epic_read_eepromreg( sc );
 1755 }
 1756 
 1757 static void
 1758 epic_output_eepromw __P((
 1759     epic_softc_t * sc,
 1760     u_int16_t val))
 1761 {
 1762         int i;          
 1763         for( i = 0xF; i >= 0; i--){
 1764                 if( (val & (1 << i)) ) epic_eeprom_clock( sc, 0x0B );
 1765                 else epic_eeprom_clock( sc, 3);
 1766         }
 1767 }
 1768 
 1769 static u_int16_t
 1770 epic_input_eepromw __P((
 1771     epic_softc_t *sc))
 1772 {
 1773         int i;
 1774         int tmp;
 1775         u_int16_t retval = 0;
 1776 
 1777         for( i = 0xF; i >= 0; i--) {    
 1778                 tmp = epic_eeprom_clock( sc, 0x3 );
 1779                 if( tmp & 0x10 ){
 1780                         retval |= (1 << i);
 1781                 }
 1782         }
 1783         return retval;
 1784 }
 1785 
 1786 static int
 1787 epic_read_eeprom __P((
 1788     epic_softc_t *sc,
 1789     u_int16_t loc))
 1790 {
 1791         u_int16_t dataval;
 1792         u_int16_t read_cmd;
 1793 
 1794         epic_write_eepromreg( sc , 3);
 1795 
 1796         if( epic_read_eepromreg( sc ) & 0x40 )
 1797                 read_cmd = ( loc & 0x3F ) | 0x180;
 1798         else
 1799                 read_cmd = ( loc & 0xFF ) | 0x600;
 1800 
 1801         epic_output_eepromw( sc, read_cmd );
 1802 
 1803         dataval = epic_input_eepromw( sc );
 1804 
 1805         epic_write_eepromreg( sc, 1 );
 1806         
 1807         return dataval;
 1808 }
 1809 
 1810 static u_int16_t
 1811 epic_read_phy_register __P((
 1812     epic_softc_t *sc,
 1813     u_int16_t loc))
 1814 {
 1815         int i;
 1816 
 1817         CSR_WRITE_4( sc, MIICTL, ((loc << 4) | 0x0601) );
 1818 
 1819         for( i=0;i<0x100000;i++) if( !(CSR_READ_4( sc, MIICTL )&1) ) break;
 1820 
 1821         return CSR_READ_4( sc, MIIDATA );
 1822 }
 1823 
 1824 static void
 1825 epic_write_phy_register __P((
 1826     epic_softc_t * sc,
 1827     u_int16_t loc,
 1828     u_int16_t val))
 1829 {
 1830         int i;
 1831 
 1832         CSR_WRITE_4( sc, MIIDATA, val );
 1833         CSR_WRITE_4( sc, MIICTL, ((loc << 4) | 0x0602) );
 1834 
 1835         for( i=0;i<0x100000;i++) if( !(CSR_READ_4( sc, MIICTL )&2) ) break;
 1836 
 1837         return;
 1838 }
 1839 
 1840 static void
 1841 epic_dump_state __P((
 1842     epic_softc_t * sc))
 1843 {
 1844         int j;
 1845         struct epic_tx_desc *tdesc;
 1846         struct epic_rx_desc *rdesc;
 1847         printf(EPIC_FORMAT ": cur_rx: %d, pending_txs: %d, dirty_tx: %d, cur_tx: %d\n", EPIC_ARGS(sc),sc->cur_rx,sc->pending_txs,sc->dirty_tx,sc->cur_tx);
 1848         printf(EPIC_FORMAT ": COMMAND: 0x%08x, INTSTAT: 0x%08x\n",EPIC_ARGS(sc),CSR_READ_4(sc,COMMAND),CSR_READ_4(sc,INTSTAT));
 1849         printf(EPIC_FORMAT ": PRCDAR: 0x%08x, PTCDAR: 0x%08x\n",EPIC_ARGS(sc),CSR_READ_4(sc,PRCDAR),CSR_READ_4(sc,PTCDAR));
 1850         printf(EPIC_FORMAT ": dumping rx descriptors\n",EPIC_ARGS(sc));
 1851         for(j=0;j<RX_RING_SIZE;j++){
 1852                 rdesc = sc->rx_desc + j;
 1853                 printf("desc%d: %4d 0x%04x, 0x%08x, %4d, 0x%08x\n",
 1854                         j,
 1855                         rdesc->rxlength,rdesc->status,
 1856                         rdesc->bufaddr,
 1857                         rdesc->buflength,
 1858                         rdesc->next
 1859                 );
 1860         }
 1861         printf(EPIC_FORMAT ": dumping tx descriptors\n",EPIC_ARGS(sc));
 1862         for(j=0;j<TX_RING_SIZE;j++){
 1863                 tdesc = sc->tx_desc + j;
 1864                 printf(
 1865                 "desc%d: %4d 0x%04x, 0x%08lx, 0x%04x %4u, 0x%08lx, mbuf: %p\n",
 1866                         j,
 1867                         tdesc->txlength,tdesc->status,
 1868                         (u_long)tdesc->bufaddr,
 1869                         tdesc->control,tdesc->buflength,
 1870                         (u_long)tdesc->next,
 1871                         (void *)sc->tx_buffer[j].mbuf
 1872                 );
 1873         }
 1874 }
 1875 #endif /* NPCI > 0 */

Cache object: ab52f2151be263b58654b555daa4a1df


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