summaryrefslogtreecommitdiffstats
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorstsp <stsp@openbsd.org>2020-07-13 16:18:52 +0000
committerstsp <stsp@openbsd.org>2020-07-13 16:18:52 +0000
commit50b95bf0a8c8c336e41dfa30f13e95d7cfe4b583 (patch)
tree1e4d7d18e51c6ff8176587eb8957d276822a0173 /sys/dev/pci
parentWhere we have a pointer (sc) to the relevant adapter_softc, use (diff)
downloadwireguard-openbsd-50b95bf0a8c8c336e41dfa30f13e95d7cfe4b583.tar.xz
wireguard-openbsd-50b95bf0a8c8c336e41dfa30f13e95d7cfe4b583.zip
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/dev/pci')
-rw-r--r--sys/dev/pci/if_iwx.c37
-rw-r--r--sys/dev/pci/if_iwxreg.h3
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