summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2007-09-07 19:32:10 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2007-09-07 19:32:10 +0000
commit62fc1b4a641d37a48a5d409872ac6d05dde89661 (patch)
treeffa0171a6dd93e68845f0970dcd1c04b78c08e7b /sys/dev
parentdd104d2e95224717ef2ccaf5decb6ffb10f1a1ad (diff)
make sure the length of the first segment of a Tx descriptor is a multiple
of 4 by inserting padding bytes when necessary. 802.11 QoS headers have a length that is not a multiple of 4.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/if_iwn.c17
-rw-r--r--sys/dev/pci/if_iwnreg.h3
2 files changed, 13 insertions, 7 deletions
diff --git a/sys/dev/pci/if_iwn.c b/sys/dev/pci/if_iwn.c
index 1a075c1cd2d..33e943deeed 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.4 2007/09/07 19:05:05 damien Exp $ */
+/* $OpenBSD: if_iwn.c,v 1.5 2007/09/07 19:32:09 damien Exp $ */
/*-
* Copyright (c) 2007
@@ -1659,7 +1659,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
uint32_t flags;
uint8_t type;
u_int hdrlen;
- int i, rate, error, ovhd = 0;
+ int i, rate, error, pad, ovhd = 0;
desc = &ring->desc[ring->cur];
data = &ring->data[ring->cur];
@@ -1766,6 +1766,13 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
} else
tx->timeout = htole16(0);
+ if (hdrlen & 3) {
+ /* first segment's length must be a multiple of 4 */
+ flags |= IWN_TX_NEED_PADDING;
+ pad = 4 - (hdrlen & 3);
+ } else
+ pad = 0;
+
tx->flags = htole32(flags);
tx->len = htole16(m0->m_pkthdr.len);
tx->rate = iwn_plcp_signal(rate);
@@ -1843,7 +1850,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni,
/* first scatter/gather segment is used by the tx data command */
IWN_SET_DESC_NSEGS(desc, 1 + data->map->dm_nsegs);
- IWN_SET_DESC_SEG(desc, 0, paddr, 4 + sizeof (*tx) + hdrlen);
+ IWN_SET_DESC_SEG(desc, 0, paddr, 4 + sizeof (*tx) + hdrlen + pad);
for (i = 1; i <= data->map->dm_nsegs; i++) {
IWN_SET_DESC_SEG(desc, i, data->map->dm_segs[i - 1].ds_addr,
data->map->dm_segs[i - 1].ds_len);
@@ -3373,11 +3380,9 @@ iwn_hw_config(struct iwn_softc *sc)
{
uint32_t tmp, hw;
-#ifdef notyet
/* enable interrupts mitigation */
/* XXX generates way too much interrupts (vmstat -i) !! */
- IWN_WRITE(sc, IWN_INTR_MIT, 512 / 32);
-#endif
+ IWN_WRITE(sc, IWN_INTR_MIT, 0 /* 512 / 32 */);
/* voodoo from the reference driver */
tmp = pci_conf_read(sc->sc_pct, sc->sc_pcitag, PCI_CLASS_REG);
diff --git a/sys/dev/pci/if_iwnreg.h b/sys/dev/pci/if_iwnreg.h
index d24c3d7e35b..6cd1c60af45 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.2 2007/09/06 19:33:20 damien Exp $ */
+/* $OpenBSD: if_iwnreg.h,v 1.3 2007/09/07 19:32:09 damien Exp $ */
/*-
* Copyright (c) 2007
@@ -432,6 +432,7 @@ struct iwn_cmd_data {
#define IWN_TX_BT_DISABLE (1 << 12) /* bluetooth coexistence */
#define IWN_TX_AUTO_SEQ (1 << 13)
#define IWN_TX_INSERT_TSTAMP (1 << 16)
+#define IWN_TX_NEED_PADDING (1 << 20)
uint8_t ntries;
uint8_t bluetooth;