diff options
author | Damien Bergamini <damien@cvs.openbsd.org> | 2007-09-07 19:32:10 +0000 |
---|---|---|
committer | Damien Bergamini <damien@cvs.openbsd.org> | 2007-09-07 19:32:10 +0000 |
commit | 62fc1b4a641d37a48a5d409872ac6d05dde89661 (patch) | |
tree | ffa0171a6dd93e68845f0970dcd1c04b78c08e7b /sys/dev | |
parent | dd104d2e95224717ef2ccaf5decb6ffb10f1a1ad (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.c | 17 | ||||
-rw-r--r-- | sys/dev/pci/if_iwnreg.h | 3 |
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; |