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