summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2004-12-04 17:24:07 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2004-12-04 17:24:07 +0000
commit574ecaad13b64447ec4608bb7d86cae17f7e9957 (patch)
tree2e608400c4405ff7f0c5c35557ad0fe289991b85 /sys/dev/pci
parentaf710e19c5ae140daa7db0d2c9e5309d8d626e93 (diff)
Clean DMA allocation of Tx and Rx rings
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_iwi.c714
-rw-r--r--sys/dev/pci/if_iwireg.h43
-rw-r--r--sys/dev/pci/if_iwivar.h75
3 files changed, 392 insertions, 440 deletions
diff --git a/sys/dev/pci/if_iwi.c b/sys/dev/pci/if_iwi.c
index 467a0b1b230..db5eb12bb9b 100644
--- a/sys/dev/pci/if_iwi.c
+++ b/sys/dev/pci/if_iwi.c
@@ -1,4 +1,4 @@
-/* $Id: if_iwi.c,v 1.13 2004/11/24 21:17:26 damien Exp $ */
+/* $Id: if_iwi.c,v 1.14 2004/12/04 17:24:06 damien Exp $ */
/*-
* Copyright (c) 2004
@@ -94,17 +94,19 @@ static const struct ieee80211_rateset iwi_rateset_11g =
int iwi_match(struct device *, void *, void *);
void iwi_attach(struct device *, struct device *, void *);
int iwi_detach(struct device *, int);
+int iwi_dma_alloc(struct iwi_softc *);
+void iwi_release(struct iwi_softc *);
int iwi_media_change(struct ifnet *);
void iwi_media_status(struct ifnet *, struct ifmediareq *);
u_int16_t iwi_read_prom_word(struct iwi_softc *, u_int8_t);
int iwi_newstate(struct ieee80211com *, enum ieee80211_state, int);
void iwi_fix_channel(struct ieee80211com *, struct mbuf *);
-void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_slot *, struct iwi_buf *,
+void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_buf *, int,
struct iwi_frame *);
-void iwi_notification_intr(struct iwi_softc *, struct iwi_buf *,
+void iwi_notification_intr(struct iwi_softc *, struct iwi_rx_buf *,
struct iwi_notif *);
void iwi_rx_intr(struct iwi_softc *);
-void iwi_tx_intr(struct iwi_softc *, int);
+void iwi_tx_intr(struct iwi_softc *);
int iwi_intr(void *);
int iwi_cmd(struct iwi_softc *, u_int8_t, void *, u_int8_t, int);
int iwi_tx_start(struct ifnet *, struct mbuf *, struct ieee80211_node *);
@@ -113,14 +115,6 @@ void iwi_watchdog(struct ifnet *);
int iwi_get_table0(struct iwi_softc *, u_int32_t *);
int iwi_get_radio(struct iwi_softc *, int *);
int iwi_ioctl(struct ifnet *, u_long, caddr_t);
-int iwi_init_buffers(struct iwi_softc *, int);
-void iwi_free_buffers(struct iwi_softc *);
-int iwi_init_tx_queue(struct iwi_softc *, int, int);
-void iwi_free_tx_queue(struct iwi_softc *, int);
-int iwi_init_rx_queue(struct iwi_softc *);
-void iwi_free_rx_queue(struct iwi_softc *);
-int iwi_init_queues(struct iwi_softc *);
-void iwi_free_queues(struct iwi_softc *);
void iwi_stop_master(struct iwi_softc *);
int iwi_reset(struct iwi_softc *);
int iwi_load_ucode(struct iwi_softc *, const char *);
@@ -230,6 +224,11 @@ iwi_attach(struct device *parent, struct device *self, void *aux)
return;
}
+ if (iwi_dma_alloc(sc) != 0) {
+ printf(": could not allocate DMA resources\n");
+ return;
+ }
+
ic->ic_phytype = IEEE80211_T_DS;
ic->ic_opmode = IEEE80211_M_STA;
ic->ic_state = IEEE80211_S_INIT;
@@ -331,6 +330,8 @@ iwi_detach(struct device* self, int flags)
ieee80211_ifdetach(ifp);
if_detach(ifp);
+ iwi_release(sc);
+
if (sc->sc_ih != NULL) {
pci_intr_disestablish(sc->sc_pct, sc->sc_ih);
sc->sc_ih = NULL;
@@ -342,6 +343,196 @@ iwi_detach(struct device* self, int flags)
}
int
+iwi_dma_alloc(struct iwi_softc *sc)
+{
+ int i, nsegs, error;
+
+ /*
+ * Allocate and map Tx ring
+ */
+ error = bus_dmamap_create(sc->sc_dmat,
+ sizeof (struct iwi_tx_desc) * IWI_TX_RING_SIZE, 1,
+ sizeof (struct iwi_tx_desc) * IWI_TX_RING_SIZE, 0, BUS_DMA_NOWAIT,
+ &sc->tx_ring_map);
+ if (error != 0) {
+ printf("%s: could not create tx ring DMA map\n",
+ sc->sc_dev.dv_xname);
+ goto fail;
+ }
+
+ error = bus_dmamem_alloc(sc->sc_dmat,
+ sizeof (struct iwi_tx_desc) * IWI_TX_RING_SIZE, PAGE_SIZE, 0,
+ &sc->tx_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ printf("%s: could not allocate tx ring DMA memory\n",
+ sc->sc_dev.dv_xname);
+ goto fail;
+ }
+
+ error = bus_dmamem_map(sc->sc_dmat, &sc->tx_ring_seg, nsegs,
+ sizeof (struct iwi_tx_desc) * IWI_TX_RING_SIZE,
+ (caddr_t *)&sc->tx_desc, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ printf("%s: could not map tx ring DMA memory\n",
+ sc->sc_dev.dv_xname);
+ goto fail;
+ }
+
+ error = bus_dmamap_load(sc->sc_dmat, sc->tx_ring_map, sc->tx_desc,
+ sizeof (struct iwi_tx_desc) * IWI_TX_RING_SIZE, NULL,
+ BUS_DMA_NOWAIT);
+ if (error != 0) {
+ printf("%s: could not load tx ring DMA map\n",
+ sc->sc_dev.dv_xname);
+ goto fail;
+ }
+
+ bzero(sc->tx_desc, sizeof (struct iwi_tx_desc) * IWI_TX_RING_SIZE);
+
+ /*
+ * Allocate and map command ring
+ */
+ error = bus_dmamap_create(sc->sc_dmat,
+ sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_SIZE, 1,
+ sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_SIZE, 0,
+ BUS_DMA_NOWAIT, &sc->cmd_ring_map);
+ if (error != 0) {
+ printf("%s: could not create command ring DMA map\n",
+ sc->sc_dev.dv_xname);
+ goto fail;
+ }
+
+ error = bus_dmamem_alloc(sc->sc_dmat,
+ sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_SIZE, PAGE_SIZE, 0,
+ &sc->cmd_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ printf("%s: could not allocate command ring DMA memory\n",
+ sc->sc_dev.dv_xname);
+ goto fail;
+ }
+
+ error = bus_dmamem_map(sc->sc_dmat, &sc->cmd_ring_seg, nsegs,
+ sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_SIZE,
+ (caddr_t *)&sc->cmd_desc, BUS_DMA_NOWAIT);
+ if (error != 0) {
+ printf("%s: could not map command ring DMA memory\n",
+ sc->sc_dev.dv_xname);
+ goto fail;
+ }
+
+ error = bus_dmamap_load(sc->sc_dmat, sc->cmd_ring_map, sc->cmd_desc,
+ sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_SIZE, NULL,
+ BUS_DMA_NOWAIT);
+ if (error != 0) {
+ printf("%s: could not load command ring DMA map\n",
+ sc->sc_dev.dv_xname);
+ goto fail;
+ }
+
+ bzero(sc->cmd_desc, sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_SIZE);
+
+ /*
+ * Allocate Tx buffers DMA maps
+ */
+ for (i = 0; i < IWI_TX_RING_SIZE; i++) {
+ error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, IWI_MAX_NSEG,
+ MCLBYTES, 0, BUS_DMA_NOWAIT, &sc->tx_buf[i].map);
+ if (error != 0) {
+ printf("%s: could not create tx buf DMA map",
+ sc->sc_dev.dv_xname);
+ goto fail;
+ }
+ }
+
+ /*
+ * Allocate and map Rx buffers
+ */
+ for (i = 0; i < IWI_RX_RING_SIZE; i++) {
+
+ error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, MCLBYTES,
+ 0, BUS_DMA_NOWAIT, &sc->rx_buf[i].map);
+ if (error != 0) {
+ printf("%s: could not create rx buf DMA map",
+ sc->sc_dev.dv_xname);
+ goto fail;
+ }
+
+ MGETHDR(sc->rx_buf[i].m, M_DONTWAIT, MT_DATA);
+ if (sc->rx_buf[i].m == NULL) {
+ printf("%s: could not allocate rx mbuf\n",
+ sc->sc_dev.dv_xname);
+ error = ENOMEM;
+ goto fail;
+ }
+
+ MCLGET(sc->rx_buf[i].m, M_DONTWAIT);
+ if (!(sc->rx_buf[i].m->m_flags & M_EXT)) {
+ m_freem(sc->rx_buf[i].m);
+ printf("%s: could not allocate rx mbuf cluster\n",
+ sc->sc_dev.dv_xname);
+ error = ENOMEM;
+ goto fail;
+ }
+
+ error = bus_dmamap_load(sc->sc_dmat, sc->rx_buf[i].map,
+ mtod(sc->rx_buf[i].m, void *), MCLBYTES, NULL,
+ BUS_DMA_NOWAIT);
+ if (error != 0) {
+ printf("%s: could not load rx buffer DMA map\n",
+ sc->sc_dev.dv_xname);
+ goto fail;
+ }
+ }
+
+ return 0;
+
+fail: iwi_release(sc);
+ return error;
+}
+
+void
+iwi_release(struct iwi_softc *sc)
+{
+ int i;
+
+ if (sc->tx_ring_map != NULL) {
+ if (sc->tx_desc != NULL) {
+ bus_dmamap_unload(sc->sc_dmat, sc->tx_ring_map);
+ bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->tx_desc,
+ sizeof (struct iwi_tx_desc) * IWI_TX_RING_SIZE);
+ bus_dmamem_free(sc->sc_dmat, &sc->tx_ring_seg, 1);
+ }
+ bus_dmamap_destroy(sc->sc_dmat, sc->tx_ring_map);
+ }
+
+ if (sc->cmd_ring_map != NULL) {
+ if (sc->cmd_desc != NULL) {
+ bus_dmamap_unload(sc->sc_dmat, sc->cmd_ring_map);
+ bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->cmd_desc,
+ sizeof (struct iwi_cmd_desc) * IWI_CMD_RING_SIZE);
+ bus_dmamem_free(sc->sc_dmat, &sc->cmd_ring_seg, 1);
+ }
+ bus_dmamap_destroy(sc->sc_dmat, sc->cmd_ring_map);
+ }
+
+ for (i = 0; i < IWI_TX_RING_SIZE; i++) {
+ if (sc->tx_buf[i].m != NULL) {
+ bus_dmamap_unload(sc->sc_dmat, sc->tx_buf[i].map);
+ m_freem(sc->tx_buf[i].m);
+ }
+ bus_dmamap_destroy(sc->sc_dmat, sc->tx_buf[i].map);
+ }
+
+ for (i = 0; i < IWI_RX_RING_SIZE; i++) {
+ if (sc->rx_buf[i].m != NULL) {
+ bus_dmamap_unload(sc->sc_dmat, sc->rx_buf[i].map);
+ m_freem(sc->rx_buf[i].m);
+ }
+ bus_dmamap_destroy(sc->sc_dmat, sc->rx_buf[i].map);
+ }
+}
+
+int
iwi_media_change(struct ifnet *ifp)
{
int error;
@@ -530,8 +721,8 @@ iwi_fix_channel(struct ieee80211com *ic, struct mbuf *m)
}
void
-iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_slot *slot,
- struct iwi_buf *buf, struct iwi_frame *frame)
+iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_buf *buf, int i,
+ struct iwi_frame *frame)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
@@ -620,6 +811,7 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_slot *slot,
sc->sc_dev.dv_xname);
return;
}
+
MCLGET(m, M_DONTWAIT);
if (!(m->m_flags & M_EXT)) {
m_freem(m);
@@ -638,11 +830,11 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_slot *slot,
}
buf->m = m;
- CSR_WRITE_4(sc, slot->csr, buf->map->dm_segs[0].ds_addr);
+ CSR_WRITE_4(sc, IWI_CSR_RX_BASE + i * 4, buf->map->dm_segs[0].ds_addr);
}
void
-iwi_notification_intr(struct iwi_softc *sc, struct iwi_buf *buf,
+iwi_notification_intr(struct iwi_softc *sc, struct iwi_rx_buf *buf,
struct iwi_notif *notif)
{
struct ieee80211com *ic = &sc->sc_ic;
@@ -725,17 +917,16 @@ iwi_notification_intr(struct iwi_softc *sc, struct iwi_buf *buf,
void
iwi_rx_intr(struct iwi_softc *sc)
{
- struct iwi_rx_queue *q = &sc->rxqueue;
- struct iwi_rx_slot *slot;
- struct iwi_buf *buf;
+ struct iwi_rx_buf *buf;
struct iwi_hdr *hdr;
u_int32_t r, i;
r = CSR_READ_4(sc, IWI_CSR_RX_READ_INDEX);
- for (i = (q->cur + 1) % q->size; i != r; i = (i + 1) % q->size) {
- slot = &q->slots[i];
- buf = slot->buf;
+ for (i = (sc->rx_cur + 1) % IWI_RX_RING_SIZE; i != r;
+ i = (i + 1) % IWI_RX_RING_SIZE) {
+
+ buf = &sc->rx_buf[i];
bus_dmamap_sync(sc->sc_dmat, buf->map, 0,
sizeof (struct iwi_hdr), BUS_DMASYNC_POSTREAD);
@@ -744,7 +935,7 @@ iwi_rx_intr(struct iwi_softc *sc)
switch (hdr->type) {
case IWI_HDR_TYPE_FRAME:
- iwi_frame_intr(sc, slot, buf,
+ iwi_frame_intr(sc, buf, i,
(struct iwi_frame *)(hdr + 1));
break;
@@ -760,23 +951,24 @@ iwi_rx_intr(struct iwi_softc *sc)
}
/* Tell the firmware what we have processed */
- q->cur = (r == 0) ? q->size - 1 : r - 1;
- CSR_WRITE_4(sc, IWI_CSR_RX_WRITE_INDEX, q->cur);
+ sc->rx_cur = (r == 0) ? IWI_RX_RING_SIZE - 1 : r - 1;
+ CSR_WRITE_4(sc, IWI_CSR_RX_WRITE_INDEX, sc->rx_cur);
}
void
-iwi_tx_intr(struct iwi_softc *sc, int index)
+iwi_tx_intr(struct iwi_softc *sc)
{
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
- struct iwi_tx_queue *q = &sc->txqueue[index];
- struct iwi_buf *buf;
+ struct iwi_tx_buf *buf;
u_int32_t r, i;
- r = CSR_READ_4(sc, q->csr_read);
+ r = CSR_READ_4(sc, IWI_CSR_TX1_READ_INDEX);
+
+ for (i = (sc->tx_old + 1) % IWI_TX_RING_SIZE; i != r;
+ i = (i + 1) % IWI_TX_RING_SIZE) {
- for (i = (q->old + 1) % q->size; i != r; i = (i + 1) % q->size) {
- buf = q->slots[i].buf;
+ buf = &sc->tx_buf[i];
bus_dmamap_unload(sc->sc_dmat, buf->map);
m_freem(buf->m);
@@ -791,11 +983,11 @@ iwi_tx_intr(struct iwi_softc *sc, int index)
/* kill watchdog timer */
sc->sc_tx_timer = 0;
- TAILQ_INSERT_TAIL(&sc->sc_free_buf, buf, next);
+ sc->tx_free++;
}
/* Remember what the firmware has processed */
- q->old = (r == 0) ? q->size - 1 : r - 1;
+ sc->tx_old = (r == 0) ? IWI_TX_RING_SIZE - 1 : r - 1;
/* Call start() since some buffer descriptors have been released */
ifp->if_flags &= ~IFF_OACTIVE;
@@ -819,20 +1011,11 @@ iwi_intr(void *arg)
if (r & IWI_INTR_RX_TRANSFER)
iwi_rx_intr(sc);
- if (r & IWI_INTR_TX0_TRANSFER)
+ if (r & IWI_INTR_CMD_TRANSFER)
wakeup(sc);
if (r & IWI_INTR_TX1_TRANSFER)
- iwi_tx_intr(sc, 1);
-
- if (r & IWI_INTR_TX2_TRANSFER)
- iwi_tx_intr(sc, 2);
-
- if (r & IWI_INTR_TX3_TRANSFER)
- iwi_tx_intr(sc, 3);
-
- if (r & IWI_INTR_TX4_TRANSFER)
- iwi_tx_intr(sc, 4);
+ iwi_tx_intr(sc);
if (r & IWI_INTR_FW_INITED) {
if (!(r & (IWI_INTR_FATAL_ERROR | IWI_INTR_PARITY_ERROR)))
@@ -855,37 +1038,27 @@ iwi_intr(void *arg)
int
iwi_cmd(struct iwi_softc *sc, u_int8_t type, void *data, u_int8_t len,
- int flags)
+ int async)
{
- struct iwi_tx_queue *q = &sc->txqueue[0];
- struct iwi_tx_slot *slot;
- struct iwi_hdr *hdr;
- struct iwi_cmd *cmd;
+ struct iwi_cmd_desc *desc;
DPRINTFN(2, ("TX!CMD!%u!%u\n", type, len));
- slot = &q->slots[q->cur];
-
- hdr = (struct iwi_hdr *)slot->virtaddr;
- hdr->type = IWI_HDR_TYPE_COMMAND;
- hdr->flags = IWI_HDR_FLAG_IRQ;
+ desc = &sc->cmd_desc[sc->cmd_cur];
+ desc->hdr.type = IWI_HDR_TYPE_COMMAND;
+ desc->hdr.flags = IWI_HDR_FLAG_IRQ;
+ desc->type = type;
+ desc->len = len;
+ bcopy(data, desc->data, len);
- cmd = (struct iwi_cmd *)(hdr + 1);
- cmd->type = type;
- cmd->len = len;
- bcopy(data, cmd->data, len);
-
- bus_dmamap_sync(sc->sc_dmat, q->map, q->cur * IWI_TX_SLOT_SIZE,
- sizeof (struct iwi_hdr) + sizeof (struct iwi_cmd),
- BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(sc->sc_dmat, sc->cmd_ring_map,
+ sc->cmd_cur * sizeof (struct iwi_cmd_desc),
+ sizeof (struct iwi_cmd_desc), BUS_DMASYNC_PREWRITE);
- q->cur = (q->cur + 1) % q->size;
- CSR_WRITE_4(sc, q->csr_write, q->cur);
+ sc->cmd_cur = (sc->cmd_cur + 1) % IWI_CMD_RING_SIZE;
+ CSR_WRITE_4(sc, IWI_CSR_CMD_WRITE_INDEX, sc->cmd_cur);
- if (flags & IWI_ASYNC_CMD)
- return 0;
-
- return tsleep(sc, 0, "iwicmd", hz);
+ return async ? 0 : tsleep(sc, 0, "iwicmd", hz);
}
int
@@ -893,12 +1066,9 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni)
{
struct iwi_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
- struct iwi_tx_queue *q = &sc->txqueue[1];
struct ieee80211_frame *wh;
- struct iwi_tx_slot *slot;
- struct iwi_buf *buf;
- struct iwi_hdr *hdr;
- struct iwi_data *data;
+ struct iwi_tx_buf *buf;
+ struct iwi_tx_desc *desc;
int error, i;
#if NBPFILTER > 0
@@ -924,7 +1094,8 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni)
/* trim IEEE802.11 header */
m_adj(m, sizeof (struct ieee80211_frame));
- buf = TAILQ_FIRST(&sc->sc_free_buf);
+ buf = &sc->tx_buf[sc->tx_cur];
+ desc = &sc->tx_desc[sc->tx_cur];
error = bus_dmamap_load_mbuf(sc->sc_dmat, buf->map, m, BUS_DMA_NOWAIT);
if (error != 0) {
@@ -934,51 +1105,45 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node *ni)
return error;
}
- TAILQ_REMOVE(&sc->sc_free_buf, buf, next);
-
buf->m = m;
buf->ni = ni;
- slot = &q->slots[q->cur];
- slot->buf = buf;
-
- hdr = (struct iwi_hdr *)slot->virtaddr;
- hdr->type = IWI_HDR_TYPE_DATA;
- hdr->flags = IWI_HDR_FLAG_IRQ;
-
- data = (struct iwi_data *)(hdr + 1);
- data->cmd = IWI_DATA_CMD_TX;
- data->len = htole16(m->m_pkthdr.len);
- data->flags = IWI_DATA_FLAG_NEED_ACK;
+ desc->hdr.type = IWI_HDR_TYPE_DATA;
+ desc->hdr.flags = IWI_HDR_FLAG_IRQ;
+ desc->cmd = IWI_DATA_CMD_TX;
+ desc->len = htole16(m->m_pkthdr.len);
+ desc->flags = IWI_DATA_FLAG_NEED_ACK;
if (ic->ic_flags & IEEE80211_F_WEPON) {
wh->i_fc[1] |= IEEE80211_FC1_WEP;
- data->wep_txkey = ic->ic_wep_txkey;
+ desc->wep_txkey = ic->ic_wep_txkey;
} else
- data->flags |= IWI_DATA_FLAG_NO_WEP;
+ desc->flags |= IWI_DATA_FLAG_NO_WEP;
#if 0
if (ic->ic_flags & IEEE80211_F_SHPREAMBLE)
- data->flags |= IWI_DATA_FLAG_SHPREAMBLE;
+ desc->flags |= IWI_DATA_FLAG_SHPREAMBLE;
#endif
- bcopy(wh, &data->wh, sizeof (struct ieee80211_frame));
- data->nseg = htole32(buf->map->dm_nsegs);
+ bcopy(wh, &desc->wh, sizeof (struct ieee80211_frame));
+ desc->nseg = htole32(buf->map->dm_nsegs);
for (i = 0; i < buf->map->dm_nsegs; i++) {
- data->seg_addr[i] = htole32(buf->map->dm_segs[i].ds_addr);
- data->seg_len[i] = htole32(buf->map->dm_segs[i].ds_len);
+ desc->seg_addr[i] = htole32(buf->map->dm_segs[i].ds_addr);
+ desc->seg_len[i] = htole32(buf->map->dm_segs[i].ds_len);
}
- bus_dmamap_sync(sc->sc_dmat, q->map, q->cur * IWI_TX_SLOT_SIZE,
- sizeof (struct iwi_hdr) + sizeof (struct iwi_data),
- BUS_DMASYNC_PREWRITE);
+ bus_dmamap_sync(sc->sc_dmat, sc->tx_ring_map,
+ sc->tx_cur * sizeof (struct iwi_tx_desc),
+ sizeof (struct iwi_tx_desc), BUS_DMASYNC_PREWRITE);
bus_dmamap_sync(sc->sc_dmat, buf->map, 0, MCLBYTES,
BUS_DMASYNC_PREWRITE);
- DPRINTFN(5, ("TX!DATA!%u!%u\n", data->len, data->nseg));
+ DPRINTFN(5, ("TX!DATA!%u!%u\n", desc->len, desc->nseg));
/* Inform firmware about this new packet */
- q->cur = (q->cur + 1) % q->size;
- CSR_WRITE_4(sc, q->csr_write, q->cur);
+ sc->tx_cur = (sc->tx_cur + 1) % IWI_TX_RING_SIZE;
+ CSR_WRITE_4(sc, IWI_CSR_TX1_WRITE_INDEX, sc->tx_cur);
+
+ sc->tx_free--;
return 0;
}
@@ -999,7 +1164,7 @@ iwi_start(struct ifnet *ifp)
if (m == NULL)
break;
- if (TAILQ_EMPTY(&sc->sc_free_buf)) {
+ if (sc->tx_free <= 2) {
IF_PREPEND(&ifp->if_snd, m);
ifp->if_flags |= IFF_OACTIVE;
break;
@@ -1147,269 +1312,6 @@ iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
return error;
}
-int
-iwi_init_buffers(struct iwi_softc *sc, int nbuf)
-{
- struct iwi_buf *buf;
- int error, i;
-
- sc->nbuf = nbuf;
- sc->buf_list = malloc(nbuf * sizeof (struct iwi_buf), M_DEVBUF,
- M_NOWAIT);
- if (sc->buf_list == NULL) {
- printf("%s: could not allocate buffers\n",
- sc->sc_dev.dv_xname);
- error = ENOMEM;
- goto fail;
- }
- bzero(sc->buf_list, nbuf * sizeof (struct iwi_buf));
-
- TAILQ_INIT(&sc->sc_free_buf);
- for (i = 0, buf = sc->buf_list; i < nbuf; i++, buf++) {
- error = bus_dmamap_create(sc->sc_dmat, nbuf * MCLBYTES, nbuf,
- MCLBYTES, 0, BUS_DMA_NOWAIT, &buf->map);
- if (error != 0) {
- printf("%s: could not create buffer dma map",
- sc->sc_dev.dv_xname);
- goto fail;
- }
- TAILQ_INSERT_TAIL(&sc->sc_free_buf, buf, next);
- }
-
- return 0;
-
-fail: iwi_free_buffers(sc);
- return error;
-}
-
-void
-iwi_free_buffers(struct iwi_softc *sc)
-{
- struct iwi_buf *buf;
- int i;
-
- if (sc->buf_list != NULL) {
- for (i = 0, buf = sc->buf_list; i < sc->nbuf; i++, buf++) {
- if (buf->m != NULL) {
- m_freem(buf->m);
- bus_dmamap_unload(sc->sc_dmat, buf->map);
- }
- bus_dmamap_destroy(sc->sc_dmat, buf->map);
- }
-
- free(sc->buf_list, M_DEVBUF);
- sc->buf_list = NULL;
- }
-}
-
-int
-iwi_init_tx_queue(struct iwi_softc *sc, int index, int size)
-{
- struct iwi_tx_queue *q = &sc->txqueue[index];
- struct iwi_tx_slot *slot;
- int i, nsegs, error;
-
- /* Allocate DMA memory for transmission slots */
- error = bus_dmamap_create(sc->sc_dmat, size * IWI_TX_SLOT_SIZE, 1,
- size * IWI_TX_SLOT_SIZE, 0, BUS_DMA_NOWAIT, &q->map);
- if (error != 0) {
- printf("%s: could not create dma map\n", sc->sc_dev.dv_xname);
- goto fail;
- }
-
- error = bus_dmamem_alloc(sc->sc_dmat, size * IWI_TX_SLOT_SIZE,
- PAGE_SIZE, 0, &q->seg, 1, &nsegs, BUS_DMA_NOWAIT);
- if (error != 0) {
- printf("%s: could not allocate dma memory\n",
- sc->sc_dev.dv_xname);
- goto fail;
- }
-
- error = bus_dmamem_map(sc->sc_dmat, &q->seg, nsegs,
- size * IWI_TX_SLOT_SIZE, &q->virtaddr, BUS_DMA_NOWAIT);
- if (error != 0) {
- printf("%s: could not map dma memory\n", sc->sc_dev.dv_xname);
- goto fail;
- }
-
- error = bus_dmamap_load(sc->sc_dmat, q->map, q->virtaddr,
- size * IWI_TX_SLOT_SIZE, NULL, BUS_DMA_NOWAIT);
- if (error != 0) {
- printf("%s: could not load dma memory\n", sc->sc_dev.dv_xname);
- goto fail;
- }
-
- bzero(q->virtaddr, size * IWI_TX_SLOT_SIZE);
-
- q->slots = malloc(size * sizeof (struct iwi_tx_slot), M_DEVBUF,
- M_NOWAIT);
- if (q->slots == NULL) {
- printf("%s: could not allocate tx slots\n",
- sc->sc_dev.dv_xname);
- error = ENOMEM;
- goto fail;
- }
- bzero(q->slots, size * sizeof (struct iwi_tx_slot));
- for (i = 0, slot = q->slots; i < size; i++, slot++)
- slot->virtaddr = (u_char *)q->virtaddr + i * IWI_TX_SLOT_SIZE;
-
- q->size = size;
- q->old = q->size - 1;
- q->cur = 0;
- q->csr_read = IWI_CSR_TX_READ_INDEX + index * 4;
- q->csr_write = IWI_CSR_TX_WRITE_INDEX + index * 4;
-
- CSR_WRITE_4(sc, IWI_CSR_TX_BASE + index * 8,
- q->map->dm_segs[0].ds_addr);
- CSR_WRITE_4(sc, IWI_CSR_TX_SIZE + index * 8, q->size);
- CSR_WRITE_4(sc, q->csr_read, 0);
- CSR_WRITE_4(sc, q->csr_write, q->cur);
-
- return 0;
-
-fail: iwi_free_tx_queue(sc, index);
- return error;
-}
-
-void
-iwi_free_tx_queue(struct iwi_softc *sc, int index)
-{
- struct iwi_tx_queue *q = &sc->txqueue[index];
-
- if (q->slots != NULL) {
- free(q->slots, M_DEVBUF);
- q->slots = NULL;
- }
-
- if (q->virtaddr != NULL) {
- bus_dmamap_unload(sc->sc_dmat, q->map);
- bus_dmamem_unmap(sc->sc_dmat, q->virtaddr,
- q->size * IWI_TX_SLOT_SIZE);
- bus_dmamem_free(sc->sc_dmat, &q->seg, 1);
- q->virtaddr = NULL;
- bus_dmamap_destroy(sc->sc_dmat, q->map);
- q->map = NULL;
- }
-}
-
-int
-iwi_init_rx_queue(struct iwi_softc *sc)
-{
- struct iwi_rx_queue *q = &sc->rxqueue;
- struct iwi_rx_slot *slot;
- struct iwi_buf *buf;
- int error, i;
-
- q->slots = malloc(IWI_RX_NSLOTS * sizeof (struct iwi_rx_slot),
- M_DEVBUF, M_NOWAIT);
- if (q->slots == NULL) {
- printf("%s: could not allocate rx slots\n",
- sc->sc_dev.dv_xname);
- error = ENOMEM;
- goto fail;
- }
- bzero(q->slots, IWI_RX_NSLOTS * sizeof (struct iwi_rx_slot));
- for (i = 0, slot = q->slots; i < IWI_RX_NSLOTS; i++, slot++) {
- slot->csr = IWI_CSR_RX_SLOT_BASE + i * 4;
-
- buf = slot->buf = TAILQ_FIRST(&sc->sc_free_buf);
- TAILQ_REMOVE(&sc->sc_free_buf, buf, next);
-
- MGETHDR(buf->m, M_DONTWAIT, MT_DATA);
- if (buf->m == NULL) {
- printf("%s: could not allocate rx mbuf\n",
- sc->sc_dev.dv_xname);
- error = ENOMEM;
- goto fail;
- }
- MCLGET(buf->m, M_DONTWAIT);
- if (!(buf->m->m_flags & M_EXT)) {
- m_freem(buf->m);
- printf("%s: could not allocate rx mbuf cluster\n",
- sc->sc_dev.dv_xname);
- error = ENOMEM;
- goto fail;
- }
-
- error = bus_dmamap_load(sc->sc_dmat, buf->map,
- mtod(buf->m, void *), MCLBYTES, NULL, BUS_DMA_NOWAIT);
- if (error != 0) {
- printf("%s: could not map rxbuf dma memory\n",
- sc->sc_dev.dv_xname);
- goto fail;
- }
-
- CSR_WRITE_4(sc, slot->csr, buf->map->dm_segs[0].ds_addr);
- }
-
- q->size = IWI_RX_NSLOTS;
- q->cur = q->size - 1;
-
- CSR_WRITE_4(sc, IWI_CSR_RX_READ_INDEX, 0);
- CSR_WRITE_4(sc, IWI_CSR_RX_WRITE_INDEX, q->cur);
-
- return 0;
-
-fail: iwi_free_rx_queue(sc);
- return error;
-}
-
-void
-iwi_free_rx_queue(struct iwi_softc *sc)
-{
- struct iwi_rx_queue *q = &sc->rxqueue;
-
- if (q->slots != NULL) {
- free(q->slots, M_DEVBUF);
- q->slots = NULL;
- }
-}
-
-int
-iwi_init_queues(struct iwi_softc *sc)
-{
- int i, error;
-
- if ((error = iwi_init_buffers(sc, 64 + IWI_RX_NSLOTS - 2)) != 0)
- goto fail;
-
- /*
- * There are 5 different transmission queues. Queue 0 is used for
- * transmitting host commands while queues 1 through 4 are used for
- * transmitting data at different QoS levels. Only queues 0 and 1 are
- * used at this time but firmware requires all queues to be correctly
- * initialized.
- */
- for (i = 0; i < 5; i++) {
- error = iwi_init_tx_queue(sc, i, (i != 0) ? 64 : 16);
- if (error != 0) {
- printf("%s: could not initialize tx queue %d\n",
- sc->sc_dev.dv_xname, i);
- goto fail;
- }
- }
-
- if ((error = iwi_init_rx_queue(sc)) != 0)
- goto fail;
-
- return 0;
-
-fail: iwi_free_queues(sc);
- return error;
-}
-
-void
-iwi_free_queues(struct iwi_softc *sc)
-{
- int i;
-
- iwi_free_buffers(sc);
- iwi_free_rx_queue(sc);
-
- for (i = 0; i < 5; i++)
- iwi_free_tx_queue(sc, i);
-}
-
void
iwi_stop_master(struct iwi_softc *sc)
{
@@ -1849,7 +1751,7 @@ iwi_scan(struct iwi_softc *sc)
*(p - count) = IWI_CHAN_2GHZ | count;
DPRINTF(("Start scanning\n"));
- return iwi_cmd(sc, IWI_CMD_SCAN, &scan, sizeof scan, IWI_ASYNC_CMD);
+ return iwi_cmd(sc, IWI_CMD_SCAN, &scan, sizeof scan, 1);
}
int
@@ -1872,7 +1774,7 @@ iwi_auth_and_assoc(struct iwi_softc *sc)
config.pass_noise = 1;
DPRINTF(("Configuring adapter\n"));
error = iwi_cmd(sc, IWI_CMD_SET_CONFIGURATION, &config,
- sizeof config, IWI_ASYNC_CMD);
+ sizeof config, 1);
if (error != 0)
return error;
}
@@ -1884,8 +1786,7 @@ iwi_auth_and_assoc(struct iwi_softc *sc)
printf("\n");
}
#endif
- error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ni->ni_essid, ni->ni_esslen,
- IWI_ASYNC_CMD);
+ error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ni->ni_essid, ni->ni_esslen, 1);
if (error != 0)
return error;
@@ -1896,14 +1797,13 @@ iwi_auth_and_assoc(struct iwi_softc *sc)
rs.nrates = ni->ni_rates.rs_nrates;
bcopy(ni->ni_rates.rs_rates, rs.rates, rs.nrates);
DPRINTF(("Setting negociated rates (%u)\n", rs.nrates));
- error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, IWI_ASYNC_CMD);
+ error = iwi_cmd(sc, IWI_CMD_SET_RATES, &rs, sizeof rs, 1);
if (error != 0)
return error;
data = htole32(0);
DPRINTF(("Setting sensitivity to %d\n", letoh32(data)));
- error = iwi_cmd(sc, IWI_CMD_SET_SENSITIVITY, &data, sizeof data,
- IWI_ASYNC_CMD);
+ error = iwi_cmd(sc, IWI_CMD_SET_SENSITIVITY, &data, sizeof data, 1);
if (error != 0)
return error;
@@ -1921,8 +1821,7 @@ iwi_auth_and_assoc(struct iwi_softc *sc)
IEEE80211_ADDR_COPY(assoc.dst, ni->ni_bssid);
DPRINTF(("Trying to associate to %s channel %u auth %u\n",
ether_sprintf(assoc.bssid), assoc.chan, assoc.auth));
- return iwi_cmd(sc, IWI_CMD_ASSOCIATE, &assoc, sizeof assoc,
- IWI_ASYNC_CMD);
+ return iwi_cmd(sc, IWI_CMD_ASSOCIATE, &assoc, sizeof assoc, 1);
}
int
@@ -1930,7 +1829,7 @@ iwi_init(struct ifnet *ifp)
{
struct iwi_softc *sc = ifp->if_softc;
const char *name;
- int error;
+ int i, error;
if ((error = iwi_reset(sc)) != 0) {
printf("%s: could not reset adapter\n", sc->sc_dev.dv_xname);
@@ -1950,11 +1849,46 @@ iwi_init(struct ifnet *ifp)
iwi_stop_master(sc);
- if ((error = iwi_init_queues(sc)) != 0) {
- printf("%s: could not initialize queues\n",
- sc->sc_dev.dv_xname);
- goto fail;
- }
+ sc->tx_cur = 0;
+ sc->tx_old = IWI_TX_RING_SIZE - 1;
+ sc->tx_free = IWI_TX_RING_SIZE;
+ sc->cmd_cur = 0;
+ sc->rx_cur = IWI_RX_RING_SIZE - 1;
+
+ CSR_WRITE_4(sc, IWI_CSR_CMD_BASE, sc->cmd_ring_map->dm_segs[0].ds_addr);
+ CSR_WRITE_4(sc, IWI_CSR_CMD_SIZE, IWI_CMD_RING_SIZE);
+ CSR_WRITE_4(sc, IWI_CSR_CMD_READ_INDEX, 0);
+ CSR_WRITE_4(sc, IWI_CSR_CMD_WRITE_INDEX, sc->cmd_cur);
+
+ CSR_WRITE_4(sc, IWI_CSR_TX1_BASE, sc->tx_ring_map->dm_segs[0].ds_addr);
+ CSR_WRITE_4(sc, IWI_CSR_TX1_SIZE, IWI_TX_RING_SIZE);
+ CSR_WRITE_4(sc, IWI_CSR_TX1_READ_INDEX, 0);
+ CSR_WRITE_4(sc, IWI_CSR_TX1_WRITE_INDEX, sc->tx_cur);
+
+ CSR_WRITE_4(sc, IWI_CSR_TX2_BASE, sc->tx_ring_map->dm_segs[0].ds_addr);
+ CSR_WRITE_4(sc, IWI_CSR_TX2_SIZE, IWI_TX_RING_SIZE);
+ CSR_WRITE_4(sc, IWI_CSR_TX2_READ_INDEX, 0);
+ CSR_WRITE_4(sc, IWI_CSR_TX2_WRITE_INDEX, 0);
+
+ CSR_WRITE_4(sc, IWI_CSR_TX3_BASE, sc->tx_ring_map->dm_segs[0].ds_addr);
+ CSR_WRITE_4(sc, IWI_CSR_TX3_SIZE, IWI_TX_RING_SIZE);
+ CSR_WRITE_4(sc, IWI_CSR_TX3_READ_INDEX, 0);
+ CSR_WRITE_4(sc, IWI_CSR_TX3_WRITE_INDEX, 0);
+
+ CSR_WRITE_4(sc, IWI_CSR_TX4_BASE, sc->tx_ring_map->dm_segs[0].ds_addr);
+ CSR_WRITE_4(sc, IWI_CSR_TX4_SIZE, IWI_TX_RING_SIZE);
+ CSR_WRITE_4(sc, IWI_CSR_TX4_READ_INDEX, 0);
+ CSR_WRITE_4(sc, IWI_CSR_TX4_WRITE_INDEX, 0);
+
+ for (i = 0; i < IWI_RX_RING_SIZE; i++)
+ CSR_WRITE_4(sc, IWI_CSR_RX_BASE + i * 4,
+ sc->rx_buf[i].map->dm_segs[0].ds_addr);
+
+ /*
+ * Kick Rx
+ */
+ CSR_WRITE_4(sc, IWI_CSR_RX_WRITE_INDEX, sc->rx_cur);
+ CSR_WRITE_4(sc, IWI_CSR_RX_READ_INDEX, 0);
switch (sc->sc_ic.ic_opmode) {
case IEEE80211_M_STA:
@@ -2003,11 +1937,30 @@ iwi_stop(struct ifnet *ifp, int disable)
{
struct iwi_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
+ struct iwi_tx_buf *buf;
+ int i;
iwi_stop_master(sc);
CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_SW_RESET);
- iwi_free_queues(sc);
+ /*
+ * Release Tx buffers
+ */
+ for (i = 0; i < IWI_TX_RING_SIZE; i++) {
+ buf = &sc->tx_buf[i];
+
+ if (buf->m != NULL) {
+ bus_dmamap_unload(sc->sc_dmat, buf->map);
+ m_freem(buf->m);
+ buf->m = NULL;
+
+ if (buf->ni != NULL) {
+ if (buf->ni != ic->ic_bss)
+ ieee80211_free_node(ic, buf->ni);
+ buf->ni = NULL;
+ }
+ }
+ }
ifp->if_timer = 0;
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
@@ -2018,4 +1971,3 @@ iwi_stop(struct ifnet *ifp, int disable)
struct cfdriver iwi_cd = {
0, "iwi", DV_IFNET
};
-
diff --git a/sys/dev/pci/if_iwireg.h b/sys/dev/pci/if_iwireg.h
index 45873342ea6..f6161b4e4d2 100644
--- a/sys/dev/pci/if_iwireg.h
+++ b/sys/dev/pci/if_iwireg.h
@@ -1,4 +1,4 @@
-/* $Id: if_iwireg.h,v 1.5 2004/11/24 21:20:58 damien Exp $ */
+/* $Id: if_iwireg.h,v 1.6 2004/12/04 17:24:06 damien Exp $ */
/*-
* Copyright (c) 2004
@@ -27,8 +27,9 @@
* SUCH DAMAGE.
*/
-#define IWI_TX_SLOT_SIZE 128
-#define IWI_RX_NSLOTS 32
+#define IWI_TX_RING_SIZE 64
+#define IWI_CMD_RING_SIZE 16
+#define IWI_RX_RING_SIZE 32
#define IWI_CSR_INTR 0x0008
#define IWI_CSR_INTR_MASK 0x000c
@@ -39,21 +40,37 @@
#define IWI_CSR_RST 0x0020
#define IWI_CSR_CTL 0x0024
#define IWI_CSR_IO 0x0030
-#define IWI_CSR_TX_BASE 0x0200
-#define IWI_CSR_TX_SIZE 0x0204
-#define IWI_CSR_TX_READ_INDEX 0x0280
+#define IWI_CSR_CMD_BASE 0x0200
+#define IWI_CSR_CMD_SIZE 0x0204
+#define IWI_CSR_TX1_BASE 0x0208
+#define IWI_CSR_TX1_SIZE 0x020c
+#define IWI_CSR_TX2_BASE 0x0210
+#define IWI_CSR_TX2_SIZE 0x0214
+#define IWI_CSR_TX3_BASE 0x0218
+#define IWI_CSR_TX3_SIZE 0x021c
+#define IWI_CSR_TX4_BASE 0x0220
+#define IWI_CSR_TX4_SIZE 0x0224
+#define IWI_CSR_CMD_READ_INDEX 0x0280
+#define IWI_CSR_TX1_READ_INDEX 0x0284
+#define IWI_CSR_TX2_READ_INDEX 0x0288
+#define IWI_CSR_TX3_READ_INDEX 0x028c
+#define IWI_CSR_TX4_READ_INDEX 0x0290
#define IWI_CSR_RX_READ_INDEX 0x02a0
-#define IWI_CSR_RX_SLOT_BASE 0x0500
+#define IWI_CSR_RX_BASE 0x0500
#define IWI_CSR_TABLE0_SIZE 0x0700
#define IWI_CSR_TABLE0_BASE 0x0704
#define IWI_CSR_CURRENT_TX_RATE IWI_CSR_TABLE0_BASE
-#define IWI_CSR_TX_WRITE_INDEX 0x0f80
+#define IWI_CSR_CMD_WRITE_INDEX 0x0f80
+#define IWI_CSR_TX1_WRITE_INDEX 0x0f84
+#define IWI_CSR_TX2_WRITE_INDEX 0x0f88
+#define IWI_CSR_TX3_WRITE_INDEX 0x0f8c
+#define IWI_CSR_TX4_WRITE_INDEX 0x0f90
#define IWI_CSR_RX_WRITE_INDEX 0x0fa0
#define IWI_CSR_READ_INT 0x0ff4
/* possible flags for IWI_CSR_INTR */
#define IWI_INTR_RX_TRANSFER 0x00000002
-#define IWI_INTR_TX0_TRANSFER 0x00000800
+#define IWI_INTR_CMD_TRANSFER 0x00000800
#define IWI_INTR_TX1_TRANSFER 0x00001000
#define IWI_INTR_TX2_TRANSFER 0x00002000
#define IWI_INTR_TX3_TRANSFER 0x00004000
@@ -63,7 +80,7 @@
#define IWI_INTR_PARITY_ERROR 0x80000000
#define IWI_INTR_MASK \
- (IWI_INTR_RX_TRANSFER | IWI_INTR_TX0_TRANSFER | \
+ (IWI_INTR_RX_TRANSFER | IWI_INTR_CMD_TRANSFER | \
IWI_INTR_TX1_TRANSFER | IWI_INTR_TX2_TRANSFER | \
IWI_INTR_TX3_TRANSFER | IWI_INTR_TX4_TRANSFER | \
IWI_INTR_FW_INITED | IWI_INTR_FATAL_ERROR | \
@@ -186,7 +203,8 @@ struct iwi_frame {
} __attribute__((__packed__));
/* header for transmission */
-struct iwi_data {
+struct iwi_tx_desc {
+ struct iwi_hdr hdr;
u_int32_t reserved1[2];
u_int8_t cmd;
#define IWI_DATA_CMD_TX 0x0b
@@ -214,7 +232,8 @@ struct iwi_data {
} __attribute__((__packed__));
/* command */
-struct iwi_cmd {
+struct iwi_cmd_desc {
+ struct iwi_hdr hdr;
u_int8_t type;
#define IWI_CMD_ENABLE 2
#define IWI_CMD_SET_CONFIGURATION 6
diff --git a/sys/dev/pci/if_iwivar.h b/sys/dev/pci/if_iwivar.h
index 699b323f4b8..5256de5b178 100644
--- a/sys/dev/pci/if_iwivar.h
+++ b/sys/dev/pci/if_iwivar.h
@@ -1,4 +1,4 @@
-/* $Id: if_iwivar.h,v 1.2 2004/11/22 21:34:35 damien Exp $ */
+/* $Id: if_iwivar.h,v 1.3 2004/12/04 17:24:06 damien Exp $ */
/*-
* Copyright (c) 2004
@@ -27,42 +27,6 @@
* SUCH DAMAGE.
*/
-struct iwi_buf {
- struct mbuf *m;
- struct ieee80211_node *ni;
- bus_dmamap_t map;
- TAILQ_ENTRY(iwi_buf) next;
-};
-
-struct iwi_tx_slot {
- caddr_t virtaddr;
- struct iwi_buf *buf;
-};
-
-struct iwi_rx_slot {
- u_int32_t csr;
- struct iwi_buf *buf;
-};
-
-struct iwi_rx_queue {
- struct iwi_rx_slot *slots;
- u_int32_t cur;
- u_int32_t size;
-};
-
-struct iwi_tx_queue {
- bus_dmamap_t map;
- bus_dma_segment_t seg;
- bus_addr_t physaddr;
- caddr_t virtaddr;
- struct iwi_tx_slot *slots;
- u_int32_t csr_read;
- u_int32_t csr_write;
- u_int32_t old;
- u_int32_t cur;
- u_int32_t size;
-};
-
struct iwi_rx_radiotap_header {
struct ieee80211_radiotap_header wr_ihdr;
u_int8_t wr_flags;
@@ -103,8 +67,33 @@ struct iwi_softc {
u_int32_t flags;
#define IWI_FLAG_FW_INITED (1 << 0)
- struct iwi_tx_queue txqueue[5];
- struct iwi_rx_queue rxqueue;
+ bus_dma_tag_t sc_dmat;
+
+ struct iwi_tx_desc *tx_desc;
+ bus_dmamap_t tx_ring_map;
+ bus_dma_segment_t tx_ring_seg;
+
+ struct iwi_tx_buf {
+ bus_dmamap_t map;
+ struct mbuf *m;
+ struct ieee80211_node *ni;
+ } tx_buf[IWI_TX_RING_SIZE];
+
+ int tx_cur;
+ int tx_old;
+ int tx_free;
+
+ struct iwi_cmd_desc *cmd_desc;
+ bus_dmamap_t cmd_ring_map;
+ bus_dma_segment_t cmd_ring_seg;
+ int cmd_cur;
+
+ struct iwi_rx_buf {
+ bus_dmamap_t map;
+ struct mbuf *m;
+ } rx_buf[IWI_RX_RING_SIZE];
+
+ int rx_cur;
struct resource *irq;
struct resource *mem;
@@ -118,12 +107,6 @@ struct iwi_softc {
int sc_tx_timer;
- bus_dma_tag_t sc_dmat;
-
- struct iwi_buf *buf_list;
- int nbuf;
- TAILQ_HEAD(, iwi_buf) sc_free_buf;
-
#if NBPFILTER > 0
caddr_t sc_drvbpf;
@@ -143,7 +126,5 @@ struct iwi_softc {
#endif
};
-#define IWI_ASYNC_CMD (1 << 0)
-
#define SIOCGRADIO _IOWR('i', 139, struct ifreq)
#define SIOCGTABLE0 _IOWR('i', 140, struct ifreq)