summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_iwn.c65
-rw-r--r--sys/dev/pci/if_iwnreg.h8
-rw-r--r--sys/dev/pci/if_iwnvar.h3
-rw-r--r--sys/dev/pci/if_wpi.c53
-rw-r--r--sys/dev/pci/if_wpireg.h5
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