summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2021-01-04 04:50:06 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2021-01-04 04:50:06 +0000
commit6498ba27a3a3c9dc6d07786599b27365ab3bb7cd (patch)
tree60b491016537cbacfc04713cce5f2568ee4fd7f1
parent6e3508fab7361066300756eac175dcc4b6787354 (diff)
use bus_dmamap_sync around updates to the doorbells.
ok jmatthew@
-rw-r--r--sys/dev/pci/if_mcx.c102
1 files changed, 69 insertions, 33 deletions
diff --git a/sys/dev/pci/if_mcx.c b/sys/dev/pci/if_mcx.c
index cb966c7a4d3..e5d096a99ec 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.91 2020/12/27 01:00:25 dlg Exp $ */
+/* $OpenBSD: if_mcx.c,v 1.92 2021/01/04 04:50:05 dlg Exp $ */
/*
* Copyright (c) 2017 David Gwynne <dlg@openbsd.org>
@@ -2220,6 +2220,7 @@ struct mcx_dmamem {
#define MCX_DMA_MAP(_mxm) ((_mxm)->mxm_map)
#define MCX_DMA_DVA(_mxm) ((_mxm)->mxm_map->dm_segs[0].ds_addr)
#define MCX_DMA_KVA(_mxm) ((void *)(_mxm)->mxm_kva)
+#define MCX_DMA_OFF(_mxm, _off) ((void *)((_mxm)->mxm_kva + (_off)))
#define MCX_DMA_LEN(_mxm) ((_mxm)->mxm_size)
struct mcx_hwmem {
@@ -2243,7 +2244,7 @@ struct mcx_eq {
struct mcx_cq {
int cq_n;
struct mcx_dmamem cq_mem;
- uint32_t *cq_doorbell;
+ bus_addr_t cq_doorbell;
uint32_t cq_cons;
uint32_t cq_count;
};
@@ -2266,7 +2267,7 @@ struct mcx_rx {
int rx_rqn;
struct mcx_dmamem rx_rq_mem;
struct mcx_slot *rx_slots;
- uint32_t *rx_doorbell;
+ bus_addr_t rx_doorbell;
uint32_t rx_prod;
struct timeout rx_refill;
@@ -2281,7 +2282,7 @@ struct mcx_tx {
int tx_sqn;
struct mcx_dmamem tx_sq_mem;
struct mcx_slot *tx_slots;
- uint32_t *tx_doorbell;
+ bus_addr_t tx_doorbell;
int tx_bf_offset;
uint32_t tx_cons;
@@ -4477,6 +4478,8 @@ mcx_create_cq(struct mcx_softc *sc, struct mcx_cq *cq, int uar, int db, int eqn)
uint64_t *pas;
int insize, npages, paslen, i, token;
+ cq->cq_doorbell = MCX_CQ_DOORBELL_BASE + (MCX_CQ_DOORBELL_STRIDE * db);
+
npages = howmany((1 << MCX_LOG_CQ_SIZE) * sizeof(struct mcx_cq_entry),
MCX_PAGE_SIZE);
paslen = npages * sizeof(*pas);
@@ -4516,8 +4519,7 @@ mcx_create_cq(struct mcx_softc *sc, struct mcx_cq *cq, int uar, int db, int eqn)
(MCX_CQ_MOD_PERIOD << MCX_CQ_CTX_PERIOD_SHIFT) |
MCX_CQ_MOD_COUNTER);
mbin->cmd_cq_ctx.cq_doorbell = htobe64(
- MCX_DMA_DVA(&sc->sc_doorbell_mem) +
- MCX_CQ_DOORBELL_BASE + (MCX_CQ_DOORBELL_STRIDE * db));
+ MCX_DMA_DVA(&sc->sc_doorbell_mem) + cq->cq_doorbell);
bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&cq->cq_mem),
0, MCX_DMA_LEN(&cq->cq_mem), BUS_DMASYNC_PREREAD);
@@ -4546,11 +4548,13 @@ mcx_create_cq(struct mcx_softc *sc, struct mcx_cq *cq, int uar, int db, int eqn)
cq->cq_n = mcx_get_id(out->cmd_cqn);
cq->cq_cons = 0;
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);
+ bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&sc->sc_doorbell_mem),
+ cq->cq_doorbell, sizeof(struct mcx_cq_doorbell),
+ BUS_DMASYNC_PREWRITE);
+
mcx_arm_cq(sc, cq, uar);
return (0);
@@ -4600,6 +4604,10 @@ mcx_destroy_cq(struct mcx_softc *sc, struct mcx_cq *cq)
return -1;
}
+ bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&sc->sc_doorbell_mem),
+ cq->cq_doorbell, sizeof(struct mcx_cq_doorbell),
+ BUS_DMASYNC_POSTWRITE);
+
bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&cq->cq_mem),
0, MCX_DMA_LEN(&cq->cq_mem), BUS_DMASYNC_POSTREAD);
mcx_dmamem_free(sc, &cq->cq_mem);
@@ -4621,9 +4629,11 @@ mcx_create_rq(struct mcx_softc *sc, struct mcx_rx *rx, int db, int cqn)
int error;
uint64_t *pas;
uint32_t rq_flags;
- uint8_t *doorbell;
int insize, npages, paslen, token;
+ rx->rx_doorbell = MCX_WQ_DOORBELL_BASE +
+ (db * MCX_WQ_DOORBELL_STRIDE);
+
npages = howmany((1 << MCX_LOG_RQ_SIZE) * sizeof(struct mcx_rq_entry),
MCX_PAGE_SIZE);
paslen = npages * sizeof(*pas);
@@ -4662,7 +4672,7 @@ mcx_create_rq(struct mcx_softc *sc, struct mcx_rx *rx, int db, int cqn)
mbin->rq_wq.wq_type = MCX_WQ_CTX_TYPE_CYCLIC;
mbin->rq_wq.wq_pd = htobe32(sc->sc_pd);
mbin->rq_wq.wq_doorbell = htobe64(MCX_DMA_DVA(&sc->sc_doorbell_mem) +
- MCX_WQ_DOORBELL_BASE + (db * MCX_WQ_DOORBELL_STRIDE));
+ rx->rx_doorbell);
mbin->rq_wq.wq_log_stride = htobe16(4);
mbin->rq_wq.wq_log_size = MCX_LOG_RQ_SIZE;
@@ -4694,9 +4704,8 @@ mcx_create_rq(struct mcx_softc *sc, struct mcx_rx *rx, int db, int cqn)
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));
+ bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&sc->sc_doorbell_mem),
+ rx->rx_doorbell, sizeof(uint32_t), BUS_DMASYNC_PREWRITE);
return (0);
@@ -4801,6 +4810,9 @@ mcx_destroy_rq(struct mcx_softc *sc, struct mcx_rx *rx)
return -1;
}
+ bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&sc->sc_doorbell_mem),
+ rx->rx_doorbell, sizeof(uint32_t), BUS_DMASYNC_POSTWRITE);
+
bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&rx->rx_rq_mem),
0, MCX_DMA_LEN(&rx->rx_rq_mem), BUS_DMASYNC_POSTWRITE);
mcx_dmamem_free(sc, &rx->rx_rq_mem);
@@ -4977,9 +4989,11 @@ mcx_create_sq(struct mcx_softc *sc, struct mcx_tx *tx, int uar, int db,
struct mcx_cmd_create_sq_out *out;
int error;
uint64_t *pas;
- uint8_t *doorbell;
int insize, npages, paslen, token;
+ tx->tx_doorbell = MCX_WQ_DOORBELL_BASE +
+ (db * MCX_WQ_DOORBELL_STRIDE);
+
npages = howmany((1 << MCX_LOG_SQ_SIZE) * sizeof(struct mcx_sq_entry),
MCX_PAGE_SIZE);
paslen = npages * sizeof(*pas);
@@ -5019,7 +5033,7 @@ mcx_create_sq(struct mcx_softc *sc, struct mcx_tx *tx, int uar, int db,
mbin->sq_wq.wq_pd = htobe32(sc->sc_pd);
mbin->sq_wq.wq_uar_page = htobe32(uar);
mbin->sq_wq.wq_doorbell = htobe64(MCX_DMA_DVA(&sc->sc_doorbell_mem) +
- MCX_WQ_DOORBELL_BASE + (db * MCX_WQ_DOORBELL_STRIDE));
+ tx->tx_doorbell);
mbin->sq_wq.wq_log_stride = htobe16(MCX_LOG_SQ_ENTRY_SIZE);
mbin->sq_wq.wq_log_size = MCX_LOG_SQ_SIZE;
@@ -5053,9 +5067,8 @@ mcx_create_sq(struct mcx_softc *sc, struct mcx_tx *tx, int uar, int db,
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);
+ bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&sc->sc_doorbell_mem),
+ tx->tx_doorbell, sizeof(uint32_t), BUS_DMASYNC_PREWRITE);
return (0);
@@ -5104,6 +5117,9 @@ mcx_destroy_sq(struct mcx_softc *sc, struct mcx_tx *tx)
return -1;
}
+ bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&sc->sc_doorbell_mem),
+ tx->tx_doorbell, sizeof(uint32_t), BUS_DMASYNC_POSTWRITE);
+
bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&tx->tx_sq_mem),
0, MCX_DMA_LEN(&tx->tx_sq_mem), BUS_DMASYNC_POSTWRITE);
mcx_dmamem_free(sc, &tx->tx_sq_mem);
@@ -6579,7 +6595,12 @@ mcx_rx_fill_slots(struct mcx_softc *sc, struct mcx_rx *rx, uint nslots)
rx->rx_prod = p;
- htobem32(rx->rx_doorbell, p & MCX_WQ_DOORBELL_MASK);
+ bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&sc->sc_doorbell_mem),
+ rx->rx_doorbell, sizeof(uint32_t), BUS_DMASYNC_POSTWRITE);
+ htobem32(MCX_DMA_OFF(&sc->sc_doorbell_mem, rx->rx_doorbell),
+ p & MCX_WQ_DOORBELL_MASK);
+ bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&sc->sc_doorbell_mem),
+ rx->rx_doorbell, sizeof(uint32_t), BUS_DMASYNC_PREWRITE);
return (nslots - fills);
}
@@ -6791,24 +6812,32 @@ mcx_next_cq_entry(struct mcx_softc *sc, struct mcx_cq *cq)
static void
mcx_arm_cq(struct mcx_softc *sc, struct mcx_cq *cq, int uar)
{
+ struct mcx_cq_doorbell *db;
bus_size_t offset;
uint32_t val;
uint64_t uval;
- offset = (MCX_PAGE_SIZE * uar);
val = ((cq->cq_count) & 3) << MCX_CQ_DOORBELL_ARM_CMD_SN_SHIFT;
val |= (cq->cq_cons & MCX_CQ_DOORBELL_ARM_CI_MASK);
- cq->cq_doorbell[0] = htobe32(cq->cq_cons & MCX_CQ_DOORBELL_ARM_CI_MASK);
- cq->cq_doorbell[1] = htobe32(val);
+ db = MCX_DMA_OFF(&sc->sc_doorbell_mem, cq->cq_doorbell);
+
+ bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&sc->sc_doorbell_mem),
+ cq->cq_doorbell, sizeof(*db), BUS_DMASYNC_POSTWRITE);
- uval = val;
- uval <<= 32;
+ htobem32(&db->db_update_ci, cq->cq_cons & MCX_CQ_DOORBELL_ARM_CI_MASK);
+ htobem32(&db->db_arm_ci, val);
+
+ bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&sc->sc_doorbell_mem),
+ cq->cq_doorbell, sizeof(*db), BUS_DMASYNC_PREWRITE);
+
+ offset = (MCX_PAGE_SIZE * uar) + MCX_UAR_CQ_DOORBELL;
+
+ uval = (uint64_t)val << 32;
uval |= cq->cq_n;
- bus_space_write_raw_8(sc->sc_memt, sc->sc_memh,
- offset + MCX_UAR_CQ_DOORBELL, htobe64(uval));
- mcx_bar(sc, offset + MCX_UAR_CQ_DOORBELL, sizeof(uint64_t),
- BUS_SPACE_BARRIER_WRITE);
+
+ bus_space_write_raw_8(sc->sc_memt, sc->sc_memh, offset, htobe64(uval));
+ mcx_bar(sc, offset, sizeof(uval), BUS_SPACE_BARRIER_WRITE);
}
void
@@ -7733,20 +7762,27 @@ mcx_start(struct ifqueue *ifq)
0, MCX_DMA_LEN(&tx->tx_sq_mem), BUS_DMASYNC_PREWRITE);
if (used) {
- htobem32(tx->tx_doorbell, tx->tx_prod & MCX_WQ_DOORBELL_MASK);
+ bus_size_t blueflame;
- membar_sync();
+ bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&sc->sc_doorbell_mem),
+ tx->tx_doorbell, sizeof(uint32_t), BUS_DMASYNC_POSTWRITE);
+ htobem32(MCX_DMA_OFF(&sc->sc_doorbell_mem, tx->tx_doorbell),
+ tx->tx_prod & MCX_WQ_DOORBELL_MASK);
+ bus_dmamap_sync(sc->sc_dmat, MCX_DMA_MAP(&sc->sc_doorbell_mem),
+ tx->tx_doorbell, sizeof(uint32_t), BUS_DMASYNC_PREWRITE);
/*
* write the first 64 bits of the last sqe we produced
* to the blue flame buffer
*/
+
+ blueflame = bf_base + tx->tx_bf_offset;
bus_space_write_raw_8(sc->sc_memt, sc->sc_memh,
- bf_base + tx->tx_bf_offset, *bf);
+ blueflame, *bf);
+ mcx_bar(sc, blueflame, sizeof(*bf), BUS_SPACE_BARRIER_WRITE);
+
/* next write goes to the other buffer */
tx->tx_bf_offset ^= sc->sc_bf_size;
-
- membar_sync();
}
}