1: /*
   2:  * Copyright (c) 1982,1986,1988 Regents of the University of California.
   3:  * All rights reserved.
   4:  *
   5:  * Redistribution and use in source and binary forms are permitted
   6:  * provided that this notice is preserved and that due credit is given
   7:  * to the University of California at Berkeley. The name of the University
   8:  * may not be used to endorse or promote products derived from this
   9:  * software without specific prior written permission. This software
  10:  * is provided ``as is'' without express or implied warranty.
  11:  *
  12:  *	%W% (Berkeley) %G%
  13:  */
  14: 
  15: #include "css.h"
  16: #if NCSS > 0
  17: 
  18: /*
  19:  * DEC/CSS IMP11-A ARPAnet IMP interface driver.
  20:  * Since "imp11a" is such a mouthful, it is called
  21:  * "css" after the LH/DH being called "acc".
  22:  *
  23:  * Configuration notes:
  24:  *
  25:  * As delivered from DEC/CSS, it
  26:  * is addressed and vectored as two DR11-B's.  This makes
  27:  * Autoconfig almost IMPOSSIBLE.  To make it work, the
  28:  * interrupt vectors must be restrapped to make the vectors
  29:  * consecutive.  The 020 hole between the CSR addresses is
  30:  * tolerated, althought that could be cleaned-up also.
  31:  *
  32:  * Additionally, the TRANSMIT side of the IMP11-A has the
  33:  * lower address of the two subunits, so the vector ordering
  34:  * in the CONFIG file is reversed from most other devices.
  35:  * It should be:
  36:  *
  37:  * device css0 ....  cssxint cssrint
  38:  *
  39:  * If you get it wrong, it will still autoconfig, but will just
  40:  * sit there with RECEIVE IDLE indicated on the front panel.
  41:  */
  42: #include "param.h"
  43: #include "systm.h"
  44: #include "mbuf.h"
  45: #include "buf.h"
  46: #include "protosw.h"
  47: #include "socket.h"
  48: #include "vmmac.h"
  49: 
  50: #include "../machine/pte.h"
  51: 
  52: #include "../net/if.h"
  53: #include "../netimp/if_imp.h"
  54: 
  55: #include "../vax/cpu.h"
  56: #include "../vax/mtpr.h"
  57: #include "if_cssreg.h"
  58: #include "if_uba.h"
  59: #include "../vaxuba/ubareg.h"
  60: #include "../vaxuba/ubavar.h"
  61: 
  62: int     cssprobe(), cssattach(), cssrint(), cssxint();
  63: struct  uba_device *cssinfo[NCSS];
  64: u_short cssstd[] = { 0 };
  65: struct  uba_driver cssdriver =
  66:         { cssprobe, 0, cssattach, 0, cssstd, "css", cssinfo };
  67: 
  68: int     cssinit(), cssoutput(), cssdown(), cssreset();
  69: 
  70: /*
  71:  * "Lower half" of IMP interface driver.
  72:  *
  73:  * Each IMP interface is handled by a common module which handles
  74:  * the IMP-host protocol and a hardware driver which manages the
  75:  * hardware specific details of talking with the IMP.
  76:  *
  77:  * The hardware portion of the IMP driver handles DMA and related
  78:  * management of UNIBUS resources.  The IMP protocol module interprets
  79:  * contents of these messages and "controls" the actions of the
  80:  * hardware module during IMP resets, but not, for instance, during
  81:  * UNIBUS resets.
  82:  *
  83:  * The two modules are coupled at "attach time", and ever after,
  84:  * through the imp interface structure.  Higher level protocols,
  85:  * e.g. IP, interact with the IMP driver, rather than the CSS.
  86:  */
  87: struct  css_softc {
  88:     struct  imp_softc *css_imp; /* pointer to IMP's imp_softc struct */
  89:     struct  ifuba css_ifuba;    /* UNIBUS resources */
  90:     struct  mbuf *css_iq;       /* input reassembly queue */
  91:     short   css_olen;       /* size of last message sent */
  92:     char    css_flush;      /* flush remainder of message */
  93: } css_softc[NCSS];
  94: 
  95: /*
  96:  * Reset the IMP and cause a transmitter interrupt by
  97:  * performing a null DMA.
  98:  */
  99: cssprobe(reg)
 100:         caddr_t reg;
 101: {
 102:         register int br, cvec;          /* r11, r10 value-result */
 103:         register struct cssdevice *addr = (struct cssdevice *)reg;
 104: 
 105: #ifdef lint
 106:         br = 0; cvec = br; br = cvec;
 107:         cssrint(0); cssxint(0);
 108: #endif
 109: 
 110:         addr->css_icsr = CSS_CLR;
 111:         addr->css_ocsr = CSS_CLR;
 112:         DELAY(50000);
 113:     addr->css_icsr = 0;
 114:     addr->css_ocsr = 0;
 115:         DELAY(50000);
 116: 
 117:     addr->css_oba = 0;
 118:     addr->css_owc = -1;
 119:         addr->css_ocsr = CSS_IE | CSS_GO;   /* enable interrupts */
 120:         DELAY(50000);
 121:         addr->css_ocsr = 0;
 122: 
 123:         return (1);
 124: }
 125: 
 126: /*
 127:  * Call the IMP module to allow it to set up its internal
 128:  * state, then tie the two modules together by setting up
 129:  * the back pointers to common data structures.
 130:  */
 131: cssattach(ui)
 132:         register struct uba_device *ui;
 133: {
 134:         register struct css_softc *sc = &css_softc[ui->ui_unit];
 135:         register struct impcb *ip;
 136: 
 137:         if ((sc->css_imp = impattach(ui->ui_driver->ud_dname, ui->ui_unit,
 138:         cssreset)) == 0)
 139:                 return;
 140:     ip = &sc->css_imp->imp_cb;
 141:         ip->ic_init = cssinit;
 142:         ip->ic_output = cssoutput;
 143:         ip->ic_down = cssdown;
 144:     sc->css_ifuba.ifu_flags = UBA_CANTWAIT | UBA_NEED16;
 145: #ifdef notdef
 146:     sc->css_ifuba.ifu_flags |= UBA_NEEDBDP;
 147: #endif
 148: }
 149: 
 150: /*
 151:  * Reset interface after UNIBUS reset.
 152:  * If interface is on specified uba, reset its state.
 153:  */
 154: cssreset(unit, uban)
 155:         int unit, uban;
 156: {
 157:         register struct uba_device *ui;
 158:         register struct css_softc *sc;
 159: 
 160:         if (unit >= NCSS || (ui = cssinfo[unit]) == 0 || ui->ui_alive == 0 ||
 161:             ui->ui_ubanum != uban)
 162:                 return;
 163:         printf(" css%d", unit);
 164:         sc = &css_softc[unit];
 165:     sc->css_imp->imp_if.if_flags &= ~IFF_RUNNING;
 166:         /* must go through IMP to allow it to set state */
 167:         (*sc->css_imp->imp_if.if_init)(sc->css_imp->imp_if.if_unit);
 168: }
 169: 
 170: /*
 171:  * Initialize interface: clear recorded pending operations,
 172:  * and retrieve, and reinitialize UNIBUS resources.
 173:  */
 174: cssinit(unit)
 175:         int unit;
 176: {
 177:         register struct css_softc *sc;
 178:         register struct uba_device *ui;
 179:         register struct cssdevice *addr;
 180:         int x, info;
 181: 
 182:     if (unit >= NCSS || (ui = cssinfo[unit]) == 0 || ui->ui_alive == 0) {
 183:         printf("css%d: not alive\n", unit);
 184:         return(0);
 185:     }
 186:     sc = &css_softc[unit];
 187: 
 188:     /*
 189: 	 * Header length is 0 to if_ubainit since we have to pass
 190: 	 * the IMP leader up to the protocol interpretaion
 191: 	 * routines.  If we had the deader length as
 192: 	 * sizeof(struct imp_leader), then the if_ routines
 193: 	 * would assume we handle it on input and output.
 194: 	 */
 195: 
 196:         if ((sc->css_imp->imp_if.if_flags & IFF_RUNNING) == 0 &&
 197:         if_ubainit(&sc->css_ifuba, ui->ui_ubanum, 0,
 198:         (int)btoc(IMP_RCVBUF)) == 0) {
 199:                 printf("css%d: can't initialize\n", unit);
 200:         ui->ui_alive = 0;
 201:         sc->css_imp->imp_if.if_flags &= ~(IFF_UP | IFF_RUNNING);
 202:         return(0);
 203:         }
 204:     sc->css_imp->imp_if.if_flags |= IFF_RUNNING;
 205:         addr = (struct cssdevice *)ui->ui_addr;
 206: 
 207:         /* reset the imp interface. */
 208:         x = spl5();
 209:         addr->css_icsr = CSS_CLR;
 210:         addr->css_ocsr = CSS_CLR;
 211:     DELAY(100);
 212:     addr->css_icsr = 0;
 213:     addr->css_ocsr = 0;
 214:         addr->css_icsr = IN_HRDY;       /* close the relay */
 215:     DELAY(5000);
 216:         splx(x);
 217: 
 218:         /*
 219: 	 * This may hang if the imp isn't really there.
 220: 	 * Will test and verify safe operation.
 221: 	 */
 222: 
 223:     x = 500;
 224:     while (x-- > 0) {
 225:         if ((addr->css_icsr & (IN_HRDY|IN_IMPNR)) == IN_HRDY)
 226:             break;
 227:                 addr->css_icsr = IN_HRDY;   /* close the relay */
 228:                 DELAY(5000);
 229:         }
 230: 
 231:     if (x <= 0) {
 232:         printf("css%d: imp doesn't respond, icsr=%b\n", unit,
 233:             CSS_INBITS, addr->css_icsr);
 234:         goto down;
 235:     }
 236: 
 237:         /*
 238:          * Put up a read.  We can't restart any outstanding writes
 239:          * until we're back in synch with the IMP (i.e. we've flushed
 240:          * the NOOPs it throws at us).
 241: 	 * Note: IMP_RCVBUF includes the leader.
 242:          */
 243: 
 244:         x = spl5();
 245:         info = sc->css_ifuba.ifu_r.ifrw_info;
 246:         addr->css_iba = (u_short)info;
 247:         addr->css_iwc = -(IMP_RCVBUF >> 1);
 248:         addr->css_icsr =
 249:                 IN_HRDY | CSS_IE | IN_WEN | ((info & 0x30000) >> 12) | CSS_GO;
 250:         splx(x);
 251:     return(1);
 252: 
 253: down:
 254:     ui->ui_alive = 0;
 255:     return(0);
 256: }
 257: 
 258: /*
 259:  * Drop the host ready line to mark host down.
 260:  * UNTESTED.
 261:  */
 262: cssdown(unit)
 263:     int unit;
 264: {
 265:         register struct cssdevice *addr;
 266:     int x;
 267: 
 268:     addr = (struct cssdevice *)(cssinfo[unit]->ui_addr);
 269:         /* reset the imp interface. */
 270:         x = spl5();
 271:         addr->css_icsr = CSS_CLR;
 272:         addr->css_ocsr = CSS_CLR;
 273:     DELAY(100);
 274:     addr->css_icsr = 0;
 275:     addr->css_ocsr = 0;
 276:         splx(x);
 277:     return (1);
 278: }
 279: 
 280: /*
 281:  * Start output on an interface.
 282:  */
 283: cssoutput(unit, m)
 284:         int unit;
 285:         struct mbuf *m;
 286: {
 287:         int info;
 288:         struct uba_device *ui = cssinfo[unit];
 289:         register struct css_softc *sc = &css_softc[unit];
 290:         register struct cssdevice *addr;
 291: 
 292:         sc->css_olen = if_wubaput(&sc->css_ifuba, m);
 293:         /*
 294:          * Have request mapped to UNIBUS for transmission.
 295:          * Purge any stale data from the BDP, and start the output.
 296:          */
 297:     if (sc->css_ifuba.ifu_flags & UBA_NEEDBDP)
 298:         UBAPURGE(sc->css_ifuba.ifu_uba, sc->css_ifuba.ifu_w.ifrw_bdp);
 299:         addr = (struct cssdevice *)ui->ui_addr;
 300:         info = sc->css_ifuba.ifu_w.ifrw_info;
 301:         addr->css_oba = (u_short)info;
 302:         addr->css_owc = -((sc->css_olen + 1) >> 1);
 303:         addr->css_ocsr =
 304:         (u_short)(CSS_IE | OUT_ENLB | ((info & 0x30000) >> 12) | CSS_GO);
 305:         sc->css_imp->imp_cb.ic_oactive = 1;
 306: }
 307: 
 308: /*
 309:  * Output interrupt handler.
 310:  */
 311: cssxint(unit)
 312: {
 313:         register struct uba_device *ui = cssinfo[unit];
 314:         register struct css_softc *sc = &css_softc[unit];
 315:         register struct cssdevice *addr;
 316: 
 317:         addr = (struct cssdevice *)ui->ui_addr;
 318:         if (sc->css_imp->imp_cb.ic_oactive == 0) {
 319:                 printf("css%d: stray output interrupt csr=%b\n",
 320:             unit, addr->css_ocsr, CSS_OUTBITS);
 321:                 return;
 322:         }
 323:         sc->css_imp->imp_if.if_opackets++;
 324:         sc->css_imp->imp_cb.ic_oactive = 0;
 325:         if (addr->css_ocsr & CSS_ERR){
 326:                 sc->css_imp->imp_if.if_oerrors++;
 327:                 printf("css%d: output error, ocsr=%b icsr=%b\n", unit,
 328:                         addr->css_ocsr, CSS_OUTBITS,
 329:             addr->css_icsr, CSS_INBITS);
 330:     }
 331:     if (sc->css_ifuba.ifu_xtofree) {
 332:         m_freem(sc->css_ifuba.ifu_xtofree);
 333:         sc->css_ifuba.ifu_xtofree = 0;
 334:     }
 335:     impstart(sc->css_imp);
 336: }
 337: 
 338: /*
 339:  * Input interrupt handler
 340:  */
 341: cssrint(unit)
 342: {
 343:         register struct css_softc *sc = &css_softc[unit];
 344:         register struct cssdevice *addr;
 345:         struct mbuf *m;
 346:         int len, info;
 347: 
 348:         sc->css_imp->imp_if.if_ipackets++;
 349: 
 350:         /*
 351:          * Purge BDP; flush message if error indicated.
 352:          */
 353: 
 354:         addr = (struct cssdevice *)cssinfo[unit]->ui_addr;
 355:     if (sc->css_ifuba.ifu_flags & UBA_NEEDBDP)
 356:         UBAPURGE(sc->css_ifuba.ifu_uba, sc->css_ifuba.ifu_r.ifrw_bdp);
 357:         if (addr->css_icsr & CSS_ERR) {
 358:                 printf("css%d: recv error, csr=%b\n", unit,
 359:                     addr->css_icsr, CSS_INBITS);
 360:                 sc->css_imp->imp_if.if_ierrors++;
 361:                 sc->css_flush = 1;
 362:         }
 363: 
 364:         if (sc->css_flush) {
 365:                 if (addr->css_icsr & IN_EOM)
 366:                         sc->css_flush = 0;
 367:                 goto setup;
 368:         }
 369: 
 370:         len = IMP_RCVBUF + (addr->css_iwc << 1);
 371:     if (len < 0 || len > IMP_RCVBUF) {
 372:         printf("css%d: bad length=%d\n", len);
 373:         sc->css_imp->imp_if.if_ierrors++;
 374:         goto setup;
 375:     }
 376: 
 377:         /*
 378:          * The offset parameter is always 0 since using
 379:          * trailers on the ARPAnet is insane.
 380:          */
 381:         m = if_rubaget(&sc->css_ifuba, len, 0, &sc->css_imp->imp_if);
 382:         if (m == 0)
 383:                 goto setup;
 384:         if ((addr->css_icsr & IN_EOM) == 0) {
 385:         if (sc->css_iq)
 386:             m_cat(sc->css_iq, m);
 387:         else
 388:             sc->css_iq = m;
 389:         goto setup;
 390:     }
 391:     if (sc->css_iq) {
 392:         m_cat(sc->css_iq, m);
 393:         m = sc->css_iq;
 394:         sc->css_iq = 0;
 395:         }
 396:         impinput(unit, m);
 397: 
 398: setup:
 399:         /*
 400:          * Setup for next message.
 401:          */
 402:         info = sc->css_ifuba.ifu_r.ifrw_info;
 403:         addr->css_iba = (u_short)info;
 404:         addr->css_iwc = - (IMP_RCVBUF >> 1);
 405:         addr->css_icsr =
 406:                 IN_HRDY | CSS_IE | IN_WEN | ((info & 0x30000) >> 12) | CSS_GO;
 407: }
 408: #endif

Defined functions

cssattach defined in line 131; used 2 times
cssdown defined in line 262; used 2 times
cssinit defined in line 174; used 2 times
cssoutput defined in line 283; used 2 times
cssprobe defined in line 99; used 2 times
cssreset defined in line 154; used 2 times
cssrint defined in line 341; used 2 times
cssxint defined in line 311; used 2 times

Defined variables

css_softc defined in line 93; used 6 times
cssdriver defined in line 65; never used
cssinfo defined in line 63; used 7 times
cssstd defined in line 64; used 1 times
  • in line 66

Defined struct's

css_softc defined in line 87; used 12 times
Last modified: 1988-02-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1709
Valid CSS Valid XHTML 1.0 Strict