# 2.11BSD#431 - /usr/src/sys/pdpif/if_il.c

##### Functions

    il_setaddr        X
    ilattach          X
    ilcint            X
    ilinit            X
    ilioctl           X
    iloutput          X
    ilprobe           X
    ilrint            X
    ilstart           X
    iltotal           X
    ilwait            X
    ilwatch           X

##### Variables

    il_softc          X
    ildebug           X
    ildriver          X
    ilinfo            X
    ilstd             X

##### Macros

    ILF_OACTIVE       X
    ILF_RCVPENDING    X
    ILF_RUNNING       X
    ILF_SETADDR       X
    ILF_STATPENDING   X
    ILUNIT            X
    ILWATCHINTERVAL   X
    MAPBUFDESC        X
    is_addr           X
    is_if             X

##### struct's

    il_softc          X

       1: /*
       2:  * Copyright (c) 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_il.c	2.2 (2.11BSD GTE) 1/6/95
       7:  *
       8:  *	1/6/95 - sms: start of network data was already computed in sys_net.c,
       9:  *		it should no longer be done in this driver.  Using 'startnet'
      10:  *		as an initialization done flag caused the driver to skip
      11:  *		testing for a UNIBUS MAP on an 11/44.  *crash*.
      12:  *		Trailer output capability was removed (it was already gone from
      13:  *		the receive routine as well as several other ether drivers).
      14:  *	12/29/92 - sms: remove Q22 ifdefs, replacing them with runtime tests
      15:  *		  for a Unibus Map.
      16:  *	2.11BSD - Remove ilreset since that's a vax'ism and is never
      17:  *		  called on a pdp-11.  Since the unibus resources are
      18:  *		  allocated in the attach routine and ubarelse is a noop
      19:  *		  remove the second allocation in ilinit.  uballoc calling
      20:  *		  convention altered - sms 9/7/90
      21:  */
      22:
      23: #include "il.h"
      24: #if NIL > 0
      25:
      26: /*
      27:  * Interlan Ethernet Communications Controller interface
      28:  */
      29: #include "param.h"
      30: #include "../machine/seg.h"
      31:
      32: #include "systm.h"
      33: #include "mbuf.h"
      34: #include "buf.h"
      35: #include "domain.h"
      36: #include "protosw.h"
      37: #include "socket.h"
      38: #include "ioctl.h"
      39: #include "if_ilreg.h"
      40: #include "if_il.h"
      41: #include "if_uba.h"
      42: #include "errno.h"
      43: #include "../pdpuba/ubavar.h"
      44: #include "map.h"
      45: #include "uba.h"
      46:
      47: #include "../net/if.h"
      48: #include "../net/netisr.h"
      49:
      50: #ifdef INET
      51: #include "../netinet/in.h"
      52: #include "../netinet/in_systm.h"
      53: #include "../netinet/in_var.h"
      54: #include "../netinet/ip.h"
      55: #include "../netinet/ip_var.h"
      56: #include "../netinet/if_ether.h"
      57: #endif
      58:
      59: #ifdef NS
      60: #include "../netns/ns.h"
      61: #include "../netns/ns_if.h"
      62: #endif
      63:
      64: int ilprobe(), ilattach(), ilrint(), ilcint();
      65: struct  uba_device *ilinfo[NIL];
      66: u_short ilstd[] = { 0 };
      67: struct  uba_driver ildriver =
      68:     { ilprobe, 0, ilattach, 0, ilstd, "il", ilinfo };
      69: #define ILUNIT(x)   minor(x)
      70: int ilinit(),iloutput(),ilioctl(),ilwatch();
      71: int ildebug = 0;
      72: static  short   ilub;
      73: extern  long    startnet;
      74:
      75: /*
      76:  * Ethernet software status per interface.
      77:  *
      78:  * Each interface is referenced by a network interface structure,
      79:  * is_if, which the routing code uses to locate the interface.
      80:  * This structure contains the output queue for the interface, its address, ...
      81:  * We also have, for each interface, a UBA interface structure, which
      82:  * contains information about the UNIBUS resources held by the interface:
      83:  * map registers, buffered data paths, etc.  Information is cached in this
      84:  * structure for use by the if_uba.c routines in running the interface
      85:  * efficiently.
      86:  */
      87: struct  il_softc {
      88:     struct  arpcom is_ac;       /* Ethernet common part */
      89: #define is_if   is_ac.ac_if     /* network-visible interface */
      90: #define is_addr is_ac.ac_enaddr     /* hardware Ethernet address */
      91:     struct  ifuba is_ifuba;     /* UNIBUS resources */
      92:     int is_flags;
      93: #define ILF_OACTIVE 0x1     /* output is active */
      94: #define ILF_RCVPENDING  0x2     /* start rcv in ilcint */
      95: #define ILF_STATPENDING 0x4     /* stat cmd pending */
      96: #define ILF_RUNNING 0x8     /* board is running */
      97: #define ILF_SETADDR 0x10        /* physical address is changed */
      98:     short   is_lastcmd;     /* can't read csr, so must save it */
      99:     short   is_scaninterval;    /* interval of stat collection */
     100: #define ILWATCHINTERVAL 60      /* once every 60 seconds */
     101:     struct  il_stats is_stats;  /* holds on-board statistics */
     102:     struct  il_stats is_sum;    /* summation over time */
     103:     long    is_ubaddr;              /* mapping registers of is_stats */
     104: } il_softc[NIL];
     105:
     106: ilprobe(reg)
     107:     caddr_t reg;
     108: {
     109: #ifdef notdef
     110:     register int br, cvec;      /* r11, r10 value-result */
     111:     register struct ildevice *addr = (struct ildevice *)reg;
     112:     register i;
     113:
     114: #ifdef lint
     115:     br = 0; cvec = br; br = cvec;
     116:     i = 0; ilrint(i); ilcint(i); ilwatch(i);
     117: #endif
     118:
     119:     addr->il_csr = ILC_OFFLINE|IL_CIE;
     120:     DELAY(100000L);
     121:     i = addr->il_csr;       /* clear CDONE */
     122:     if (cvec > 0 && cvec != 0x200)
     123:         cvec -= 4;
     124:     return (1);
     125: #endif
     126: }
     127:
     128: /*
     129:  * Interface exists: make available by filling in network interface
     130:  * record.  System will initialize the interface when it is ready
     131:  * to accept packets.  A STATUS command is done to get the ethernet
     132:  * address and other interesting data.
     133:  */
     134: ilattach(ui)
     135:     struct uba_device *ui;
     136: {
     137:     register struct il_softc *is = &il_softc[ui->ui_unit];
     138:     register struct ifnet *ifp = &is->is_if;
     139:     register struct ildevice *addr = (struct ildevice *)ui->ui_addr;
     140:
     141:     ilub = mfkd(&ubmap);    /* get copy of kernel UBmap flag */
     142:
     143:     ifp->if_unit = ui->ui_unit;
     144:     ifp->if_name = "il";
     145:     ifp->if_mtu = ETHERMTU;
     146:     ifp->if_flags = IFF_BROADCAST;
     147:
     148:     /*
     149: 	 * Reset the board and map the statistics
     150: 	 * buffer onto the Unibus.
     151: 	 */
     152:     addr->il_csr = ILC_RESET;
     153:     (void)ilwait(ui, "reset");
     154:
     155:     if  (ilub)
     156:         {
     157:         is->is_ubaddr = uballoc((caddr_t)&is->is_stats,sizeof(struct il_stats));
     158:         addr->il_csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_STAT;
     159:         }
     160:     else
     161:         {
     162:         is->is_ubaddr = (long)((caddr_t)&is->is_stats) + startnet;
     163:         addr->il_ber = hiint(is->is_ubaddr) & 077;
     164:         addr->il_csr = ILC_STAT;
     165:         }
     166:
     167:     addr->il_bar = loint(is->is_ubaddr);
     168:     addr->il_bcr = sizeof (struct il_stats);
     169:
     170:     (void)ilwait(ui, "status");
     171:     ubarelse(ui->ui_ubanum, &is->is_ubaddr);    /* NOOP on pdp-11 */
     172:     if (ildebug)
     173:         printf("il%d: module=%s firmware=%s\n", ui->ui_unit,
     174:             is->is_stats.ils_module, is->is_stats.ils_firmware);
     175:     bcopy((caddr_t)is->is_stats.ils_addr, (caddr_t)is->is_addr,
     176:         sizeof (is->is_addr));
     177:     printf("il%d: hardware address %s\n", ui->ui_unit,
     178:         ether_sprintf(is->is_addr));
     179:     ifp->if_init = ilinit;
     180:     ifp->if_output = iloutput;
     181:     ifp->if_ioctl = ilioctl;
     182:     ifp->if_reset = 0;
     183:     is->is_ifuba.ifu_flags = UBA_CANTWAIT;
     184:     if_attach(ifp);
     185: }
     186:
     187: ilwait(ui, op)
     188:     struct uba_device *ui;
     189:     char *op;
     190: {
     191:     register struct ildevice *addr = (struct ildevice *)ui->ui_addr;
     192:
     193:     while ((addr->il_csr&IL_CDONE) == 0)
     194:         ;
     195:     if (addr->il_csr&IL_STATUS) {
     196:         printf("il%d: %s failed, csr=%b\n", ui->ui_unit, op,
     197:             addr->il_csr, IL_BITS);
     198:         return (-1);
     199:     }
     200:     return (0);
     201: }
     202:
     203: /*
     204:  * Initialization of interface; clear recorded pending
     205:  * operations, and reinitialize UNIBUS usage.
     206:  */
     207: ilinit(unit)
     208:     int unit;
     209: {
     210:     register struct il_softc *is = &il_softc[unit];
     211:     register struct uba_device *ui = ilinfo[unit];
     212:     register struct ildevice *addr;
     213:     struct ifnet *ifp = &is->is_if;
     214:     int s;
     215:
     216:     /* not yet, if address still unknown */
     217:     if (ifp->if_addrlist == (struct ifaddr *)0)
     218:         return;
     219:     if (is->is_flags & ILF_RUNNING)
     220:         return;
     221:
     222:     if ((ifp->if_flags & IFF_RUNNING) == 0) {
     223:         if (if_ubainit(&is->is_ifuba, ui->ui_ubanum,
     224:             sizeof (struct il_rheader), (int)btoc(ETHERMTU)) == 0) {
     225:             printf("il%d: can't initialize\n", unit);
     226:             is->is_if.if_flags &= ~IFF_UP;
     227:             return;
     228:         }
     229: /*
     230:  * since is->is_ubaddr is set in ilattach and ubarelse is a NOOP the
     231:  * allocation of unibus resources here has been removed.
     232: */
     233:     }
     234:     ifp->if_watchdog = ilwatch;
     235:     is->is_scaninterval = ILWATCHINTERVAL;
     236:     ifp->if_timer = is->is_scaninterval;
     237:     addr = (struct ildevice *)ui->ui_addr;
     238:
     239:     /*
     240: 	 * Turn off source address insertion (it's faster this way),
     241: 	 * and set board online.  Former doesn't work if board is
     242: 	 * already online (happens on ubareset), so we put it offline
     243: 	 * first.
     244: 	 */
     245:     s = splimp();
     246:     addr->il_csr = ILC_RESET;
     247:     if (ilwait(ui, "hardware diag")) {
     248:         is->is_if.if_flags &= ~IFF_UP;
     249:         splx(s);
     250:         return;
     251:     }
     252:     addr->il_csr = ILC_CISA;
     253:     while ((addr->il_csr & IL_CDONE) == 0)
     254:         ;
     255:     /*
     256: 	 * If we must reprogram this board's physical ethernet
     257: 	 * address (as for secondary NS interfaces), we do so
     258: 	 * before putting it on line, and starting receive requests.
     259: 	 * If you try this on an older 1010 board, it will total
     260: 	 * wedge the board.
     261: 	 */
     262:     if (is->is_flags & ILF_SETADDR) {
     263:         bcopy((caddr_t)is->is_addr, (caddr_t)&is->is_stats,
     264:                             sizeof is->is_addr);
     265:         addr->il_bar = loint(is->is_ubaddr);
     266:         addr->il_bcr = sizeof is->is_addr;
     267:         if  (!ilub)
     268:             {
     269:             addr->il_ber = hiint(is->is_ubaddr) & 077;
     270:             addr->il_csr = ILC_LDPA;
     271:             }
     272:         else
     273:             addr->il_csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_LDPA;
     274:         if (ilwait(ui, "setaddr"))
     275:             return;
     276:         addr->il_bar = loint(is->is_ubaddr);
     277:         addr->il_bcr = sizeof (struct il_stats);
     278:         if  (!ilub)
     279:             {
     280:             addr->il_ber = hiint(is->is_ubaddr) & 077;
     281:             addr->il_csr = ILC_STAT;
     282:             }
     283:         else
     284:             addr->il_csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_STAT;
     285:
     286:         if (ilwait(ui, "verifying setaddr"))
     287:             return;
     288:         if (bcmp((caddr_t)is->is_stats.ils_addr, (caddr_t)is->is_addr,
     289:                         sizeof (is->is_addr)) != 0) {
     290:             printf("il%d: setaddr didn't work\n", ui->ui_unit);
     291:             return;
     292:         }
     293:     }
     294:     /*
     295: 	 * Set board online.
     296: 	 * Hang receive buffer and start any pending
     297: 	 * writes by faking a transmit complete.
     298: 	 * Receive bcr is not a multiple of 8 so buffer
     299: 	 * chaining can't happen.
     300: 	 */
     301:     addr->il_csr = ILC_ONLINE;
     302:     while ((addr->il_csr & IL_CDONE) == 0)
     303:         ;
     304:     addr->il_bar = loint(is->is_ifuba.ifu_r.ifrw_info);
     305:     addr->il_bcr = sizeof(struct il_rheader) + ETHERMTU + 6;
     306:     if  (!ilub)
     307:         {
     308:         addr->il_ber = hiint(is->is_ifuba.ifu_r.ifrw_info) & 077;
     309:         addr->il_csr = ILC_RCV|IL_RIE;
     310:         }
     311:     else
     312:         addr->il_csr =
     313:             ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;
     314:     while ((addr->il_csr & IL_CDONE) == 0)
     315:         ;
     316:     is->is_flags = ILF_OACTIVE;
     317:     is->is_if.if_flags |= IFF_RUNNING;
     318:     is->is_flags |= ILF_RUNNING;
     319:     is->is_lastcmd = 0;
     320:     ilcint(unit);
     321:     splx(s);
     322: }
     323:
     324: /*
     325:  * Start output on interface.
     326:  * Get another datagram to send off of the interface queue,
     327:  * and map it to the interface before starting the output.
     328:  */
     329: ilstart(dev)
     330:     dev_t dev;
     331: {
     332:         int unit = ILUNIT(dev), len;
     333:     struct uba_device *ui = ilinfo[unit];
     334:     register struct il_softc *is = &il_softc[unit];
     335:     register struct ildevice *addr;
     336:     struct mbuf *m;
     337:     short csr;
     338:
     339:     IF_DEQUEUE(&is->is_if.if_snd, m);
     340:     addr = (struct ildevice *)ui->ui_addr;
     341:     if (m == 0) {
     342:         if ((is->is_flags & ILF_STATPENDING) == 0)
     343:             return;
     344:         addr->il_bar = loint(is->is_ubaddr);
     345:         addr->il_bcr = sizeof (struct il_stats);
     346:         if  (!ilub)
     347:             {
     348:             addr->il_ber = hiint(is->is_ubaddr) & 077;
     349:             csr = ILC_STAT|IL_RIE|IL_CIE;
     350:             }
     351:         else
     352:             csr = ((is->is_ubaddr >> 2) & IL_EUA)|ILC_STAT|IL_RIE|IL_CIE;
     353:         is->is_flags &= ~ILF_STATPENDING;
     354:         goto startcmd;
     355:     }
     356:     len = if_wubaput(&is->is_ifuba, m);
     357:     /*
     358: 	 * Ensure minimum packet length.
     359: 	 * This makes the safe assumtion that there are no virtual holes
     360: 	 * after the data.
     361: 	 * For security, it might be wise to zero out the added bytes,
     362: 	 * but we're mainly interested in speed at the moment.
     363: 	 */
     364:     if (len - sizeof(struct ether_header) < ETHERMIN)
     365:         len = ETHERMIN + sizeof(struct ether_header);
     366:
     367:     addr->il_bar = loint(is->is_ifuba.ifu_w.ifrw_info);
     368:     addr->il_bcr = len;
     369:     if  (!ilub)
     370:         {
     371:         addr->il_ber = hiint(is->is_ifuba.ifu_w.ifrw_info) & 077;
     372:         csr = ILC_XMIT|IL_CIE|IL_RIE;
     373:         }
     374:     else
     375:         csr =
     376:           ((is->is_ifuba.ifu_w.ifrw_info >> 2) & IL_EUA)|ILC_XMIT|IL_CIE|IL_RIE;
     377:
     378: startcmd:
     379:     is->is_lastcmd = csr & IL_CMD;
     380:     addr->il_csr = csr;
     381:     is->is_flags |= ILF_OACTIVE;
     382: }
     383:
     384: /*
     385:  * Command done interrupt.
     386:  */
     387: ilcint(unit)
     388:     int unit;
     389: {
     390:     register struct il_softc *is = &il_softc[unit];
     391:     struct uba_device *ui = ilinfo[unit];
     392:     register struct ildevice *addr = (struct ildevice *)ui->ui_addr;
     393:     short csr;
     394:
     395:     if ((is->is_flags & ILF_OACTIVE) == 0) {
     396:         printf("il%d: stray xmit interrupt, csr=%b\n", unit,
     397:             addr->il_csr, IL_BITS);
     398:         return;
     399:     }
     400:
     401:     csr = addr->il_csr;
     402:     /*
     403: 	 * Hang receive buffer if it couldn't
     404: 	 * be done earlier (in ilrint).
     405: 	 */
     406:     if (is->is_flags & ILF_RCVPENDING) {
     407:         int s;
     408:
     409:         addr->il_bar = loint(is->is_ifuba.ifu_r.ifrw_info);
     410:         addr->il_bcr = sizeof(struct il_rheader) + ETHERMTU + 6;
     411:         if  (!ilub)
     412:             {
     413:             addr->il_ber = hiint(is->is_ifuba.ifu_r.ifrw_info)&077;
     414:             addr->il_csr = ILC_RCV|IL_RIE;
     415:             }
     416:         else
     417:             addr->il_csr =
     418:           ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;
     419:         s = splhigh();
     420:         while ((addr->il_csr & IL_CDONE) == 0)
     421:             ;
     422:         splx(s);
     423:         is->is_flags &= ~ILF_RCVPENDING;
     424:     }
     425:     is->is_flags &= ~ILF_OACTIVE;
     426:     csr &= IL_STATUS;
     427:     switch (is->is_lastcmd) {
     428:
     429:     case ILC_XMIT:
     430:         is->is_if.if_opackets++;
     431:         if (csr > ILERR_RETRIES)
     432:             is->is_if.if_oerrors++;
     433:         break;
     434:
     435:     case ILC_STAT:
     436:         if (csr == ILERR_SUCCESS)
     437:             iltotal(is);
     438:         break;
     439:     }
     440:     if (is->is_ifuba.ifu_xtofree) {
     441:         m_freem(is->is_ifuba.ifu_xtofree);
     442:         is->is_ifuba.ifu_xtofree = 0;
     443:     }
     444:     ilstart(unit);
     445: }
     446:
     447: /*
     448:  * Ethernet interface receiver interrupt.
     449:  * If input error just drop packet.
     450:  * Otherwise purge input buffered data path and examine
     451:  * packet to determine type.  If can't determine length
     452:  * from type, then have to drop packet.  Othewise decapsulate
     453:  * packet based on type and pass to type specific higher-level
     454:  * input routine.
     455:  */
     456: ilrint(unit)
     457:     int unit;
     458: {
     459:     register struct il_softc *is = &il_softc[unit];
     460:     struct ildevice *addr = (struct ildevice *)ilinfo[unit]->ui_addr;
     461:     register struct il_rheader *il;
     462:         struct mbuf *m;
     463:     int len, off, resid, s;
     464:     int status; /* save status locally so only one restorseg5 */
     465:     register struct ifqueue *inq;
     466:     register int type;
     467:     segm sav5;
     468:
     469: #define MAPBUFDESC  (((btoc(sizeof(struct il_rheader) + ETHERMTU)-1)<<8)|RW)
     470:
     471:     is->is_if.if_ipackets++;
     472:     saveseg5(sav5);
     473:     mapseg5(is->is_ifuba.ifu_r.ifrw_click, MAPBUFDESC);
     474:     il = (struct il_rheader *)SEG5;
     475:     len = il->ilr_length - sizeof(struct il_rheader);
     476:     type = ntohs((u_short)il->ilr_type);
     477:     status = il->ilr_status;
     478:     restorseg5(sav5);
     479:     if ((status&(ILFSTAT_A|ILFSTAT_C)) || len < ETHERMIN ||
     480:         len > ETHERMTU) {
     481:         is->is_if.if_ierrors++;
     482:         goto setup;
     483:     }
     484:
     485:     /*
     486: 	 * Ignore zero length packets and packets with trailers.
     487: 	 */
     488:     if (!len || type >= ETHERTYPE_TRAIL &&
     489:         type < ETHERTYPE_TRAIL+ETHERTYPE_NTRAILER)
     490:         goto setup;
     491:
     492:     /*
     493: 	 * Pull packet off interface.
     494: 	 */
     495:     m = if_rubaget(&is->is_ifuba, len, 0, &is->is_if);
     496:     if (m == 0)
     497:         goto setup;
     498:
     499:     switch (type) {
     500:
     501: #ifdef INET
     502:     case ETHERTYPE_IP:
     503:         schednetisr(NETISR_IP);
     504:         inq = &ipintrq;
     505:         break;
     506:
     507:     case ETHERTYPE_ARP:
     508:         arpinput(&is->is_ac, m);
     509:         goto setup;
     510: #endif
     511: #ifdef NS
     512:     case ETHERTYPE_NS:
     513:         schednetisr(NETISR_NS);
     514:         inq = &nsintrq;
     515:         break;
     516:
     517: #endif
     518:     default:
     519:         m_freem(m);
     520:         goto setup;
     521:     }
     522:
     523:     s = splimp();
     524:     if (IF_QFULL(inq)) {
     525:         IF_DROP(inq);
     526:         m_freem(m);
     527:     } else
     528:         IF_ENQUEUE(inq, m);
     529:     splx(s);
     530:
     531: setup:
     532:     /*
     533: 	 * Reset for next packet if possible.
     534: 	 * If waiting for transmit command completion, set flag
     535: 	 * and wait until command completes.
     536: 	 */
     537:     if (is->is_flags & ILF_OACTIVE) {
     538:         is->is_flags |= ILF_RCVPENDING;
     539:         return;
     540:     }
     541:     addr->il_bar = loint(is->is_ifuba.ifu_r.ifrw_info);
     542:     addr->il_bcr = sizeof(struct il_rheader) + ETHERMTU + 6;
     543:     if  (!ilub)
     544:         {
     545:         addr->il_ber = hiint(is->is_ifuba.ifu_r.ifrw_info) & 077;
     546:         addr->il_csr = ILC_RCV|IL_RIE;
     547:         }
     548:     else
     549:         addr->il_csr =
     550:           ((is->is_ifuba.ifu_r.ifrw_info >> 2) & IL_EUA)|ILC_RCV|IL_RIE;
     551:     s = splhigh();
     552:     while ((addr->il_csr & IL_CDONE) == 0)
     553:         ;
     554:     splx(s);
     555: }
     556:
     557: /*
     558:  * Ethernet output routine.
     559:  * Encapsulate a packet of type family for the local net.
     560:  * Use trailer local net encapsulation if enough data in first
     561:  * packet leaves a multiple of 512 bytes of data in remainder.
     562:  */
     563: iloutput(ifp, m0, dst)
     564:     struct ifnet *ifp;
     565:     struct mbuf *m0;
     566:     struct sockaddr *dst;
     567: {
     568:     int type, s;
     569:     u_char edst[6];
     570:     struct in_addr idst;
     571:     register struct il_softc *is = &il_softc[ifp->if_unit];
     572:     register struct mbuf *m = m0;
     573:     register struct ether_header *il;
     574:     register int off;
     575:     int usetrailers;
     576:
     577:     if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
     578:         m_freem(m);
     579:         return(ENETDOWN);
     580:     }
     581:     switch (dst->sa_family) {
     582:
     583: #ifdef INET
     584:     case AF_INET:
     585:         idst = ((struct sockaddr_in *)dst)->sin_addr;
     586:         if (!arpresolve(&is->is_ac, m, &idst, edst, &usetrailers))
     587:             return (0); /* if not yet resolved */
     588:         type = ETHERTYPE_IP;
     589:         off = 0;
     590:         goto gottype;
     591: #endif
     592: #ifdef NS
     593:     case AF_NS:
     594:         type = ETHERTYPE_NS;
     595:         bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
     596:         (caddr_t)edst, sizeof (edst));
     597:         off = 0;
     598:         goto gottype;
     599: #endif
     600:
     601:     case AF_UNSPEC:
     602:         il = (struct ether_header *)dst->sa_data;
     603:         bcopy((caddr_t)il->ether_dhost, (caddr_t)edst, sizeof (edst));
     604:         type = il->ether_type;
     605:         goto gottype;
     606:
     607:     default:
     608:         printf("il%d: can't handle af%d\n", ifp->if_unit,
     609:             dst->sa_family);
     610:         m_freem(m);
     611:         return(EAFNOSUPPORT);
     612:     }
     613:
     614: gottype:
     615:     /*
     616: 	 * Add local net header.  If no space in first mbuf,
     617: 	 * allocate another.
     618: 	 */
     619:     if (m->m_off > MMAXOFF ||
     620:         MMINOFF + sizeof (struct ether_header) > m->m_off) {
     621:         m = m_get(M_DONTWAIT, MT_HEADER);
     622:         if (m == 0) {
     623:             m_freem(m0);
     624:             return(ENOBUFS);
     625:         }
     626:         m->m_next = m0;
     627:         m->m_off = MMINOFF;
     628:         m->m_len = sizeof (struct ether_header);
     629:     } else {
     630:         m->m_off -= sizeof (struct ether_header);
     631:         m->m_len += sizeof (struct ether_header);
     632:     }
     633:     il = mtod(m, struct ether_header *);
     634:     il->ether_type = htons((u_short)type);
     635:     bcopy((caddr_t)edst, (caddr_t)il->ether_dhost, sizeof (edst));
     636:     bcopy((caddr_t)is->is_addr, (caddr_t)il->ether_shost,
     637:         sizeof(il->ether_shost));
     638:
     639:     /*
     640: 	 * Queue message on interface, and start output if interface
     641: 	 * not yet active.
     642: 	 */
     643:     s = splimp();
     644:     if (IF_QFULL(&ifp->if_snd)) {
     645:         IF_DROP(&ifp->if_snd);
     646:         splx(s);
     647:         m_freem(m);
     648:         return(ENOBUFS);
     649:     }
     650:     IF_ENQUEUE(&ifp->if_snd, m);
     651:     if ((is->is_flags & ILF_OACTIVE) == 0)
     652:         ilstart(ifp->if_unit);
     653:     splx(s);
     654:     return (0);
     655: }
     656:
     657: /*
     658:  * Watchdog routine, request statistics from board.
     659:  */
     660: ilwatch(unit)
     661:     int unit;
     662: {
     663:     register struct il_softc *is = &il_softc[unit];
     664:     register struct ifnet *ifp = &is->is_if;
     665:     int s;
     666:
     667:     if (is->is_flags & ILF_STATPENDING) {
     668:         ifp->if_timer = is->is_scaninterval;
     669:         return;
     670:     }
     671:     s = splimp();
     672:     is->is_flags |= ILF_STATPENDING;
     673:     if ((is->is_flags & ILF_OACTIVE) == 0)
     674:         ilstart(ifp->if_unit);
     675:     splx(s);
     676:     ifp->if_timer = is->is_scaninterval;
     677: }
     678:
     679: /*
     680:  * Total up the on-board statistics.
     681:  */
     682: iltotal(is)
     683:     register struct il_softc *is;
     684: {
     685:     register u_short *interval, *sum, *end;
     686:
     687:     interval = &is->is_stats.ils_frames;
     688:     sum = &is->is_sum.ils_frames;
     689:     end = is->is_sum.ils_fill2;
     690:     while (sum < end)
     691:         *sum++ += *interval++;
     692:     is->is_if.if_collisions = is->is_sum.ils_collis;
     693: }
     694:
     695: /*
     696:  * Process an ioctl request.
     697:  */
     698: ilioctl(ifp, cmd, data)
     699:     register struct ifnet *ifp;
     700:     int cmd;
     701:     caddr_t data;
     702: {
     703:     register struct ifaddr *ifa = (struct ifaddr *)data;
     704:     register struct il_softc *is = &il_softc[ifp->if_unit];
     705:     int s = splimp(), error = 0;
     706:
     707: /*	printf("\tilioctl new:%X\n", ntohl(IA_SIN(ifa)->sin_addr.s_addr));/**/
     708:     switch (cmd) {
     709:
     710:     case SIOCSIFADDR:
     711:         ifp->if_flags |= IFF_UP;
     712:         ilinit(ifp->if_unit);
     713:
     714:         switch (ifa->ifa_addr.sa_family) {
     715: #ifdef INET
     716:         case AF_INET:
     717:             ((struct arpcom *)ifp)->ac_ipaddr =
     718:                 IA_SIN(ifa)->sin_addr;
     719:             arpwhohas((struct arpcom *)ifp, &IA_SIN(ifa)->sin_addr);
     720:             break;
     721: #endif INET
     722: #ifdef NS
     723:         case AF_NS:
     724:             {
     725:             register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
     726:
     727:             if (ns_nullhost(*ina)) {
     728:                 ina->x_host = * (union ns_host *)
     729:                      (il_softc[ifp->if_unit].is_addr);
     730:             } else {
     731:                 il_setaddr(ina->x_host.c_host, ifp->if_unit);
     732:                 return (0);
     733:             }
     734:             break;
     735:             }
     736: #endif NS
     737:         }
     738:         break;
     739:
     740:     case SIOCSIFFLAGS:
     741:         if ((ifp->if_flags & IFF_UP) == 0 &&
     742:             is->is_flags & ILF_RUNNING) {
     743:             ((struct ildevice *)
     744:                (ilinfo[ifp->if_unit]->ui_addr))->il_csr = ILC_RESET;
     745:             is->is_flags &= ~ILF_RUNNING;
     746:         } else if (ifp->if_flags & IFF_UP &&
     747:             (is->is_flags & ILF_RUNNING) == 0)
     748:             ilinit(ifp->if_unit);
     749:         break;
     750:
     751:     default:
     752:         error = EINVAL;
     753:     }
     754:     splx(s);
     755:     return (error);
     756: }
     757:
     758: /*
     759:  * set ethernet address for unit
     760:  */
     761: #ifdef  NS  /* NS way to set addr */
     762: il_setaddr(physaddr, unit)
     763: u_char *physaddr;
     764: int unit;
     765: {
     766:     register struct il_softc *is = &il_softc[unit];
     767:
     768:     if (! (is->is_flags & ILF_RUNNING))
     769:         return;
     770:
     771:     bcopy((caddr_t)physaddr, (caddr_t)is->is_addr, sizeof is->is_addr);
     772:     is->is_flags &= ~ILF_RUNNING;
     773:     is->is_flags |= ILF_SETADDR;
     774:     ilinit(unit);
     775: }
     776: #endif	NS
     777: #endif	NIL

#### Defined functions

il_setaddr defined in line 762; used 1 times

- in line 731

ilattach defined in line 134; used 2 times

- in line 64-68(2)

ilcint defined in line 387; used 3 times

- in line 64, 116, 320

ilinit defined in line 207; used 5 times

- in line 70, 179, 712, 748, 774

ilioctl defined in line 698; used 2 times

- in line 70, 181

iloutput defined in line 563; used 2 times

- in line 70, 180

ilprobe defined in line 106; used 2 times

- in line 64-68(2)

ilrint defined in line 456; used 2 times

- in line 64, 116

ilstart defined in line 329; used 3 times

- in line 444, 652, 674

iltotal defined in line 682; used 1 times

- in line 437

ilwait defined in line 187; used 5 times

- in line 153, 170, 247, 274, 286

ilwatch defined in line 660; used 3 times

- in line 70, 116, 234

#### Defined variables

il_softc defined in line 104; used 10 times

- in line 137, 210, 334, 390, 459, 571, 663, 704, 729, 766

ildebug defined in line 71; used 1 times

- in line 172

ildriver defined in line 67; never used
ilinfo defined in line 65; used 6 times

- in line 68, 211, 333, 391, 460, 744

ilstd defined in line 66; used 1 times

- in line 68

ilub defined in line 72; used 9 times

- in line 141, 155, 267, 278, 306, 346, 369, 411, 543

#### Defined struct's

il_softc defined in line 87; used 20 times

- in line 137(2), 210(2), 334(2), 390(2), 459(2), 571(2), 663(2), 683(2), 704(2), 766(2)

#### Defined macros

ILF_OACTIVE defined in line 93; used 7 times

- in line 316, 381, 395, 425, 537, 651, 673

ILF_RCVPENDING defined in line 94; used 3 times

- in line 406, 423, 538

ILF_RUNNING defined in line 96; used 7 times

- in line 219, 318, 742-747(3), 768-772(2)

ILF_SETADDR defined in line 97; used 2 times

- in line 262, 773

ILF_STATPENDING defined in line 95; used 4 times

- in line 342, 353, 667-672(2)

ILUNIT defined in line 69; used 1 times

- in line 332

ILWATCHINTERVAL defined in line 100; used 1 times

- in line 235

MAPBUFDESC defined in line 469; used 1 times

- in line 473

is_addr defined in line 90; used 12 times

- in line 175-178(3), 263-266(3), 288-289(2), 636, 729, 771(2)

is_if defined in line 89; used 13 times

- in line 138, 213, 226, 248, 317, 339, 430-432(2), 471, 481, 495, 664, 692

Last modified: 1995-01-07 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1808 |