summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorJonathan Matthew <jmatthew@cvs.openbsd.org>2021-04-23 07:00:59 +0000
committerJonathan Matthew <jmatthew@cvs.openbsd.org>2021-04-23 07:00:59 +0000
commitbd5e9f7d3d49e98aca1ea6968f193b87cc18c7ac (patch)
treebc58fd23eb62e4cb9b83a6a0fbb6b9b1c256c395 /sys/dev/pci
parent12b073e46a4ba1153661fcf8c28c71035e593f98 (diff)
When we have a single tx/rx queue, the cp ring is also used for async
events, so it can't be allocated when the interface is brought up and freed when it's taken down. ok dlg@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_bnxt.c67
1 files changed, 37 insertions, 30 deletions
diff --git a/sys/dev/pci/if_bnxt.c b/sys/dev/pci/if_bnxt.c
index ac9cc4a510d..931d02ccda7 100644
--- a/sys/dev/pci/if_bnxt.c
+++ b/sys/dev/pci/if_bnxt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bnxt.c,v 1.30 2021/04/23 04:58:34 jmatthew Exp $ */
+/* $OpenBSD: if_bnxt.c,v 1.31 2021/04/23 07:00:58 jmatthew Exp $ */
/*-
* Broadcom NetXtreme-C/E network driver.
*
@@ -730,32 +730,35 @@ bnxt_queue_up(struct bnxt_softc *sc, struct bnxt_queue *bq)
goto free_tx;
}
- cp->ring_mem = bnxt_dmamem_alloc(sc, PAGE_SIZE * BNXT_CP_PAGES);
- if (cp->ring_mem == NULL) {
- printf("%s: failed to allocate completion ring %d mem\n",
- DEVNAME(sc), bq->q_index);
- goto free_rx;
- }
- cp->ring.vaddr = BNXT_DMA_KVA(cp->ring_mem);
- cp->ring.paddr = BNXT_DMA_DVA(cp->ring_mem);
- cp->cons = UINT32_MAX;
- cp->v_bit = 1;
- bnxt_mark_cpr_invalid(cp);
-
- if (bnxt_hwrm_ring_alloc(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
- &cp->ring, (uint16_t)HWRM_NA_SIGNATURE,
- HWRM_NA_SIGNATURE, 1) != 0) {
- printf("%s: failed to allocate completion queue %d\n",
- DEVNAME(sc), bq->q_index);
- goto free_rx;
- }
+ /* completion ring is already allocated if we only have one queue */
+ if (sc->sc_nqueues > 1) {
+ cp->ring_mem = bnxt_dmamem_alloc(sc, PAGE_SIZE * BNXT_CP_PAGES);
+ if (cp->ring_mem == NULL) {
+ printf("%s: failed to allocate completion ring %d mem\n",
+ DEVNAME(sc), bq->q_index);
+ goto free_rx;
+ }
+ cp->ring.vaddr = BNXT_DMA_KVA(cp->ring_mem);
+ cp->ring.paddr = BNXT_DMA_DVA(cp->ring_mem);
+ cp->cons = UINT32_MAX;
+ cp->v_bit = 1;
+ bnxt_mark_cpr_invalid(cp);
+
+ if (bnxt_hwrm_ring_alloc(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
+ &cp->ring, (uint16_t)HWRM_NA_SIGNATURE,
+ HWRM_NA_SIGNATURE, 1) != 0) {
+ printf("%s: failed to allocate completion queue %d\n",
+ DEVNAME(sc), bq->q_index);
+ goto free_rx;
+ }
- if (bnxt_set_cp_ring_aggint(sc, cp) != 0) {
- printf("%s: failed to set interrupt %d aggregation\n",
- DEVNAME(sc), bq->q_index);
- goto free_rx;
+ if (bnxt_set_cp_ring_aggint(sc, cp) != 0) {
+ printf("%s: failed to set interrupt %d aggregation\n",
+ DEVNAME(sc), bq->q_index);
+ goto free_rx;
+ }
+ bnxt_write_cp_doorbell(sc, &cp->ring, 1);
}
- bnxt_write_cp_doorbell(sc, &cp->ring, 1);
if (bnxt_hwrm_stat_ctx_alloc(sc, &bq->q_cp,
BNXT_DMA_DVA(sc->sc_stats_ctx_mem) +
@@ -960,17 +963,21 @@ bnxt_queue_down(struct bnxt_softc *sc, struct bnxt_queue *bq)
&rx->rx_ag_ring);
bnxt_hwrm_ring_free(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
&rx->rx_ring);
- bnxt_hwrm_ring_free(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
- &cp->ring);
+
+ /* if only one queue, leave cp ring in place for async events */
+ if (sc->sc_nqueues > 1) {
+ bnxt_hwrm_ring_free(sc, HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
+ &cp->ring);
+
+ bnxt_dmamem_free(sc, cp->ring_mem);
+ cp->ring_mem = NULL;
+ }
bnxt_dmamem_free(sc, rx->rx_ring_mem);
rx->rx_ring_mem = NULL;
bnxt_dmamem_free(sc, tx->tx_ring_mem);
tx->tx_ring_mem = NULL;
-
- bnxt_dmamem_free(sc, cp->ring_mem);
- cp->ring_mem = NULL;
}
void