ixp425_npe.c (186352) | ixp425_npe.c (186420) |
---|---|
1/*- 2 * Copyright (c) 2006-2008 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 43 unchanged lines hidden (view full) --- 52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * SUCH DAMAGE. 58*/ 59#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2006-2008 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 43 unchanged lines hidden (view full) --- 52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * SUCH DAMAGE. 58*/ 59#include <sys/cdefs.h> |
60__FBSDID("$FreeBSD: head/sys/arm/xscale/ixp425/ixp425_npe.c 186352 2008-12-20 03:26:09Z sam $"); | 60__FBSDID("$FreeBSD: head/sys/arm/xscale/ixp425/ixp425_npe.c 186420 2008-12-23 04:51:46Z sam $"); |
61 62/* 63 * Intel XScale Network Processing Engine (NPE) support. 64 * 65 * Each NPE has an ixpnpeX device associated with it that is 66 * attached at boot. Depending on the microcode loaded into 67 * an NPE there may be an Ethernet interface (npeX) or some 68 * other network interface (e.g. for ATM). This file has support --- 38 unchanged lines hidden (view full) --- 107 bus_space_tag_t sc_iot; 108 bus_space_handle_t sc_ioh; 109 bus_size_t sc_size; /* size of mapped register window */ 110 struct resource *sc_irq; /* IRQ resource */ 111 void *sc_ih; /* interrupt handler */ 112 struct mtx sc_mtx; /* mailbox lock */ 113 uint32_t sc_msg[2]; /* reply msg collected in ixpnpe_intr */ 114 int sc_msgwaiting; /* sc_msg holds valid data */ | 61 62/* 63 * Intel XScale Network Processing Engine (NPE) support. 64 * 65 * Each NPE has an ixpnpeX device associated with it that is 66 * attached at boot. Depending on the microcode loaded into 67 * an NPE there may be an Ethernet interface (npeX) or some 68 * other network interface (e.g. for ATM). This file has support --- 38 unchanged lines hidden (view full) --- 107 bus_space_tag_t sc_iot; 108 bus_space_handle_t sc_ioh; 109 bus_size_t sc_size; /* size of mapped register window */ 110 struct resource *sc_irq; /* IRQ resource */ 111 void *sc_ih; /* interrupt handler */ 112 struct mtx sc_mtx; /* mailbox lock */ 113 uint32_t sc_msg[2]; /* reply msg collected in ixpnpe_intr */ 114 int sc_msgwaiting; /* sc_msg holds valid data */ |
115 int sc_npeid; 116 int sc_nrefs; /* # of references */ |
|
115 116 int validImage; /* valid ucode image loaded */ 117 int started; /* NPE is started */ 118 uint8_t functionalityId;/* ucode functionality ID */ 119 int insMemSize; /* size of instruction memory */ 120 int dataMemSize; /* size of data memory */ 121 uint32_t savedExecCount; 122 uint32_t savedEcsDbgCtxtReg2; 123}; | 117 118 int validImage; /* valid ucode image loaded */ 119 int started; /* NPE is started */ 120 uint8_t functionalityId;/* ucode functionality ID */ 121 int insMemSize; /* size of instruction memory */ 122 int dataMemSize; /* size of data memory */ 123 uint32_t savedExecCount; 124 uint32_t savedEcsDbgCtxtReg2; 125}; |
126static struct ixpnpe_softc *npes[NPE_MAX]; |
|
124 125#define IX_NPEDL_NPEIMAGE_FIELD_MASK 0xff 126 127/* used to read download map from version in microcode image */ 128#define IX_NPEDL_BLOCK_TYPE_INSTRUCTION 0x00000000 129#define IX_NPEDL_BLOCK_TYPE_DATA 0x00000001 130#define IX_NPEDL_BLOCK_TYPE_STATE 0x00000002 131#define IX_NPEDL_END_OF_DOWNLOAD_MAP 0x0000000F --- 150 unchanged lines hidden (view full) --- 282 struct ixpnpe_softc *sc; 283 const struct npeconfig *config; 284 int rid; 285 286 if (npeid >= NPE_MAX) { 287 device_printf(dev, "%s: bad npeid %d\n", __func__, npeid); 288 return NULL; 289 } | 127 128#define IX_NPEDL_NPEIMAGE_FIELD_MASK 0xff 129 130/* used to read download map from version in microcode image */ 131#define IX_NPEDL_BLOCK_TYPE_INSTRUCTION 0x00000000 132#define IX_NPEDL_BLOCK_TYPE_DATA 0x00000001 133#define IX_NPEDL_BLOCK_TYPE_STATE 0x00000002 134#define IX_NPEDL_END_OF_DOWNLOAD_MAP 0x0000000F --- 150 unchanged lines hidden (view full) --- 285 struct ixpnpe_softc *sc; 286 const struct npeconfig *config; 287 int rid; 288 289 if (npeid >= NPE_MAX) { 290 device_printf(dev, "%s: bad npeid %d\n", __func__, npeid); 291 return NULL; 292 } |
293 sc = npes[npeid]; 294 if (sc != NULL) { 295 sc->sc_nrefs++; 296 return sc; 297 } |
|
290 config = &npeconfigs[npeid]; 291 292 /* XXX M_BUS */ 293 sc = malloc(sizeof(struct ixpnpe_softc), M_TEMP, M_WAITOK | M_ZERO); 294 sc->sc_dev = dev; 295 sc->sc_iot = sa->sc_iot; 296 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "npe driver", MTX_DEF); | 298 config = &npeconfigs[npeid]; 299 300 /* XXX M_BUS */ 301 sc = malloc(sizeof(struct ixpnpe_softc), M_TEMP, M_WAITOK | M_ZERO); 302 sc->sc_dev = dev; 303 sc->sc_iot = sa->sc_iot; 304 mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "npe driver", MTX_DEF); |
305 sc->sc_npeid = npeid; 306 sc->sc_nrefs = 1; |
|
297 298 sc->sc_size = config->size; 299 sc->insMemSize = config->ins_memsize; /* size of instruction memory */ 300 sc->dataMemSize = config->data_memsize; /* size of data memory */ 301 302 if (bus_space_map(sc->sc_iot, config->base, sc->sc_size, 0, &sc->sc_ioh)) 303 panic("%s: Cannot map registers", device_get_name(dev)); 304 --- 10 unchanged lines hidden (view full) --- 315 bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_NET | INTR_MPSAFE, 316 NULL, ixpnpe_intr, sc, &sc->sc_ih); 317 /* 318 * Enable output fifo interrupts (NB: must also set OFIFO Write Enable) 319 */ 320 npe_reg_write(sc, IX_NPECTL, 321 npe_reg_read(sc, IX_NPECTL) | (IX_NPECTL_OFE | IX_NPECTL_OFWE)); 322 | 307 308 sc->sc_size = config->size; 309 sc->insMemSize = config->ins_memsize; /* size of instruction memory */ 310 sc->dataMemSize = config->data_memsize; /* size of data memory */ 311 312 if (bus_space_map(sc->sc_iot, config->base, sc->sc_size, 0, &sc->sc_ioh)) 313 panic("%s: Cannot map registers", device_get_name(dev)); 314 --- 10 unchanged lines hidden (view full) --- 325 bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_NET | INTR_MPSAFE, 326 NULL, ixpnpe_intr, sc, &sc->sc_ih); 327 /* 328 * Enable output fifo interrupts (NB: must also set OFIFO Write Enable) 329 */ 330 npe_reg_write(sc, IX_NPECTL, 331 npe_reg_read(sc, IX_NPECTL) | (IX_NPECTL_OFE | IX_NPECTL_OFWE)); 332 |
333 npes[npeid] = sc; 334 |
|
323 return sc; 324} 325 326void 327ixpnpe_detach(struct ixpnpe_softc *sc) 328{ | 335 return sc; 336} 337 338void 339ixpnpe_detach(struct ixpnpe_softc *sc) 340{ |
329 /* disable output fifo interrupts */ 330 npe_reg_write(sc, IX_NPECTL, 331 npe_reg_read(sc, IX_NPECTL) &~ (IX_NPECTL_OFE | IX_NPECTL_OFWE)); | 341 if (--sc->sc_nrefs == 0) { 342 npes[sc->sc_npeid] = NULL; |
332 | 343 |
333 bus_teardown_intr(sc->sc_dev, sc->sc_irq, sc->sc_ih); 334 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size); 335 mtx_destroy(&sc->sc_mtx); 336 free(sc, M_TEMP); | 344 /* disable output fifo interrupts */ 345 npe_reg_write(sc, IX_NPECTL, 346 npe_reg_read(sc, IX_NPECTL) &~ (IX_NPECTL_OFE | IX_NPECTL_OFWE)); 347 348 bus_teardown_intr(sc->sc_dev, sc->sc_irq, sc->sc_ih); 349 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size); 350 mtx_destroy(&sc->sc_mtx); 351 free(sc, M_TEMP); 352 } |
337} 338 339int 340ixpnpe_stopandreset(struct ixpnpe_softc *sc) 341{ 342 int error; 343 344 mtx_lock(&sc->sc_mtx); --- 11 unchanged lines hidden (view full) --- 356static int 357ixpnpe_start_locked(struct ixpnpe_softc *sc) 358{ 359 int error; 360 361 if (!sc->started) { 362 error = npe_cpu_start(sc); 363 if (error == 0) | 353} 354 355int 356ixpnpe_stopandreset(struct ixpnpe_softc *sc) 357{ 358 int error; 359 360 mtx_lock(&sc->sc_mtx); --- 11 unchanged lines hidden (view full) --- 372static int 373ixpnpe_start_locked(struct ixpnpe_softc *sc) 374{ 375 int error; 376 377 if (!sc->started) { 378 error = npe_cpu_start(sc); 379 if (error == 0) |
364 sc->started = 1; | 380 sc->started = 1; |
365 } else 366 error = 0; 367 368 DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error); 369 return error; 370} 371 372int --- 64 unchanged lines hidden (view full) --- 437 /* reached end of library, image not found */ 438 return ESRCH; 439 } 440 offset += image->size; 441 } 442 return ESRCH; 443} 444 | 381 } else 382 error = 0; 383 384 DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error); 385 return error; 386} 387 388int --- 64 unchanged lines hidden (view full) --- 453 /* reached end of library, image not found */ 454 return ESRCH; 455 } 456 offset += image->size; 457 } 458 return ESRCH; 459} 460 |
445int 446ixpnpe_init(struct ixpnpe_softc *sc, const char *imageName, uint32_t imageId) | 461static int 462ixpnpe_load_firmware(struct ixpnpe_softc *sc, const char *imageName, 463 uint32_t imageId) |
447{ 448 static const char *devname[4] = 449 { "IXP425", "IXP435/IXP465", "DeviceID#2", "DeviceID#3" }; 450 uint32_t imageSize; 451 const uint32_t *imageCodePtr; 452 const struct firmware *fw; 453 int error; 454 --- 44 unchanged lines hidden (view full) --- 499 sc->functionalityId = IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId); 500 mtx_unlock(&sc->sc_mtx); 501done: 502 firmware_put(fw, FIRMWARE_UNLOAD); 503 DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error); 504 return error; 505} 506 | 464{ 465 static const char *devname[4] = 466 { "IXP425", "IXP435/IXP465", "DeviceID#2", "DeviceID#3" }; 467 uint32_t imageSize; 468 const uint32_t *imageCodePtr; 469 const struct firmware *fw; 470 int error; 471 --- 44 unchanged lines hidden (view full) --- 516 sc->functionalityId = IX_NPEDL_FUNCTIONID_FROM_IMAGEID_GET(imageId); 517 mtx_unlock(&sc->sc_mtx); 518done: 519 firmware_put(fw, FIRMWARE_UNLOAD); 520 DPRINTF(sc->sc_dev, "%s: error %d\n", __func__, error); 521 return error; 522} 523 |
524static int 525override_imageid(device_t dev, const char *resname, uint32_t *val) 526{ 527 int unit = device_get_unit(dev); 528 int resval; 529 530 if (resource_int_value("npe", unit, resname, &resval) != 0) 531 return 0; 532 /* XXX validate */ 533 if (bootverbose) 534 device_printf(dev, "using npe.%d.%s=0x%x override\n", 535 unit, resname, resval); 536 *val = resval; 537 return 1; 538} 539 |
|
507int | 540int |
541ixpnpe_init(struct ixpnpe_softc *sc) 542{ 543 static const uint32_t npeconfig[NPE_MAX] = { 544 [NPE_A] = IXP425_NPE_A_IMAGEID, 545 [NPE_B] = IXP425_NPE_B_IMAGEID, 546 [NPE_C] = IXP425_NPE_C_IMAGEID, 547 }; 548 uint32_t imageid, msg[2]; 549 int error; 550 551 if (sc->started) 552 return 0; 553 /* 554 * Load NPE firmware and start it running. We assume 555 * that minor version bumps remain compatible so probe 556 * the firmware image starting with the expected version 557 * and then bump the minor version up to the max. 558 */ 559 if (!override_imageid(sc->sc_dev, "imageid", &imageid)) 560 imageid = npeconfig[sc->sc_npeid]; 561 for (;;) { 562 error = ixpnpe_load_firmware(sc, "npe_fw", imageid); 563 if (error == 0) 564 break; 565 /* 566 * ESRCH is returned when the requested image 567 * is not present 568 */ 569 if (error != ESRCH) { 570 device_printf(sc->sc_dev, 571 "cannot init NPE (error %d)\n", error); 572 return error; 573 } 574 /* bump the minor version up to the max possible */ 575 if (NPEIMAGE_MINOR(imageid) == 0xff) { 576 device_printf(sc->sc_dev, "cannot locate firmware " 577 "(imageid 0x%08x)\n", imageid); 578 return error; 579 } 580 imageid++; 581 } 582 /* NB: firmware should respond with a status msg */ 583 if (ixpnpe_recvmsg_sync(sc, msg) != 0) { 584 device_printf(sc->sc_dev, 585 "firmware did not respond as expected\n"); 586 return EIO; 587 } 588 return 0; 589} 590 591int |
|
508ixpnpe_getfunctionality(struct ixpnpe_softc *sc) 509{ 510 return (sc->validImage ? sc->functionalityId : 0); 511} 512 513static int 514npe_checkbits(struct ixpnpe_softc *sc, uint32_t reg, uint32_t expectedBitsSet) 515{ --- 974 unchanged lines hidden --- | 592ixpnpe_getfunctionality(struct ixpnpe_softc *sc) 593{ 594 return (sc->validImage ? sc->functionalityId : 0); 595} 596 597static int 598npe_checkbits(struct ixpnpe_softc *sc, uint32_t reg, uint32_t expectedBitsSet) 599{ --- 974 unchanged lines hidden --- |