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