diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2020-07-13 16:18:53 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2020-07-13 16:18:53 +0000 |
commit | 9e6e80a0bb3bbb3a34d0337f7b2296da7c3d2916 (patch) | |
tree | 69c85cba99e9b87a845fbe094da86024dee49555 /sys | |
parent | 4aa411c38c3f3878e03ec89da9e8a636ab44fde3 (diff) |
Increase iwx(4) command queue size to the size expected by hardware.
The iwx(4) command queue has 256 entries in hardware. The Linux driver
contains an abstraction layer which allows it to allocate just 32 command
queue entries in software. Because I misunderstood how this works iwx(4)
ended up with 32 command queue entries, but without a shim which presents
these 32 entries as 256 entries to hardware.
Our command queue size was later bumped to 64 to make fatal firmware errors
during initialization disappear. The problem was still not fully understood
at that time. I didn't realize that firmware errors coincided with the
command queue index wrapping around.
Hardware expects the queue to wrap at 256 entries so fix this problem for
good in a simple way: Allocate 256 entries for the command queue, just
like iwm(4) does.
This will allow us to enable background scanning on iwx(4), which so far
triggered firmware errors due to additional scan commands causing the
command queue index to wrap at 64.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/pci/if_iwx.c | 37 | ||||
-rw-r--r-- | sys/dev/pci/if_iwxreg.h | 3 |
2 files changed, 12 insertions, 28 deletions
diff --git a/sys/dev/pci/if_iwx.c b/sys/dev/pci/if_iwx.c index 62327da989d..a24beaeeb46 100644 --- a/sys/dev/pci/if_iwx.c +++ b/sys/dev/pci/if_iwx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwx.c,v 1.39 2020/07/10 13:22:20 patrick Exp $ */ +/* $OpenBSD: if_iwx.c,v 1.40 2020/07/13 16:18:52 stsp Exp $ */ /* * Copyright (c) 2014, 2016 genua gmbh <info@genua.de> @@ -801,7 +801,7 @@ iwx_ctxt_info_init(struct iwx_softc *sc, const struct iwx_fw_sects *fws) ctxt_info->hcmd_cfg.cmd_queue_addr = htole64(sc->txq[IWX_DQA_CMD_QUEUE].desc_dma.paddr); ctxt_info->hcmd_cfg.cmd_queue_size = - IWX_TFD_QUEUE_CB_SIZE(IWX_CMD_QUEUE_SIZE); + IWX_TFD_QUEUE_CB_SIZE(IWX_TX_RING_COUNT); /* allocate ucode sections in dram and set addresses */ err = iwx_init_fw_sec(sc, fws, &ctxt_info->dram); @@ -1642,20 +1642,15 @@ iwx_alloc_tx_ring(struct iwx_softc *sc, struct iwx_tx_ring *ring, int qid) { bus_addr_t paddr; bus_size_t size; - int i, err, qlen; + int i, err; ring->qid = qid; ring->queued = 0; ring->cur = 0; ring->tail = 0; - if (qid == IWX_DQA_CMD_QUEUE) - qlen = IWX_CMD_QUEUE_SIZE; - else - qlen = IWX_TX_RING_COUNT; - /* Allocate TX descriptors (256-byte aligned). */ - size = qlen * sizeof (struct iwx_tfh_tfd); + size = IWX_TX_RING_COUNT * sizeof(struct iwx_tfh_tfd); err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->desc_dma, size, 256); if (err) { printf("%s: could not allocate TX ring DMA memory\n", @@ -1688,7 +1683,7 @@ iwx_alloc_tx_ring(struct iwx_softc *sc, struct iwx_tx_ring *ring, int qid) goto fail; } - size = qlen * sizeof(struct iwx_device_cmd); + size = IWX_TX_RING_COUNT * sizeof(struct iwx_device_cmd); err = iwx_dma_contig_alloc(sc->sc_dmat, &ring->cmd_dma, size, IWX_FIRST_TB_SIZE_ALIGN); if (err) { @@ -1698,7 +1693,7 @@ iwx_alloc_tx_ring(struct iwx_softc *sc, struct iwx_tx_ring *ring, int qid) ring->cmd = ring->cmd_dma.vaddr; paddr = ring->cmd_dma.paddr; - for (i = 0; i < qlen; i++) { + for (i = 0; i < IWX_TX_RING_COUNT; i++) { struct iwx_tx_data *data = &ring->data[i]; size_t mapsize; @@ -1730,14 +1725,9 @@ fail: iwx_free_tx_ring(sc, ring); void iwx_reset_tx_ring(struct iwx_softc *sc, struct iwx_tx_ring *ring) { - int i, qlen; - - if (ring->qid == IWX_DQA_CMD_QUEUE) - qlen = IWX_CMD_QUEUE_SIZE; - else - qlen = IWX_TX_RING_COUNT; + int i; - for (i = 0; i < qlen; i++) { + for (i = 0; i < IWX_TX_RING_COUNT; i++) { struct iwx_tx_data *data = &ring->data[i]; if (data->m != NULL) { @@ -1765,18 +1755,13 @@ iwx_reset_tx_ring(struct iwx_softc *sc, struct iwx_tx_ring *ring) void iwx_free_tx_ring(struct iwx_softc *sc, struct iwx_tx_ring *ring) { - int i, qlen; + int i; iwx_dma_contig_free(&ring->desc_dma); iwx_dma_contig_free(&ring->cmd_dma); iwx_dma_contig_free(&ring->bc_tbl); - if (ring->qid == IWX_DQA_CMD_QUEUE) - qlen = IWX_CMD_QUEUE_SIZE; - else - qlen = IWX_TX_RING_COUNT; - - for (i = 0; i < qlen; i++) { + for (i = 0; i < IWX_TX_RING_COUNT; i++) { struct iwx_tx_data *data = &ring->data[i]; if (data->m != NULL) { @@ -3853,7 +3838,7 @@ iwx_send_cmd(struct iwx_softc *sc, struct iwx_host_cmd *hcmd) /* Kick command ring. */ DPRINTF(("%s: sending command 0x%x\n", __func__, code)); ring->queued++; - ring->cur = (ring->cur + 1) % IWX_CMD_QUEUE_SIZE; + ring->cur = (ring->cur + 1) % IWX_TX_RING_COUNT; IWX_WRITE(sc, IWX_HBUS_TARG_WRPTR, ring->qid << 16 | ring->cur); if (!async) { diff --git a/sys/dev/pci/if_iwxreg.h b/sys/dev/pci/if_iwxreg.h index bae735764f7..419efccd26f 100644 --- a/sys/dev/pci/if_iwxreg.h +++ b/sys/dev/pci/if_iwxreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwxreg.h,v 1.15 2020/06/22 16:25:55 stsp Exp $ */ +/* $OpenBSD: if_iwxreg.h,v 1.16 2020/07/13 16:18:52 stsp Exp $ */ /*- * Based on BSD-licensed source modules in the Linux iwlwifi driver, @@ -1402,7 +1402,6 @@ enum iwx_gen2_tx_fifo { #define IWX_TX_QUEUE_CFG_TFD_SHORT_FORMAT (1 << 1) #define IWX_DEFAULT_QUEUE_SIZE IWX_TFD_QUEUE_SIZE_MAX -#define IWX_CMD_QUEUE_SIZE 64 /** * struct iwx_tx_queue_cfg_cmd - txq hw scheduler config command |