git: 4cd966142822 - main - dpaa2: Avoid dpaa2_cmd race conditions

From: Dmitry Salychev <dsl_at_FreeBSD.org>
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 ***