1 /* $NetBSD: if_ntwoc_isa.c,v 1.1 2000/01/04 06:29:21 chopps Exp $ */ 2 /* 3 * Copyright (c) 1999 Christian E. Hopps 4 * Copyright (c) 1996 John Hay. 5 * Copyright (c) 1996 SDL Communications, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $Id: if_ntwoc_isa.c,v 1.1 2000/01/04 06:29:21 chopps Exp $ 33 */ 34 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/device.h> 39 #include <sys/mbuf.h> 40 #include <sys/socket.h> 41 42 #include <net/if.h> 43 44 #include <machine/cpu.h> 45 #include <machine/bus.h> 46 #include <machine/intr.h> 47 48 #include <dev/isa/isavar.h> 49 50 #include <dev/ic/hd64570reg.h> 51 #include <dev/ic/hd64570var.h> 52 53 #include <dev/isa/if_ntwoc_isareg.h> 54 55 #if 1 56 #define NTWO_DEBUG 57 #endif 58 59 #ifdef NTWO_DEBUG 60 #define NTWO_DPRINTF(x) printf x 61 #else 62 #define NTWO_DPRINTF(x) 63 #endif 64 65 #if __NetBSD_Version__ >= 104160000 66 static void ntwoc_isa_config_interrupts __P((struct device *)); 67 #else 68 #define SCA_BASECLOCK 9830400 69 #endif 70 71 /* hard core 16k for now */ 72 #define NTWOC_WIN_SIZE 0x4000 73 74 struct ntwoc_isa_softc { 75 /* Generic device stuff */ 76 struct device sc_dev; /* Common to all devices */ 77 78 /* PCI chipset glue */ 79 void *sc_ih; /* Interrupt handler */ 80 isa_chipset_tag_t sc_ic; /* ISA chipset handle */ 81 82 struct sca_softc sc_sca; /* the SCA itself */ 83 }; 84 85 static int ntwoc_isa_probe __P((struct device *, struct cfdata *, void *)); 86 static void ntwoc_isa_attach __P((struct device *, struct device *, void *)); 87 88 static void ntwoc_isa_clock_callback __P((void *, int, int)); 89 static void ntwoc_isa_dtr_callback __P((void *, int, int)); 90 static int ntwoc_isa_intr __P((void *)); 91 static void ntwoc_isa_get_clock __P((struct sca_port *, u_int8_t, u_int8_t, 92 u_int8_t, u_int8_t)); 93 static void ntwoc_isa_setup_memory(struct sca_softc *sc); 94 static void ntwoc_isa_shutdown __P((void *sc)); 95 96 struct cfattach ntwoc_isa_ca = { 97 sizeof(struct ntwoc_isa_softc), ntwoc_isa_probe, ntwoc_isa_attach, 98 }; 99 100 /* 101 * Names for daughter card types. These match the NTWOC_DB_* defines. 102 */ 103 char *ntwoc_db_names[] = { 104 "V.35", "Unknown 0x01", "Test", "Unknown 0x03", 105 "RS232", "Unknown 0x05", "RS422", "None" 106 }; 107 108 /* some weird offset XXX */ 109 #define SCA_REG(r) (((r) & 0xf) + (((r) & 0xf0) << 6)) 110 111 /* 112 * functions that read and write to the sca registers 113 */ 114 static void 115 ntwoc_isa_sca_write_1(struct sca_softc *sc, u_int reg, u_int8_t val) 116 { 117 bus_space_write_1(sc->sc_iot, sc->scu_sca_ioh[(reg & 0xf0) >> 4], 118 (reg & 0xf), val); 119 } 120 121 static void 122 ntwoc_isa_sca_write_2(struct sca_softc *sc, u_int reg, u_int16_t val) 123 { 124 bus_space_write_2(sc->sc_iot, sc->scu_sca_ioh[(reg & 0xf0) >> 4], 125 (reg & 0xf), val); 126 } 127 128 static u_int8_t 129 ntwoc_isa_sca_read_1(struct sca_softc *sc, u_int reg) 130 { 131 return 132 bus_space_read_1(sc->sc_iot, sc->scu_sca_ioh[(reg & 0xf0) >> 4], 133 (reg & 0xf)); 134 } 135 136 static u_int16_t 137 ntwoc_isa_sca_read_2(struct sca_softc *sc, u_int reg) 138 { 139 return 140 bus_space_read_2(sc->sc_iot, sc->scu_sca_ioh[(reg & 0xf0) >> 4], 141 (reg & 0xf)); 142 } 143 144 /* 145 * set the correct window/page 146 */ 147 static void 148 ntwoc_isa_set_page(struct sca_softc *sca, bus_addr_t addr) 149 { 150 u_int8_t psr; 151 152 /* get old psr value replace old window with new */ 153 psr = bus_space_read_1(sca->sc_iot, sca->sc_ioh, NTWOC_PSR); 154 psr &= ~NTWOC_PG_MSK; 155 psr |= ((addr >> sca->scu_pageshift) & NTWOC_PG_MSK); 156 bus_space_write_1(sca->sc_iot, sca->sc_ioh, NTWOC_PSR, psr); 157 } 158 159 /* 160 * enable the memory window 161 */ 162 static void 163 ntwoc_isa_set_on(struct sca_softc *sca) 164 { 165 u_int8_t pcr; 166 167 /* get old value and add window enable */ 168 pcr = bus_space_read_1(sca->sc_iot, sca->sc_ioh, NTWOC_PCR); 169 pcr |= NTWOC_PCR_MEM_WIN; 170 bus_space_write_1(sca->sc_iot, sca->sc_ioh, NTWOC_PCR, pcr); 171 } 172 173 /* 174 * turn off memory window 175 */ 176 static void 177 ntwoc_isa_set_off(struct sca_softc *sca) 178 { 179 u_int8_t pcr; 180 181 /* get old value and remove window enable */ 182 pcr = bus_space_read_1(sca->sc_iot, sca->sc_ioh, NTWOC_PCR); 183 pcr &= ~NTWOC_PCR_MEM_WIN; 184 bus_space_write_1(sca->sc_iot, sca->sc_ioh, NTWOC_PCR, pcr); 185 } 186 187 static int 188 ntwoc_isa_probe(struct device *parent, struct cfdata *match, void *aux) 189 { 190 struct isa_attach_args *ia; 191 bus_space_tag_t iot, memt; 192 bus_space_handle_t ioh, memh, sca_ioh[16]; 193 int i, tmp, dbg, rv; 194 int gotmem, gotsca[16]; 195 u_int32_t ioport; 196 197 ia = (struct isa_attach_args *)aux; 198 iot = ia->ia_iot; 199 memt = ia->ia_memt; 200 201 memset(gotsca, 0, sizeof(gotsca)); 202 gotmem = rv = 0; 203 dbg = 0; 204 205 /* disallow wildcarded I/O base */ 206 if (ia->ia_iobase == ISACF_PORT_DEFAULT) { 207 printf("ntwoc_isa_probe: must specify port address\n"); 208 return (0); 209 } 210 211 if (ia->ia_irq == ISACF_IRQ_DEFAULT) { 212 printf("ntwoc_isa_probe: must specify irq\n"); 213 return (0); 214 } 215 216 if (ia->ia_maddr == ISACF_IOMEM_DEFAULT) { 217 printf("ntwoc_isa_probe: must specify iomem\n"); 218 return (0); 219 } 220 221 tmp = (match->cf_flags & NTWOC_FLAGS_NPORT_MASK) + 1; 222 if (tmp < 1 || tmp > 2) { 223 printf("ntwoc_isa_probe: only 1 or 2 ports allowed\n"); 224 return (0); 225 } 226 227 /* map the isa io addresses */ 228 if ((tmp = bus_space_map(iot, ia->ia_iobase, NTWOC_SRC_IOPORT_SIZE, 0, 229 &ioh))) { 230 printf("ntwoc_isa_probe: mapping port 0x%x sz %d failed: %d\n", 231 ia->ia_iobase, NTWOC_SRC_IOPORT_SIZE, tmp); 232 return (0); 233 } 234 235 ioport = ia->ia_iobase + 0x8000; 236 for (i = 0; i < 16; ioport += (0x10 << 6), i++) { 237 /* map the isa io addresses */ 238 if ((tmp = bus_space_map(iot, ioport, 16, 0, &sca_ioh[i]))) { 239 printf( 240 "ntwoc_isa_probe: mapping sca 0x%x sz %d failed: %d\n", 241 ioport, 16, tmp); 242 goto out; 243 } 244 gotsca[i] = 1; 245 } 246 247 /* map the isa memory addresses */ 248 /* XXX we really want the user to select this */ 249 if ((tmp = bus_space_map(ia->ia_memt, ia->ia_maddr, NTWOC_WIN_SIZE, 0, 250 &memh))) { 251 printf("ntwoc_isa_probe: mapping mem 0x%x sz %d failed: %d\n", 252 ia->ia_maddr, NTWOC_WIN_SIZE, tmp); 253 goto out; 254 } 255 gotmem = 1; 256 257 /* turn off the card */ 258 bus_space_write_1(iot, ioh, NTWOC_PCR, 0); 259 260 /* 261 * Next, we'll test the Base Address Register to retension of 262 * data... ... seeing if we're *really* talking to an N2. 263 */ 264 for (i = 0; i < 0x100; i++) { 265 bus_space_write_1(iot, ioh, NTWOC_BAR, i); 266 (void)bus_space_read_1(iot, ioh, NTWOC_PCR); 267 if (bus_space_read_1(iot, ioh, NTWOC_BAR) != i) { 268 printf("ntwoc_isa_probe failed (BAR %x, %x)\n", i, tmp); 269 goto out; 270 } 271 } 272 273 /* XXX XXX update the calls to SCA_REG to use our mapping */ 274 275 /* 276 * Now see if we can see the SCA. 277 */ 278 bus_space_write_1(iot, ioh, NTWOC_PCR, 279 NTWOC_PCR_SCARUN | bus_space_read_1(iot, ioh, NTWOC_PCR)); 280 bus_space_write_1(iot, sca_ioh[0], SCA_REG(SCA_WCRL), 0); 281 bus_space_write_1(iot, sca_ioh[0], SCA_REG(SCA_WCRM), 0); 282 bus_space_write_1(iot, sca_ioh[0], SCA_REG(SCA_WCRH), 0); 283 bus_space_write_1(iot, sca_ioh[0], SCA_REG(SCA_PCR), 0); 284 285 bus_space_write_1(iot, sca_ioh[0], SCA_REG(SCA_TMC0), 0); 286 (void)bus_space_read_1(iot, ioh, 0); 287 if ((tmp = bus_space_read_1(iot, sca_ioh[0], SCA_REG(SCA_TMC0))) != 0) { 288 printf("ntwoc_isa_probe: Error reading SCA (TMC0 0, %x)\n", 289 tmp); 290 goto out; 291 } 292 293 bus_space_write_1(iot, sca_ioh[0], SCA_REG(SCA_TMC0), 0x5A); 294 (void)bus_space_read_1(iot, ioh, 0); 295 296 tmp = bus_space_read_1(iot, sca_ioh[0], SCA_REG(SCA_TMC0)); 297 if (tmp != 0x5A) { 298 printf("ntwoc_isa_probe: Error reading SCA (TMC0 5A, %x)\n", 299 tmp); 300 goto out; 301 } 302 303 bus_space_write_2(iot, sca_ioh[0], SCA_REG(SCA_CDAL0), 0); 304 (void)bus_space_read_1(iot, ioh, 0); 305 tmp = bus_space_read_2(iot, sca_ioh[0], SCA_REG(SCA_CDAL0)); 306 if (tmp != 0) { 307 printf("ntwoc_isa_probe: Error reading SCA (CDAL0 0, %x)\n", 308 tmp); 309 goto out; 310 } 311 312 bus_space_write_2(iot, sca_ioh[0], SCA_REG(SCA_CDAL0), 0x55AA); 313 (void)bus_space_read_1(iot, ioh, 0); 314 tmp = bus_space_read_2(iot, sca_ioh[0], SCA_REG(SCA_CDAL0)); 315 if (tmp != 0x55AA) { 316 printf("ntwoc_isa_probe: Error reading SCA (CDAL0 55AA, %x)\n", 317 tmp); 318 goto out; 319 } 320 321 /* 322 * I had a weird card that didn't function correctly on a certain 323 * newer MB. I suspect it was the whacky port addresses. 324 * The following correctly failed it. 325 */ 326 bus_space_write_2(iot, sca_ioh[0], SCA_REG(SCA_TCNTL0), 0x0); 327 (void)bus_space_read_1(iot, ioh, 0); 328 tmp = bus_space_read_2(iot, sca_ioh[0], SCA_REG(SCA_TCNTL0)); 329 if (tmp != 0) { 330 printf("ntwoc_isa_probe: Error reading SCA (TCNTL0 0, %x)\n", 331 tmp); 332 goto out; 333 } 334 335 bus_space_write_2(iot, sca_ioh[0], SCA_REG(SCA_TCNTL0), 0x55AA); 336 (void)bus_space_read_1(iot, ioh, 0); 337 tmp = bus_space_read_2(iot, sca_ioh[0], SCA_REG(SCA_TCNTL0)); 338 if (tmp != 0x55AA) { 339 printf("ntwoc_isa_probe: Error reading SCA (TCNTL0 55AA, %x)\n", 340 tmp); 341 goto out; 342 } 343 344 ia->ia_iosize = NTWOC_SRC_IOPORT_SIZE; 345 ia->ia_msize = NTWOC_WIN_SIZE; 346 rv = 1; 347 out: 348 /* turn off the card */ 349 bus_space_write_1(iot, ioh, NTWOC_PCR, 0); 350 351 if (gotmem) 352 bus_space_unmap(memt, memh, NTWOC_WIN_SIZE); 353 for (i = 0; i < 16; i++) { 354 if (gotsca[i]) 355 bus_space_unmap(iot, sca_ioh[i], 16); 356 } 357 bus_space_unmap(iot, ioh, NTWOC_SRC_IOPORT_SIZE); 358 return (rv); 359 } 360 361 /* 362 * we win! attach the card 363 */ 364 static void 365 ntwoc_isa_attach(struct device *parent, struct device *self, void *aux) 366 { 367 struct ntwoc_isa_softc *sc; 368 struct isa_attach_args *ia; 369 struct sca_softc *sca; 370 bus_addr_t addr; 371 u_int8_t rdiv, tdiv, tmc; 372 u_int32_t flags, ioport; 373 u_int16_t tmp; 374 int i, dbg, pgs, rv; 375 376 ia = (struct isa_attach_args *)aux; 377 sc = (struct ntwoc_isa_softc *)self; 378 sca = &sc->sc_sca; 379 dbg = 0; 380 381 printf(": N2 Serial Interface\n"); 382 flags = sc->sc_dev.dv_cfdata->cf_flags; 383 384 sc->sc_ic = ia->ia_ic; 385 sca->sc_parent = &sc->sc_dev; 386 sca->sc_numports = (flags & NTWOC_FLAGS_NPORT_MASK) + 1; 387 sca->sc_usedma = 0; 388 sca->sc_aux = sc; 389 sca->sc_dtr_callback = ntwoc_isa_dtr_callback; 390 sca->sc_clock_callback = ntwoc_isa_clock_callback; 391 sca->sc_read_1 = ntwoc_isa_sca_read_1; 392 sca->sc_read_2 = ntwoc_isa_sca_read_2; 393 sca->sc_write_1 = ntwoc_isa_sca_write_1; 394 sca->sc_write_2 = ntwoc_isa_sca_write_2; 395 sca->scu_set_page = ntwoc_isa_set_page; 396 sca->scu_page_on = ntwoc_isa_set_on; 397 sca->scu_page_off = ntwoc_isa_set_off; 398 399 /* map the io */ 400 sca->sc_iot = ia->ia_iot; 401 if ((rv = bus_space_map(ia->ia_iot, ia->ia_iobase, 402 NTWOC_SRC_IOPORT_SIZE, 0, &sca->sc_ioh))) { 403 printf("%s: can't map io 0x%x sz %d, %d\n", 404 sc->sc_dev.dv_xname, ia->ia_iobase, NTWOC_SRC_IOPORT_SIZE, 405 rv); 406 return; 407 } 408 409 /* support weird mapping (they used this to avoid 10-bit aliasing) */ 410 ioport = ia->ia_iobase + 0x8000; 411 for (i = 0; i < 16; ioport += (0x10 << 6), i++) { 412 /* map the isa io addresses */ 413 if ((tmp = bus_space_map(ia->ia_iot, ioport, 16, 0, 414 &sca->scu_sca_ioh[i]))) { 415 printf("%s: mapping sca 0x%x sz %d failed: %d\n", 416 sc->sc_dev.dv_xname, ioport, 16, tmp); 417 return; 418 } 419 } 420 421 /* map the isa memory */ 422 sca->scu_memt = ia->ia_memt; 423 sca->scu_pagesize = 0x4000; /* force 16k for now */ 424 if (sca->scu_pagesize < 0x8000) { 425 /* round down to 16k */ 426 sca->scu_pagesize = 0x4000; 427 sca->scu_pageshift = 14; 428 tmp = NTWOC_PSR_WIN_16K; 429 } else if (sca->scu_pagesize < 0x10000) { 430 /* round down to 32k */ 431 sca->scu_pagesize = 0x8000; 432 sca->scu_pageshift = 15; 433 tmp = NTWOC_PSR_WIN_32K; 434 } else if (sca->scu_pagesize < 0x20000) { 435 /* round down to 64k */ 436 sca->scu_pagesize = 0x10000; 437 sca->scu_pageshift = 16; 438 tmp = NTWOC_PSR_WIN_64K; 439 } else { 440 sca->scu_pagesize = 0x20000; 441 sca->scu_pageshift = 17; 442 tmp = NTWOC_PSR_WIN_128K; 443 } 444 sca->scu_pagemask = sca->scu_pagesize - 1; 445 if ((rv = bus_space_map(ia->ia_memt, ia->ia_maddr, sca->scu_pagesize, 0, 446 &sca->scu_memh))) { 447 printf("%s: can't map mem 0x%x sz %ld, %d\n", 448 sc->sc_dev.dv_xname, ia->ia_maddr, sca->scu_pagesize, rv); 449 return; 450 } 451 452 /* turn the card on!! */ 453 bus_space_write_1(sca->sc_iot, sca->sc_ioh, NTWOC_PCR, 454 bus_space_read_1(sca->sc_iot, sca->sc_ioh, NTWOC_PCR) 455 | NTWOC_PCR_SCARUN); 456 457 /* set the window size to 16k */ 458 bus_space_write_1(sca->sc_iot, sca->sc_ioh, NTWOC_PSR, tmp); 459 460 /* reset mcr */ 461 bus_space_write_1(sca->sc_iot, sca->sc_ioh, NTWOC_MCR, 462 NTWOC_MCR_DTR0 | NTWOC_MCR_DTR1 | NTWOC_MCR_TE0 | NTWOC_MCR_TE1); 463 464 465 /* allow for address above 1M and 16 bit i/o */ 466 #if 0 467 bus_space_write_1(sca->sc_iot, sca->sc_ioh, NTWOC_PCR, 468 bus_space_read_1(sca->sc_iot, sca->sc_ioh, NTWOC_PCR) 469 | NTWOC_PCR_EN_VPM | NTWOC_PCR_ISA16); 470 #endif 471 bus_space_write_1(sca->sc_iot, sca->sc_ioh, NTWOC_PCR, 472 bus_space_read_1(sca->sc_iot, sca->sc_ioh, NTWOC_PCR) 473 | NTWOC_PCR_ISA16); 474 475 /* program the card with the io address */ 476 bus_space_write_1(sca->sc_iot, sca->sc_ioh, NTWOC_PCR, 477 ((ia->ia_maddr >> 16) & NTWOC_PCR_16M_SEL) 478 | 479 (bus_space_read_1(sca->sc_iot, sca->sc_ioh, NTWOC_PCR) 480 & ~NTWOC_PCR_16M_SEL)); 481 bus_space_write_1(sca->sc_iot, sca->sc_ioh, NTWOC_BAR, 482 (ia->ia_maddr >> 12)); 483 484 /* enable the memory window */ 485 ntwoc_isa_set_on(sca); 486 487 /* 488 * write a magic value into each possible page of memory 489 * incrementing by our window size 490 */ 491 addr = 0; 492 for (i = 0; i <= NTWOC_PSR_PG_SEL; addr += sca->scu_pagesize, i++) { 493 /* select the page */ 494 ntwoc_isa_set_page(sca, addr); 495 bus_space_write_2(sca->scu_memt, sca->scu_memh, 0, 0xAA55); 496 } 497 498 /* 499 * go back through pages and verify that value is different 500 * after writing to previous page 501 */ 502 addr = 0; 503 for (i = 0; i <= NTWOC_PSR_PG_SEL; addr += sca->scu_pagesize, i++) { 504 ntwoc_isa_set_page(sca, addr); 505 506 tmp = bus_space_read_2(sca->scu_memt, sca->scu_memh, 0); 507 if (tmp != 0xAA55) 508 break; 509 510 /* write a different value into this page now */ 511 bus_space_write_2(sca->scu_memt, sca->scu_memh, 0, i); 512 } 513 sca->scu_npages = pgs = i; /* final count of 16K pages */ 514 515 /* erase the pages */ 516 addr = 0; 517 for (i = 0; i <= pgs; addr += sca->scu_pagesize, i++) { 518 ntwoc_isa_set_page(sca, addr); 519 bus_space_set_region_1(sca->scu_memt, sca->scu_memh, 0, 0, 520 sca->scu_pagesize); 521 } 522 523 #if 0 524 printf("%s: sca port 0x%x-0x%x dpram %ldk %d serial port%s\n", 525 sc->sc_dev.dv_xname, ia->ia_iobase | 0x8000, 526 (ia->ia_iobase | 0x8000) + NTWOC_SRC_ASIC_SIZE - 1, 527 pgs * (sca->scu_pagesize / 1024), sca->sc_numports, 528 (sca->sc_numports > 1 ? "s" : "")); 529 #else 530 printf("%s: dpram %ldk %d serial port%s\n", 531 sc->sc_dev.dv_xname, pgs * (sca->scu_pagesize / 1024), 532 sca->sc_numports, (sca->sc_numports > 1 ? "s" : "")); 533 #endif 534 535 /* disable the memory window */ 536 ntwoc_isa_set_off(sca); 537 538 /* enabled sca dma */ 539 bus_space_write_1(sca->sc_iot, sca->sc_ioh, NTWOC_PSR, 540 bus_space_read_1(sca->sc_iot, sca->sc_ioh, NTWOC_PSR) 541 | NTWOC_PSR_EN_SCA_DMA); 542 543 /* now establish our irq -- perhaps sanity check the value */ 544 sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE, 545 IPL_NET, ntwoc_isa_intr, sc); 546 if (sc->sc_ih == NULL) { 547 printf("%s: can't establish interrupt\n", 548 sc->sc_dev.dv_xname); 549 return; 550 } 551 552 /* make sure we have 2 pages for each port */ 553 if (pgs < 2 * sca->sc_numports) { 554 printf("%s: %d less than required pages of memory of %d\n", 555 sc->sc_dev.dv_xname, pgs, 2 * sca->sc_numports); 556 return; 557 } 558 559 /* sca_get_base_clock(sca); */ 560 561 /* 562 * get clock information from user 563 */ 564 rdiv = (flags & NTWOC_FLAGS_RXDIV_MASK) >> NTWOC_FLAGS_RXDIV_SHIFT; 565 if (rdiv > 9) 566 panic("bad rx divisor in flags"); 567 568 tdiv = (flags & NTWOC_FLAGS_TXDIV_MASK) >> NTWOC_FLAGS_TXDIV_SHIFT; 569 if (tdiv > 9) 570 panic("bad tx divisor in flags"); 571 tmc = (flags & NTWOC_FLAGS_TMC_MASK) >> NTWOC_FLAGS_TMC_SHIFT; 572 573 ntwoc_isa_get_clock(&sca->sc_ports[0], 574 flags & NTWOC_FLAGS_CLK0_MASK, tmc, rdiv, tdiv); 575 if (sca->sc_numports > 1) 576 ntwoc_isa_get_clock(&sca->sc_ports[1], 577 (flags & NTWOC_FLAGS_CLK1_MASK) >> NTWOC_FLAGS_CLK1_SHIFT, 578 tmc, rdiv, tdiv); 579 580 ntwoc_isa_setup_memory(sca); 581 582 sca_init(sca); 583 584 /* attach configured ports */ 585 sca_port_attach(sca, 0); 586 if (sca->sc_numports == 2) 587 sca_port_attach(sca, 1); 588 589 /* 590 * Add shutdown hook so that DMA is disabled prior to reboot. Not 591 * doing do could allow DMA to corrupt kernel memory during the 592 * reboot before the driver initializes. 593 */ 594 shutdownhook_establish(ntwoc_isa_shutdown, sc); 595 596 #if __NetBSD_Version__ >= 104160000 597 /* 598 * defer getting the base clock until interrupts are enabled 599 * (and thus we have microtime()) 600 */ 601 config_interrupts(self, ntwoc_isa_config_interrupts); 602 #else 603 /* no callback pre 1.4-mumble */ 604 sca->sc_baseclock = SCA_BASECLOCK; 605 sca_print_clock_info(&sc->sc_sca); 606 #endif 607 } 608 609 /* 610 * extract the clock information for a port from the flags field 611 */ 612 static void 613 ntwoc_isa_get_clock(struct sca_port *scp, u_int8_t flags, u_int8_t tmc, 614 u_int8_t rdiv, u_int8_t tdiv) 615 { 616 scp->sp_eclock = 617 (flags & NTWOC_FLAGS_ECLOCK_MASK) >> NTWOC_FLAGS_ECLOCK_SHIFT; 618 scp->sp_rxs = rdiv; 619 scp->sp_txs = tdiv; 620 scp->sp_tmc = tmc; 621 622 /* get rx source */ 623 switch ((flags & NTWOC_FLAGS_RXS_MASK) >> NTWOC_FLAGS_RXS_SHIFT) { 624 case NTWOC_FLAGS_RXS_LINE: 625 scp->sp_rxs = 0; 626 break; 627 case NTWOC_FLAGS_RXS_LINE_SN: 628 scp->sp_rxs |= SCA_RXS_CLK_LINE_SN; 629 break; 630 case NTWOC_FLAGS_RXS_INTERNAL: 631 scp->sp_rxs |= SCA_RXS_CLK_INTERNAL; 632 break; 633 case NTWOC_FLAGS_RXS_ADPLL_OUT: 634 scp->sp_rxs |= SCA_RXS_CLK_ADPLL_OUT; 635 break; 636 case NTWOC_FLAGS_RXS_ADPLL_IN: 637 scp->sp_rxs |= SCA_RXS_CLK_ADPLL_IN; 638 break; 639 default: 640 panic("bad rx source in flags"); 641 } 642 643 /* get tx source */ 644 switch ((flags & NTWOC_FLAGS_TXS_MASK) >> NTWOC_FLAGS_TXS_SHIFT) { 645 case NTWOC_FLAGS_TXS_LINE: 646 scp->sp_txs = 0; 647 break; 648 case NTWOC_FLAGS_TXS_INTERNAL: 649 scp->sp_txs |= SCA_TXS_CLK_INTERNAL; 650 break; 651 case NTWOC_FLAGS_TXS_RXCLOCK: 652 scp->sp_txs |= SCA_TXS_CLK_RXCLK; 653 break; 654 default: 655 panic("bad rx source in flags"); 656 } 657 } 658 659 660 static int 661 ntwoc_isa_intr(void *arg) 662 { 663 struct ntwoc_isa_softc *sc = (struct ntwoc_isa_softc *)arg; 664 665 return sca_hardintr(&sc->sc_sca); 666 } 667 668 /* 669 * shut down interrupts and DMA, so we don't trash the kernel on warm 670 * boot. Also, lower DTR on each port and disable card interrupts. 671 */ 672 static void 673 ntwoc_isa_shutdown(void *aux) 674 { 675 struct ntwoc_isa_softc *sc = aux; 676 u_int16_t mcr; 677 678 /* 679 * shut down the SCA ports 680 */ 681 sca_shutdown(&sc->sc_sca); 682 683 /* 684 * lower DTR on both ports 685 */ 686 mcr = bus_space_read_1(sc->sc_sca.sc_iot, sc->sc_sca.sc_ioh, NTWOC_MCR); 687 mcr |= (NTWOC_MCR_DTR0 | NTWOC_MCR_DTR1); 688 bus_space_write_1(sc->sc_sca.sc_iot, sc->sc_sca.sc_ioh, NTWOC_MCR, mcr); 689 } 690 691 static void 692 ntwoc_isa_dtr_callback(void *aux, int port, int state) 693 { 694 struct ntwoc_isa_softc *sc = aux; 695 u_int8_t mcr; 696 697 mcr = bus_space_read_1(sc->sc_sca.sc_iot, sc->sc_sca.sc_ioh, NTWOC_MCR); 698 699 NTWO_DPRINTF(("port == %d, state == %d, old mcr: 0x%02x\n", 700 port, state, mcr)); 701 702 if (port == 0) { 703 if (state == 0) 704 mcr |= NTWOC_MCR_DTR0; 705 else 706 mcr &= ~NTWOC_MCR_DTR0; 707 } else { 708 if (state == 0) 709 mcr |= NTWOC_MCR_DTR1; 710 else 711 mcr &= ~NTWOC_MCR_DTR1; 712 } 713 714 NTWO_DPRINTF(("new mcr: 0x%02x\n", mcr)); 715 716 bus_space_write_1(sc->sc_sca.sc_iot, sc->sc_sca.sc_ioh, NTWOC_MCR, mcr); 717 } 718 719 static void 720 ntwoc_isa_clock_callback(void *aux, int port, int enable) 721 { 722 struct ntwoc_isa_softc *sc = aux; 723 u_int8_t mcr; 724 725 mcr = bus_space_read_1(sc->sc_sca.sc_iot, sc->sc_sca.sc_ioh, NTWOC_MCR); 726 727 NTWO_DPRINTF(("clock: port == %d, enable == %d, old mcr: 0x%02x\n", 728 port, enable, mcr)); 729 730 if (port == 0) { 731 if (enable == 0) 732 mcr &= ~NTWOC_MCR_ETC0; 733 else 734 mcr |= NTWOC_MCR_ETC0; 735 } else { 736 if (enable == 0) 737 mcr &= ~NTWOC_MCR_ETC1; 738 else 739 mcr |= NTWOC_MCR_ETC1; 740 } 741 742 NTWO_DPRINTF(("clock: new mcr: 0x%02x\n", mcr)); 743 744 bus_space_write_1(sc->sc_sca.sc_iot, sc->sc_sca.sc_ioh, NTWOC_MCR, mcr); 745 } 746 747 static void 748 ntwoc_isa_setup_memory(struct sca_softc *sc) 749 { 750 struct sca_port *scp; 751 u_int i, j; 752 753 /* allocate enough descriptors for a full page */ 754 755 sc->sc_ports[0].sp_ntxdesc = (sc->scu_pagesize / SCA_BSIZE) - 1; 756 sc->sc_ports[0].sp_nrxdesc = (sc->scu_pagesize / SCA_BSIZE) - 1; 757 if (sc->sc_numports == 2) { 758 sc->sc_ports[1].sp_ntxdesc = sc->sc_ports[0].sp_ntxdesc; 759 sc->sc_ports[1].sp_nrxdesc = sc->sc_ports[0].sp_nrxdesc; 760 } 761 762 j = 0; 763 for (i = 0; i < sc->sc_numports; i++) { 764 scp = &sc->sc_ports[i]; 765 scp->sp_txdesc_p = (bus_addr_t)(j * sc->scu_pagesize); 766 scp->sp_txdesc = (void *)scp->sp_txdesc_p; 767 scp->sp_txbuf_p = scp->sp_txdesc_p; 768 scp->sp_txbuf_p += SCA_BSIZE; 769 scp->sp_txbuf = (void *)scp->sp_txbuf_p; 770 j++; 771 772 scp->sp_rxdesc_p = (bus_addr_t)(j * sc->scu_pagesize); 773 scp->sp_rxdesc = (void *)scp->sp_txdesc_p; 774 scp->sp_rxbuf_p = scp->sp_rxdesc_p; 775 scp->sp_rxbuf_p += SCA_BSIZE; 776 scp->sp_rxbuf = (void *)scp->sp_rxbuf_p; 777 j++; 778 } 779 } 780 781 #if __NetBSD_Version__ >= 104160000 782 /* 783 * get the base clock frequency 784 */ 785 static void 786 ntwoc_isa_config_interrupts(self) 787 struct device *self; 788 { 789 struct ntwoc_isa_softc *sc; 790 791 sc = (void *)self; 792 sca_get_base_clock(&sc->sc_sca); 793 sca_print_clock_info(&sc->sc_sca); 794 } 795 #endif 796