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