diff options
-rw-r--r-- | sys/dev/pci/if_mcx.c | 101 |
1 files changed, 65 insertions, 36 deletions
diff --git a/sys/dev/pci/if_mcx.c b/sys/dev/pci/if_mcx.c index f5504237355..b797ea3cc09 100644 --- a/sys/dev/pci/if_mcx.c +++ b/sys/dev/pci/if_mcx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_mcx.c,v 1.81 2020/12/25 22:38:08 dlg Exp $ */ +/* $OpenBSD: if_mcx.c,v 1.82 2020/12/26 11:06:52 dlg Exp $ */ /* * Copyright (c) 2017 David Gwynne <dlg@openbsd.org> @@ -4212,7 +4212,7 @@ mcx_create_eq(struct mcx_softc *sc, struct mcx_eq *eq, int uar, howmany(insize, MCX_CMDQ_MAILBOX_DATASIZE), &cqe->cq_input_ptr, token) != 0) { printf(", unable to allocate create eq mailboxen\n"); - return (-1); + goto free_eq; } mbin = mcx_cq_mbox_data(mcx_cq_mbox(&mxm, 0)); mbin->cmd_eq_ctx.eq_uar_size = htobe32( @@ -4228,26 +4228,33 @@ mcx_create_eq(struct mcx_softc *sc, struct mcx_eq *eq, int uar, error = mcx_cmdq_poll(sc, cqe, 1000); if (error != 0) { printf(", create eq timeout\n"); - goto free; + goto free_mxm; } if (mcx_cmdq_verify(cqe) != 0) { printf(", create eq command corrupt\n"); - goto free; + goto free_mxm; } out = mcx_cmdq_out(cqe); if (out->cmd_status != MCX_CQ_STATUS_OK) { printf(", create eq failed (%x, %x)\n", out->cmd_status, betoh32(out->cmd_syndrome)); - error = -1; - goto free; + goto free_mxm; } eq->eq_n = mcx_get_id(out->cmd_eqn); + + mcx_dmamem_free(sc, &mxm); + mcx_arm_eq(sc, eq, uar); -free: + + return (0); + +free_mxm: mcx_dmamem_free(sc, &mxm); - return (error); +free_eq: + mcx_dmamem_free(sc, &eq->eq_mem); + return (-1); } static int @@ -4494,8 +4501,7 @@ mcx_create_cq(struct mcx_softc *sc, struct mcx_cq *cq, int uar, int db, int eqn) &cmde->cq_input_ptr, token) != 0) { printf("%s: unable to allocate create cq mailboxen\n", DEVNAME(sc)); - error = -1; - goto free; + goto free_cq; } mbin = mcx_cq_mbox_data(mcx_cq_mbox(&mxm, 0)); mbin->cmd_cq_ctx.cq_uar_size = htobe32( @@ -4515,19 +4521,18 @@ mcx_create_cq(struct mcx_softc *sc, struct mcx_cq *cq, int uar, int db, int eqn) error = mcx_cmdq_poll(sc, cmde, 1000); if (error != 0) { printf("%s: create cq timeout\n", DEVNAME(sc)); - goto free; + goto free_mxm; } if (mcx_cmdq_verify(cmde) != 0) { printf("%s: create cq command corrupt\n", DEVNAME(sc)); - goto free; + goto free_mxm; } out = mcx_cmdq_out(cmde); if (out->cmd_status != MCX_CQ_STATUS_OK) { printf("%s: create cq failed (%x, %x)\n", DEVNAME(sc), out->cmd_status, betoh32(out->cmd_syndrome)); - error = -1; - goto free; + goto free_mxm; } cq->cq_n = mcx_get_id(out->cmd_cqn); @@ -4535,11 +4540,18 @@ mcx_create_cq(struct mcx_softc *sc, struct mcx_cq *cq, int uar, int db, int eqn) cq->cq_count = 0; cq->cq_doorbell = MCX_DMA_KVA(&sc->sc_doorbell_mem) + MCX_CQ_DOORBELL_BASE + (MCX_CQ_DOORBELL_STRIDE * db); + + mcx_dmamem_free(sc, &mxm); + mcx_arm_cq(sc, cq, uar); -free: + return (0); + +free_mxm: mcx_dmamem_free(sc, &mxm); - return (error); +free_cq: + mcx_dmamem_free(sc, &cq->cq_mem); + return (-1); } static int @@ -4578,8 +4590,9 @@ mcx_destroy_cq(struct mcx_softc *sc, struct mcx_cq *cq) return -1; } - cq->cq_n = 0; mcx_dmamem_free(sc, &cq->cq_mem); + + cq->cq_n = 0; cq->cq_cons = 0; cq->cq_count = 0; return 0; @@ -4624,8 +4637,7 @@ mcx_create_rq(struct mcx_softc *sc, struct mcx_rx *rx, int db, int cqn) &cqe->cq_input_ptr, token) != 0) { printf("%s: unable to allocate create rq mailboxen\n", DEVNAME(sc)); - error = -1; - goto free; + goto free_rq; } mbin = (struct mcx_rq_ctx *) (((char *)mcx_cq_mbox_data(mcx_cq_mbox(&mxm, 0))) + 0x10); @@ -4649,30 +4661,35 @@ mcx_create_rq(struct mcx_softc *sc, struct mcx_rx *rx, int db, int cqn) error = mcx_cmdq_poll(sc, cqe, 1000); if (error != 0) { printf("%s: create rq timeout\n", DEVNAME(sc)); - goto free; + goto free_mxm; } if (mcx_cmdq_verify(cqe) != 0) { printf("%s: create rq command corrupt\n", DEVNAME(sc)); - goto free; + goto free_mxm; } out = mcx_cmdq_out(cqe); if (out->cmd_status != MCX_CQ_STATUS_OK) { printf("%s: create rq failed (%x, %x)\n", DEVNAME(sc), out->cmd_status, betoh32(out->cmd_syndrome)); - error = -1; - goto free; + goto free_mxm; } rx->rx_rqn = mcx_get_id(out->cmd_rqn); + mcx_dmamem_free(sc, &mxm); + doorbell = MCX_DMA_KVA(&sc->sc_doorbell_mem); rx->rx_doorbell = (uint32_t *)(doorbell + MCX_WQ_DOORBELL_BASE + (db * MCX_WQ_DOORBELL_STRIDE)); -free: + return (0); + +free_mxm: mcx_dmamem_free(sc, &mxm); - return (error); +free_rq: + mcx_dmamem_free(sc, &rx->rx_rq_mem); + return (-1); } static int @@ -4768,6 +4785,7 @@ mcx_destroy_rq(struct mcx_softc *sc, struct mcx_rx *rx) } rx->rx_rqn = 0; + mcx_dmamem_free(sc, &rx->rx_rq_mem); return 0; } @@ -4968,8 +4986,7 @@ mcx_create_sq(struct mcx_softc *sc, struct mcx_tx *tx, int uar, int db, &cqe->cq_input_ptr, token) != 0) { printf("%s: unable to allocate create sq mailboxen\n", DEVNAME(sc)); - error = -1; - goto free; + goto free_sq; } mbin = (struct mcx_sq_ctx *) (((char *)mcx_cq_mbox_data(mcx_cq_mbox(&mxm, 0))) + 0x10); @@ -4994,30 +5011,36 @@ mcx_create_sq(struct mcx_softc *sc, struct mcx_tx *tx, int uar, int db, error = mcx_cmdq_poll(sc, cqe, 1000); if (error != 0) { printf("%s: create sq timeout\n", DEVNAME(sc)); - goto free; + goto free_mxm; } if (mcx_cmdq_verify(cqe) != 0) { printf("%s: create sq command corrupt\n", DEVNAME(sc)); - goto free; + goto free_mxm; } out = mcx_cmdq_out(cqe); if (out->cmd_status != MCX_CQ_STATUS_OK) { printf("%s: create sq failed (%x, %x)\n", DEVNAME(sc), out->cmd_status, betoh32(out->cmd_syndrome)); - error = -1; - goto free; + goto free_mxm; } tx->tx_uar = uar; tx->tx_sqn = mcx_get_id(out->cmd_sqn); + mcx_dmamem_free(sc, &mxm); + doorbell = MCX_DMA_KVA(&sc->sc_doorbell_mem); tx->tx_doorbell = (uint32_t *)(doorbell + MCX_WQ_DOORBELL_BASE + (db * MCX_WQ_DOORBELL_STRIDE) + 4); -free: + + return (0); + +free_mxm: mcx_dmamem_free(sc, &mxm); - return (error); +free_sq: + mcx_dmamem_free(sc, &tx->tx_sq_mem); + return (-1); } static int @@ -5057,6 +5080,7 @@ mcx_destroy_sq(struct mcx_softc *sc, struct mcx_tx *tx) } tx->tx_sqn = 0; + mcx_dmamem_free(sc, &tx->tx_sq_mem); return 0; } @@ -6968,16 +6992,21 @@ mcx_queue_up(struct mcx_softc *sc, struct mcx_queues *q) if (mcx_create_cq(sc, &q->q_cq, q->q_uar, q->q_index, q->q_eq.eq_n) != 0) - return ENOMEM; + goto destroy_tx_slots; if (mcx_create_sq(sc, tx, q->q_uar, q->q_index, q->q_cq.cq_n) != 0) - return ENOMEM; + goto destroy_cq; if (mcx_create_rq(sc, rx, q->q_index, q->q_cq.cq_n) != 0) - return ENOMEM; + goto destroy_sq; return 0; + +destroy_sq: + mcx_destroy_sq(sc, tx); +destroy_cq: + mcx_destroy_cq(sc, &q->q_cq); destroy_tx_slots: mcx_free_slots(sc, tx->tx_slots, i, (1 << MCX_LOG_SQ_SIZE)); tx->tx_slots = NULL; |