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