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