home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / trace / tcpdump-2.2.1 / bpf / hpdev / if_le.c next >
Encoding:
C/C++ Source or Header  |  1991-05-05  |  26.5 KB  |  1,154 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: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  *    @(#)if_le.c    6.18 (Berkeley) 2/23/86
  22.  */
  23.  
  24. #include "le.h"
  25. #if NLE > 0
  26.  
  27. #include "bpfilter.h"
  28.  
  29. /*
  30.  * AMD 7990 LANCE
  31.  *
  32.  * This driver will generate and accept tailer encapsulated packets even
  33.  * though it buys us nothing.  The motivation was to avoid incompatibilities
  34.  * with VAXen, SUNs, and others that handle and benefit from them.
  35.  * This reasoning is dubious.
  36.  */
  37. #include "param.h"
  38. #include "systm.h"
  39. #include "time.h"
  40. #include "kernel.h"
  41. #include "mbuf.h"
  42. #include "buf.h"
  43. #include "protosw.h"
  44. #include "socket.h"
  45. #include "syslog.h"
  46. #include "ioctl.h"
  47. #include "errno.h"
  48.  
  49. #include "../net/if.h"
  50. #include "../net/netisr.h"
  51. #include "../net/route.h"
  52.  
  53. #ifdef INET
  54. #include "../netinet/in.h"
  55. #include "../netinet/in_systm.h"
  56. #include "../netinet/in_var.h"
  57. #include "../netinet/ip.h"
  58. #include "../netinet/if_ether.h"
  59. #endif
  60.  
  61. #ifdef NS
  62. #include "../netns/ns.h"
  63. #include "../netns/ns_if.h"
  64. #endif
  65.  
  66. #ifdef RMP
  67. #include "../netrmp/rmp.h"
  68. #include "../netrmp/rmp_var.h"
  69. #endif
  70.  
  71. #ifdef UTAHONLY
  72. #ifdef APPLETALK
  73. #include "../netddp/atalk.h"
  74. #endif
  75. #endif
  76.  
  77. #include "machine/cpu.h"
  78. #include "machine/isr.h"
  79. #include "machine/mtpr.h"
  80. #include "device.h"
  81. #include "if_lereg.h"
  82.  
  83. #if NBPFILTER > 0
  84. #include "../net/bpf.h"
  85. #include "../net/bpfdesc.h"
  86. #endif
  87.  
  88. /* offsets for:       ID,   REGS,    MEM,  NVRAM */
  89. int    lestd[] = { 0, 0x4000, 0x8000, 0xC008 };
  90.  
  91. int    leattach();
  92. struct    driver ledriver = {
  93.     leattach, "le",
  94. };
  95.  
  96. struct    isr le_isr[NLE];
  97. int    ledebug = 0;        /* console error messages */
  98.  
  99. int    leintr(), leinit(), leioctl(), leoutput();
  100. struct    mbuf *leget();
  101. extern    struct ifnet loif;
  102.  
  103. #ifdef DEBUG
  104. struct    le_stats {
  105.     long    lexints;    /* transmitter interrupts */
  106.     long    lerints;    /* receiver interrupts */
  107.     long    lerbufs;    /* total buffers received during interrupts */
  108.     long    lerhits;    /* times current rbuf was full */
  109.     long    lerscans;    /* rbufs scanned before finding first full */
  110. } lestats[NLE];
  111. #endif
  112.  
  113. #ifdef JAGUAR
  114. #define PACKETSTATS
  115. #endif
  116.  
  117. #ifdef PACKETSTATS
  118. long    lexpacketsizes[LEMTU+1];
  119. long    lerpacketsizes[LEMTU+1];
  120. #endif
  121.  
  122. /*
  123.  * Ethernet software status per interface.
  124.  *
  125.  * Each interface is referenced by a network interface structure,
  126.  * le_if, which the routing code uses to locate the interface.
  127.  * This structure contains the output queue for the interface, its address, ...
  128.  */
  129. struct    le_softc {
  130.     struct    arpcom sc_ac;    /* common Ethernet structures */
  131. #define    sc_if    sc_ac.ac_if    /* network-visible interface */
  132. #define    sc_addr    sc_ac.ac_enaddr    /* hardware Ethernet address */
  133.     struct    lereg0 *sc_r0;    /* DIO registers */
  134.     struct    lereg1 *sc_r1;    /* LANCE registers */
  135.     struct    lereg2 *sc_r2;    /* dual-port RAM */
  136.     int    sc_rmd;        /* predicted next rmd to process */
  137.     int    sc_runt;
  138.     int    sc_jab;
  139.     int    sc_merr;
  140.     int    sc_babl;
  141.     int    sc_cerr;
  142.     int    sc_miss;
  143.     int    sc_xint;
  144.     int    sc_xown;
  145.     int    sc_uflo;
  146.     int    sc_rxlen;
  147.     int    sc_rxoff;
  148.     int    sc_txoff;
  149.     int    sc_busy;
  150.     int    sc_oactive;        /* is output active? */
  151. #if NBPFILTER > 0
  152.     caddr_t    sc_bpf;
  153. #endif
  154. } le_softc[NLE];
  155.  
  156. /* access LANCE registers */
  157. #define    LERDWR(cntl, src, dst) \
  158.     do { \
  159.         (dst) = (src); \
  160.     } while (((cntl)->ler0_status & LE_ACK) == 0);
  161.  
  162. /*
  163.  * Interface exists: make available by filling in network interface
  164.  * record.  System will initialize the interface when it is ready
  165.  * to accept packets.
  166.  */
  167. leattach(hd)
  168.     struct hp_device *hd;
  169. {
  170.     register struct lereg0 *ler0;
  171.     register struct lereg2 *ler2;
  172.     struct lereg2 *lemem = 0;
  173.     struct le_softc *le = &le_softc[hd->hp_unit];
  174.     struct ifnet *ifp = &le->sc_if;
  175.     char *cp;
  176.     int i;
  177.  
  178.     ler0 = le->sc_r0 = (struct lereg0 *)(lestd[0] + (int)hd->hp_addr);
  179.     le->sc_r1 = (struct lereg1 *)(lestd[1] + (int)hd->hp_addr);
  180.     ler2 = le->sc_r2 = (struct lereg2 *)(lestd[2] + (int)hd->hp_addr);
  181.     if (ler0->ler0_id != LEID)
  182.         return(0);
  183.     le_isr[hd->hp_unit].isr_intr = leintr;
  184.     hd->hp_ipl = le_isr[hd->hp_unit].isr_ipl = LE_IPL(ler0->ler0_status);
  185.     le_isr[hd->hp_unit].isr_arg = hd->hp_unit;
  186.     ler0->ler0_id = 0xFF;
  187.     DELAY(100);
  188.  
  189.     /*
  190.      * Read the ethernet address off the board, one nibble at a time.
  191.      */
  192.     cp = (char *)(lestd[3] + (int)hd->hp_addr);
  193.     for (i = 0; i < sizeof(le->sc_addr); i++) {
  194.         le->sc_addr[i] = (*++cp & 0xF) << 4;
  195.         cp++;
  196.         le->sc_addr[i] |= *++cp & 0xF;
  197.         cp++;
  198.     }
  199.     printf("le%d: hardware address %s\n", hd->hp_unit,
  200.         ether_sprintf(le->sc_addr));
  201.  
  202.     /*
  203.      * Setup for transmit/receive
  204.      */
  205.     ler2->ler2_mode = LE_MODE;
  206.  
  207.     ler2->ler2_padr[0] = le->sc_addr[1];
  208.     ler2->ler2_padr[1] = le->sc_addr[0];
  209.     ler2->ler2_padr[2] = le->sc_addr[3];
  210.     ler2->ler2_padr[3] = le->sc_addr[2];
  211.     ler2->ler2_padr[4] = le->sc_addr[5];
  212.     ler2->ler2_padr[5] = le->sc_addr[4];
  213. #ifdef RMP
  214.     /*
  215.      * Set up logical addr filter to accept multicast 9:0:9:0:0:4
  216.      * This should be an ioctl() to the driver.  (XXX)
  217.      */
  218.     ler2->ler2_ladrf0 = 0x00100000;
  219.     ler2->ler2_ladrf1 = 0x0;
  220. #else
  221.     ler2->ler2_ladrf0 = 0;
  222.     ler2->ler2_ladrf1 = 0;
  223. #endif
  224.     ler2->ler2_rlen = LE_RLEN;
  225.     ler2->ler2_rdra = (int)lemem->ler2_rmd;
  226.     ler2->ler2_tlen = LE_TLEN;
  227.     ler2->ler2_tdra = (int)lemem->ler2_tmd;
  228.     isrlink(&le_isr[hd->hp_unit]);
  229.     ler0->ler0_status = LE_IE;
  230.  
  231.     ifp->if_unit = hd->hp_unit;
  232.     ifp->if_name = "le";
  233.     ifp->if_mtu = ETHERMTU;
  234.     ifp->if_init = leinit;
  235.     ifp->if_ioctl = leioctl;
  236.     ifp->if_output = leoutput;
  237.     ifp->if_flags = IFF_BROADCAST;
  238. #if NBPFILTER > 0
  239.     bpfattach(&le->sc_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
  240. #endif
  241.     if_attach(ifp);
  242.     return (1);
  243. }
  244.  
  245. ledrinit(ler2)
  246.     register struct lereg2 *ler2;
  247. {
  248.     register struct lereg2 *lemem = 0;
  249.     register int i;
  250.  
  251.     for (i = 0; i < LERBUF; i++) {
  252.         ler2->ler2_rmd[i].rmd0 = (int)lemem->ler2_rbuf[i];
  253.         ler2->ler2_rmd[i].rmd1 = LE_OWN;
  254.         ler2->ler2_rmd[i].rmd2 = -LEMTU;
  255.         ler2->ler2_rmd[i].rmd3 = 0;
  256.     }
  257.     for (i = 0; i < LETBUF; i++) {
  258.         ler2->ler2_tmd[i].tmd0 = (int)lemem->ler2_tbuf[i];
  259.         ler2->ler2_tmd[i].tmd1 = 0;
  260.         ler2->ler2_tmd[i].tmd2 = 0;
  261.         ler2->ler2_tmd[i].tmd3 = 0;
  262.     }
  263. }
  264.  
  265. lereset(unit)
  266.     register int unit;
  267. {
  268.     register struct le_softc *le = &le_softc[unit];
  269.     register struct lereg0 *ler0 = le->sc_r0;
  270.     register struct lereg1 *ler1 = le->sc_r1;
  271.     register struct lereg2 *lemem = 0;
  272.     register int timo = 100000;
  273.     register int stat;
  274. #if NBPFILTER > 0
  275.     if (le->sc_if.if_flags & IFF_PROMISC)
  276.         /* set the promiscuous bit */
  277.         le->sc_r2->ler2_mode = LE_MODE|0x8000;
  278.     else
  279.         le->sc_r2->ler2_mode = LE_MODE;
  280. #endif
  281.     LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
  282.     LERDWR(ler0, LE_STOP, ler1->ler1_rdp);
  283.     ledrinit(le->sc_r2);
  284.     le->sc_rmd = 0;
  285.     LERDWR(ler0, LE_CSR1, ler1->ler1_rap);
  286.     LERDWR(ler0, (int)&lemem->ler2_mode, ler1->ler1_rdp);
  287.     LERDWR(ler0, LE_CSR2, ler1->ler1_rap);
  288.     LERDWR(ler0, 0, ler1->ler1_rdp);
  289.     LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
  290.     LERDWR(ler0, LE_INIT, ler1->ler1_rdp);
  291.     do {
  292.         if (--timo == 0) {
  293.             printf("le%d: init timeout, stat = 0x%x\n",
  294.                    unit, stat);
  295.             break;
  296.         }
  297.         LERDWR(ler0, ler1->ler1_rdp, stat);
  298.     } while ((stat & LE_IDON) == 0);
  299.     LERDWR(ler0, LE_STOP, ler1->ler1_rdp);
  300.     LERDWR(ler0, LE_CSR3, ler1->ler1_rap);
  301.     LERDWR(ler0, LE_BSWP, ler1->ler1_rdp);
  302.     LERDWR(ler0, LE_CSR0, ler1->ler1_rap);
  303.     LERDWR(ler0, LE_STRT | LE_INEA, ler1->ler1_rdp);
  304.     le->sc_oactive = 0;
  305. }
  306.  
  307. /*
  308.  * Initialization of interface
  309.  */
  310. leinit(unit)
  311.     int unit;
  312. {
  313.     struct le_softc *le = &le_softc[unit];
  314.     register struct ifnet *ifp = &le->sc_if;
  315.     int s;
  316.  
  317.     /* not yet, if address still unknown */
  318.     if (ifp->if_addrlist == (struct ifaddr *)0)
  319.         return;
  320.     if ((ifp->if_flags & IFF_RUNNING) == 0) {
  321.         s = splimp();
  322.         ifp->if_flags |= IFF_RUNNING;
  323.         lereset(unit);
  324.             lestart(unit);
  325.         splx(s);
  326.     }
  327. }
  328.  
  329. /*
  330.  * Start output on interface.  Get another datagram to send
  331.  * off of the interface queue, and copy it to the interface
  332.  * before starting the output.
  333.  */
  334. lestart(unit)
  335.     int unit;
  336. {
  337.     register struct le_softc *le = &le_softc[unit];
  338.     register struct letmd *tmd;
  339.     register struct mbuf *m;
  340.     int len;
  341.  
  342.     if ((le->sc_if.if_flags & IFF_RUNNING) == 0)
  343.         return;
  344.     IF_DEQUEUE(&le->sc_if.if_snd, m);
  345.     if (m == 0)
  346.         return;
  347.     len = leput(le->sc_r2->ler2_tbuf[0], m);
  348. #if NBPFILTER > 0
  349.     /* 
  350.      * If bpf is listening on this interface, let it 
  351.      * see the packet before we commit it to the wire.
  352.      */
  353.     if (le->sc_bpf)
  354.         bpf_tap(le->sc_bpf, le->sc_r2->ler2_tbuf[0], len);
  355. #endif
  356.  
  357. #ifdef PACKETSTATS
  358.     if (len <= LEMTU)
  359.         lexpacketsizes[len]++;
  360. #endif
  361.     tmd = le->sc_r2->ler2_tmd;
  362.     tmd->tmd3 = 0;
  363.     tmd->tmd2 = -len;
  364.     tmd->tmd1 = LE_OWN | LE_STP | LE_ENP;
  365.     le->sc_oactive = 1;
  366. }
  367.  
  368. leintr(unit)
  369.     register int unit;
  370. {
  371.     register struct le_softc *le = &le_softc[unit];
  372.     register struct lereg0 *ler0 = le->sc_r0;
  373.     register struct lereg1 *ler1;
  374.     register int stat;
  375.  
  376.     if ((ler0->ler0_status & LE_IR) == 0)
  377.         return(0);
  378.     if (ler0->ler0_status & LE_JAB) {
  379.         le->sc_jab++;
  380.         lereset(unit);
  381.         return(1);
  382.     }
  383.     ler1 = le->sc_r1;
  384.     LERDWR(ler0, ler1->ler1_rdp, stat);
  385.     if (stat & LE_SERR) {
  386.         leerror(unit, stat);
  387.         if (stat & LE_MERR) {
  388.             le->sc_merr++;
  389.             lereset(unit);
  390.             return(1);
  391.         }
  392.         if (stat & LE_BABL)
  393.             le->sc_babl++;
  394.         if (stat & LE_CERR)
  395.             le->sc_cerr++;
  396.         if (stat & LE_MISS)
  397.             le->sc_miss++;
  398.         LERDWR(ler0, LE_BABL|LE_CERR|LE_MISS|LE_INEA, ler1->ler1_rdp);
  399.     }
  400.     if ((stat & LE_RXON) == 0) {
  401.         le->sc_rxoff++;
  402.         lereset(unit);
  403.         return(1);
  404.     }
  405.     if ((stat & LE_TXON) == 0) {
  406.         le->sc_txoff++;
  407.         lereset(unit);
  408.         return(1);
  409.     }
  410.     if (stat & LE_RINT) {
  411.         /* interrupt is cleared in lerint */
  412.         lerint(unit);
  413.     }
  414.     if (stat & LE_TINT) {
  415.         LERDWR(ler0, LE_TINT|LE_INEA, ler1->ler1_rdp);
  416.         lexint(unit);
  417.     }
  418.     return(1);
  419. }
  420.  
  421. /*
  422.  * Ethernet interface transmitter interrupt.
  423.  * Start another output if more data to send.
  424.  */
  425. lexint(unit)
  426.     register int unit;
  427. {
  428.     register struct le_softc *le = &le_softc[unit];
  429.     register struct letmd *tmd = le->sc_r2->ler2_tmd;
  430.  
  431. #ifdef DEBUG
  432.     lestats[unit].lexints++;
  433. #endif
  434.     if (le->sc_oactive == 0) {
  435.         le->sc_xint++;
  436.         return;
  437.     }
  438.     if (tmd->tmd1 & LE_OWN) {
  439.         le->sc_xown++;
  440.         return;
  441.     }
  442.     if (tmd->tmd1 & LE_ERR) {
  443. err:
  444.         lexerror(unit);
  445.         le->sc_if.if_oerrors++;
  446.         if (tmd->tmd3 & (LE_TBUFF|LE_UFLO)) {
  447.             le->sc_uflo++;
  448.             lereset(unit);
  449.         }
  450.         else if (tmd->tmd3 & LE_LCOL)
  451.             le->sc_if.if_collisions++;
  452.         else if (tmd->tmd3 & LE_RTRY)
  453.             le->sc_if.if_collisions += 16;
  454.     }
  455.     else if (tmd->tmd3 & LE_TBUFF)
  456.         /* XXX documentation says BUFF not included in ERR */
  457.         goto err;
  458.     else if (tmd->tmd1 & LE_ONE)
  459.         le->sc_if.if_collisions++;
  460.     else if (tmd->tmd1 & LE_MORE)
  461.         /* what is the real number? */
  462.         le->sc_if.if_collisions += 2;
  463.     else
  464.         le->sc_if.if_opackets++;
  465.     le->sc_oactive = 0;
  466.     lestart(unit);
  467. }
  468.  
  469. #define    LENEXTRMP \
  470.     if (++bix == LERBUF) bix = 0, rmd = le->sc_r2->ler2_rmd; else ++rmd
  471.  
  472. /*
  473.  * Ethernet interface receiver interrupt.
  474.  * If input error just drop packet.
  475.  * Decapsulate packet based on type and pass to type specific
  476.  * higher-level input routine.
  477.  */
  478. lerint(unit)
  479.     int unit;
  480. {
  481.     register struct le_softc *le = &le_softc[unit];
  482.     register int bix = le->sc_rmd;
  483.     register struct lermd *rmd = &le->sc_r2->ler2_rmd[bix];
  484. #ifdef DEBUG
  485.     register struct le_stats *ls = &lestats[unit];
  486.  
  487.     ls->lerints++;
  488. #endif
  489.  
  490.     /*
  491.      * Out of sync with hardware, should never happen?
  492.      */
  493. #ifdef DEBUG
  494.     if (rmd->rmd1 & LE_OWN) {
  495.         do {
  496.             ls->lerscans++;
  497.             LENEXTRMP;
  498.         } while ((rmd->rmd1 & LE_OWN) && bix != le->sc_rmd);
  499.         if (bix == le->sc_rmd)
  500.             printf("le%d: RINT with no buffer\n", unit);
  501.     } else
  502.         ls->lerhits++;
  503. #else
  504.     if (rmd->rmd1 & LE_OWN) {
  505.         LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
  506.         return;
  507.     }
  508. #endif
  509.  
  510.     /*
  511.      * Process all buffers with valid data
  512.      */
  513.     while ((rmd->rmd1 & LE_OWN) == 0) {
  514.         int len = rmd->rmd3;
  515.  
  516.         /* Clear interrupt to avoid race condition */
  517.         LERDWR(le->sc_r0, LE_RINT|LE_INEA, le->sc_r1->ler1_rdp);
  518.  
  519.         if (rmd->rmd1 & LE_ERR) {
  520.             le->sc_rmd = bix;
  521.             lererror(unit, "bad packet");
  522.             le->sc_if.if_ierrors++;
  523.         } else if ((rmd->rmd1 & (LE_STP|LE_ENP)) != (LE_STP|LE_ENP)) {
  524.             /*
  525.              * Find the end of the packet so we can see how long
  526.              * it was.  We still throw it away.
  527.              */
  528.             do {
  529.                 LERDWR(le->sc_r0, LE_RINT|LE_INEA,
  530.                        le->sc_r1->ler1_rdp);
  531.                 rmd->rmd3 = 0;
  532.                 rmd->rmd1 = LE_OWN;
  533.                 LENEXTRMP;
  534.             } while (!(rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)));
  535.             le->sc_rmd = bix;
  536.             lererror(unit, "chained buffer");
  537.             le->sc_rxlen++;
  538.             /*
  539.              * If search terminated without successful completion
  540.              * we reset the hardware (conservative).
  541.              */
  542.             if ((rmd->rmd1 & (LE_OWN|LE_ERR|LE_STP|LE_ENP)) !=
  543.                 LE_ENP) {
  544.                 lereset(unit);
  545.                 return;
  546.             }
  547.         } else {
  548.             leread(unit, le->sc_r2->ler2_rbuf[bix], len);
  549. #ifdef PACKETSTATS
  550.             lerpacketsizes[len]++;
  551. #endif
  552. #ifdef DEBUG
  553.             ls->lerbufs++;
  554. #endif
  555.         }
  556.         rmd->rmd3 = 0;
  557.         rmd->rmd1 = LE_OWN;
  558.         LENEXTRMP;
  559.     }
  560.     le->sc_rmd = bix;
  561. }
  562.  
  563. leread(unit, buf, len)
  564.     int unit;
  565.     char *buf;
  566.     int len;
  567. {
  568.     register struct le_softc *le = &le_softc[unit];
  569.     register struct ether_header *et;
  570.         struct mbuf *m;
  571.     struct ifqueue *inq;
  572.     int resid;
  573.  
  574.     le->sc_if.if_ipackets++;
  575.     et = (struct ether_header *)buf;
  576.     et->ether_type = ntohs((u_short)et->ether_type);
  577.     /* adjust input length to account for header and CRC */
  578.     len -= sizeof(struct ether_header) + 4;
  579.  
  580. #ifdef RMP
  581.     /*  (XXX)
  582.      *
  583.      *  If Ethernet Type field is < MaxPacketSize, we probably have
  584.      *  a IEEE802 packet here.  Make sure that the size is at least
  585.      *  that of the HP LLC.  Also do sanity checks on length of LLC
  586.      *  (old Ethernet Type field) and packet length.
  587.      *
  588.      *  Provided the above checks succeed, change `len' to reflect
  589.      *  the length of the LLC (i.e. et->ether_type) and change the
  590.      *  type field to ETHERTYPE_IEEE so we can switch() on it later.
  591.      *  Yes, this is a hack and will eventually be done "right".
  592.      */
  593.     if (et->ether_type <= IEEE802LEN_MAX && len >= sizeof(struct hp_llc) &&
  594.         len >= et->ether_type && len >= IEEE802LEN_MIN) {
  595.         len = et->ether_type;
  596.         et->ether_type = ETHERTYPE_IEEE;    /* hack! */
  597.     }
  598. #endif
  599.     if (len <= 0) {
  600.         if (ledebug)
  601.             log(LOG_WARNING,
  602.                 "le%d: ierror(runt packet): from %s: len=%d\n",
  603.                 unit, ether_sprintf(et->ether_shost), len);
  604.         le->sc_runt++;
  605.         le->sc_if.if_ierrors++;
  606.         return;
  607.     }
  608.  
  609. #if NBPFILTER > 0
  610.     /*
  611.      * Check if there's a bpf filter listening on this interface.
  612.      * If so, hand off the raw packet to enet. 
  613.      */
  614.     if (le->sc_bpf) {
  615.         bpf_tap(le->sc_bpf, buf, len + sizeof(struct ether_header));
  616.  
  617.         /*
  618.          * Note that the interface cannot be in promiscuous mode if
  619.          * there are no bpf listeners.  And if we are in promiscuous
  620.          * mode, we have to check if this packet is really ours.
  621.          *
  622.          * XXX This test does not support multicasts.
  623.          */
  624.         if ((le->sc_if.if_flags & IFF_PROMISC)
  625.             && bcmp(et->ether_dhost, le->sc_addr, 
  626.                 sizeof(et->ether_dhost)) != 0
  627.             && bcmp(et->ether_dhost, etherbroadcastaddr, 
  628.                 sizeof(et->ether_dhost)) != 0)
  629.             return;
  630.     }
  631. #endif
  632.     m = leget(buf, len, 0, &le->sc_if);
  633.     if (m == 0)
  634.         return;
  635.  
  636.     switch (et->ether_type) {
  637.  
  638. #ifdef INET
  639.     case ETHERTYPE_IP:
  640.         schednetisr(NETISR_IP);
  641.         inq = &ipintrq;
  642.         break;
  643.  
  644.     case ETHERTYPE_ARP:
  645.         arpinput(&le->sc_ac, m);
  646.         return;
  647. #endif
  648. #ifdef NS
  649.     case ETHERTYPE_NS:
  650.         schednetisr(NETISR_NS);
  651.         inq = &nsintrq;
  652.         break;
  653. #endif
  654. #ifdef RMP
  655.     case ETHERTYPE_IEEE:
  656.     {
  657.         /*
  658.          *  Snag the Logical Link Control header (IEEE 802.2).
  659.          */
  660.         struct hp_llc *llc = &(mtod(m, struct rmp_packet *)->hp_llc);
  661.  
  662.         /*
  663.          *  If the DSAP (and HP's extended DXSAP) indicate this
  664.          *  is an RMP packet, hand it to the raw input routine.
  665.          */
  666.         if (llc->dsap == IEEE_DSAP_HP && llc->dxsap == HPEXT_DXSAP) {
  667.             static struct sockproto rmp_sp = {AF_RMP,RMPPROTO_BOOT};
  668.             static struct sockaddr rmp_src = {AF_RMP};
  669.             static struct sockaddr rmp_dst = {AF_RMP};
  670.  
  671.             bcopy(et->ether_shost, rmp_src.sa_data,
  672.                   sizeof(et->ether_shost));
  673.             bcopy(et->ether_dhost, rmp_dst.sa_data,
  674.                   sizeof(et->ether_dhost));
  675.  
  676.             raw_input(m, &rmp_sp, &rmp_src, &rmp_dst);
  677.             return;
  678.         }
  679.     }
  680.     /* FALL THRU */
  681. #endif
  682.  
  683. #ifdef UTAHONLY
  684. #ifdef APPLETALK
  685.     case ETHERTYPE_APPLETALK:
  686.         schednetisr(NETISR_DDP);
  687.         inq = &ddpintq;
  688.         break;
  689.  
  690.     case ETHERTYPE_AARP:
  691.         aarpinput(&le->sc_ac, m);
  692.         return;
  693. #endif
  694. #endif
  695.     default:
  696.         m_freem(m);
  697.         return;
  698.     }
  699.  
  700.     if (IF_QFULL(inq)) {
  701.         IF_DROP(inq);
  702.         m_freem(m);
  703.         return;
  704.     }
  705.     IF_ENQUEUE(inq, m);
  706. }
  707.  
  708. /*
  709.  * Ethernet output routine.
  710.  * Encapsulate a packet of type family for the local net.
  711.  * Use trailer local net encapsulation if enough data in first
  712.  * packet leaves a multiple of 512 bytes of data in remainder.
  713.  * If destination is this address or broadcast, send packet to
  714.  * loop device to kludge around the fact that the interface can't
  715.  * talk to itself.
  716.  */
  717. leoutput(ifp, m0, dst)
  718.     struct ifnet *ifp;
  719.     struct mbuf *m0;
  720.     struct sockaddr *dst;
  721. {
  722.     int type, s, error;
  723.      u_char edst[6];
  724.     struct in_addr idst;
  725.     register struct le_softc *le = &le_softc[ifp->if_unit];
  726.     register struct mbuf *m = m0;
  727.     register struct ether_header *et;
  728.     struct mbuf *mcopy = (struct mbuf *)0;
  729.     register int off = 0;
  730.     int usetrailers;
  731.  
  732.     if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
  733.         error = ENETDOWN;
  734.         goto bad;
  735.     }
  736.     switch (dst->sa_family) {
  737.  
  738. #ifdef INET
  739.     case AF_INET:
  740.         idst = ((struct sockaddr_in *)dst)->sin_addr;
  741.         if (!arpresolve(&le->sc_ac, m, &idst, edst, &usetrailers))
  742.             return (0);    /* if not yet resolved */
  743.         if (!bcmp((caddr_t)edst, (caddr_t)etherbroadcastaddr,
  744.             sizeof(edst)))
  745.             mcopy = m_copy(m, 0, (int)M_COPYALL);
  746.         off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
  747.         /* need per host negotiation */
  748.         if (usetrailers && off > 0 && (off & 0x1ff) == 0 &&
  749.             m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
  750.             type = ETHERTYPE_TRAIL + (off>>9);
  751.             m->m_off -= 2 * sizeof (u_short);
  752.             m->m_len += 2 * sizeof (u_short);
  753.             *mtod(m, u_short *) = ntohs((u_short)ETHERTYPE_IP);
  754.             *(mtod(m, u_short *) + 1) = ntohs((u_short)m->m_len);
  755.         } else {
  756.             type = ETHERTYPE_IP;
  757.             off = 0;
  758.         }
  759.         break;
  760. #endif
  761. #ifdef NS
  762.     case AF_NS:
  763.          bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
  764.             (caddr_t)edst, sizeof (edst));
  765.  
  766.         if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost,
  767.             sizeof(edst))) {
  768.  
  769.                 mcopy = m_copy(m, 0, (int)M_COPYALL);
  770.         } else if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost,
  771.             sizeof(edst))) {
  772.  
  773.                 return(looutput(&loif, m, dst));
  774.         }
  775.         type = ETHERTYPE_NS;
  776.         break;
  777. #endif
  778. #ifdef RMP
  779.     case AF_RMP:
  780.         /*  (XXX)
  781.          *
  782.          *  This is IEEE 802.3 -- the Ethernet `type' field is
  783.          *  really a `length' field.
  784.          */
  785.         type = m->m_len;
  786.          bcopy((caddr_t)dst->sa_data, (caddr_t)edst, sizeof(edst));
  787.         break;
  788. #endif
  789.  
  790. #ifdef UTAHONLY
  791. #ifdef APPLETALK
  792.        case AF_APPLETALK:
  793.         {
  794.         struct sockaddr_at *dat = (struct sockaddr_at *)dst;
  795.         int dnode;
  796.         register struct lap *lap;
  797.         register struct ifaddr *ifa;
  798.         register struct a_addr *ata;
  799.         register struct arpcom *ac = &le->sc_ac;
  800.  
  801.         for (ifa = ac->ac_if.if_addrlist; ifa; ifa = ifa->ifa_next) {
  802.             if (ifa->ifa_addr.sa_family == AF_APPLETALK)
  803.                 break;
  804.         }
  805.         if (ifa == NULL)
  806.                        return (ENETDOWN);      /* don't know who we are yet */
  807.         ata = (struct a_addr *)(ifa->ifa_addr.sa_data);
  808.         if (ata->at_Node == 0)
  809.             return (ENETDOWN);      /* don't know who we are yet */
  810.  
  811.         lap = mtod(m, struct lap *);
  812.         lap->src = ata->at_Node;
  813.                 if ((lap->type & 0xFF) == LT_DDP) {
  814.                         /*
  815.                          * All traffic to the local net uses short DDP,
  816.                          * so we know long ddp must go to the bridge.
  817.                          */
  818.             lap->dst = dnode = ata->at_Abridge & 0xff;
  819.         } else
  820.             /*
  821.              * lap->dst was filled in by ddp code for short ddp
  822.              */
  823.             dnode = lap->dst & 0xFF;
  824.  
  825.         idst.s_addr = 0L;
  826.         ((char *)(&idst))[3] = dnode;     /* to fake out arpresolve */
  827.  
  828.         if (!aarpresolve(ac, m, dnode, edst, &usetrailers))
  829.             return (0);
  830.  
  831.         type = ETHERTYPE_APPLETALK;
  832.         break;
  833.         }
  834. #endif
  835. #endif
  836.  
  837.     case AF_UNSPEC:
  838.         et = (struct ether_header *)dst->sa_data;
  839.          bcopy((caddr_t)et->ether_dhost, (caddr_t)edst, sizeof (edst));
  840.         type = et->ether_type;
  841.         break;
  842.  
  843.     default:
  844.         printf("le%d: can't handle af%u\n", ifp->if_unit,
  845.             dst->sa_family);
  846.         error = EAFNOSUPPORT;
  847.         goto bad;
  848.     }
  849.     /*
  850.      * Packet to be sent as trailer: move first packet
  851.      * (control information) to end of chain.
  852.      */
  853.     if (off) {
  854.         while (m->m_next)
  855.             m = m->m_next;
  856.         m->m_next = m0;
  857.         m = m0->m_next;
  858.         m0->m_next = 0;
  859.         m0 = m;
  860.     }
  861.     /*
  862.      * Add local net header.  If no space in first mbuf,
  863.      * allocate another.
  864.      */
  865.     if (m->m_off > MMAXOFF ||
  866.         MMINOFF + sizeof (struct ether_header) > m->m_off) {
  867.         m = m_get(M_DONTWAIT, MT_HEADER);
  868.         if (m == 0) {
  869.             error = ENOBUFS;
  870.             goto bad;
  871.         }
  872.         m->m_next = m0;
  873.         m->m_off = MMINOFF;
  874.         m->m_len = sizeof (struct ether_header);
  875.     } else {
  876.         m->m_off -= sizeof (struct ether_header);
  877.         m->m_len += sizeof (struct ether_header);
  878.     }
  879.     et = mtod(m, struct ether_header *);
  880.      bcopy((caddr_t)edst, (caddr_t)et->ether_dhost, sizeof (edst));
  881.     bcopy((caddr_t)le->sc_addr, (caddr_t)et->ether_shost,
  882.         sizeof(et->ether_shost));
  883.     et->ether_type = htons((u_short)type);
  884.  
  885.     /*
  886.      * Queue message on interface, and start output if interface
  887.      * not yet active.
  888.      */
  889.     s = splimp();
  890.     if (IF_QFULL(&ifp->if_snd)) {
  891.         IF_DROP(&ifp->if_snd);
  892.         error = ENOBUFS;
  893.         goto qfull;
  894.     }
  895.     IF_ENQUEUE(&ifp->if_snd, m);
  896.     if (le->sc_oactive == 0)
  897.         lestart(ifp->if_unit);
  898.     else
  899.         le->sc_busy++;
  900.     splx(s);
  901.     return (mcopy ? looutput(&loif, mcopy, dst) : 0);
  902.  
  903. qfull:
  904.     m0 = m;
  905.     splx(s);
  906. bad:
  907.     m_freem(m0);
  908.     if (mcopy)
  909.         m_freem(mcopy);
  910.     return (error);
  911. }
  912.  
  913. /*
  914.  * Routine to copy from mbuf chain to transmit
  915.  * buffer in board local memory.
  916.  */
  917. leput(lebuf, m)
  918.     register char *lebuf;
  919.     register struct mbuf *m;
  920. {
  921.     register struct mbuf *mp;
  922.     register int len, tlen = 0;
  923.  
  924.     for (mp = m; mp; mp = mp->m_next) {
  925.         len = mp->m_len;
  926.         if (len == 0)
  927.             continue;
  928.         tlen += len;
  929.         bcopy(mtod(mp, char *), lebuf, len);
  930.         lebuf += len;
  931.     }
  932.     m_freem(m);
  933.     if (tlen < LEMINSIZE) {
  934.         bzero(lebuf, LEMINSIZE - tlen);
  935.         tlen = LEMINSIZE;
  936.     }
  937.  
  938.     return(tlen);
  939. }
  940.  
  941. /*
  942.  * Routine to copy from board local memory into mbufs.
  943.  */
  944. struct mbuf *
  945. leget(lebuf, totlen, off0, ifp)
  946.     char *lebuf;
  947.     int totlen, off0;
  948.     struct ifnet *ifp;
  949. {
  950.     register struct mbuf *m;
  951.     struct mbuf *top = 0, **mp = ⊤
  952.     register int off = off0, len;
  953.     register char *cp;
  954.     char *mcp;
  955.  
  956.     lebuf += sizeof (struct ether_header);
  957.     cp = lebuf;
  958.     if (off) {
  959.         cp += off + 2 * sizeof(u_short);
  960.         totlen -= 2 * sizeof(u_short);
  961.     }
  962.     while (totlen > 0) {
  963.         MGET(m, M_DONTWAIT, MT_DATA);
  964.         if (m == 0)
  965.             goto bad;
  966.         len = totlen;
  967.         if (off)
  968.             len -= off;
  969.         if (ifp)
  970.             len += sizeof(ifp);
  971.         if (len >= MINCLSIZE) {
  972.             MCLGET(m);
  973.             if (m->m_len == MCLBYTES)
  974.                 m->m_len = len = MIN(len, MCLBYTES);
  975.             else
  976.                 m->m_len = len = MIN(MLEN, len);
  977.         } else {
  978.             /*
  979.              * Place initial small packet/header at end of mbuf.
  980.              */
  981.             m->m_len = len = MIN(MLEN, len);
  982.             m->m_off = MMINOFF;
  983.         }
  984.         mcp = mtod(m, char *);
  985.         if (ifp) {
  986.             /*
  987.              * Prepend interface pointer to first mbuf.
  988.              */
  989.             *(mtod(m, struct ifnet **)) = ifp;
  990.             mcp += sizeof(ifp);
  991.             len -= sizeof(ifp);
  992.             ifp = (struct ifnet *)0;
  993.         }
  994.         bcopy(cp, mcp, len);
  995.         *mp = m;
  996.         mp = &m->m_next;
  997.         cp += len;
  998.         if (off == 0) {
  999.             totlen -= len;
  1000.             continue;
  1001.         }
  1002.         off += len;
  1003.         if (off == totlen) {
  1004.             cp = lebuf;
  1005.             off = 0;
  1006.             totlen = off0;
  1007.         }
  1008.     }
  1009.     return (top);
  1010. bad:
  1011.     m_freem(top);
  1012.     return (0);
  1013. }
  1014.  
  1015. /*
  1016.  * Process an ioctl request.
  1017.  */
  1018. leioctl(ifp, cmd, data)
  1019.     register struct ifnet *ifp;
  1020.     int cmd;
  1021.     caddr_t data;
  1022. {
  1023.     register struct ifaddr *ifa = (struct ifaddr *)data;
  1024.     struct le_softc *le = &le_softc[ifp->if_unit];
  1025.     struct lereg1 *ler1 = le->sc_r1;
  1026.     int s = splimp(), error = 0;
  1027.  
  1028.     switch (cmd) {
  1029.  
  1030.     case SIOCSIFADDR:
  1031.         ifp->if_flags |= IFF_UP;
  1032.         switch (ifa->ifa_addr.sa_family) {
  1033. #ifdef INET
  1034.         case AF_INET:
  1035.             leinit(ifp->if_unit);    /* before arpwhohas */
  1036.             ((struct arpcom *)ifp)->ac_ipaddr =
  1037.                 IA_SIN(ifa)->sin_addr;
  1038.             arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
  1039. #ifdef UTAHONLY
  1040. #ifdef APPLETALK
  1041.             getatnode(ifp);
  1042. #endif
  1043. #endif
  1044.             break;
  1045. #endif
  1046. #ifdef NS
  1047.         case AF_NS:
  1048.             {
  1049.             register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
  1050.  
  1051.             if (ns_nullhost(*ina))
  1052.                 ina->x_host = *(union ns_host *)(le->sc_addr);
  1053.             else {
  1054.                 /* 
  1055.                  * The manual says we can't change the address 
  1056.                  * while the receiver is armed,
  1057.                  * so reset everything
  1058.                  */
  1059.                 ifp->if_flags &= ~IFF_RUNNING; 
  1060.                 bcopy((caddr_t)ina->x_host.c_host,
  1061.                     (caddr_t)le->sc_addr, sizeof(le->sc_addr));
  1062.             }
  1063.             leinit(ifp->if_unit); /* does le_setaddr() */
  1064.             break;
  1065.             }
  1066. #endif
  1067.         default:
  1068.             leinit(ifp->if_unit);
  1069.             break;
  1070.         }
  1071.         break;
  1072.  
  1073.     case SIOCSIFFLAGS:
  1074.         if ((ifp->if_flags & IFF_UP) == 0 &&
  1075.             ifp->if_flags & IFF_RUNNING) {
  1076.             LERDWR(le->sc_r0, LE_STOP, ler1->ler1_rdp);
  1077.             ifp->if_flags &= ~IFF_RUNNING;
  1078.         } else if (ifp->if_flags & IFF_UP &&
  1079.             (ifp->if_flags & IFF_RUNNING) == 0)
  1080.             leinit(ifp->if_unit);
  1081.         break;
  1082.  
  1083.     default:
  1084.         error = EINVAL;
  1085.     }
  1086.     splx(s);
  1087.     return (error);
  1088. }
  1089.  
  1090. leerror(unit, stat)
  1091.     int unit;
  1092.     int stat;
  1093. {
  1094.     if (!ledebug)
  1095.         return;
  1096.  
  1097.     /*
  1098.      * Not all transceivers implement heartbeat
  1099.      * so we only log CERR once.
  1100.      */
  1101.     if ((stat & LE_CERR) && le_softc[unit].sc_cerr)
  1102.         return;
  1103.     log(LOG_WARNING,
  1104.         "le%d: error: stat=%b\n", unit,
  1105.         stat,
  1106.         "\20\20ERR\17BABL\16CERR\15MISS\14MERR\13RINT\12TINT\11IDON\10INTR\07INEA\06RXON\05TXON\04TDMD\03STOP\02STRT\01INIT");
  1107. }
  1108.  
  1109. lererror(unit, msg)
  1110.     int unit;
  1111.     char *msg;
  1112. {
  1113.     register struct le_softc *le = &le_softc[unit];
  1114.     register struct lermd *rmd;
  1115.     int len;
  1116.  
  1117.     if (!ledebug)
  1118.         return;
  1119.  
  1120.     rmd = &le->sc_r2->ler2_rmd[le->sc_rmd];
  1121.     len = rmd->rmd3;
  1122.     log(LOG_WARNING,
  1123.         "le%d: ierror(%s): from %s: buf=%d, len=%d, rmd1=%b\n",
  1124.         unit, msg,
  1125.         len > 11 ? ether_sprintf(&le->sc_r2->ler2_rbuf[le->sc_rmd][6]) : "unknown",
  1126.         le->sc_rmd, len,
  1127.         rmd->rmd1,
  1128.         "\20\20OWN\17ERR\16FRAM\15OFLO\14CRC\13RBUF\12STP\11ENP");
  1129. }
  1130.  
  1131. lexerror(unit)
  1132.     int unit;
  1133. {
  1134.     register struct le_softc *le = &le_softc[unit];
  1135.     register struct letmd *tmd;
  1136.     int len;
  1137.  
  1138.     if (!ledebug)
  1139.         return;
  1140.  
  1141.     tmd = le->sc_r2->ler2_tmd;
  1142.     len = -tmd->tmd2;
  1143.     log(LOG_WARNING,
  1144.         "le%d: oerror: to %s: buf=%d, len=%d, tmd1=%b, tmd3=%b\n",
  1145.         unit,
  1146.         len > 5 ? ether_sprintf(&le->sc_r2->ler2_tbuf[0][0]) : "unknown",
  1147.         0, len,
  1148.         tmd->tmd1,
  1149.         "\20\20OWN\17ERR\16RES\15MORE\14ONE\13DEF\12STP\11ENP",
  1150.         tmd->tmd3,
  1151.         "\20\20BUFF\17UFLO\16RES\15LCOL\14LCAR\13RTRY");
  1152. }
  1153. #endif
  1154.