diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_iwn.c | 65 | ||||
-rw-r--r-- | sys/dev/pci/if_iwnreg.h | 8 | ||||
-rw-r--r-- | sys/dev/pci/if_iwnvar.h | 3 | ||||
-rw-r--r-- | sys/dev/pci/if_wpi.c | 53 | ||||
-rw-r--r-- | sys/dev/pci/if_wpireg.h | 5 |
5 files changed, 75 insertions, 59 deletions
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c index 0a68f1ef8a3..2fff50a85fe 100644 --- a/sys/dev/pci/if_iwn.c +++ b/sys/dev/pci/if_iwn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwn.c,v 1.56 2009/05/28 16:03:23 damien Exp $ */ +/* $OpenBSD: if_iwn.c,v 1.57 2009/05/29 08:25:45 damien Exp $ */ /*- * Copyright (c) 2007-2009 Damien Bergamini <damien.bergamini@free.fr> @@ -273,6 +273,7 @@ static const struct iwn_hal iwn4965_hal = { #endif &iwn4965_sensitivity_limits, IWN4965_NTXQUEUES, + IWN4965_NDMACHNLS, IWN4965_ID_BROADCAST, IWN4965_RXONSZ, IWN4965_SCHEDSZ, @@ -302,6 +303,7 @@ static const struct iwn_hal iwn5000_hal = { #endif &iwn5000_sensitivity_limits, IWN5000_NTXQUEUES, + IWN5000_NDMACHNLS, IWN5000_ID_BROADCAST, IWN5000_RXONSZ, IWN5000_SCHEDSZ, @@ -1149,20 +1151,8 @@ fail: iwn_free_tx_ring(sc, ring); void iwn_reset_tx_ring(struct iwn_softc *sc, struct iwn_tx_ring *ring) { - uint32_t tmp; - int i, ntries; + int i; - if (iwn_nic_lock(sc) == 0) { - IWN_WRITE(sc, IWN_FH_TX_CONFIG(ring->qid), 0); - for (ntries = 0; ntries < 200; ntries++) { - tmp = IWN_READ(sc, IWN_FH_TX_STATUS); - if ((tmp & IWN_FH_TX_STATUS_IDLE(ring->qid)) == - IWN_FH_TX_STATUS_IDLE(ring->qid)) - break; - DELAY(10); - } - iwn_nic_unlock(sc); - } for (i = 0; i < IWN_TX_RING_COUNT; i++) { struct iwn_tx_data *data = &ring->data[i]; @@ -4793,21 +4783,21 @@ iwn5000_load_firmware_section(struct iwn_softc *sc, uint32_t dst, if ((error = iwn_nic_lock(sc)) != 0) return error; - IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_CHNL), + IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_DMACHNL), IWN_FH_TX_CONFIG_DMA_PAUSE); - IWN_WRITE(sc, IWN_FH_SRAM_ADDR(IWN_SRVC_CHNL), dst); - IWN_WRITE(sc, IWN_FH_TFBD_CTRL0(IWN_SRVC_CHNL), + IWN_WRITE(sc, IWN_FH_SRAM_ADDR(IWN_SRVC_DMACHNL), dst); + IWN_WRITE(sc, IWN_FH_TFBD_CTRL0(IWN_SRVC_DMACHNL), IWN_LOADDR(dma->paddr)); - IWN_WRITE(sc, IWN_FH_TFBD_CTRL1(IWN_SRVC_CHNL), + IWN_WRITE(sc, IWN_FH_TFBD_CTRL1(IWN_SRVC_DMACHNL), IWN_HIADDR(dma->paddr) << 28 | size); - IWN_WRITE(sc, IWN_FH_TXBUF_STATUS(IWN_SRVC_CHNL), + IWN_WRITE(sc, IWN_FH_TXBUF_STATUS(IWN_SRVC_DMACHNL), IWN_FH_TXBUF_STATUS_TBNUM(1) | IWN_FH_TXBUF_STATUS_TBIDX(1) | IWN_FH_TXBUF_STATUS_TFBD_VALID); /* Kick Flow Handler to start DMA transfer. */ - IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_CHNL), + IWN_WRITE(sc, IWN_FH_TX_CONFIG(IWN_SRVC_DMACHNL), IWN_FH_TX_CONFIG_DMA_ENA | IWN_FH_TX_CONFIG_CIRQ_HOST_ENDTFD); iwn_nic_unlock(sc); @@ -5101,7 +5091,7 @@ int iwn_hw_init(struct iwn_softc *sc) { const struct iwn_hal *hal = sc->sc_hal; - int error, qid; + int error, chnl, qid; /* Clear pending interrupts. */ IWN_WRITE(sc, IWN_INT, 0xffffffff); @@ -5158,12 +5148,15 @@ iwn_hw_init(struct iwn_softc *sc) /* Set physical address of TX ring (256-byte aligned.) */ IWN_WRITE(sc, IWN_FH_CBBC_QUEUE(qid), txq->desc_dma.paddr >> 8); - /* Enable TX for this ring. */ - IWN_WRITE(sc, IWN_FH_TX_CONFIG(qid), + } + iwn_nic_unlock(sc); + + /* Enable DMA channels. */ + for (chnl = 0; chnl < hal->ndmachnls; chnl++) { + IWN_WRITE(sc, IWN_FH_TX_CONFIG(chnl), IWN_FH_TX_CONFIG_DMA_ENA | IWN_FH_TX_CONFIG_DMA_CREDIT_ENA); } - iwn_nic_unlock(sc); /* Clear "radio off" and "commands blocked" bits. */ IWN_WRITE(sc, IWN_UCODE_GP1_CLR, IWN_UCODE_GP1_RFKILL); @@ -5198,7 +5191,8 @@ void iwn_hw_stop(struct iwn_softc *sc) { const struct iwn_hal *hal = sc->sc_hal; - int qid; + int chnl, qid, ntries; + uint32_t tmp; IWN_WRITE(sc, IWN_RESET, IWN_RESET_NEVO); @@ -5213,13 +5207,28 @@ iwn_hw_stop(struct iwn_softc *sc) /* Stop TX scheduler. */ iwn_prph_write(sc, hal->sched_txfact_addr, 0); - /* Stop all TX rings. */ - for (qid = 0; qid < hal->ntxqs; qid++) - iwn_reset_tx_ring(sc, &sc->txq[qid]); + /* Stop all DMA channels. */ + if (iwn_nic_lock(sc) == 0) { + for (chnl = 0; chnl < hal->ndmachnls; chnl++) { + IWN_WRITE(sc, IWN_FH_TX_CONFIG(chnl), 0); + for (ntries = 0; ntries < 200; ntries++) { + tmp = IWN_READ(sc, IWN_FH_TX_STATUS); + if ((tmp & IWN_FH_TX_STATUS_IDLE(chnl)) == + IWN_FH_TX_STATUS_IDLE(chnl)) + break; + DELAY(10); + } + } + iwn_nic_unlock(sc); + } /* Stop RX ring. */ iwn_reset_rx_ring(sc, &sc->rxq); + /* Reset all TX rings. */ + for (qid = 0; qid < hal->ntxqs; qid++) + iwn_reset_tx_ring(sc, &sc->txq[qid]); + if (iwn_nic_lock(sc) == 0) { iwn_prph_write(sc, IWN_APMG_CLK_DIS, IWN_APMG_CLK_DMA_RQT); iwn_nic_unlock(sc); diff --git a/sys/dev/pci/if_iwnreg.h b/sys/dev/pci/if_iwnreg.h index 8c1869e8e1a..8a746917be6 100644 --- a/sys/dev/pci/if_iwnreg.h +++ b/sys/dev/pci/if_iwnreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwnreg.h,v 1.25 2009/05/27 09:50:31 damien Exp $ */ +/* $OpenBSD: if_iwnreg.h,v 1.26 2009/05/29 08:25:45 damien Exp $ */ /*- * Copyright (c) 2007, 2008 @@ -25,7 +25,11 @@ #define IWN4965_NTXQUEUES 16 #define IWN5000_NTXQUEUES 20 -#define IWN_SRVC_CHNL 9 + +#define IWN4965_NDMACHNLS 7 +#define IWN5000_NDMACHNLS 8 + +#define IWN_SRVC_DMACHNL 9 /* Maximum number of DMA segments for TX. */ #define IWN_MAX_SCATTER 20 diff --git a/sys/dev/pci/if_iwnvar.h b/sys/dev/pci/if_iwnvar.h index 35390eec9e1..d321892c364 100644 --- a/sys/dev/pci/if_iwnvar.h +++ b/sys/dev/pci/if_iwnvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_iwnvar.h,v 1.11 2009/05/20 16:31:50 damien Exp $ */ +/* $OpenBSD: if_iwnvar.h,v 1.12 2009/05/29 08:25:45 damien Exp $ */ /*- * Copyright (c) 2007, 2008 @@ -180,6 +180,7 @@ struct iwn_hal { #endif const struct iwn_sensitivity_limits *limits; int ntxqs; + int ndmachnls; uint8_t broadcast_id; int rxonsz; int schedsz; diff --git a/sys/dev/pci/if_wpi.c b/sys/dev/pci/if_wpi.c index 307cd95563c..d902ece384b 100644 --- a/sys/dev/pci/if_wpi.c +++ b/sys/dev/pci/if_wpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wpi.c,v 1.86 2009/05/12 19:10:57 damien Exp $ */ +/* $OpenBSD: if_wpi.c,v 1.87 2009/05/29 08:25:45 damien Exp $ */ /*- * Copyright (c) 2006-2008 @@ -785,20 +785,8 @@ fail: wpi_free_tx_ring(sc, ring); void wpi_reset_tx_ring(struct wpi_softc *sc, struct wpi_tx_ring *ring) { - uint32_t tmp; - int i, ntries; + int i; - if (wpi_nic_lock(sc) == 0) { - WPI_WRITE(sc, WPI_FH_TX_CONFIG(ring->qid), 0); - for (ntries = 0; ntries < 100; ntries++) { - tmp = WPI_READ(sc, WPI_FH_TX_STATUS); - if ((tmp & WPI_FH_TX_STATUS_IDLE(ring->qid)) == - WPI_FH_TX_STATUS_IDLE(ring->qid)) - break; - DELAY(10); - } - wpi_nic_unlock(sc); - } for (i = 0; i < WPI_TX_RING_COUNT; i++) { struct wpi_tx_data *data = &ring->data[i]; @@ -3120,7 +3108,7 @@ wpi_nic_config(struct wpi_softc *sc) int wpi_hw_init(struct wpi_softc *sc) { - int qid, ntries, error; + int chnl, ntries, error; /* Clear pending interrupts. */ WPI_WRITE(sc, WPI_INT, 0xffffffff); @@ -3188,11 +3176,11 @@ wpi_hw_init(struct wpi_softc *sc) WPI_WRITE(sc, WPI_FH_TX_BASE, sc->shared_dma.paddr); WPI_WRITE(sc, WPI_FH_MSG_CONFIG, 0xffff05a5); - for (qid = 0; qid < 6; qid++) { - WPI_WRITE(sc, WPI_FH_CBBC_CTRL(qid), 0); - WPI_WRITE(sc, WPI_FH_CBBC_BASE(qid), 0); - /* Enable TX for this ring. */ - WPI_WRITE(sc, WPI_FH_TX_CONFIG(qid), 0x80200008); + /* Enable all DMA channels. */ + for (chnl = 0; chnl < WPI_NDMACHNLS; chnl++) { + WPI_WRITE(sc, WPI_FH_CBBC_CTRL(chnl), 0); + WPI_WRITE(sc, WPI_FH_CBBC_BASE(chnl), 0); + WPI_WRITE(sc, WPI_FH_TX_CONFIG(chnl), 0x80200008); } wpi_nic_unlock(sc); (void)WPI_READ(sc, WPI_FH_TX_BASE); /* barrier */ @@ -3227,7 +3215,8 @@ wpi_hw_init(struct wpi_softc *sc) void wpi_hw_stop(struct wpi_softc *sc) { - int qid; + int chnl, qid, ntries; + uint32_t tmp; WPI_WRITE(sc, WPI_RESET, WPI_RESET_NEVO); @@ -3239,19 +3228,31 @@ wpi_hw_stop(struct wpi_softc *sc) /* Make sure we no longer hold the NIC lock. */ wpi_nic_unlock(sc); - /* Stop TX scheduler. */ if (wpi_nic_lock(sc) == 0) { + /* Stop TX scheduler. */ wpi_prph_write(sc, WPI_ALM_SCHED_MODE, 0); + + /* Stop all DMA channels. */ + for (chnl = 0; chnl < WPI_NDMACHNLS; chnl++) { + WPI_WRITE(sc, WPI_FH_TX_CONFIG(chnl), 0); + for (ntries = 0; ntries < 100; ntries++) { + tmp = WPI_READ(sc, WPI_FH_TX_STATUS); + if ((tmp & WPI_FH_TX_STATUS_IDLE(chnl)) == + WPI_FH_TX_STATUS_IDLE(chnl)) + break; + DELAY(10); + } + } wpi_nic_unlock(sc); } - /* Stop all TX rings. */ - for (qid = 0; qid < WPI_NTXQUEUES; qid++) - wpi_reset_tx_ring(sc, &sc->txq[qid]); - /* Stop RX ring. */ wpi_reset_rx_ring(sc, &sc->rxq); + /* Reset all TX rings. */ + for (qid = 0; qid < WPI_NTXQUEUES; qid++) + wpi_reset_tx_ring(sc, &sc->txq[qid]); + if (wpi_nic_lock(sc) == 0) { wpi_prph_write(sc, WPI_APMG_CLK_DIS, WPI_APMG_CLK_DMA_CLK_RQT); wpi_nic_unlock(sc); diff --git a/sys/dev/pci/if_wpireg.h b/sys/dev/pci/if_wpireg.h index e3a98caa277..aef053b2a5f 100644 --- a/sys/dev/pci/if_wpireg.h +++ b/sys/dev/pci/if_wpireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_wpireg.h,v 1.24 2009/05/24 18:51:12 damien Exp $ */ +/* $OpenBSD: if_wpireg.h,v 1.25 2009/05/29 08:25:45 damien Exp $ */ /*- * Copyright (c) 2006-2008 @@ -23,7 +23,8 @@ #define WPI_RX_RING_COUNT_LOG 6 #define WPI_RX_RING_COUNT (1 << WPI_RX_RING_COUNT_LOG) -#define WPI_NTXQUEUES 16 +#define WPI_NTXQUEUES 8 +#define WPI_NDMACHNLS 6 /* Maximum scatter/gather. */ #define WPI_MAX_SCATTER 4 |