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-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

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

Cache object: a1dd935ea9202fb4174b05651d1be823


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