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