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