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

##### Functions

    il_setaddr        X
    ilattach          X
    ilcint            X
    ilinit            X
    ilioctl           X
    iloutput          X
    ilprobe           X
    ilreset           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
    ildataaddr        X
    is_addr           X
    is_if             X

##### struct's

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

#### Defined functions

il_setaddr defined in line 753; used 1 times

- in line 723

ilattach defined in line 118; used 2 times

- in line 52-56(2)

ilcint defined in line 345; used 3 times

- in line 52, 101, 289

ilinit defined in line 197; used 6 times

- in line 58, 151, 190, 704, 740, 765

ilioctl defined in line 691; used 2 times

- in line 58, 153

iloutput defined in line 530; used 2 times

- in line 58, 152

ilprobe defined in line 92; used 2 times

- in line 52-56(2)

ilreset defined in line 179; used 2 times

- in line 58, 154

ilrint defined in line 408; used 2 times

- in line 52, 101

ilstart defined in line 298; used 3 times

- in line 396, 641, 667

iltotal defined in line 675; used 1 times

- in line 389

ilwait defined in line 159; used 5 times

- in line 135, 142, 235, 256-261(2)

ilwatch defined in line 653; used 3 times

- in line 58, 101, 222

#### Defined variables

il_softc defined in line 90; used 12 times

- in line 121, 188-189(2), 200, 303, 348, 411, 538, 656, 697, 721, 757

ildebug defined in line 59; used 1 times

- in line 144

ildriver defined in line 55; never used
ilinfo defined in line 53; used 7 times

- in line 56, 184, 201, 302, 349, 412, 736

ilstd defined in line 54; used 1 times

- in line 56

#### Defined struct's

il_softc defined in line 73; used 20 times

- in line 121(2), 200(2), 303(2), 348(2), 411(2), 538(2), 656(2), 676(2), 697(2), 757(2)

#### Defined macros

ILF_OACTIVE defined in line 79; used 7 times

- in line 285, 339, 353, 377, 510, 640, 666

ILF_RCVPENDING defined in line 80; used 3 times

- in line 364, 375, 511

ILF_RUNNING defined in line 82; used 8 times

- in line 189, 209, 287, 734-739(3), 759-763(2)

ILF_SETADDR defined in line 83; used 2 times

- in line 250, 764

ILF_STATPENDING defined in line 81; used 4 times

- in line 311-316(2), 660-665(2)

ILUNIT defined in line 57; used 1 times

- in line 301

ILWATCHINTERVAL defined in line 86; used 1 times

- in line 223

ildataaddr defined in line 439; used 2 times

- in line 445-446(2)

is_addr defined in line 76; used 12 times

- in line 147-150(3), 251-254(3), 263-264(2), 625, 721, 762(2)

is_if defined in line 75; used 15 times

- in line 122, 188, 203, 216, 236, 286, 308, 382-384(2), 418, 425-427(2), 461, 657, 685

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