home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / hp300 / dev / if_le.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-08  |  21.7 KB  |  885 lines

  1. /*
  2.  * Copyright (c) 1982, 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  *    @(#)if_le.c    7.6 (Berkeley) 5/8/91
  34.  */
  35.  
  36. #include "le.h"
  37. #if NLE > 0
  38.  
  39. #include "bpfilter.h"
  40.  
  41. /*
  42.  * AMD 7990 LANCE
  43.  *
  44.  * This driver will generate and accept tailer encapsulated packets even
  45.  * though it buys us nothing.  The motivation was to avoid incompatibilities
  46.  * with VAXen, SUNs, and others that handle and benefit from them.
  47.  * This reasoning is dubious.
  48.  */
  49. #include "sys/param.h"
  50. #include "sys/systm.h"
  51. #include "sys/mbuf.h"
  52. #include "sys/buf.h"
  53. #include "sys/protosw.h"
  54. #include "sys/socket.h"
  55. #include "sys/syslog.h"
  56. #include "sys/ioctl.h"
  57. #include "sys/errno.h"
  58.  
  59. #include "net/if.h"
  60. #include "net/netisr.h"
  61. #include "net/route.h"
  62.  
  63. #ifdef INET
  64. #include "netinet/in.h"
  65. #include "netinet/in_systm.h"
  66. #include "netinet/in_var.h"
  67. #include "netinet/ip.h"
  68. #include "netinet/if_ether.h"
  69. #endif
  70.  
  71. #ifdef NS
  72. #include "netns/ns.h"
  73. #include "netns/ns_if.h"
  74. #endif
  75.  
  76. #ifdef RMP
  77. #include "netrmp/rmp.h"
  78. #include "netrmp/rmp_var.h"
  79. #endif
  80.  
  81. #include "../include/cpu.h"
  82. #include "../hp300/isr.h"
  83. #include "../include/mtpr.h"
  84. #include "device.h"
  85. #include "if_lereg.h"
  86.  
  87. #if NBPFILTER > 0
  88. #include "../net/bpf.h"
  89. #include "../net/bpfdesc.h"
  90. #endif
  91.  
  92. /* offsets for:       ID,   REGS,    MEM,  NVRAM */
  93. int    lestd[] = { 0, 0x4000, 0x8000, 0xC008 };
  94.  
  95. int    leattach();
  96. struct    driver ledriver = {
  97.     leattach, "le",
  98. };
  99.  
  100. struct    isr le_isr[NLE];
  101. int    ledebug = 0;        /* console error messages */
  102.  
  103. int    leintr(), leinit(), leioctl(), lestart(), ether_output();
  104. struct    mbuf *leget();
  105. extern    struct ifnet loif;
  106.  
  107. /*
  108.  * Ethernet software status per interface.
  109.  *
  110.  * Each interface is referenced by a network interface structure,
  111.  * le_if, which the routing code uses to locate the interface.
  112.  * This structure contains the output queue for the interface, its address, ...
  113.  */
  114. struct    le_softc {
  115.     struct    arpcom sc_ac;    /* common Ethernet structures */
  116. #define    sc_if    sc_ac.ac_if    /* network-visible interface */
  117. #define    sc_addr    sc_ac.ac_enaddr    /* hardware Ethernet address */
  118.     struct    lereg0 *sc_r0;    /* DIO registers */
  119.     struct    lereg1 *sc_r1;    /* LANCE registers */
  120.     struct    lereg2 *sc_r2;    /* dual-port RAM */
  121.     int    sc_rmd;        /* predicted next rmd to process */
  122.     int    sc_runt;
  123.     int    sc_jab;
  124.     int    sc_merr;
  125.     int    sc_babl;
  126.     int    sc_cerr;
  127.     int    sc_miss;
  128.     int    sc_xint;
  129.     int    sc_xown;
  130.     int    sc_uflo;
  131.     int    sc_rxlen;
  132.     int    sc_rxoff;
  133.     int    sc_txoff;
  134.     int    sc_busy;
  135.     short    sc_iflags;
  136. #if NBPFILTER > 0
  137.     caddr_t sc_bpf;
  138. #endif
  139. } le_softc[NLE];
  140.  
  141. /* access LANCE registers */
  142. #define    LERDWR(cntl, src, dst) \
  143.     do { \
  144.         (dst) = (src); \
  145.     } while (((cntl)->ler0_status & LE_ACK) == 0);
  146.  
  147. /*
  148.  * Interface exists: make available by filling in network interface
  149.  * record.  System will initialize the interface when it is ready
  150.  * to accept packets.
  151.  */
  152. leattach(hd)
  153.     struct hp_device *hd;
  154. {
  155.     register struct lereg0 *ler0;
  156.     register struct lereg2 *ler2;
  157.     struct lereg2 *lemem = 0;
  158.     struct le_softc *le = &le_softc[hd->hp_unit];
  159.     struct ifnet *ifp = &le->sc_if;
  160.     char *cp;
  161.     int i;
  162.  
  163.     ler0 = le->sc_r0 = (struct lereg0 *)(lestd[0] + (int)hd->hp_addr);
  164.     le->sc_r1 = (struct lereg1 *)(lestd[1] + (int)hd->hp_addr);
  165.     ler2 = le->sc_r2 = (struct lereg2 *)(lestd[2] + (int)hd->hp_addr);
  166.     if (ler0->ler0_id != LEID)
  167.         return(0);
  168.     le_isr[hd->hp_unit].isr_intr = leintr;
  169.     hd->hp_ipl = le_isr[hd->hp_unit].isr_ipl = LE_IPL(ler0->ler0_status);
  170.     le_isr[hd->hp_unit].isr_arg = hd->hp_unit;
  171.     ler0->ler0_id = 0xFF;
  172.     DELAY(100);
  173.  
  174.     /*
  175.      * Read the ethernet address off the board, one nibble at a time.
  176.      */
  177.     cp = (char *)(lestd[3] + (int)hd->hp_addr);
  178.     for (i = 0; i < sizeof(le->sc_addr); i++) {
  179.         le->sc_addr[i] = (*++cp & 0xF) << 4;
  180.         cp++;
  181.         le->sc_addr[i] |= *++cp & 0xF;
  182.         cp++;
  183.     }
  184.     printf("le%d: hardware address %s\n", hd->hp_unit,
  185.         ether_sprintf(le->sc_addr));
  186.  
  187.     /*
  188.      * Setup for transmit/receive
  189.      */
  190.     ler2->ler2_mode = LE_MODE;
  191.     ler2->ler2_padr[0] = le->sc_addr[1];
  192.     ler2->ler2_padr[1] = le->sc_addr[0];
  193.     ler2->ler2_padr[2] = le->sc_addr[3];
  194.     ler2->ler2_padr[3] = le->sc_addr[2];
  195.     ler2->ler2_padr[4] = le->sc_addr[5];
  196.     ler2->ler2_padr[5] = le->sc_addr[4];
  197. #ifdef RMP
  198.     /*
  199.      * Set up logical addr filter to accept multicast 9:0:9:0:0:4
  200.      * This should be an ioctl() to the driver.  (XXX)
  201.      */
  202.     ler2->ler2_ladrf0 = 0x00100000;
  203.     ler2->ler2_ladrf1 = 0x0;
  204. #else
  205.     ler2->ler2_ladrf0 = 0;
  206.     ler2->ler2_ladrf1 = 0;
  207. #endif
  208.     ler2->ler2_rlen = LE_RLEN;
  209.     ler2->ler2_rdra = (int)lemem->ler2_rmd;
  210.     ler2->ler2_tlen = LE_TLEN;
  211.     ler2->ler2_tdra = (int)lemem->ler2_tmd;
  212.     isrlink(&le_isr[hd->hp_unit]);
  213.     ler0->ler0_status = LE_IE;
  214.  
  215.     ifp->if_unit = hd->hp_unit;
  216.     ifp->if_name = "le";
  217.     ifp->if_mtu = ETHERMTU;
  218.     ifp->if_init = leinit;
  219.     ifp->if_ioctl = leioctl;
  220.     ifp->if_output = ether_output;
  221.     ifp->if_start = lestart;
  222.     ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
  223. #if NBPFILTER > 0
  224.     bpfattach(&le->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
  225. #endif
  226.     if_attach(ifp);
  227.     return (1);
  228. }
  229.  
  230. ledrinit(ler2)
  231.     register struct lereg2 *ler2;
  232. {
  233.     register struct lereg2 *lemem = 0;
  234.     register int i;
  235.  
  236.     for (i = 0; i < LERBUF; i++) {
  237.         ler2->ler2_rmd[i].rmd0 = (int)lemem->ler2_rbuf[i];
  238.         ler2->ler2_rmd[i].rmd1 = LE_OWN;
  239.         ler2->ler2_rmd[i].rmd2 = -LEMTU;
  240.         ler2->ler2_rmd[i].rmd3 = 0;
  241.     }
  242.     for (i = 0; i < LETBUF; i++) {
  243.         ler2->ler2_tmd[i].tmd0 = (int)lemem->ler2_tbuf[i];
  244.         ler2->ler2_tmd[i].tmd1 = 0;
  245.         ler2->ler2_tmd[i].tmd2 = 0;
  246.         ler2->ler2_tmd[i].tmd3 = 0;
  247.     }
  248. }
  249.  
  250. lereset(unit)
  251.     register int unit;
  252. {
  253.     register struct le_softc *le = &le_softc[unit];
  254.     register struct lereg0 *ler0 = le->sc_r0;
  255.     register struct lereg1 *ler1 = le->sc_r1;
  256.     register struct lereg2 *lemem = 0;
  257.     register int timo = 100000;
  258.     register int stat;
  259.  
  260. #ifdef lint
  261.     stat = unit;
  262. #endif
  263. #if NBPFILTER > 0
  264.     if (le->sc_if.if_flags & IFF_PROMISC)
  265.         /* set the promiscuous bit */
  266.         le->sc_r2->ler2_mode = LE_MODE|0x8000;
  267.     else
  268.         le->sc_r2->ler2_mode = LE_MODE;
  269. #endif
  270.     LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
  271.     LERDWR(ler0, LE_STOP, ler1->ler1_rdp);
  272.     ledrinit(le->sc_r2);
  273.     le->sc_rmd = 0;
  274.     LERDWR(ler0, LE_CSR1, ler1->ler1_rap);
  275.     LERDWR(ler0, (int)&lemem->ler2_mode, ler1->ler1_rdp);
  276.     LERDWR(ler0, LE_CSR2, ler1->ler1_rap);
  277.     LERDWR(ler0, 0, ler1->ler1_rdp);
  278.     LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
  279.     LERDWR(ler0, LE_INIT, ler1->ler1_rdp);
  280.     do {
  281.         if (--timo == 0) {
  282.             printf("le%d: init timeout, stat = 0x%x\n",
  283.                    unit, stat);
  284.             break;
  285.         }
  286.         LERDWR(ler0, ler1->ler1_rdp, stat);
  287.     } while ((stat & LE_IDON) == 0);
  288.     LERDWR(ler0, LE_STOP, ler1->ler1_rdp);
  289.     LERDWR(ler0, LE_CSR3, ler1->ler1_rap);
  290.     LERDWR(ler0, LE_BSWP, ler1->ler1_rdp);
  291.     LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
  292.     LERDWR(ler0, LE_STRT | LE_INEA, ler1->ler1_rdp);
  293.     le->sc_if.if_flags &= ~IFF_OACTIVE;
  294. }
  295.  
  296. /*
  297.  * Initialization of interface
  298.  */
  299. leinit(unit)
  300.     int unit;
  301. {
  302.     struct le_softc *le = &le_softc[unit];
  303.     register struct ifnet *ifp = &le->sc_if;
  304.     int s;
  305.  
  306.     /* not yet, if address still unknown */
  307.     if (ifp->if_addrlist == (struct ifaddr *)0)
  308.         return;
  309.     if ((ifp->if_flags & IFF_RUNNING) == 0) {
  310.         s = splimp();
  311.         ifp->if_flags |= IFF_RUNNING;
  312.         lereset(unit);
  313.             (void) lestart(ifp);
  314.         splx(s);
  315.     }
  316. }
  317.  
  318. /*
  319.  * Start output on interface.  Get another datagram to send
  320.  * off of the interface queue, and copy it to the interface
  321.  * before starting the output.
  322.  */
  323. lestart(ifp)
  324.     struct ifnet *ifp;
  325. {
  326.     register struct le_softc *le = &le_softc[ifp->if_unit];
  327.     register struct letmd *tmd;
  328.     register struct mbuf *m;
  329.     int len;
  330.  
  331.     if ((le->sc_if.if_flags & IFF_RUNNING) == 0)
  332.         return (0);
  333.     IF_DEQUEUE(&le->sc_if.if_snd, m);
  334.     if (m == 0)
  335.         return (0);
  336.     len = leput(le->sc_r2->ler2_tbuf[0], m);
  337. #if NBPFILTER > 0
  338.     /*
  339.      * If bpf is listening on this interface, let it
  340.      * see the packet before we commit it to the wire.
  341.      */
  342.     if (le->sc_bpf)
  343.                 bpf_tap(le->sc_bpf, le->sc_r2->ler2_tbuf[0], len);
  344. #endif
  345.     tmd = le->sc_r2->ler2_tmd;
  346.     tmd->tmd3 = 0;
  347.     tmd->tmd2 = -len;
  348.     tmd->tmd1 = LE_OWN | LE_STP | LE_ENP;
  349.     le->sc_if.if_flags |= IFF_OACTIVE;
  350.     return (0);
  351. }
  352.  
  353. leintr(unit)
  354.     register int unit;
  355. {
  356.     register struct le_softc *le = &le_softc[unit];
  357.     register struct lereg0 *ler0 = le->sc_r0;
  358.     register struct lereg1 *ler1;
  359.     register int stat;
  360.  
  361.     if ((ler0->ler0_status & LE_IR) == 0)
  362.         return(0);
  363.     if (ler0->ler0_status & LE_JAB) {
  364.         le->sc_jab++;
  365.         lereset(unit);
  366.         return(1);
  367.     }
  368.     ler1 = le->sc_r1;
  369.     LERDWR(ler0, ler1->ler1_rdp, stat);
  370.     if (stat & LE_SERR) {
  371.         leerror(unit, stat);
  372.         if (stat & LE_MERR) {
  373.             le->sc_merr++;
  374.             lereset(unit);
  375.             return(1);
  376.         }
  377.         if (stat & LE_BABL)
  378.             le->sc_babl++;
  379.         if (stat & LE_CERR)
  380.             le->sc_cerr++;
  381.         if (stat & LE_MISS)
  382.             le->sc_miss++;
  383.         LERDWR(ler0, LE_BABL|LE_CERR|LE_MISS|LE_INEA, ler1->ler1_rdp);
  384.     }
  385.     if ((stat & LE_RXON) == 0) {
  386.         le->sc_rxoff++;
  387.         lereset(unit);
  388.         return(1);
  389.     }
  390.     if ((stat & LE_TXON) == 0) {
  391.         le->sc_txoff++;
  392.         lereset(unit);
  393.         return(1);
  394.     }
  395.     if (stat & LE_RINT) {
  396.         /* interrupt is cleared in lerint */
  397.         lerint(unit);
  398.     }
  399.     if (stat & LE_TINT) {
  400.         LERDWR(ler0, LE_TINT|LE_INEA, ler1->ler1_rdp);
  401.         lexint(unit);
  402.     }
  403.     return(1);
  404. }
  405.  
  406. /*
  407.  * Ethernet interface transmitter interrupt.
  408.  * Start another output if more data to send.
  409.  */
  410. lexint(unit)
  411.     register int unit;
  412. {
  413.     register struct le_softc *le = &le_softc[unit];
  414.     register struct letmd *tmd = le->sc_r2->ler2_tmd;
  415.  
  416.     if ((le->sc_if.if_flags & IFF_OACTIVE) == 0) {
  417.         le->sc_xint++;
  418.         return;
  419.     }
  420.     if (tmd->tmd1 & LE_OWN) {
  421.         le->sc_xown++;
  422.         return;
  423.     }
  424.     if (tmd->tmd1 & LE_ERR) {
  425. err:
  426.         lexerror(unit);
  427.         le->sc_if.if_oerrors++;
  428.         if (tmd->tmd3 & (LE_TBUFF|LE_UFLO)) {
  429.             le->sc_uflo++;
  430.             lereset(unit);
  431.         }
  432.         else if (tmd->tmd3 & LE_LCOL)
  433.             le->sc_if.if_collisions++;
  434.         else if (tmd->tmd3 & LE_RTRY)
  435.             le->sc_if.if_collisions += 16;
  436.     }
  437.     else if (tmd->tmd3 & LE_TBUFF)
  438.         /* XXX documentation says BUFF not included in ERR */
  439.         goto err;
  440.     else if (tmd->tmd1 & LE_ONE)
  441.         le->sc_if.if_collisions++;
  442.     else if (tmd->tmd1 & LE_MORE)
  443.         /* what is the real number? */
  444.         le->sc_if.if_collisions += 2;
  445.     else
  446.         le->sc_if.if_opackets++;
  447.     le->sc_if.if_flags &= ~IFF_OACTIVE;
  448.     (void) lestart(&le->sc_if);
  449. }
  450.  
  451. #define    LENEXTRMP \
  452.     if (++bix == LERBUF) bix = 0, rmd = le->sc_r2->ler2_rmd; else ++rmd
  453.  
  454. /*
  455.  * Ethernet interface receiver interrupt.
  456.  * If input error just drop packet.
  457.  * Decapsulate packet based on type and pass to type specific
  458.  * higher-level input routine.
  459.  */
  460. lerint(unit)
  461.     int unit;
  462. {
  463.     register struct le_softc *le = &le_softc[unit];
  464.     register int bix = le->sc_rmd;
  465.     register struct lermd *rmd = &le->sc_r2->ler2_rmd[bix];
  466.  
  467.     /*
  468.      * Out of sync with hardware, should never happen?
  469.      */
  470.     if (rmd->rmd1 & LE_OWN) {
  471.         LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
  472.         return;
  473.     }
  474.  
  475.     /*
  476.      * Process all buffers with valid data
  477.      */
  478.     while ((rmd->rmd1 & LE_OWN) == 0) {
  479.         int len = rmd->rmd3;
  480.  
  481.         /* Clear interrupt to avoid race condition */
  482.         LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
  483.  
  484.         if (rmd->rmd1 & LE_ERR) {
  485.             le->sc_rmd = bix;
  486.             lererror(unit, "bad packet");
  487.             le->sc_if.if_ierrors++;
  488.         } else if ((rmd->rmd1 & (LE_STP|LE_ENP)) != (LE_STP|LE_ENP)) {
  489.             /*
  490.              * Find the end of the packet so we can see how long
  491.              * it was.  We still throw it away.
  492.              */
  493.             do {
  494.                 LERDWR(le->sc_r0, LE_RINT|LE_INEA,
  495.                        le->sc_r1->ler1_rdp);
  496.                 rmd->rmd3 = 0;
  497.                 rmd->rmd1 = LE_OWN;
  498.                 LENEXTRMP;
  499.             } while (!(rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)));
  500.             le->sc_rmd = bix;
  501.             lererror(unit, "chained buffer");
  502.             le->sc_rxlen++;
  503.             /*
  504.              * If search terminated without successful completion
  505.              * we reset the hardware (conservative).
  506.              */
  507.             if ((rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)) !=
  508.                 LE_ENP) {
  509.                 lereset(unit);
  510.                 return;
  511.             }
  512.         } else
  513.             leread(unit, le->sc_r2->ler2_rbuf[bix], len);
  514.         rmd->rmd3 = 0;
  515.         rmd->rmd1 = LE_OWN;
  516.         LENEXTRMP;
  517.     }
  518.     le->sc_rmd = bix;
  519. }
  520.  
  521. leread(unit, buf, len)
  522.     int unit;
  523.     char *buf;
  524.     int len;
  525. {
  526.     register struct le_softc *le = &le_softc[unit];
  527.     register struct ether_header *et;
  528.         struct mbuf *m;
  529.     int off, resid;
  530.  
  531.     le->sc_if.if_ipackets++;
  532.     et = (struct ether_header *)buf;
  533.     et->ether_type = ntohs((u_short)et->ether_type);
  534.     /* adjust input length to account for header and CRC */
  535.     len = len - sizeof(struct ether_header) - 4;
  536.  
  537. #ifdef RMP
  538.     /*  (XXX)
  539.      *
  540.      *  If Ethernet Type field is < MaxPacketSize, we probably have
  541.      *  a IEEE802 packet here.  Make sure that the size is at least
  542.      *  that of the HP LLC.  Also do sanity checks on length of LLC
  543.      *  (old Ethernet Type field) and packet length.
  544.      *
  545.      *  Provided the above checks succeed, change `len' to reflect
  546.      *  the length of the LLC (i.e. et->ether_type) and change the
  547.      *  type field to ETHERTYPE_IEEE so we can switch() on it later.
  548.      *  Yes, this is a hack and will eventually be done "right".
  549.      */
  550.     if (et->ether_type <= IEEE802LEN_MAX && len >= sizeof(struct hp_llc) &&
  551.         len >= et->ether_type && len >= IEEE802LEN_MIN) {
  552.         len = et->ether_type;
  553.         et->ether_type = ETHERTYPE_IEEE;    /* hack! */
  554.     }
  555. #endif
  556.  
  557. #define    ledataaddr(et, off, type)    ((type)(((caddr_t)((et)+1)+(off))))
  558.     if (et->ether_type >= ETHERTYPE_TRAIL &&
  559.         et->ether_type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER) {
  560.         off = (et->ether_type - ETHERTYPE_TRAIL) * 512;
  561.         if (off >= ETHERMTU)
  562.             return;        /* sanity */
  563.         et->ether_type = ntohs(*ledataaddr(et, off, u_short *));
  564.         resid = ntohs(*(ledataaddr(et, off+2, u_short *)));
  565.         if (off + resid > len)
  566.             return;        /* sanity */
  567.         len = off + resid;
  568.     } else
  569.         off = 0;
  570.  
  571.     if (len <= 0) {
  572.         if (ledebug)
  573.             log(LOG_WARNING,
  574.                 "le%d: ierror(runt packet): from %s: len=%d\n",
  575.                 unit, ether_sprintf(et->ether_shost), len);
  576.         le->sc_runt++;
  577.         le->sc_if.if_ierrors++;
  578.         return;
  579.     }
  580. #if NBPFILTER > 0
  581.     /*
  582.      * Check if there's a bpf filter listening on this interface.
  583.      * If so, hand off the raw packet to bpf, which must deal with
  584.      * trailers in its own way.
  585.      */
  586.     if (le->sc_bpf) {
  587.         bpf_tap(le->sc_bpf, buf, len + sizeof(struct ether_header));
  588.  
  589.         /*
  590.          * Note that the interface cannot be in promiscuous mode if
  591.          * there are no bpf listeners.  And if we are in promiscuous
  592.          * mode, we have to check if this packet is really ours.
  593.          *
  594.          * XXX This test does not support multicasts.
  595.          */
  596.         if ((le->sc_if.if_flags & IFF_PROMISC)
  597.             && bcmp(et->ether_dhost, le->sc_addr, 
  598.                 sizeof(et->ether_dhost)) != 0
  599.             && bcmp(et->ether_dhost, etherbroadcastaddr, 
  600.                 sizeof(et->ether_dhost)) != 0)
  601.             return;
  602.     }
  603. #endif
  604.     /*
  605.      * Pull packet off interface.  Off is nonzero if packet
  606.      * has trailing header; leget will then force this header
  607.      * information to be at the front, but we still have to drop
  608.      * the type and length which are at the front of any trailer data.
  609.      */
  610.     m = leget(buf, len, off, &le->sc_if);
  611.     if (m == 0)
  612.         return;
  613. #ifdef RMP
  614.     /*
  615.      * (XXX)
  616.      * This needs to be integrated with the ISO stuff in ether_input()
  617.      */
  618.     if (et->ether_type == ETHERTYPE_IEEE) {
  619.         /*
  620.          *  Snag the Logical Link Control header (IEEE 802.2).
  621.          */
  622.         struct hp_llc *llc = &(mtod(m, struct rmp_packet *)->hp_llc);
  623.  
  624.         /*
  625.          *  If the DSAP (and HP's extended DXSAP) indicate this
  626.          *  is an RMP packet, hand it to the raw input routine.
  627.          */
  628.         if (llc->dsap == IEEE_DSAP_HP && llc->dxsap == HPEXT_DXSAP) {
  629.             static struct sockproto rmp_sp = {AF_RMP,RMPPROTO_BOOT};
  630.             static struct sockaddr rmp_src = {AF_RMP};
  631.             static struct sockaddr rmp_dst = {AF_RMP};
  632.  
  633.             bcopy(et->ether_shost, rmp_src.sa_data,
  634.                   sizeof(et->ether_shost));
  635.             bcopy(et->ether_dhost, rmp_dst.sa_data,
  636.                   sizeof(et->ether_dhost));
  637.  
  638.             raw_input(m, &rmp_sp, &rmp_src, &rmp_dst);
  639.             return;
  640.         }
  641.     }
  642. #endif
  643.     ether_input(&le->sc_if, et, m);
  644. }
  645.  
  646. /*
  647.  * Routine to copy from mbuf chain to transmit
  648.  * buffer in board local memory.
  649.  */
  650. leput(lebuf, m)
  651.     register char *lebuf;
  652.     register struct mbuf *m;
  653. {
  654.     register struct mbuf *mp;
  655.     register int len, tlen = 0;
  656.  
  657.     for (mp = m; mp; mp = mp->m_next) {
  658.         len = mp->m_len;
  659.         if (len == 0)
  660.             continue;
  661.         tlen += len;
  662.         bcopy(mtod(mp, char *), lebuf, len);
  663.         lebuf += len;
  664.     }
  665.     m_freem(m);
  666.     if (tlen < LEMINSIZE) {
  667.         bzero(lebuf, LEMINSIZE - tlen);
  668.         tlen = LEMINSIZE;
  669.     }
  670.     return(tlen);
  671. }
  672.  
  673. /*
  674.  * Routine to copy from board local memory into mbufs.
  675.  */
  676. struct mbuf *
  677. leget(lebuf, totlen, off0, ifp)
  678.     char *lebuf;
  679.     int totlen, off0;
  680.     struct ifnet *ifp;
  681. {
  682.     register struct mbuf *m;
  683.     struct mbuf *top = 0, **mp = ⊤
  684.     register int off = off0, len;
  685.     register char *cp;
  686.     char *epkt;
  687.  
  688.     lebuf += sizeof (struct ether_header);
  689.     cp = lebuf;
  690.     epkt = cp + totlen;
  691.     if (off) {
  692.         cp += off + 2 * sizeof(u_short);
  693.         totlen -= 2 * sizeof(u_short);
  694.     }
  695.  
  696.     MGETHDR(m, M_DONTWAIT, MT_DATA);
  697.     if (m == 0)
  698.         return (0);
  699.     m->m_pkthdr.rcvif = ifp;
  700.     m->m_pkthdr.len = totlen;
  701.     m->m_len = MHLEN;
  702.  
  703.     while (totlen > 0) {
  704.         if (top) {
  705.             MGET(m, M_DONTWAIT, MT_DATA);
  706.             if (m == 0) {
  707.                 m_freem(top);
  708.                 return (0);
  709.             }
  710.             m->m_len = MLEN;
  711.         }
  712.         len = min(totlen, epkt - cp);
  713.         if (len >= MINCLSIZE) {
  714.             MCLGET(m, M_DONTWAIT);
  715.             if (m->m_flags & M_EXT)
  716.                 m->m_len = len = min(len, MCLBYTES);
  717.             else
  718.                 len = m->m_len;
  719.         } else {
  720.             /*
  721.              * Place initial small packet/header at end of mbuf.
  722.              */
  723.             if (len < m->m_len) {
  724.                 if (top == 0 && len + max_linkhdr <= m->m_len)
  725.                     m->m_data += max_linkhdr;
  726.                 m->m_len = len;
  727.             } else
  728.                 len = m->m_len;
  729.         }
  730.         bcopy(cp, mtod(m, caddr_t), (unsigned)len);
  731.         cp += len;
  732.         *mp = m;
  733.         mp = &m->m_next;
  734.         totlen -= len;
  735.         if (cp == epkt)
  736.             cp = lebuf;
  737.     }
  738.     return (top);
  739. }
  740.  
  741. /*
  742.  * Process an ioctl request.
  743.  */
  744. leioctl(ifp, cmd, data)
  745.     register struct ifnet *ifp;
  746.     int cmd;
  747.     caddr_t data;
  748. {
  749.     register struct ifaddr *ifa = (struct ifaddr *)data;
  750.     struct le_softc *le = &le_softc[ifp->if_unit];
  751.     struct lereg1 *ler1 = le->sc_r1;
  752.     int s = splimp(), error = 0;
  753.  
  754.     switch (cmd) {
  755.  
  756.     case SIOCSIFADDR:
  757.         ifp->if_flags |= IFF_UP;
  758.         switch (ifa->ifa_addr->sa_family) {
  759. #ifdef INET
  760.         case AF_INET:
  761.             leinit(ifp->if_unit);    /* before arpwhohas */
  762.             ((struct arpcom *)ifp)->ac_ipaddr =
  763.                 IA_SIN(ifa)->sin_addr;
  764.             arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
  765.             break;
  766. #endif
  767. #ifdef NS
  768.         case AF_NS:
  769.             {
  770.             register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
  771.  
  772.             if (ns_nullhost(*ina))
  773.                 ina->x_host = *(union ns_host *)(le->sc_addr);
  774.             else {
  775.                 /* 
  776.                  * The manual says we can't change the address 
  777.                  * while the receiver is armed,
  778.                  * so reset everything
  779.                  */
  780.                 ifp->if_flags &= ~IFF_RUNNING; 
  781.                 bcopy((caddr_t)ina->x_host.c_host,
  782.                     (caddr_t)le->sc_addr, sizeof(le->sc_addr));
  783.             }
  784.             leinit(ifp->if_unit); /* does le_setaddr() */
  785.             break;
  786.             }
  787. #endif
  788.         default:
  789.             leinit(ifp->if_unit);
  790.             break;
  791.         }
  792.         break;
  793.  
  794.     case SIOCSIFFLAGS:
  795.         if ((ifp->if_flags & IFF_UP) == 0 &&
  796.             ifp->if_flags & IFF_RUNNING) {
  797.             LERDWR(le->sc_r0, LE_STOP, ler1->ler1_rdp);
  798.             ifp->if_flags &= ~IFF_RUNNING;
  799.         } else if (ifp->if_flags & IFF_UP &&
  800.             (ifp->if_flags & IFF_RUNNING) == 0)
  801.             leinit(ifp->if_unit);
  802.         /*
  803.          * If the state of the promiscuous bit changes, the interface
  804.          * must be reset to effect the change.
  805.          */
  806.         if (((ifp->if_flags ^ le->sc_iflags) & IFF_PROMISC) &&
  807.             (ifp->if_flags & IFF_RUNNING)) {
  808.             le->sc_iflags = ifp->if_flags;
  809.             lereset(ifp->if_unit);
  810.             lestart(ifp);
  811.         }
  812.         break;
  813.  
  814.     default:
  815.         error = EINVAL;
  816.     }
  817.     splx(s);
  818.     return (error);
  819. }
  820.  
  821. leerror(unit, stat)
  822.     int unit;
  823.     int stat;
  824. {
  825.     if (!ledebug)
  826.         return;
  827.  
  828.     /*
  829.      * Not all transceivers implement heartbeat
  830.      * so we only log CERR once.
  831.      */
  832.     if ((stat & LE_CERR) && le_softc[unit].sc_cerr)
  833.         return;
  834.     log(LOG_WARNING,
  835.         "le%d: error: stat=%b\n", unit,
  836.         stat,
  837.         "\20\20ERR\17BABL\16CERR\15MISS\14MERR\13RINT\12TINT\11IDON\10INTR\07INEA\06RXON\05TXON\04TDMD\03STOP\02STRT\01INIT");
  838. }
  839.  
  840. lererror(unit, msg)
  841.     int unit;
  842.     char *msg;
  843. {
  844.     register struct le_softc *le = &le_softc[unit];
  845.     register struct lermd *rmd;
  846.     int len;
  847.  
  848.     if (!ledebug)
  849.         return;
  850.  
  851.     rmd = &le->sc_r2->ler2_rmd[le->sc_rmd];
  852.     len = rmd->rmd3;
  853.     log(LOG_WARNING,
  854.         "le%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n",
  855.         unit, msg,
  856.         len > 11 ? ether_sprintf(&le->sc_r2->ler2_rbuf[le->sc_rmd][6]) : "unknown",
  857.         le->sc_rmd, len,
  858.         rmd->rmd1,
  859.         "\20\20OWN\17ERR\16FRAM\15OFLO\14CRC\13RBUF\12STP\11ENP");
  860. }
  861.  
  862. lexerror(unit)
  863.     int unit;
  864. {
  865.     register struct le_softc *le = &le_softc[unit];
  866.     register struct letmd *tmd;
  867.     int len;
  868.  
  869.     if (!ledebug)
  870.         return;
  871.  
  872.     tmd = le->sc_r2->ler2_tmd;
  873.     len = -tmd->tmd2;
  874.     log(LOG_WARNING,
  875.         "le%d: oerror: to %s: buf=%d, len=%d, tmd1=%b, tmd3=%b\n",
  876.         unit,
  877.         len > 5 ? ether_sprintf(&le->sc_r2->ler2_tbuf[0][0]) : "unknown",
  878.         0, len,
  879.         tmd->tmd1,
  880.         "\20\20OWN\17ERR\16RES\15MORE\14ONE\13DEF\12STP\11ENP",
  881.         tmd->tmd3,
  882.         "\20\20BUFF\17UFLO\16RES\15LCOL\14LCAR\13RTRY");
  883. }
  884. #endif
  885.