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