if_mn.c revision 57616
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 * $Id: if_mn.c,v 1.1 1999/02/01 13:06:40 phk Exp $
10 *
11 * Driver for Siemens reference design card "Easy321-R1".
12 *
13 * This card contains a FALC54 E1/T1 framer and a MUNICH32X 32-channel HDLC
14 * controller.
15 *
16 * The driver supports E1 mode with up to 31 channels.  We send CRC4 but don't
17 * check it coming in.
18 *
19 * The FALC54 and MUNICH32X have far too many registers and weird modes for
20 * comfort, so I have not bothered typing it all into a "fooreg.h" file,
21 * you will (badly!) need the documentation anyway if you want to mess with
22 * this gadget.
23 *
24 * $FreeBSD: head/sys/pci/if_mn.c 57616 2000-02-29 10:02:29Z billf $
25 */
26
27/*
28 * Stuff to describe the MUNIC32X and FALC54 chips.
29 */
30
31#define M32_CHAN	32	/* We have 32 channels */
32#define M32_TS		32	/* We have 32 timeslots */
33
34#define NG_MN_NODE_TYPE	"mn"
35#define NG_MN_COOKIKE	941432500
36
37#define MN_MAGIC	0x4d6e0000
38
39#define MN_GET		(MN_MAGIC | 0x1)
40#define MN_SET		(MN_MAGIC | 0x2)
41#define MN_DEBUG	(MN_MAGIC | 0x3)
42
43struct mn_control	{
44	int		cmd;
45	char		name[8];
46	unsigned	chan;
47	unsigned	ts[M32_CHAN];
48};
49
50#ifdef _KERNEL
51#define PPP_HEADER_LEN       4 	/* XXX: should live in some header somewhere */
52
53#include <sys/param.h>
54#include <sys/systm.h>
55#include <sys/conf.h>
56#include <sys/mbuf.h>
57#include <sys/kernel.h>
58#include <sys/sysctl.h>
59#include <sys/malloc.h>
60#include <sys/socket.h>
61#include <sys/sockio.h>
62#include <pci/pcireg.h>
63#include <pci/pcivar.h>
64#include <vm/vm.h>
65#include <vm/pmap.h>
66#include <machine/clock.h>
67
68#include <netgraph/ng_message.h>
69#include <netgraph/ng_sample.h>
70#include <netgraph/netgraph.h>
71
72static int mn_maxlatency = 1000;
73SYSCTL_INT(_debug, OID_AUTO, mn_maxlatency, CTLFLAG_RW,
74    &mn_maxlatency, 0,
75	"The number of milliseconds a packet is allowed to spend in the output queue.  "
76	"If the output queue is longer than this number of milliseconds when the packet "
77	"arrives for output, the packet will be dropped."
78);
79
80#ifndef NMN
81/* Most machines don't support more than 4 busmaster PCI slots, if even that many */
82#define NMN	4
83#endif
84
85/* From: PEB 20321 data sheet, p187, table 22 */
86struct m32xreg {
87	u_int32_t conf,    cmd,     stat,    imask;
88	u_int32_t fill10,  piqba,   piql,    fill1c;
89	u_int32_t mode1,   mode2,   ccba,    txpoll;
90	u_int32_t tiqba,   tiql,    riqba,   riql;
91	u_int32_t lconf,   lccba,   fill48,  ltran;
92	u_int32_t ltiqba,  ltiql,   lriqba,  lriql;
93	u_int32_t lreg0,   lreg1,   lreg2,   lreg3;
94	u_int32_t lreg4,   lreg5,   lre6,    lstat;
95	u_int32_t gpdir,   gpdata,  gpod,    fill8c;
96	u_int32_t ssccon,  sscbr,   ssctb,   sscrb;
97	u_int32_t ssccse,  sscim,   fillab,  fillac;
98	u_int32_t iomcon1, iomcon2, iomstat, fillbc;
99	u_int32_t iomcit0, iomcit1, iomcir0, iomcir1;
100	u_int32_t iomtmo,  iomrmo,  filld8,  filldc;
101	u_int32_t mbcmd,   mbdata1, mbdata2, mbdata3;
102	u_int32_t mbdata4, mbdata5, mbdata6, mbdata7;
103};
104
105/* From: PEB 2254 data sheet, p80, table 10 */
106struct f54wreg {
107	u_int16_t xfifo;
108	u_int8_t                  cmdr,   mode,   rah1,   rah2,   ral1,   ral2;
109	u_int8_t  ipc,    ccr1,   ccr3,   pre,    rtr1,   rtr2,   rtr3,   rtr4;
110	u_int8_t  ttr1,   ttr2,   ttr3,   ttr4,   imr0,   imr1,   imr2,   imr3;
111	u_int8_t  imr4,   fill19, fmr0,   fmr1,   fmr2,   loop,   xsw,    xsp;
112	u_int8_t  xc0,    xc1,    rc0,    rc1,    xpm0,   xpm1,   xpm2,   tswm;
113	u_int8_t  test1,  idle,   xsa4,   xsa5,   xsa6,   xsa7,   xsa8,   fmr3;
114	u_int8_t  icb1,   icb2,   icb3,   icb4,   lim0,   lim1,   pcd,    pcr;
115	u_int8_t  lim2,   fill39[7];
116	u_int8_t  fill40[8];
117	u_int8_t  fill48[8];
118	u_int8_t  fill50[8];
119	u_int8_t  fill58[8];
120	u_int8_t  dec,    fill61, test2,  fill63[5];
121	u_int8_t  fill68[8];
122	u_int8_t  xs[16];
123};
124
125/* From: PEB 2254 data sheet, p117, table 10 */
126struct f54rreg {
127	u_int16_t rfifo;
128	u_int8_t                  fill2,  mode,   rah1,   rah2,   ral1,   ral2;
129	u_int8_t  ipc,    ccr1,   ccr3,   pre,    rtr1,   rtr2,   rtr3,   rtr4;
130	u_int8_t  ttr1,   ttr2,   ttr3,   ttr4,   imr0,   imr1,   imr2,   imr3;
131	u_int8_t  imr4,   fill19, fmr0,   fmr1,   fmr2,   loop,   xsw,    xsp;
132	u_int8_t  xc0,    xc1,    rc0,    rc1,    xpm0,   xpm1,   xpm2,   tswm;
133	u_int8_t  test,   idle,   xsa4,   xsa5,   xsa6,   xsa7,   xsa8,   fmr13;
134	u_int8_t  icb1,   icb2,   icb3,   icb4,   lim0,   lim1,   pcd,    pcr;
135	u_int8_t  lim2,   fill39[7];
136	u_int8_t  fill40[8];
137	u_int8_t  fill48[4],                      frs0,   frs1,   rsw,    rsp;
138	u_int16_t fec,            cvc,            cec1,           ebc;
139	u_int16_t cec2,           cec3;
140	u_int8_t                                  rsa4,   rsa5,   rsa6,   rsa7;
141	u_int8_t  rsa8,   rsa6s,  tsr0,   tsr1,   sis,    rsis;
142	u_int16_t                                                 rbc;
143	u_int8_t  isr0,   isr1,   isr2,   isr3,   fill6c, fill6d, gis,    vstr;
144	u_int8_t  rs[16];
145};
146
147/* Transmit & receive descriptors */
148struct trxd {
149	u_int32_t	flags;
150	vm_offset_t	next;
151	vm_offset_t	data;
152	u_int32_t	status;	/* only used for receive */
153	struct mbuf	*m;	/* software use only */
154	struct trxd	*vnext;	/* software use only */
155};
156
157/* Channel specification */
158struct cspec {
159	u_int32_t	flags;
160	vm_offset_t	rdesc;
161	vm_offset_t	tdesc;
162	u_int32_t	itbs;
163};
164
165struct m32_mem {
166	vm_offset_t	csa;
167	u_int32_t	ccb;
168	u_int32_t	reserve1[2];
169	u_int32_t	ts[M32_TS];
170	struct cspec	cs[M32_CHAN];
171	vm_offset_t	crxd[M32_CHAN];
172	vm_offset_t	ctxd[M32_CHAN];
173};
174
175struct softc;
176struct sockaddr;
177struct rtentry;
178
179static	const char*	mn_probe  (pcici_t tag, pcidi_t type);
180static	void	mn_attach (pcici_t tag, int unit);
181static	u_long	mn_count;
182static	void	mn_create_channel(struct softc *sc, int chan);
183static	int	mn_reset(struct softc *sc);
184static	struct trxd * mn_alloc_desc(void);
185static	void	mn_free_desc(struct trxd *dp);
186static	void	mn_intr(void *xsc);
187static	u_int32_t mn_parse_ts(const char *s, int *nbit);
188#ifdef notyet
189static	void	m32_dump(struct softc *sc);
190static	void	f54_dump(struct softc *sc);
191static	void	mn_fmt_ts(char *p, u_int32_t ts);
192#endif /* notyet */
193
194static	ng_constructor_t ngmn_constructor;
195static	ng_rcvmsg_t ngmn_rcvmsg;
196static	ng_shutdown_t ngmn_shutdown;
197static	ng_newhook_t ngmn_newhook;
198static	ng_connect_t ngmn_connect;
199static	ng_rcvdata_t ngmn_rcvdata;
200static	ng_disconnect_t ngmn_disconnect;
201
202static struct ng_type mntypestruct = {
203	NG_VERSION,
204	NG_MN_NODE_TYPE,
205	NULL,
206	ngmn_constructor,
207	ngmn_rcvmsg,
208	ngmn_shutdown,
209	ngmn_newhook,
210	NULL,
211	ngmn_connect,
212	ngmn_rcvdata,
213	ngmn_rcvdata,
214	ngmn_disconnect,
215	NULL
216};
217
218static MALLOC_DEFINE(M_MN, "mn", "Mx driver related");
219
220#define NIQB	64
221
222struct softc;
223
224struct schan {
225	enum {DOWN, UP} state;
226	struct softc	*sc;
227	int		chan;
228	u_int32_t	ts;
229	char		name[8];
230	struct trxd	*r1, *rl;
231	struct trxd	*x1, *xl;
232	hook_p		hook;
233
234	time_t		last_recv;
235	time_t		last_rxerr;
236	time_t		last_xmit;
237
238	u_long		rx_error;
239
240	u_long		short_error;
241	u_long		crc_error;
242	u_long		dribble_error;
243	u_long		long_error;
244	u_long		abort_error;
245	u_long		overflow_error;
246
247	int		last_error;
248	int		prev_error;
249
250	u_long		tx_pending;
251	u_long		tx_limit;
252};
253
254static struct softc {
255	int	unit;
256	pcici_t tag;
257	vm_offset_t	m0v, m0p, m1v, m1p;
258	struct m32xreg	*m32x;
259	struct f54wreg	*f54w;
260	struct f54rreg	*f54r;
261	struct m32_mem	m32_mem;
262	u_int32_t	tiqb[NIQB];
263	u_int32_t	riqb[NIQB];
264	u_int32_t	piqb[NIQB];
265	u_int32_t	ltiqb[NIQB];
266	u_int32_t	lriqb[NIQB];
267	char		name[8];
268	u_int32_t	falc_irq, falc_state, framer_state;
269	struct schan *ch[M32_CHAN];
270	char	nodename[NG_NODELEN + 1];
271	node_p	node;
272
273	u_long		cnt_fec;
274	u_long		cnt_cvc;
275	u_long		cnt_cec1;
276	u_long		cnt_ebc;
277	u_long		cnt_cec2;
278	u_long		cnt_cec3;
279	u_long		cnt_rbc;
280} *softc[NMN];
281
282static int
283ngmn_constructor(node_p *nodep)
284{
285
286	return (EINVAL);
287}
288
289static int
290ngmn_shutdown(node_p nodep)
291{
292
293	return (EINVAL);
294}
295
296static int
297ngmn_rcvmsg(node_p node, struct ng_mesg *msg, const char *retaddr, struct ng_mesg **resp)
298{
299	struct softc *sc;
300	struct schan *sch;
301	char *arg;
302	int pos, i;
303
304	sc = node->private;
305
306	if (msg->header.typecookie != NGM_GENERIC_COOKIE ||
307	    msg->header.cmd != NGM_TEXT_STATUS) {
308		if (resp)
309			*resp = NULL;
310		FREE(msg, M_NETGRAPH);
311		return (EINVAL);
312	}
313	NG_MKRESPONSE(*resp, msg, sizeof(struct ng_mesg) + NG_TEXTRESPONSE,
314	    M_NOWAIT);
315	if (*resp == NULL) {
316		FREE(msg, M_NETGRAPH);
317		return (ENOMEM);
318	}
319	arg = (char *)(*resp)->data;
320	pos = 0;
321	pos += sprintf(pos + arg,"Framer status %b;\n", sc->framer_state, "\20"
322	    "\40LOS\37AIS\36LFA\35RRA"
323	    "\34AUXP\33NMF\32LMFA\31frs0.0"
324	    "\30frs1.7\27TS16RA\26TS16LOS\25TS16AIS"
325	    "\24TS16LFA\23frs1.2\22XLS\21XLO"
326	    "\20RS1\17rsw.6\16RRA\15RY0"
327	    "\14RY1\13RY2\12RY3\11RY4"
328	    "\10SI1\7SI2\6rsp.5\5rsp.4"
329	    "\4rsp.3\3RSIF\2RS13\1RS15");
330	pos += sprintf(pos + arg,"    Framing errors: %lu", sc->cnt_fec);
331	pos += sprintf(pos + arg,"  Code Violations: %lu\n", sc->cnt_cvc);
332
333	pos += sprintf(pos + arg,"    Falc State %b;\n", sc->falc_state, "\20"
334	    "\40LOS\37AIS\36LFA\35RRA"
335	    "\34AUXP\33NMF\32LMFA\31frs0.0"
336	    "\30frs1.7\27TS16RA\26TS16LOS\25TS16AIS"
337	    "\24TS16LFA\23frs1.2\22XLS\21XLO"
338	    "\20RS1\17rsw.6\16RRA\15RY0"
339	    "\14RY1\13RY2\12RY3\11RY4"
340	    "\10SI1\7SI2\6rsp.5\5rsp.4"
341	    "\4rsp.3\3RSIF\2RS13\1RS15");
342	pos += sprintf(pos + arg, "    Falc IRQ %b\n", sc->falc_irq, "\20"
343	    "\40RME\37RFS\36T8MS\35RMB\34CASC\33CRC4\32SA6SC\31RPF"
344	    "\30b27\27RDO\26ALLS\25XDU\24XMB\23b22\22XLSC\21XPR"
345	    "\20FAR\17LFA\16MFAR\15T400MS\14AIS\13LOS\12RAR\11RA"
346	    "\10ES\7SEC\6LMFA16\5AIS16\4RA16\3API\2SLN\1SLP");
347	for (i = 0; i < M32_CHAN; i++) {
348		if (!sc->ch[i])
349			continue;
350		sch = sc->ch[i];
351
352		pos += sprintf(arg + pos, "  Chan %d <%s> ",
353		    i, sch->hook->name);
354
355		pos += sprintf(arg + pos, "  Last Rx: ");
356		if (sch->last_recv)
357			pos += sprintf(arg + pos, "%lu s", time_second - sch->last_recv);
358		else
359			pos += sprintf(arg + pos, "never");
360
361		pos += sprintf(arg + pos, ", last RxErr: ");
362		if (sch->last_rxerr)
363			pos += sprintf(arg + pos, "%lu s", time_second - sch->last_rxerr);
364		else
365			pos += sprintf(arg + pos, "never");
366
367		pos += sprintf(arg + pos, ", last Tx: ");
368		if (sch->last_xmit)
369			pos += sprintf(arg + pos, "%lu s\n", time_second - sch->last_xmit);
370		else
371			pos += sprintf(arg + pos, "never\n");
372
373		pos += sprintf(arg + pos, "    RX error(s) %lu", sch->rx_error);
374		pos += sprintf(arg + pos, " Short: %lu", sch->short_error);
375		pos += sprintf(arg + pos, " CRC: %lu", sch->crc_error);
376		pos += sprintf(arg + pos, " Mod8: %lu", sch->dribble_error);
377		pos += sprintf(arg + pos, " Long: %lu", sch->long_error);
378		pos += sprintf(arg + pos, " Abort: %lu", sch->abort_error);
379		pos += sprintf(arg + pos, " Overflow: %lu\n", sch->overflow_error);
380
381		pos += sprintf(arg + pos, "    Last error: %b  Prev error: %b\n",
382		    sch->last_error, "\20\7SHORT\5CRC\4MOD8\3LONG\2ABORT\1OVERRUN",
383		    sch->prev_error, "\20\7SHORT\5CRC\4MOD8\3LONG\2ABORT\1OVERRUN");
384	}
385	(*resp)->header.arglen = pos + 1;
386	FREE(msg, M_NETGRAPH);
387	return (0);
388}
389
390static int
391ngmn_newhook(node_p node, hook_p hook, const char *name)
392{
393	u_int32_t ts, chan;
394	struct softc *sc;
395	int nbit;
396
397	sc = node->private;
398
399	if (name[0] != 't' || name[1] != 's')
400		return (EINVAL);
401
402	ts = mn_parse_ts(name + 2, &nbit);
403	if (ts == 0)
404		return (EINVAL);
405	chan = ffs(ts) - 1;
406	if (sc->ch[chan])
407		return (EBUSY);
408	mn_create_channel(sc, chan);
409	sc->ch[chan]->ts = ts;
410	sc->ch[chan]->hook = hook;
411	sc->ch[chan]->tx_limit = nbit * 8;
412	hook->private = sc->ch[chan];
413	return(0);
414}
415
416
417static struct trxd *mn_desc_free;
418
419static struct trxd *
420mn_alloc_desc(void)
421{
422	struct trxd *dp;
423
424	dp = mn_desc_free;
425	if (dp)
426		mn_desc_free = dp->vnext;
427	else
428		dp = (struct trxd *)malloc(sizeof *dp, M_MN, M_NOWAIT);
429	return (dp);
430}
431
432static void
433mn_free_desc(struct trxd *dp)
434{
435	dp->vnext =  mn_desc_free;
436	mn_desc_free = dp;
437}
438
439static u_int32_t
440mn_parse_ts(const char *s, int *nbit)
441{
442	unsigned r;
443	int i, j;
444	char *p;
445
446	r = 0;
447	j = 0;
448	*nbit = 0;
449	while(*s) {
450		i = strtol(s, &p, 0);
451		if (i < 1 || i > 31)
452			return (0);
453		while (j && j < i) {
454			r |= 1 << j++;
455			(*nbit)++;
456		}
457		j = 0;
458		r |= 1 << i;
459		(*nbit)++;
460		if (*p == ',') {
461			s = p + 1;
462			continue;
463		} else if (*p == '-') {
464			j = i;
465			s = p + 1;
466			continue;
467		} else if (!*p) {
468			break;
469		} else {
470			return (0);
471		}
472	}
473	return (r);
474}
475
476#ifdef notyet
477static void
478mn_fmt_ts(char *p, u_int32_t ts)
479{
480	char *s;
481	int j;
482
483	s = "";
484	ts &= 0xfffffffe;
485	for (j = 1; j < 32; j++) {
486		if (!(ts & (1 << j)))
487			continue;
488		sprintf(p, "%s%d", s, j);
489		p += strlen(p);
490		s = ",";
491		if (!(ts & (1 << (j+1))))
492			continue;
493		for (; j < 32; j++)
494			if (!(ts & (1 << (j+1))))
495				break;
496		sprintf(p, "-%d", j);
497		p += strlen(p);
498		s = ",";
499	}
500}
501#endif /* notyet */
502
503/*
504 * OUTPUT
505 */
506
507static int
508ngmn_rcvdata(hook_p hook, struct mbuf *m, meta_p meta)
509{
510	struct mbuf  *m2;
511	struct trxd *dp, *dp2;
512	struct schan *sch;
513	struct softc *sc;
514	int chan, pitch, len;
515
516	sch = hook->private;
517	sc = sch->sc;
518	chan = sch->chan;
519
520	if (sch->state != UP) {
521		NG_FREE_DATA(m, meta);
522		return (0);
523	}
524	if (sch->tx_pending + m->m_pkthdr.len > sch->tx_limit * mn_maxlatency) {
525		NG_FREE_DATA(m, meta);
526		return (0);
527	}
528	NG_FREE_META(meta);
529	pitch = 0;
530	m2 = m;
531	dp2 = sc->ch[chan]->xl;
532	len = m->m_pkthdr.len;
533	while (len) {
534		dp = mn_alloc_desc();
535		if (!dp) {
536			pitch++;
537			m_freem(m);
538			sc->ch[chan]->xl = dp2;
539			dp = dp2->vnext;
540			while (dp) {
541				dp2 = dp->vnext;
542				mn_free_desc(dp);
543				dp = dp2;
544			}
545			sc->ch[chan]->xl->vnext = 0;
546			break;
547		}
548		dp->data = vtophys(m2->m_data);
549		dp->flags = m2->m_len << 16;
550		dp->flags += 1;
551		len -= m2->m_len;
552		dp->next = vtophys(dp);
553		dp->vnext = 0;
554		sc->ch[chan]->xl->next = vtophys(dp);
555		sc->ch[chan]->xl->vnext = dp;
556		sc->ch[chan]->xl = dp;
557		if (!len) {
558			dp->m = m;
559			dp->flags |= 0xc0000000;
560			dp2->flags &= ~0x40000000;
561		} else {
562			dp->m = 0;
563			m2 = m2->m_next;
564		}
565	}
566	if (pitch)
567		printf("%s%d: Short on mem, pitched %d packets\n",
568		    sc->name, chan, pitch);
569	else
570		sch->tx_pending += m->m_pkthdr.len;
571	return (0);
572}
573
574/*
575 * OPEN
576 */
577static int
578ngmn_connect(hook_p hook)
579{
580	int i, nts, chan;
581	struct trxd *dp, *dp2;
582	struct mbuf *m;
583	struct softc *sc;
584	struct schan *sch;
585	u_int32_t u;
586
587	sch = hook->private;
588	chan = sch->chan;
589	sc = sch->sc;
590
591	printf("%s: OPEN{ state = %d\n", sch->name, sch->state);
592	if (sch->state == UP)
593		return (0);
594	sch->state = UP;
595
596	/* Count and configure the timeslots for this channel */
597	for (nts = i = 0; i < 32; i++)
598		if (sch->ts & (1 << i)) {
599			sc->m32_mem.ts[i] = 0x00ff00ff |
600				(chan << 24) | (chan << 8);
601			nts++;
602		}
603
604	/* Init the receiver & xmitter to HDLC */
605	sc->m32_mem.cs[chan].flags = 0x80e90006;
606	/* Allocate two buffers per timeslot */
607	sc->m32_mem.cs[chan].itbs = nts * 2;
608
609	/* Setup a transmit chain with one descriptor */
610	/* XXX: we actually send a 1 byte packet */
611	dp = mn_alloc_desc();
612	MGETHDR(m, M_WAIT, MT_DATA);
613	dp->m = m;
614	dp->flags = 0xc0000000 + (1 << 16);
615	dp->next = vtophys(dp);
616	dp->vnext = 0;
617	dp->data = vtophys(sc->name);
618	sc->m32_mem.cs[chan].tdesc = vtophys(dp);
619	sc->ch[chan]->x1 = dp;
620	sc->ch[chan]->xl = dp;
621
622	/* Setup a receive chain with 5 + NTS descriptors */
623
624	dp = mn_alloc_desc();
625	MGETHDR(m, M_WAIT, MT_DATA);
626	MCLGET(m, M_WAIT);
627	dp->m = m;
628	dp->data = vtophys(m->m_data);
629	dp->flags = 0x40000000;
630	dp->flags += 1600 << 16;
631	dp->next = vtophys(dp);
632	dp->vnext = 0;
633	sc->ch[chan]->rl = dp;
634
635	for (i = 0; i < (nts + 10); i++) {
636		dp2 = dp;
637		dp = mn_alloc_desc();
638		MGETHDR(m, M_WAIT, MT_DATA);
639		MCLGET(m, M_WAIT);
640		dp->m = m;
641		dp->data = vtophys(m->m_data);
642		dp->flags = 0x00000000;
643		dp->flags += 1600 << 16;
644		dp->next = vtophys(dp2);
645		dp->vnext = dp2;
646	}
647	sc->m32_mem.cs[chan].rdesc = vtophys(dp);
648	sc->ch[chan]->r1 = dp;
649
650	/* Initialize this channel */
651	sc->m32_mem.ccb = 0x00008000 + (chan << 8);
652	sc->m32x->cmd = 0x1;
653	DELAY(30);
654	u = sc->m32x->stat;
655	if (!(u & 1))
656		printf("%s: init chan %d stat %08x\n", sc->name, chan, u);
657	sc->m32x->stat = 1;
658
659	printf("%s%d: TLS} state = %d\n", sc->name, chan, sc->ch[chan]->state);
660	return (0);
661}
662
663/*
664 * CLOSE
665 */
666static int
667ngmn_disconnect(hook_p hook)
668{
669	int chan, i;
670	struct softc *sc;
671	struct schan *sch;
672	struct trxd *dp, *dp2;
673	u_int32_t u;
674
675	sch = hook->private;
676	chan = sch->chan;
677	sc = sch->sc;
678
679	printf("%s: TLF{ state = %d\n", sch->name, sch->state);
680	if (sch->state == DOWN)
681		return (0);
682	sch->state = DOWN;
683
684	/* Set receiver & transmitter off */
685	sc->m32_mem.cs[chan].flags = 0x80920006;
686	sc->m32_mem.cs[chan].itbs = 0;
687
688	/* free the timeslots */
689	for (i = 0; i < 32; i++)
690		if (sc->ch[chan]->ts & (1 << i))
691			sc->m32_mem.ts[i] = 0x20002000;
692
693	/* Initialize this channel */
694	sc->m32_mem.ccb = 0x00008000 + (chan << 8);
695	sc->m32x->cmd = 0x1;
696	DELAY(30);
697	u = sc->m32x->stat;
698	if (!(u & 1))
699		printf("%s: zap chan %d stat %08x\n", sc->name, chan, u);
700	sc->m32x->stat = 1;
701
702	/* Free all receive descriptors and mbufs */
703	for (dp = sc->ch[chan]->r1; dp ; dp = dp2) {
704		if (dp->m)
705			m_freem(dp->m);
706		sc->ch[chan]->r1 = dp2 = dp->vnext;
707		mn_free_desc(dp);
708	}
709
710	/* Free all transmit descriptors and mbufs */
711	for (dp = sc->ch[chan]->x1; dp ; dp = dp2) {
712		if (dp->m)
713			m_freem(dp->m);
714		sc->ch[chan]->x1 = dp2 = dp->vnext;
715		mn_free_desc(dp);
716	}
717	printf("%s%d: TLF} state = %d\n", sc->name, chan, sc->ch[chan]->state);
718	return(0);
719}
720
721/*
722 * Create a new channel.
723 */
724static void
725mn_create_channel(struct softc *sc, int chan)
726{
727	struct schan *sch;
728
729	sch = sc->ch[chan] = (struct schan *)malloc(sizeof *sc->ch[chan],
730	    M_MN, M_WAITOK);
731	bzero(sch, sizeof *sch);
732	sch->sc = sc;
733	sch->state = DOWN;
734	sch->chan = chan;
735	sprintf(sch->name, "%s%d", sc->name, chan);
736	return;
737}
738
739#ifdef notyet
740/*
741 * Dump Munich32x state
742 */
743static void
744m32_dump(struct softc *sc)
745{
746	u_int32_t *tp4;
747	int i, j;
748
749	printf("mn%d: MUNICH32X dump\n", sc->unit);
750	tp4 = (u_int32_t *)sc->m0v;
751	for(j = 0; j < 64; j += 8) {
752		printf("%02x", j * sizeof *tp4);
753		for(i = 0; i < 8; i++)
754			printf(" %08x", tp4[i+j]);
755		printf("\n");
756	}
757	for(j = 0; j < M32_CHAN; j++) {
758		if (!sc->ch[j])
759			continue;
760		printf("CH%d: state %d ts %08x",
761			j, sc->ch[j]->state, sc->ch[j]->ts);
762		printf("  %08x %08x %08x %08x %08x %08x\n",
763			sc->m32_mem.cs[j].flags,
764			sc->m32_mem.cs[j].rdesc,
765			sc->m32_mem.cs[j].tdesc,
766			sc->m32_mem.cs[j].itbs,
767			sc->m32_mem.crxd[j],
768			sc->m32_mem.ctxd[j] );
769	}
770}
771
772/*
773 * Dump Falch54 state
774 */
775static void
776f54_dump(struct softc *sc)
777{
778	u_int8_t *tp1;
779	int i, j;
780
781	printf("%s: FALC54 dump\n", sc->name);
782	tp1 = (u_int8_t *)sc->m1v;
783	for(j = 0; j < 128; j += 16) {
784		printf("%s: %02x |", sc->name, j * sizeof *tp1);
785		for(i = 0; i < 16; i++)
786			printf(" %02x", tp1[i+j]);
787		printf("\n");
788	}
789}
790#endif /* notyet */
791
792/*
793 * Init Munich32x
794 */
795static void
796m32_init(struct softc *sc)
797{
798
799	sc->m32x->conf =  0x00000000;
800	sc->m32x->mode1 = 0x81048000 + 1600; 	/* XXX: temp */
801#if 1
802	sc->m32x->mode2 = 0x00000081;
803	sc->m32x->txpoll = 0xffffffff;
804#else
805	sc->m32x->mode2 = 0x00000101;
806#endif
807	sc->m32x->lconf = 0x6060009B;
808	sc->m32x->imask = 0x00000000;
809}
810
811/*
812 * Init the Falc54
813 */
814static void
815f54_init(struct softc *sc)
816{
817	sc->f54w->ipc  = 0x07;
818
819	sc->f54w->xpm0 = 0xbd;
820	sc->f54w->xpm1 = 0x03;
821	sc->f54w->xpm2 = 0x00;
822
823	sc->f54w->imr0 = 0x18; /* RMB, CASC */
824	sc->f54w->imr1 = 0x08; /* XMB */
825	sc->f54w->imr2 = 0x00;
826	sc->f54w->imr3 = 0x38; /* LMFA16, AIS16, RA16 */
827	sc->f54w->imr4 = 0x00;
828
829	sc->f54w->fmr0 = 0xf0; /* X: HDB3, R: HDB3 */
830	sc->f54w->fmr1 = 0x0e; /* Send CRC4, 2Mbit, ECM */
831	sc->f54w->fmr2 = 0x03; /* Auto Rem-Alarm, Auto resync */
832
833	sc->f54w->lim1 = 0xb0; /* XCLK=8kHz, .62V threshold */
834	sc->f54w->pcd =  0x0a;
835	sc->f54w->pcr =  0x15;
836	sc->f54w->xsw =  0x9f; /* fmr4 */
837	sc->f54w->xsp =  0x1c; /* fmr5 */
838	sc->f54w->xc0 =  0x07;
839	sc->f54w->xc1 =  0x3d;
840	sc->f54w->rc0 =  0x05;
841	sc->f54w->rc1 =  0x00;
842	sc->f54w->cmdr = 0x51;
843}
844
845static int
846mn_reset(struct softc *sc)
847{
848	u_int32_t u;
849	int i, j;
850
851	u = 0;
852	for(i = 5; i >= 0; i-- ) {
853		sc->m32x->gpdir = i;
854		for (j = 0; j < 8; j ++) {
855			sc->m32x->gpdata = j;
856			u += sc->m32x->gpdata;
857		}
858	}
859	if (u != 0xe4) {
860		printf("mn%d: WARNING: Controller failed to initialize.\n",
861		    sc->unit);
862#if 0
863		return (0);
864#endif
865		printf("mn%d: %x\n", sc->unit, u);
866	}
867
868	sc->m32x->ccba = vtophys(&sc->m32_mem.csa);
869	sc->m32_mem.csa = vtophys(&sc->m32_mem.ccb);
870
871	bzero(sc->tiqb, sizeof sc->tiqb);
872	sc->m32x->tiqba = vtophys(&sc->tiqb);
873	sc->m32x->tiql = NIQB / 16 - 1;
874
875	bzero(sc->riqb, sizeof sc->riqb);
876	sc->m32x->riqba = vtophys(&sc->riqb);
877	sc->m32x->riql = NIQB / 16 - 1;
878
879	bzero(sc->ltiqb, sizeof sc->ltiqb);
880	sc->m32x->ltiqba = vtophys(&sc->ltiqb);
881	sc->m32x->ltiql = NIQB / 16 - 1;
882
883	bzero(sc->lriqb, sizeof sc->lriqb);
884	sc->m32x->lriqba = vtophys(&sc->lriqb);
885	sc->m32x->lriql = NIQB / 16 - 1;
886
887	bzero(sc->piqb, sizeof sc->piqb);
888	sc->m32x->piqba = vtophys(&sc->piqb);
889	sc->m32x->piql = NIQB / 16 - 1;
890
891	m32_init(sc);
892	f54_init(sc);
893
894	u = sc->m32x->stat;
895	sc->m32x->stat = u;
896	sc->m32_mem.ccb = 0x4;
897	sc->m32x->cmd = 0x1;
898	DELAY(1000);
899	u = sc->m32x->stat;
900	sc->m32x->stat = u;
901
902	/* set all timeslots to known state */
903	for (i = 0; i < 32; i++)
904		sc->m32_mem.ts[i] = 0x20002000;
905
906	if (!(u & 1)) {
907		printf(
908"mn%d: WARNING: Controller failed the PCI bus-master test.\n"
909"mn%d: WARNING: Use a PCI slot which can support bus-master cards.\n",
910		    sc->unit, sc->unit);
911		return  (0);
912	}
913	return (1);
914}
915
916/*
917 * FALC54 interrupt handling
918 */
919static void
920f54_intr(struct softc *sc)
921{
922	unsigned g, u, s;
923
924	g = sc->f54r->gis;
925	u = sc->f54r->isr0 << 24;
926	u |= sc->f54r->isr1 << 16;
927	u |= sc->f54r->isr2 <<  8;
928	u |= sc->f54r->isr3;
929	sc->falc_irq = u;
930	/* don't chat about the 1 sec heart beat */
931	if (u & ~0x40) {
932#if 0
933		printf("%s*: FALC54 IRQ GIS:%02x %b\n", sc->name, g, u, "\20"
934		    "\40RME\37RFS\36T8MS\35RMB\34CASC\33CRC4\32SA6SC\31RPF"
935		    "\30b27\27RDO\26ALLS\25XDU\24XMB\23b22\22XLSC\21XPR"
936		    "\20FAR\17LFA\16MFAR\15T400MS\14AIS\13LOS\12RAR\11RA"
937		    "\10ES\7SEC\6LMFA16\5AIS16\4RA16\3API\2SLN\1SLP");
938#endif
939		s = sc->f54r->frs0 << 24;
940		s |= sc->f54r->frs1 << 16;
941		s |= sc->f54r->rsw <<  8;
942		s |= sc->f54r->rsp;
943		sc->falc_state = s;
944
945		s &= ~0x01844038;	/* undefined or static bits */
946		s &= ~0x00009fc7;	/* bits we don't care about */
947		s &= ~0x00780000;	/* XXX: TS16 related */
948		s &= ~0x06000000;	/* XXX: Multiframe related */
949#if 0
950		printf("%s*: FALC54 Status %b\n", sc->name, s, "\20"
951		    "\40LOS\37AIS\36LFA\35RRA\34AUXP\33NMF\32LMFA\31frs0.0"
952		    "\30frs1.7\27TS16RA\26TS16LOS\25TS16AIS\24TS16LFA\23frs1.2\22XLS\21XLO"
953		    "\20RS1\17rsw.6\16RRA\15RY0\14RY1\13RY2\12RY3\11RY4"
954		    "\10SI1\7SI2\6rsp.5\5rsp.4\4rsp.3\3RSIF\2RS13\1RS15");
955#endif
956		if (s != sc->framer_state) {
957#if 0
958			for (i = 0; i < M32_CHAN; i++) {
959				if (!sc->ch[i])
960					continue;
961			        sp = &sc->ch[i]->ifsppp;
962				if (!(sp->pp_if.if_flags & IFF_UP))
963					continue;
964				if (s)
965					timeout((timeout_t *)sp->pp_down, sp, 1 * hz);
966				else
967					timeout((timeout_t *)sp->pp_up, sp, 1 * hz);
968			}
969#endif
970			sc->framer_state = s;
971		}
972	}
973	/* Once per second check error counters */
974	/* XXX: not clear if this is actually ok */
975	if (!(u & 0x40))
976		return;
977	sc->cnt_fec  += sc->f54r->fec;
978	sc->cnt_cvc  += sc->f54r->cvc;
979	sc->cnt_cec1 += sc->f54r->cec1;
980	sc->cnt_ebc  += sc->f54r->ebc;
981	sc->cnt_cec2 += sc->f54r->cec2;
982	sc->cnt_cec3 += sc->f54r->cec3;
983	sc->cnt_rbc  += sc->f54r->rbc;
984}
985
986/*
987 * Transmit interrupt for one channel
988 */
989static void
990mn_tx_intr(struct softc *sc, u_int32_t vector)
991{
992	u_int32_t chan;
993	struct trxd *dp;
994	struct mbuf *m;
995
996	chan = vector & 0x1f;
997	if (!sc->ch[chan])
998		return;
999	if (sc->ch[chan]->state != UP) {
1000		printf("%s: tx_intr when not UP\n", sc->name);
1001		return;
1002	}
1003	for (;;) {
1004		dp = sc->ch[chan]->x1;
1005		if (vtophys(dp) == sc->m32_mem.ctxd[chan])
1006			return;
1007		m = dp->m;
1008		if (m) {
1009			sc->ch[chan]->tx_pending -= m->m_pkthdr.len;
1010			m_freem(m);
1011		}
1012		sc->ch[chan]->last_xmit = time_second;
1013		sc->ch[chan]->x1 = dp->vnext;
1014		mn_free_desc(dp);
1015	}
1016}
1017
1018/*
1019 * Receive interrupt for one channel
1020 */
1021static void
1022mn_rx_intr(struct softc *sc, u_int32_t vector)
1023{
1024	u_int32_t chan, err;
1025	struct trxd *dp;
1026	struct mbuf *m;
1027	struct schan *sch;
1028
1029	chan = vector & 0x1f;
1030	if (!sc->ch[chan])
1031		return;
1032	sch = sc->ch[chan];
1033	if (sch->state != UP) {
1034		printf("%s: rx_intr when not UP\n", sc->name);
1035		return;
1036	}
1037	vector &= ~0x1f;
1038	if (vector == 0x30000b00)
1039		sch->rx_error++;
1040	for (;;) {
1041		dp = sch->r1;
1042		if (vtophys(dp) == sc->m32_mem.crxd[chan])
1043			return;
1044		m = dp->m;
1045		dp->m = 0;
1046		m->m_pkthdr.len = m->m_len = (dp->status >> 16) & 0x1fff;
1047		err = (dp->status >> 8) & 0xff;
1048		if (!err) {
1049			ng_queue_data(sch->hook, m, NULL);
1050			sch->last_recv = time_second;
1051			m = 0;
1052			/* we could be down by now... */
1053			if (sch->state != UP)
1054				return;
1055		} else if (err & 0x40) {
1056			sch->short_error++;
1057		} else if (err & 0x10) {
1058			sch->crc_error++;
1059		} else if (err & 0x08) {
1060			sch->dribble_error++;
1061		} else if (err & 0x04) {
1062			sch->long_error++;
1063		} else if (err & 0x02) {
1064			sch->abort_error++;
1065		} else if (err & 0x01) {
1066			sch->overflow_error++;
1067		}
1068		if (err) {
1069			sch->last_rxerr = time_second;
1070			sch->prev_error = sch->last_error;
1071			sch->last_error = err;
1072		}
1073
1074		sc->ch[chan]->r1 = dp->vnext;
1075
1076		/* Replenish desc + mbuf supplies */
1077		if (!m) {
1078			MGETHDR(m, M_DONTWAIT, MT_DATA);
1079			if (m == NULL) {
1080				mn_free_desc(dp);
1081				return;
1082			}
1083			MCLGET(m, M_DONTWAIT);
1084			if((m->m_flags & M_EXT) == 0) {
1085				mn_free_desc(dp);
1086				return;
1087			}
1088		}
1089		dp->m = m;
1090		dp->data = vtophys(m->m_data);
1091		dp->flags = 0x40000000;
1092		dp->flags += 1600 << 16;
1093		dp->next = vtophys(dp);
1094		dp->vnext = 0;
1095		sc->ch[chan]->rl->next = vtophys(dp);
1096		sc->ch[chan]->rl->vnext = dp;
1097		sc->ch[chan]->rl->flags &= ~0x40000000;
1098		sc->ch[chan]->rl = dp;
1099	}
1100}
1101
1102
1103/*
1104 * Interupt handler
1105 */
1106
1107static void
1108mn_intr(void *xsc)
1109{
1110	struct softc *sc;
1111	u_int32_t stat, lstat, u;
1112	int i, j;
1113
1114	sc = xsc;
1115	stat =  sc->m32x->stat;
1116	lstat =  sc->m32x->lstat;
1117#if 0
1118	if (!stat && !(lstat & 2))
1119		return;
1120#endif
1121
1122	if (stat & ~0xc200) {
1123		printf("%s*: I stat=%08x lstat=%08x\n", sc->name, stat, lstat);
1124	}
1125
1126	if ((stat & 0x200) || (lstat & 2))
1127		f54_intr(sc);
1128
1129	for (j = i = 0; i < 64; i ++) {
1130		u = sc->riqb[i];
1131		if (u) {
1132			sc->riqb[i] = 0;
1133			mn_rx_intr(sc, u);
1134			if ((u & ~0x1f) == 0x30000800 || (u & ~0x1f) == 0x30000b00)
1135				continue;
1136			u &= ~0x30000400;	/* bits we don't care about */
1137			if ((u & ~0x1f) == 0x00000900)
1138				continue;
1139			if (!(u & ~0x1f))
1140				continue;
1141			if (!j)
1142				printf("%s*: RIQB:", sc->name);
1143			printf(" [%d]=%08x", i, u);
1144			j++;
1145		}
1146	}
1147	if (j)
1148	    printf("\n");
1149
1150	for (j = i = 0; i < 64; i ++) {
1151		u = sc->tiqb[i];
1152		if (u) {
1153			sc->tiqb[i] = 0;
1154			mn_tx_intr(sc, u);
1155			if ((u & ~0x1f) == 0x20000800)
1156				continue;
1157			u &= ~0x20000000;	/* bits we don't care about */
1158			if (!u)
1159				continue;
1160			if (!j)
1161				printf("%s*: TIQB:", sc->name);
1162			printf(" [%d]=%08x", i, u);
1163			j++;
1164		}
1165	}
1166	if (j)
1167		printf("\n");
1168	sc->m32x->stat = stat;
1169}
1170
1171static void
1172mn_timeout(void *xsc)
1173{
1174	static int round = 0;
1175	struct softc *sc;
1176
1177	mn_intr(xsc);
1178	sc = xsc;
1179	timeout(mn_timeout, xsc, 10 * hz);
1180	round++;
1181	if (round == 2) {
1182		sc->m32_mem.ccb = 0x00008004;
1183		sc->m32x->cmd = 0x1;
1184	} else if (round > 2) {
1185		printf("%s: timeout\n", sc->name);
1186	}
1187}
1188
1189/*
1190 * PCI initialization stuff
1191 */
1192
1193static struct pci_device mn_device = {
1194	"mn",
1195	mn_probe,
1196	mn_attach,
1197	&mn_count,
1198	NULL
1199};
1200
1201#ifdef COMPAT_PCI_DRIVER
1202COMPAT_PCI_DRIVER(ti, mn_device);
1203#else
1204DATA_SET(pcidevice_set, mn_device);
1205#endif /* COMPAT_PCI_DRIVER */
1206
1207static const char*
1208mn_probe (pcici_t tag, pcidi_t typea)
1209{
1210	u_int id = pci_conf_read(tag, PCI_ID_REG);
1211
1212	if (sizeof (struct m32xreg) != 256) {
1213		printf("MN: sizeof(struct m32xreg) = %d, should have been 256\n", sizeof (struct m32xreg));
1214		return (0);
1215	}
1216	if (sizeof (struct f54rreg) != 128) {
1217		printf("MN: sizeof(struct f54rreg) = %d, should have been 128\n", sizeof (struct f54rreg));
1218		return (0);
1219	}
1220	if (sizeof (struct f54wreg) != 128) {
1221		printf("MN: sizeof(struct f54wreg) = %d, should have been 128\n", sizeof (struct f54wreg));
1222		return (0);
1223	}
1224
1225	if (id == 0x2101110a)
1226		return "Munich32X E1/T1 HDLC Controller";
1227
1228	return 0;
1229}
1230
1231static void
1232mn_attach (pcici_t tag, int unit)
1233{
1234	struct softc *sc;
1235	u_int32_t u;
1236	u_int32_t pci_class;
1237	static int once;
1238
1239	if (!once) {
1240		if (ng_newtype(&mntypestruct))
1241			printf("ng_newtype failed\n");
1242		once++;
1243	}
1244
1245	sc = (struct softc *)malloc(sizeof *sc, M_MN, M_WAITOK);
1246	softc[unit] = sc;
1247	bzero(sc, sizeof *sc);
1248
1249	sc->tag = tag;
1250	sc->unit = unit;
1251	sprintf(sc->name, "mn%c", 'A' + unit);
1252
1253	if (!pci_map_int(tag, mn_intr, sc, &net_imask)) {
1254		printf("mn%d: could not map interrupt\n", sc->unit);
1255		return;
1256	}
1257	pci_map_mem(tag, PCI_MAP_REG_START, &sc->m0v, &sc->m0p);
1258	pci_map_mem(tag, PCI_MAP_REG_START + 4, &sc->m1v, &sc->m1p);
1259
1260	u = pci_conf_read(tag, PCIR_COMMAND);
1261	pci_conf_write(tag, PCIR_COMMAND, u | PCIM_CMD_PERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN);
1262	pci_conf_write(tag, PCIR_COMMAND, 0x02800046);
1263
1264	pci_class = pci_conf_read(tag, PCI_CLASS_REG);
1265
1266	sc->m32x = (struct m32xreg *) sc->m0v;
1267	sc->f54w = (struct f54wreg *) sc->m1v;
1268	sc->f54r = (struct f54rreg *) sc->m1v;
1269
1270	/* We must reset before poking at FALC54 registers */
1271	u = mn_reset(sc);
1272	if (!u)
1273		return;
1274
1275	printf("mn%d: Munich32X", sc->unit);
1276	switch (pci_class & 0xff) {
1277	case 0x13:
1278		printf(" Rev 1.3");
1279		break;
1280	default:
1281		printf(" Rev 0x%x\n", pci_class & 0xff);
1282	}
1283	printf(", Falc54");
1284	switch (sc->f54r->vstr) {
1285	case 0:
1286		printf(" Rev < 1.3\n");
1287		break;
1288	case 1:
1289		printf(" Rev 1.3\n");
1290		break;
1291	case 2:
1292		printf(" Rev 1.4\n");
1293		break;
1294	case 0x10:
1295		printf("-LH Rev 1.1\n");
1296		break;
1297	default:
1298		printf(" Rev 0x%x\n", sc->f54r->vstr);
1299	}
1300
1301	if (ng_make_node_common(&mntypestruct, &sc->node) != 0) {
1302		printf("ng_make_node_common failed\n");
1303		return;
1304	}
1305	sc->node->private = sc;
1306	sprintf(sc->nodename, "%s%d", NG_MN_NODE_TYPE, sc->unit);
1307	if (ng_name_node(sc->node, sc->nodename)) {
1308		ng_rmnode(sc->node);
1309		ng_unref(sc->node);
1310		return;
1311	}
1312
1313	return;
1314}
1315#endif /* _KERNEL */
1316