xref: /dragonfly/sys/dev/misc/musycc/musycc.c (revision 7d84b73d)
1 /*
2  * ----------------------------------------------------------------------------
3  * "THE BEER-WARE LICENSE" (Revision 42):
4  * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
5  * can do whatever you want with this stuff. If we meet some day, and you think
6  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7  * ----------------------------------------------------------------------------
8  *
9  * $FreeBSD: src/sys/dev/musycc/musycc.c,v 1.17.2.3 2001/03/13 22:05:36 phk Exp $
10  *
11  *
12  *
13  * Card state machine:
14  * -------------------
15  *
16  * This is the state engine which drives the card "as such" which in reality
17  * means the MUSYCC chip.
18  *
19  *  State	Description
20  *
21  *  IDLE	The card is in this state when no channels are configured.
22  *		This is the state we leave the card in after _attach()
23  *
24  *  INIT	The card is being initialized
25  *
26  *  RUNNING	The card is running
27  *
28  *  FAULT	The card is hosed and being reset
29  *
30  *      ------------------
31  *     /                  \
32  *    v                    |
33  *  IDLE ---> INIT ---> RUNNING
34  *                       ^   |
35  *                       |   |
36  *                       |   v
37  *                       FAULT
38  *
39  */
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/conf.h>
44 #include <sys/kernel.h>
45 #include <sys/sysctl.h>
46 #include <sys/malloc.h>
47 #include <sys/bus.h>
48 #include <sys/mbuf.h>
49 #include <sys/queue.h>
50 #include <sys/rman.h>
51 
52 #include <machine/clock.h>
53 
54 #include <bus/pci/pcireg.h>
55 #include <bus/pci/pcivar.h>
56 
57 #include "pci_if.h"
58 
59 #include <netgraph/ng_message.h>
60 #include <netgraph/netgraph.h>
61 
62 #include <vm/vm.h>
63 #include <vm/pmap.h>
64 
65 static MALLOC_DEFINE(M_MUSYCC, "musycc", "MUSYCC related");
66 
67 static int maxlatency = 250;
68 SYSCTL_INT(_debug, OID_AUTO, musycc_maxlatency, CTLFLAG_RW, &maxlatency, 0,
69 	"The number of milliseconds a packet is allowed to spend in the output queue.  "
70 	"If the output queue is longer than this number of milliseconds when the packet "
71 	"arrives for output, the packet will be dropped."
72 );
73 
74 static int debug = 0;
75 SYSCTL_INT(_debug, OID_AUTO, musycc_debug, CTLFLAG_RW, &debug, 0, "");
76 
77 struct softc;
78 static void init_8370(struct softc *sc);
79 static	u_int32_t parse_ts(const char *s, int *nbit);
80 
81 /*
82  * Device driver initialization stuff
83  */
84 
85 static devclass_t musycc_devclass;
86 
87 /* XXX: Notice, these babies must be aligned to 2k boundaries [5-7] */
88 struct groupr {
89 	u_int32_t	thp[32];   /* Transmit Head Pointer [5-29]	     */
90 	u_int32_t	tmp[32];   /* Transmit Message Pointer [5-30]	     */
91 	u_int32_t	rhp[32];   /* Receive Head Pointer [5-29]	     */
92 	u_int32_t	rmp[32];   /* Receive Message Pointer [5-30]	     */
93 	u_int8_t	ttsm[128]; /* Time Slot Map [5-22]		     */
94 	u_int8_t	tscm[256]; /* Subchannel Map [5-24]		     */
95 	u_int32_t	tcct[32];  /* Channel Configuration [5-26]	     */
96 	u_int8_t	rtsm[128]; /* Time Slot Map [5-22] 		     */
97 	u_int8_t	rscm[256]; /* Subchannel Map [5-24]		     */
98 	u_int32_t	rcct[32];  /* Channel Configuration [5-26]	     */
99 	u_int32_t	__glcd;	   /* Global Configuration Descriptor [5-10] */
100 	u_int32_t	__iqp;	   /* Interrupt Queue Pointer [5-36]	     */
101 	u_int32_t	__iql;	   /* Interrupt Queue Length [5-36]	     */
102 	u_int32_t	grcd;	   /* Group Configuration Descriptor [5-16]  */
103 	u_int32_t	mpd;	   /* Memory Protection Descriptor [5-18]    */
104 	u_int32_t	mld;	   /* Message Length Descriptor [5-20]	     */
105 	u_int32_t	pcd;	   /* Port Configuration Descriptor [5-19]   */
106 	u_int32_t	__rbist;   /* Receive BIST status [5-4]		     */
107 	u_int32_t	__tbist;   /* Receive BIST status [5-4]		     */
108 };
109 
110 struct globalr {
111 	u_int32_t	gbp;	   /* Group Base Pointer */
112 	u_int32_t	dacbp;	   /* Dual Address Cycle Base Pointer */
113 	u_int32_t	srd;	   /* Service Request Descriptor */
114 	u_int32_t	isd;	   /* Interrupt Service Descriptor */
115 	u_int32_t	__thp[28];   /* Transmit Head Pointer [5-29]	     */
116 	u_int32_t	__tmp[32];   /* Transmit Message Pointer [5-30]	     */
117 	u_int32_t	__rhp[32];   /* Receive Head Pointer [5-29]	     */
118 	u_int32_t	__rmp[32];   /* Receive Message Pointer [5-30]	     */
119 	u_int8_t	ttsm[128]; /* Time Slot Map [5-22]		     */
120 	u_int8_t	tscm[256]; /* Subchannel Map [5-24]		     */
121 	u_int32_t	tcct[32];  /* Channel Configuration [5-26]	     */
122 	u_int8_t	rtsm[128]; /* Time Slot Map [5-22] 		     */
123 	u_int8_t	rscm[256]; /* Subchannel Map [5-24]		     */
124 	u_int32_t	rcct[32];  /* Channel Configuration [5-26]	     */
125 	u_int32_t	glcd;	   /* Global Configuration Descriptor [5-10] */
126 	u_int32_t	iqp;	   /* Interrupt Queue Pointer [5-36]	     */
127 	u_int32_t	iql;	   /* Interrupt Queue Length [5-36]	     */
128 	u_int32_t	grcd;	   /* Group Configuration Descriptor [5-16]  */
129 	u_int32_t	mpd;	   /* Memory Protection Descriptor [5-18]    */
130 	u_int32_t	mld;	   /* Message Length Descriptor [5-20]	     */
131 	u_int32_t	pcd;	   /* Port Configuration Descriptor [5-19]   */
132 	u_int32_t	rbist;   /* Receive BIST status [5-4]		     */
133 	u_int32_t	tbist;   /* Receive BIST status [5-4]		     */
134 };
135 
136 /*
137  * Because the chan_group must be 2k aligned we create this super
138  * structure so we can use the remaining 476 bytes for something useful
139  */
140 
141 struct mycg {
142 	struct groupr	cg;
143 };
144 
145 struct mdesc {
146 	u_int32_t	status;
147 	u_int32_t	data;
148 	u_int32_t	next;
149 	/* Software only */
150 	struct mbuf	*m;
151 	struct mdesc	*snext;
152 };
153 
154 #define NPORT	8
155 
156 #define NHDLC	32
157 
158 #define NIQD	32
159 
160 struct softc;
161 
162 struct schan {
163 	enum {DOWN, UP} state;
164 	struct softc	*sc;
165 	int		chan;
166 	u_int32_t	ts;
167 	char		hookname[8];
168 
169 	hook_p		hook;
170 
171 	u_long		rx_drop;	/* mbuf allocation failures */
172 	u_long		tx_limit;
173 	u_long		tx_pending;
174 	struct mdesc	*tx_next_md;	/* next MD */
175 	struct mdesc	*tx_last_md;	/* last MD */
176 	int		rx_last_md;	/* index to next MD */
177 	int		nmd;		/* count of MD's. */
178 
179 	time_t		last_recv;
180 	time_t		last_rdrop;
181 	time_t		last_rxerr;
182 	u_long		crc_error;
183 	u_long		dribble_error;
184 	u_long		long_error;
185 	u_long		abort_error;
186 	u_long		short_error;
187 	u_long		txn, rxn;
188 
189 	time_t		last_xmit;
190 	time_t		last_txerr;
191 
192 	time_t		last_txdrop;
193 	u_long		tx_drop;
194 
195 #if 0
196 
197 
198 	u_long		rx_error;
199 
200 	u_long		overflow_error;
201 
202 	int		last_error;
203 	int		prev_error;
204 
205 #endif
206 };
207 
208 enum framing {WHOKNOWS, E1, E1U, T1, T1U};
209 enum clocksource {EXT, INT};
210 
211 struct softc {
212 	enum framing framing;
213 	enum clocksource clocksource;
214 	int nhooks;
215 	u_int32_t last;
216 	struct csoftc *csc;
217 	u_int32_t *ds8370;
218 	void	*ds847x;
219 	struct globalr *reg;
220 	struct groupr *ram;
221 	struct mycg *mycg;
222 	struct mdesc *mdt[NHDLC];
223 	struct mdesc *mdr[NHDLC];
224 	node_p node;			/* NG node */
225 	char nodename[NG_NODESIZ];	/* NG nodename */
226 	struct schan *chan[NHDLC];
227 	u_long		cnt_ferr;
228 	u_long		cnt_cerr;
229 	u_long		cnt_lcv;
230 	u_long		cnt_febe;
231 	u_long		cnt_berr;
232 	u_long		cnt_fred;
233 	u_long		cnt_cofa;
234 	u_long		cnt_sef;
235 };
236 
237 /*
238  * SoftC for the entire card.
239  */
240 
241 struct csoftc {
242 	enum { C_IDLE, C_INIT, C_RUNNING, C_FAULT } state;
243 
244 	int	unit, bus, slot;
245 	LIST_ENTRY(csoftc) list;
246 
247 	device_t f[2];
248 	struct resource *irq[2];
249 	void *intrhand[2];
250 	vm_offset_t physbase[2];
251 	u_char *virbase[2];
252 
253 	u_int creg, *cregp;
254 	int nchan;
255 	struct softc serial[NPORT];
256 
257 	struct globalr *reg;
258 	struct globalr *ram;
259 	u_int32_t iqd[NIQD];
260 };
261 
262 /*
263  *
264  */
265 
266 #define NG_NODETYPE	"lmc1504"
267 
268 static  ng_constructor_t musycc_constructor;
269 static  ng_rcvmsg_t musycc_rcvmsg;
270 static  ng_shutdown_t musycc_shutdown;
271 static  ng_newhook_t musycc_newhook;
272 static  ng_connect_t musycc_connect;
273 static  ng_rcvdata_t musycc_rcvdata;
274 static  ng_disconnect_t musycc_disconnect;
275 
276 static struct ng_type ngtypestruct = {
277 	NG_VERSION,
278 	NG_NODETYPE,
279 	NULL,
280 	musycc_constructor,
281 	musycc_rcvmsg,
282 	musycc_shutdown,
283 	musycc_newhook,
284 	NULL,
285 	musycc_connect,
286 	musycc_rcvdata,
287 	musycc_rcvdata,
288 	musycc_disconnect,
289 	NULL
290 };
291 
292 /*
293  *
294  */
295 
296 static u_int32_t
297 parse_ts(const char *s, int *nbit)
298 {
299 	unsigned r;
300 	int i, j;
301 	char *p;
302 
303 	r = 0;
304 	j = -1;
305 	*nbit = 0;
306 	while(*s) {
307 		i = strtol(s, &p, 0);
308 		if (i < 0 || i > 31)
309 			return (0);
310 		while (j != -1 && j < i) {
311 			r |= 1 << j++;
312 			(*nbit)++;
313 		}
314 		j = -1;
315 		r |= 1 << i;
316 		(*nbit)++;
317 		if (*p == ',') {
318 			s = p + 1;
319 			continue;
320 		} else if (*p == '-') {
321 			j = i + 1;
322 			s = p + 1;
323 			continue;
324 		} else if (!*p) {
325 			break;
326 		} else {
327 			return (0);
328 		}
329 	}
330 	return (r);
331 }
332 
333 /*
334  *
335  */
336 
337 
338 static LIST_HEAD(, csoftc) sc_list = LIST_HEAD_INITIALIZER(&sc_list);
339 
340 #if 0
341 static void
342 poke_847x(void *dummy)
343 {
344 	static int count;
345 	int i;
346 	struct csoftc *csc;
347 
348 	timeout(poke_847x, NULL, 1);
349 	LIST_FOREACH(csc, &sc_list, list)  {
350 		count++;
351 		i = (csc->creg >> 24 & 0xf);
352 		csc->creg &= ~0xf000000;
353 		i++;
354 		csc->creg |= (i & 0xf) << 24;
355 		*csc->cregp = csc->creg;
356 #if 0
357 		for (i = 0; i < sc->nchan; i++) {
358 			if (sc->serial[i].last == 0xffffffff) {
359 				sc->serial[i].reg->srd = 0;
360 				sc->serial[i].last = 0;
361 				return;
362 			}
363 		}
364 #endif
365 	}
366 }
367 #endif
368 
369 static void
370 init_card(struct csoftc *csc)
371 {
372 
373 	kprintf("init_card(%p)\n", csc);
374 
375 	csc->state = C_INIT;
376 	csc->reg->srd = 0x100;
377 	tsleep(csc, PCATCH, "icard", hz / 10);
378 	csc->reg->gbp = vtophys(csc->ram);
379 	csc->ram->glcd = 0x3f30;	/* XXX: designer magic */
380 
381 	csc->ram->iqp = vtophys(csc->iqd);
382 	csc->ram->iql = NIQD - 1;
383 	csc->ram->dacbp = 0;		/* 32bit only */
384 
385 	csc->reg->srd = csc->serial[0].last = 0x400;
386 	tsleep(&csc->serial[0].last, PCATCH, "con1", hz);
387 /*
388 	timeout(poke_847x, NULL, 1);
389 */
390 #if 0
391 	DELAY(20000);
392 #endif
393 	csc->state = C_RUNNING;
394 }
395 
396 static void
397 init_ctrl(struct softc *sc)
398 {
399 	int i;
400 
401 	kprintf("init_ctrl(%p) [%s] [%08x]\n", sc, sc->nodename, sc->csc->reg->glcd);
402 	init_8370(sc);
403 	tsleep(sc, PCATCH, "ds8370", hz);
404 	kprintf("%s: glcd: [%08x]\n", sc->nodename, sc->csc->reg->glcd);
405 	sc->reg->gbp = vtophys(sc->ram);
406 	sc->ram->grcd =  0x00000001;	/* RXENBL */
407 	sc->ram->grcd |= 0x00000002;	/* TXENBL */
408 	sc->ram->grcd |= 0x00000004;	/* SUBDSBL */
409 	if (sc->framing == E1 || sc->framing == T1)
410 		sc->ram->grcd |= 0x00000008;	/* OOFABT */
411 	else
412 		sc->ram->grcd |= 0x00000000;	/* !OOFABT */
413 
414 	sc->ram->grcd |= 0x00000020;	/* MSKCOFA */
415 
416 	sc->ram->grcd |= 0x00000440;	/* POLLTH=1 */
417 
418 	sc->ram->mpd = 0;		/* Memory Protection NI [5-18] */
419 
420 	sc->ram->pcd =  0x0000001;	/* PORTMD=1 (E1/32ts) */
421 	sc->ram->pcd |= 1 << 5;		/* TSYNC_EDGE */
422 	sc->ram->pcd |= 1 << 9;		/* TRITX */
423 
424 	/* Message length descriptor */
425 	/* XXX: MTU */
426 	sc->ram->mld = 1600;
427 	sc->ram->mld |= (1600 << 16);
428 
429 	for (i = 0; i < NHDLC; i++) {
430 		sc->ram->ttsm[i] = 0;
431 		sc->ram->rtsm[i] = 0;
432 	}
433 	sc->reg->srd = sc->last = 0x500;
434 	tsleep(&sc->last, PCATCH, "con1", hz);
435 	sc->reg->srd = sc->last = 0x520;
436 	tsleep(&sc->last, PCATCH, "con1", hz);
437 }
438 
439 /*
440  *
441  */
442 
443 static void
444 status_chans(struct softc *sc, char *s)
445 {
446 	int i;
447 	struct schan *scp;
448 
449 	s += strlen(s);
450 	for (i = 0; i < NHDLC; i++) {
451 		scp = sc->chan[i];
452 		if (scp == NULL)
453 			continue;
454 		ksprintf(s + strlen(s), "c%2d:", i);
455 		ksprintf(s + strlen(s), " ts %08x", scp->ts);
456 		ksprintf(s + strlen(s), " RX %lus/%lus",
457 		    time_uptime - scp->last_recv, time_uptime - scp->last_rxerr);
458 		ksprintf(s + strlen(s), " TX %lus/%lus/%lus",
459 		    time_uptime - scp->last_xmit,
460 		    time_uptime - scp->last_txerr,
461 		    time_uptime - scp->last_txdrop);
462 		ksprintf(s + strlen(s), " TXdrop %lu Pend %lu",
463 		    scp->tx_drop,
464 		    scp->tx_pending);
465 		ksprintf(s + strlen(s), " CRC %lu Dribble %lu Long %lu Short %lu Abort %lu",
466 		    scp->crc_error,
467 		    scp->dribble_error,
468 		    scp->long_error,
469 		    scp->short_error,
470 		    scp->abort_error);
471 		ksprintf(s + strlen(s), "\n TX: %lu RX: %lu\n",
472 		    scp->txn, scp->rxn);
473 	}
474 }
475 
476 
477 /*
478  *
479  */
480 
481 static void
482 status_8370(struct softc *sc, char *s)
483 {
484 	u_int32_t *p = sc->ds8370;
485 
486 	s += strlen(s);
487 	ksprintf(s, "Framer: "); s += strlen(s);
488 	switch (sc->framing) {
489 		case WHOKNOWS: ksprintf(s, "(unconfigured)\n"); break;
490 		case E1: ksprintf(s, "(e1)\n"); break;
491 		case E1U: ksprintf(s, "(e1u)\n"); break;
492 		case T1: ksprintf(s, "(t1)\n"); break;
493 		case T1U: ksprintf(s, "(t1u)\n"); break;
494 		default: ksprintf(s, "(mode %d XXX?)\n", sc->framing); break;
495 	}
496 	s += strlen(s);
497 	ksprintf(s, "    Red alarms:"); s += strlen(s);
498 	if (p[0x47] & 0x08) { ksprintf(s, " ALOS"); s += strlen(s); }
499 	if (p[0x47] & 0x04) { ksprintf(s, " LOS"); s += strlen(s); }
500 	if (sc->framing == E1 || sc->framing == T1) {
501 		if (p[0x47] & 0x02) { ksprintf(s, " LOF"); s += strlen(s); }
502 	}
503 	ksprintf(s, "\n    Yellow alarms:"); s += strlen(s);
504 	if (p[0x47] & 0x80) { ksprintf(s, " RMYEL"); s += strlen(s); }
505 	if (p[0x47] & 0x40) { ksprintf(s, " RYEL"); s += strlen(s); }
506 	ksprintf(s, "\n    Blue alarms:"); s += strlen(s);
507 	if (p[0x47] & 0x10) { ksprintf(s, " AIS"); s += strlen(s); }
508 	ksprintf(s, "\n"); s += strlen(s);
509 	ksprintf(s, "\n    Various alarms:"); s += strlen(s);
510 	if (p[0x48] & 0x10) { ksprintf(s, " TSHORT"); s += strlen(s); }
511 	ksprintf(s, "\n    Counters:"); s += strlen(s);
512 	if (sc->framing == E1) {
513 		ksprintf(s, " FERR=%lu", sc->cnt_ferr); s += strlen(s);
514 	}
515 	ksprintf(s, " CERR=%lu", sc->cnt_cerr); s += strlen(s);
516 	ksprintf(s, " LCV=%lu",  sc->cnt_lcv); s += strlen(s);
517 	ksprintf(s, " FEBE=%lu", sc->cnt_febe); s += strlen(s);
518 	ksprintf(s, " BERR=%lu", sc->cnt_berr); s += strlen(s);
519 	ksprintf(s, " FRED=%lu", sc->cnt_fred); s += strlen(s);
520 	ksprintf(s, " COFA=%lu", sc->cnt_cofa); s += strlen(s);
521 	ksprintf(s, " SEF=%lu", sc->cnt_sef); s += strlen(s);
522 	ksprintf(s, "\n"); s += strlen(s);
523 }
524 
525 static void
526 dump_8370(struct softc *sc, char *s, int offset)
527 {
528 	int i, j;
529 	u_int32_t *p = sc->ds8370;
530 
531 	s += strlen(s);
532 	for (i = 0; i < 0x100; i += 16) {
533 		ksprintf(s, "%03x: ", i + offset);
534 		s += strlen(s);
535 		for (j = 0; j < 0x10; j ++) {
536 			ksprintf(s, " %02x", p[i + j + offset] & 0xff);
537 			s += strlen(s);
538 		}
539 		ksprintf(s, "\n");
540 		s += strlen(s);
541 	}
542 }
543 
544 static void
545 init_8370(struct softc *sc)
546 {
547 	int i;
548 	u_int32_t *p = sc->ds8370;
549 
550 	p[0x001] = 0x80; /* CR0 - Reset */
551 	DELAY(20);
552 	p[0x001] = 0x00; /* CR0 - E1, RFRAME: FAS only */
553 	DELAY(20);
554 	if (sc->clocksource == INT)
555 		p[0x002] = 0x40; /* JAT_CR - XXX */
556 	else
557 		p[0x002] = 0x20; /* JAT_CR - XXX */
558 	p[0x00D] = 0x01; /* IER6 - ONESEC */
559 	p[0x014] = 0x00; /* LOOP - */
560 	p[0x015] = 0x00; /* DL3_TS - */
561 	p[0x016] = 0x00; /* DL3_BIT - */
562 	p[0x017] = 0x00; /* DL3_BIT - */
563 	p[0x018] = 0xFF; /* PIO - XXX */
564 	p[0x019] = 0x3c; /* POE - CLADO_OE|RCKO_OE */
565 	if (sc->clocksource == INT)
566 		p[0x01A] = 0x37; /* CMUX - RSBCKI(RSBCKI), TSBCKI(CLADO), CLADO(RCKO), TCKI(CLADO) */
567 	else
568 		p[0x01A] = 0x37; /* CMUX - RSBCKI(RSBCKI), TSBCKI(RSBCKI), CLADO(RCKO), TCKI(RCKO) */
569 
570 	/* I.431/G.775 */
571 	p[0x020] = 0x41; /* LIU_CR - SQUELCH */
572 	p[0x022] = 0xb1; /* RLIU_CR - */
573 	p[0x024] = 0x1d; /* VGA_MAX - */
574 	p[0x027] = 0xba; /* DSLICE - */
575 	p[0x028] = 0xda; /* EQ_OUT - */
576 	p[0x02a] = 0xa6; /* PRE_EQ - */
577 
578 	if (sc->framing == E1U || sc->framing == T1U)
579 		p[0x040] = 0x49; /* RCRO - XXX */
580 	else
581 		p[0x040] = 0x09; /* RCRO - XXX */
582 
583 	p[0x041] = 0x00; /* RPATT - XXX */
584 	p[0x045] = 0x00; /* RALM - XXX */
585 	p[0x046] = 0x05; /* LATCH - LATCH_CNT|LATCH_ALM */
586 
587 	p[0x068] = 0x4c; /* TLIU_CR - TERM|Pulse=6 */
588 	p[0x070] = 0x04; /* TCR0 - TFRAME=4 */
589 
590 	if (sc->framing == E1U || sc->framing == T1U)
591 		p[0x071] = 0x41; /* TCR1 - TZCS */
592 	else
593 		p[0x071] = 0x51; /* TCR1 - TZCS */
594 
595 	if (sc->framing == E1U || sc->framing == T1U)
596 		p[0x072] = 0x00;
597 	else
598 		p[0x072] = 0x1b; /* TCR1 - INS_YEL|INS_MF|INS_CRC|INS_FBIT */
599 
600 	p[0x073] = 0x00; /* TERROR */
601 	p[0x074] = 0x00; /* TMAN */
602 
603 	if (sc->framing == E1U || sc->framing == T1U)
604 		p[0x075] = 0x0; /* TALM */
605 	else
606 		p[0x075] = 0x10; /* TALM - AUTO_YEL */
607 
608 	p[0x076] = 0x00; /* TPATT */
609 	p[0x077] = 0x00; /* TLP */
610 
611 	p[0x090] = 0x05; /* CLAD_CR - XXX */
612 	p[0x091] = 0x01; /* CSEL - 2048kHz */
613 
614 	if (sc->framing == E1U || sc->framing == T1U) {
615 		p[0x0a0] = 0x00;
616 		p[0x0a6] = 0x00;
617 		p[0x0b1] = 0x00;
618 	}
619 
620 	p[0x0d0] = 0x46; /* SBI_CR - SBI=6 */
621 	p[0x0d1] = 0x70; /* RSB_CR - XXX */
622 	p[0x0d2] = 0x00; /* RSYNC_BIT - 0 */
623 	p[0x0d3] = 0x00; /* RSYNC_TS - 0 */
624 	p[0x0d4] = 0x30; /* TSB_CR - XXX */
625 	p[0x0d5] = 0x00; /* TSYNC_BIT - 0 */
626 	p[0x0d6] = 0x00; /* TSYNC_TS - 0 */
627 	if (sc->framing == E1U || sc->framing == T1U)
628 		p[0x0d7] = 0x05; /* RSIG_CR - 0  | FRZ_OFF*/
629 	else
630 		p[0x0d7] = 0x01; /* RSIG_CR - 0 */
631 	p[0x0d8] = 0x00; /* RSIG_FRM - 0 */
632 	for (i = 0; i < 32; i ++) {
633 		p[0x0e0 + i] = 0x0d; /* SBC$i - RINDO|TINDO|ASSIGN */
634 		p[0x100 + i] = 0x00; /* TPC$i - 0 */
635 		p[0x180 + i] = 0x00; /* RPC$i - 0 */
636 	}
637 }
638 
639 /*
640  * Interrupts
641  */
642 
643 static void
644 musycc_intr0_tx_eom(struct softc *sc, int ch)
645 {
646 	struct schan *sch;
647 	struct mdesc *md;
648 
649 	sch = sc->chan[ch];
650 	if (sch == NULL || sch->state != UP) {
651 		/* XXX: this should not happen once the driver is done */
652 		kprintf("Xmit packet on uninitialized channel %d\n", ch);
653 	}
654 	if (sc->mdt[ch] == NULL)
655 		return; 	/* XXX: can this happen ? */
656 	for (;;) {
657 		md = sch->tx_last_md;
658 		if (md->status == 0)
659 			break;
660 		if (md->status & 0x80000000)
661 			break;		/* Not our mdesc, done */
662 		sch->tx_last_md = md->snext;
663 		md->data = 0;
664 		if (md->m != NULL) {
665 			sch->tx_pending -= md->m->m_pkthdr.len;
666 			m_freem(md->m);
667 			md->m = NULL;
668 		}
669 		md->status = 0;
670 	}
671 }
672 
673 /*
674  * Receive interrupt on controller *sc, channel ch
675  *
676  * We perambulate the Rx descriptor ring until we hit
677  * a mdesc which isn't ours to take.
678  */
679 
680 static void
681 musycc_intr0_rx_eom(struct softc *sc, int ch)
682 {
683 	u_int32_t status, error;
684 	struct schan *sch;
685 	struct mbuf *m, *m2;
686 	struct mdesc *md;
687 
688 	sch = sc->chan[ch];
689 	if (sch == NULL || sch->state != UP) {
690 		/* XXX: this should not happen once the driver is done */
691 		kprintf("Received packet on uninitialized channel %d\n", ch);
692 		return;
693 	}
694 	if (sc->mdr[ch] == NULL)
695 		return; 	/* XXX: can this happen ? */
696 	for (;;) {
697 		md = &sc->mdr[ch][sch->rx_last_md];
698 		status = md->status;
699 		if (!(status & 0x80000000))
700 			break;		/* Not our mdesc, done */
701 		m = md->m;
702 		m->m_len = m->m_pkthdr.len = status & 0x3fff;
703 		error = (status >> 16) & 0xf;
704 		if (error == 0) {
705 			MGETHDR(m2, M_NOWAIT, MT_DATA);
706 			if (m2 != NULL) {
707 				MCLGET(m2, M_NOWAIT);
708 				if((m2->m_flags & M_EXT) != 0) {
709 					/* Substitute the mbuf+cluster. */
710 					md->m = m2;
711 					md->data = vtophys(m2->m_data);
712 					/* Pass the received mbuf upwards. */
713 					sch->last_recv = time_uptime;
714 					ng_queue_data(sch->hook, m, NULL);
715 				} else {
716 					/*
717 					 * We didn't get a mbuf cluster,
718 					 * drop received packet, free the
719 					 * mbuf we cannot use and recycle
720 					 * the mbuf+cluster we already had.
721 					 */
722 					m_freem(m2);
723 					sch->last_rdrop = time_uptime;
724 					sch->rx_drop++;
725 				}
726 			} else {
727 				/*
728 				 * We didn't get a mbuf, drop received packet
729 				 * and recycle the "old" mbuf+cluster.
730 				 */
731 				sch->last_rdrop = time_uptime;
732 				sch->rx_drop++;
733 			}
734 		} else if (error == 9) {
735 			sch->last_rxerr = time_uptime;
736 			sch->crc_error++;
737 		} else if (error == 10) {
738 			sch->last_rxerr = time_uptime;
739 			sch->dribble_error++;
740 		} else if (error == 11) {
741 			sch->last_rxerr = time_uptime;
742 			sch->abort_error++;
743 		} else if (error == 12) {
744 			sch->last_rxerr = time_uptime;
745 			sch->long_error++;
746 		} else {
747 			sch->last_rxerr = time_uptime;
748 			/* Receive error, print some useful info */
749 			kprintf("%s %s: RX 0x%08x ", sch->sc->nodename,
750 			    sch->hookname, status);
751 			/* Don't print a lot, just the begining will do */
752 			if (m->m_len > 16)
753 				m->m_len = m->m_pkthdr.len = 16;
754 			m_print(m);
755 			kprintf("\n");
756 		}
757 		md->status = 1600;	/* XXX: MTU */
758 		/* Check next mdesc in the ring */
759 		if (++sch->rx_last_md >= sch->nmd)
760 			sch->rx_last_md = 0;
761 	}
762 }
763 
764 static void
765 musycc_intr0(void *arg)
766 {
767 	int i, j, g, ch, ev, er;
768 	struct csoftc *csc;
769 	u_int32_t u, u1, n, c;
770 	struct softc *sc;
771 
772 	csc = arg;
773 
774 	for (;;) {
775 		u = csc->reg->isd;
776 		c = u & 0x7fff;
777 		n = u >> 16;
778 		if (c == 0)
779 			return;
780 		if (debug & 1)
781 			kprintf("%s: IRQ: %08x n = %d c = %d\n", csc->serial[0].nodename, u, n, c);
782 		for (i = 0; i < c; i++) {
783 			j = (n + i) % NIQD;
784 			u1 = csc->iqd[j];
785 			g = (u1 >> 29) & 0x3;
786 			g |= (u1 >> (14-2)) & 0x4;
787 			ch = (u1 >> 24) & 0x1f;
788 			ev = (u1 >> 20) & 0xf;
789 			er = (u1 >> 16) & 0xf;
790 			sc = &csc->serial[g];
791 			if ((debug & 2) || er) {
792 				kprintf("%08x %d", u1, g);
793 				kprintf("/%s", u1 & 0x80000000 ? "T" : "R");
794 				kprintf("/%02d", ch);
795 				kprintf(" %02d", ev);
796 				kprintf(":%02d", er);
797 				kprintf("\n");
798 			}
799 			switch (ev) {
800 			case 1: /* SACK		Service Request Acknowledge	    */
801 #if 0
802 				kprintf("%s: SACK: %08x group=%d", sc->nodename, csc->iqd[j], g);
803 				kprintf("/%s", csc->iqd[j] & 0x80000000 ? "T" : "R");
804 				kprintf(" cmd %08x (%08x) \n", sc->last, sc->reg->srd);
805 #endif
806 				sc->last = 0xffffffff;
807 				wakeup(&sc->last);
808 				break;
809 			case 5: /* CHABT	Change To Abort Code (0x7e -> 0xff) */
810 			case 6: /* CHIC		Change To Idle Code (0xff -> 0x7e)  */
811 				break;
812 			case 3: /* EOM		End Of Message			    */
813 				if (csc->iqd[j] & 0x80000000)
814 					musycc_intr0_tx_eom(sc, ch);
815 				else
816 					musycc_intr0_rx_eom(sc, ch);
817 				break;
818 			case 0:
819 				if (er == 13) {	/* SHT */
820 					sc->chan[ch]->last_rxerr = time_uptime;
821 					sc->chan[ch]->short_error++;
822 					break;
823 				}
824 			default:
825 				musycc_intr0_tx_eom(sc, ch);
826 				musycc_intr0_rx_eom(sc, ch);
827 #if 1
828 				kprintf("huh ? %08x %d", u1, g);
829 				kprintf("/%s", u1 & 0x80000000 ? "T" : "R");
830 				kprintf("/%02d", ch);
831 				kprintf(" %02d", ev);
832 				kprintf(":%02d", er);
833 				kprintf("\n");
834 #endif
835 			}
836 			csc->iqd[j] = 0xffffffff;
837 			j++;
838 			j %= NIQD;
839 			csc->reg->isd = j << 16;
840 		}
841 	}
842 }
843 
844 static void
845 musycc_intr1(void *arg)
846 {
847 	int i;
848 	struct csoftc *csc;
849 	struct softc *sc;
850 	u_int32_t *u;
851 	u_int8_t irr;
852 
853 	csc = arg;
854 
855 	for (i = 0; i < csc->nchan; i++) {
856 		sc = &csc->serial[i];
857 		u = sc->ds8370;
858 		irr = u[3];
859 		if (irr == 0)
860 			continue;
861 		if (u[0x5] & 1) { /* ONESEC */
862 			sc->cnt_ferr +=  u[0x50] & 0xff;
863 			sc->cnt_ferr += (u[0x51] & 0xff) << 8;
864 			sc->cnt_cerr +=  u[0x52] & 0xff;
865 			sc->cnt_cerr += (u[0x53] & 0xff) << 8;
866 			sc->cnt_lcv  +=  u[0x54] & 0xff;
867 			sc->cnt_lcv  += (u[0x55] & 0xff) << 8;
868 			sc->cnt_febe +=  u[0x56] & 0xff;
869 			sc->cnt_febe += (u[0x57] & 0xff) << 8;
870 			sc->cnt_berr +=  u[0x58] & 0xff;
871 			sc->cnt_berr += (u[0x59] & 0xff) << 8;
872 			sc->cnt_fred += (u[0x5a] & 0xf0) >> 4;
873 			sc->cnt_cofa += (u[0x5a] & 0x0c) >> 2;
874 			sc->cnt_sef  +=  u[0x5a] & 0x03;
875 		}
876 		if (debug & 4) {
877 			int j;
878 
879 			kprintf("musycc_intr1:%d %02x", i, irr);
880 			for (j = 4; j < 0x14; j++)
881 				kprintf(" %02x", u[j] & 0xff);
882 			kprintf("\n");
883 		}
884 	}
885 }
886 
887 /*
888  * NetGraph Stuff
889  */
890 
891 static int
892 musycc_constructor(node_p *nodep)
893 {
894 
895 	return (EINVAL);
896 }
897 
898 static int
899 musycc_shutdown(node_p nodep)
900 {
901 
902 	return (EINVAL);
903 }
904 
905 static void
906 musycc_config(node_p node, char *set, char *ret)
907 {
908 	struct softc *sc;
909 	struct csoftc *csc;
910 	enum framing wframing;
911 	int i;
912 
913 	sc = node->private;
914 	csc = sc->csc;
915 	if (csc->state == C_IDLE)
916 		init_card(csc);
917 	while (csc->state != C_RUNNING)
918 		tsleep(&csc->state, PCATCH, "crun", hz/10);
919 	if (set != NULL) {
920 		if (!strncmp(set, "line ", 5)) {
921 			wframing = sc->framing;
922 			if (!strcmp(set, "line e1")) {
923 				wframing = E1;
924 			} else if (!strcmp(set, "line e1u")) {
925 				wframing = E1U;
926 			} else {
927 				strcat(ret, "ENOGROK\n");
928 				return;
929 			}
930 			if (wframing == sc->framing)
931 				return;
932 			if (sc->nhooks > 0) {
933 				ksprintf(ret, "Cannot change line when %d hooks open\n", sc->nhooks);
934 				return;
935 			}
936 			sc->framing = wframing;
937 			init_ctrl(sc);
938 			return;
939 		}
940 		if (!strcmp(set, "clock source internal")) {
941 			sc->clocksource = INT;
942 			init_ctrl(sc);
943 		} else if (!strcmp(set, "clock source line")) {
944 			sc->clocksource = EXT;
945 			init_ctrl(sc);
946 		} else if (!strcmp(set, "show 8370 0")) {
947 			dump_8370(sc, ret, 0);
948 		} else if (!strcmp(set, "show 8370 1")) {
949 			dump_8370(sc, ret, 0x100);
950 		} else if (!strncmp(set, "creg", 4)) {
951 			i = strtol(set + 5, 0, 0);
952 			kprintf("set creg %d\n", i);
953 			csc->creg = 0xfe | (i << 24);
954 			*csc->cregp = csc->creg;
955 /*
956 		} else if (!strcmp(set, "reset")) {
957 			reset_group(sc, ret);
958 		} else if (!strcmp(set, "reset all")) {
959 			reset_card(sc, ret);
960 */
961 		} else {
962 			kprintf("%s CONFIG SET [%s]\n", sc->nodename, set);
963 			goto barf;
964 		}
965 
966 		return;
967 	}
968 	if (sc->framing == E1)
969 		strcat(ret, "line e1\n");
970 	else if (sc->framing == E1U)
971 		strcat(ret, "line e1u\n");
972 	if (sc->clocksource == INT)
973 		strcat(ret, "clock source internal\n");
974 	else
975 		strcat(ret, "clock source line\n");
976 	return;
977 barf:
978 	strcpy(ret, "Syntax Error\n");
979 	strcat(ret, "\tline {e1|e1u}\n");
980 	strcat(ret, "\tshow 8370 {0|1}\n");
981 	return;
982 }
983 
984 /*
985  * Handle status and config enquiries.
986  * Respond with a synchronous response.
987  */
988 static int
989 musycc_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp)
990 {
991 	struct softc *sc;
992 	char *s, *r;
993 
994 	sc = node->private;
995 
996 	if (msg->header.typecookie != NGM_GENERIC_COOKIE)
997 		goto out;
998 
999 	if (msg->header.cmd == NGM_TEXT_STATUS) {
1000 		NG_MKRESPONSE(*resp, msg,
1001 		    sizeof(struct ng_mesg) + NG_TEXTRESPONSE, M_NOWAIT);
1002 		if (*resp == NULL) {
1003 			kfree(msg, M_NETGRAPH);
1004 			return (ENOMEM);
1005 		}
1006 		s = (char *)(*resp)->data;
1007 		status_8370(sc, s);
1008 		status_chans(sc,s);
1009 		(*resp)->header.arglen = strlen(s) + 1;
1010 		kfree(msg, M_NETGRAPH);
1011 		return (0);
1012 	} else if (msg->header.cmd == NGM_TEXT_CONFIG) {
1013 		if (msg->header.arglen) {
1014 			s = (char *)msg->data;
1015 		} else {
1016 			s = NULL;
1017 		}
1018 
1019 		NG_MKRESPONSE(*resp, msg,
1020 		    sizeof(struct ng_mesg) + NG_TEXTRESPONSE, M_NOWAIT);
1021 		if (*resp == NULL) {
1022 			kfree(msg, M_NETGRAPH);
1023 			return (ENOMEM);
1024 		}
1025 		r = (char *)(*resp)->data;
1026 		*r = '\0';
1027 		musycc_config(node, s, r);
1028 		(*resp)->header.arglen = strlen(r) + 1;
1029 		kfree(msg, M_NETGRAPH);
1030 		return (0);
1031 	}
1032 
1033 out:
1034 	if (resp)
1035 		*resp = NULL;
1036 	kfree(msg, M_NETGRAPH);
1037 	return (EINVAL);
1038 }
1039 
1040 static int
1041 musycc_newhook(node_p node, hook_p hook, const char *name)
1042 {
1043 	struct softc *sc;
1044 	struct csoftc *csc;
1045 	struct schan *sch;
1046 	u_int32_t ts, chan;
1047 	int nbit;
1048 
1049 	sc = node->private;
1050 	csc = sc->csc;
1051 
1052 	while (csc->state != C_RUNNING)
1053 		tsleep(&csc->state, PCATCH, "crun", hz/10);
1054 
1055 	if (sc->framing == WHOKNOWS)
1056 		return (EINVAL);
1057 
1058 	if (name[0] != 't' || name[1] != 's')
1059 		return (EINVAL);
1060 	ts = parse_ts(name + 2, &nbit);
1061 	if (ts == 0)
1062 		return (EINVAL);
1063 	chan = ffs(ts) - 1;
1064 
1065 	if (sc->framing == E1U && nbit == 32)
1066 		;
1067 	else if (sc->framing == T1U && nbit == 24)
1068 		;
1069 	else if (ts & 1)
1070 		return (EINVAL);
1071 
1072 	if (sc->chan[chan] == NULL) {
1073 		sch = kmalloc(sizeof(*sch), M_MUSYCC, M_WAITOK | M_ZERO);
1074 		sch->sc = sc;
1075 		sch->state = DOWN;
1076 		sch->chan = chan;
1077 		ksprintf(sch->hookname, name);	/* XXX overflow ? */
1078 		sc->chan[chan] = sch;
1079 	} else if (sc->chan[chan]->state == UP) {
1080 		return (EBUSY);
1081 	}
1082 	sc->nhooks++;
1083 	sch = sc->chan[chan];
1084 	sch->ts = ts;
1085 	sch->hook = hook;
1086 	sch->tx_limit = nbit * 8;
1087 	hook->private = sch;
1088 	return(0);
1089 }
1090 
1091 static int
1092 musycc_rcvdata(hook_p hook, struct mbuf *m, meta_p meta)
1093 {
1094 
1095 	struct softc *sc;
1096 	struct csoftc *csc;
1097 	struct schan *sch;
1098 	struct mdesc *md, *md0;
1099 	u_int32_t ch, u, u0, len;
1100 	struct mbuf *m2;
1101 
1102 	sch = hook->private;
1103 	sc = sch->sc;
1104 	csc = sc->csc;
1105 	ch = sch->chan;
1106 
1107 	if (csc->state != C_RUNNING) {
1108 		kprintf("csc->state = %d\n", csc->state);
1109 		NG_FREE_DATA(m, meta);
1110 		return (0);
1111 	}
1112 
1113 	NG_FREE_META(meta);
1114 	meta = NULL;
1115 
1116 	if (sch->state != UP) {
1117 		kprintf("sch->state = %d\n", sch->state);
1118 		NG_FREE_DATA(m, meta);
1119 		return (0);
1120 	}
1121 	if (sch->tx_pending + m->m_pkthdr.len > sch->tx_limit * maxlatency) {
1122 		sch->tx_drop++;
1123 		sch->last_txdrop = time_uptime;
1124 		NG_FREE_DATA(m, meta);
1125 		return (0);
1126 	}
1127 
1128 	/* find out if we have enough txmd's */
1129 	m2 = m;
1130 	md = sch->tx_next_md;
1131 	for (len = m2->m_pkthdr.len; len; m2 = m2->m_next) {
1132 		if (m2->m_len == 0)
1133 			continue;
1134 		if (md->status != 0) {
1135 			sch->tx_drop++;
1136 			sch->last_txdrop = time_uptime;
1137 			NG_FREE_DATA(m, meta);
1138 			return (0);
1139 		}
1140 		len -= m2->m_len;
1141 		md = md->snext;
1142 	}
1143 
1144 	m2 = m;
1145 	md = md0 = sch->tx_next_md;
1146 	u0 = 0;
1147 	for (len = m->m_pkthdr.len; len > 0; m = m->m_next) {
1148 		if (m->m_len == 0)
1149 			continue;
1150 		if (md->status != 0) {
1151 			kprintf("Out of tx md(2)\n");
1152 			sch->last_txerr = time_uptime;
1153 			sch->tx_drop++;
1154 			sch->last_txdrop = time_uptime;
1155 			NG_FREE_DATA(m, meta);
1156 			break;
1157 		}
1158 
1159 		md->data = vtophys(m->m_data);
1160 		if (md == md0)
1161 			u = 0x00000000;	/* OWNER = CPU */
1162 		else
1163 			u = 0x80000000;	/* OWNER = MUSYCC */
1164 		u |= m->m_len;
1165 		len -= m->m_len;
1166 		if (len > 0) {
1167 			md->m = NULL;
1168 			if (md == md0)
1169 				u0 = u;
1170 			else
1171 				md->status = u;
1172 			md = md->snext;
1173 			continue;
1174 		}
1175 		u |= 0x20000000;	/* EOM */
1176 		md->m = m2;
1177 		sch->tx_pending += m2->m_pkthdr.len;
1178 		if (md == md0) {
1179 			u |= 0x80000000;	/* OWNER = MUSYCC */
1180 			md->status = u;
1181 		} else {
1182 			md->status = u;
1183 			md0->status = u0 | 0x80000000; /* OWNER = MUSYCC */
1184 		}
1185 		sch->last_xmit = time_uptime;
1186 		sch->tx_next_md = md->snext;
1187 	}
1188 	sch->txn++;
1189 	return (0);
1190 }
1191 
1192 static int
1193 musycc_connect(hook_p hook)
1194 {
1195 	struct softc *sc;
1196 	struct csoftc *csc;
1197 	struct schan *sch;
1198 	int nts, nbuf, i, nmd, ch;
1199 	struct mbuf *m;
1200 
1201 	sch = hook->private;
1202 	sc = sch->sc;
1203 	csc = sc->csc;
1204 	ch = sch->chan;
1205 
1206 	while (csc->state != C_RUNNING)
1207 		tsleep(&csc->state, PCATCH, "crun", hz/10);
1208 
1209 	if (sch->state == UP)
1210 		return (0);
1211 	sch->state = UP;
1212 
1213 	/* Setup the Time Slot Map */
1214 	nts = 0;
1215 	for (i = ch; i < 32; i++) {
1216 		if (sch->ts & (1 << i)) {
1217 			sc->ram->rtsm[i] = ch | (4 << 5);
1218 			sc->ram->ttsm[i] = ch | (4 << 5);
1219 			nts++;
1220 		}
1221 	}
1222 
1223 	/*
1224 	 * Find the length of the first run of timeslots.
1225 	 * XXX: find the longest instead.
1226 	 */
1227 	nbuf = 0;
1228 	for (i = ch; i < 32; i++) {
1229 		if (sch->ts & (1 << i))
1230 			nbuf++;
1231 		else
1232 			break;
1233 	}
1234 
1235 	kprintf("Connect ch= %d ts= %08x nts= %d nbuf = %d\n",
1236 	    ch, sch->ts, nts, nbuf);
1237 
1238 	/* Reread the Time Slot Map */
1239 	sc->reg->srd = sc->last = 0x1800;
1240 	tsleep(&sc->last, PCATCH, "con1", hz);
1241 	sc->reg->srd = sc->last = 0x1820;
1242 	tsleep(&sc->last, PCATCH, "con2", hz);
1243 
1244 	/* Set the channel mode */
1245 	sc->ram->tcct[ch] = 0x2800; /* HDLC-FCS16 | MAXSEL[2] */
1246 	sc->ram->rcct[ch] = 0x2800; /* HDLC-FCS16 | MAXSEL[2] */
1247 
1248 	/*
1249 	 * Allocate the FIFO space
1250 	 * We don't do subchanneling so we can use 128 dwords [4-13]
1251 	 */
1252 	sc->ram->tcct[ch] |= (1 + 2 * (nbuf - 1)) << 16; /* BUFFLEN */
1253 	sc->ram->rcct[ch] |= (1 + 2 * (nbuf - 1)) << 16; /* BUFFLEN */
1254 	sc->ram->tcct[ch] |= ((ch * 2) << 24);	 /* BUFFLOC */
1255 	sc->ram->rcct[ch] |= ((ch * 2) << 24);	 /* BUFFLOC */
1256 
1257 	/* Reread the Channel Configuration Descriptor for this channel */
1258 	sc->reg->srd = sc->last = 0x0b00 + ch;
1259 	tsleep(&sc->last, PCATCH, "con3", hz);
1260 	sc->reg->srd = sc->last = 0x0b20 + ch;
1261 	tsleep(&sc->last, PCATCH, "con4", hz);
1262 
1263 	/*
1264 	 * Figure out how many receive buffers we want:  10 + nts * 2
1265 	 *  1 timeslot,  50 bytes packets -> 68msec
1266 	 * 31 timeslots, 50 bytes packets -> 14msec
1267 	 */
1268 	sch->nmd = nmd = 200 + nts * 4;
1269 	sch->rx_last_md = 0;
1270 	sc->mdt[ch] = kmalloc(sizeof(struct mdesc) * nmd, M_MUSYCC, M_WAITOK);
1271 	sc->mdr[ch] = kmalloc(sizeof(struct mdesc) * nmd, M_MUSYCC, M_WAITOK);
1272 	for (i = 0; i < nmd; i++) {
1273 		if (i == nmd - 1) {
1274 			sc->mdt[ch][i].snext = &sc->mdt[ch][0];
1275 			sc->mdt[ch][i].next = vtophys(sc->mdt[ch][i].snext);
1276 			sc->mdr[ch][i].snext = &sc->mdr[ch][0];
1277 			sc->mdr[ch][i].next = vtophys(sc->mdr[ch][i].snext);
1278 		} else {
1279 			sc->mdt[ch][i].snext = &sc->mdt[ch][i + 1];
1280 			sc->mdt[ch][i].next = vtophys(sc->mdt[ch][i].snext);
1281 			sc->mdr[ch][i].snext = &sc->mdr[ch][i + 1];
1282 			sc->mdr[ch][i].next = vtophys(sc->mdr[ch][i].snext);
1283 		}
1284 		sc->mdt[ch][i].status = 0;
1285 		sc->mdt[ch][i].m = NULL;
1286 		sc->mdt[ch][i].data = 0;
1287 
1288 		MGETHDR(m, M_WAITOK, MT_DATA);
1289 		MCLGET(m, M_WAITOK);
1290 		sc->mdr[ch][i].m = m;
1291 		sc->mdr[ch][i].data = vtophys(m->m_data);
1292 		sc->mdr[ch][i].status = 1600; /* MTU */
1293 	}
1294 	sch->tx_last_md = sch->tx_next_md = &sc->mdt[ch][0];
1295 
1296 	/* Configure it into the chip */
1297 	sc->ram->thp[ch] = vtophys(&sc->mdt[ch][0]);
1298 	sc->ram->tmp[ch] = vtophys(&sc->mdt[ch][0]);
1299 	sc->ram->rhp[ch] = vtophys(&sc->mdr[ch][0]);
1300 	sc->ram->rmp[ch] = vtophys(&sc->mdr[ch][0]);
1301 
1302 	/* Activate the Channel */
1303 	sc->reg->srd = sc->last = 0x0800 + ch;
1304 	tsleep(&sc->last, PCATCH, "con4", hz);
1305 	sc->reg->srd = sc->last = 0x0820 + ch;
1306 	tsleep(&sc->last, PCATCH, "con3", hz);
1307 
1308 	return (0);
1309 }
1310 
1311 static int
1312 musycc_disconnect(hook_p hook)
1313 {
1314 	struct softc *sc;
1315 	struct csoftc *csc;
1316 	struct schan *sch;
1317 	int i, ch;
1318 
1319 	sch = hook->private;
1320 	sc = sch->sc;
1321 	csc = sc->csc;
1322 	ch = sch->chan;
1323 
1324 	while (csc->state != C_RUNNING)
1325 		tsleep(&csc->state, PCATCH, "crun", hz/10);
1326 
1327 	/* Deactivate the channel */
1328 	sc->reg->srd = sc->last = 0x0900 + sch->chan;
1329 	tsleep(&sc->last, PCATCH, "con3", hz);
1330 	sc->reg->srd = sc->last = 0x0920 + sch->chan;
1331 	tsleep(&sc->last, PCATCH, "con4", hz);
1332 
1333 	if (sch->state == DOWN)
1334 		return (0);
1335 	sch->state = DOWN;
1336 
1337 	sc->ram->thp[ch] = 0;
1338 	sc->ram->tmp[ch] = 0;
1339 	sc->ram->rhp[ch] = 0;
1340 	sc->ram->rmp[ch] = 0;
1341 	for (i = 0; i < sch->nmd; i++) {
1342 		if (sc->mdt[ch][i].m != NULL)
1343 			m_freem(sc->mdt[ch][i].m);
1344 		if (sc->mdr[ch][i].m != NULL)
1345 			m_freem(sc->mdr[ch][i].m);
1346 	}
1347 	kfree(sc->mdt[ch], M_MUSYCC);
1348 	sc->mdt[ch] = NULL;
1349 	kfree(sc->mdr[ch], M_MUSYCC);
1350 	sc->mdr[ch] = NULL;
1351 
1352 	for (i = 0; i < 32; i++) {
1353 		if (sch->ts & (1 << i)) {
1354 			sc->ram->rtsm[i] = 0;
1355 			sc->ram->ttsm[i] = 0;
1356 		}
1357 	}
1358 	sc->nhooks--;
1359 	sch->tx_pending = 0;
1360 
1361 	return (0);
1362 }
1363 
1364 
1365 
1366 /*
1367  * PCI initialization stuff
1368  */
1369 
1370 static int
1371 musycc_probe(device_t self)
1372 {
1373 	char desc[40];
1374 
1375 	if (sizeof(struct groupr) != 1572) {
1376 		kprintf("sizeof(struct groupr) = %zu, should be 1572\n",
1377 		    sizeof(struct groupr));
1378 		return(ENXIO);
1379 	}
1380 
1381 	if (sizeof(struct globalr) != 1572) {
1382 		kprintf("sizeof(struct globalr) = %zu, should be 1572\n",
1383 		    sizeof(struct globalr));
1384 		return(ENXIO);
1385 	}
1386 
1387 	if (sizeof(struct mycg) > 2048) {
1388 		kprintf("sizeof(struct mycg) = %zu, should be <= 2048\n",
1389 		    sizeof(struct mycg));
1390 		return(ENXIO);
1391 	}
1392 
1393 	switch (pci_get_devid(self)) {
1394 	case 0x8471109e: strcpy(desc, "CN8471 MUSYCC"); break;
1395 	case 0x8472109e: strcpy(desc, "CN8472 MUSYCC"); break;
1396 	case 0x8474109e: strcpy(desc, "CN8474 MUSYCC"); break;
1397 	case 0x8478109e: strcpy(desc, "CN8478 MUSYCC"); break;
1398 	default:
1399 		return (ENXIO);
1400 	}
1401 
1402 	switch (pci_get_function(self)) {
1403 	case 0: strcat(desc, " Network controller"); break;
1404 	case 1: strcat(desc, " Ebus bridge"); break;
1405 	default:
1406 		return (ENXIO);
1407 	}
1408 
1409 	device_set_desc_copy(self, desc);
1410 	return 0;
1411 }
1412 
1413 static int
1414 musycc_attach(device_t self)
1415 {
1416 	struct csoftc *csc;
1417 	struct resource *res;
1418 	struct softc *sc;
1419 	int rid, i, error;
1420 	int f;
1421 	u_int32_t	*u32p, u;
1422 	static int once;
1423 
1424 	if (!once) {
1425 		once++;
1426 		error = ng_newtype(&ngtypestruct);
1427 		if (error != 0)
1428 			kprintf("ng_newtype() failed %d\n", error);
1429 	}
1430 	kprintf("We have %zu pad bytes in mycg\n", 2048 - sizeof(struct mycg));
1431 
1432 	f = pci_get_function(self);
1433 	/* For function zero allocate a csoftc */
1434 	if (f == 0) {
1435 		csc = kmalloc(sizeof(*csc), M_MUSYCC, M_WAITOK | M_ZERO);
1436 		csc->bus = pci_get_bus(self);
1437 		csc->slot = pci_get_slot(self);
1438 		LIST_INSERT_HEAD(&sc_list, csc, list);
1439 	} else {
1440 		LIST_FOREACH(csc, &sc_list, list) {
1441 			if (csc->bus != pci_get_bus(self))
1442 				continue;
1443 			if (csc->slot != pci_get_slot(self))
1444 				continue;
1445 			break;
1446 		}
1447 	}
1448 	csc->f[f] = self;
1449 	device_set_softc(self, csc);
1450 	rid = PCIR_MAPS;
1451 	res = bus_alloc_resource(self, SYS_RES_MEMORY, &rid,
1452 	    0, ~0, 1, RF_ACTIVE);
1453 	if (res == NULL) {
1454 		device_printf(self, "Could not map memory\n");
1455 		return ENXIO;
1456 	}
1457 	csc->virbase[f] = (u_char *)rman_get_virtual(res);
1458 	csc->physbase[f] = rman_get_start(res);
1459 
1460 	/* Allocate interrupt */
1461 	rid = 0;
1462 	csc->irq[f] = bus_alloc_resource(self, SYS_RES_IRQ, &rid, 0, ~0,
1463 	    1, RF_SHAREABLE | RF_ACTIVE);
1464 
1465 	if (csc->irq[f] == NULL) {
1466 		kprintf("couldn't map interrupt\n");
1467 		return(ENXIO);
1468 	}
1469 
1470 	error = bus_setup_intr(self, csc->irq[f], 0,
1471 			       (f == 0 ? musycc_intr0 : musycc_intr1), csc,
1472 			       &csc->intrhand[f], NULL);
1473 
1474 	if (error) {
1475 		kprintf("couldn't set up irq\n");
1476 		return(ENXIO);
1477 	}
1478 
1479 	if (f == 0)
1480 		return (0);
1481 
1482 	for (i = 0; i < 2; i++)
1483 		kprintf("f%d: device %p virtual %p physical %08lx\n",
1484 		    i, csc->f[i], csc->virbase[i], csc->physbase[i]);
1485 
1486 	csc->reg = (struct globalr *)csc->virbase[0];
1487 	csc->reg->glcd = 0x3f30;	/* XXX: designer magic */
1488 	u32p = (u_int32_t *)csc->virbase[1];
1489 	u = u32p[0x1200];
1490 	if ((u & 0xffff0000) != 0x13760000) {
1491 		kprintf("Not a LMC1504 (ID is 0x%08x).  Bailing out.\n", u);
1492 		return(ENXIO);
1493 	}
1494 	csc->nchan = (u >> 8) & 0xf;
1495 	kprintf("Found <LanMedia LMC1504 Rev %d Chan %d>\n", (u >> 12) & 0xf, csc->nchan);
1496 
1497 	csc->creg = 0xfe;
1498 	csc->cregp = &u32p[0x1000];
1499 	*csc->cregp = csc->creg;
1500 	for (i = 0; i < csc->nchan; i++) {
1501 		sc = &csc->serial[i];
1502 		sc->csc = csc;
1503 		sc->last = 0xffffffff;
1504 		sc->ds8370 = (u_int32_t *)
1505 		    (csc->virbase[1] + i * 0x800);
1506 		sc->ds847x = csc->virbase[0] + i * 0x800;
1507 		sc->reg = (struct globalr *)
1508 		    (csc->virbase[0] + i * 0x800);
1509 		sc->mycg = kmalloc(sizeof(struct mycg), M_MUSYCC,
1510 				   M_WAITOK | M_ZERO);
1511 		sc->ram = &sc->mycg->cg;
1512 
1513 		error = ng_make_node_common(&ngtypestruct, &sc->node);
1514 		if (error) {
1515 			kprintf("ng_make_node_common() failed %d\n", error);
1516 			continue;
1517 		}
1518 		sc->node->private = sc;
1519 		ksprintf(sc->nodename, "sync-%d-%d-%d",
1520 			csc->bus,
1521 			csc->slot,
1522 			i);
1523 		error = ng_name_node(sc->node, sc->nodename);
1524 		/* XXX Apparently failure isn't a problem */
1525 	}
1526 	csc->ram = (struct globalr *)&csc->serial[0].mycg->cg;
1527 	sc = &csc->serial[0];
1528 	sc->reg->srd = sc->last = 0x100;
1529 	csc->state = C_IDLE;
1530 
1531 	return 0;
1532 }
1533 
1534 static device_method_t musycc_methods[] = {
1535 	/* Device interface */
1536 	DEVMETHOD(device_probe,		musycc_probe),
1537 	DEVMETHOD(device_attach,	musycc_attach),
1538 	DEVMETHOD(device_suspend,	bus_generic_suspend),
1539 	DEVMETHOD(device_resume,	bus_generic_resume),
1540 	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
1541 
1542 	DEVMETHOD_END
1543 };
1544 
1545 static driver_t musycc_driver = {
1546 	"musycc",
1547 	musycc_methods,
1548 	0
1549 };
1550 
1551 DRIVER_MODULE(musycc, pci, musycc_driver, musycc_devclass, NULL, NULL);
1552