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: src/sys/i386/isa/if_ar.c,v 1.12.2.1 1999/09/05 08:12:41 peter Exp $
   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 "ar.h"
   52 #include "bpfilter.h"
   53 
   54 #include <sys/param.h>
   55 #include <sys/systm.h>
   56 #include <sys/mbuf.h>
   57 #include <sys/sockio.h>
   58 #include <sys/socket.h>
   59 
   60 #include <net/if.h>
   61 #include <net/if_sppp.h>
   62 
   63 #if NBPFILTER > 0
   64 #include <net/bpf.h>
   65 #endif
   66 
   67 #include <machine/clock.h>
   68 #include <machine/md_var.h>
   69 
   70 #include <i386/isa/if_arregs.h>
   71 #include <i386/isa/ic/hd64570.h>
   72 
   73 #include "ioconf.h"
   74 
   75 #ifdef TRACE
   76 #define TRC(x)               x
   77 #else
   78 #define TRC(x)
   79 #endif
   80 
   81 #define TRCL(x)              x
   82 
   83 #define PPP_HEADER_LEN       4
   84 
   85 #define ARC_GET_WIN(addr)       ((addr >> ARC_WIN_SHFT) & AR_WIN_MSK)
   86 
   87 #define ARC_SET_MEM(iobase,win) outb(iobase+AR_MSCA_EN, AR_ENA_MEM | \
   88                                 ARC_GET_WIN(win))
   89 #define ARC_SET_SCA(iobase,ch)  outb(iobase+AR_MSCA_EN, AR_ENA_MEM | \
   90                                 AR_ENA_SCA | (ch ? AR_SEL_SCA_1:AR_SEL_SCA_0))
   91 #define ARC_SET_OFF(iobase)     outb(iobase+AR_MSCA_EN, 0)
   92 
   93 static struct ar_hardc {
   94         int cunit;
   95         struct ar_softc *sc;
   96         u_short iobase;
   97         int startunit;
   98         int numports;
   99         caddr_t mem_start;
  100         caddr_t mem_end;
  101 
  102         u_int memsize;          /* in bytes */
  103         u_char bustype;         /* ISA, MCA, PCI.... */
  104         u_char interface;       /* X21, V.35, EIA-530.... */
  105         u_char revision;
  106         u_char handshake;       /* handshake lines supported by card. */
  107 
  108         u_char txc_dtr[NPORT/NCHAN]; /* the register is write only */
  109         u_int txc_dtr_off[NPORT/NCHAN];
  110 
  111         sca_regs *sca;
  112 
  113 }ar_hardc[NAR];
  114 
  115 struct ar_softc {
  116         struct sppp ifsppp;
  117         int unit;            /* With regards to all ar devices */
  118         int subunit;         /* With regards to this card */
  119         struct ar_hardc *hc;
  120 
  121         struct buf_block {
  122                 u_int txdesc;        /* On card address */
  123                 u_int txstart;       /* On card address */
  124                 u_int txend;         /* On card address */
  125                 u_int txtail;        /* Index of first unused buffer */
  126                 u_int txmax;         /* number of usable buffers/descriptors */
  127                 u_int txeda;         /* Error descriptor addresses */
  128         }block[AR_TX_BLOCKS];
  129 
  130         char  xmit_busy;     /* Transmitter is busy */
  131         char  txb_inuse;     /* Number of tx blocks currently in use */
  132         char  txb_new;       /* Index to where new buffer will be added */
  133         char  txb_next_tx;    /* Index to next block ready to tx */
  134 
  135         u_int rxdesc;        /* On card address */
  136         u_int rxstart;       /* On card address */
  137         u_int rxend;         /* On card address */
  138         u_int rxhind;        /* Index to the head of the rx buffers. */
  139         u_int rxmax;         /* number of usable buffers/descriptors */
  140 
  141         int scano;
  142         int scachan;
  143 };
  144 
  145 static int arprobe(struct isa_device *id);
  146 static int arattach(struct isa_device *id);
  147 
  148 /*
  149  * This translate from irq numbers to
  150  * the value that the arnet card needs
  151  * in the lower part of the AR_INT_SEL
  152  * register.
  153  */
  154 static int irqtable[16] = {
  155         0,      /*  0 */
  156         0,      /*  1 */
  157         0,      /*  2 */
  158         1,      /*  3 */
  159         0,      /*  4 */
  160         2,      /*  5 */
  161         0,      /*  6 */
  162         3,      /*  7 */
  163         0,      /*  8 */
  164         0,      /*  9 */
  165         4,      /* 10 */
  166         5,      /* 11 */
  167         6,      /* 12 */
  168         0,      /* 13 */
  169         0,      /* 14 */
  170         7       /* 15 */
  171 };
  172 
  173 struct isa_driver ardriver = {arprobe, arattach, "arc"};
  174 
  175 static void ar_xmit(struct ar_softc *sc);
  176 static void arstart(struct ifnet *ifp);
  177 static int arioctl(struct ifnet *ifp, int cmd, caddr_t data);
  178 static void arwatchdog(struct ifnet *ifp);
  179 static int ar_packet_avail(struct ar_softc *sc, int *len, u_char *rxstat);
  180 static void ar_copy_rxbuf(struct mbuf *m, struct ar_softc *sc, int len);
  181 static void ar_eat_packet(struct ar_softc *sc, int single);
  182 static void ar_get_packets(struct ar_softc *sc);
  183 
  184 static void ar_up(struct ar_softc *sc);
  185 static void ar_down(struct ar_softc *sc);
  186 static void arc_init(struct isa_device *id);
  187 static void ar_init_sca(struct ar_hardc *hc, int scano);
  188 static void ar_init_msci(struct ar_softc *sc);
  189 static void ar_init_rx_dmac(struct ar_softc *sc);
  190 static void ar_init_tx_dmac(struct ar_softc *sc);
  191 static void ar_dmac_intr(struct ar_hardc *hc, int scano, u_char isr);
  192 static void ar_msci_intr(struct ar_hardc *hc, int scano, u_char isr);
  193 static void ar_timer_intr(struct ar_hardc *hc, int scano, u_char isr);
  194 
  195 /*
  196  * Register the Adapter.
  197  * Probe to see if it is there.
  198  * Get its information and fill it in.
  199  */
  200 static int
  201 arprobe(struct isa_device *id)
  202 {
  203         struct ar_hardc *hc = &ar_hardc[id->id_unit];
  204         u_int tmp;
  205         u_short port;
  206 
  207         /*
  208          * Register the card.
  209          */
  210 
  211         /*
  212          * Now see if the card is realy there.
  213          *
  214          * XXX For now I just check the undocumented ports
  215          * for "570". We will probably have to do more checking.
  216          */
  217         port = id->id_iobase;
  218 
  219         if((inb(port+AR_ID_5) != '5') || (inb(port+AR_ID_7) != '7') ||
  220            (inb(port+AR_ID_0) != ''))
  221                 return 0;
  222         /*
  223          * We have a card here, fill in what we can.
  224          */
  225         tmp = inb(port + AR_BMI);
  226         hc->bustype = tmp & AR_BUS_MSK;
  227         hc->memsize = (tmp & AR_MEM_MSK) >> AR_MEM_SHFT;
  228         hc->memsize = 1 << hc->memsize;
  229         hc->memsize <<= 16;
  230         hc->interface = (tmp & AR_IFACE_MSK);
  231         hc->revision = inb(port + AR_REV);
  232         hc->numports = inb(port + AR_PNUM);
  233         hc->handshake = inb(port + AR_HNDSH);
  234 
  235         id->id_msize = ARC_WIN_SIZ;
  236 
  237         hc->iobase = id->id_iobase;
  238         hc->mem_start = id->id_maddr;
  239         hc->mem_end = id->id_maddr + id->id_msize;
  240         hc->cunit = id->id_unit;
  241 
  242         switch(hc->interface) {
  243         case AR_IFACE_EIA_232:
  244                 printf("ar%d: The EIA 232 interface is not supported.\n",
  245                         id->id_unit);
  246                 return 0;
  247         case AR_IFACE_V_35:
  248                 break;
  249         case AR_IFACE_EIA_530:
  250                 printf("ar%d: WARNING: The EIA 530 interface is untested.\n",
  251                         id->id_unit);
  252                 break;
  253         case AR_IFACE_X_21:
  254                 break;
  255         case AR_IFACE_COMBO:
  256                 printf("ar%d: WARNING: The COMBO interface is untested.\n",
  257                         id->id_unit);
  258                 break;
  259         }
  260 
  261         if(id->id_unit == 0)
  262                 hc->startunit = 0;
  263         else
  264                 hc->startunit = ar_hardc[id->id_unit - 1].startunit +
  265                                 ar_hardc[id->id_unit - 1].numports;
  266 
  267         /*
  268          * Do a little sanity check.
  269          */
  270         if((hc->numports > NPORT) || (hc->memsize > (512*1024)))
  271                 return 0;
  272 
  273         return ARC_IO_SIZ;      /* return the amount of IO addresses used. */
  274 }
  275 
  276 
  277 /*
  278  * Malloc memory for the softc structures.
  279  * Reset the card to put it in a known state.
  280  * Register the ports on the adapter.
  281  * Fill in the info for each port.
  282  * Attach each port to sppp and bpf.
  283  */
  284 static int
  285 arattach(struct isa_device *id)
  286 {
  287         struct ar_hardc *hc = &ar_hardc[id->id_unit];
  288         struct ar_softc *sc;
  289         struct ifnet *ifp;
  290         int unit;
  291         char *iface;
  292 
  293         switch(hc->interface) {
  294         default: iface = "UNKNOWN"; break;
  295         case AR_IFACE_EIA_232: iface = "EIA-232"; break;
  296         case AR_IFACE_V_35: iface = "EIA-232 or V.35"; break;
  297         case AR_IFACE_EIA_530: iface = "EIA-530"; break;
  298         case AR_IFACE_X_21: iface = "X.21"; break;
  299         case AR_IFACE_COMBO: iface = "COMBO X.21 / EIA-530"; break;
  300         }
  301 
  302         printf("arc%d: %uK RAM, %u ports, rev %u, "
  303                 "%s interface.\n",
  304                 id->id_unit,
  305                 hc->memsize/1024,
  306                 hc->numports,
  307                 hc->revision,
  308                 iface);
  309         
  310         arc_init(id);
  311 
  312         sc = hc->sc;
  313 
  314         for(unit=0;unit<hc->numports;unit+=NCHAN)
  315                 ar_init_sca(hc, unit / NCHAN);
  316 
  317         /*
  318          * Now configure each port on the card.
  319          */
  320         for(unit=0;unit<hc->numports;sc++,unit++) {
  321                 sc->hc = hc;
  322                 sc->subunit = unit;
  323                 sc->unit = hc->startunit + unit;
  324                 sc->scano = unit / NCHAN;
  325                 sc->scachan = unit%NCHAN;
  326 
  327                 ar_init_rx_dmac(sc);
  328                 ar_init_tx_dmac(sc);
  329                 ar_init_msci(sc);
  330 
  331                 ifp = &sc->ifsppp.pp_if;
  332 
  333                 ifp->if_softc = sc;
  334                 ifp->if_unit = hc->startunit + unit;
  335                 ifp->if_name = "ar";
  336                 ifp->if_mtu = PP_MTU;
  337                 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
  338                 ifp->if_ioctl = arioctl;
  339                 ifp->if_start = arstart;
  340                 ifp->if_watchdog = arwatchdog;
  341 
  342                 sc->ifsppp.pp_flags = PP_KEEPALIVE;
  343 
  344                 printf("ar%d: Adapter %d, port %d.\n",
  345                         sc->unit,
  346                         hc->cunit,
  347                         sc->subunit);
  348 
  349                 sppp_attach((struct ifnet *)&sc->ifsppp);
  350                 if_attach(ifp);
  351 
  352 #if NBPFILTER > 0
  353                 bpfattach(ifp, DLT_PPP, PPP_HEADER_LEN);
  354 #endif
  355         }
  356 
  357         ARC_SET_OFF(hc->iobase);
  358 
  359         return 1;
  360 }
  361 
  362 /*
  363  * First figure out which SCA gave the interrupt.
  364  * Process it.
  365  * See if there is other interrupts pending.
  366  * Repeat until there is no more interrupts.
  367  */
  368 void
  369 arintr(int unit)
  370 {
  371         struct ar_hardc *hc = &ar_hardc[unit];
  372         sca_regs *sca = hc->sca;
  373         u_char isr0, isr1, isr2, arisr;
  374         int scano;
  375 
  376         arisr = inb(hc->iobase + AR_ISTAT);
  377 
  378         while(arisr & AR_BD_INT) {
  379                 if(arisr & AR_INT_0)
  380                         scano = 0;
  381                 else if(arisr & AR_INT_1)
  382                         scano = 1;
  383                 else {
  384                         /* XXX Oops this shouldn't happen. */
  385                         printf("arc%d: Interrupted with no interrupt.\n", unit);
  386                         return;
  387                 }
  388 
  389                 ARC_SET_SCA(hc->iobase, scano);
  390 
  391                 isr0 = sca->isr0;
  392                 isr1 = sca->isr1;
  393                 isr2 = sca->isr2;
  394 
  395                 TRC(printf("arc%d: ARINTR isr0 %x, isr1 %x, isr2 %x\n",
  396                         unit,
  397                         isr0,
  398                         isr1,
  399                         isr2));
  400                 if(isr0)
  401                         ar_msci_intr(hc, scano, isr0);
  402 
  403                 if(isr1)
  404                         ar_dmac_intr(hc, scano, isr1);
  405 
  406                 if(isr2)
  407                         ar_timer_intr(hc, scano, isr2);
  408 
  409                 /*
  410                  * Proccess the second sca's interrupt if available.
  411                  * Else see if there are any new interrupts.
  412                  */
  413                 if((arisr & AR_INT_0) && (arisr & AR_INT_1))
  414                         arisr &= ~AR_INT_0;
  415                 else
  416                         arisr = inb(hc->iobase + AR_ISTAT);
  417         }
  418 
  419         ARC_SET_OFF(hc->iobase);
  420 }
  421 
  422 
  423 /*
  424  * This will only start the transmitter. It is assumed that the data
  425  * is already there. It is normally called from arstart() or ar_dmac_intr().
  426  *
  427  */
  428 static void
  429 ar_xmit(struct ar_softc *sc)
  430 {
  431         struct ifnet *ifp = &sc->ifsppp.pp_if;
  432         dmac_channel *dmac = &sc->hc->sca->dmac[DMAC_TXCH(sc->scachan)];
  433 
  434         ARC_SET_SCA(sc->hc->iobase, sc->scano);
  435         dmac->cda = (u_short)(sc->block[sc->txb_next_tx].txdesc & 0xffff);
  436 
  437         dmac->eda = (u_short)(sc->block[sc->txb_next_tx].txeda & 0xffff);
  438         dmac->dsr = SCA_DSR_DE;
  439 
  440         sc->xmit_busy = 1;
  441 
  442         sc->txb_next_tx++;
  443         if(sc->txb_next_tx == AR_TX_BLOCKS)
  444                 sc->txb_next_tx = 0;
  445 
  446         ifp->if_timer = 2; /* Value in seconds. */
  447         ARC_SET_OFF(sc->hc->iobase);
  448 }
  449 
  450 /*
  451  * This function will be called from the upper level when a user add a
  452  * packet to be send, and from the interrupt handler after a finished
  453  * transmit.
  454  *
  455  * NOTE: it should run at spl_imp().
  456  *
  457  * This function only place the data in the oncard buffers. It does not
  458  * start the transmition. ar_xmit() does that.
  459  *
  460  * Transmitter idle state is indicated by the IFF_OACTIVE flag. The function
  461  * that clears that should ensure that the transmitter and it's DMA is
  462  * in a "good" idle state.
  463  */
  464 static void
  465 arstart(struct ifnet *ifp)
  466 {
  467         struct ar_softc *sc = ifp->if_softc;
  468         int i, len, tlen;
  469         struct mbuf *mtx;
  470         u_char *txdata;
  471         sca_descriptor *txdesc;
  472         struct buf_block *blkp;
  473 
  474         if(!(ifp->if_flags & IFF_RUNNING))
  475                 return;
  476   
  477 top_arstart:
  478 
  479         /*
  480          * See if we have space for more packets.
  481          */
  482         if(sc->txb_inuse == AR_TX_BLOCKS) {
  483                 ifp->if_flags |= IFF_OACTIVE;
  484                 return;
  485         }
  486 
  487         mtx = sppp_dequeue(ifp);
  488         if(!mtx)
  489                 return;
  490 
  491         /*
  492          * It is OK to set the memory window outside the loop because
  493          * all tx buffers and descriptors are assumed to be in the same
  494          * 16K window.
  495          */
  496         ARC_SET_MEM(sc->hc->iobase, sc->block[0].txdesc);
  497 
  498         /*
  499          * We stay in this loop until there is nothing in the
  500          * TX queue left or the tx buffer is full.
  501          */
  502         i = 0;
  503         blkp = &sc->block[sc->txb_new];
  504         txdesc = (sca_descriptor *)
  505                 (sc->hc->mem_start + (blkp->txdesc & ARC_WIN_MSK));
  506         txdata = (u_char *)(sc->hc->mem_start + (blkp->txstart & ARC_WIN_MSK));
  507         for(;;) {
  508                 len = mtx->m_pkthdr.len;
  509 
  510                 TRC(printf("ar%d: ARstart len %u\n", sc->unit, len));
  511 
  512                 /*
  513                  * We can do this because the tx buffers don't wrap.
  514                  */
  515                 m_copydata(mtx, 0, len, txdata);
  516                 tlen = len;
  517                 while(tlen > AR_BUF_SIZ) {
  518                         txdesc->stat = 0;
  519                         txdesc->len = AR_BUF_SIZ;
  520                         tlen -= AR_BUF_SIZ;
  521                         txdesc++;
  522                         txdata += AR_BUF_SIZ;
  523                         i++;
  524                 }
  525                 /* XXX Move into the loop? */
  526                 txdesc->stat = SCA_DESC_EOM;
  527                 txdesc->len = tlen;
  528                 txdesc++;
  529                 txdata += AR_BUF_SIZ;
  530                 i++;
  531 
  532 #if NBPFILTER > 0
  533                 if(ifp->if_bpf)
  534                         bpf_mtap(ifp, mtx);
  535 #endif
  536                 m_freem(mtx);
  537                 ++sc->ifsppp.pp_if.if_opackets;
  538 
  539                 /*
  540                  * Check if we have space for another mbuf.
  541                  * XXX This is hardcoded. A packet won't be larger
  542                  * than 3 buffers (3 x 512).
  543                  */
  544                 if((i + 3) >= blkp->txmax)
  545                         break;
  546 
  547                 mtx = sppp_dequeue(ifp);
  548                 if(!mtx)
  549                         break;
  550         }
  551 
  552         blkp->txtail = i;
  553 
  554         /*
  555          * Mark the last descriptor, so that the SCA know where
  556          * to stop.
  557          */
  558         txdesc--;
  559         txdesc->stat |= SCA_DESC_EOT;
  560 
  561         txdesc = (sca_descriptor *)blkp->txdesc;
  562         blkp->txeda = (u_short)((u_int)&txdesc[i]);
  563 
  564 #if 0
  565         printf("ARstart: %p desc->cp %x\n", &txdesc->cp, txdesc->cp);
  566         printf("ARstart: %p desc->bp %x\n", &txdesc->bp, txdesc->bp);
  567         printf("ARstart: %p desc->bpb %x\n", &txdesc->bpb, txdesc->bpb);
  568         printf("ARstart: %p desc->len %x\n", &txdesc->len, txdesc->len);
  569         printf("ARstart: %p desc->stat %x\n", &txdesc->stat, txdesc->stat);
  570 #endif
  571 
  572         sc->txb_inuse++;
  573         sc->txb_new++;
  574         if(sc->txb_new == AR_TX_BLOCKS)
  575                 sc->txb_new = 0;
  576 
  577         if(sc->xmit_busy == 0)
  578                 ar_xmit(sc);
  579 
  580         ARC_SET_OFF(sc->hc->iobase);
  581 
  582         goto top_arstart;
  583 }
  584 
  585 static int
  586 arioctl(struct ifnet *ifp, int cmd, caddr_t data)
  587 {
  588         int s, error;
  589         int was_up, should_be_up;
  590         struct sppp *sp = (struct sppp *)ifp;
  591         struct ar_softc *sc = ifp->if_softc;
  592 
  593         TRC(printf("ar%d: arioctl.\n", ifp->if_unit);)
  594 
  595         if(cmd == SIOCSIFFLAGS) {
  596                 if(ifp->if_flags & IFF_LINK2)
  597                         sp->pp_flags |= PP_CISCO;
  598                 else
  599                         sp->pp_flags &= ~PP_CISCO;
  600         }
  601 
  602         was_up = ifp->if_flags & IFF_RUNNING;
  603 
  604         error = sppp_ioctl(ifp, cmd, data);
  605         TRC(printf("ar%d: ioctl: ifsppp.pp_flags = %x, if_flags %x.\n", 
  606                 ifp->if_unit, ((struct sppp *)ifp)->pp_flags, ifp->if_flags);)
  607         if(error)
  608                 return error;
  609 
  610         if((cmd != SIOCSIFFLAGS) && cmd != (SIOCSIFADDR))
  611                 return 0;
  612 
  613         TRC(printf("ar%d: arioctl %s.\n", ifp->if_unit, 
  614                 (cmd == SIOCSIFFLAGS) ? "SIOCSIFFLAGS" : "SIOCSIFADDR");)
  615 
  616         s = splimp();
  617         should_be_up = ifp->if_flags & IFF_RUNNING;
  618 
  619         if(!was_up && should_be_up) {
  620                 /* Interface should be up -- start it. */
  621                 ar_up(sc);
  622                 arstart(ifp);
  623                 /* XXX Maybe clear the IFF_UP flag so that the link
  624                  * will only go up after sppp lcp and ipcp negotiation.
  625                  */
  626         } else if(was_up && !should_be_up) {
  627                 /* Interface should be down -- stop it. */
  628                 ar_down(sc);
  629                 sppp_flush(ifp);
  630         }
  631         splx(s);
  632         return 0;
  633 }
  634 
  635 /*
  636  * This is to catch lost tx interrupts.
  637  */
  638 static void
  639 arwatchdog(struct ifnet *ifp)
  640 {
  641         struct ar_softc *sc = ifp->if_softc;
  642         msci_channel *msci = &sc->hc->sca->msci[sc->scachan];
  643 
  644         if(!(ifp->if_flags & IFF_RUNNING))
  645                 return;
  646 
  647         ARC_SET_SCA(sc->hc->iobase, sc->scano);
  648 
  649         /* XXX if(sc->ifsppp.pp_if.if_flags & IFF_DEBUG) */
  650                 printf("ar%d: transmit failed, "
  651                         "ST0 %x, ST1 %x, ST3 %x, DSR %x.\n",
  652                         ifp->if_unit,
  653                         msci->st0,
  654                         msci->st1,
  655                         msci->st3,
  656                         sc->hc->sca->dmac[DMAC_TXCH(sc->scachan)].dsr);
  657 
  658         if(msci->st1 & SCA_ST1_UDRN) {
  659                 msci->cmd = SCA_CMD_TXABORT;
  660                 msci->cmd = SCA_CMD_TXENABLE;
  661                 msci->st1 = SCA_ST1_UDRN;
  662         }
  663 
  664         sc->xmit_busy = 0;
  665         ifp->if_flags &= ~IFF_OACTIVE;
  666 
  667         if(sc->txb_inuse && --sc->txb_inuse)
  668                 ar_xmit(sc);
  669 
  670         arstart(ifp);
  671 }
  672 
  673 static void
  674 ar_up(struct ar_softc *sc)
  675 {
  676         sca_regs *sca = sc->hc->sca;
  677         msci_channel *msci = &sca->msci[sc->scachan];
  678 
  679         TRC(printf("ar%d: sca %p, msci %p, ch %d\n",
  680                 sc->unit, sca, msci, sc->scachan));
  681 
  682         /*
  683          * Enable transmitter and receiver.
  684          * Raise DTR and RTS.
  685          * Enable interrupts.
  686          */
  687         ARC_SET_SCA(sc->hc->iobase, sc->scano);
  688 
  689         /* XXX
  690          * What about using AUTO mode in msci->md0 ???
  691          * And what about CTS/DCD etc... ?
  692          */
  693         if(sc->hc->handshake & AR_SHSK_RTS)
  694                 msci->ctl &= ~SCA_CTL_RTS;
  695         if(sc->hc->handshake & AR_SHSK_DTR) {
  696                 sc->hc->txc_dtr[sc->scano] &= sc->scachan ? 
  697                         ~AR_TXC_DTR_DTR1 : ~AR_TXC_DTR_DTR0;
  698                 outb(sc->hc->iobase + sc->hc->txc_dtr_off[sc->scano],
  699                         sc->hc->txc_dtr[sc->scano]);
  700         }
  701 
  702         if(sc->scachan == 0) {
  703                 sca->ier0 |= 0x0F;
  704                 sca->ier1 |= 0x0F;
  705         } else {
  706                 sca->ier0 |= 0xF0;
  707                 sca->ier1 |= 0xF0;
  708         }
  709 
  710         msci->cmd = SCA_CMD_RXENABLE;
  711         inb(sc->hc->iobase + AR_ID_5); /* XXX slow it down a bit. */
  712         msci->cmd = SCA_CMD_TXENABLE;
  713 
  714         ARC_SET_OFF(sc->hc->iobase);
  715 }
  716 
  717 static void
  718 ar_down(struct ar_softc *sc)
  719 {
  720         sca_regs *sca = sc->hc->sca;
  721         msci_channel *msci = &sca->msci[sc->scachan];
  722 
  723         /*
  724          * Disable transmitter and receiver.
  725          * Lower DTR and RTS.
  726          * Disable interrupts.
  727          */
  728         ARC_SET_SCA(sc->hc->iobase, sc->scano);
  729         msci->cmd = SCA_CMD_RXDISABLE;
  730         inb(sc->hc->iobase + AR_ID_5); /* XXX slow it down a bit. */
  731         msci->cmd = SCA_CMD_TXDISABLE;
  732 
  733         if(sc->hc->handshake & AR_SHSK_RTS)
  734                 msci->ctl |= SCA_CTL_RTS;
  735         if(sc->hc->handshake & AR_SHSK_DTR) {
  736                 sc->hc->txc_dtr[sc->scano] |= sc->scachan ? 
  737                         AR_TXC_DTR_DTR1 : AR_TXC_DTR_DTR0;
  738                 outb(sc->hc->iobase + sc->hc->txc_dtr_off[sc->scano],
  739                         sc->hc->txc_dtr[sc->scano]);
  740         }
  741 
  742         if(sc->scachan == 0) {
  743                 sca->ier0 &= ~0x0F;
  744                 sca->ier1 &= ~0x0F;
  745         } else {
  746                 sca->ier0 &= ~0xF0;
  747                 sca->ier1 &= ~0xF0;
  748         }
  749 
  750         ARC_SET_OFF(sc->hc->iobase);
  751 }
  752 
  753 /*
  754  * Initialize the card, allocate memory for the ar_softc structures
  755  * and fill in the pointers.
  756  */
  757 static void
  758 arc_init(struct isa_device *id)
  759 {
  760         struct ar_hardc *hc = &ar_hardc[id->id_unit];
  761         struct ar_softc *sc;
  762         int x;
  763         u_int chanmem;
  764         u_int bufmem;
  765         u_int next;
  766         u_int descneeded;
  767         u_char isr, mar;
  768 
  769         sc = hc->sc = malloc(hc->numports * sizeof(struct ar_softc),
  770                                 M_DEVBUF, M_WAITOK);
  771         bzero(sc, hc->numports * sizeof(struct ar_softc));
  772 
  773         hc->txc_dtr[0] = AR_TXC_DTR_NOTRESET |
  774                          AR_TXC_DTR_DTR0 | AR_TXC_DTR_DTR1;
  775         hc->txc_dtr[1] = AR_TXC_DTR_DTR0 | AR_TXC_DTR_DTR1;
  776         hc->txc_dtr_off[0] = AR_TXC_DTR0;
  777         hc->txc_dtr_off[1] = AR_TXC_DTR2;
  778 
  779         /*
  780          * reset the card and wait at least 1uS.
  781          */
  782         outb(hc->iobase + AR_TXC_DTR0, ~AR_TXC_DTR_NOTRESET & hc->txc_dtr[0]);
  783         DELAY(2);
  784         outb(hc->iobase + AR_TXC_DTR0, hc->txc_dtr[0]);
  785 
  786         /*
  787          * Configure the card.
  788          * Mem address, irq, 
  789          */
  790         mar = kvtop(id->id_maddr) >> 16;
  791         isr = irqtable[ffs(id->id_irq) - 1] << 1;
  792         if(isr == 0)
  793                 printf("ar%d: Warning illegal interrupt %d\n",
  794                         id->id_unit, ffs(id->id_irq) - 1);
  795         isr = isr | ((kvtop(id->id_maddr) & 0xc000) >> 10);
  796 
  797         hc->sca = (sca_regs *)hc->mem_start;
  798 
  799         outb(hc->iobase + AR_MEM_SEL, mar);
  800         outb(hc->iobase + AR_INT_SEL, isr | AR_INTS_CEN);
  801 
  802         /*
  803          * Set the TX clock direction and enable TX.
  804          */
  805         switch(hc->interface) {
  806         case AR_IFACE_V_35:
  807                 hc->txc_dtr[0] |= AR_TXC_DTR_TX0 | AR_TXC_DTR_TX1 |
  808                                   AR_TXC_DTR_TXCS0 | AR_TXC_DTR_TXCS1;
  809                 hc->txc_dtr[1] |= AR_TXC_DTR_TX0 | AR_TXC_DTR_TX1 |
  810                                   AR_TXC_DTR_TXCS0 | AR_TXC_DTR_TXCS1;
  811                 break;
  812         case AR_IFACE_EIA_530:
  813         case AR_IFACE_COMBO:
  814         case AR_IFACE_X_21:
  815                 hc->txc_dtr[0] |= AR_TXC_DTR_TX0 | AR_TXC_DTR_TX1;
  816                 hc->txc_dtr[1] |= AR_TXC_DTR_TX0 | AR_TXC_DTR_TX1;
  817         }
  818         outb(hc->iobase + AR_TXC_DTR0, hc->txc_dtr[0]);
  819         if(hc->numports > NCHAN)
  820                 outb(hc->iobase + AR_TXC_DTR2, hc->txc_dtr[1]);
  821 
  822         chanmem = hc->memsize / hc->numports;
  823         next = 0;
  824 
  825         for(x=0;x<hc->numports;x++, sc++) {
  826                 int blk;
  827 
  828                 for(blk = 0; blk < AR_TX_BLOCKS; blk++) {
  829                         sc->block[blk].txdesc = next;
  830                         bufmem = (16 * 1024) / AR_TX_BLOCKS;
  831                         descneeded = bufmem / AR_BUF_SIZ;
  832                         sc->block[blk].txstart = sc->block[blk].txdesc +
  833                                 ((((descneeded * sizeof(sca_descriptor)) /
  834                                         AR_BUF_SIZ) + 1) * AR_BUF_SIZ);
  835                         sc->block[blk].txend = next + bufmem;
  836                         sc->block[blk].txmax =
  837                                 (sc->block[blk].txend - sc->block[blk].txstart)
  838                                 / AR_BUF_SIZ;
  839                         next += bufmem;
  840 
  841                         TRC(printf("ar%d: blk %d: txdesc %x, txstart %x, "
  842                                    "txend %x, txmax %d\n",
  843                                    x,
  844                                    blk,
  845                                    sc->block[blk].txdesc,
  846                                    sc->block[blk].txstart,
  847                                    sc->block[blk].txend,
  848                                    sc->block[blk].txmax));
  849                 }
  850 
  851                 sc->rxdesc = next;
  852                 bufmem = chanmem - (bufmem * AR_TX_BLOCKS);
  853                 descneeded = bufmem / AR_BUF_SIZ;
  854                 sc->rxstart = sc->rxdesc +
  855                                 ((((descneeded * sizeof(sca_descriptor)) /
  856                                         AR_BUF_SIZ) + 1) * AR_BUF_SIZ);
  857                 sc->rxend = next + bufmem;
  858                 sc->rxmax = (sc->rxend - sc->rxstart) / AR_BUF_SIZ;
  859                 next += bufmem;
  860         }
  861 }
  862 
  863 
  864 /*
  865  * The things done here are channel independent.
  866  *
  867  *   Configure the sca waitstates.
  868  *   Configure the global interrupt registers.
  869  *   Enable master dma enable.
  870  */
  871 static void
  872 ar_init_sca(struct ar_hardc *hc, int scano)
  873 {
  874         sca_regs *sca = hc->sca;
  875 
  876         ARC_SET_SCA(hc->iobase, scano);
  877 
  878         /*
  879          * Do the wait registers.
  880          * Set everything to 0 wait states.
  881          */
  882         sca->pabr0 = 0;
  883         sca->pabr1 = 0;
  884         sca->wcrl  = 0;
  885         sca->wcrm  = 0;
  886         sca->wcrh  = 0;
  887 
  888         /*
  889          * Configure the interrupt registers.
  890          * Most are cleared until the interface is configured.
  891          */
  892         sca->ier0 = 0x00; /* MSCI interrupts... Not used with dma. */
  893         sca->ier1 = 0x00; /* DMAC interrupts */
  894         sca->ier2 = 0x00; /* TIMER interrupts... Not used yet. */
  895         sca->itcr = 0x00; /* Use ivr and no intr ack */
  896         sca->ivr  = 0x40; /* Fill in the interrupt vector. */
  897         sca->imvr = 0x40;
  898 
  899         /*
  900          * Configure the timers.
  901          * XXX Later
  902          */
  903 
  904 
  905         /*
  906          * Set the DMA channel priority to rotate between
  907          * all four channels.
  908          *
  909          * Enable all dma channels.
  910          */
  911         sca->pcr = SCA_PCR_PR2;
  912         sca->dmer = SCA_DMER_EN;
  913 }
  914 
  915 
  916 /*
  917  * Configure the msci
  918  *
  919  * NOTE: The serial port configuration is hardcoded at the moment.
  920  */
  921 static void
  922 ar_init_msci(struct ar_softc *sc)
  923 {
  924         msci_channel *msci = &sc->hc->sca->msci[sc->scachan];
  925 
  926         ARC_SET_SCA(sc->hc->iobase, sc->scano);
  927 
  928         msci->cmd = SCA_CMD_RESET;
  929 
  930         msci->md0 = SCA_MD0_CRC_1 |
  931                     SCA_MD0_CRC_CCITT |
  932                     SCA_MD0_CRC_ENABLE |
  933                     SCA_MD0_MODE_HDLC;
  934         msci->md1 = SCA_MD1_NOADDRCHK;
  935         msci->md2 = SCA_MD2_DUPLEX | SCA_MD2_NRZ;
  936 
  937         /*
  938          * Acording to the manual I should give a reset after changing the
  939          * mode registers.
  940          */
  941         msci->cmd = SCA_CMD_RXRESET;
  942         msci->ctl = SCA_CTL_IDLPAT | SCA_CTL_UDRNC | SCA_CTL_RTS;
  943 
  944         /*
  945          * For now all interfaces are programmed to use the RX clock for
  946          * the TX clock.
  947          */
  948         switch(sc->hc->interface) {
  949         case AR_IFACE_V_35:
  950                 msci->rxs = SCA_RXS_CLK_RXC0 | SCA_RXS_DIV1;
  951                 msci->txs = SCA_TXS_CLK_TXC | SCA_TXS_DIV1;
  952                 break;
  953         case AR_IFACE_X_21:
  954         case AR_IFACE_EIA_530:
  955         case AR_IFACE_COMBO:
  956                 msci->rxs = SCA_RXS_CLK_RXC0 | SCA_RXS_DIV1;
  957                 msci->txs = SCA_TXS_CLK_RX | SCA_TXS_DIV1;
  958         }
  959 
  960         msci->tmc = 153;   /* This give 64k for loopback */
  961 
  962         /* XXX
  963          * Disable all interrupts for now. I think if you are using
  964          * the dmac you don't use these interrupts.
  965          */
  966         msci->ie0 = 0;
  967         msci->ie1 = 0x0C; /* XXX CTS and DCD (DSR on 570I) level change. */
  968         msci->ie2 = 0;
  969         msci->fie = 0;
  970 
  971         msci->sa0 = 0;
  972         msci->sa1 = 0;
  973 
  974         msci->idl = 0x7E; /* XXX This is what cisco does. */
  975 
  976         /*
  977          * This is what the ARNET diags use.
  978          */
  979         msci->rrc  = 0x0E;
  980         msci->trc0 = 0x12;
  981         msci->trc1 = 0x1F;
  982 }
  983 
  984 /*
  985  * Configure the rx dma controller.
  986  */
  987 static void
  988 ar_init_rx_dmac(struct ar_softc *sc)
  989 {
  990         dmac_channel *dmac = &sc->hc->sca->dmac[DMAC_RXCH(sc->scachan)];
  991         sca_descriptor *rxd;
  992         u_int rxbuf;
  993         u_int rxda;
  994         u_int rxda_d;
  995 
  996         ARC_SET_MEM(sc->hc->iobase, sc->rxdesc);
  997 
  998         rxd = (sca_descriptor *)(sc->hc->mem_start + (sc->rxdesc&ARC_WIN_MSK));
  999         rxda_d = (u_int)sc->hc->mem_start - (sc->rxdesc & ~ARC_WIN_MSK);
 1000 
 1001         for(rxbuf=sc->rxstart;rxbuf<sc->rxend;rxbuf += AR_BUF_SIZ, rxd++) {
 1002                 rxda = (u_int)&rxd[1] - rxda_d;
 1003                 rxd->cp = (u_short)(rxda & 0xfffful);
 1004 
 1005                 TRC(printf("Descrp %p, data pt %p, data long %lx, ",
 1006                         &sc->rxdesc[x], rxinuse->buf, rxbuf));
 1007 
 1008                 rxd->bp = (u_short)(rxbuf & 0xfffful);
 1009                 rxd->bpb = (u_char)((rxbuf >> 16) & 0xff);
 1010                 rxd->len = 0;
 1011                 rxd->stat = 0xff; /* The sca write here when it is finished. */
 1012 
 1013                 TRC(printf("bpb %x, bp %x.\n", rxd->bpb, rxd->bp));
 1014         }
 1015         rxd--;
 1016         rxd->cp = (u_short)(sc->rxdesc & 0xfffful);
 1017 
 1018         sc->rxhind = 0;
 1019 
 1020         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1021 
 1022         dmac->dsr = 0;    /* Disable DMA transfer */
 1023         dmac->dcr = SCA_DCR_ABRT;
 1024 
 1025         /* XXX maybe also SCA_DMR_CNTE */
 1026         dmac->dmr = SCA_DMR_TMOD | SCA_DMR_NF;
 1027         dmac->bfl = AR_BUF_SIZ;
 1028 
 1029         dmac->cda = (u_short)(sc->rxdesc & 0xffff);
 1030         dmac->sarb = (u_char)((sc->rxdesc >> 16) & 0xff);
 1031 
 1032         rxd = (sca_descriptor *)sc->rxstart;
 1033         dmac->eda = (u_short)((u_int)&rxd[sc->rxmax - 1] & 0xffff);
 1034 
 1035         dmac->dir = 0xF0;
 1036 
 1037         dmac->dsr = SCA_DSR_DE;
 1038 }
 1039 
 1040 /*
 1041  * Configure the TX DMA descriptors.
 1042  * Initialize the needed values and chain the descriptors.
 1043  */
 1044 static void
 1045 ar_init_tx_dmac(struct ar_softc *sc)
 1046 {
 1047         dmac_channel *dmac = &sc->hc->sca->dmac[DMAC_TXCH(sc->scachan)];
 1048         struct buf_block *blkp;
 1049         int blk;
 1050         sca_descriptor *txd;
 1051         u_int txbuf;
 1052         u_int txda;
 1053         u_int txda_d;
 1054 
 1055         ARC_SET_MEM(sc->hc->iobase, sc->block[0].txdesc);
 1056 
 1057         for(blk = 0; blk < AR_TX_BLOCKS; blk++) {
 1058                 blkp = &sc->block[blk];
 1059                 txd = (sca_descriptor *)(sc->hc->mem_start +
 1060                                         (blkp->txdesc&ARC_WIN_MSK));
 1061                 txda_d = (u_int)sc->hc->mem_start -
 1062                                 (blkp->txdesc & ~ARC_WIN_MSK);
 1063 
 1064                 txbuf=blkp->txstart;
 1065                 for(;txbuf<blkp->txend;txbuf += AR_BUF_SIZ, txd++) {
 1066                         txda = (u_int)&txd[1] - txda_d;
 1067                         txd->cp = (u_short)(txda & 0xfffful);
 1068 
 1069                         txd->bp = (u_short)(txbuf & 0xfffful);
 1070                         txd->bpb = (u_char)((txbuf >> 16) & 0xff);
 1071                         TRC(printf("ar%d: txbuf %x, bpb %x, bp %x\n",
 1072                                 sc->unit, txbuf, txd->bpb, txd->bp));
 1073                         txd->len = 0;
 1074                         txd->stat = 0;
 1075                 }
 1076                 txd--;
 1077                 txd->cp = (u_short)(blkp->txdesc & 0xfffful);
 1078 
 1079                 blkp->txtail = (u_int)txd - (u_int)sc->hc->mem_start;
 1080                 TRC(printf("TX Descriptors start %x, end %x.\n",
 1081                         blkp->txhead,
 1082                         blkp->txtail));
 1083         }
 1084 
 1085         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1086 
 1087         dmac->dsr = 0; /* Disable DMA */
 1088         dmac->dcr = SCA_DCR_ABRT;
 1089         dmac->dmr = SCA_DMR_TMOD | SCA_DMR_NF;
 1090         dmac->dir = SCA_DIR_EOT | SCA_DIR_BOF | SCA_DIR_COF;
 1091 
 1092         dmac->sarb = (u_char)((sc->block[0].txdesc >> 16) & 0xff);
 1093 }
 1094 
 1095 
 1096 /*
 1097  * Look through the descriptors to see if there is a complete packet
 1098  * available. Stop if we get to where the sca is busy.
 1099  *
 1100  * Return the length and status of the packet.
 1101  * Return nonzero if there is a packet available.
 1102  *
 1103  * NOTE:
 1104  * It seems that we get the interrupt a bit early. The updateing of
 1105  * descriptor values is not always completed when this is called.
 1106  */
 1107 static int
 1108 ar_packet_avail(struct ar_softc *sc,
 1109                     int *len,
 1110                     u_char *rxstat)
 1111 {
 1112         sca_descriptor *rxdesc;
 1113         sca_descriptor *endp;
 1114         sca_descriptor *cda;
 1115 
 1116         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1117         cda = (sca_descriptor *)(sc->hc->mem_start +
 1118               (sc->hc->sca->dmac[DMAC_RXCH(sc->scachan)].cda &  ARC_WIN_MSK));
 1119 
 1120         ARC_SET_MEM(sc->hc->iobase, sc->rxdesc);
 1121         rxdesc = (sca_descriptor *)
 1122                         (sc->hc->mem_start + (sc->rxdesc & ARC_WIN_MSK));
 1123         endp = rxdesc;
 1124         rxdesc = &rxdesc[sc->rxhind];
 1125         endp = &endp[sc->rxmax];
 1126 
 1127         *len = 0;
 1128 
 1129         while(rxdesc != cda) {
 1130                 *len += rxdesc->len;
 1131 
 1132                 if(rxdesc->stat & SCA_DESC_EOM) {
 1133                         *rxstat = rxdesc->stat;
 1134                         TRC(printf("ar%d: PKT AVAIL len %d, %x, bufs %u.\n",
 1135                                 sc->unit, *len, *rxstat, x));
 1136                         return 1;
 1137                 }
 1138 
 1139                 rxdesc++;
 1140                 if(rxdesc == endp)
 1141                         rxdesc = (sca_descriptor *)
 1142                                (sc->hc->mem_start + (sc->rxdesc & ARC_WIN_MSK));
 1143         }
 1144 
 1145         *len = 0;
 1146         *rxstat = 0;
 1147         return 0;
 1148 }
 1149 
 1150 
 1151 /*
 1152  * Copy a packet from the on card memory into a provided mbuf.
 1153  * Take into account that buffers wrap and that a packet may
 1154  * be larger than a buffer.
 1155  */
 1156 static void 
 1157 ar_copy_rxbuf(struct mbuf *m,
 1158                    struct ar_softc *sc,
 1159                    int len)
 1160 {
 1161         sca_descriptor *rxdesc;
 1162         u_int rxdata;
 1163         u_int rxmax;
 1164         u_int off = 0;
 1165         u_int tlen;
 1166 
 1167         rxdata = sc->rxstart + (sc->rxhind * AR_BUF_SIZ);
 1168         rxmax = sc->rxstart + (sc->rxmax * AR_BUF_SIZ);
 1169 
 1170         rxdesc = (sca_descriptor *)
 1171                         (sc->hc->mem_start + (sc->rxdesc & ARC_WIN_MSK));
 1172         rxdesc = &rxdesc[sc->rxhind];
 1173 
 1174         while(len) {
 1175                 tlen = (len < AR_BUF_SIZ) ? len : AR_BUF_SIZ;
 1176                 ARC_SET_MEM(sc->hc->iobase, rxdata);
 1177                 bcopy(sc->hc->mem_start + (rxdata & ARC_WIN_MSK), 
 1178                         mtod(m, caddr_t) + off,
 1179                         tlen);
 1180 
 1181                 off += tlen;
 1182                 len -= tlen;
 1183 
 1184                 ARC_SET_MEM(sc->hc->iobase, sc->rxdesc);
 1185                 rxdesc->len = 0;
 1186                 rxdesc->stat = 0xff;
 1187 
 1188                 rxdata += AR_BUF_SIZ;
 1189                 rxdesc++;
 1190                 if(rxdata == rxmax) {
 1191                         rxdata = sc->rxstart;
 1192                         rxdesc = (sca_descriptor *)
 1193                                 (sc->hc->mem_start + (sc->rxdesc & ARC_WIN_MSK));
 1194                 }
 1195         }
 1196 }
 1197 
 1198 /*
 1199  * If single is set, just eat a packet. Otherwise eat everything up to
 1200  * where cda points. Update pointers to point to the next packet.
 1201  */
 1202 static void
 1203 ar_eat_packet(struct ar_softc *sc, int single)
 1204 {
 1205         sca_descriptor *rxdesc;
 1206         sca_descriptor *endp;
 1207         sca_descriptor *cda;
 1208         int loopcnt = 0;
 1209         u_char stat;
 1210 
 1211         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1212         cda = (sca_descriptor *)(sc->hc->mem_start +
 1213               (sc->hc->sca->dmac[DMAC_RXCH(sc->scachan)].cda &  ARC_WIN_MSK));
 1214 
 1215         /*
 1216          * Loop until desc->stat == (0xff || EOM)
 1217          * Clear the status and length in the descriptor.
 1218          * Increment the descriptor.
 1219          */
 1220         ARC_SET_MEM(sc->hc->iobase, sc->rxdesc);
 1221         rxdesc = (sca_descriptor *)
 1222                 (sc->hc->mem_start + (sc->rxdesc & ARC_WIN_MSK));
 1223         endp = rxdesc;
 1224         rxdesc = &rxdesc[sc->rxhind];
 1225         endp = &endp[sc->rxmax];
 1226 
 1227         while(rxdesc != cda) {
 1228                 loopcnt++;
 1229                 if(loopcnt > sc->rxmax) {
 1230                         printf("ar%d: eat pkt %d loop, cda %x, "
 1231                                "rxdesc %x, stat %x.\n",
 1232                                sc->unit,
 1233                                loopcnt,
 1234                                cda,
 1235                                rxdesc,
 1236                                rxdesc->stat);
 1237                         break;
 1238                 }
 1239 
 1240                 stat = rxdesc->stat;
 1241 
 1242                 rxdesc->len = 0;
 1243                 rxdesc->stat = 0xff;
 1244 
 1245                 rxdesc++;
 1246                 sc->rxhind++;
 1247                 if(rxdesc == endp) {
 1248                         rxdesc = (sca_descriptor *)
 1249                                (sc->hc->mem_start + (sc->rxdesc & ARC_WIN_MSK));
 1250                         sc->rxhind = 0;
 1251                 }
 1252 
 1253                 if(single && (stat == SCA_DESC_EOM))
 1254                         break;
 1255         }
 1256 
 1257         /*
 1258          * Update the eda to the previous descriptor.
 1259          */
 1260         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1261 
 1262         rxdesc = (sca_descriptor *)sc->rxdesc;
 1263         rxdesc = &rxdesc[(sc->rxhind + sc->rxmax - 2 ) % sc->rxmax];
 1264 
 1265         sc->hc->sca->dmac[DMAC_RXCH(sc->scachan)].eda = 
 1266                         (u_short)((u_int)rxdesc & 0xffff);
 1267 }
 1268 
 1269 
 1270 /*
 1271  * While there is packets available in the rx buffer, read them out
 1272  * into mbufs and ship them off.
 1273  */
 1274 static void
 1275 ar_get_packets(struct ar_softc *sc)
 1276 {
 1277         sca_descriptor *rxdesc;
 1278         struct mbuf *m = NULL;
 1279         int i;
 1280         int len;
 1281         u_char rxstat;
 1282 
 1283         while(ar_packet_avail(sc, &len, &rxstat)) {
 1284                 if(((rxstat & SCA_DESC_ERRORS) == 0) && (len < MCLBYTES)) {
 1285                         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1286                         if(m == NULL) {
 1287                                 /* eat packet if get mbuf fail!! */
 1288                                 ar_eat_packet(sc, 1);
 1289                                 continue;
 1290                         }
 1291                         m->m_pkthdr.rcvif = &sc->ifsppp.pp_if;
 1292                         m->m_pkthdr.len = m->m_len = len;
 1293                         if(len > MHLEN) {
 1294                                 MCLGET(m, M_DONTWAIT);
 1295                                 if((m->m_flags & M_EXT) == 0) {
 1296                                         m_freem(m);
 1297                                         ar_eat_packet(sc, 1);
 1298                                         continue;
 1299                                 }
 1300                         }
 1301                         ar_copy_rxbuf(m, sc, len);
 1302 #if NBPFILTER > 0
 1303                         if(sc->ifsppp.pp_if.if_bpf)
 1304                                 bpf_mtap(&sc->ifsppp.pp_if, m);
 1305 #endif
 1306                         sppp_input(&sc->ifsppp.pp_if, m);
 1307                         sc->ifsppp.pp_if.if_ipackets++;
 1308 
 1309                         /*
 1310                          * Update the eda to the previous descriptor.
 1311                          */
 1312                         i = (len + AR_BUF_SIZ - 1) / AR_BUF_SIZ;
 1313                         sc->rxhind = (sc->rxhind + i) % sc->rxmax;
 1314 
 1315                         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1316 
 1317                         rxdesc = (sca_descriptor *)sc->rxdesc;
 1318                         rxdesc =
 1319                              &rxdesc[(sc->rxhind + sc->rxmax - 2 ) % sc->rxmax];
 1320 
 1321                         sc->hc->sca->dmac[DMAC_RXCH(sc->scachan)].eda = 
 1322                                 (u_short)((u_int)rxdesc & 0xffff);
 1323                 } else {
 1324                         int tries = 5;
 1325 
 1326                         while((rxstat == 0xff) && --tries)
 1327                                 ar_packet_avail(sc, &len, &rxstat);
 1328 
 1329                         /*
 1330                          * It look like we get an interrupt early
 1331                          * sometimes and then the status is not
 1332                          * filled in yet.
 1333                          */
 1334                         if(tries && (tries != 5))
 1335                                 continue;
 1336 
 1337                         ar_eat_packet(sc, 1);
 1338 
 1339                         sc->ifsppp.pp_if.if_ierrors++;
 1340 
 1341                         ARC_SET_SCA(sc->hc->iobase, sc->scano);
 1342 
 1343                         TRCL(printf("ar%d: Receive error chan %d, "
 1344                                         "stat %x, msci st3 %x,"
 1345                                         "rxhind %d, cda %x, eda %x.\n",
 1346                                         sc->unit,
 1347                                         sc->scachan, 
 1348                                         rxstat,
 1349                                         sc->hc->sca->msci[sc->scachan].st3,
 1350                                         sc->rxhind,
 1351                                         sc->hc->sca->dmac[
 1352                                                 DMAC_RXCH(sc->scachan)].cda,
 1353                                         sc->hc->sca->dmac[
 1354                                                 DMAC_RXCH(sc->scachan)].eda));
 1355                 }
 1356         }
 1357 }
 1358 
 1359 
 1360 /*
 1361  * All DMA interrupts come here.
 1362  *
 1363  * Each channel has two interrupts.
 1364  * Interrupt A for errors and Interrupt B for normal stuff like end
 1365  * of transmit or receive dmas.
 1366  */
 1367 static void
 1368 ar_dmac_intr(struct ar_hardc *hc, int scano, u_char isr1)
 1369 {
 1370         u_char dsr;
 1371         u_char dotxstart = isr1;
 1372         int mch;
 1373         struct ar_softc *sc;
 1374         sca_regs *sca = hc->sca;
 1375         dmac_channel *dmac;
 1376 
 1377         mch = 0;
 1378         /*
 1379          * Shortcut if there is no interrupts for dma channel 0 or 1
 1380          */
 1381         if((isr1 & 0x0F) == 0) {
 1382                 mch = 1;
 1383                 isr1 >>= 4;
 1384         }
 1385 
 1386         do {
 1387                 sc = &hc->sc[mch + (NCHAN * scano)];
 1388 
 1389                 /*
 1390                  * Transmit channel
 1391                  */
 1392                 if(isr1 & 0x0C) {
 1393                         dmac = &sca->dmac[DMAC_TXCH(mch)];
 1394 
 1395                         ARC_SET_SCA(hc->iobase, scano);
 1396 
 1397                         dsr = dmac->dsr;
 1398                         dmac->dsr = dsr;
 1399 
 1400                         /* Counter overflow */
 1401                         if(dsr & SCA_DSR_COF) {
 1402                                 printf("ar%d: TX DMA Counter overflow, "
 1403                                         "txpacket no %lu.\n",
 1404                                         sc->unit,
 1405                                         sc->ifsppp.pp_if.if_opackets);
 1406                                 sc->ifsppp.pp_if.if_oerrors++;
 1407                         }
 1408 
 1409                         /* Buffer overflow */
 1410                         if(dsr & SCA_DSR_BOF) {
 1411                                 printf("ar%d: TX DMA Buffer overflow, "
 1412                                         "txpacket no %lu, dsr %02x, "
 1413                                         "cda %04x, eda %04x.\n",
 1414                                         sc->unit,
 1415                                         sc->ifsppp.pp_if.if_opackets,
 1416                                         dsr,
 1417                                         dmac->cda,
 1418                                         dmac->eda);
 1419                                 sc->ifsppp.pp_if.if_oerrors++;
 1420                         }
 1421 
 1422                         /* End of Transfer */
 1423                         if(dsr & SCA_DSR_EOT) {
 1424                                 /*
 1425                                  * This should be the most common case.
 1426                                  *
 1427                                  * Clear the IFF_OACTIVE flag.
 1428                                  *
 1429                                  * Call arstart to start a new transmit if
 1430                                  * there is data to transmit.
 1431                                  */
 1432                                 sc->xmit_busy = 0;
 1433                                 sc->ifsppp.pp_if.if_flags &= ~IFF_OACTIVE;
 1434                                 sc->ifsppp.pp_if.if_timer = 0;
 1435 
 1436                                 if(sc->txb_inuse && --sc->txb_inuse)
 1437                                         ar_xmit(sc);
 1438                         }
 1439                 }
 1440 
 1441                 /*
 1442                  * Receive channel
 1443                  */
 1444                 if(isr1 & 0x03) {
 1445                         dmac = &sca->dmac[DMAC_RXCH(mch)];
 1446 
 1447                         ARC_SET_SCA(hc->iobase, scano);
 1448 
 1449                         dsr = dmac->dsr;
 1450                         dmac->dsr = dsr;
 1451 
 1452                         TRC(printf("AR: RX DSR %x\n", dsr));
 1453 
 1454                         /* End of frame */
 1455                         if(dsr & SCA_DSR_EOM) {
 1456                                 TRC(int tt = sc->ifsppp.pp_if.if_ipackets;)
 1457                                 TRC(int ind = sc->rxhind;)
 1458 
 1459                                 ar_get_packets(sc);
 1460                                 TRC(
 1461                                 if(tt == sc->ifsppp.pp_if.if_ipackets) {
 1462                                         sca_descriptor *rxdesc;
 1463                                         int i;
 1464 
 1465                                         ARC_SET_SCA(hc->iobase, scano);
 1466                                         printf("AR: RXINTR isr1 %x, dsr %x, "
 1467                                                "no data %d pkts, orxhind %d.\n",
 1468                                                dotxstart,
 1469                                                dsr,
 1470                                                tt,
 1471                                                ind);
 1472                                         printf("AR: rxdesc %x, rxstart %x, "
 1473                                                "rxend %x, rxhind %d, "
 1474                                                "rxmax %d.\n",
 1475                                                sc->rxdesc,
 1476                                                sc->rxstart,
 1477                                                sc->rxend,
 1478                                                sc->rxhind,
 1479                                                sc->rxmax);
 1480                                         printf("AR: cda %x, eda %x.\n",
 1481                                                dmac->cda,
 1482                                                dmac->eda);
 1483 
 1484                                         ARC_SET_MEM(sc->hc->iobase, sc->rxdesc);
 1485                                         rxdesc = (sca_descriptor *)
 1486                                                  (sc->hc->mem_start +
 1487                                                   (sc->rxdesc & ARC_WIN_MSK));
 1488                                         rxdesc = &rxdesc[sc->rxhind];
 1489                                         for(i=0;i<3;i++,rxdesc++)
 1490                                                 printf("AR: rxdesc->stat %x, "
 1491                                                         "len %d.\n",
 1492                                                         rxdesc->stat,
 1493                                                         rxdesc->len);
 1494                                 })
 1495                         }
 1496 
 1497                         /* Counter overflow */
 1498                         if(dsr & SCA_DSR_COF) {
 1499                                 printf("ar%d: RX DMA Counter overflow, "
 1500                                         "rxpkts %lu.\n",
 1501                                         sc->unit,
 1502                                         sc->ifsppp.pp_if.if_ipackets);
 1503                                 sc->ifsppp.pp_if.if_ierrors++;
 1504                         }
 1505 
 1506                         /* Buffer overflow */
 1507                         if(dsr & SCA_DSR_BOF) {
 1508                                 ARC_SET_SCA(hc->iobase, scano);
 1509                                 printf("ar%d: RX DMA Buffer overflow, "
 1510                                         "rxpkts %lu, rxind %d, "
 1511                                         "cda %x, eda %x, dsr %x.\n",
 1512                                         sc->unit,
 1513                                         sc->ifsppp.pp_if.if_ipackets,
 1514                                         sc->rxhind,
 1515                                         dmac->cda,
 1516                                         dmac->eda,
 1517                                         dsr);
 1518                                 /*
 1519                                  * Make sure we eat as many as possible.
 1520                                  * Then get the system running again.
 1521                                  */
 1522                                 ar_eat_packet(sc, 0);
 1523                                 sc->ifsppp.pp_if.if_ierrors++;
 1524                                 ARC_SET_SCA(hc->iobase, scano);
 1525                                 sca->msci[mch].cmd = SCA_CMD_RXMSGREJ;
 1526                                 dmac->dsr = SCA_DSR_DE;
 1527 
 1528                                 TRC(printf("ar%d: RX DMA Buffer overflow, "
 1529                                         "rxpkts %lu, rxind %d, "
 1530                                         "cda %x, eda %x, dsr %x. After\n",
 1531                                         sc->unit,
 1532                                         sc->ifsppp.pp_if.if_ipackets,
 1533                                         sc->rxhind,
 1534                                         dmac->cda,
 1535                                         dmac->eda,
 1536                                         dmac->dsr);)
 1537                         }
 1538 
 1539                         /* End of Transfer */
 1540                         if(dsr & SCA_DSR_EOT) {
 1541                                 /*
 1542                                  * If this happen, it means that we are
 1543                                  * receiving faster than what the processor
 1544                                  * can handle.
 1545                                  *
 1546                                  * XXX We should enable the dma again.
 1547                                  */
 1548                                 printf("ar%d: RX End of transfer, rxpkts %lu.\n",
 1549                                         sc->unit,
 1550                                         sc->ifsppp.pp_if.if_ipackets);
 1551                                 sc->ifsppp.pp_if.if_ierrors++;
 1552                         }
 1553                 }
 1554 
 1555                 isr1 >>= 4;
 1556 
 1557                 mch++;
 1558         }while((mch<NCHAN) && isr1);
 1559 
 1560         /*
 1561          * Now that we have done all the urgent things, see if we
 1562          * can fill the transmit buffers.
 1563          */
 1564         for(mch = 0; mch < NCHAN; mch++) {
 1565                 if(dotxstart & 0x0C) {
 1566                         sc = &hc->sc[mch + (NCHAN * scano)];
 1567                         arstart(&sc->ifsppp.pp_if);
 1568                 }
 1569                 dotxstart >>= 4;
 1570         }
 1571 }
 1572 
 1573 static void
 1574 ar_msci_intr(struct ar_hardc *hc, int scano, u_char isr0)
 1575 {
 1576         printf("arc%d: ARINTR: MSCI\n", hc->cunit);
 1577 }
 1578 
 1579 static void
 1580 ar_timer_intr(struct ar_hardc *hc, int scano, u_char isr2)
 1581 {
 1582         printf("arc%d: ARINTR: TIMER\n", hc->cunit);
 1583 }
 1584 
 1585 /*
 1586  ********************************* END ************************************
 1587  */
 1588 

Cache object: a07a7ce3939de936b358a808388b71ce


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