root/dev/pci/if_lmc.c

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

DEFINITIONS

This source file includes following definitions.
  1. lmc_delay_300ns
  2. lmc_srom_idle
  3. lmc_srom_read
  4. lmc_mii_writebits
  5. lmc_mii_turnaround
  6. lmc_mii_readbits
  7. lmc_mii_readreg
  8. lmc_mii_writereg
  9. lmc_read_macaddr
  10. lmc_watchdog
  11. lmc_ifup
  12. lmc_ifdown
  13. lmc_rx_intr
  14. lmc_tx_intr
  15. lmc_print_abnormal_interrupt
  16. lmc_intr_handler
  17. lmc_intr_normal
  18. lmc_mbuf_compress
  19. lmc_txput
  20. lmc_ifioctl
  21. lmc_ifstart
  22. lmc_ifstart_one
  23. lmc_attach
  24. lmc_initring

    1 /*      $OpenBSD: if_lmc.c,v 1.23 2006/05/13 19:10:02 brad Exp $ */
    2 /*      $NetBSD: if_lmc.c,v 1.1 1999/03/25 03:32:43 explorer Exp $      */
    3 
    4 /*-
    5  * Copyright (c) 1997-1999 LAN Media Corporation (LMC)
    6  * All rights reserved.  www.lanmedia.com
    7  *
    8  * This code is written by Michael Graff <graff@vix.com> for LMC.
    9  * The code is derived from permitted modifications to software created
   10  * by Matt Thomas (matt@3am-software.com).
   11  *
   12  * Redistribution and use in source and binary forms, with or without
   13  * modification, are permitted provided that the following conditions
   14  * are met:
   15  * 1. Redistributions of source code must retain the above copyright
   16  *    notice, this list of conditions and the following disclaimer.
   17  * 2. Redistributions in binary form must reproduce the above
   18  *    copyright notice, this list of conditions and the following disclaimer
   19  *    in the documentation and/or other materials provided with the
   20  *    distribution.
   21  * 3. All marketing or advertising materials mentioning features or
   22  *    use of this software must display the following acknowledgement:
   23  *      This product includes software developed by LAN Media Corporation
   24  *      and its contributors.
   25  * 4. Neither the name of LAN Media Corporation nor the names of its
   26  *    contributors may be used to endorse or promote products derived
   27  *    from this software without specific prior written permission.
   28  *
   29  * THIS SOFTWARE IS PROVIDED BY LAN MEDIA CORPORATION AND CONTRIBUTORS
   30  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   31  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   32  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   33  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   34  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   35  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   36  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   37  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   39  * THE POSSIBILITY OF SUCH DAMAGE.
   40  */
   41 
   42 /*-
   43  * Copyright (c) 1994-1997 Matt Thomas (matt@3am-software.com)
   44  * All rights reserved.
   45  *
   46  * Redistribution and use in source and binary forms, with or without
   47  * modification, are permitted provided that the following conditions
   48  * are met:
   49  * 1. Redistributions of source code must retain the above copyright
   50  *    notice, this list of conditions and the following disclaimer.
   51  * 2. The name of the author may not be used to endorse or promote products
   52  *    derived from this software without specific prior written permission
   53  *
   54  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   55  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   56  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   57  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   58  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   59  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   60  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   61  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   62  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   63  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   64  */
   65 
   66 /*
   67  * LMC1200 (DS1) & LMC5245 (DS3) LED definitions
   68  * led0 yellow = far-end link is in Red alarm condition
   69  * led1 blue   = received an Alarm Indication signal (upstream failure)
   70  * led2 Green  = power to adapter, Gate Array loaded & driver attached
   71  * led3 red    = Loss of Signal (LOS) or out of frame (OOF) conditions
   72  *               detected on T3 receive signal
   73  *
   74  * LMC1000 (SSI) & LMC5200 (HSSI) LED definitions
   75  * led0 Green  = power to adapter, Gate Array loaded & driver attached
   76  * led1 Green  = DSR and DTR and RTS and CTS are set (CA, TA for LMC5200)
   77  * led2 Green  = Cable detected (Green indicates non-loopback mode for LMC5200)
   78  * led3 red    = No timing is available from the cable or the on-board
   79  *               frequency generator. (ST not available for LMC5200)
   80  */
   81 
   82 #include "bpfilter.h"
   83 
   84 #include <sys/param.h>
   85 #include <sys/systm.h>
   86 #include <sys/mbuf.h>
   87 #include <sys/socket.h>
   88 #include <sys/ioctl.h>
   89 #include <sys/errno.h>
   90 #include <sys/malloc.h>
   91 #include <sys/kernel.h>
   92 #include <sys/proc.h>
   93 #include <sys/device.h>
   94 
   95 #include <dev/pci/pcidevs.h>
   96 
   97 #include <net/if.h>
   98 #include <net/if_types.h>
   99 #include <net/if_dl.h>
  100 #include <net/netisr.h>
  101 
  102 #if NBPFILTER > 0
  103 #include <net/bpf.h>
  104 #endif
  105 
  106 #include <net/if_sppp.h>
  107 
  108 #include <machine/bus.h>
  109 
  110 #include <dev/pci/pcireg.h>
  111 #include <dev/pci/pcivar.h>
  112 #include <dev/ic/dc21040reg.h>
  113 
  114 #include <dev/pci/if_lmc_types.h>
  115 #include <dev/pci/if_lmcioctl.h>
  116 #include <dev/pci/if_lmcvar.h>
  117 
  118 /*
  119  * This module supports
  120  *      the DEC 21140A pass 2.2 PCI Fast Ethernet Controller.
  121  */
  122 static ifnet_ret_t lmc_ifstart_one(struct ifnet *ifp);
  123 static ifnet_ret_t lmc_ifstart(struct ifnet *ifp);
  124 static struct mbuf *lmc_txput(lmc_softc_t * const sc, struct mbuf *m);
  125 static void lmc_rx_intr(lmc_softc_t * const sc);
  126 
  127 static void lmc_watchdog(struct ifnet *ifp);
  128 static void lmc_ifup(lmc_softc_t * const sc);
  129 static void lmc_ifdown(lmc_softc_t * const sc);
  130 
  131 /*
  132  * Code the read the SROM and MII bit streams (I2C)
  133  */
  134 static inline void
  135 lmc_delay_300ns(lmc_softc_t * const sc)
  136 {
  137         int idx;
  138         for (idx = (300 / 33) + 1; idx > 0; idx--)
  139                 (void)LMC_CSR_READ(sc, csr_busmode);
  140 }
  141 
  142 #define EMIT    \
  143 do { \
  144         LMC_CSR_WRITE(sc, csr_srom_mii, csr); \
  145         lmc_delay_300ns(sc); \
  146 } while (0)
  147 
  148 static inline void
  149 lmc_srom_idle(lmc_softc_t * const sc)
  150 {
  151         unsigned bit, csr;
  152     
  153         csr  = SROMSEL ; EMIT;
  154         csr  = SROMSEL | SROMRD; EMIT;  
  155         csr ^= SROMCS; EMIT;
  156         csr ^= SROMCLKON; EMIT;
  157 
  158         /*
  159          * Write 25 cycles of 0 which will force the SROM to be idle.
  160          */
  161         for (bit = 3 + SROM_BITWIDTH + 16; bit > 0; bit--) {
  162                 csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
  163                 csr ^= SROMCLKON; EMIT;     /* clock high; data valid */
  164         }
  165         csr ^= SROMCLKOFF; EMIT;
  166         csr ^= SROMCS; EMIT;
  167         csr  = 0; EMIT;
  168 }
  169 
  170      
  171 static void
  172 lmc_srom_read(lmc_softc_t * const sc)
  173 {   
  174         unsigned idx; 
  175         const unsigned bitwidth = SROM_BITWIDTH;
  176         const unsigned cmdmask = (SROMCMD_RD << bitwidth);
  177         const unsigned msb = 1 << (bitwidth + 3 - 1);
  178         unsigned lastidx = (1 << bitwidth) - 1;
  179 
  180         lmc_srom_idle(sc);
  181 
  182         for (idx = 0; idx <= lastidx; idx++) {
  183                 unsigned lastbit, data, bits, bit, csr;
  184                 csr  = SROMSEL ;                EMIT;
  185                 csr  = SROMSEL | SROMRD;        EMIT;
  186                 csr ^= SROMCSON;                EMIT;
  187                 csr ^=            SROMCLKON;    EMIT;
  188     
  189                 lastbit = 0;
  190                 for (bits = idx|cmdmask, bit = bitwidth + 3
  191                              ; bit > 0
  192                              ; bit--, bits <<= 1) {
  193                         const unsigned thisbit = bits & msb;
  194                         csr ^= SROMCLKOFF; EMIT;    /* clock L data invalid */
  195                         if (thisbit != lastbit) {
  196                                 csr ^= SROMDOUT; EMIT;/* clock L invert data */
  197                         } else {
  198                                 EMIT;
  199                         }
  200                         csr ^= SROMCLKON; EMIT;     /* clock H data valid */
  201                         lastbit = thisbit;
  202                 }
  203                 csr ^= SROMCLKOFF; EMIT;
  204 
  205                 for (data = 0, bits = 0; bits < 16; bits++) {
  206                         data <<= 1;
  207                         csr ^= SROMCLKON; EMIT;     /* clock H data valid */ 
  208                         data |= LMC_CSR_READ(sc, csr_srom_mii) & SROMDIN ? 1 : 0;
  209                         csr ^= SROMCLKOFF; EMIT;    /* clock L data invalid */
  210                 }
  211                 sc->lmc_rombuf[idx*2] = data & 0xFF;
  212                 sc->lmc_rombuf[idx*2+1] = data >> 8;
  213                 csr  = SROMSEL | SROMRD; EMIT;
  214                 csr  = 0; EMIT;
  215         }
  216         lmc_srom_idle(sc);
  217 }
  218 
  219 #define MII_EMIT    do { LMC_CSR_WRITE(sc, csr_srom_mii, csr); lmc_delay_300ns(sc); } while (0)
  220 
  221 static inline void
  222 lmc_mii_writebits(lmc_softc_t * const sc, unsigned data, unsigned bits)
  223 {
  224     unsigned msb = 1 << (bits - 1);
  225     unsigned csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
  226     unsigned lastbit = (csr & MII_DOUT) ? msb : 0;
  227 
  228     csr |= MII_WR; MII_EMIT;            /* clock low; assert write */
  229 
  230     for (; bits > 0; bits--, data <<= 1) {
  231         const unsigned thisbit = data & msb;
  232         if (thisbit != lastbit) {
  233             csr ^= MII_DOUT; MII_EMIT;  /* clock low; invert data */
  234         }
  235         csr ^= MII_CLKON; MII_EMIT;     /* clock high; data valid */
  236         lastbit = thisbit;
  237         csr ^= MII_CLKOFF; MII_EMIT;    /* clock low; data not valid */
  238     }
  239 }
  240 
  241 static void
  242 lmc_mii_turnaround(lmc_softc_t * const sc, u_int32_t cmd)
  243 {
  244     u_int32_t csr;
  245 
  246     csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
  247     if (cmd == MII_WRCMD) {
  248         csr |= MII_DOUT; MII_EMIT;      /* clock low; change data */
  249         csr ^= MII_CLKON; MII_EMIT;     /* clock high; data valid */
  250         csr ^= MII_CLKOFF; MII_EMIT;    /* clock low; data not valid */
  251         csr ^= MII_DOUT; MII_EMIT;      /* clock low; change data */
  252     } else {
  253         csr |= MII_RD; MII_EMIT;        /* clock low; switch to read */
  254     }
  255     csr ^= MII_CLKON; MII_EMIT;         /* clock high; data valid */
  256     csr ^= MII_CLKOFF; MII_EMIT;        /* clock low; data not valid */
  257 }
  258 
  259 static u_int32_t
  260 lmc_mii_readbits(lmc_softc_t * const sc)
  261 {
  262     u_int32_t data;
  263     u_int32_t csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
  264     int idx;
  265 
  266     for (idx = 0, data = 0; idx < 16; idx++) {
  267         data <<= 1;     /* this is NOOP on the first pass through */
  268         csr ^= MII_CLKON; MII_EMIT;     /* clock high; data valid */
  269         if (LMC_CSR_READ(sc, csr_srom_mii) & MII_DIN)
  270             data |= 1;
  271         csr ^= MII_CLKOFF; MII_EMIT;    /* clock low; data not valid */
  272     }
  273     csr ^= MII_RD; MII_EMIT;            /* clock low; turn off read */
  274 
  275     return data;
  276 }
  277 
  278 u_int32_t
  279 lmc_mii_readreg(lmc_softc_t * const sc, u_int32_t devaddr, u_int32_t regno)
  280 {
  281     u_int32_t csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
  282     u_int32_t data;
  283 
  284     csr &= ~(MII_RD|MII_CLK); MII_EMIT;
  285     lmc_mii_writebits(sc, MII_PREAMBLE, 32);
  286     lmc_mii_writebits(sc, MII_RDCMD, 8);
  287     lmc_mii_writebits(sc, devaddr, 5);
  288     lmc_mii_writebits(sc, regno, 5);
  289     lmc_mii_turnaround(sc, MII_RDCMD);
  290 
  291     data = lmc_mii_readbits(sc);
  292     return (data);
  293 }
  294 
  295 void
  296 lmc_mii_writereg(lmc_softc_t * const sc, u_int32_t devaddr,
  297                    u_int32_t regno, u_int32_t data)
  298 {
  299     u_int32_t csr;
  300 
  301     csr = LMC_CSR_READ(sc, csr_srom_mii) & (MII_RD|MII_DOUT|MII_CLK);
  302     csr &= ~(MII_RD|MII_CLK); MII_EMIT;
  303     lmc_mii_writebits(sc, MII_PREAMBLE, 32);
  304     lmc_mii_writebits(sc, MII_WRCMD, 8);
  305     lmc_mii_writebits(sc, devaddr, 5);
  306     lmc_mii_writebits(sc, regno, 5);
  307     lmc_mii_turnaround(sc, MII_WRCMD);
  308     lmc_mii_writebits(sc, data, 16);
  309 }
  310 
  311 int
  312 lmc_read_macaddr(lmc_softc_t * const sc)
  313 {
  314         lmc_srom_read(sc);
  315 
  316         bcopy(sc->lmc_rombuf + 20, sc->lmc_enaddr, 6);
  317 
  318         return 0;
  319 }
  320 
  321 /*
  322  * Check to make certain there is a signal from the modem, and flicker
  323  * lights as needed.
  324  */
  325 static void
  326 lmc_watchdog(struct ifnet *ifp)
  327 {
  328         lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
  329         int state;
  330         u_int32_t ostatus;
  331         u_int32_t link_status;
  332         u_int32_t ticks;
  333 
  334         state = 0;
  335 
  336         /*
  337          * Make sure the tx jabber and rx watchdog are off,
  338          * and the transmit and receive processes are running.
  339          */
  340         LMC_CSR_WRITE (sc, csr_15, 0x00000011);
  341         sc->lmc_cmdmode |= TULIP_CMD_TXRUN | TULIP_CMD_RXRUN;
  342         LMC_CSR_WRITE (sc, csr_command, sc->lmc_cmdmode);
  343 
  344         /* Is the transmit clock still available? */
  345         ticks = LMC_CSR_READ (sc, csr_gp_timer);
  346         ticks = 0x0000ffff - (ticks & 0x0000ffff);
  347         if (ticks == 0)
  348         {
  349                 /* no clock found ? */
  350                 if (sc->tx_clockState != 0)
  351                 {
  352                         sc->tx_clockState = 0;
  353                         if (sc->lmc_cardtype == LMC_CARDTYPE_SSI)
  354                                 lmc_led_on (sc, LMC_MII16_LED3); /* ON red */
  355                 }
  356         else
  357                 if (sc->tx_clockState == 0)
  358                 {
  359                         sc->tx_clockState = 1;
  360                         if (sc->lmc_cardtype == LMC_CARDTYPE_SSI)
  361                                 lmc_led_off (sc, LMC_MII16_LED3); /* OFF red */
  362                 }
  363         }
  364 
  365         link_status = sc->lmc_media->get_link_status(sc);
  366         ostatus = ((sc->lmc_flags & LMC_MODEMOK) == LMC_MODEMOK);
  367 
  368         /*
  369          * hardware level link lost, but the interface is marked as up.
  370          * Mark it as down.
  371          */
  372         if (link_status == LMC_LINK_DOWN && ostatus) {
  373                 printf(LMC_PRINTF_FMT ": physical link down\n",
  374                        LMC_PRINTF_ARGS);
  375                 sc->lmc_flags &= ~LMC_MODEMOK;
  376                 if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
  377                     sc->lmc_cardtype == LMC_CARDTYPE_T1)
  378                         lmc_led_on (sc, LMC_DS3_LED3 | LMC_DS3_LED2);
  379                                                         /* turn on red LED */
  380                 else {
  381                         lmc_led_off (sc, LMC_MII16_LED1);
  382                         lmc_led_on (sc, LMC_MII16_LED0);
  383                         if (sc->lmc_timing == LMC_CTL_CLOCK_SOURCE_EXT)
  384                                 lmc_led_on (sc, LMC_MII16_LED3);
  385                 }
  386 
  387         }
  388 
  389         /*
  390          * hardware link is up, but the interface is marked as down.
  391          * Bring it back up again.
  392          */
  393         if (link_status != LMC_LINK_DOWN && !ostatus) {
  394                 printf(LMC_PRINTF_FMT ": physical link up\n",
  395                        LMC_PRINTF_ARGS);
  396                 if (sc->lmc_flags & LMC_IFUP)
  397                         lmc_ifup(sc);
  398                 sc->lmc_flags |= LMC_MODEMOK;
  399                 if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
  400                     sc->lmc_cardtype == LMC_CARDTYPE_T1)
  401                 {
  402                         sc->lmc_miireg16 |= LMC_DS3_LED3;
  403                         lmc_led_off (sc, LMC_DS3_LED3);
  404                                                         /* turn off red LED */
  405                         lmc_led_on (sc, LMC_DS3_LED2);
  406                 } else {
  407                         lmc_led_on (sc, LMC_MII16_LED0 | LMC_MII16_LED1
  408                                     | LMC_MII16_LED2);
  409                         if (sc->lmc_timing != LMC_CTL_CLOCK_SOURCE_EXT)
  410                                 lmc_led_off (sc, LMC_MII16_LED3);
  411                 }
  412 
  413                 return;
  414         }
  415 
  416         /* Call media specific watchdog functions */
  417         sc->lmc_media->watchdog(sc);
  418 
  419         /*
  420          * remember the timer value
  421          */
  422         ticks = LMC_CSR_READ(sc, csr_gp_timer);
  423         LMC_CSR_WRITE(sc, csr_gp_timer, 0xffffffffUL);
  424         sc->ictl.ticks = 0x0000ffff - (ticks & 0x0000ffff);
  425 
  426         ifp->if_timer = 1;
  427 }
  428 
  429 /*
  430  * Mark the interface as "up" and enable TX/RX and TX/RX interrupts.
  431  * This also does a full software reset.
  432  */
  433 static void
  434 lmc_ifup(lmc_softc_t * const sc)
  435 {
  436         sc->lmc_if.if_timer = 0;
  437 
  438         lmc_dec_reset(sc);
  439         lmc_reset(sc);
  440 
  441         sc->lmc_media->set_link_status(sc, LMC_LINK_UP);
  442         sc->lmc_media->set_status(sc, NULL);
  443 
  444         sc->lmc_flags |= LMC_IFUP;
  445 
  446         /*
  447          * for DS3 & DS1 adapters light the green light, led2
  448          */
  449         if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
  450             sc->lmc_cardtype == LMC_CARDTYPE_T1)
  451                 lmc_led_on (sc, LMC_MII16_LED2);
  452         else
  453                 lmc_led_on (sc, LMC_MII16_LED0 | LMC_MII16_LED2);
  454 
  455         /*
  456          * select what interrupts we want to get
  457          */
  458         sc->lmc_intrmask |= (TULIP_STS_NORMALINTR
  459                                | TULIP_STS_RXINTR
  460                                | TULIP_STS_RXNOBUF
  461                                | TULIP_STS_TXINTR
  462                                | TULIP_STS_ABNRMLINTR
  463                                | TULIP_STS_SYSERROR
  464                                | TULIP_STS_TXSTOPPED
  465                                | TULIP_STS_TXUNDERFLOW
  466                                | TULIP_STS_RXSTOPPED
  467                                );
  468         LMC_CSR_WRITE(sc, csr_intr, sc->lmc_intrmask);
  469 
  470         sc->lmc_cmdmode |= TULIP_CMD_TXRUN;
  471         sc->lmc_cmdmode |= TULIP_CMD_RXRUN;
  472         LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
  473 
  474         sc->lmc_if.if_timer = 1;
  475 }
  476 
  477 /*
  478  * Mark the interface as "down" and disable TX/RX and TX/RX interrupts.
  479  * This is done by performing a full reset on the interface.
  480  */
  481 static void
  482 lmc_ifdown(lmc_softc_t * const sc)
  483 {
  484         sc->lmc_if.if_timer = 0;
  485         sc->lmc_flags &= ~LMC_IFUP;
  486 
  487         sc->lmc_media->set_link_status(sc, LMC_LINK_DOWN);
  488         lmc_led_off(sc, LMC_MII16_LED_ALL);
  489 
  490         lmc_dec_reset(sc);
  491         lmc_reset(sc);
  492         sc->lmc_media->set_status(sc, NULL);
  493 }
  494 
  495 static void
  496 lmc_rx_intr(lmc_softc_t * const sc)
  497 {
  498         lmc_ringinfo_t * const ri = &sc->lmc_rxinfo;
  499         struct ifnet * const ifp = &sc->lmc_if;
  500         u_int32_t status;
  501         int fillok = 1;
  502 
  503         sc->lmc_rxtick++;
  504 
  505         for (;;) {
  506                 lmc_desc_t *eop = ri->ri_nextin;
  507                 int total_len = 0, last_offset = 0;
  508                 struct mbuf *ms = NULL, *me = NULL;
  509                 int accept = 0;
  510                 bus_dmamap_t map;
  511                 int error;
  512 
  513                 if (fillok && sc->lmc_rxq.ifq_len < LMC_RXQ_TARGET)
  514                         goto queue_mbuf;
  515 
  516                 /*
  517                  * If the TULIP has no descriptors, there can't be any receive
  518                  * descriptors to process.
  519                  */
  520                 if (eop == ri->ri_nextout)
  521                         break;
  522             
  523                 /*
  524                  * 90% of the packets will fit in one descriptor.  So we
  525                  * optimize for that case.
  526                  */
  527                 LMC_RXDESC_POSTSYNC(sc, eop, sizeof(*eop));
  528                 status = letoh32(((volatile lmc_desc_t *) eop)->d_status);
  529                 if ((status &
  530                         (TULIP_DSTS_OWNER|TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) == 
  531                         (TULIP_DSTS_RxFIRSTDESC|TULIP_DSTS_RxLASTDESC)) {
  532                         IF_DEQUEUE(&sc->lmc_rxq, ms);
  533                         me = ms;
  534                 } else {
  535                         /*
  536                          * If still owned by the TULIP, don't touch it.
  537                          */
  538                         if (status & TULIP_DSTS_OWNER)
  539                                 break;
  540 
  541                         /*
  542                          * It is possible (though improbable unless the
  543                          * BIG_PACKET support is enabled or MCLBYTES < 1518)
  544                          * for a received packet to cross more than one
  545                          * receive descriptor.
  546                          */
  547                         while ((status & TULIP_DSTS_RxLASTDESC) == 0) {
  548                                 if (++eop == ri->ri_last)
  549                                         eop = ri->ri_first;
  550                                 LMC_RXDESC_POSTSYNC(sc, eop, sizeof(*eop));
  551                                 status = letoh32(((volatile lmc_desc_t *)
  552                                         eop)->d_status);
  553                                 if (eop == ri->ri_nextout || 
  554                                         (status & TULIP_DSTS_OWNER)) {
  555                                         return;
  556                                 }
  557                                 total_len++;
  558                         }
  559 
  560                         /*
  561                          * Dequeue the first buffer for the start of the
  562                          * packet.  Hopefully this will be the only one we
  563                          * need to dequeue.  However, if the packet consumed
  564                          * multiple descriptors, then we need to dequeue
  565                          * those buffers and chain to the starting mbuf.
  566                          * All buffers but the last buffer have the same
  567                          * length so we can set that now. (we add to
  568                          * last_offset instead of multiplying since we
  569                          * normally won't go into the loop and thereby
  570                          * saving a ourselves from doing a multiplication
  571                          * by 0 in the normal case).
  572                          */
  573                         IF_DEQUEUE(&sc->lmc_rxq, ms);
  574                         for (me = ms; total_len > 0; total_len--) {
  575                                 map = LMC_GETCTX(me, bus_dmamap_t);
  576                                 LMC_RXMAP_POSTSYNC(sc, map);
  577                                 bus_dmamap_unload(sc->lmc_dmatag, map);
  578                                 sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
  579 #if defined(DIAGNOSTIC)
  580                                 LMC_SETCTX(me, NULL);
  581 #endif
  582                                 me->m_len = LMC_RX_BUFLEN;
  583                                 last_offset += LMC_RX_BUFLEN;
  584                                 IF_DEQUEUE(&sc->lmc_rxq, me->m_next);
  585                                 me = me->m_next;
  586                         }
  587                 }
  588 
  589                 /*
  590                  *  Now get the size of received packet (minus the CRC).
  591                  */
  592                 total_len = ((status >> 16) & 0x7FFF);
  593                 if (sc->ictl.crc_length == 16)
  594                         total_len -= 2;
  595                 else
  596                         total_len -= 4;
  597 
  598                 if ((sc->lmc_flags & LMC_RXIGNORE) == 0
  599                     && ((status & LMC_DSTS_ERRSUM) == 0
  600 #ifdef BIG_PACKET
  601                         || (total_len <= sc->lmc_if.if_mtu + PPP_HEADER_LEN
  602                             && (status & TULIP_DSTS_RxOVERFLOW) == 0)
  603 #endif
  604                         )) {
  605 
  606                         map = LMC_GETCTX(me, bus_dmamap_t);
  607                         bus_dmamap_sync(sc->lmc_dmatag, map, 0, me->m_len,
  608                                 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  609                         bus_dmamap_unload(sc->lmc_dmatag, map);
  610                         sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
  611 #if defined(DIAGNOSTIC)
  612                         LMC_SETCTX(me, NULL);
  613 #endif
  614 
  615                         me->m_len = total_len - last_offset;
  616 #if NBPFILTER > 0
  617                         if (sc->lmc_bpf != NULL) {
  618                                 if (me == ms)
  619                                         LMC_BPF_TAP(sc, mtod(ms, caddr_t),
  620                                             total_len, BPF_DIRECTION_IN);
  621                                 else
  622                                         LMC_BPF_MTAP(sc, ms, BPF_DIRECTION_IN);
  623                         }
  624 #endif
  625                         sc->lmc_flags |= LMC_RXACT;
  626                         accept = 1;
  627                 } else {
  628                         ifp->if_ierrors++;
  629                         if (status & TULIP_DSTS_RxOVERFLOW) {
  630                                 sc->lmc_dot3stats.dot3StatsInternalMacReceiveErrors++;
  631                         }
  632                         map = LMC_GETCTX(me, bus_dmamap_t);
  633                         bus_dmamap_unload(sc->lmc_dmatag, map);
  634                         sc->lmc_rxmaps[sc->lmc_rxmaps_free++] = map;
  635 #if defined(DIAGNOSTIC)
  636                         LMC_SETCTX(me, NULL);
  637 #endif
  638                 }
  639 
  640                 ifp->if_ipackets++;
  641                 if (++eop == ri->ri_last)
  642                         eop = ri->ri_first;
  643                 ri->ri_nextin = eop;
  644 
  645         queue_mbuf:
  646                 /*
  647                  * Either we are priming the TULIP with mbufs (m == NULL)
  648                  * or we are about to accept an mbuf for the upper layers
  649                  * so we need to allocate an mbuf to replace it.  If we
  650                  * can't replace it, send up it anyways.  This may cause
  651                  * us to drop packets in the future but that's better than
  652                  * being caught in livelock.
  653                  *
  654                  * Note that if this packet crossed multiple descriptors
  655                  * we don't even try to reallocate all the mbufs here.
  656                  * Instead we rely on the test of the beginning of
  657                  * the loop to refill for the extra consumed mbufs.
  658                  */
  659                 if (accept || ms == NULL) {
  660                         struct mbuf *m0;
  661                         MGETHDR(m0, M_DONTWAIT, MT_DATA);
  662                         if (m0 != NULL) {
  663                                 MCLGET(m0, M_DONTWAIT);
  664                                 if ((m0->m_flags & M_EXT) == 0) {
  665                                         m_freem(m0);
  666                                         m0 = NULL;
  667                                 }
  668                         }
  669                         if (accept) {
  670                                 ms->m_pkthdr.len = total_len;
  671                                 ms->m_pkthdr.rcvif = ifp;
  672                                 sppp_input(ifp, ms);
  673                         }
  674                         ms = m0;
  675                 }
  676                 if (ms == NULL) {
  677                         /*
  678                          * Couldn't allocate a new buffer.  Don't bother 
  679                          * trying to replenish the receive queue.
  680                          */
  681                         fillok = 0;
  682                         sc->lmc_flags |= LMC_RXBUFSLOW;
  683                         continue;
  684                 }
  685                 /*
  686                  * Now give the buffer(s) to the TULIP and save in our
  687                  * receive queue.
  688                  */
  689                 do {
  690                         u_int32_t ctl;
  691                         lmc_desc_t * const nextout = ri->ri_nextout;
  692 
  693                         if (sc->lmc_rxmaps_free > 0) {
  694                                 map = sc->lmc_rxmaps[--sc->lmc_rxmaps_free];
  695                         } else {
  696                                 m_freem(ms);
  697                                 sc->lmc_flags |= LMC_RXBUFSLOW;
  698 #if defined(LMC_DEBUG)
  699                                 sc->lmc_dbg.dbg_rxlowbufs++;
  700 #endif
  701                                 break;
  702                         }
  703                         LMC_SETCTX(ms, map);
  704                         error = bus_dmamap_load(sc->lmc_dmatag, map,
  705                                 mtod(ms, void *), LMC_RX_BUFLEN, 
  706                                 NULL, BUS_DMA_NOWAIT);
  707                         if (error) {
  708                                 printf(LMC_PRINTF_FMT
  709                                         ": unable to load rx map, "
  710                                         "error = %d\n",
  711                                         LMC_PRINTF_ARGS, error);
  712                                 panic("lmc_rx_intr");           /* XXX */
  713                         }
  714 
  715                         ctl = letoh32(nextout->d_ctl);
  716                         /* For some weird reason we lose TULIP_DFLAG_ENDRING */
  717                         if ((nextout+1) == ri->ri_last)
  718                                 ctl = LMC_CTL(LMC_CTL_FLGS(ctl)|
  719                                         TULIP_DFLAG_ENDRING, 0, 0);
  720                         nextout->d_addr1 = htole32(map->dm_segs[0].ds_addr);
  721                         if (map->dm_nsegs == 2) {
  722                                 nextout->d_addr2 = htole32(map->dm_segs[1].ds_addr);
  723                                 nextout->d_ctl = 
  724                                         htole32(LMC_CTL(LMC_CTL_FLGS(ctl),
  725                                                 map->dm_segs[0].ds_len,
  726                                                 map->dm_segs[1].ds_len));
  727                         } else {
  728                                 nextout->d_addr2 = 0;
  729                                 nextout->d_ctl = 
  730                                         htole32(LMC_CTL(LMC_CTL_FLGS(ctl),
  731                                                 map->dm_segs[0].ds_len, 0));
  732                         }
  733                         LMC_RXDESC_POSTSYNC(sc, nextout, sizeof(*nextout));
  734                         ri->ri_nextout->d_status = htole32(TULIP_DSTS_OWNER);
  735                         LMC_RXDESC_POSTSYNC(sc, nextout, sizeof(u_int32_t));
  736                         if (++ri->ri_nextout == ri->ri_last)
  737                                 ri->ri_nextout = ri->ri_first;
  738                         me = ms->m_next;
  739                         ms->m_next = NULL;
  740                         IF_ENQUEUE(&sc->lmc_rxq, ms);
  741                 } while ((ms = me) != NULL);
  742 
  743                 if (sc->lmc_rxq.ifq_len >= LMC_RXQ_TARGET)
  744                         sc->lmc_flags &= ~LMC_RXBUFSLOW;
  745         }
  746 }
  747 
  748 static int
  749 lmc_tx_intr(lmc_softc_t * const sc)
  750 {
  751     lmc_ringinfo_t * const ri = &sc->lmc_txinfo;
  752     struct mbuf *m;
  753     int xmits = 0;
  754     int descs = 0;
  755     u_int32_t d_status;
  756 
  757     sc->lmc_txtick++;
  758 
  759     while (ri->ri_free < ri->ri_max) {
  760         u_int32_t flag;
  761 
  762         LMC_TXDESC_POSTSYNC(sc, ri->ri_nextin, sizeof(*ri->ri_nextin));
  763         d_status = letoh32(((volatile lmc_desc_t *) ri->ri_nextin)->d_status);
  764         if (d_status & TULIP_DSTS_OWNER)
  765             break;
  766 
  767         flag = LMC_CTL_FLGS(letoh32(ri->ri_nextin->d_ctl));
  768         if (flag & TULIP_DFLAG_TxLASTSEG) {
  769                 IF_DEQUEUE(&sc->lmc_txq, m);
  770                 if (m != NULL) {
  771                     bus_dmamap_t map = LMC_GETCTX(m, bus_dmamap_t);
  772                     LMC_TXMAP_POSTSYNC(sc, map);
  773                     sc->lmc_txmaps[sc->lmc_txmaps_free++] = map;
  774 #if NBPFILTER > 0
  775                     if (sc->lmc_bpf != NULL)
  776                         LMC_BPF_MTAP(sc, m, BPF_DIRECTION_OUT);
  777 #endif
  778                     m_freem(m);
  779 #if defined(LMC_DEBUG)
  780                 } else {
  781                     printf(LMC_PRINTF_FMT ": tx_intr: failed to dequeue mbuf?!?\n", LMC_PRINTF_ARGS);
  782 #endif
  783                 }
  784                     xmits++;
  785                     if (d_status & LMC_DSTS_ERRSUM) {
  786                         sc->lmc_if.if_oerrors++;
  787                         if (d_status & TULIP_DSTS_TxUNDERFLOW) {
  788                             sc->lmc_dot3stats.dot3StatsInternalTransmitUnderflows++;
  789                         }
  790                     } else {
  791                         if (d_status & TULIP_DSTS_TxDEFERRED) {
  792                             sc->lmc_dot3stats.dot3StatsDeferredTransmissions++;
  793                         }
  794                     }
  795         }
  796 
  797         if (++ri->ri_nextin == ri->ri_last)
  798             ri->ri_nextin = ri->ri_first;
  799 
  800         ri->ri_free++;
  801         descs++;
  802         sc->lmc_if.if_flags &= ~IFF_OACTIVE;
  803     }
  804     /*
  805      * If nothing left to transmit, disable the timer.
  806      * Else if progress, reset the timer back to 2 ticks.
  807      */
  808     sc->lmc_if.if_opackets += xmits;
  809 
  810     return descs;
  811 }
  812 
  813 static void
  814 lmc_print_abnormal_interrupt (lmc_softc_t * const sc, u_int32_t csr)
  815 {
  816         printf(LMC_PRINTF_FMT ": Abnormal interrupt\n", LMC_PRINTF_ARGS);
  817 }
  818 
  819 static const char * const lmc_system_errors[] = {
  820     "parity error",
  821     "master abort",
  822     "target abort",
  823     "reserved #3",
  824     "reserved #4",
  825     "reserved #5",
  826     "reserved #6",
  827     "reserved #7",
  828 };
  829 
  830 static void
  831 lmc_intr_handler(lmc_softc_t * const sc, int *progress_p)
  832 {
  833     u_int32_t csr;
  834 
  835     while ((csr = LMC_CSR_READ(sc, csr_status)) & sc->lmc_intrmask) {
  836 
  837         *progress_p = 1;
  838         LMC_CSR_WRITE(sc, csr_status, csr);
  839 
  840         if (csr & TULIP_STS_SYSERROR) {
  841             sc->lmc_last_system_error = (csr & TULIP_STS_ERRORMASK) >> TULIP_STS_ERR_SHIFT;
  842             if (sc->lmc_flags & LMC_NOMESSAGES) {
  843                 sc->lmc_flags |= LMC_SYSTEMERROR;
  844             } else {
  845                 printf(LMC_PRINTF_FMT ": system error: %s\n",
  846                        LMC_PRINTF_ARGS,
  847                        lmc_system_errors[sc->lmc_last_system_error]);
  848             }
  849             sc->lmc_flags |= LMC_NEEDRESET;
  850             sc->lmc_system_errors++;
  851             break;
  852         }
  853         if (csr & (TULIP_STS_RXINTR | TULIP_STS_RXNOBUF)) {
  854             u_int32_t misses = LMC_CSR_READ(sc, csr_missed_frames);
  855             if (csr & TULIP_STS_RXNOBUF)
  856                 sc->lmc_dot3stats.dot3StatsMissedFrames += misses & 0xFFFF;
  857             /*
  858              * Pass 2.[012] of the 21140A-A[CDE] may hang and/or corrupt data
  859              * on receive overflows.
  860              */
  861            if ((misses & 0x0FFE0000) && (sc->lmc_features & LMC_HAVE_RXBADOVRFLW)) {
  862                 sc->lmc_dot3stats.dot3StatsInternalMacReceiveErrors++;
  863                 /*
  864                  * Stop the receiver process and spin until it's stopped.
  865                  * Tell rx_intr to drop the packets it dequeues.
  866                  */
  867                 LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode & ~TULIP_CMD_RXRUN);
  868                 while ((LMC_CSR_READ(sc, csr_status) & TULIP_STS_RXSTOPPED) == 0)
  869                     ;
  870                 LMC_CSR_WRITE(sc, csr_status, TULIP_STS_RXSTOPPED);
  871                 sc->lmc_flags |= LMC_RXIGNORE;
  872             }
  873             lmc_rx_intr(sc);
  874             if (sc->lmc_flags & LMC_RXIGNORE) {
  875                 /*
  876                  * Restart the receiver.
  877                  */
  878                 sc->lmc_flags &= ~LMC_RXIGNORE;
  879                 LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
  880             }
  881         }
  882         if (csr & TULIP_STS_ABNRMLINTR) {
  883             u_int32_t tmp = csr & sc->lmc_intrmask
  884                 & ~(TULIP_STS_NORMALINTR|TULIP_STS_ABNRMLINTR);
  885             if (csr & TULIP_STS_TXUNDERFLOW) {
  886                 if ((sc->lmc_cmdmode & TULIP_CMD_THRESHOLDCTL) != TULIP_CMD_THRSHLD160) {
  887                     sc->lmc_cmdmode += TULIP_CMD_THRSHLD96;
  888                     sc->lmc_flags |= LMC_NEWTXTHRESH;
  889                 } else if (sc->lmc_features & LMC_HAVE_STOREFWD) {
  890                     sc->lmc_cmdmode |= TULIP_CMD_STOREFWD;
  891                     sc->lmc_flags |= LMC_NEWTXTHRESH;
  892                 }
  893             }
  894             if (sc->lmc_flags & LMC_NOMESSAGES) {
  895                 sc->lmc_statusbits |= tmp;
  896             } else {
  897                 lmc_print_abnormal_interrupt(sc, tmp);
  898                 sc->lmc_flags |= LMC_NOMESSAGES;
  899             }
  900             LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
  901         }
  902 
  903         if (csr & TULIP_STS_TXINTR)
  904                 lmc_tx_intr(sc);
  905 
  906         if (sc->lmc_flags & LMC_WANTTXSTART)
  907             lmc_ifstart(&sc->lmc_if);
  908     }
  909 }
  910 
  911 lmc_intrfunc_t
  912 lmc_intr_normal(void *arg)
  913 {
  914         lmc_softc_t * sc = (lmc_softc_t *) arg;
  915         int progress = 0;
  916 
  917         lmc_intr_handler(sc, &progress);
  918 
  919 #if !defined(LMC_VOID_INTRFUNC)
  920         return progress;
  921 #endif
  922 }
  923 
  924 static struct mbuf *
  925 lmc_mbuf_compress(struct mbuf *m)
  926 {
  927         struct mbuf *m0;
  928 #if MCLBYTES >= LMC_MTU + PPP_HEADER_LEN && !defined(BIG_PACKET)
  929         MGETHDR(m0, M_DONTWAIT, MT_DATA);
  930         if (m0 != NULL) {
  931                 if (m->m_pkthdr.len > MHLEN) {
  932                         MCLGET(m0, M_DONTWAIT);
  933                         if ((m0->m_flags & M_EXT) == 0) {
  934                                 m_freem(m);
  935                                 m_freem(m0);
  936                                 return NULL;
  937                         }
  938                 }
  939                 m_copydata(m, 0, m->m_pkthdr.len, mtod(m0, caddr_t));
  940                 m0->m_pkthdr.len = m0->m_len = m->m_pkthdr.len;
  941         }
  942 #else
  943         int mlen = MHLEN;
  944         int len = m->m_pkthdr.len;
  945         struct mbuf **mp = &m0;
  946 
  947         while (len > 0) {
  948                 if (mlen == MHLEN) {
  949                         MGETHDR(*mp, M_DONTWAIT, MT_DATA);
  950                 } else {
  951                         MGET(*mp, M_DONTWAIT, MT_DATA);
  952                 }
  953                 if (*mp == NULL) {
  954                         m_freem(m0);
  955                         m0 = NULL;
  956                         break;
  957                 }
  958                 if (len > MLEN) {
  959                         MCLGET(*mp, M_DONTWAIT);
  960                         if (((*mp)->m_flags & M_EXT) == 0) {
  961                                 m_freem(m0);
  962                                 m0 = NULL;
  963                                 break;
  964                         }
  965                         (*mp)->m_len = (len <= MCLBYTES ? len : MCLBYTES);
  966                 } else {
  967                         (*mp)->m_len = (len <= mlen ? len : mlen);
  968                 }
  969                 m_copydata(m, m->m_pkthdr.len - len,
  970                            (*mp)->m_len, mtod((*mp), caddr_t));
  971                 len -= (*mp)->m_len;
  972                 mp = &(*mp)->m_next;
  973                 mlen = MLEN;
  974         }
  975 #endif
  976         m_freem(m);
  977         return m0;
  978 }
  979 
  980 /*
  981  * queue the mbuf handed to us for the interface.  If we cannot
  982  * queue it, return the mbuf.  Return NULL if the mbuf was queued.
  983  */
  984 static struct mbuf *
  985 lmc_txput(lmc_softc_t * const sc, struct mbuf *m)
  986 {
  987         lmc_ringinfo_t * const ri = &sc->lmc_txinfo;
  988         lmc_desc_t *eop, *nextout;
  989         int segcnt, free;
  990         u_int32_t d_status, ctl;
  991         bus_dmamap_t map;
  992         int error;
  993 
  994 #if defined(LMC_DEBUG)
  995         if ((sc->lmc_cmdmode & TULIP_CMD_TXRUN) == 0) {
  996                 printf(LMC_PRINTF_FMT ": txput: tx not running\n",
  997                        LMC_PRINTF_ARGS);
  998                 sc->lmc_flags |= LMC_WANTTXSTART;
  999                 goto finish;
 1000         }
 1001 #endif
 1002 
 1003         /*
 1004          * Now we try to fill in our transmit descriptors.  This is
 1005          * a bit reminiscent of going on the Ark two by two
 1006          * since each descriptor for the TULIP can describe
 1007          * two buffers.  So we advance through packet filling
 1008          * each of the two entries at a time to fill each
 1009          * descriptor.  Clear the first and last segment bits
 1010          * in each descriptor (actually just clear everything
 1011          * but the end-of-ring or chain bits) to make sure
 1012          * we don't get messed up by previously sent packets.
 1013          *
 1014          * We may fail to put the entire packet on the ring if
 1015          * there is either not enough ring entries free or if the
 1016          * packet has more than MAX_TXSEG segments.  In the former
 1017          * case we will just wait for the ring to empty.  In the
 1018          * latter case we have to recopy.
 1019          */
 1020         d_status = 0;
 1021         eop = nextout = ri->ri_nextout;
 1022         segcnt = 0;
 1023         free = ri->ri_free;
 1024         /*
 1025          * Reclaim some DMA maps from if we are out.
 1026          */
 1027         if (sc->lmc_txmaps_free == 0) {
 1028 #if defined(LMC_DEBUG)
 1029                 sc->lmc_dbg.dbg_no_txmaps++;
 1030 #endif
 1031                 free += lmc_tx_intr(sc);
 1032         }
 1033         if (sc->lmc_txmaps_free > 0) {
 1034                 map = sc->lmc_txmaps[sc->lmc_txmaps_free-1];
 1035         } else {
 1036                 sc->lmc_flags |= LMC_WANTTXSTART;
 1037 #if defined(LMC_DEBUG)
 1038                 sc->lmc_dbg.dbg_txput_finishes[1]++;
 1039 #endif
 1040                 goto finish;
 1041         }
 1042         error = bus_dmamap_load_mbuf(sc->lmc_dmatag, map, m, BUS_DMA_NOWAIT);
 1043         if (error != 0) {
 1044                 if (error == EFBIG) {
 1045                         /*
 1046                          * The packet exceeds the number of transmit buffer
 1047                          * entries that we can use for one packet, so we have
 1048                          * to recopy it into one mbuf and then try again.
 1049                          */
 1050                         m = lmc_mbuf_compress(m);
 1051                         if (m == NULL) {
 1052 #if defined(LMC_DEBUG)
 1053                                 sc->lmc_dbg.dbg_txput_finishes[2]++;
 1054 #endif
 1055                                 goto finish;
 1056                         }
 1057                         error = bus_dmamap_load_mbuf(sc->lmc_dmatag, map, m,
 1058                                 BUS_DMA_NOWAIT);
 1059                 }
 1060                 if (error != 0) {
 1061                         printf(LMC_PRINTF_FMT ": unable to load tx map, "
 1062                                 "error = %d\n", LMC_PRINTF_ARGS, error);
 1063 #if defined(LMC_DEBUG)
 1064                         sc->lmc_dbg.dbg_txput_finishes[3]++;
 1065 #endif
 1066                         goto finish;
 1067                 }
 1068         }
 1069         if ((free -= (map->dm_nsegs + 1) / 2) <= 0
 1070                 /*
 1071                  * See if there's any unclaimed space in the transmit ring.
 1072                  */
 1073                 && (free += lmc_tx_intr(sc)) <= 0) {
 1074                 /*
 1075                  * There's no more room but since nothing
 1076                  * has been committed at this point, just
 1077                  * show output is active, put back the
 1078                  * mbuf and return.
 1079                  */
 1080                 sc->lmc_flags |= LMC_WANTTXSTART;
 1081 #if defined(LMC_DEBUG)
 1082                 sc->lmc_dbg.dbg_txput_finishes[4]++;
 1083 #endif
 1084                 bus_dmamap_unload(sc->lmc_dmatag, map);
 1085                 goto finish;
 1086         }
 1087         for (; map->dm_nsegs - segcnt > 1; segcnt += 2) {
 1088                 int flg;
 1089 
 1090                 eop = nextout;
 1091                 flg            = LMC_CTL_FLGS(letoh32(eop->d_ctl));
 1092                 flg           &= TULIP_DFLAG_ENDRING;
 1093                 flg           |= TULIP_DFLAG_TxNOPADDING;
 1094                 if (sc->ictl.crc_length == 16)
 1095                         flg |= TULIP_DFLAG_TxHASCRC;
 1096                 eop->d_status  = htole32(d_status);
 1097                 eop->d_addr1   = htole32(map->dm_segs[segcnt].ds_addr);
 1098                 eop->d_addr2   = htole32(map->dm_segs[segcnt+1].ds_addr);
 1099                 eop->d_ctl     = htole32(LMC_CTL(flg, 
 1100                                  map->dm_segs[segcnt].ds_len,
 1101                                  map->dm_segs[segcnt+1].ds_len));
 1102                 d_status = TULIP_DSTS_OWNER;
 1103                 if (++nextout == ri->ri_last)
 1104                         nextout = ri->ri_first;
 1105         }
 1106         if (segcnt < map->dm_nsegs) {
 1107                 int flg;
 1108 
 1109                 eop = nextout;
 1110                 flg            = LMC_CTL_FLGS(letoh32(eop->d_ctl));
 1111                 flg           &= TULIP_DFLAG_ENDRING;
 1112                 flg           |= TULIP_DFLAG_TxNOPADDING;
 1113                 if (sc->ictl.crc_length == 16)
 1114                         flg |= TULIP_DFLAG_TxHASCRC;
 1115                 eop->d_status  = htole32(d_status);
 1116                 eop->d_addr1   = htole32(map->dm_segs[segcnt].ds_addr);
 1117                 eop->d_addr2   = 0;
 1118                 eop->d_ctl     = htole32(LMC_CTL(flg, 
 1119                                  map->dm_segs[segcnt].ds_len, 0));
 1120                 if (++nextout == ri->ri_last)
 1121                         nextout = ri->ri_first;
 1122         }
 1123         LMC_TXMAP_PRESYNC(sc, map);
 1124         LMC_SETCTX(m, map);
 1125         map = NULL;
 1126         --sc->lmc_txmaps_free;          /* commit to using the dmamap */
 1127 
 1128         /*
 1129          * The descriptors have been filled in.  Now get ready
 1130          * to transmit.
 1131          */
 1132         IF_ENQUEUE(&sc->lmc_txq, m);
 1133         m = NULL;
 1134 
 1135         /*
 1136          * Make sure the next descriptor after this packet is owned
 1137          * by us since it may have been set up above if we ran out
 1138          * of room in the ring.
 1139          */
 1140         nextout->d_status = 0;
 1141         LMC_TXDESC_PRESYNC(sc, nextout, sizeof(u_int32_t));
 1142 
 1143         /*
 1144          * Mark the last and first segments, indicate we want a transmit
 1145          * complete interrupt, and tell it to transmit!
 1146          */
 1147         ctl = letoh32(eop->d_ctl);
 1148         eop->d_ctl = htole32(LMC_CTL(
 1149                 LMC_CTL_FLGS(ctl)|TULIP_DFLAG_TxLASTSEG|TULIP_DFLAG_TxWANTINTR,
 1150                 LMC_CTL_LEN1(ctl),
 1151                 LMC_CTL_LEN2(ctl)));
 1152 
 1153         /*
 1154          * Note that ri->ri_nextout is still the start of the packet
 1155          * and until we set the OWNER bit, we can still back out of
 1156          * everything we have done.
 1157          */
 1158         ctl = letoh32(ri->ri_nextout->d_ctl);
 1159         ri->ri_nextout->d_ctl = htole32(LMC_CTL(
 1160                 LMC_CTL_FLGS(ctl)|TULIP_DFLAG_TxFIRSTSEG,
 1161                 LMC_CTL_LEN1(ctl),
 1162                 LMC_CTL_LEN2(ctl)));
 1163         if (eop < ri->ri_nextout) {
 1164                 LMC_TXDESC_PRESYNC(sc, ri->ri_nextout,
 1165                         (caddr_t) ri->ri_last - (caddr_t) ri->ri_nextout);
 1166                 LMC_TXDESC_PRESYNC(sc, ri->ri_first,
 1167                         (caddr_t) (eop + 1) - (caddr_t) ri->ri_first);
 1168         } else {
 1169                 LMC_TXDESC_PRESYNC(sc, ri->ri_nextout,
 1170                         (caddr_t) (eop + 1) - (caddr_t) ri->ri_nextout);
 1171         }
 1172         ri->ri_nextout->d_status = htole32(TULIP_DSTS_OWNER);
 1173         LMC_TXDESC_PRESYNC(sc, ri->ri_nextout, sizeof(u_int32_t));
 1174 
 1175         LMC_CSR_WRITE(sc, csr_txpoll, 1);
 1176 
 1177         /*
 1178          * This advances the ring for us.
 1179          */
 1180         ri->ri_nextout = nextout;
 1181         ri->ri_free = free;
 1182 
 1183         /*
 1184          * switch back to the single queueing ifstart.
 1185          */
 1186         sc->lmc_flags &= ~LMC_WANTTXSTART;
 1187         sc->lmc_if.if_start = lmc_ifstart_one;
 1188 
 1189         /*
 1190          * If we want a txstart, there must be not enough space in the
 1191          * transmit ring.  So we want to enable transmit done interrupts
 1192          * so we can immediately reclaim some space.  When the transmit
 1193          * interrupt is posted, the interrupt handler will call tx_intr
 1194          * to reclaim space and then txstart (since WANTTXSTART is set).
 1195          * txstart will move the packet into the transmit ring and clear
 1196          * WANTTXSTART thereby causing TXINTR to be cleared.
 1197          */
 1198  finish:
 1199         if (sc->lmc_flags & LMC_WANTTXSTART) {
 1200                 sc->lmc_if.if_flags |= IFF_OACTIVE;
 1201                 sc->lmc_if.if_start = lmc_ifstart;
 1202         }
 1203 
 1204         return m;
 1205 }
 1206 
 1207 
 1208 /*
 1209  * This routine is entered at splnet()
 1210  */
 1211 static int
 1212 lmc_ifioctl(struct ifnet * ifp, ioctl_cmd_t cmd, caddr_t data)
 1213 {
 1214         lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
 1215         int s;
 1216         struct proc *p = curproc;
 1217         int error = 0;
 1218         struct ifreq *ifr = (struct ifreq *)data;
 1219         u_int32_t new_state;
 1220         u_int32_t old_state;
 1221         lmc_ctl_t ctl;
 1222 
 1223         s = LMC_RAISESPL();
 1224 
 1225         switch (cmd) {
 1226         case LMCIOCGINFO:
 1227                 error = copyout(&sc->ictl, ifr->ifr_data, sizeof(lmc_ctl_t));
 1228 
 1229                 goto out;
 1230                 break;
 1231 
 1232         case LMCIOCSINFO:
 1233                 error = suser(p, 0);
 1234                 if (error)
 1235                         goto out;
 1236 
 1237                 error = copyin(ifr->ifr_data, &ctl, sizeof(lmc_ctl_t));
 1238                 if (error != 0)
 1239                         goto out;
 1240 
 1241                 sc->lmc_media->set_status(sc, &ctl);
 1242 
 1243                 goto out;
 1244                 break;
 1245 
 1246         case SIOCSIFMTU:
 1247                 /*
 1248                  * Don't allow the MTU to get larger than we can handle
 1249                  */
 1250                 if (ifr->ifr_mtu > LMC_MTU) {
 1251                         error = EINVAL;
 1252                         goto out;
 1253                 } else {
 1254                         ifp->if_mtu = ifr->ifr_mtu;
 1255                 }
 1256                 break;
 1257         }
 1258 
 1259         /*
 1260          * call the sppp ioctl layer
 1261          */
 1262         error = sppp_ioctl(ifp, cmd, data);
 1263         if (error != 0)
 1264                 goto out;
 1265 
 1266         /*
 1267          * If we are transitioning from up to down or down to up, call
 1268          * our init routine.
 1269          */
 1270         new_state = ifp->if_flags & IFF_UP;
 1271         old_state = sc->lmc_flags & LMC_IFUP;
 1272 
 1273         if (new_state && !old_state)
 1274                 lmc_ifup(sc);
 1275         else if (!new_state && old_state)
 1276                 lmc_ifdown(sc);
 1277 
 1278  out:
 1279         LMC_RESTORESPL(s);
 1280 
 1281         return error;
 1282 }
 1283 
 1284 /*
 1285  * These routines gets called at device spl (from sppp_output).
 1286  */
 1287 
 1288 static ifnet_ret_t
 1289 lmc_ifstart(struct ifnet * const ifp)
 1290 {
 1291         lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
 1292         struct mbuf *m, *m0;
 1293 
 1294         if (sc->lmc_flags & LMC_IFUP) {
 1295                 while (sppp_isempty(ifp) == 0) {
 1296                         m = sppp_pick(ifp);
 1297                         if (m == NULL)
 1298                                 break;
 1299                         if ((m = lmc_txput(sc, m)) != NULL)
 1300                                 break;
 1301                         m0 = sppp_dequeue(ifp);
 1302 #if defined(LMC_DEBUG)
 1303                         if (m0 != m)
 1304                                 printf("lmc_ifstart: mbuf mismatch!\n");
 1305 #endif
 1306                 }
 1307                 LMC_CSR_WRITE(sc, csr_txpoll, 1);
 1308         }
 1309 }
 1310 
 1311 static ifnet_ret_t
 1312 lmc_ifstart_one(struct ifnet * const ifp)
 1313 {
 1314         lmc_softc_t * const sc = LMC_IFP_TO_SOFTC(ifp);
 1315         struct mbuf *m, *m0;
 1316 
 1317         if ((sc->lmc_flags & LMC_IFUP) && (sppp_isempty(ifp) == 0)) {
 1318                 m = sppp_pick(ifp);
 1319                 if ((m = lmc_txput(sc, m)) != NULL)
 1320                         return;
 1321                 m0 = sppp_dequeue(ifp);
 1322 #if defined(LMC_DEBUG)
 1323                 if (m0 != m)
 1324                         printf("lmc_ifstart: mbuf mismatch!\n");
 1325 #endif
 1326                 LMC_CSR_WRITE(sc, csr_txpoll, 1);
 1327         }
 1328 }
 1329 
 1330 /*
 1331  * Set up the OS interface magic and attach to the operating system
 1332  * network services.
 1333  */
 1334 void
 1335 lmc_attach(lmc_softc_t * const sc)
 1336 {
 1337         struct ifnet * const ifp = &sc->lmc_if;
 1338 
 1339         ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
 1340         ifp->if_ioctl = lmc_ifioctl;
 1341         ifp->if_start = lmc_ifstart;
 1342         ifp->if_watchdog = lmc_watchdog;
 1343         ifp->if_timer = 1;
 1344         ifp->if_mtu = LMC_MTU;
 1345         IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
 1346         IFQ_SET_READY(&ifp->if_snd);
 1347   
 1348         if_attach(ifp);
 1349         if_alloc_sadl(ifp);
 1350 
 1351         sppp_attach((struct ifnet *)&sc->lmc_sppp);
 1352         sc->lmc_sppp.pp_flags = PP_CISCO | PP_KEEPALIVE;
 1353         sc->lmc_sppp.pp_framebytes = 3;
 1354 
 1355 #if NBPFILTER > 0
 1356         LMC_BPF_ATTACH(sc);
 1357 #endif
 1358 
 1359         /*
 1360          * turn off those LEDs...
 1361          */
 1362         sc->lmc_miireg16 |= LMC_MII16_LED_ALL;
 1363         /*
 1364          * for DS3 & DS1 adapters light the green light, led2
 1365          */
 1366         if (sc->lmc_cardtype == LMC_CARDTYPE_DS3 ||
 1367             sc->lmc_cardtype == LMC_CARDTYPE_T1)
 1368                 lmc_led_on (sc, LMC_MII16_LED2);
 1369         else
 1370                 lmc_led_on (sc, LMC_MII16_LED0 | LMC_MII16_LED2);
 1371 }
 1372 
 1373 void
 1374 lmc_initring(lmc_softc_t * const sc, lmc_ringinfo_t * const ri,
 1375                lmc_desc_t *descs, int ndescs)
 1376 {
 1377         ri->ri_max = ndescs;
 1378         ri->ri_first = descs;
 1379         ri->ri_last = ri->ri_first + ri->ri_max;
 1380         bzero((caddr_t) ri->ri_first, sizeof(ri->ri_first[0]) * ri->ri_max);
 1381         ri->ri_last[-1].d_ctl = htole32(LMC_CTL(TULIP_DFLAG_ENDRING, 0, 0));
 1382 }

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