git: 4cd966142822 - main - dpaa2: Avoid dpaa2_cmd race conditions
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 19 Apr 2023 15:50:14 UTC
The branch main has been updated by dsl: URL: https://cgit.FreeBSD.org/src/commit/?id=4cd966142822ce24c12751c863a073a8b7cb9c14 commit 4cd966142822ce24c12751c863a073a8b7cb9c14 Author: Dmitry Salychev <dsl@FreeBSD.org> AuthorDate: 2023-04-07 18:10:17 +0000 Commit: Dmitry Salychev <dsl@FreeBSD.org> CommitDate: 2023-04-19 15:39:05 +0000 dpaa2: Avoid dpaa2_cmd race conditions struct dpaa2_cmd is no longer malloc'ed, but can be allocated on stack and initialized with DPAA2_CMD_INIT() on demand. Drivers stopped caching their DPAA2 command objects (and associated tokens) in the software contexts in order to avoid using them concurrently. Reviewed by: bz Approved by: bz (mentor) MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D39509 --- sys/dev/dpaa2/dpaa2_bp.c | 86 ++-- sys/dev/dpaa2/dpaa2_bp.h | 6 - sys/dev/dpaa2/dpaa2_con.c | 77 ++- sys/dev/dpaa2/dpaa2_con.h | 5 - sys/dev/dpaa2/dpaa2_io.c | 98 ++-- sys/dev/dpaa2/dpaa2_io.h | 5 - sys/dev/dpaa2/dpaa2_mac.c | 178 ++++--- sys/dev/dpaa2/dpaa2_mac.h | 6 - sys/dev/dpaa2/dpaa2_mcp.c | 116 ++--- sys/dev/dpaa2/dpaa2_mcp.h | 32 +- sys/dev/dpaa2/dpaa2_ni.c | 1181 +++++++++++++++++++++++++++++++++------------ sys/dev/dpaa2/dpaa2_ni.h | 5 - sys/dev/dpaa2/dpaa2_rc.c | 97 ++-- 13 files changed, 1224 insertions(+), 668 deletions(-) diff --git a/sys/dev/dpaa2/dpaa2_bp.c b/sys/dev/dpaa2/dpaa2_bp.c index 78e1ca68cdb1..51f708422257 100644 --- a/sys/dev/dpaa2/dpaa2_bp.c +++ b/sys/dev/dpaa2/dpaa2_bp.c @@ -87,25 +87,42 @@ dpaa2_bp_probe(device_t dev) static int dpaa2_bp_detach(device_t dev) { + device_t pdev = device_get_parent(dev); device_t child = dev; struct dpaa2_bp_softc *sc = device_get_softc(dev); + struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev); struct dpaa2_devinfo *dinfo = device_get_ivars(dev); + struct dpaa2_cmd cmd; + uint16_t rc_token, bp_token; + int error; - if (sc->cmd != NULL) { - (void)DPAA2_CMD_BP_DISABLE(dev, child, sc->cmd); - (void)DPAA2_CMD_BP_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, - sc->bp_token)); - (void)DPAA2_CMD_RC_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, - sc->rc_token)); + DPAA2_CMD_INIT(&cmd); - dpaa2_mcp_free_command(sc->cmd); - sc->cmd = NULL; + error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token); + if (error) { + device_printf(dev, "%s: failed to open DPRC: error=%d\n", + __func__, error); + goto err_exit; } + error = DPAA2_CMD_BP_OPEN(dev, child, &cmd, dinfo->id, &bp_token); + if (error) { + device_printf(dev, "%s: failed to open DPBP: id=%d, error=%d\n", + __func__, dinfo->id, error); + goto close_rc; + } + (void)DPAA2_CMD_BP_DISABLE(dev, child, &cmd); + (void)DPAA2_CMD_BP_CLOSE(dev, child, &cmd); + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); dinfo->portal = NULL; bus_release_resources(sc->dev, dpaa2_bp_spec, sc->res); return (0); + +close_rc: + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); +err_exit: + return (ENXIO); } static int @@ -118,16 +135,17 @@ dpaa2_bp_attach(device_t dev) struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev); struct dpaa2_devinfo *dinfo = device_get_ivars(dev); struct dpaa2_devinfo *mcp_dinfo; + struct dpaa2_cmd cmd; + uint16_t rc_token, bp_token; int error; sc->dev = dev; - sc->cmd = NULL; error = bus_alloc_resources(sc->dev, dpaa2_bp_spec, sc->res); if (error) { device_printf(dev, "%s: failed to allocate resources: " "error=%d\n", __func__, error); - return (ENXIO); + goto err_exit; } /* Send commands to MC via allocated portal. */ @@ -135,56 +153,52 @@ dpaa2_bp_attach(device_t dev) mcp_dinfo = device_get_ivars(mcp_dev); dinfo->portal = mcp_dinfo->portal; - /* Allocate a command to send to MC hardware. */ - error = dpaa2_mcp_init_command(&sc->cmd, DPAA2_CMD_DEF); - if (error) { - device_printf(dev, "%s: failed to allocate dpaa2_cmd: " - "error=%d\n", __func__, error); - dpaa2_bp_detach(dev); - return (ENXIO); - } + DPAA2_CMD_INIT(&cmd); - /* Open resource container and DPBP object. */ - error = DPAA2_CMD_RC_OPEN(dev, child, sc->cmd, rcinfo->id, - &sc->rc_token); + error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token); if (error) { device_printf(dev, "%s: failed to open DPRC: error=%d\n", __func__, error); - dpaa2_bp_detach(dev); - return (ENXIO); + goto detach; } - error = DPAA2_CMD_BP_OPEN(dev, child, sc->cmd, dinfo->id, &sc->bp_token); + error = DPAA2_CMD_BP_OPEN(dev, child, &cmd, dinfo->id, &bp_token); if (error) { device_printf(dev, "%s: failed to open DPBP: id=%d, error=%d\n", __func__, dinfo->id, error); - dpaa2_bp_detach(dev); - return (ENXIO); + goto close_rc; } - /* Prepare DPBP object. */ - error = DPAA2_CMD_BP_RESET(dev, child, sc->cmd); + error = DPAA2_CMD_BP_RESET(dev, child, &cmd); if (error) { device_printf(dev, "%s: failed to reset DPBP: id=%d, error=%d\n", __func__, dinfo->id, error); - dpaa2_bp_detach(dev); - return (ENXIO); + goto close_bp; } - error = DPAA2_CMD_BP_ENABLE(dev, child, sc->cmd); + error = DPAA2_CMD_BP_ENABLE(dev, child, &cmd); if (error) { device_printf(dev, "%s: failed to enable DPBP: id=%d, " "error=%d\n", __func__, dinfo->id, error); - dpaa2_bp_detach(dev); - return (ENXIO); + goto close_bp; } - error = DPAA2_CMD_BP_GET_ATTRIBUTES(dev, child, sc->cmd, &sc->attr); + error = DPAA2_CMD_BP_GET_ATTRIBUTES(dev, child, &cmd, &sc->attr); if (error) { device_printf(dev, "%s: failed to get DPBP attributes: id=%d, " "error=%d\n", __func__, dinfo->id, error); - dpaa2_bp_detach(dev); - return (ENXIO); + goto close_bp; } + (void)DPAA2_CMD_BP_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, bp_token)); + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); return (0); + +close_bp: + (void)DPAA2_CMD_BP_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, bp_token)); +close_rc: + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); +detach: + dpaa2_bp_detach(dev); +err_exit: + return (ENXIO); } static device_method_t dpaa2_bp_methods[] = { diff --git a/sys/dev/dpaa2/dpaa2_bp.h b/sys/dev/dpaa2/dpaa2_bp.h index 3ba7196eb030..d05cb399cc17 100644 --- a/sys/dev/dpaa2/dpaa2_bp.h +++ b/sys/dev/dpaa2/dpaa2_bp.h @@ -60,12 +60,6 @@ struct dpaa2_bp_conf { struct dpaa2_bp_softc { device_t dev; struct dpaa2_bp_attr attr; - - /* Help to send commands to MC. */ - struct dpaa2_cmd *cmd; - uint16_t rc_token; - uint16_t bp_token; - struct resource *res[DPAA2_BP_MAX_RESOURCES]; }; diff --git a/sys/dev/dpaa2/dpaa2_con.c b/sys/dev/dpaa2/dpaa2_con.c index 602497c2c8de..993cdb2fe29d 100644 --- a/sys/dev/dpaa2/dpaa2_con.c +++ b/sys/dev/dpaa2/dpaa2_con.c @@ -101,17 +101,7 @@ dpaa2_con_probe(device_t dev) static int dpaa2_con_detach(device_t dev) { - device_t child = dev; - struct dpaa2_con_softc *sc = device_get_softc(dev); - - DPAA2_CMD_CON_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->con_token)); - DPAA2_CMD_RC_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->rc_token)); - dpaa2_mcp_free_command(sc->cmd); - - sc->cmd = NULL; - sc->con_token = 0; - sc->rc_token = 0; - + /* TBD */ return (0); } @@ -125,6 +115,8 @@ dpaa2_con_attach(device_t dev) struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev); struct dpaa2_devinfo *dinfo = device_get_ivars(dev); struct dpaa2_devinfo *mcp_dinfo; + struct dpaa2_cmd cmd; + uint16_t rc_token, con_token; int error; sc->dev = dev; @@ -133,7 +125,7 @@ dpaa2_con_attach(device_t dev) if (error) { device_printf(dev, "%s: failed to allocate resources: " "error=%d\n", __func__, error); - return (ENXIO); + goto err_exit; } /* Obtain MC portal. */ @@ -141,57 +133,48 @@ dpaa2_con_attach(device_t dev) mcp_dinfo = device_get_ivars(mcp_dev); dinfo->portal = mcp_dinfo->portal; - /* Allocate a command to send to MC hardware. */ - error = dpaa2_mcp_init_command(&sc->cmd, DPAA2_CMD_DEF); - if (error) { - device_printf(dev, "Failed to allocate dpaa2_cmd: error=%d\n", - error); - goto err_exit; - } + DPAA2_CMD_INIT(&cmd); - /* Open resource container and DPCON object. */ - error = DPAA2_CMD_RC_OPEN(dev, child, sc->cmd, rcinfo->id, - &sc->rc_token); + error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token); if (error) { - device_printf(dev, "Failed to open DPRC: error=%d\n", error); - goto err_free_cmd; + device_printf(dev, "%s: failed to open DPRC: error=%d\n", + __func__, error); + goto err_exit; } - error = DPAA2_CMD_CON_OPEN(dev, child, sc->cmd, dinfo->id, - &sc->con_token); + error = DPAA2_CMD_CON_OPEN(dev, child, &cmd, dinfo->id, &con_token); if (error) { - device_printf(dev, "Failed to open DPCON: id=%d, error=%d\n", - dinfo->id, error); - goto err_close_rc; + device_printf(dev, "%s: failed to open DPCON: id=%d, error=%d\n", + __func__, dinfo->id, error); + goto close_rc; } - /* Prepare DPCON object. */ - error = DPAA2_CMD_CON_RESET(dev, child, sc->cmd); + error = DPAA2_CMD_CON_RESET(dev, child, &cmd); if (error) { - device_printf(dev, "Failed to reset DPCON: id=%d, error=%d\n", - dinfo->id, error); - goto err_close_con; + device_printf(dev, "%s: failed to reset DPCON: id=%d, " + "error=%d\n", __func__, dinfo->id, error); + goto close_con; } - error = DPAA2_CMD_CON_GET_ATTRIBUTES(dev, child, sc->cmd, &sc->attr); + error = DPAA2_CMD_CON_GET_ATTRIBUTES(dev, child, &cmd, &sc->attr); if (error) { - device_printf(dev, "Failed to get DPCON attributes: id=%d, " - "error=%d\n", dinfo->id, error); - goto err_close_con; + device_printf(dev, "%s: failed to get DPCON attributes: id=%d, " + "error=%d\n", __func__, dinfo->id, error); + goto close_con; } - /* TODO: Enable debug output via sysctl (to reduce output). */ - if (bootverbose) + if (bootverbose) { device_printf(dev, "chan_id=%d, priorities=%d\n", sc->attr.chan_id, sc->attr.prior_num); + } + (void)DPAA2_CMD_CON_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, con_token)); + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); return (0); - err_close_con: - DPAA2_CMD_CON_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->con_token)); - err_close_rc: - DPAA2_CMD_RC_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->rc_token)); - err_free_cmd: - dpaa2_mcp_free_command(sc->cmd); - err_exit: +close_con: + DPAA2_CMD_CON_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, con_token)); +close_rc: + DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); +err_exit: return (ENXIO); } diff --git a/sys/dev/dpaa2/dpaa2_con.h b/sys/dev/dpaa2/dpaa2_con.h index 82fd50f4eaed..85a492935d46 100644 --- a/sys/dev/dpaa2/dpaa2_con.h +++ b/sys/dev/dpaa2/dpaa2_con.h @@ -58,11 +58,6 @@ struct dpaa2_con_softc { device_t dev; struct resource *res[DPAA2_CON_MAX_RESOURCES]; struct dpaa2_con_attr attr; - - /* Help to send commands to MC. */ - struct dpaa2_cmd *cmd; - uint16_t rc_token; - uint16_t con_token; }; extern struct resource_spec dpaa2_con_spec[]; diff --git a/sys/dev/dpaa2/dpaa2_io.c b/sys/dev/dpaa2/dpaa2_io.c index e2b7992bfdb6..b644516308b2 100644 --- a/sys/dev/dpaa2/dpaa2_io.c +++ b/sys/dev/dpaa2/dpaa2_io.c @@ -127,50 +127,68 @@ dpaa2_io_probe(device_t dev) static int dpaa2_io_detach(device_t dev) { + device_t pdev = device_get_parent(dev); device_t child = dev; struct dpaa2_io_softc *sc = device_get_softc(dev); + struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev); struct dpaa2_devinfo *dinfo = device_get_ivars(dev); + struct dpaa2_cmd cmd; + uint16_t rc_token, io_token; int error; + DPAA2_CMD_INIT(&cmd); + /* Tear down interrupt handler and release IRQ resources. */ dpaa2_io_release_irqs(dev); /* Free software portal helper object. */ dpaa2_swp_free_portal(sc->swp); - /* Disable DPIO object. */ - error = DPAA2_CMD_IO_DISABLE(dev, child, dpaa2_mcp_tk(sc->cmd, - sc->io_token)); - if (error && bootverbose) + error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token); + if (error) { + device_printf(dev, "%s: failed to open DPRC: error=%d\n", + __func__, error); + goto err_exit; + } + error = DPAA2_CMD_IO_OPEN(dev, child, &cmd, dinfo->id, &io_token); + if (error) { + device_printf(dev, "%s: failed to open DPIO: id=%d, error=%d\n", + __func__, dinfo->id, error); + goto close_rc; + } + + error = DPAA2_CMD_IO_DISABLE(dev, child, &cmd); + if (error && bootverbose) { device_printf(dev, "%s: failed to disable DPIO: id=%d, " "error=%d\n", __func__, dinfo->id, error); + } - /* Close control sessions with the DPAA2 objects. */ - DPAA2_CMD_IO_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->io_token)); - DPAA2_CMD_RC_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->rc_token)); - - /* Free pre-allocated MC command. */ - dpaa2_mcp_free_command(sc->cmd); - sc->cmd = NULL; - sc->io_token = 0; - sc->rc_token = 0; + (void)DPAA2_CMD_IO_CLOSE(dev, child, &cmd); + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); /* Unmap memory resources of the portal. */ for (int i = 0; i < MEM_RES_NUM; i++) { - if (sc->res[MEM_RID(i)] == NULL) + if (sc->res[MEM_RID(i)] == NULL) { continue; + } error = bus_unmap_resource(sc->dev, SYS_RES_MEMORY, sc->res[MEM_RID(i)], &sc->map[MEM_RID(i)]); - if (error && bootverbose) + if (error && bootverbose) { device_printf(dev, "%s: failed to unmap memory " "resource: rid=%d, error=%d\n", __func__, MEM_RID(i), error); + } } /* Release allocated resources. */ bus_release_resources(dev, dpaa2_io_spec, sc->res); return (0); + +close_rc: + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); +err_exit: + return (error); } static int @@ -183,6 +201,7 @@ dpaa2_io_attach(device_t dev) struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev); struct dpaa2_devinfo *dinfo = device_get_ivars(dev); struct dpaa2_devinfo *mcp_dinfo; + struct dpaa2_cmd cmd; struct resource_map_request req; struct { vm_memattr_t memattr; @@ -192,11 +211,11 @@ dpaa2_io_attach(device_t dev) { VM_MEMATTR_DEVICE, "cache-inhibited part" }, { VM_MEMATTR_DEVICE, "control registers" } }; + uint16_t rc_token, io_token; int error; sc->dev = dev; sc->swp = NULL; - sc->cmd = NULL; sc->intr = NULL; sc->irq_resource = NULL; @@ -215,8 +234,9 @@ dpaa2_io_attach(device_t dev) /* Map memory resources of the portal. */ for (int i = 0; i < MEM_RES_NUM; i++) { - if (sc->res[MEM_RID(i)] == NULL) + if (sc->res[MEM_RID(i)] == NULL) { continue; + } resource_init_map_request(&req); req.memattr = map_args[i].memattr; @@ -229,45 +249,37 @@ dpaa2_io_attach(device_t dev) } } - /* Allocate a command to send to the MC hardware. */ - error = dpaa2_mcp_init_command(&sc->cmd, DPAA2_CMD_DEF); - if (error) { - device_printf(dev, "%s: failed to allocate dpaa2_cmd: " - "error=%d\n", __func__, error); - goto err_exit; - } + DPAA2_CMD_INIT(&cmd); - /* Prepare DPIO object. */ - error = DPAA2_CMD_RC_OPEN(dev, child, sc->cmd, rcinfo->id, - &sc->rc_token); + error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token); if (error) { device_printf(dev, "%s: failed to open DPRC: error=%d\n", __func__, error); goto err_exit; } - error = DPAA2_CMD_IO_OPEN(dev, child, sc->cmd, dinfo->id, &sc->io_token); + error = DPAA2_CMD_IO_OPEN(dev, child, &cmd, dinfo->id, &io_token); if (error) { device_printf(dev, "%s: failed to open DPIO: id=%d, error=%d\n", __func__, dinfo->id, error); - goto err_exit; + goto close_rc; } - error = DPAA2_CMD_IO_RESET(dev, child, sc->cmd); + error = DPAA2_CMD_IO_RESET(dev, child, &cmd); if (error) { device_printf(dev, "%s: failed to reset DPIO: id=%d, error=%d\n", __func__, dinfo->id, error); - goto err_exit; + goto close_io; } - error = DPAA2_CMD_IO_GET_ATTRIBUTES(dev, child, sc->cmd, &sc->attr); + error = DPAA2_CMD_IO_GET_ATTRIBUTES(dev, child, &cmd, &sc->attr); if (error) { device_printf(dev, "%s: failed to get DPIO attributes: id=%d, " "error=%d\n", __func__, dinfo->id, error); - goto err_exit; + goto close_io; } - error = DPAA2_CMD_IO_ENABLE(dev, child, sc->cmd); + error = DPAA2_CMD_IO_ENABLE(dev, child, &cmd); if (error) { device_printf(dev, "%s: failed to enable DPIO: id=%d, " "error=%d\n", __func__, dinfo->id, error); - goto err_exit; + goto close_io; } /* Prepare descriptor of the QBMan software portal. */ @@ -306,18 +318,23 @@ dpaa2_io_attach(device_t dev) goto err_exit; } -#if 0 - /* TODO: Enable debug output via sysctl (to reduce output). */ - if (bootverbose) + if (bootverbose) { device_printf(dev, "dpio_id=%d, swp_id=%d, chan_mode=%s, " "notif_priors=%d, swp_version=0x%x\n", sc->attr.id, sc->attr.swp_id, sc->attr.chan_mode == DPAA2_IO_LOCAL_CHANNEL ? "local_channel" : "no_channel", sc->attr.priors_num, sc->attr.swp_version); -#endif + } + + (void)DPAA2_CMD_IO_CLOSE(dev, child, &cmd); + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); return (0); +close_io: + (void)DPAA2_CMD_IO_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, io_token)); +close_rc: + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); err_exit: dpaa2_io_detach(dev); return (ENXIO); @@ -354,10 +371,11 @@ dpaa2_io_conf_wq_channel(device_t iodev, struct dpaa2_io_notif_ctx *ctx) struct dpaa2_io_softc *sc = device_get_softc(iodev); /* Enable generation of the CDAN notifications. */ - if (ctx->cdan_en) + if (ctx->cdan_en) { return (dpaa2_swp_conf_wq_channel(sc->swp, ctx->fq_chan_id, DPAA2_WQCHAN_WE_EN | DPAA2_WQCHAN_WE_CTX, ctx->cdan_en, ctx->qman_ctx)); + } return (0); } diff --git a/sys/dev/dpaa2/dpaa2_io.h b/sys/dev/dpaa2/dpaa2_io.h index d02dab8144df..13def050fffb 100644 --- a/sys/dev/dpaa2/dpaa2_io.h +++ b/sys/dev/dpaa2/dpaa2_io.h @@ -92,11 +92,6 @@ struct dpaa2_io_softc { struct dpaa2_swp *swp; struct dpaa2_io_attr attr; - /* Help to send commands to MC. */ - struct dpaa2_cmd *cmd; - uint16_t rc_token; - uint16_t io_token; - struct resource *res[DPAA2_IO_MAX_RESOURCES]; struct resource_map map[DPAA2_IO_MAX_RESOURCES]; diff --git a/sys/dev/dpaa2/dpaa2_mac.c b/sys/dev/dpaa2/dpaa2_mac.c index d6e381c0dd15..990286e53bfa 100644 --- a/sys/dev/dpaa2/dpaa2_mac.c +++ b/sys/dev/dpaa2/dpaa2_mac.c @@ -118,6 +118,8 @@ dpaa2_mac_attach(device_t dev) struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev); struct dpaa2_devinfo *dinfo = device_get_ivars(dev); struct dpaa2_devinfo *mcp_dinfo; + struct dpaa2_cmd cmd; + uint16_t rc_token, mac_token; int error; sc->dev = dev; @@ -128,7 +130,7 @@ dpaa2_mac_attach(device_t dev) if (error) { device_printf(dev, "%s: failed to allocate resources: " "error=%d\n", __func__, error); - return (ENXIO); + goto err_exit; } /* Obtain MC portal. */ @@ -136,42 +138,33 @@ dpaa2_mac_attach(device_t dev) mcp_dinfo = device_get_ivars(mcp_dev); dinfo->portal = mcp_dinfo->portal; - /* Allocate a command to send to MC hardware. */ - error = dpaa2_mcp_init_command(&sc->cmd, DPAA2_CMD_DEF); + DPAA2_CMD_INIT(&cmd); + + error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token); if (error) { - device_printf(dev, "Failed to allocate dpaa2_cmd: error=%d\n", - error); + device_printf(dev, "%s: failed to open DPRC: error=%d\n", + __func__, error); goto err_exit; } - - /* Open resource container and DPMAC object. */ - error = DPAA2_CMD_RC_OPEN(dev, child, sc->cmd, rcinfo->id, - &sc->rc_token); + error = DPAA2_CMD_MAC_OPEN(dev, child, &cmd, dinfo->id, &mac_token); if (error) { - device_printf(dev, "Failed to open DPRC: error=%d\n", error); - goto err_free_cmd; + device_printf(dev, "%s: failed to open DPMAC: id=%d, error=%d\n", + __func__, dinfo->id, error); + goto close_rc; } - error = DPAA2_CMD_MAC_OPEN(dev, child, sc->cmd, dinfo->id, - &sc->mac_token); + + error = DPAA2_CMD_MAC_GET_ATTRIBUTES(dev, child, &cmd, &sc->attr); if (error) { - device_printf(dev, "Failed to open DPMAC: id=%d, error=%d\n", - dinfo->id, error); - goto err_close_rc; + device_printf(dev, "%s: failed to get DPMAC attributes: id=%d, " + "error=%d\n", __func__, dinfo->id, error); + goto close_mac; } - - error = DPAA2_CMD_MAC_GET_ATTRIBUTES(dev, child, sc->cmd, &sc->attr); + error = DPAA2_CMD_MAC_GET_ADDR(dev, child, &cmd, sc->addr); if (error) { - device_printf(dev, "Failed to get DPMAC attributes: id=%d, " - "error=%d\n", dinfo->id, error); - goto err_close_mac; + device_printf(dev, "%s: failed to get physical address: " + "error=%d\n", __func__, error); } - error = DPAA2_CMD_MAC_GET_ADDR(dev, child, sc->cmd, sc->addr); - if (error) - device_printf(dev, "Failed to get physical address: error=%d\n", - error); - /* - * TODO: Enable debug output via sysctl. - */ + if (bootverbose) { device_printf(dev, "ether %6D\n", sc->addr, ":"); device_printf(dev, "max_rate=%d, eth_if=%s, link_type=%s\n", @@ -182,18 +175,19 @@ dpaa2_mac_attach(device_t dev) error = dpaa2_mac_setup_irq(dev); if (error) { - device_printf(dev, "Failed to setup IRQs: error=%d\n", error); - goto err_close_mac; + device_printf(dev, "%s: failed to setup IRQs: error=%d\n", + __func__, error); + goto close_mac; } + (void)DPAA2_CMD_MAC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, mac_token)); + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); return (0); -err_close_mac: - DPAA2_CMD_MAC_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->mac_token)); -err_close_rc: - DPAA2_CMD_RC_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->rc_token)); -err_free_cmd: - dpaa2_mcp_free_command(sc->cmd); +close_mac: + (void)DPAA2_CMD_MAC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, mac_token)); +close_rc: + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); err_exit: return (ENXIO); } @@ -201,17 +195,7 @@ err_exit: static int dpaa2_mac_detach(device_t dev) { - device_t child = dev; - struct dpaa2_mac_softc *sc = device_get_softc(dev); - - DPAA2_CMD_MAC_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->mac_token)); - DPAA2_CMD_RC_CLOSE(dev, child, dpaa2_mcp_tk(sc->cmd, sc->rc_token)); - dpaa2_mcp_free_command(sc->cmd); - - sc->cmd = NULL; - sc->rc_token = 0; - sc->mac_token = 0; - + /* TBD */ return (0); } @@ -221,53 +205,80 @@ dpaa2_mac_detach(device_t dev) static int dpaa2_mac_setup_irq(device_t dev) { + device_t pdev = device_get_parent(dev); device_t child = dev; struct dpaa2_mac_softc *sc = device_get_softc(dev); - struct dpaa2_cmd *cmd = sc->cmd; - uint16_t mac_token = sc->mac_token; + struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev); + struct dpaa2_devinfo *dinfo = device_get_ivars(dev); + struct dpaa2_cmd cmd; + uint16_t rc_token, mac_token; uint32_t irq_mask; int error; - /* Configure IRQs. */ error = dpaa2_mac_setup_msi(sc); if (error) { - device_printf(dev, "Failed to allocate MSI\n"); - return (error); + device_printf(dev, "%s: failed to allocate MSI\n", __func__); + goto err_exit; } if ((sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid[0], RF_ACTIVE | RF_SHAREABLE)) == NULL) { - device_printf(dev, "Failed to allocate IRQ resource\n"); - return (ENXIO); + device_printf(dev, "%s: failed to allocate IRQ resource\n", + __func__); + error = ENXIO; + goto err_exit; } if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, NULL, dpaa2_mac_intr, sc, &sc->intr)) { - device_printf(dev, "Failed to setup IRQ resource\n"); - return (ENXIO); + device_printf(dev, "%s: failed to setup IRQ resource\n", + __func__); + error = ENXIO; + goto err_exit; + } + + DPAA2_CMD_INIT(&cmd); + + error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token); + if (error) { + device_printf(dev, "%s: failed to open DPRC: error=%d\n", + __func__, error); + goto err_exit; + } + error = DPAA2_CMD_MAC_OPEN(dev, child, &cmd, dinfo->id, &mac_token); + if (error) { + device_printf(dev, "%s: failed to open DPMAC: id=%d, error=%d\n", + __func__, dinfo->id, error); + goto close_rc; } - /* Configure DPNI to generate interrupts. */ irq_mask = DPMAC_IRQ_LINK_CFG_REQ | DPMAC_IRQ_LINK_CHANGED | DPMAC_IRQ_LINK_UP_REQ | DPMAC_IRQ_LINK_DOWN_REQ | DPMAC_IRQ_EP_CHANGED; - error = DPAA2_CMD_MAC_SET_IRQ_MASK(dev, child, dpaa2_mcp_tk(cmd, - mac_token), DPMAC_IRQ_INDEX, irq_mask); + error = DPAA2_CMD_MAC_SET_IRQ_MASK(dev, child, &cmd, DPMAC_IRQ_INDEX, + irq_mask); if (error) { - device_printf(dev, "Failed to set IRQ mask\n"); - return (error); + device_printf(dev, "%s: failed to set IRQ mask\n", __func__); + goto close_mac; } - - /* Enable IRQ. */ - error = DPAA2_CMD_MAC_SET_IRQ_ENABLE(dev, child, cmd, DPMAC_IRQ_INDEX, + error = DPAA2_CMD_MAC_SET_IRQ_ENABLE(dev, child, &cmd, DPMAC_IRQ_INDEX, true); if (error) { - device_printf(dev, "Failed to enable IRQ\n"); - return (error); + device_printf(dev, "%s: failed to enable IRQ\n", __func__); + goto close_mac; } + (void)DPAA2_CMD_MAC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, mac_token)); + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); return (0); + +close_mac: + (void)DPAA2_CMD_MAC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, mac_token)); +close_rc: + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); +err_exit: + return (error); } /** @@ -297,15 +308,42 @@ static void dpaa2_mac_intr(void *arg) { struct dpaa2_mac_softc *sc = (struct dpaa2_mac_softc *) arg; - device_t child = sc->dev; + device_t pdev = device_get_parent(sc->dev); + device_t dev = sc->dev; + device_t child = dev; + struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev); + struct dpaa2_devinfo *dinfo = device_get_ivars(dev); + struct dpaa2_cmd cmd; uint32_t status = ~0u; /* clear all IRQ status bits */ + uint16_t rc_token, mac_token; int error; - error = DPAA2_CMD_MAC_GET_IRQ_STATUS(sc->dev, child, - dpaa2_mcp_tk(sc->cmd, sc->mac_token), DPMAC_IRQ_INDEX, &status); - if (error) + DPAA2_CMD_INIT(&cmd); + + error = DPAA2_CMD_RC_OPEN(dev, child, &cmd, rcinfo->id, &rc_token); + if (error) { + device_printf(dev, "%s: failed to open DPRC: error=%d\n", + __func__, error); + goto err_exit; + } + error = DPAA2_CMD_MAC_OPEN(dev, child, &cmd, dinfo->id, &mac_token); + if (error) { + device_printf(dev, "%s: failed to open DPMAC: id=%d, error=%d\n", + __func__, dinfo->id, error); + goto close_rc; + } + error = DPAA2_CMD_MAC_GET_IRQ_STATUS(dev, child, &cmd, DPMAC_IRQ_INDEX, + &status); + if (error) { device_printf(sc->dev, "%s: failed to obtain IRQ status: " "error=%d\n", __func__, error); + } + + (void)DPAA2_CMD_MAC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, mac_token)); +close_rc: + (void)DPAA2_CMD_RC_CLOSE(dev, child, DPAA2_CMD_TK(&cmd, rc_token)); +err_exit: + return; } static const char * diff --git a/sys/dev/dpaa2/dpaa2_mac.h b/sys/dev/dpaa2/dpaa2_mac.h index cbdf2d824045..d31513e725c4 100644 --- a/sys/dev/dpaa2/dpaa2_mac.h +++ b/sys/dev/dpaa2/dpaa2_mac.h @@ -108,12 +108,6 @@ struct dpaa2_mac_softc { struct resource *res[DPAA2_MAC_MAX_RESOURCES]; struct dpaa2_mac_attr attr; - /* Help to send commands to MC. */ - struct dpaa2_cmd *cmd; - uint16_t rc_token; - uint16_t mac_token; - - /* Interrupts. */ int irq_rid[DPAA2_MAC_MSI_COUNT]; struct resource *irq_res; void *intr; /* interrupt handle */ diff --git a/sys/dev/dpaa2/dpaa2_mcp.c b/sys/dev/dpaa2/dpaa2_mcp.c index f41d9a7d21b0..9d24463413f3 100644 --- a/sys/dev/dpaa2/dpaa2_mcp.c +++ b/sys/dev/dpaa2/dpaa2_mcp.c @@ -108,54 +108,14 @@ dpaa2_mcp_free_portal(struct dpaa2_mcp *mcp) free(mcp, M_DPAA2_MCP); } -int -dpaa2_mcp_init_command(struct dpaa2_cmd **cmd, uint16_t flags) -{ - const int mflags = flags & DPAA2_CMD_NOWAIT_ALLOC - ? (M_NOWAIT | M_ZERO) : (M_WAITOK | M_ZERO); - struct dpaa2_cmd *c; - struct dpaa2_cmd_header *hdr; - - if (!cmd) - return (DPAA2_CMD_STAT_EINVAL); - - c = malloc(sizeof(struct dpaa2_cmd), M_DPAA2_MCP, mflags); - if (!c) - return (DPAA2_CMD_STAT_NO_MEMORY); - - hdr = (struct dpaa2_cmd_header *) &c->header; - hdr->srcid = 0; - hdr->status = DPAA2_CMD_STAT_OK; - hdr->token = 0; - hdr->cmdid = 0; - hdr->flags_hw = DPAA2_CMD_DEF; - hdr->flags_sw = DPAA2_CMD_DEF; - if (flags & DPAA2_CMD_HIGH_PRIO) - hdr->flags_hw |= DPAA2_HW_FLAG_HIGH_PRIO; - if (flags & DPAA2_CMD_INTR_DIS) - hdr->flags_sw |= DPAA2_SW_FLAG_INTR_DIS; - for (uint32_t i = 0; i < DPAA2_CMD_PARAMS_N; i++) - c->params[i] = 0; - *cmd = c; - - return (0); -} - -void -dpaa2_mcp_free_command(struct dpaa2_cmd *cmd) -{ - if (cmd != NULL) - free(cmd, M_DPAA2_MCP); -} - struct dpaa2_cmd * dpaa2_mcp_tk(struct dpaa2_cmd *cmd, uint16_t token) { struct dpaa2_cmd_header *hdr; - if (cmd != NULL) { - hdr = (struct dpaa2_cmd_header *) &cmd->header; - hdr->token = token; - } + KASSERT(cmd != NULL, ("%s: cmd is NULL", __func__)); + + hdr = (struct dpaa2_cmd_header *) &cmd->header; + hdr->token = token; return (cmd); } @@ -163,15 +123,16 @@ struct dpaa2_cmd * dpaa2_mcp_f(struct dpaa2_cmd *cmd, uint16_t flags) { struct dpaa2_cmd_header *hdr; - if (cmd) { - hdr = (struct dpaa2_cmd_header *) &cmd->header; - hdr->flags_hw = DPAA2_CMD_DEF; - hdr->flags_sw = DPAA2_CMD_DEF; - - if (flags & DPAA2_CMD_HIGH_PRIO) - hdr->flags_hw |= DPAA2_HW_FLAG_HIGH_PRIO; - if (flags & DPAA2_CMD_INTR_DIS) - hdr->flags_sw |= DPAA2_SW_FLAG_INTR_DIS; + KASSERT(cmd != NULL, ("%s: cmd is NULL", __func__)); + + hdr = (struct dpaa2_cmd_header *) &cmd->header; + hdr->flags_hw = DPAA2_CMD_DEF; + hdr->flags_sw = DPAA2_CMD_DEF; + if (flags & DPAA2_CMD_HIGH_PRIO) { + hdr->flags_hw |= DPAA2_HW_FLAG_HIGH_PRIO; + } + if (flags & DPAA2_CMD_INTR_DIS) { + hdr->flags_sw |= DPAA2_SW_FLAG_INTR_DIS; } return (cmd); } @@ -198,7 +159,7 @@ dpaa2_mcp_attach(device_t dev) struct dpaa2_mcp_softc *sc = device_get_softc(dev); struct dpaa2_devinfo *rcinfo = device_get_ivars(pdev); struct dpaa2_devinfo *dinfo = device_get_ivars(dev); - struct dpaa2_cmd *cmd; + struct dpaa2_cmd cmd; struct dpaa2_mcp *portal; struct resource_map_request req; uint16_t rc_token, mcp_token; @@ -240,61 +201,40 @@ dpaa2_mcp_attach(device_t dev) goto err_exit; } - /* Allocate a command to send to MC hardware. */ - error = dpaa2_mcp_init_command(&cmd, DPAA2_CMD_DEF); - if (error) { - device_printf(dev, "%s: failed to allocate dpaa2_cmd: " - "error=%d\n", __func__, error); - goto err_exit; - } + DPAA2_CMD_INIT(&cmd); *** 2640 LINES SKIPPED ***