Deleted Added
full compact
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 ---