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