1 /* $NetBSD: if_ie_gsc.c,v 1.5 2020/04/15 15:50:15 skrll Exp $ */ 2 3 /* $OpenBSD: if_ie_gsc.c,v 1.6 2001/01/12 22:57:04 mickey Exp $ */ 4 5 /* 6 * Copyright (c) 1998-2004 Michael Shalayeff 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 /* 32 * Referencies: 33 * 1. 82596DX and 82596SX High-Performance 32-bit Local Area Network Coprocessor 34 * Intel Corporation, November 1996, Order Number: 290219-006 35 * 36 * 2. 712 I/O Subsystem ERS Rev 1.0 37 * Hewlett-Packard, June 17 1992, Dwg No. A-A2263-66510-31 38 */ 39 40 #include <sys/cdefs.h> 41 __KERNEL_RCSID(0, "$NetBSD: if_ie_gsc.c,v 1.5 2020/04/15 15:50:15 skrll Exp $"); 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/device.h> 46 #include <sys/socket.h> 47 #include <sys/sockio.h> 48 49 #include <uvm/uvm_extern.h> 50 51 #include <net/if.h> 52 #include <net/if_dl.h> 53 #include <net/if_ether.h> 54 #include <net/if_types.h> 55 #include <net/if_media.h> 56 57 #include <netinet/in.h> 58 59 #include <sys/bus.h> 60 #include <machine/intr.h> 61 #include <machine/iomod.h> 62 #include <machine/autoconf.h> 63 64 #include <hppa/dev/cpudevs.h> 65 #include <hppa/gsc/gscbusvar.h> 66 #include <hppa/hppa/machdep.h> 67 68 #include <dev/ic/i82586reg.h> 69 #include <dev/ic/i82586var.h> 70 71 #define I82596_DEBUG I82586_DEBUG 72 73 #ifdef __for_reference_only 74 struct ie_gsc_regs { 75 uint32_t ie_reset; 76 uint32_t ie_port; 77 uint32_t ie_attn; 78 }; 79 #endif 80 81 #define IE_GSC_BANK_SZ (12) 82 #define IE_GSC_REG_RESET (0) 83 #define IE_GSC_REG_PORT (4) 84 #define IE_GSC_REG_ATTN (8) 85 86 #define IE_GSC_ALIGN(v) ((((u_int) (v)) + 0xf) & ~0xf) 87 88 #define IE_GSC_SYSBUS (IE_SYSBUS_596_RSVD_SET | \ 89 IE_SYSBUS_596_82586 | \ 90 IE_SYSBUS_596_INTLOW | \ 91 IE_SYSBUS_596_TRGEXT | \ 92 IE_SYSBUS_596_BE) 93 94 #define IE_SIZE 0x8000 95 96 struct ie_gsc_softc { 97 struct ie_softc ie; 98 99 /* tag and handle to hppa-specific adapter registers. */ 100 bus_space_tag_t iot; 101 bus_space_handle_t ioh; 102 103 /* bus_dma_tag_t for the memory used by the adapter. */ 104 bus_dma_tag_t iemt; 105 106 /* interrupt handle. */ 107 void *sc_ih; 108 109 /* miscellaneous flags. */ 110 int flags; 111 #define IEGSC_GECKO (1 << 0) 112 }; 113 114 int ie_gsc_probe(device_t, cfdata_t, void *); 115 void ie_gsc_attach(device_t, device_t, void *); 116 117 CFATTACH_DECL_NEW(ie_gsc, sizeof(struct ie_gsc_softc), 118 ie_gsc_probe, ie_gsc_attach, NULL, NULL); 119 120 static int ie_gsc_media[] = { 121 IFM_ETHER | IFM_10_2, 122 }; 123 #define IE_NMEDIA __arraycount(ie_gsc_media) 124 125 void ie_gsc_reset(struct ie_softc *, int); 126 void ie_gsc_attend(struct ie_softc *, int); 127 void ie_gsc_run(struct ie_softc *); 128 void ie_gsc_port(struct ie_softc *, u_int); 129 uint16_t ie_gsc_read16(struct ie_softc *, int); 130 void ie_gsc_write16(struct ie_softc *, int, uint16_t); 131 void ie_gsc_write24(struct ie_softc *, int, int); 132 void ie_gsc_memcopyin(struct ie_softc *, void *, int, size_t); 133 void ie_gsc_memcopyout(struct ie_softc *, const void *, int, size_t); 134 135 136 /* Reset the adapter. */ 137 void 138 ie_gsc_reset(struct ie_softc *sc, int what) 139 { 140 struct ie_gsc_softc *gsc = (struct ie_gsc_softc *)sc; 141 int i; 142 143 switch (what) { 144 case CHIP_PROBE: 145 bus_space_write_4(gsc->iot, gsc->ioh, IE_GSC_REG_RESET, 0); 146 break; 147 148 case CARD_RESET: 149 bus_space_write_4(gsc->iot, gsc->ioh, IE_GSC_REG_RESET, 0); 150 151 /* 152 * Per [2] 4.6.2.1 153 * delay for 10 system clocks + 5 transmit clocks, 154 * NB: works for system clocks over 10MHz 155 */ 156 DELAY(1000); 157 158 /* 159 * After the hardware reset: 160 * inform i825[89]6 about new SCP address, 161 * which must be at least 16-byte aligned 162 */ 163 ie_gsc_port(sc, IE_PORT_ALT_SCP); 164 ie_gsc_attend(sc, what); 165 166 for (i = 9000; i-- && ie_gsc_read16(sc, IE_ISCP_BUSY(sc->iscp)); 167 DELAY(100)) 168 pdcache(0, (vaddr_t)sc->sc_maddr + sc->iscp, 169 IE_ISCP_SZ); 170 171 #if I82596_DEBUG 172 if (i < 0) { 173 printf("timeout for PORT command (%x)%s\n", 174 ie_gsc_read16(sc, IE_ISCP_BUSY(sc->iscp)), 175 (gsc->flags & IEGSC_GECKO)? " on gecko":""); 176 return; 177 } 178 #endif 179 break; 180 } 181 } 182 183 /* Do a channel attention on the adapter. */ 184 void 185 ie_gsc_attend(struct ie_softc *sc, int why) 186 { 187 struct ie_gsc_softc *gsc = (struct ie_gsc_softc *)sc; 188 189 bus_space_write_4(gsc->iot, gsc->ioh, IE_GSC_REG_ATTN, 0); 190 } 191 192 /* Enable the adapter. */ 193 void 194 ie_gsc_run(struct ie_softc *sc) 195 { 196 } 197 198 /* Run an i82596 PORT command on the adapter. */ 199 void 200 ie_gsc_port(struct ie_softc *sc, u_int cmd) 201 { 202 struct ie_gsc_softc *gsc = (struct ie_gsc_softc *)sc; 203 204 switch (cmd) { 205 case IE_PORT_RESET: 206 case IE_PORT_DUMP: 207 break; 208 case IE_PORT_SELF_TEST: 209 cmd |= (sc->sc_dmamap->dm_segs[0].ds_addr + 0); 210 break; 211 case IE_PORT_ALT_SCP: 212 cmd |= (sc->sc_dmamap->dm_segs[0].ds_addr + sc->scp); 213 break; 214 } 215 216 if (gsc->flags & IEGSC_GECKO) { 217 bus_space_write_4(gsc->iot, gsc->ioh, 218 IE_GSC_REG_PORT, (cmd & 0xffff)); 219 DELAY(1000); 220 bus_space_write_4(gsc->iot, gsc->ioh, 221 IE_GSC_REG_PORT, (cmd >> 16)); 222 DELAY(1000); 223 } else { 224 bus_space_write_4(gsc->iot, gsc->ioh, 225 IE_GSC_REG_PORT, (cmd >> 16)); 226 DELAY(1000); 227 bus_space_write_4(gsc->iot, gsc->ioh, 228 IE_GSC_REG_PORT, (cmd & 0xffff)); 229 DELAY(1000); 230 } 231 } 232 233 uint16_t 234 ie_gsc_read16(struct ie_softc *sc, int offset) 235 { 236 uint16_t val; 237 238 __asm volatile( 239 " ldh 0(%1), %0 \n" 240 " fdc %%r0(%1) \n" 241 : "=&r" (val) 242 : "r" ((char *)sc->sc_maddr + offset)); 243 return val; 244 } 245 246 void 247 ie_gsc_write16(struct ie_softc *sc, int offset, uint16_t v) 248 { 249 250 __asm volatile( 251 " sth %0, 0(%1) \n" 252 " fdc %%r0(%1) \n" 253 : /* no outputs */ 254 : "r" (v), "r" ((char *)sc->sc_maddr + offset)); 255 } 256 257 void 258 ie_gsc_write24(struct ie_softc *sc, int offset, int addr) 259 { 260 261 /* 262 * i82586.c assumes that the chip address space starts at 263 * zero, so we have to add in the appropriate offset here. 264 */ 265 addr += sc->sc_dmamap->dm_segs[0].ds_addr; 266 __asm volatile( 267 " ldi 2, %%r21 \n" 268 " extru %0, 15, 16, %%r22 \n" 269 " sth %0, 0(%1) \n" 270 " sth %%r22, 2(%1) \n" 271 " fdc %%r0(%1) \n" 272 " fdc %%r21(%1) \n" 273 : /* No outputs */ 274 : "r" (addr), "r" ((char *)sc->sc_maddr + offset) 275 : "r21", "r22"); 276 } 277 278 void 279 ie_gsc_memcopyin(struct ie_softc *sc, void *p, int offset, size_t size) 280 { 281 struct ie_gsc_softc *gsc = (struct ie_gsc_softc *)sc; 282 283 if (size == 0) 284 return; 285 286 memcpy(p, (char *)sc->sc_maddr + offset, size); 287 bus_dmamap_sync(gsc->iemt, sc->sc_dmamap, offset, size, 288 BUS_DMASYNC_PREREAD); 289 hppa_led_blink(HPPA_LED_NETRCV); 290 } 291 292 void 293 ie_gsc_memcopyout(struct ie_softc *sc, const void *p, int offset, size_t size) 294 { 295 struct ie_gsc_softc *gsc = (struct ie_gsc_softc *)sc; 296 297 if (size == 0) 298 return; 299 300 memcpy((char *)sc->sc_maddr + offset, p, size); 301 bus_dmamap_sync(gsc->iemt, sc->sc_dmamap, offset, size, 302 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 303 hppa_led_blink(HPPA_LED_NETSND); 304 } 305 306 /* 307 * i82596 probe routine 308 */ 309 int i82596_probe(struct ie_softc *); 310 int 311 i82596_probe(struct ie_softc *sc) 312 { 313 struct ie_gsc_softc *gsc = (struct ie_gsc_softc *)sc; 314 int i; 315 316 /* Set up the SCP. */ 317 sc->ie_bus_write16(sc, IE_SCP_BUS_USE(sc->scp), IE_GSC_SYSBUS); 318 sc->ie_bus_write24(sc, IE_SCP_ISCP(sc->scp), sc->iscp); 319 320 /* Set up the ISCP. */ 321 sc->ie_bus_write16(sc, IE_ISCP_SCB(sc->iscp), sc->scb); 322 sc->ie_bus_write24(sc, IE_ISCP_BASE(sc->iscp), 0); 323 324 /* Set BUSY in the ISCP. */ 325 sc->ie_bus_write16(sc, IE_ISCP_BUSY(sc->iscp), 1); 326 327 /* Reset the adapter. */ 328 bus_dmamap_sync(gsc->iemt, sc->sc_dmamap, 0, sc->sc_msize, 329 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 330 sc->hwreset(sc, CARD_RESET); 331 332 /* Make sure that BUSY got cleared. */ 333 if (sc->ie_bus_read16(sc, IE_ISCP_BUSY(sc->iscp))) { 334 #if I82596_DEBUG 335 printf ("%s: ISCP set failed\n", device_xname(sc->sc_dev)); 336 #endif 337 return 0; 338 } 339 340 /* Run the chip self-test. */ 341 sc->ie_bus_write24(sc, 0, -sc->sc_dmamap->dm_segs[0].ds_addr); 342 sc->ie_bus_write24(sc, 4, -(sc->sc_dmamap->dm_segs[0].ds_addr + 1)); 343 bus_dmamap_sync(gsc->iemt, sc->sc_dmamap, 0, sc->sc_msize, 344 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 345 ie_gsc_port(sc, IE_PORT_SELF_TEST); 346 for (i = 9000; i-- && sc->ie_bus_read16(sc, 4); DELAY(100)) 347 pdcache(0, (vaddr_t)sc->sc_maddr, sc->sc_msize); 348 349 #if I82596_DEBUG 350 printf (": test %x:%x\n%s", 351 *((volatile int32_t *)((char *)sc->sc_maddr + 0)), 352 *((volatile int32_t *)((char *)sc->sc_maddr + 4)), 353 device_xname(sc->sc_dev)); 354 #endif 355 return 1; 356 } 357 358 int 359 ie_gsc_probe(device_t parent, cfdata_t match, void *aux) 360 { 361 struct gsc_attach_args *ga = aux; 362 363 if (ga->ga_type.iodc_type != HPPA_TYPE_FIO || 364 (ga->ga_type.iodc_sv_model != HPPA_FIO_LAN && 365 ga->ga_type.iodc_sv_model != HPPA_FIO_GLAN)) 366 return 0; 367 368 return 1; 369 } 370 371 void 372 ie_gsc_attach(device_t parent, device_t self, void *aux) 373 { 374 struct ie_gsc_softc *gsc = device_private(self); 375 struct ie_softc *sc = &gsc->ie; 376 struct gsc_attach_args *ga = aux; 377 bus_dma_segment_t seg; 378 int rseg; 379 int rv; 380 uint8_t myaddr[ETHER_ADDR_LEN]; 381 382 if (ga->ga_type.iodc_sv_model == HPPA_FIO_GLAN) 383 gsc->flags |= IEGSC_GECKO; 384 385 /* Map the GSC registers. */ 386 if (bus_space_map(ga->ga_iot, ga->ga_hpa, 387 IE_GSC_BANK_SZ, 0, &gsc->ioh)) { 388 printf(": can't map i/o space\n"); 389 return; 390 } 391 392 /* Set up some initial glue. */ 393 sc->sc_dev = self; 394 gsc->iot = ga->ga_iot; 395 gsc->iemt = ga->ga_dmatag; 396 sc->bt = ga->ga_iot; 397 sc->sc_msize = IE_SIZE; 398 399 /* 400 * Allocate one contiguous segment of physical memory 401 * to be used with the i82596. Since we're running the 402 * chip in i82586 mode, we're restricted to 24-bit 403 * physical addresses. 404 */ 405 if (bus_dmamem_alloc(gsc->iemt, sc->sc_msize, PAGE_SIZE, 0, 406 &seg, 1, &rseg, BUS_DMA_NOWAIT | BUS_DMA_24BIT)) { 407 printf (": can't allocate %d bytes of DMA memory\n", 408 sc->sc_msize); 409 return; 410 } 411 412 /* Map that physical memory into kernel virtual space. */ 413 if (bus_dmamem_map(gsc->iemt, &seg, rseg, sc->sc_msize, 414 (void **)&sc->sc_maddr, BUS_DMA_NOWAIT)) { 415 printf (": can't map DMA memory\n"); 416 bus_dmamem_free(gsc->iemt, &seg, rseg); 417 return; 418 } 419 420 /* Create a DMA map for the memory. */ 421 if (bus_dmamap_create(gsc->iemt, sc->sc_msize, rseg, sc->sc_msize, 422 0, BUS_DMA_NOWAIT, &sc->sc_dmamap)) { 423 printf(": can't create DMA map\n"); 424 bus_dmamem_unmap(gsc->iemt, 425 (void *)sc->sc_maddr, sc->sc_msize); 426 bus_dmamem_free(gsc->iemt, &seg, rseg); 427 return; 428 } 429 430 /* Load the mapped DMA memory into the DMA map. */ 431 if (bus_dmamap_load(gsc->iemt, sc->sc_dmamap, sc->sc_maddr, 432 sc->sc_msize, NULL, BUS_DMA_NOWAIT)) { 433 printf(": can't load DMA map\n"); 434 bus_dmamap_destroy(gsc->iemt, sc->sc_dmamap); 435 bus_dmamem_unmap(gsc->iemt, 436 (void *)sc->sc_maddr, sc->sc_msize); 437 bus_dmamem_free(gsc->iemt, &seg, rseg); 438 return; 439 } 440 441 #if 1 442 /* XXX - this should go away. */ 443 sc->bh = (bus_space_handle_t)sc->sc_maddr; 444 #endif 445 446 #if I82596_DEBUG 447 printf(" mem %x[%p]/%x\n%s", 448 (u_int)sc->sc_dmamap->dm_segs[0].ds_addr, 449 sc->sc_maddr, 450 sc->sc_msize, 451 device_xname(self)); 452 sc->sc_debug = IED_ALL; 453 #endif 454 455 /* Initialize our bus glue. */ 456 sc->hwreset = ie_gsc_reset; 457 sc->chan_attn = ie_gsc_attend; 458 sc->hwinit = ie_gsc_run; 459 sc->memcopyout = ie_gsc_memcopyout; 460 sc->memcopyin = ie_gsc_memcopyin; 461 sc->ie_bus_read16 = ie_gsc_read16; 462 sc->ie_bus_write16 = ie_gsc_write16; 463 sc->ie_bus_write24 = ie_gsc_write24; 464 sc->intrhook = NULL; 465 466 /* Clear all RAM. */ 467 memset(sc->sc_maddr, 0, sc->sc_msize); 468 bus_dmamap_sync(gsc->iemt, sc->sc_dmamap, 0, sc->sc_msize, 469 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 470 471 /* 472 * We use low memory to set up SCP, ICSP and SCB data 473 * structures. The remaining pages become the buffer area 474 * (managed in i82586.c). 475 */ 476 477 /* 478 * Since we have an i82596, we can control where where 479 * the chip looks for SCP. We plan to use the first 480 * two 32-bit words of memory for the self-test, so the 481 * SCP can go after that. 482 */ 483 sc->scp = IE_GSC_ALIGN(8); 484 485 /* ISCP follows SCP */ 486 sc->iscp = IE_GSC_ALIGN(sc->scp + IE_SCP_SZ); 487 488 /* SCB follows ISCP */ 489 sc->scb = IE_GSC_ALIGN(sc->iscp + IE_ISCP_SZ); 490 491 /* The remainder of the memory is for buffers. */ 492 sc->buf_area = IE_GSC_ALIGN(sc->scb + IE_SCB_SZ); 493 sc->buf_area_sz = sc->sc_msize - sc->buf_area; 494 495 /* Finally, we can probe the chip. */ 496 rv = i82596_probe(sc); 497 if (!rv) { 498 bus_dmamap_destroy(gsc->iemt, sc->sc_dmamap); 499 bus_dmamem_unmap(gsc->iemt, 500 (void *)sc->sc_maddr, sc->sc_msize); 501 bus_dmamem_free(gsc->iemt, &seg, rseg); 502 return; 503 } 504 if (!rv) 505 return; 506 507 /* Get our Ethernet address. */ 508 memcpy(myaddr, ga->ga_ether_address, ETHER_ADDR_LEN); 509 510 /* Set up the SCP. */ 511 sc->ie_bus_write16(sc, IE_SCP_BUS_USE(sc->scp), IE_GSC_SYSBUS); 512 sc->ie_bus_write24(sc, IE_SCP_ISCP(sc->scp), sc->iscp); 513 514 /* Set up the ISCP. */ 515 sc->ie_bus_write16(sc, IE_ISCP_SCB(sc->iscp), sc->scb); 516 sc->ie_bus_write24(sc, IE_ISCP_BASE(sc->iscp), 0); 517 518 /* Set BUSY in the ISCP. */ 519 sc->ie_bus_write16(sc, IE_ISCP_BUSY(sc->iscp), 1); 520 521 /* Reset the adapter. */ 522 bus_dmamap_sync(gsc->iemt, sc->sc_dmamap, 0, sc->sc_msize, 523 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 524 sc->hwreset(sc, CARD_RESET); 525 bus_dmamap_sync(gsc->iemt, sc->sc_dmamap, 0, sc->sc_msize, 526 BUS_DMASYNC_PREREAD); 527 528 /* Now call the MI attachment. */ 529 printf(": v%d.%d", ga->ga_type.iodc_model, ga->ga_type.iodc_sv_rev); 530 i82586_attach(sc, 531 (gsc->flags & IEGSC_GECKO) ? 532 "LASI/i82596CA" : 533 "i82596DX", 534 myaddr, ie_gsc_media, IE_NMEDIA, ie_gsc_media[0]); 535 gsc->sc_ih = hppa_intr_establish(IPL_NET, i82586_intr, sc, 536 ga->ga_ir, ga->ga_irq); 537 } 538