# 2.11BSD#431 - /usr/src/sys/vaxif/if_en.c

##### Functions

    enattach          X
    encollide         X
    endocoll          X
    eninit            X
    enioctl           X
    enoutput          X
    enprobe           X
    enreset           X
    enrint            X
    enstart           X
    enswab            X
    enxint            X

##### Variables

    en_softc          X
    enalldelay        X
    endriver          X
    endst             X
    eninfo            X
    enlastdel         X
    enlastmask        X
    enproto           X
    ensrc             X
    enstd             X

##### Macros

    ENF_SWABIPS       X
    ENMRU             X
    ENMTU             X
    ENUNIT            X
    STEP              X
    endataaddr        X

##### struct's

    en_softc          X

       1: /*
       2:  * Copyright (c) 1982, 1986 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  *
       6:  *	@(#)if_en.c	7.1 (Berkeley) 6/5/86
       7:  */
       8:
       9: #include "en.h"
      10: #if NEN > 0
      11:
      12: /*
      13:  * Xerox prototype (3 Mb) Ethernet interface driver.
      14:  */
      15: #include "../machine/pte.h"
      16:
      17: #include "param.h"
      18: #include "systm.h"
      19: #include "mbuf.h"
      20: #include "buf.h"
      21: #include "protosw.h"
      22: #include "socket.h"
      23: #include "vmmac.h"
      24: #include "errno.h"
      25: #include "ioctl.h"
      26:
      27: #include "../net/if.h"
      28: #include "../net/netisr.h"
      29: #include "../net/route.h"
      30:
      31: #ifdef  INET
      32: #include "../netinet/in.h"
      33: #include "../netinet/in_systm.h"
      34: #include "../netinet/in_var.h"
      35: #include "../netinet/ip.h"
      36: #endif
      37:
      38: #ifdef PUP
      39: #include "../netpup/pup.h"
      40: #include "../netpup/ether.h"
      41: #endif
      42:
      43: #ifdef NS
      44: #include "../netns/ns.h"
      45: #include "../netns/ns_if.h"
      46: #endif
      47:
      48: #include "../vax/cpu.h"
      49: #include "../vax/mtpr.h"
      50: #include "if_en.h"
      51: #include "if_enreg.h"
      52: #include "if_uba.h"
      53: #include "../vaxuba/ubareg.h"
      54: #include "../vaxuba/ubavar.h"
      55:
      56: #define ENMTU   (1024+512)
      57: #define ENMRU   (1024+512+16)       /* 16 is enough to receive trailer */
      58:
      59: int enprobe(), enattach(), enrint(), enxint(), encollide();
      60: struct  uba_device *eninfo[NEN];
      61: u_short enstd[] = { 0 };
      62: struct  uba_driver endriver =
      63:     { enprobe, 0, enattach, 0, enstd, "en", eninfo };
      64: #define ENUNIT(x)   minor(x)
      65:
      66: int eninit(),enoutput(),enreset(),enioctl();
      67:
      68: #ifdef notdef
      69: /*
      70:  * If you need to byte swap IP's in the system, define
      71:  * this and do a SIOCSIFFLAGS at boot time.
      72:  */
      73: #define ENF_SWABIPS 0x1000
      74: #endif
      75:
      76: /*
      77:  * Ethernet software status per interface.
      78:  *
      79:  * Each interface is referenced by a network interface structure,
      80:  * es_if, which the routing code uses to locate the interface.
      81:  * This structure contains the output queue for the interface, its address, ...
      82:  * We also have, for each interface, a UBA interface structure, which
      83:  * contains information about the UNIBUS resources held by the interface:
      84:  * map registers, buffered data paths, etc.  Information is cached in this
      85:  * structure for use by the if_uba.c routines in running the interface
      86:  * efficiently.
      87:  */
      88: struct  en_softc {
      89:     struct  ifnet es_if;        /* network-visible interface */
      90:     struct  ifuba es_ifuba;     /* UNIBUS resources */
      91:     short   es_host;        /* hardware host number */
      92:     short   es_delay;       /* current output delay */
      93:     short   es_mask;        /* mask for current output delay */
      94:     short   es_lastx;       /* host last transmitted to */
      95:     short   es_oactive;     /* is output active? */
      96:     short   es_olen;        /* length of last output */
      97:     short   es_nsactive;        /* is interface enabled for ns? */
      98: } en_softc[NEN];
      99:
     100: /*
     101:  * Do output DMA to determine interface presence and
     102:  * interrupt vector.  DMA is too short to disturb other hosts.
     103:  */
     104: enprobe(reg)
     105:     caddr_t reg;
     106: {
     107:     register int br, cvec;      /* r11, r10 value-result */
     108:     register struct endevice *addr = (struct endevice *)reg;
     109:
     110: #ifdef lint
     111:     br = 0; cvec = br; br = cvec;
     112:     enrint(0); enxint(0); encollide(0);
     113: #endif
     114:     addr->en_istat = 0;
     115:     addr->en_owc = -1;
     116:     addr->en_oba = 0;
     117:     addr->en_ostat = EN_IEN|EN_GO;
     118:     DELAY(100000);
     119:     addr->en_ostat = 0;
     120:     return (1);
     121: }
     122:
     123: /*
     124:  * Interface exists: make available by filling in network interface
     125:  * record.  System will initialize the interface when it is ready
     126:  * to accept packets.
     127:  */
     128: enattach(ui)
     129:     struct uba_device *ui;
     130: {
     131:     register struct en_softc *es = &en_softc[ui->ui_unit];
     132:
     133:     es->es_if.if_unit = ui->ui_unit;
     134:     es->es_if.if_name = "en";
     135:     es->es_if.if_mtu = ENMTU;
     136:     es->es_if.if_flags = IFF_BROADCAST;
     137:     es->es_if.if_init = eninit;
     138:     es->es_if.if_output = enoutput;
     139:     es->es_if.if_ioctl = enioctl;
     140:     es->es_if.if_reset = enreset;
     141:     es->es_ifuba.ifu_flags = UBA_NEEDBDP | UBA_NEED16 | UBA_CANTWAIT;
     142: #if defined(VAX750)
     143:     /* don't chew up 750 bdp's */
     144:     if (cpu == VAX_750 && ui->ui_unit > 0)
     145:         es->es_ifuba.ifu_flags &= ~UBA_NEEDBDP;
     146: #endif
     147:     if_attach(&es->es_if);
     148: }
     149:
     150: /*
     151:  * Reset of interface after UNIBUS reset.
     152:  * If interface is on specified uba, reset its state.
     153:  */
     154: enreset(unit, uban)
     155:     int unit, uban;
     156: {
     157:     register struct uba_device *ui;
     158:
     159:     if (unit >= NEN || (ui = eninfo[unit]) == 0 || ui->ui_alive == 0 ||
     160:         ui->ui_ubanum != uban)
     161:         return;
     162:     printf(" en%d", unit);
     163:     eninit(unit);
     164: }
     165:
     166: /*
     167:  * Initialization of interface; clear recorded pending
     168:  * operations, and reinitialize UNIBUS usage.
     169:  */
     170: eninit(unit)
     171:     int unit;
     172: {
     173:     register struct en_softc *es = &en_softc[unit];
     174:     register struct uba_device *ui = eninfo[unit];
     175:     register struct endevice *addr;
     176:     int s;
     177:
     178:     if (es->es_if.if_addrlist == (struct ifaddr *)0)
     179:         return;
     180:     if (if_ubainit(&es->es_ifuba, ui->ui_ubanum,
     181:         sizeof (struct en_header), (int)btoc(ENMRU)) == 0) {
     182:         printf("en%d: can't initialize\n", unit);
     183:         es->es_if.if_flags &= ~IFF_UP;
     184:         return;
     185:     }
     186:     addr = (struct endevice *)ui->ui_addr;
     187:     addr->en_istat = addr->en_ostat = 0;
     188:
     189:     /*
     190: 	 * Hang a receive and start any
     191: 	 * pending writes by faking a transmit complete.
     192: 	 */
     193:     s = splimp();
     194:     addr->en_iba = es->es_ifuba.ifu_r.ifrw_info;
     195:     addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1;
     196:     addr->en_istat = EN_IEN|EN_GO;
     197:     es->es_oactive = 1;
     198:     es->es_if.if_flags |= IFF_RUNNING;
     199:     enxint(unit);
     200:     splx(s);
     201: }
     202:
     203: int enalldelay = 0;
     204: int enlastdel = 50;
     205: int enlastmask = (~0) << 5;
     206:
     207: /*
     208:  * Start or restart output on interface.
     209:  * If interface is already active, then this is a retransmit
     210:  * after a collision, and just restuff registers and delay.
     211:  * If interface is not already active, get another datagram
     212:  * to send off of the interface queue, and map it to the interface
     213:  * before starting the output.
     214:  */
     215: enstart(dev)
     216:     dev_t dev;
     217: {
     218:         int unit = ENUNIT(dev);
     219:     struct uba_device *ui = eninfo[unit];
     220:     register struct en_softc *es = &en_softc[unit];
     221:     register struct endevice *addr;
     222:     register struct en_header *en;
     223:     struct mbuf *m;
     224:     int dest;
     225:
     226:     if (es->es_oactive)
     227:         goto restart;
     228:
     229:     /*
     230: 	 * Not already active: dequeue another request
     231: 	 * and map it to the UNIBUS.  If no more requests,
     232: 	 * just return.
     233: 	 */
     234:     IF_DEQUEUE(&es->es_if.if_snd, m);
     235:     if (m == 0) {
     236:         es->es_oactive = 0;
     237:         return;
     238:     }
     239:     en = mtod(m, struct en_header *);
     240:     dest = en->en_dhost;
     241:     en->en_shost = es->es_host;
     242:     es->es_olen = if_wubaput(&es->es_ifuba, m);
     243: #ifdef ENF_SWABIPS
     244:     /*
     245: 	 * The Xerox interface does word at a time DMA, so
     246: 	 * someone must do byte swapping of user data if high
     247: 	 * and low ender machines are to communicate.  It doesn't
     248: 	 * belong here, but certain people depend on it, so...
     249: 	 *
     250: 	 * Should swab everybody, but this is a kludge anyway.
     251: 	 */
     252:     if (es->es_if.if_flags & ENF_SWABIPS) {
     253:         en = (struct en_header *)es->es_ifuba.ifu_w.ifrw_addr;
     254:         if (en->en_type == ENTYPE_IP)
     255:             enswab((caddr_t)(en + 1), (caddr_t)(en + 1),
     256:                 es->es_olen - sizeof (struct en_header) + 1);
     257:     }
     258: #endif
     259:
     260:     /*
     261: 	 * Ethernet cannot take back-to-back packets (no
     262: 	 * buffering in interface.  To help avoid overrunning
     263: 	 * receivers, enforce a small delay (about 1ms) in interface:
     264: 	 *	* between all packets when enalldelay
     265: 	 *	* whenever last packet was broadcast
     266: 	 *	* whenever this packet is to same host as last packet
     267: 	 */
     268:     if (enalldelay || es->es_lastx == 0 || es->es_lastx == dest) {
     269:         es->es_delay = enlastdel;
     270:         es->es_mask = enlastmask;
     271:     }
     272:     es->es_lastx = dest;
     273:
     274: restart:
     275:     /*
     276: 	 * Have request mapped to UNIBUS for transmission.
     277: 	 * Purge any stale data from this BDP, and start the otput.
     278: 	 */
     279:     if (es->es_ifuba.ifu_flags & UBA_NEEDBDP)
     280:         UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_w.ifrw_bdp);
     281:     addr = (struct endevice *)ui->ui_addr;
     282:     addr->en_oba = (int)es->es_ifuba.ifu_w.ifrw_info;
     283:     addr->en_odelay = es->es_delay;
     284:     addr->en_owc = -((es->es_olen + 1) >> 1);
     285:     addr->en_ostat = EN_IEN|EN_GO;
     286:     es->es_oactive = 1;
     287: }
     288:
     289: /*
     290:  * Ethernet interface transmitter interrupt.
     291:  * Start another output if more data to send.
     292:  */
     293: enxint(unit)
     294:     int unit;
     295: {
     296:     register struct uba_device *ui = eninfo[unit];
     297:     register struct en_softc *es = &en_softc[unit];
     298:     register struct endevice *addr = (struct endevice *)ui->ui_addr;
     299:
     300:     if (es->es_oactive == 0)
     301:         return;
     302:     if (es->es_mask && (addr->en_ostat&EN_OERROR)) {
     303:         es->es_if.if_oerrors++;
     304:         endocoll(unit);
     305:         return;
     306:     }
     307:     es->es_if.if_opackets++;
     308:     es->es_oactive = 0;
     309:     es->es_delay = 0;
     310:     es->es_mask = ~0;
     311:     if (es->es_ifuba.ifu_xtofree) {
     312:         m_freem(es->es_ifuba.ifu_xtofree);
     313:         es->es_ifuba.ifu_xtofree = 0;
     314:     }
     315:     if (es->es_if.if_snd.ifq_head == 0) {
     316:         es->es_lastx = 256;     /* putatively illegal */
     317:         return;
     318:     }
     319:     enstart(unit);
     320: }
     321:
     322: /*
     323:  * Collision on ethernet interface.  Do exponential
     324:  * backoff, and retransmit.  If have backed off all
     325:  * the way print warning diagnostic, and drop packet.
     326:  */
     327: encollide(unit)
     328:     int unit;
     329: {
     330:     struct en_softc *es = &en_softc[unit];
     331:
     332:     es->es_if.if_collisions++;
     333:     if (es->es_oactive == 0)
     334:         return;
     335:     endocoll(unit);
     336: }
     337:
     338: endocoll(unit)
     339:     int unit;
     340: {
     341:     register struct en_softc *es = &en_softc[unit];
     342:
     343:     /*
     344: 	 * Es_mask is a 16 bit number with n low zero bits, with
     345: 	 * n the number of backoffs.  When es_mask is 0 we have
     346: 	 * backed off 16 times, and give up.
     347: 	 */
     348:     if (es->es_mask == 0) {
     349:         printf("en%d: send error\n", unit);
     350:         enxint(unit);
     351:         return;
     352:     }
     353:     /*
     354: 	 * Another backoff.  Restart with delay based on n low bits
     355: 	 * of the interval timer.
     356: 	 */
     357:     es->es_mask <<= 1;
     358:     es->es_delay = mfpr(ICR) &~ es->es_mask;
     359:     enstart(unit);
     360: }
     361:
     362: #ifdef notdef
     363: struct  sockproto enproto = { AF_ETHERLINK };
     364: struct  sockaddr_en endst = { AF_ETHERLINK };
     365: struct  sockaddr_en ensrc = { AF_ETHERLINK };
     366: #endif
     367: /*
     368:  * Ethernet interface receiver interrupt.
     369:  * If input error just drop packet.
     370:  * Otherwise purge input buffered data path and examine
     371:  * packet to determine type.  If can't determine length
     372:  * from type, then have to drop packet.  Othewise decapsulate
     373:  * packet based on type and pass to type specific higher-level
     374:  * input routine.
     375:  */
     376: enrint(unit)
     377:     int unit;
     378: {
     379:     register struct en_softc *es = &en_softc[unit];
     380:     struct endevice *addr = (struct endevice *)eninfo[unit]->ui_addr;
     381:     register struct en_header *en;
     382:         struct mbuf *m;
     383:     int len; short resid;
     384:     register struct ifqueue *inq;
     385:     int off, s;
     386:
     387:     es->es_if.if_ipackets++;
     388:
     389:     /*
     390: 	 * Purge BDP; drop if input error indicated.
     391: 	 */
     392:     if (es->es_ifuba.ifu_flags & UBA_NEEDBDP)
     393:         UBAPURGE(es->es_ifuba.ifu_uba, es->es_ifuba.ifu_r.ifrw_bdp);
     394:     if (addr->en_istat&EN_IERROR) {
     395:         es->es_if.if_ierrors++;
     396:         goto setup;
     397:     }
     398:
     399:     /*
     400: 	 * Calculate input data length.
     401: 	 * Get pointer to ethernet header (in input buffer).
     402: 	 * Deal with trailer protocol: if type is PUP trailer
     403: 	 * get true type from first 16-bit word past data.
     404: 	 * Remember that type was trailer by setting off.
     405: 	 */
     406:     resid = addr->en_iwc;
     407:     if (resid)
     408:         resid |= 0176000;
     409:     len = (((sizeof (struct en_header) + ENMRU) >> 1) + resid) << 1;
     410:     len -= sizeof (struct en_header);
     411:     if (len > ENMRU)
     412:         goto setup;         /* sanity */
     413:     en = (struct en_header *)(es->es_ifuba.ifu_r.ifrw_addr);
     414:     en->en_type = ntohs(en->en_type);
     415: #define endataaddr(en, off, type)   ((type)(((caddr_t)((en)+1)+(off))))
     416:     if (en->en_type >= ENTYPE_TRAIL &&
     417:         en->en_type < ENTYPE_TRAIL+ENTYPE_NTRAILER) {
     418:         off = (en->en_type - ENTYPE_TRAIL) * 512;
     419:         if (off > ENMTU)
     420:             goto setup;     /* sanity */
     421:         en->en_type = ntohs(*endataaddr(en, off, u_short *));
     422:         resid = ntohs(*(endataaddr(en, off+2, u_short *)));
     423:         if (off + resid > len)
     424:             goto setup;     /* sanity */
     425:         len = off + resid;
     426:     } else
     427:         off = 0;
     428:     if (len == 0)
     429:         goto setup;
     430: #ifdef ENF_SWABIPS
     431:     if (es->es_if.if_flags & ENF_SWABIPS && en->en_type == ENTYPE_IP)
     432:         enswab((caddr_t)(en + 1), (caddr_t)(en + 1), len);
     433: #endif
     434:     /*
     435: 	 * Pull packet off interface.  Off is nonzero if packet
     436: 	 * has trailing header; if_rubaget will then force this header
     437: 	 * information to be at the front, but we still have to drop
     438: 	 * the type and length which are at the front of any trailer data.
     439: 	 */
     440:     m = if_rubaget(&es->es_ifuba, len, off, &es->es_if);
     441:     if (m == 0)
     442:         goto setup;
     443:     if (off) {
     444:         struct ifnet *ifp;
     445:
     446:         ifp = *(mtod(m, struct ifnet **));
     447:         m->m_off += 2 * sizeof (u_short);
     448:         m->m_len -= 2 * sizeof (u_short);
     449:         *(mtod(m, struct ifnet **)) = ifp;
     450:     }
     451:     switch (en->en_type) {
     452:
     453: #ifdef INET
     454:     case ENTYPE_IP:
     455:         schednetisr(NETISR_IP);
     456:         inq = &ipintrq;
     457:         break;
     458: #endif
     459: #ifdef PUP
     460:     case ENTYPE_PUP:
     461:         rpup_input(m);
     462:         goto setup;
     463: #endif
     464: #ifdef NS
     465:     case ETHERTYPE_NS:
     466:         if (es->es_nsactive) {
     467:             schednetisr(NETISR_NS);
     468:             inq = &nsintrq;
     469:         } else {
     470:             m_freem(m);
     471:             goto setup;
     472:         }
     473:         break;
     474: #endif
     475:
     476:     default:
     477: #ifdef notdef
     478:         enproto.sp_protocol = en->en_type;
     479:         endst.sen_host = en->en_dhost;
     480:         endst.sen_net = ensrc.sen_net = es->es_if.if_net;
     481:         ensrc.sen_host = en->en_shost;
     482:         raw_input(m, &enproto,
     483:             (struct sockaddr *)&ensrc, (struct sockaddr *)&endst);
     484: #else
     485:         m_freem(m);
     486: #endif
     487:         goto setup;
     488:     }
     489:
     490:     s = splimp();
     491:     if (IF_QFULL(inq)) {
     492:         IF_DROP(inq);
     493:         m_freem(m);
     494:     } else
     495:         IF_ENQUEUE(inq, m);
     496:     splx(s);
     497:
     498: setup:
     499:     /*
     500: 	 * Reset for next packet.
     501: 	 */
     502:     addr->en_iba = es->es_ifuba.ifu_r.ifrw_info;
     503:     addr->en_iwc = -(sizeof (struct en_header) + ENMRU) >> 1;
     504:     addr->en_istat = EN_IEN|EN_GO;
     505: }
     506:
     507: /*
     508:  * Ethernet output routine.
     509:  * Encapsulate a packet of type family for the local net.
     510:  * Use trailer local net encapsulation if enough data in first
     511:  * packet leaves a multiple of 512 bytes of data in remainder.
     512:  */
     513: enoutput(ifp, m0, dst)
     514:     struct ifnet *ifp;
     515:     struct mbuf *m0;
     516:     struct sockaddr *dst;
     517: {
     518:     int type, dest, s, error;
     519:     register struct mbuf *m = m0;
     520:     register struct en_header *en;
     521:     register int off;
     522:
     523:     if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
     524:         error = ENETDOWN;
     525:         goto bad;
     526:     }
     527:     switch (dst->sa_family) {
     528:
     529: #ifdef INET
     530:     case AF_INET:
     531:         {
     532:         struct in_addr in;
     533:
     534:         in = ((struct sockaddr_in *)dst)->sin_addr;
     535:         if (in_broadcast(in))
     536:             dest = EN_BROADCAST;
     537:         else
     538:             dest = in_lnaof(in);
     539:         }
     540:         if (dest >= 0x100) {
     541:             error = EPERM;      /* ??? */
     542:             goto bad;
     543:         }
     544:         off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;
     545:         /* need per host negotiation */
     546:         if ((ifp->if_flags & IFF_NOTRAILERS) == 0)
     547:         if (off > 0 && (off & 0x1ff) == 0 &&
     548:             m->m_off >= MMINOFF + 2 * sizeof (u_short)) {
     549:             type = ENTYPE_TRAIL + (off>>9);
     550:             m->m_off -= 2 * sizeof (u_short);
     551:             m->m_len += 2 * sizeof (u_short);
     552:             *mtod(m, u_short *) = htons((u_short)ENTYPE_IP);
     553:             *(mtod(m, u_short *) + 1) = ntohs((u_short)m->m_len);
     554:             goto gottrailertype;
     555:         }
     556:         type = ENTYPE_IP;
     557:         off = 0;
     558:         goto gottype;
     559: #endif
     560: #ifdef NS
     561:     case AF_NS:
     562:     {
     563:         u_char *up;
     564:
     565:         type = ETHERTYPE_NS;
     566:         up = ((struct sockaddr_ns *)dst)->sns_addr.x_host.c_host;
     567:         if (*up & 1)
     568:             dest = EN_BROADCAST;
     569:         else
     570:             dest = up[5];
     571:
     572:         off = 0;
     573:         goto gottype;
     574:     }
     575: #endif
     576: #ifdef PUP
     577:     case AF_PUP:
     578:         dest = ((struct sockaddr_pup *)dst)->spup_host;
     579:         type = ENTYPE_PUP;
     580:         off = 0;
     581:         goto gottype;
     582: #endif
     583:
     584: #ifdef notdef
     585:     case AF_ETHERLINK:
     586:         goto gotheader;
     587: #endif
     588:
     589:     default:
     590:         printf("en%d: can't handle af%d\n", ifp->if_unit,
     591:             dst->sa_family);
     592:         error = EAFNOSUPPORT;
     593:         goto bad;
     594:     }
     595:
     596: gottrailertype:
     597:     /*
     598: 	 * Packet to be sent as trailer: move first packet
     599: 	 * (control information) to end of chain.
     600: 	 */
     601:     while (m->m_next)
     602:         m = m->m_next;
     603:     m->m_next = m0;
     604:     m = m0->m_next;
     605:     m0->m_next = 0;
     606:     m0 = m;
     607:
     608: gottype:
     609:     /*
     610: 	 * Add local net header.  If no space in first mbuf,
     611: 	 * allocate another.
     612: 	 */
     613:     if (m->m_off > MMAXOFF ||
     614:         MMINOFF + sizeof (struct en_header) > m->m_off) {
     615:         MGET(m, M_DONTWAIT, MT_HEADER);
     616:         if (m == 0) {
     617:             error = ENOBUFS;
     618:             goto bad;
     619:         }
     620:         m->m_next = m0;
     621:         m->m_off = MMINOFF;
     622:         m->m_len = sizeof (struct en_header);
     623:     } else {
     624:         m->m_off -= sizeof (struct en_header);
     625:         m->m_len += sizeof (struct en_header);
     626:     }
     627:     en = mtod(m, struct en_header *);
     628:     /* add en_shost later */
     629:     en->en_dhost = dest;
     630:     en->en_type = htons((u_short)type);
     631:
     632: #ifdef notdef
     633: gotheader:
     634: #endif
     635:     /*
     636: 	 * Queue message on interface, and start output if interface
     637: 	 * not yet active.
     638: 	 */
     639:     s = splimp();
     640:     if (IF_QFULL(&ifp->if_snd)) {
     641:         IF_DROP(&ifp->if_snd);
     642:         error = ENOBUFS;
     643:         goto qfull;
     644:     }
     645:     IF_ENQUEUE(&ifp->if_snd, m);
     646:     if (en_softc[ifp->if_unit].es_oactive == 0)
     647:         enstart(ifp->if_unit);
     648:     splx(s);
     649:     return (0);
     650: qfull:
     651:     m0 = m;
     652:     splx(s);
     653: bad:
     654:     m_freem(m0);
     655:     return (error);
     656: }
     657:
     658: /*
     659:  * Process an ioctl request.
     660:  */
     661: enioctl(ifp, cmd, data)
     662:     register struct ifnet *ifp;
     663:     int cmd;
     664:     caddr_t data;
     665: {
     666:     register struct en_softc *es = ((struct en_softc *)ifp);
     667:     struct ifaddr *ifa = (struct ifaddr *) data;
     668:     int s = splimp(), error = 0;
     669:     struct endevice *enaddr;
     670:
     671:     switch (cmd) {
     672:
     673:     case SIOCSIFADDR:
     674:         enaddr = (struct endevice *)eninfo[ifp->if_unit]->ui_addr;
     675:         es->es_host = (~enaddr->en_addr) & 0xff;
     676:         /*
     677: 		 * Attempt to check agreement of protocol address
     678: 		 * and board address.
     679: 		 */
     680:         switch (ifa->ifa_addr.sa_family) {
     681:         case AF_INET:
     682:             if (in_lnaof(IA_SIN(ifa)->sin_addr) != es->es_host)
     683:                 return (EADDRNOTAVAIL);
     684:             break;
     685: #ifdef NS
     686:         case AF_NS:
     687:             if (IA_SNS(ifa)->sns_addr.x_host.c_host[5]
     688:                             != es->es_host)
     689:                 return (EADDRNOTAVAIL);
     690:             es->es_nsactive = 1;
     691:             break;
     692: #endif
     693:         }
     694:         ifp->if_flags |= IFF_UP;
     695:         if ((ifp->if_flags & IFF_RUNNING) == 0)
     696:             eninit(ifp->if_unit);
     697:         break;
     698:
     699:     default:
     700:         error = EINVAL;
     701:         break;
     702:     }
     703:     splx(s);
     704:     return (error);
     705: }
     706:
     707: #ifdef ENF_SWABIPS
     708: /*
     709:  * Swab bytes
     710:  * Jeffrey Mogul, Stanford
     711:  */
     712: enswab(from, to, n)
     713:     register unsigned char *from, *to;
     714:     register int n;
     715: {
     716:     register unsigned long temp;
     717:
     718:     if ((n <= 0) || (n > 0xFFFF)) {
     719:         printf("enswab: bad len %d\n", n);
     720:         return;
     721:     }
     722:
     723:     n >>= 1; n++;
     724: #define STEP    {temp = *from++;*to++ = *from++;*to++ = temp;}
     725:     /* round to multiple of 8 */
     726:     while ((--n) & 07)
     727:         STEP;
     728:     n >>= 3;
     729:     while (--n >= 0) {
     730:         STEP; STEP; STEP; STEP;
     731:         STEP; STEP; STEP; STEP;
     732:     }
     733: }
     734: #endif
     735: #endif

#### Defined functions

enattach defined in line 128; used 2 times

- in line 59-63(2)

encollide defined in line 327; used 2 times

- in line 59, 112

endocoll defined in line 338; used 2 times

- in line 304, 335

eninit defined in line 170; used 4 times

- in line 66, 137, 163, 696

enioctl defined in line 661; used 2 times

- in line 66, 139

enoutput defined in line 513; used 2 times

- in line 66, 138

enprobe defined in line 104; used 2 times

- in line 59-63(2)

enreset defined in line 154; used 2 times

- in line 66, 140

enrint defined in line 376; used 2 times

- in line 59, 112

enstart defined in line 215; used 3 times

- in line 319, 359, 647

enswab defined in line 712; used 2 times

- in line 255, 432

enxint defined in line 293; used 4 times

- in line 59, 112, 199, 350

#### Defined variables

en_softc defined in line 98; used 8 times

- in line 131, 173, 220, 297, 330, 341, 379, 646

enalldelay defined in line 203; used 1 times

- in line 268

endriver defined in line 62; never used
endst defined in line 364; used 3 times

- in line 479-483(3)

eninfo defined in line 60; used 7 times

- in line 63, 159, 174, 219, 296, 380, 674

enlastdel defined in line 204; used 1 times

- in line 269

enlastmask defined in line 205; used 1 times

- in line 270

enproto defined in line 363; used 2 times

- in line 478-482(2)

ensrc defined in line 365; used 3 times

- in line 480-483(3)

enstd defined in line 61; used 1 times

- in line 63

#### Defined struct's

en_softc defined in line 88; used 18 times

- in line 131(2), 173(2), 220(2), 297(2), 330(2), 341(2), 379(2), 666(4)

#### Defined macros

ENF_SWABIPS defined in line 73; used 5 times

- in line 243, 252, 430-431(2), 707

ENMRU defined in line 57; used 5 times

- in line 181, 195, 409-411(2), 503

ENMTU defined in line 56; used 2 times

- in line 135, 419

ENUNIT defined in line 64; used 1 times

- in line 218

STEP defined in line 724; used 9 times

- in line 727-731(9)

endataaddr defined in line 415; used 2 times

- in line 421-422(2)

Last modified: 1986-06-06 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 307 |