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/i386/isa/if_ar.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 /*
    2  * Copyright (c) 1995 John Hay.  All rights reserved.
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  * 1. Redistributions of source code must retain the above copyright
    8  *    notice, this list of conditions and the following disclaimer.
    9  * 2. Redistributions in binary form must reproduce the above copyright
   10  *    notice, this list of conditions and the following disclaimer in the
   11  *    documentation and/or other materials provided with the distribution.
   12  * 3. All advertising materials mentioning features or use of this software
   13  *    must display the following acknowledgement:
   14  *      This product includes software developed by John Hay.
   15  * 4. Neither the name of the author nor the names of any co-contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY John Hay ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL John Hay BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  * $FreeBSD$
   32  */
   33 
   34 /*
   35  * Programming assumptions and other issues.
   36  *
   37  * The descriptors of a DMA channel will fit in a 16K memory window.
   38  *
   39  * The buffers of a transmit DMA channel will fit in a 16K memory window.
   40  *
   41  * Only the ISA bus cards with X.21 and V.35 is tested.
   42  *
   43  * When interface is going up, handshaking is set and it is only cleared
   44  * when the interface is down'ed.
   45  *
   46  * There should be a way to set/reset Raw HDLC/PPP, Loopback, DCE/DTE,
   47  * internal/external clock, etc.....
   48  *
   49  */
   50 
   51 #include "opt_netgraph.h"
   52 #include "ar.h"
   53 #include "bpfilter.h"
   54 
   55 #include <sys/param.h>
   56 #include <sys/systm.h>
   57 #include <sys/malloc.h>
   58 #include <sys/mbuf.h>
   59 #include <sys/sockio.h>
   60 #include <sys/socket.h>
   61 
   62 #include <net/if.h>
   63 #ifdef NETGRAPH
   64 #include <netgraph/ng_message.h>
   65 #include <netgraph/netgraph.h>
   66 #include <sys/kernel.h>
   67 #include <sys/syslog.h>
   68 #include <i386/isa/if_ar.h>
   69 #else /* NETGRAPH */
   70 #include <net/if_sppp.h>
   71 
   72 #if NBPFILTER > 0
   73 #include <net/bpf.h>
   74 #endif /* NBPFILTER > 0 */
   75 #endif /* NETGRAPH */
   76 
   77 #include <machine/clock.h>
   78 #include <machine/md_var.h>
   79 
   80 #include <i386/isa/if_arregs.h>
   81 #include <i386/isa/ic/hd64570.h>
   82 #include <i386/isa/isa_device.h>
   83 
   84 #ifndef NETGRAPH
   85 #include "sppp.h"
   86 #if NSPPP <= 0
   87 #error device 'ar' require sppp.
   88 #endif /* NSPPP <= 0 */
   89 #endif /* NETGRAPH */
   90 
   91 #ifdef TRACE
   92 #define TRC(x)               x
   93 #else
   94 #define TRC(x)
   95 #endif
   96 
   97 #define TRCL(x)              x
   98 
   99 #define PPP_HEADER_LEN       4
  100 
  101 #define ARC_GET_WIN(addr)       ((addr >> ARC_WIN_SHFT) & AR_WIN_MSK)
  102 
  103 #define ARC_SET_MEM(iobase,win) outb(iobase+AR_MSCA_EN, AR_ENA_MEM | \
  104                                 ARC_GET_WIN(win))
  105 #define ARC_SET_SCA(iobase,ch)  outb(iobase+AR_MSCA_EN, AR_ENA_MEM | \
  106                                 AR_ENA_SCA | (ch ? AR_SEL_SCA_1:AR_SEL_SCA_0))
  107 #define ARC_SET_OFF(iobase)     outb(iobase+AR_MSCA_EN, 0)
  108 
  109 static struct ar_hardc {
  110         int cunit;
  111         struct ar_softc *sc;
  112         u_short iobase;
  113         int startunit;
  114         int numports;
  115         caddr_t mem_start;
  116         caddr_t mem_end;
  117 
  118         u_int memsize;          /* in bytes */
  119         u_char bustype;         /* ISA, MCA, PCI.... */
  120         u_char interface;       /* X21, V.35, EIA-530.... */
  121         u_char revision;
  122         u_char handshake;       /* handshake lines supported by card. */
  123 
  124         u_char txc_dtr[NPORT/NCHAN]; /* the register is write only */
  125         u_int txc_dtr_off[NPORT/NCHAN];
  126 
  127         sca_regs *sca;
  128 
  129 }ar_hardc[NAR];
  130 
  131 struct ar_softc {
  132 #ifndef NETGRAPH
  133         struct sppp ifsppp;
  134 #endif /* NETGRAPH */
  135         int unit;            /* With regards to all ar devices */
  136         int subunit;         /* With regards to this card */
  137         struct ar_hardc *hc;
  138 
  139         struct buf_block {
  140                 u_int txdesc;        /* On card address */
  141                 u_int txstart;       /* On card address */
  142                 u_int txend;         /* On card address */
  143                 u_int txtail;        /* Index of first unused buffer */
  144                 u_int txmax;         /* number of usable buffers/descriptors */
  145                 u_int txeda;         /* Error descriptor addresses */
  146         }block[AR_TX_BLOCKS];
  147 
  148         char  xmit_busy;     /* Transmitter is busy */
  149         char  txb_inuse;     /* Number of tx blocks currently in use */
  150         char  txb_new;       /* Index to where new buffer will be added */
  151         char  txb_next_tx;    /* Index to next block ready to tx */
  152 
  153         u_int rxdesc;        /* On card address */
  154         u_int rxstart;       /* On card address */
  155         u_int rxend;         /* On card address */
  156         u_int rxhind;        /* Index to the head of the rx buffers. */
  157         u_int rxmax;         /* number of usable buffers/descriptors */
  158 
  159         int scano;
  160         int scachan;
  161 #ifdef NETGRAPH
  162         int     running;        /* something is attached so we are running */
  163         int     dcd;            /* do we have dcd? */
  164         /* ---netgraph bits --- */
  165         char            nodename[NG_NODELEN + 1]; /* store our node name */
  166         int             datahooks;      /* number of data hooks attached */
  167         node_p          node;           /* netgraph node */
  168         hook_p          hook;           /* data hook */
  169         hook_p          debug_hook;
  170         struct ifqueue  xmitq_hipri;    /* hi-priority transmit queue */
  171         struct ifqueue  xmitq;          /* transmit queue */
  172         int             flags;          /* state */
  173 #define SCF_RUNNING     0x01            /* board is active */
  174 #define SCF_OACTIVE     0x02            /* output is active */
  175         int             out_dog;        /* watchdog cycles output count-down */
  176         struct callout_handle handle;   /* timeout(9) handle */
  177         u_long          inbytes, outbytes;      /* stats */
  178         u_long          lastinbytes, lastoutbytes; /* a second ago */
  179         u_long          inrate, outrate;        /* highest rate seen */
  180         u_long          inlast;         /* last input N secs ago */
  181         u_long          out_deficit;    /* output since last input */
  182         u_long          oerrors, ierrors[6];
  183         u_long          opackets, ipackets;
  184 #endif /* NETGRAPH */
  185 };
  186 
  187 #ifdef NETGRAPH
  188 #define DOG_HOLDOFF     6       /* dog holds off for 6 secs */
  189 #define QUITE_A_WHILE   300     /* 5 MINUTES */
  190 #define LOTS_OF_PACKETS 100
  191 #endif /* NETGRAPH */
  192 
  193 static int arprobe(struct isa_device *id);
  194 static int arattach(struct isa_device *id);
  195 
  196 /*
  197  * This translate from irq numbers to
  198  * the value that the arnet card needs
  199  * in the lower part of the AR_INT_SEL
  200  * register.
  201  */
  202 static int irqtable[16] = {
  203         0,      /*  0 */
  204         0,      /*  1 */
  205         0,      /*  2 */
  206         1,      /*  3 */
  207         0,      /*  4 */
  208         2,      /*  5 */
  209         0,      /*  6 */
  210         3,      /*  7 */
  211         0,      /*  8 */
  212         0,      /*  9 */
  213         4,      /* 10 */
  214         5,      /* 11 */
  215         6,      /* 12 */
  216         0,      /* 13 */
  217         0,      /* 14 */
  218         7       /* 15 */
  219 };
  220 
  221 struct isa_driver ardriver = {arprobe, arattach, "arc"};
  222 
  223 static ointhand2_t arintr;
  224 static void ar_xmit(struct ar_softc *sc);
  225 #ifndef NETGRAPH
  226 static void arstart(struct ifnet *ifp);
  227 static int arioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
  228 static void arwatchdog(struct ifnet *ifp);
  229 #else   /* NETGRAPH */
  230 static void arstart(struct ar_softc *sc);
  231 static void arwatchdog(struct ar_softc *sc);
  232 #endif  /* NETGRAPH */
  233 static int ar_packet_avail(struct ar_softc *sc, int *len, u_char *rxstat);
  234 static void ar_copy_rxbuf(struct mbuf *m, struct ar_softc *sc, int len);
  235 static void ar_eat_packet(struct ar_softc *sc, int single);
  236 static void ar_get_packets(struct ar_softc *sc);
  237 
  238 static void ar_up(struct ar_softc *sc);
  239 static void ar_down(struct ar_softc *sc);
  240 static void arc_init(struct isa_device *id);
  241 static void ar_init_sca(struct ar_hardc *hc, int scano);
  242 static void ar_init_msci(struct ar_softc *sc);
  243 static void ar_init_rx_dmac(struct ar_softc *sc);
  244 static void ar_init_tx_dmac(struct ar_softc *sc);
  245 static void ar_dmac_intr(struct ar_hardc *hc, int scano, u_char isr);
  246 static void ar_msci_intr(struct ar_hardc *hc, int scano, u_char isr);
  247 static void ar_timer_intr(struct ar_hardc *hc, int scano, u_char isr);
  248 
  249 #ifdef  NETGRAPH
  250 static  void    ngar_watchdog_frame(void * arg);
  251 static  void    ngar_init(void* ignored);
  252 
  253 static ng_constructor_t ngar_constructor;
  254 static ng_rcvmsg_t      ngar_rcvmsg;
  255 static ng_shutdown_t    ngar_rmnode;
  256 static ng_newhook_t     ngar_newhook;
  257 /*static ng_findhook_t  ngar_findhook; */
  258 static ng_connect_t     ngar_connect;
  259 static ng_rcvdata_t     ngar_rcvdata;
  260 static ng_disconnect_t  ngar_disconnect;
  261         
  262 static struct ng_type typestruct = {
  263         NG_VERSION,
  264         NG_AR_NODE_TYPE,
  265         NULL,
  266         ngar_constructor,
  267         ngar_rcvmsg,
  268         ngar_rmnode,
  269         ngar_newhook,
  270         NULL,
  271         ngar_connect,
  272         ngar_rcvdata,
  273         ngar_rcvdata,
  274         ngar_disconnect,
  275         NULL
  276 };
  277 
  278 static int      ngar_done_init = 0;
  279 #endif /* NETGRAPH */
  280 
  281 /*
  282  * Register the Adapter.
  283  * Probe to see if it is there.
  284  * Get its information and fill it in.
  285  */
  286 static int
  287 arprobe(struct isa_device *id)
  288 {
  289         struct ar_hardc *hc = &ar_hardc[id->id_unit];
  290         u_int tmp;
  291         u_short port;
  292 
  293         /*
  294          * Register the card.
  295          */
  296 
  297         /*
  298          * Now see if the card is realy there.
  299          *
  300          * XXX For now I just check the undocumented ports
  301          * for "570". We will probably have to do more checking.
  302          */
  303         port = id->id_iobase;
  304 
  305         if((inb(port+AR_ID_5) != '5') || (inb(port+AR_ID_7) != '7') ||
  306            (inb(port+AR_ID_0) != ''))
  307                 return 0;
  308         /*
  309          * We have a card here, fill in what we can.
  310          */
  311         tmp = inb(port + AR_BMI);
  312         hc->bustype = tmp & AR_BUS_MSK;
  313         hc->memsize = (tmp & AR_MEM_MSK) >> AR_MEM_SHFT;
  314         hc->memsize = 1 << hc->memsize;
  315         hc->memsize <<= 16;
  316         hc->interface = (tmp & AR_IFACE_MSK);
  317         hc->revision = inb(port + AR_REV);
  318         hc->numports = inb(port + AR_PNUM);
  319         hc->handshake = inb(port + AR_HNDSH);
  320 
  321         id->id_msize = ARC_WIN_SIZ;
  322 
  323         hc->iobase = id->id_iobase;
  324         hc->mem_start = id->id_maddr;
  325         hc->mem_end = id->id_maddr + id->id_msize;
  326         hc->cunit = id->id_unit;
  327 
  328         switch(hc->interface) {
  329         case AR_IFACE_EIA_232:
  330                 printf("ar%d: The EIA 232 interface is not supported.\n",
  331                         id->id_unit);
  332                 return 0;
  333         case AR_IFACE_V_35:
  334                 break;
  335         case AR_IFACE_EIA_530:
  336                 printf("ar%d: WARNING: The EIA 530 interface is untested.\n",
  337                         id->id_unit);
  338                 break;
  339         case AR_IFACE_X_21:
  340                 break;
  341         case AR_IFACE_COMBO:
  342                 printf("ar%d: WARNING: The COMBO interface is untested.\n",
  343                         id->id_unit);
  344                 break;
  345         }
  346 
  347         if(id->id_unit == 0)
  348                 hc->startunit = 0;
  349         else
  350                 hc->startunit = ar_hardc[id->id_unit - 1].startunit +
  351                                 ar_hardc[id->id_unit - 1].numports;
  352 
  353         /*
  354          * Do a little sanity check.
  355          */
  356         if((hc->numports > NPORT) || (hc->memsize > (512*1024)))
  357                 return 0;
  358 
  359         return ARC_IO_SIZ;      /* return the amount of IO addresses used. */
  360 }
  361 
  362 
  363 /*
  364  * Malloc memory for the softc structures.
  365  * Reset the card to put it in a known state.
  366  * Register the ports on the adapter.
  367  * Fill in the info for each port.
  368  * Attach each port to sppp and bpf.
  369  */
  370 static int
  371 arattach(struct isa_device *id)
  372 {
  373         struct ar_hardc *hc = &ar_hardc[id->id_unit];
  374         struct ar_softc *sc;
  375         int unit;
  376 #ifndef NETGRAPH
  377         struct ifnet *ifp;
  378 #endif  /* NETGRAPH */
  379         char *iface;
  380 
  381         id->id_ointr = arintr;
  382         switch(hc->interface) {
  383         default: iface = "UNKNOWN"; break;
  384         case AR_IFACE_EIA_232: iface = "EIA-232"; break;
  385         case AR_IFACE_V_35: iface = "EIA-232 or V.35"; break;
  386         case AR_IFACE_EIA_530: iface = "EIA-530"; break;
  387         case AR_IFACE_X_21: iface = "X.21"; break;
  388         case AR_IFACE_COMBO: iface = "COMBO X.21 / EIA-530"; break;
  389         }
  390 
  391         printf("arc%d: %uK RAM, %u ports, rev %u, "
  392                 "%s interface.\n",
  393                 id->id_unit,
  394                 hc->memsize/1024,
  395                 hc->numports,
  396                 hc->revision,
  397                 iface);
  398         
  399         arc_init(id);
  400 
  401         sc = hc->sc;
  402 
  403         for(unit=0;unit<hc->numports;unit+=NCHAN)
  404                 ar_init_sca(hc, unit / NCHAN);
  405 
  406         /*
  407          * Now configure each port on the card.
  408          */
  409         for(unit=0;unit<hc->numports;sc++,unit++) {
  410                 sc->hc = hc;
  411                 sc->subunit = unit;
  412                 sc->unit = hc->startunit + unit;
  413                 sc->scano = unit / NCHAN;
  414                 sc->scachan = unit%NCHAN;
  415 
  416                 ar_init_rx_dmac(sc);
  417                 ar_init_tx_dmac(sc);
  418                 ar_init_msci(sc);
  419 
  420 #ifndef NETGRAPH
  421                 ifp = &sc->ifsppp.pp_if;
  422 
  423                 ifp->if_softc = sc;
  424                 ifp->if_unit = hc->startunit + unit;
  425                 ifp->if_name = "ar";
  426                 ifp->if_mtu = PP_MTU;
  427                 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
  428                 ifp->if_ioctl = arioctl;
  429                 ifp->if_start = arstart;
  430                 ifp->if_watchdog = arwatchdog;
  431 
  432                 sc->ifsppp.pp_flags = PP_KEEPALIVE;
  433 
  434                 printf("ar%d: Adapter %d, port %d.\n",
  435                         sc->unit,
  436                         hc->cunit,
  437                         sc->subunit);
  438 
  439                 sppp_attach((struct ifnet *)&sc->ifsppp);
  440                 if_attach(ifp);
  441 
  442 #if NBPFILTER > 0
  443                 bpfattach(ifp, DLT_PPP, PPP_HEADER_LEN);
  444 #endif  /* NBPFILTER > 0 */
  445 #else   /* NETGRAPH */
  446                 /*
  447                  * we have found a node, make sure our 'type' is availabe.
  448                  */
  449                 if (ngar_done_init == 0) ngar_init(NULL);
  450                 if (ng_make_node_common(&typestruct, &sc->node) != 0)
  451                         return (0);
  452                 sc->node->private = sc;
  453                 callout_handle_init(&sc->handle);
  454                 sc->xmitq.ifq_maxlen = IFQ_MAXLEN;
  455                 sc->xmitq_hipri.ifq_maxlen = IFQ_MAXLEN;
  456                 sprintf(sc->nodename, "%s%d", NG_AR_NODE_TYPE, sc->unit);
  457                 if (ng_name_node(sc->node, sc->nodename)) {
  458                         ng_rmnode(sc->node);
  459                         ng_unref(sc->node);
  460                         return (0);
  461                 }
  462                 sc->running = 0;
  463 #endif  /* NETGRAPH */
  464         }
  465 
  466         ARC_SET_OFF(hc->iobase);
  467 
  468         return 1;
  469 }
  470 
  471 /*
  472  * First figure out which SCA gave the interrupt.
  473  * Process it.
  474  * See if there is other interrupts pending.
  475  * Repeat until there is no more interrupts.
  476  */
  477 static void
  478 arintr(int unit)
  479 {
  480         struct ar_hardc *hc = &ar_hardc[unit];
  481         sca_regs *sca = hc->sca;
  482         u_char isr0, isr1, isr2, arisr;
  483         int scano;
  484 
  485         arisr = inb(hc->iobase + AR_ISTAT);
  486 
  487         while(arisr & AR_BD_INT) {
  488                 if(arisr & AR_INT_0)
  489                         scano = 0;
  490                 else if(arisr & AR_INT_1)
  491                         scano = 1;
  492                 else {
  493                         /* XXX Oops this shouldn't happen. */
  494                         printf("arc%d: Interrupted with no interrupt.\n", unit);
  495                         return;
  496                 }
  497 
  498                 ARC_SET_SCA(hc->iobase, scano);
  499 
  500                 isr0 = sca->isr0;
  501                 isr1 = sca->isr1;
  502                 isr2 = sca->isr2;
  503 
  504                 TRC(printf("arc%d: ARINTR isr0 %x, isr1 %x, isr2 %x\n",
  505                         unit,
  506                         isr0,
  507                         isr1,
  508                         isr2));
  509                 if(isr0)
  510                         ar_msci_intr(hc, scano, isr0);
  511 
  512                 if(isr1)
  513                         ar_dmac_intr(hc, scano, isr1);
  514 
  515                 if(isr2)
  516                         ar_timer_intr(hc, scano, isr2);
  517 
  518                 /*
  519                  * Proccess the second sca's interrupt if available.
  520                  * Else see if there are any new interrupts.
  521                  */
  522                 if((arisr & AR_INT_0) && (arisr & AR_INT_1))
  523                         arisr &= ~AR_INT_0;
  524                 else
  525                         arisr = inb(hc->iobase + AR_ISTAT);
  526         }
  527 
  528         ARC_SET_OFF(hc->iobase);
  529 }
  530 
  531 
  532 /*
  533  * This will only start the transmitter. It is assumed that the data
  534  * is already there. It is normally called from arstart() or ar_dmac_intr().
  535  *
  536  */
  537 static void
  538 ar_xmit(struct ar_softc *sc)
  539 {
  540 #ifndef NETGRAPH
  541         struct ifnet *ifp = &sc->ifsppp.pp_if;
  542 #endif /* NETGRAPH */
  543         dmac_channel *dmac = &sc->hc->sca->dmac[DMAC_TXCH(sc->scachan)];
  544 
  545         ARC_SET_SCA(sc->hc->iobase, sc->scano);
  546         dmac->cda = (u_short)(sc->block[sc->txb_next_tx].txdesc & 0xffff);
  547 
  548         dmac->eda = (u_short)(sc->block[sc->txb_next_tx].txeda & 0xffff);
  549         dmac->dsr = SCA_DSR_DE;
  550 
  551         sc->xmit_busy = 1;
  552 
  553         sc->txb_next_tx++;
  554         if(sc->txb_next_tx == AR_TX_BLOCKS)
  555                 sc->txb_next_tx = 0;
  556 
  557 #ifndef NETGRAPH
  558         ifp->if_timer = 2; /* Value in seconds. */
  559 #else   /* NETGRAPH */
  560         sc->out_dog = DOG_HOLDOFF;      /* give ourself some breathing space*/
  561 #endif  /* NETGRAPH */
  562         ARC_SET_OFF(sc->hc->iobase);
  563 }
  564 
  565 /*
  566  * This function will be called from the upper level when a user add a
  567  * packet to be send, and from the interrupt handler after a finished
  568  * transmit.
  569  *
  570  * NOTE: it should run at spl_imp().
  571  *
  572  * This function only place the data in the oncard buffers. It does not
  573  * start the transmition. ar_xmit() does that.
  574  *
  575  * Transmitter idle state is indicated by the IFF_OACTIVE flag. The function
  576  * that clears that should ensure that the transmitter and its DMA is
  577  * in a "good" idle state.
  578  */
  579 #ifndef NETGRAPH
  580 static void
  581 arstart(struct ifnet *ifp)
  582 {
  583         struct ar_softc *sc = ifp->if_softc;
  584 #else   /* NETGRAPH */
  585 static void
  586 arstart(struct ar_softc *sc)
  587 {
  588 #endif  /* NETGRAPH */
  589         int i, len, tlen;
  590         struct mbuf *mtx;
  591         u_char *txdata;
  592         sca_descriptor *txdesc;
  593         struct buf_block *blkp;
  594 
  595 #ifndef NETGRAPH
  596         if(!(ifp->if_flags & IFF_RUNNING))
  597                 return;
  598 #else   /* NETGRAPH */
  599 /* XXX */
  600 #endif  /* NETGRAPH */
  601   
  602 top_arstart:
  603 
  604         /*
  605          * See if we have space for more packets.
  606          */
  607         if(sc->txb_inuse == AR_TX_BLOCKS) {
  608 #ifndef NETGRAPH
  609                 ifp->if_flags |= IFF_OACTIVE;   /* yes, mark active */
  610 #else   /* NETGRAPH */
  611 /*XXX*/         /*ifp->if_flags |= IFF_OACTIVE;*/       /* yes, mark active */
  612 #endif /* NETGRAPH */
  613                 return;
  614         }
  615 
  616 #ifndef NETGRAPH
  617         mtx = sppp_dequeue(ifp);
  618 #else   /* NETGRAPH */
  619         IF_DEQUEUE(&sc->xmitq_hipri, mtx);
  620         if (mtx == NULL) {
  621                 IF_DEQUEUE(&sc->xmitq, mtx);
  622         }
  623 #endif /* NETGRAPH */
  624         if(!mtx)
  625                 return;
  626 
  627         /*
  628          * It is OK to set the memory window outside the loop because
  629          * all tx buffers and descriptors are assumed to be in the same
  630          * 16K window.
  631          */
  632         ARC_SET_MEM(sc->hc->iobase, sc->block[0].txdesc);
  633 
  634         /*
  635          * We stay in this loop until there is nothing in the
  636          * TX queue left or the tx buffer is full.
  637          */
  638         i = 0;
  639         blkp = &sc->block[sc->txb_new];
  640         txdesc = (sca_descriptor *)
  641                 (sc->hc->mem_start + (blkp->txdesc & ARC_WIN_MSK));
  642         txdata = (u_char *)(sc->hc->mem_start + (blkp->txstart & ARC_WIN_MSK));
  643         for(;;) {
  644                 len = mtx->m_pkthdr.len;
  645 
  646                 TRC(printf("ar%d: ARstart len %u\n", sc->unit, len));
  647 
  648                 /*
  649                  * We can do this because the tx buffers don't wrap.
  650                  */
  651                 m_copydata(mtx, 0, len, txdata);
  652                 tlen = len;
  653                 while(tlen > AR_BUF_SIZ) {
  654                         txdesc->stat = 0;
  655                         txdesc->len = AR_BUF_SIZ;
  656                         tlen -= AR_BUF_SIZ;
  657                         txdesc++;
  658                         txdata += AR_BUF_SIZ;
  659                         i++;
  660                 }
  661                 /* XXX Move into the loop? */
  662                 txdesc->stat = SCA_DESC_EOM;
  663                 txdesc->len = tlen;
  664                 txdesc++;
  665                 txdata += AR_BUF_SIZ;
  666                 i++;
  667 
  668 #ifndef NETGRAPH
  669 #if     NBPFILTER > 0
  670                 if(ifp->if_bpf)
  671                         bpf_mtap(ifp, mtx);
  672 #endif  /* NBPFILTER > 0 */
  673                 m_freem(mtx);
  674                 ++sc->ifsppp.pp_if.if_opackets;
  675 #else   /* NETGRAPH */
  676                 m_freem(mtx);
  677                 sc->outbytes += len;
  678                 ++sc->opackets;
  679 #endif  /* NETGRAPH */
  680 
  681                 /*
  682                  * Check if we have space for another mbuf.
  683                  * XXX This is hardcoded. A packet won't be larger
  684                  * than 3 buffers (3 x 512).
  685                  */
  686                 if((i + 3) >= blkp->txmax)
  687                         break;
  688 
  689 #ifndef NETGRAPH
  690                 mtx = sppp_dequeue(ifp);
  691 #else   /* NETGRAPH */
  692                 IF_DEQUEUE(&sc->xmitq_hipri, mtx);
  693                 if (mtx == NULL) {
  694                         IF_DEQUEUE(&sc->xmitq, mtx);
  695                 }
  696 #endif /* NETGRAPH */
  697                 if(!mtx)
  698                         break;
  699         }
  700 
  701         blkp->txtail = i;
  702 
  703         /*
  704          * Mark the last descriptor, so that the SCA know where
  705          * to stop.
  706          */
  707         txdesc--;
  708         txdesc->stat |= SCA_DESC_EOT;
  709 
  710         txdesc = (sca_descriptor *)blkp->txdesc;
  711         blkp->txeda = (u_short)((u_int)&txdesc[i]);
  712 
  713 #if 0
  714         printf("ARstart: %p desc->cp %x\n", &txdesc->cp, txdesc->cp);
  715         printf("ARstart: %p desc->bp %x\n", &txdesc->bp, txdesc->bp);
  716         printf("ARstart: %p desc->bpb %x\n", &txdesc->bpb, txdesc->bpb);
  717         printf("ARstart: %p desc->len %x\n", &txdesc->len, txdesc->len);
  718         printf("ARstart: %p desc->stat %x\n", &txdesc->stat, txdesc->stat);
  719 #endif
  720 
  721         sc->txb_inuse++;
  722         sc->txb_new++;
  723         if(sc->txb_new == AR_TX_BLOCKS)
  724                 sc->txb_new = 0;
  725 
  726         if(sc->xmit_busy == 0)
  727                 ar_xmit(sc);
  728 
  729         ARC_SET_OFF(sc->hc->iobase);
  730 
  731         goto top_arstart;
  732 }
  733 
  734 #ifndef NETGRAPH
  735 static int
  736 arioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
  737 {
  738         int s, error;
  739         int was_up, should_be_up;
  740         struct sppp *sp = (struct sppp *)ifp;
  741         struct ar_softc *sc = ifp->if_softc;
  742 
  743         TRC(printf("ar%d: arioctl.\n", ifp->if_unit);)
  744 
  745         if(cmd == SIOCSIFFLAGS) {
  746                 if(ifp->if_flags & IFF_LINK2)
  747                         sp->pp_flags |= PP_CISCO;
  748                 else
  749                         sp->pp_flags &= ~PP_CISCO;
  750         }
  751 
  752         was_up = ifp->if_flags & IFF_RUNNING;
  753 
  754         error = sppp_ioctl(ifp, cmd, data);
  755         TRC(printf("ar%d: ioctl: ifsppp.pp_flags = %x, if_flags %x.\n", 
  756                 ifp->if_unit, ((struct sppp *)ifp)->pp_flags, ifp->if_flags);)
  757         if(error)
  758                 return error;
  759 
  760         if((cmd != SIOCSIFFLAGS) && cmd != (SIOCSIFADDR))
  761                 return 0;
  762 
  763         TRC(printf("ar%d: arioctl %s.\n", ifp->if_unit, 
  764                 (cmd == SIOCSIFFLAGS) ? "SIOCSIFFLAGS" : "SIOCSIFADDR");)
  765 
  766         s = splimp();
  767         should_be_up = ifp->if_flags & IFF_RUNNING;
  768 
  769         if(!was_up && should_be_up) {
  770                 /* Interface should be up -- start it. */
  771                 ar_up(sc);
  772                 arstart(ifp);
  773                 /* XXX Maybe clear the IFF_UP flag so that the link
  774                  * will only go up after sppp lcp and ipcp negotiation.
  775                  */
  776         } else if(was_up && !should_be_up) {
  777                 /* Interface should be down -- stop it. */
  778                 ar_down(sc);
  779                 sppp_flush(ifp);
  780         }
  781         splx(s);
  782         return 0;
  783 }
  784 #endif  /* NETGRAPH */
  785 
  786 /*
  787  * This is to catch lost tx interrupts.
  788  */
  789 static void
  790 #ifndef NETGRAPH
  791 arwatchdog(struct ifnet *ifp)
  792 {
  793         struct ar_softc *sc = ifp->if_softc;
  794 #else   /* NETGRAPH */
  795 arwatchdog(struct ar_softc *sc)
  796 {
  797 #endif  /* NETGRAPH */
  798         msci_channel *msci = &sc->hc->sca->msci[sc->scachan];
  799 
  800 #ifndef NETGRAPH
  801         if(!(ifp->if_flags & IFF_RUNNING))
  802                 return;
  803 #endif  /* NETGRAPH */
  804 
  805         ARC_SET_SCA(sc->hc->iobase, sc->scano);
  806 
  807         /* XXX if(sc->ifsppp.pp_if.if_flags & IFF_DEBUG) */
  808                 printf("ar%d: transmit failed, "
  809                         "ST0 %x, ST1 %x, ST3 %x, DSR %x.\n",
  810                         sc->unit,
  811                         msci->st0,
  812                         msci->st1,
  813                         msci->st3,
  814                         sc->hc->sca->dmac[DMAC_TXCH(sc->scachan)].dsr);
  815 
  816         if(msci->st1 & SCA_ST1_UDRN) {
  817                 msci->cmd = SCA_CMD_TXABORT;
  818                 msci->cmd = SCA_CMD_TXENABLE;
  819                 msci->st1 = SCA_ST1_UDRN;
  820         }
  821 
  822         sc->xmit_busy = 0;
  823 #ifndef NETGRAPH
  824         ifp->if_flags &= ~IFF_OACTIVE;
  825 #else   /* NETGRAPH */
  826         /* XXX ifp->if_flags &= ~IFF_OACTIVE; */
  827 #endif  /* NETGRAPH */
  828 
  829         if(sc->txb_inuse && --sc->txb_inuse)
  830                 ar_xmit(sc);
  831 
  832 #ifndef NETGRAPH
  833         arstart(ifp);
  834 #else   /* NETGRAPH */
  835         arstart(sc);
  836 #endif  /* NETGRAPH */
  837 }
  838 
  839 static void
  840 ar_up(struct ar_softc *sc)
  841 {
  842         sca_regs *sca = sc->hc->sca;
  843         msci_channel *msci = &sca->msci[sc->scachan];
  844 
  845         TRC(printf("ar%d: sca %p, msci %p, ch %d\n",
  846                 sc->unit, sca, msci, sc->scachan));
  847 
  848         /*
  849          * Enable transmitter and receiver.
  850          * Raise DTR and RTS.
  851          * Enable interrupts.
  852          */
  853         ARC_SET_SCA(sc->hc->iobase, sc->scano);
  854 
  855         /* XXX
  856          * What about using AUTO mode in msci->md0 ???
  857          * And what about CTS/DCD etc... ?
  858          */
  859         if(sc->hc->handshake & AR_SHSK_RTS)
  860                 msci->ctl &= ~SCA_CTL_RTS;
  861         if(sc->hc->handshake & AR_SHSK_DTR) {
  862                 sc->hc->txc_dtr[sc->scano] &= sc->scachan ? 
  863                         ~AR_TXC_DTR_DTR1 : ~AR_TXC_DTR_DTR0;
  864                 outb(sc->hc->iobase + sc->hc->txc_dtr_off[sc->scano],
  865                         sc->hc->txc_dtr[sc->scano]);
  866         }
  867 
  868         if(sc->scachan == 0) {
  869                 sca->ier0 |= 0x0F;
  870                 sca->ier1 |= 0x0F;
  871         } else {
  872                 sca->ier0 |= 0xF0;
  873                 sca->ier1 |= 0xF0;
  874         }
  875 
  876         msci->cmd = SCA_CMD_RXENABLE;
  877         inb(sc->hc->iobase + AR_ID_5); /* XXX slow it down a bit. */
  878         msci->cmd = SCA_CMD_TXENABLE;
  879 
  880         ARC_SET_OFF(sc->hc->iobase);
  881 #ifdef  NETGRAPH
  882         untimeout(ngar_watchdog_frame, sc, sc->handle);
  883         sc->handle = timeout(ngar_watchdog_frame, sc, hz);
  884         sc->running = 1;
  885 #endif  /* NETGRAPH */
  886 }
  887 
  888 static void
  889 ar_down(struct ar_softc *sc)
  890 {
  891         sca_regs *sca = sc->hc->sca;
  892         msci_channel *msci = &sca->msci[sc->scachan];
  893 
  894 #ifdef  NETGRAPH
  895         untimeout(ngar_watchdog_frame, sc, sc->handle);
  896         sc->running = 0;
  897 #endif  /* NETGRAPH */
  898         /*
  899          * Disable transmitter and receiver.
  900          * Lower DTR and RTS.
  901          * Disable interrupts.
  902          */
  903         ARC_SET_SCA(sc->hc->iobase, sc->scano);
  904         msci->cmd = SCA_CMD_RXDISABLE;
  905         inb(sc->hc->iobase + AR_ID_5); /* XXX slow it down a bit. */
  906         msci->cmd = SCA_CMD_TXDISABLE;
  907 
  908         if(sc->hc->handshake & AR_SHSK_RTS)
  909                 msci->ctl |= SCA_CTL_RTS;
  910         if(sc->hc->handshake & AR_SHSK_DTR) {
  911                 sc->hc->txc_dtr[sc->scano] |= sc->scachan ? 
  912                         AR_TXC_DTR_DTR1 : AR_TXC_DTR_DTR0;
  913                 outb(sc->hc->iobase + sc->hc->txc_dtr_off[sc->scano],
  914                         sc->hc->txc_dtr[sc->scano]);
  915         }
  916 
  917         if(sc->scachan == 0) {
  918                 sca->ier0 &= ~0x0F;
  919                 sca->ier1 &= ~0x0F;
  920         } else {
  921                 sca->ier0 &= ~0xF0;
  922                 sca->ier1 &= ~0xF0;
  923         }
  924 
  925         ARC_SET_OFF(sc->hc->iobase);
  926 }
  927 
  928 /*
  929  * Initialize the card, allocate memory for the ar_softc structures
  930  * and fill in the pointers.
  931  */
  932 static void
  933 arc_init(struct isa_device *id)
  934 {
  935         struct ar_hardc *hc = &ar_hardc[id->id_unit];
  936         struct ar_softc *sc;
  937         int x;
  938         u_int chanmem;
  939         u_int bufmem;
  940         u_int next;
  941         u_int descneeded;
  942         u_char isr, mar;
  943 
  944         MALLOC(sc, struct ar_softc *,
  945                 hc->numports * sizeof(struct ar_softc), M_DEVBUF, M_WAITOK);
  946         if (sc == NULL)
  947                 return;
  948         bzero(sc, hc->numports * sizeof(struct ar_softc));
  949         hc->sc = sc;
  950 
  951         hc->txc_dtr[0] = AR_TXC_DTR_NOTRESET |
  952                          AR_TXC_DTR_DTR0 | AR_TXC_DTR_DTR1;
  953         hc->txc_dtr[1] = AR_TXC_DTR_DTR0 | AR_TXC_DTR_DTR1;
  954         hc->txc_dtr_off[0] = AR_TXC_DTR0;
  955         hc->txc_dtr_off[1] = AR_TXC_DTR2;
  956 
  957         /*
  958          * reset the card and wait at least 1uS.
  959          */
  960         outb(hc->iobase + AR_TXC_DTR0, ~AR_TXC_DTR_NOTRESET & hc->txc_dtr[0]);
  961         DELAY(2);
  962         outb(hc->iobase + AR_TXC_DTR0, hc->txc_dtr[0]);
  963 
  964         /*
  965          * Configure the card.
  966          * Mem address, irq, 
  967          */
  968         mar = kvtop(id->id_maddr) >> 16;
  969         isr = irqtable[ffs(id->id_irq) - 1] << 1;
  970         if(isr == 0)
  971                 printf("ar%d: Warning illegal interrupt %d\n",
  972                         id->id_unit, ffs(id->id_irq) - 1);
  973         isr = isr | ((kvtop(id->id_maddr) & 0xc000) >> 10);
  974 
  975         hc->sca = (sca_regs *)hc->mem_start;
  976 
  977         outb(hc->iobase + AR_MEM_SEL, mar);
  978         outb(hc->iobase + AR_INT_SEL, isr | AR_INTS_CEN);
  979 
  980         /*
  981          * Set the TX clock direction and enable TX.
  982          */
  983         switch(hc->interface) {
  984         case AR_IFACE_V_35:
  985                 hc->txc_dtr[0] |= AR_TXC_DTR_TX0 | AR_TXC_DTR_TX1 |
  986                                   AR_TXC_DTR_TXCS0 | AR_TXC_DTR_TXCS1;
  987                 hc->txc_dtr[1] |= AR_TXC_DTR_TX0 | AR_TXC_DTR_TX1 |
  988                                   AR_TXC_DTR_TXCS0 | AR_TXC_DTR_TXCS1;
  989                 break;
  990         case AR_IFACE_EIA_530:
  991         case AR_IFACE_COMBO:
  992         case AR_IFACE_X_21:
  993                 hc->txc_dtr[0] |= AR_TXC_DTR_TX0 | AR_TXC_DTR_TX1;
  994                 hc->txc_dtr[1] |= AR_TXC_DTR_TX0 | AR_TXC_DTR_TX1;
  995         }
  996         outb(hc->iobase + AR_TXC_DTR0, hc->txc_dtr[0]);
  997         if(hc->numports > NCHAN)
  998                 outb(hc->iobase + AR_TXC_DTR2, hc->txc_dtr[1]);
  999 
 1000         chanmem = hc->memsize / hc->numports;
 1001         next = 0;
 1002 
 1003         for(x=0;x<hc->numports;x++, sc++) {
 1004                 int blk;
 1005 
 1006                 for(blk = 0; blk < AR_TX_BLOCKS; blk++) {
 1007                         sc->block[blk].txdesc = next;
 1008                         bufmem = (16 * 1024) / AR_TX_BLOCKS;
 1009                         descneeded = bufmem / AR_BUF_SIZ;
 1010                         sc->block[blk].txstart = sc->block[blk].txdesc +
 1011                                 ((((descneeded * sizeof(sca_descriptor)) /
 1012                                         AR_BUF_SIZ) + 1) * AR_BUF_SIZ);
 1013                         sc->block[blk].txend = next + bufmem;
 1014                         sc->block[blk].txmax =
 1015                                 (sc->block[blk].txend - sc->block[blk].txstart)
 1016                                 / AR_BUF_SIZ;
 1017                         next += bufmem;
 1018 
 1019                         TRC(printf("ar%d: blk %d: txdesc %x, txstart %x, "
 1020                                    "txend %x, txmax %d\n",
 1021                                    x,
 1022                                    blk,
 1023                                    sc->block[blk].txdesc,
 1024                                    sc->block[blk].txstart,
 1025                                    sc->block[blk].txend,
 1026                                    sc->block[blk].txmax));
 1027                 }
 1028 
 1029                 sc->rxdesc = next;
 1030                 bufmem = chanmem - (bufmem * AR_TX_BLOCKS);
 1031                 descneeded = bufmem / AR_BUF_SIZ;
 1032                 sc->rxstart = sc->rxdesc +
 1033                                 ((((descneeded * sizeof(sca_descriptor)) /
 1034                                         AR_BUF_SIZ) + 1) * AR_BUF_SIZ);
 1035                 sc->rxend = next + bufmem;
 1036                 sc->rxmax = (sc->rxend - sc->rxstart) / AR_BUF_SIZ;
 1037                 next += bufmem;
 1038         }
 1039 }
 1040 
 1041 
 1042 /*
 1043  * The things done here are channel independent.
 1044  *
 1045  *   Configure the sca waitstates.
 1046  *   Configure the global interrupt registers.
 1047  *   Enable master dma enable.
 1048  */
 1049 static void
 1050 ar_init_sca(struct ar_hardc *hc, int scano)
 1051 {
 1052         sca_regs *sca = hc->sca;
 1053 
 1054         ARC_SET_SCA(hc->iobase, scano);
 1055 
 1056         /*
 1057          * Do the wait registers.
 1058          * Set everything to 0 wait states.
 1059          */
 1060         sca->pabr0 = 0;
 1061         sca->pabr1 = 0;
 1062         sca->wcrl  = 0;
 1063         sca->wcrm  = 0;
 1064         sca->wcrh  = 0;
 1065 
 1066         /*
 1067          * Configure the interrupt registers.
 1068          * Most are cleared until the interface is configured.
 1069          */
 1070         sca->ier0 = 0x00; /* MSCI interrupts... Not used with dma. */
 1071         sca->ier1 = 0x00; /* DMAC interrupts */
 1072         sca->ier2 = 0x00; /* TIMER interrupts... Not used yet. */
 1073         sca->itcr = 0x00; /* Use ivr and no intr ack */
 1074         sca->ivr  = 0x40; /* Fill in the interrupt vector. */
 1075         sca->imvr = 0x40;
 1076 
 1077         /*
 1078          * Configure the timers.
 1079          * XXX Later
 1080          */
 1081 
 1082 
 1083         /*
 1084          * Set the DMA channel priority to rotate between
 1085          * all four channels.
 1086          *
 1087          * Enable all dma channels.
 1088          */
 1089         sca->pcr = SCA_PCR_PR2;
 1090         sca->dmer = SCA_DMER_EN;
 1091 }
 1092 
 1093 
 1094 /*
 1095  * Configure the msci
 1096  *
 1097  * NOTE: The serial port configuration is hardcoded at the moment.
 1098  */
 1099 static void
 1100 ar_init_msci(struct ar_softc *sc)
 1101 {
 1102         msci_channel *msci = &sc->hc->sca->msci[sc->scachan];
 1103 
 1104         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1105 
 1106         msci->cmd = SCA_CMD_RESET;
 1107 
 1108         msci->md0 = SCA_MD0_CRC_1 |
 1109                     SCA_MD0_CRC_CCITT |
 1110                     SCA_MD0_CRC_ENABLE |
 1111                     SCA_MD0_MODE_HDLC;
 1112         msci->md1 = SCA_MD1_NOADDRCHK;
 1113         msci->md2 = SCA_MD2_DUPLEX | SCA_MD2_NRZ;
 1114 
 1115         /*
 1116          * Acording to the manual I should give a reset after changing the
 1117          * mode registers.
 1118          */
 1119         msci->cmd = SCA_CMD_RXRESET;
 1120         msci->ctl = SCA_CTL_IDLPAT | SCA_CTL_UDRNC | SCA_CTL_RTS;
 1121 
 1122         /*
 1123          * For now all interfaces are programmed to use the RX clock for
 1124          * the TX clock.
 1125          */
 1126         switch(sc->hc->interface) {
 1127         case AR_IFACE_V_35:
 1128                 msci->rxs = SCA_RXS_CLK_RXC0 | SCA_RXS_DIV1;
 1129                 msci->txs = SCA_TXS_CLK_TXC | SCA_TXS_DIV1;
 1130                 break;
 1131         case AR_IFACE_X_21:
 1132         case AR_IFACE_EIA_530:
 1133         case AR_IFACE_COMBO:
 1134                 msci->rxs = SCA_RXS_CLK_RXC0 | SCA_RXS_DIV1;
 1135                 msci->txs = SCA_TXS_CLK_RX | SCA_TXS_DIV1;
 1136         }
 1137 
 1138         msci->tmc = 153;   /* This give 64k for loopback */
 1139 
 1140         /* XXX
 1141          * Disable all interrupts for now. I think if you are using
 1142          * the dmac you don't use these interrupts.
 1143          */
 1144         msci->ie0 = 0;
 1145         msci->ie1 = 0x0C; /* XXX CTS and DCD (DSR on 570I) level change. */
 1146         msci->ie2 = 0;
 1147         msci->fie = 0;
 1148 
 1149         msci->sa0 = 0;
 1150         msci->sa1 = 0;
 1151 
 1152         msci->idl = 0x7E; /* XXX This is what cisco does. */
 1153 
 1154         /*
 1155          * This is what the ARNET diags use.
 1156          */
 1157         msci->rrc  = 0x0E;
 1158         msci->trc0 = 0x12;
 1159         msci->trc1 = 0x1F;
 1160 }
 1161 
 1162 /*
 1163  * Configure the rx dma controller.
 1164  */
 1165 static void
 1166 ar_init_rx_dmac(struct ar_softc *sc)
 1167 {
 1168         dmac_channel *dmac = &sc->hc->sca->dmac[DMAC_RXCH(sc->scachan)];
 1169         sca_descriptor *rxd;
 1170         u_int rxbuf;
 1171         u_int rxda;
 1172         u_int rxda_d;
 1173 
 1174         ARC_SET_MEM(sc->hc->iobase, sc->rxdesc);
 1175 
 1176         rxd = (sca_descriptor *)(sc->hc->mem_start + (sc->rxdesc&ARC_WIN_MSK));
 1177         rxda_d = (u_int)sc->hc->mem_start - (sc->rxdesc & ~ARC_WIN_MSK);
 1178 
 1179         for(rxbuf=sc->rxstart;rxbuf<sc->rxend;rxbuf += AR_BUF_SIZ, rxd++) {
 1180                 rxda = (u_int)&rxd[1] - rxda_d;
 1181                 rxd->cp = (u_short)(rxda & 0xfffful);
 1182 
 1183                 TRC(printf("Descrp %p, data pt %p, data long %lx, ",
 1184                         &sc->rxdesc[x], rxinuse->buf, rxbuf));
 1185 
 1186                 rxd->bp = (u_short)(rxbuf & 0xfffful);
 1187                 rxd->bpb = (u_char)((rxbuf >> 16) & 0xff);
 1188                 rxd->len = 0;
 1189                 rxd->stat = 0xff; /* The sca write here when it is finished. */
 1190 
 1191                 TRC(printf("bpb %x, bp %x.\n", rxd->bpb, rxd->bp));
 1192         }
 1193         rxd--;
 1194         rxd->cp = (u_short)(sc->rxdesc & 0xfffful);
 1195 
 1196         sc->rxhind = 0;
 1197 
 1198         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1199 
 1200         dmac->dsr = 0;    /* Disable DMA transfer */
 1201         dmac->dcr = SCA_DCR_ABRT;
 1202 
 1203         /* XXX maybe also SCA_DMR_CNTE */
 1204         dmac->dmr = SCA_DMR_TMOD | SCA_DMR_NF;
 1205         dmac->bfl = AR_BUF_SIZ;
 1206 
 1207         dmac->cda = (u_short)(sc->rxdesc & 0xffff);
 1208         dmac->sarb = (u_char)((sc->rxdesc >> 16) & 0xff);
 1209 
 1210         rxd = (sca_descriptor *)sc->rxstart;
 1211         dmac->eda = (u_short)((u_int)&rxd[sc->rxmax - 1] & 0xffff);
 1212 
 1213         dmac->dir = 0xF0;
 1214 
 1215         dmac->dsr = SCA_DSR_DE;
 1216 }
 1217 
 1218 /*
 1219  * Configure the TX DMA descriptors.
 1220  * Initialize the needed values and chain the descriptors.
 1221  */
 1222 static void
 1223 ar_init_tx_dmac(struct ar_softc *sc)
 1224 {
 1225         dmac_channel *dmac = &sc->hc->sca->dmac[DMAC_TXCH(sc->scachan)];
 1226         struct buf_block *blkp;
 1227         int blk;
 1228         sca_descriptor *txd;
 1229         u_int txbuf;
 1230         u_int txda;
 1231         u_int txda_d;
 1232 
 1233         ARC_SET_MEM(sc->hc->iobase, sc->block[0].txdesc);
 1234 
 1235         for(blk = 0; blk < AR_TX_BLOCKS; blk++) {
 1236                 blkp = &sc->block[blk];
 1237                 txd = (sca_descriptor *)(sc->hc->mem_start +
 1238                                         (blkp->txdesc&ARC_WIN_MSK));
 1239                 txda_d = (u_int)sc->hc->mem_start -
 1240                                 (blkp->txdesc & ~ARC_WIN_MSK);
 1241 
 1242                 txbuf=blkp->txstart;
 1243                 for(;txbuf<blkp->txend;txbuf += AR_BUF_SIZ, txd++) {
 1244                         txda = (u_int)&txd[1] - txda_d;
 1245                         txd->cp = (u_short)(txda & 0xfffful);
 1246 
 1247                         txd->bp = (u_short)(txbuf & 0xfffful);
 1248                         txd->bpb = (u_char)((txbuf >> 16) & 0xff);
 1249                         TRC(printf("ar%d: txbuf %x, bpb %x, bp %x\n",
 1250                                 sc->unit, txbuf, txd->bpb, txd->bp));
 1251                         txd->len = 0;
 1252                         txd->stat = 0;
 1253                 }
 1254                 txd--;
 1255                 txd->cp = (u_short)(blkp->txdesc & 0xfffful);
 1256 
 1257                 blkp->txtail = (u_int)txd - (u_int)sc->hc->mem_start;
 1258                 TRC(printf("TX Descriptors start %x, end %x.\n",
 1259                         blkp->txhead,
 1260                         blkp->txtail));
 1261         }
 1262 
 1263         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1264 
 1265         dmac->dsr = 0; /* Disable DMA */
 1266         dmac->dcr = SCA_DCR_ABRT;
 1267         dmac->dmr = SCA_DMR_TMOD | SCA_DMR_NF;
 1268         dmac->dir = SCA_DIR_EOT | SCA_DIR_BOF | SCA_DIR_COF;
 1269 
 1270         dmac->sarb = (u_char)((sc->block[0].txdesc >> 16) & 0xff);
 1271 }
 1272 
 1273 
 1274 /*
 1275  * Look through the descriptors to see if there is a complete packet
 1276  * available. Stop if we get to where the sca is busy.
 1277  *
 1278  * Return the length and status of the packet.
 1279  * Return nonzero if there is a packet available.
 1280  *
 1281  * NOTE:
 1282  * It seems that we get the interrupt a bit early. The updateing of
 1283  * descriptor values is not always completed when this is called.
 1284  */
 1285 static int
 1286 ar_packet_avail(struct ar_softc *sc,
 1287                     int *len,
 1288                     u_char *rxstat)
 1289 {
 1290         sca_descriptor *rxdesc;
 1291         sca_descriptor *endp;
 1292         sca_descriptor *cda;
 1293 
 1294         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1295         cda = (sca_descriptor *)(sc->hc->mem_start +
 1296               (sc->hc->sca->dmac[DMAC_RXCH(sc->scachan)].cda &  ARC_WIN_MSK));
 1297 
 1298         ARC_SET_MEM(sc->hc->iobase, sc->rxdesc);
 1299         rxdesc = (sca_descriptor *)
 1300                         (sc->hc->mem_start + (sc->rxdesc & ARC_WIN_MSK));
 1301         endp = rxdesc;
 1302         rxdesc = &rxdesc[sc->rxhind];
 1303         endp = &endp[sc->rxmax];
 1304 
 1305         *len = 0;
 1306 
 1307         while(rxdesc != cda) {
 1308                 *len += rxdesc->len;
 1309 
 1310                 if(rxdesc->stat & SCA_DESC_EOM) {
 1311                         *rxstat = rxdesc->stat;
 1312                         TRC(printf("ar%d: PKT AVAIL len %d, %x, bufs %u.\n",
 1313                                 sc->unit, *len, *rxstat, x));
 1314                         return 1;
 1315                 }
 1316 
 1317                 rxdesc++;
 1318                 if(rxdesc == endp)
 1319                         rxdesc = (sca_descriptor *)
 1320                                (sc->hc->mem_start + (sc->rxdesc & ARC_WIN_MSK));
 1321         }
 1322 
 1323         *len = 0;
 1324         *rxstat = 0;
 1325         return 0;
 1326 }
 1327 
 1328 
 1329 /*
 1330  * Copy a packet from the on card memory into a provided mbuf.
 1331  * Take into account that buffers wrap and that a packet may
 1332  * be larger than a buffer.
 1333  */
 1334 static void 
 1335 ar_copy_rxbuf(struct mbuf *m,
 1336                    struct ar_softc *sc,
 1337                    int len)
 1338 {
 1339         sca_descriptor *rxdesc;
 1340         u_int rxdata;
 1341         u_int rxmax;
 1342         u_int off = 0;
 1343         u_int tlen;
 1344 
 1345         rxdata = sc->rxstart + (sc->rxhind * AR_BUF_SIZ);
 1346         rxmax = sc->rxstart + (sc->rxmax * AR_BUF_SIZ);
 1347 
 1348         rxdesc = (sca_descriptor *)
 1349                         (sc->hc->mem_start + (sc->rxdesc & ARC_WIN_MSK));
 1350         rxdesc = &rxdesc[sc->rxhind];
 1351 
 1352         while(len) {
 1353                 tlen = (len < AR_BUF_SIZ) ? len : AR_BUF_SIZ;
 1354                 ARC_SET_MEM(sc->hc->iobase, rxdata);
 1355                 bcopy(sc->hc->mem_start + (rxdata & ARC_WIN_MSK), 
 1356                         mtod(m, caddr_t) + off,
 1357                         tlen);
 1358 
 1359                 off += tlen;
 1360                 len -= tlen;
 1361 
 1362                 ARC_SET_MEM(sc->hc->iobase, sc->rxdesc);
 1363                 rxdesc->len = 0;
 1364                 rxdesc->stat = 0xff;
 1365 
 1366                 rxdata += AR_BUF_SIZ;
 1367                 rxdesc++;
 1368                 if(rxdata == rxmax) {
 1369                         rxdata = sc->rxstart;
 1370                         rxdesc = (sca_descriptor *)
 1371                                 (sc->hc->mem_start + (sc->rxdesc & ARC_WIN_MSK));
 1372                 }
 1373         }
 1374 }
 1375 
 1376 /*
 1377  * If single is set, just eat a packet. Otherwise eat everything up to
 1378  * where cda points. Update pointers to point to the next packet.
 1379  */
 1380 static void
 1381 ar_eat_packet(struct ar_softc *sc, int single)
 1382 {
 1383         sca_descriptor *rxdesc;
 1384         sca_descriptor *endp;
 1385         sca_descriptor *cda;
 1386         int loopcnt = 0;
 1387         u_char stat;
 1388 
 1389         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1390         cda = (sca_descriptor *)(sc->hc->mem_start +
 1391               (sc->hc->sca->dmac[DMAC_RXCH(sc->scachan)].cda &  ARC_WIN_MSK));
 1392 
 1393         /*
 1394          * Loop until desc->stat == (0xff || EOM)
 1395          * Clear the status and length in the descriptor.
 1396          * Increment the descriptor.
 1397          */
 1398         ARC_SET_MEM(sc->hc->iobase, sc->rxdesc);
 1399         rxdesc = (sca_descriptor *)
 1400                 (sc->hc->mem_start + (sc->rxdesc & ARC_WIN_MSK));
 1401         endp = rxdesc;
 1402         rxdesc = &rxdesc[sc->rxhind];
 1403         endp = &endp[sc->rxmax];
 1404 
 1405         while(rxdesc != cda) {
 1406                 loopcnt++;
 1407                 if(loopcnt > sc->rxmax) {
 1408                         printf("ar%d: eat pkt %d loop, cda %p, "
 1409                                "rxdesc %p, stat %x.\n",
 1410                                sc->unit,
 1411                                loopcnt,
 1412                                (void *)cda,
 1413                                (void *)rxdesc,
 1414                                rxdesc->stat);
 1415                         break;
 1416                 }
 1417 
 1418                 stat = rxdesc->stat;
 1419 
 1420                 rxdesc->len = 0;
 1421                 rxdesc->stat = 0xff;
 1422 
 1423                 rxdesc++;
 1424                 sc->rxhind++;
 1425                 if(rxdesc == endp) {
 1426                         rxdesc = (sca_descriptor *)
 1427                                (sc->hc->mem_start + (sc->rxdesc & ARC_WIN_MSK));
 1428                         sc->rxhind = 0;
 1429                 }
 1430 
 1431                 if(single && (stat == SCA_DESC_EOM))
 1432                         break;
 1433         }
 1434 
 1435         /*
 1436          * Update the eda to the previous descriptor.
 1437          */
 1438         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1439 
 1440         rxdesc = (sca_descriptor *)sc->rxdesc;
 1441         rxdesc = &rxdesc[(sc->rxhind + sc->rxmax - 2 ) % sc->rxmax];
 1442 
 1443         sc->hc->sca->dmac[DMAC_RXCH(sc->scachan)].eda = 
 1444                         (u_short)((u_int)rxdesc & 0xffff);
 1445 }
 1446 
 1447 
 1448 /*
 1449  * While there is packets available in the rx buffer, read them out
 1450  * into mbufs and ship them off.
 1451  */
 1452 static void
 1453 ar_get_packets(struct ar_softc *sc)
 1454 {
 1455         sca_descriptor *rxdesc;
 1456         struct mbuf *m = NULL;
 1457         int i;
 1458         int len;
 1459         u_char rxstat;
 1460 
 1461         while(ar_packet_avail(sc, &len, &rxstat)) {
 1462                 if(((rxstat & SCA_DESC_ERRORS) == 0) && (len < MCLBYTES)) {
 1463                         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1464                         if(m == NULL) {
 1465                                 /* eat packet if get mbuf fail!! */
 1466                                 ar_eat_packet(sc, 1);
 1467                                 continue;
 1468                         }
 1469 #ifndef NETGRAPH
 1470                         m->m_pkthdr.rcvif = &sc->ifsppp.pp_if;
 1471 #else   /* NETGRAPH */
 1472                         m->m_pkthdr.rcvif = NULL;
 1473                         sc->inbytes += len;
 1474                         sc->inlast = 0;
 1475 #endif  /* NETGRAPH */
 1476                         m->m_pkthdr.len = m->m_len = len;
 1477                         if(len > MHLEN) {
 1478                                 MCLGET(m, M_DONTWAIT);
 1479                                 if((m->m_flags & M_EXT) == 0) {
 1480                                         m_freem(m);
 1481                                         ar_eat_packet(sc, 1);
 1482                                         continue;
 1483                                 }
 1484                         }
 1485                         ar_copy_rxbuf(m, sc, len);
 1486 #ifndef NETGRAPH
 1487 #if     NBPFILTER > 0
 1488                         if(sc->ifsppp.pp_if.if_bpf)
 1489                                 bpf_mtap(&sc->ifsppp.pp_if, m);
 1490 #endif  /* NBPFILTER > 0 */
 1491                         sppp_input(&sc->ifsppp.pp_if, m);
 1492                         sc->ifsppp.pp_if.if_ipackets++;
 1493 #else   /* NETGRAPH */
 1494                         ng_queue_data(sc->hook, m, NULL);
 1495                         sc->ipackets++;
 1496 #endif  /* NETGRAPH */
 1497 
 1498                         /*
 1499                          * Update the eda to the previous descriptor.
 1500                          */
 1501                         i = (len + AR_BUF_SIZ - 1) / AR_BUF_SIZ;
 1502                         sc->rxhind = (sc->rxhind + i) % sc->rxmax;
 1503 
 1504                         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1505 
 1506                         rxdesc = (sca_descriptor *)sc->rxdesc;
 1507                         rxdesc =
 1508                              &rxdesc[(sc->rxhind + sc->rxmax - 2 ) % sc->rxmax];
 1509 
 1510                         sc->hc->sca->dmac[DMAC_RXCH(sc->scachan)].eda = 
 1511                                 (u_short)((u_int)rxdesc & 0xffff);
 1512                 } else {
 1513                         int tries = 5;
 1514 
 1515                         while((rxstat == 0xff) && --tries)
 1516                                 ar_packet_avail(sc, &len, &rxstat);
 1517 
 1518                         /*
 1519                          * It look like we get an interrupt early
 1520                          * sometimes and then the status is not
 1521                          * filled in yet.
 1522                          */
 1523                         if(tries && (tries != 5))
 1524                                 continue;
 1525 
 1526                         ar_eat_packet(sc, 1);
 1527 
 1528 #ifndef NETGRAPH
 1529                         sc->ifsppp.pp_if.if_ierrors++;
 1530 #else   /* NETGRAPH */
 1531                         sc->ierrors[0]++;
 1532 #endif  /* NETGRAPH */
 1533 
 1534                         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1535 
 1536                         TRCL(printf("ar%d: Receive error chan %d, "
 1537                                         "stat %x, msci st3 %x,"
 1538                                         "rxhind %d, cda %x, eda %x.\n",
 1539                                         sc->unit,
 1540                                         sc->scachan, 
 1541                                         rxstat,
 1542                                         sc->hc->sca->msci[sc->scachan].st3,
 1543                                         sc->rxhind,
 1544                                         sc->hc->sca->dmac[
 1545                                                 DMAC_RXCH(sc->scachan)].cda,
 1546                                         sc->hc->sca->dmac[
 1547                                                 DMAC_RXCH(sc->scachan)].eda));
 1548                 }
 1549         }
 1550 }
 1551 
 1552 
 1553 /*
 1554  * All DMA interrupts come here.
 1555  *
 1556  * Each channel has two interrupts.
 1557  * Interrupt A for errors and Interrupt B for normal stuff like end
 1558  * of transmit or receive dmas.
 1559  */
 1560 static void
 1561 ar_dmac_intr(struct ar_hardc *hc, int scano, u_char isr1)
 1562 {
 1563         u_char dsr;
 1564         u_char dotxstart = isr1;
 1565         int mch;
 1566         struct ar_softc *sc;
 1567         sca_regs *sca = hc->sca;
 1568         dmac_channel *dmac;
 1569 
 1570         mch = 0;
 1571         /*
 1572          * Shortcut if there is no interrupts for dma channel 0 or 1
 1573          */
 1574         if((isr1 & 0x0F) == 0) {
 1575                 mch = 1;
 1576                 isr1 >>= 4;
 1577         }
 1578 
 1579         do {
 1580                 sc = &hc->sc[mch + (NCHAN * scano)];
 1581 
 1582                 /*
 1583                  * Transmit channel
 1584                  */
 1585                 if(isr1 & 0x0C) {
 1586                         dmac = &sca->dmac[DMAC_TXCH(mch)];
 1587 
 1588                         ARC_SET_SCA(hc->iobase, scano);
 1589 
 1590                         dsr = dmac->dsr;
 1591                         dmac->dsr = dsr;
 1592 
 1593                         /* Counter overflow */
 1594                         if(dsr & SCA_DSR_COF) {
 1595                                 printf("ar%d: TX DMA Counter overflow, "
 1596                                         "txpacket no %lu.\n",
 1597                                         sc->unit,
 1598 #ifndef NETGRAPH
 1599                                         sc->ifsppp.pp_if.if_opackets);
 1600                                 sc->ifsppp.pp_if.if_oerrors++;
 1601 #else   /* NETGRAPH */
 1602                                         sc->opackets);
 1603                                 sc->oerrors++;
 1604 #endif  /* NETGRAPH */
 1605                         }
 1606 
 1607                         /* Buffer overflow */
 1608                         if(dsr & SCA_DSR_BOF) {
 1609                                 printf("ar%d: TX DMA Buffer overflow, "
 1610                                         "txpacket no %lu, dsr %02x, "
 1611                                         "cda %04x, eda %04x.\n",
 1612                                         sc->unit,
 1613 #ifndef NETGRAPH
 1614                                         sc->ifsppp.pp_if.if_opackets,
 1615 #else   /* NETGRAPH */
 1616                                         sc->opackets,
 1617 #endif  /* NETGRAPH */
 1618                                         dsr,
 1619                                         dmac->cda,
 1620                                         dmac->eda);
 1621 #ifndef NETGRAPH
 1622                                 sc->ifsppp.pp_if.if_oerrors++;
 1623 #else   /* NETGRAPH */
 1624                                 sc->oerrors++;
 1625 #endif  /* NETGRAPH */
 1626                         }
 1627 
 1628                         /* End of Transfer */
 1629                         if(dsr & SCA_DSR_EOT) {
 1630                                 /*
 1631                                  * This should be the most common case.
 1632                                  *
 1633                                  * Clear the IFF_OACTIVE flag.
 1634                                  *
 1635                                  * Call arstart to start a new transmit if
 1636                                  * there is data to transmit.
 1637                                  */
 1638                                 sc->xmit_busy = 0;
 1639 #ifndef NETGRAPH
 1640                                 sc->ifsppp.pp_if.if_flags &= ~IFF_OACTIVE;
 1641                                 sc->ifsppp.pp_if.if_timer = 0;
 1642 #else   /* NETGRAPH */
 1643                         /* XXX  c->ifsppp.pp_if.if_flags &= ~IFF_OACTIVE; */
 1644                                 sc->out_dog = 0; /* XXX */
 1645 #endif  /* NETGRAPH */
 1646 
 1647                                 if(sc->txb_inuse && --sc->txb_inuse)
 1648                                         ar_xmit(sc);
 1649                         }
 1650                 }
 1651 
 1652                 /*
 1653                  * Receive channel
 1654                  */
 1655                 if(isr1 & 0x03) {
 1656                         dmac = &sca->dmac[DMAC_RXCH(mch)];
 1657 
 1658                         ARC_SET_SCA(hc->iobase, scano);
 1659 
 1660                         dsr = dmac->dsr;
 1661                         dmac->dsr = dsr;
 1662 
 1663                         TRC(printf("AR: RX DSR %x\n", dsr));
 1664 
 1665                         /* End of frame */
 1666                         if(dsr & SCA_DSR_EOM) {
 1667                                 TRC(int tt = sc->ifsppp.pp_if.if_ipackets;)
 1668                                 TRC(int ind = sc->rxhind;)
 1669 
 1670                                 ar_get_packets(sc);
 1671                                 TRC(
 1672 #ifndef NETGRAPH
 1673                                 if(tt == sc->ifsppp.pp_if.if_ipackets) {
 1674 #else   /* NETGRAPH */
 1675                                 if(tt == sc->ipackets) {
 1676 #endif  /* NETGRAPH */
 1677                                         sca_descriptor *rxdesc;
 1678                                         int i;
 1679 
 1680                                         ARC_SET_SCA(hc->iobase, scano);
 1681                                         printf("AR: RXINTR isr1 %x, dsr %x, "
 1682                                                "no data %d pkts, orxhind %d.\n",
 1683                                                dotxstart,
 1684                                                dsr,
 1685                                                tt,
 1686                                                ind);
 1687                                         printf("AR: rxdesc %x, rxstart %x, "
 1688                                                "rxend %x, rxhind %d, "
 1689                                                "rxmax %d.\n",
 1690                                                sc->rxdesc,
 1691                                                sc->rxstart,
 1692                                                sc->rxend,
 1693                                                sc->rxhind,
 1694                                                sc->rxmax);
 1695                                         printf("AR: cda %x, eda %x.\n",
 1696                                                dmac->cda,
 1697                                                dmac->eda);
 1698 
 1699                                         ARC_SET_MEM(sc->hc->iobase, sc->rxdesc);
 1700                                         rxdesc = (sca_descriptor *)
 1701                                                  (sc->hc->mem_start +
 1702                                                   (sc->rxdesc & ARC_WIN_MSK));
 1703                                         rxdesc = &rxdesc[sc->rxhind];
 1704                                         for(i=0;i<3;i++,rxdesc++)
 1705                                                 printf("AR: rxdesc->stat %x, "
 1706                                                         "len %d.\n",
 1707                                                         rxdesc->stat,
 1708                                                         rxdesc->len);
 1709                                 })
 1710                         }
 1711 
 1712                         /* Counter overflow */
 1713                         if(dsr & SCA_DSR_COF) {
 1714                                 printf("ar%d: RX DMA Counter overflow, "
 1715                                         "rxpkts %lu.\n",
 1716                                         sc->unit,
 1717 #ifndef NETGRAPH
 1718                                         sc->ifsppp.pp_if.if_ipackets);
 1719                                 sc->ifsppp.pp_if.if_ierrors++;
 1720 #else   /* NETGRAPH */
 1721                                         sc->ipackets);
 1722                                 sc->ierrors[1]++;
 1723 #endif  /* NETGRAPH */
 1724                         }
 1725 
 1726                         /* Buffer overflow */
 1727                         if(dsr & SCA_DSR_BOF) {
 1728                                 ARC_SET_SCA(hc->iobase, scano);
 1729                                 printf("ar%d: RX DMA Buffer overflow, "
 1730                                         "rxpkts %lu, rxind %d, "
 1731                                         "cda %x, eda %x, dsr %x.\n",
 1732                                         sc->unit,
 1733 #ifndef NETGRAPH
 1734                                         sc->ifsppp.pp_if.if_ipackets,
 1735 #else   /* NETGRAPH */
 1736                                         sc->ipackets,
 1737 #endif  /* NETGRAPH */
 1738                                         sc->rxhind,
 1739                                         dmac->cda,
 1740                                         dmac->eda,
 1741                                         dsr);
 1742                                 /*
 1743                                  * Make sure we eat as many as possible.
 1744                                  * Then get the system running again.
 1745                                  */
 1746                                 ar_eat_packet(sc, 0);
 1747 #ifndef NETGRAPH
 1748                                 sc->ifsppp.pp_if.if_ierrors++;
 1749 #else   /* NETGRAPH */
 1750                                 sc->ierrors[2]++;
 1751 #endif  /* NETGRAPH */
 1752                                 ARC_SET_SCA(hc->iobase, scano);
 1753                                 sca->msci[mch].cmd = SCA_CMD_RXMSGREJ;
 1754                                 dmac->dsr = SCA_DSR_DE;
 1755 
 1756                                 TRC(printf("ar%d: RX DMA Buffer overflow, "
 1757                                         "rxpkts %lu, rxind %d, "
 1758                                         "cda %x, eda %x, dsr %x. After\n",
 1759                                         sc->unit,
 1760                                         sc->ifsppp.pp_if.if_ipackets,
 1761                                         sc->rxhind,
 1762                                         dmac->cda,
 1763                                         dmac->eda,
 1764                                         dmac->dsr);)
 1765                         }
 1766 
 1767                         /* End of Transfer */
 1768                         if(dsr & SCA_DSR_EOT) {
 1769                                 /*
 1770                                  * If this happen, it means that we are
 1771                                  * receiving faster than what the processor
 1772                                  * can handle.
 1773                                  *
 1774                                  * XXX We should enable the dma again.
 1775                                  */
 1776                                 printf("ar%d: RX End of transfer, rxpkts %lu.\n",
 1777                                         sc->unit,
 1778 #ifndef NETGRAPH
 1779                                         sc->ifsppp.pp_if.if_ipackets);
 1780                                 sc->ifsppp.pp_if.if_ierrors++;
 1781 #else   /* NETGRAPH */
 1782                                         sc->ipackets);
 1783                                 sc->ierrors[3]++;
 1784 #endif  /* NETGRAPH */
 1785                         }
 1786                 }
 1787 
 1788                 isr1 >>= 4;
 1789 
 1790                 mch++;
 1791         }while((mch<NCHAN) && isr1);
 1792 
 1793         /*
 1794          * Now that we have done all the urgent things, see if we
 1795          * can fill the transmit buffers.
 1796          */
 1797         for(mch = 0; mch < NCHAN; mch++) {
 1798                 if(dotxstart & 0x0C) {
 1799                         sc = &hc->sc[mch + (NCHAN * scano)];
 1800 #ifndef NETGRAPH
 1801                         arstart(&sc->ifsppp.pp_if);
 1802 #else   /* NETGRAPH */
 1803                         arstart(sc);
 1804 #endif  /* NETGRAPH */
 1805                 }
 1806                 dotxstart >>= 4;
 1807         }
 1808 }
 1809 
 1810 static void
 1811 ar_msci_intr(struct ar_hardc *hc, int scano, u_char isr0)
 1812 {
 1813         printf("arc%d: ARINTR: MSCI\n", hc->cunit);
 1814 }
 1815 
 1816 static void
 1817 ar_timer_intr(struct ar_hardc *hc, int scano, u_char isr2)
 1818 {
 1819         printf("arc%d: ARINTR: TIMER\n", hc->cunit);
 1820 }
 1821 
 1822 
 1823 #ifdef  NETGRAPH
 1824 /*****************************************
 1825  * Device timeout/watchdog routine.
 1826  * called once per second.
 1827  * checks to see that if activity was expected, that it hapenned.
 1828  * At present we only look to see if expected output was completed.
 1829  */
 1830 static void
 1831 ngar_watchdog_frame(void * arg)
 1832 {
 1833         struct ar_softc * sc = arg;
 1834         int s;
 1835         int     speed;
 1836 
 1837         if(sc->running == 0)
 1838                 return; /* if we are not running let timeouts die */
 1839         /*
 1840          * calculate the apparent throughputs 
 1841          *  XXX a real hack
 1842          */
 1843         s = splimp();
 1844         speed = sc->inbytes - sc->lastinbytes;
 1845         sc->lastinbytes = sc->inbytes;
 1846         if ( sc->inrate < speed )
 1847                 sc->inrate = speed;
 1848         speed = sc->outbytes - sc->lastoutbytes;
 1849         sc->lastoutbytes = sc->outbytes;
 1850         if ( sc->outrate < speed )
 1851                 sc->outrate = speed;
 1852         sc->inlast++;
 1853         splx(s);
 1854 
 1855         if ((sc->inlast > QUITE_A_WHILE)
 1856         && (sc->out_deficit > LOTS_OF_PACKETS)) {
 1857                 log(LOG_ERR, "ar%d: No response from remote end\n", sc->unit);
 1858                 s = splimp();
 1859                 ar_down(sc);
 1860                 ar_up(sc);
 1861                 sc->inlast = sc->out_deficit = 0;
 1862                 splx(s);
 1863         } else if ( sc->xmit_busy ) { /* no TX -> no TX timeouts */
 1864                 if (sc->out_dog == 0) { 
 1865                         log(LOG_ERR, "ar%d: Transmit failure.. no clock?\n",
 1866                                         sc->unit);
 1867                         s = splimp();
 1868                         arwatchdog(sc);
 1869 #if 0
 1870                         ar_down(sc);
 1871                         ar_up(sc);
 1872 #endif
 1873                         splx(s);
 1874                         sc->inlast = sc->out_deficit = 0;
 1875                 } else {
 1876                         sc->out_dog--;
 1877                 }
 1878         }
 1879         sc->handle = timeout(ngar_watchdog_frame, sc, hz);
 1880 }
 1881 
 1882 /***********************************************************************
 1883  * This section contains the methods for the Netgraph interface
 1884  ***********************************************************************/
 1885 /*
 1886  * It is not possible or allowable to create a node of this type.
 1887  * If the hardware exists, it will already have created it.
 1888  */
 1889 static  int
 1890 ngar_constructor(node_p *nodep)
 1891 {
 1892         return (EINVAL);
 1893 }
 1894 
 1895 /*
 1896  * give our ok for a hook to be added...
 1897  * If we are not running this should kick the device into life.
 1898  * The hook's private info points to our stash of info about that
 1899  * channel.
 1900  */
 1901 static int
 1902 ngar_newhook(node_p node, hook_p hook, const char *name)
 1903 {
 1904         struct ar_softc *       sc = node->private;
 1905 
 1906         /*
 1907          * check if it's our friend the debug hook
 1908          */
 1909         if (strcmp(name, NG_AR_HOOK_DEBUG) == 0) {
 1910                 hook->private = NULL; /* paranoid */
 1911                 sc->debug_hook = hook;
 1912                 return (0);
 1913         }
 1914 
 1915         /*
 1916          * Check for raw mode hook.
 1917          */
 1918         if (strcmp(name, NG_AR_HOOK_RAW) != 0) {
 1919                 return (EINVAL);
 1920         }
 1921         hook->private = sc;
 1922         sc->hook = hook;
 1923         sc->datahooks++;
 1924         ar_up(sc);
 1925         return (0);
 1926 }
 1927 
 1928 /*
 1929  * incoming messages.
 1930  * Just respond to the generic TEXT_STATUS message
 1931  */
 1932 static  int
 1933 ngar_rcvmsg(node_p node,
 1934         struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp)
 1935 {
 1936         struct ar_softc *       sc;
 1937         int error = 0;
 1938 
 1939         sc = node->private;
 1940         switch (msg->header.typecookie) {
 1941             case        NG_AR_COOKIE: 
 1942                 error = EINVAL;
 1943                 break;
 1944             case        NGM_GENERIC_COOKIE: 
 1945                 switch(msg->header.cmd) {
 1946                     case NGM_TEXT_STATUS: {
 1947                             char        *arg;
 1948                             int pos = 0;
 1949                             int resplen = sizeof(struct ng_mesg) + 512;
 1950                             MALLOC(*resp, struct ng_mesg *, resplen,
 1951                                         M_NETGRAPH, M_NOWAIT);
 1952                             if (*resp == NULL) { 
 1953                                 error = ENOMEM;
 1954                                 break;
 1955                             }       
 1956                             bzero(*resp, resplen);
 1957                             arg = (*resp)->data;
 1958 
 1959                             /*
 1960                              * Put in the throughput information.
 1961                              */
 1962                             pos = sprintf(arg, "%ld bytes in, %ld bytes out\n"
 1963                             "highest rate seen: %ld B/S in, %ld B/S out\n",
 1964                             sc->inbytes, sc->outbytes,
 1965                             sc->inrate, sc->outrate);
 1966                             pos += sprintf(arg + pos,
 1967                                 "%ld output errors\n",
 1968                                 sc->oerrors);
 1969                             pos += sprintf(arg + pos,
 1970                                 "ierrors = %ld, %ld, %ld, %ld\n",
 1971                                 sc->ierrors[0],
 1972                                 sc->ierrors[1],
 1973                                 sc->ierrors[2],
 1974                                 sc->ierrors[3]);
 1975 
 1976                             (*resp)->header.version = NG_VERSION;
 1977                             (*resp)->header.arglen = strlen(arg) + 1;
 1978                             (*resp)->header.token = msg->header.token;
 1979                             (*resp)->header.typecookie = NG_AR_COOKIE;
 1980                             (*resp)->header.cmd = msg->header.cmd;
 1981                             strncpy((*resp)->header.cmdstr, "status",
 1982                                         NG_CMDSTRLEN);
 1983                         }
 1984                         break;
 1985                     default:
 1986                         error = EINVAL;
 1987                         break;
 1988                     }
 1989                 break;
 1990             default:
 1991                 error = EINVAL;
 1992                 break;
 1993         }
 1994         free(msg, M_NETGRAPH);
 1995         return (error);
 1996 }
 1997 
 1998 /*
 1999  * get data from another node and transmit it to the correct channel
 2000  */
 2001 static  int
 2002 ngar_rcvdata(hook_p hook, struct mbuf *m, meta_p meta)
 2003 {
 2004         int s;
 2005         int error = 0;
 2006         struct ar_softc * sc = hook->node->private;
 2007         struct ifqueue  *xmitq_p;
 2008         
 2009         /*
 2010          * data doesn't come in from just anywhere (e.g control hook)
 2011          */
 2012         if ( hook->private == NULL) {
 2013                 error = ENETDOWN;
 2014                 goto bad;
 2015         }
 2016 
 2017         /* 
 2018          * Now queue the data for when it can be sent
 2019          */
 2020         if (meta && meta->priority > 0) {
 2021                 xmitq_p = (&sc->xmitq_hipri);
 2022         } else {
 2023                 xmitq_p = (&sc->xmitq);
 2024         }
 2025         s = splimp();
 2026         if (IF_QFULL(xmitq_p)) {
 2027                 IF_DROP(xmitq_p);
 2028                 splx(s);
 2029                 error = ENOBUFS;
 2030                 goto bad;
 2031         }
 2032         IF_ENQUEUE(xmitq_p, m);
 2033         arstart(sc);
 2034         splx(s);
 2035         return (0);
 2036 
 2037 bad:
 2038         /* 
 2039          * It was an error case.
 2040          * check if we need to free the mbuf, and then return the error
 2041          */
 2042         NG_FREE_DATA(m, meta);
 2043         return (error);
 2044 }
 2045 
 2046 /*
 2047  * do local shutdown processing..
 2048  * this node will refuse to go away, unless the hardware says to..
 2049  * don't unref the node, or remove our name. just clear our links up.
 2050  */
 2051 static  int
 2052 ngar_rmnode(node_p node)
 2053 {
 2054         struct ar_softc * sc = node->private;
 2055 
 2056         ar_down(sc);
 2057         ng_cutlinks(node);
 2058         node->flags &= ~NG_INVALID; /* bounce back to life */
 2059         return (0);
 2060 }
 2061 
 2062 /* already linked */
 2063 static  int
 2064 ngar_connect(hook_p hook)
 2065 {
 2066         /* be really amiable and just say "YUP that's OK by me! " */
 2067         return (0);
 2068 }
 2069 
 2070 /*
 2071  * notify on hook disconnection (destruction)
 2072  *
 2073  * Invalidate the private data associated with this dlci.
 2074  * For this type, removal of the last link resets tries to destroy the node.
 2075  * As the device still exists, the shutdown method will not actually
 2076  * destroy the node, but reset the device and leave it 'fresh' :)
 2077  *
 2078  * The node removal code will remove all references except that owned by the
 2079  * driver. 
 2080  */
 2081 static  int
 2082 ngar_disconnect(hook_p hook)
 2083 {
 2084         struct ar_softc * sc = hook->node->private;
 2085         int     s;
 2086         /*
 2087          * If it's the data hook, then free resources etc.
 2088          */
 2089         if (hook->private) {
 2090                 s = splimp();
 2091                 sc->datahooks--;
 2092                 if (sc->datahooks == 0)
 2093                         ar_down(sc);
 2094                 splx(s);
 2095         } else {
 2096                 sc->debug_hook = NULL;
 2097         }
 2098         return (0);
 2099 }
 2100 
 2101 /*
 2102  * called during bootup
 2103  * or LKM loading to put this type into the list of known modules
 2104  */
 2105 static void
 2106 ngar_init(void *ignored)
 2107 {
 2108         if (ng_newtype(&typestruct))
 2109                 printf("ngar install failed\n");
 2110         ngar_done_init = 1;
 2111 }
 2112 #endif /* NETGRAPH */
 2113 
 2114 /*
 2115  ********************************* END ************************************
 2116  */

Cache object: e40db7a75fdeabfc5690e5985ad2ab04


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